/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.conscrypt;

import org.conscrypt.util.EmptyArray;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import javax.crypto.SecretKey;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509ExtendedKeyManager;
import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509TrustManager;
import javax.security.auth.x500.X500Principal;

/**
 * The instances of this class encapsulate all the info
 * about enabled cipher suites and protocols,
 * as well as the information about client/server mode of
 * ssl socket, whether it require/want client authentication or not,
 * and controls whether new SSL sessions may be established by this
 * socket or not.
 */
public class SSLParametersImpl implements Cloneable {

    // default source of X.509 certificate based authentication keys
    private static volatile X509KeyManager defaultX509KeyManager;
    // default source of X.509 certificate based authentication trust decisions
    private static volatile X509TrustManager defaultX509TrustManager;
    // default source of random numbers
    private static volatile SecureRandom defaultSecureRandom;
    // default SSL parameters
    private static volatile SSLParametersImpl defaultParameters;

    // client session context contains the set of reusable
    // client-side SSL sessions
    private final ClientSessionContext clientSessionContext;
    // server session context contains the set of reusable
    // server-side SSL sessions
    private final ServerSessionContext serverSessionContext;
    // source of X.509 certificate based authentication keys or null if not provided
    private final X509KeyManager x509KeyManager;
    // source of Pre-Shared Key (PSK) authentication keys or null if not provided.
    private final PSKKeyManager pskKeyManager;
    // source of X.509 certificate based authentication trust decisions or null if not provided
    private final X509TrustManager x509TrustManager;
    // source of random numbers
    private SecureRandom secureRandom;

    // protocols enabled for SSL connection
    private String[] enabledProtocols;
    // cipher suites enabled for SSL connection
    private String[] enabledCipherSuites;

    // if the peer with this parameters tuned to work in client mode
    private boolean client_mode = true;
    // if the peer with this parameters tuned to require client authentication
    private boolean need_client_auth = false;
    // if the peer with this parameters tuned to request client authentication
    private boolean want_client_auth = false;
    // if the peer with this parameters allowed to cteate new SSL session
    private boolean enable_session_creation = true;
    private String endpointIdentificationAlgorithm;

    byte[] npnProtocols;
    byte[] alpnProtocols;
    boolean useSessionTickets;
    private Boolean useSni;

    /**
     * Whether the TLS Channel ID extension is enabled. This field is
     * server-side only.
     */
    boolean channelIdEnabled;

    /**
     * Initializes the parameters. Naturally this constructor is used
     * in SSLContextImpl.engineInit method which directly passes its
     * parameters. In other words this constructor holds all
     * the functionality provided by SSLContext.init method.
     * See {@link javax.net.ssl.SSLContext#init(KeyManager[],TrustManager[],
     * SecureRandom)} for more information
     */
    protected SSLParametersImpl(KeyManager[] kms, TrustManager[] tms,
            SecureRandom sr, ClientSessionContext clientSessionContext,
            ServerSessionContext serverSessionContext)
            throws KeyManagementException {
        this.serverSessionContext = serverSessionContext;
        this.clientSessionContext = clientSessionContext;

        // initialize key managers
        if (kms == null) {
            x509KeyManager = getDefaultX509KeyManager();
            // There's no default PSK key manager
            pskKeyManager = null;
        } else {
            x509KeyManager = findFirstX509KeyManager(kms);
            pskKeyManager = findFirstPSKKeyManager(kms);
        }

        // initialize x509TrustManager
        if (tms == null) {
            x509TrustManager = getDefaultX509TrustManager();
        } else {
            x509TrustManager = findFirstX509TrustManager(tms);
        }

        // initialize secure random
        // We simply use the SecureRandom passed in by the caller. If it's
        // null, we don't replace it by a new instance. The native code below
        // then directly accesses /dev/urandom. Not the most elegant solution,
        // but faster than going through the SecureRandom object.
        secureRandom = sr;

        // initialize the list of cipher suites and protocols enabled by default
        enabledProtocols = getDefaultProtocols();
        boolean x509CipherSuitesNeeded = (x509KeyManager != null) || (x509TrustManager != null);
        boolean pskCipherSuitesNeeded = pskKeyManager != null;
        enabledCipherSuites = getDefaultCipherSuites(
                x509CipherSuitesNeeded, pskCipherSuitesNeeded);
    }

    protected static SSLParametersImpl getDefault() throws KeyManagementException {
        SSLParametersImpl result = defaultParameters;
        if (result == null) {
            // single-check idiom
            defaultParameters = result = new SSLParametersImpl(null,
                                                               null,
                                                               null,
                                                               new ClientSessionContext(),
                                                               new ServerSessionContext());
        }
        return (SSLParametersImpl) result.clone();
    }

    /**
     * Returns the appropriate session context.
     */
    public AbstractSessionContext getSessionContext() {
        return client_mode ? clientSessionContext : serverSessionContext;
    }

    /**
     * @return server session context
     */
    protected ServerSessionContext getServerSessionContext() {
        return serverSessionContext;
    }

    /**
     * @return client session context
     */
    protected ClientSessionContext getClientSessionContext() {
        return clientSessionContext;
    }

    /**
     * @return X.509 key manager or {@code null} for none.
     */
    protected X509KeyManager getX509KeyManager() {
        return x509KeyManager;
    }

    /**
     * @return Pre-Shared Key (PSK) key manager or {@code null} for none.
     */
    protected PSKKeyManager getPSKKeyManager() {
        return pskKeyManager;
    }

    /**
     * @return X.509 trust manager or {@code null} for none.
     */
    protected X509TrustManager getX509TrustManager() {
        return x509TrustManager;
    }

    /**
     * @return secure random
     */
    protected SecureRandom getSecureRandom() {
        if (secureRandom != null) {
            return secureRandom;
        }
        SecureRandom result = defaultSecureRandom;
        if (result == null) {
            // single-check idiom
            defaultSecureRandom = result = new SecureRandom();
        }
        secureRandom = result;
        return secureRandom;
    }

    /**
     * @return the secure random member reference, even it is null
     */
    protected SecureRandom getSecureRandomMember() {
        return secureRandom;
    }

    /**
     * @return the names of enabled cipher suites
     */
    protected String[] getEnabledCipherSuites() {
        return enabledCipherSuites.clone();
    }

    /**
     * Sets the enabled cipher suites after filtering through OpenSSL.
     */
    protected void setEnabledCipherSuites(String[] cipherSuites) {
        enabledCipherSuites = NativeCrypto.checkEnabledCipherSuites(cipherSuites).clone();
    }

    /**
     * @return the set of enabled protocols
     */
    protected String[] getEnabledProtocols() {
        return enabledProtocols.clone();
    }

    /**
     * Sets the set of available protocols for use in SSL connection.
     * @param protocols String[]
     */
    protected void setEnabledProtocols(String[] protocols) {
        enabledProtocols = NativeCrypto.checkEnabledProtocols(protocols).clone();
    }

    /**
     * Tunes the peer holding this parameters to work in client mode.
     * @param   mode if the peer is configured to work in client mode
     */
    protected void setUseClientMode(boolean mode) {
        client_mode = mode;
    }

    /**
     * Returns the value indicating if the parameters configured to work
     * in client mode.
     */
    protected boolean getUseClientMode() {
        return client_mode;
    }

    /**
     * Tunes the peer holding this parameters to require client authentication
     */
    protected void setNeedClientAuth(boolean need) {
        need_client_auth = need;
        // reset the want_client_auth setting
        want_client_auth = false;
    }

    /**
     * Returns the value indicating if the peer with this parameters tuned
     * to require client authentication
     */
    protected boolean getNeedClientAuth() {
        return need_client_auth;
    }

    /**
     * Tunes the peer holding this parameters to request client authentication
     */
    protected void setWantClientAuth(boolean want) {
        want_client_auth = want;
        // reset the need_client_auth setting
        need_client_auth = false;
    }

    /**
     * Returns the value indicating if the peer with this parameters
     * tuned to request client authentication
     */
    protected boolean getWantClientAuth() {
        return want_client_auth;
    }

    /**
     * Allows/disallows the peer holding this parameters to
     * create new SSL session
     */
    protected void setEnableSessionCreation(boolean flag) {
        enable_session_creation = flag;
    }

    /**
     * Returns the value indicating if the peer with this parameters
     * allowed to cteate new SSL session
     */
    protected boolean getEnableSessionCreation() {
        return enable_session_creation;
    }

    /**
     * Whether connections using this SSL connection should use the TLS
     * extension Server Name Indication (SNI).
     */
    protected void setUseSni(boolean flag) {
        useSni = Boolean.valueOf(flag);
    }

    /**
     * Returns whether connections using this SSL connection should use the TLS
     * extension Server Name Indication (SNI).
     */
    protected boolean getUseSni() {
        return useSni != null ? useSni.booleanValue() : isSniEnabledByDefault();
    }

    static byte[][] encodeIssuerX509Principals(X509Certificate[] certificates)
            throws CertificateEncodingException {
        byte[][] principalBytes = new byte[certificates.length][];
        for (int i = 0; i < certificates.length; i++) {
            principalBytes[i] = certificates[i].getIssuerX500Principal().getEncoded();
        }
        return principalBytes;
    }

    /**
     * Return a possibly null array of X509Certificates given the possibly null
     * array of DER encoded bytes.
     */
    private static OpenSSLX509Certificate[] createCertChain(long[] certificateRefs)
            throws IOException {
        if (certificateRefs == null) {
            return null;
        }
        OpenSSLX509Certificate[] certificates = new OpenSSLX509Certificate[certificateRefs.length];
        for (int i = 0; i < certificateRefs.length; i++) {
            certificates[i] = new OpenSSLX509Certificate(certificateRefs[i]);
        }
        return certificates;
    }

    OpenSSLSessionImpl getSessionToReuse(long sslNativePointer, String hostname, int port)
            throws SSLException {
        final OpenSSLSessionImpl sessionToReuse;
        if (client_mode) {
            // look for client session to reuse
            sessionToReuse = getCachedClientSession(clientSessionContext, hostname, port);
            if (sessionToReuse != null) {
                NativeCrypto.SSL_set_session(sslNativePointer,
                        sessionToReuse.sslSessionNativePointer);
            }
        } else {
            sessionToReuse = null;
        }
        return sessionToReuse;
    }

    void setTlsChannelId(long sslNativePointer, OpenSSLKey channelIdPrivateKey)
            throws SSLHandshakeException, SSLException {
        // TLS Channel ID
        if (channelIdEnabled) {
            if (client_mode) {
                // Client-side TLS Channel ID
                if (channelIdPrivateKey == null) {
                    throw new SSLHandshakeException("Invalid TLS channel ID key specified");
                }
                NativeCrypto.SSL_set1_tls_channel_id(sslNativePointer,
                        channelIdPrivateKey.getPkeyContext());
            } else {
                // Server-side TLS Channel ID
                NativeCrypto.SSL_enable_tls_channel_id(sslNativePointer);
            }
        }
    }

    void setCertificate(long sslNativePointer, String alias) throws CertificateEncodingException,
            SSLException {
        if (alias == null) {
            return;
        }
        X509KeyManager keyManager = getX509KeyManager();
        if (keyManager == null) {
            return;
        }
        PrivateKey privateKey = keyManager.getPrivateKey(alias);
        if (privateKey == null) {
            return;
        }
        X509Certificate[] certificates = keyManager.getCertificateChain(alias);
        if (certificates == null) {
            return;
        }

        /*
         * Make sure we keep a reference to the OpenSSLX509Certificate by using
         * this array. Otherwise, if they're not OpenSSLX509Certificate
         * instances originally, they may be garbage collected before we
         * complete our JNI calls.
         */
        OpenSSLX509Certificate[] openSslCerts = new OpenSSLX509Certificate[certificates.length];
        long[] x509refs = new long[certificates.length];
        for (int i = 0; i < certificates.length; i++) {
            OpenSSLX509Certificate openSslCert = OpenSSLX509Certificate
                    .fromCertificate(certificates[i]);
            openSslCerts[i] = openSslCert;
            x509refs[i] = openSslCert.getContext();
        }

        // Note that OpenSSL says to use SSL_use_certificate before
        // SSL_use_PrivateKey.
        NativeCrypto.SSL_use_certificate(sslNativePointer, x509refs);

        final OpenSSLKey key;
        try {
            key = OpenSSLKey.fromPrivateKey(privateKey);
            NativeCrypto.SSL_use_PrivateKey(sslNativePointer, key.getPkeyContext());
        } catch (InvalidKeyException e) {
            throw new SSLException(e);
        }

        // We may not have access to all the information to check the private key
        // if it's a wrapped platform key, so skip this check.
        if (!key.isWrapped()) {
            // Makes sure the set PrivateKey and X509Certificate refer to the same
            // key by comparing the public values.
            NativeCrypto.SSL_check_private_key(sslNativePointer);
        }
    }

    void setSSLParameters(long sslCtxNativePointer, long sslNativePointer, AliasChooser chooser,
            PSKCallbacks pskCallbacks, String sniHostname) throws SSLException, IOException {
        if (npnProtocols != null) {
            NativeCrypto.SSL_CTX_enable_npn(sslCtxNativePointer);
        }

        if (client_mode && alpnProtocols != null) {
            NativeCrypto.SSL_set_alpn_protos(sslNativePointer, alpnProtocols);
        }

        NativeCrypto.setEnabledProtocols(sslNativePointer, enabledProtocols);
        NativeCrypto.setEnabledCipherSuites(sslNativePointer, enabledCipherSuites);

        // setup server certificates and private keys.
        // clients will receive a call back to request certificates.
        if (!client_mode) {
            Set<String> keyTypes = new HashSet<String>();
            for (long sslCipherNativePointer : NativeCrypto.SSL_get_ciphers(sslNativePointer)) {
                String keyType = getServerX509KeyType(sslCipherNativePointer);
                if (keyType != null) {
                    keyTypes.add(keyType);
                }
            }
            X509KeyManager keyManager = getX509KeyManager();
            if (keyManager != null) {
                for (String keyType : keyTypes) {
                    try {
                        setCertificate(sslNativePointer,
                                chooser.chooseServerAlias(x509KeyManager, keyType));
                    } catch (CertificateEncodingException e) {
                        throw new IOException(e);
                    }
                }
            }
        }

        // Enable Pre-Shared Key (PSK) key exchange if requested
        PSKKeyManager pskKeyManager = getPSKKeyManager();
        if (pskKeyManager != null) {
            boolean pskEnabled = false;
            for (String enabledCipherSuite : enabledCipherSuites) {
                if ((enabledCipherSuite != null) && (enabledCipherSuite.contains("PSK"))) {
                    pskEnabled = true;
                    break;
                }
            }
            if (pskEnabled) {
                if (client_mode) {
                    NativeCrypto.set_SSL_psk_client_callback_enabled(sslNativePointer, true);
                } else {
                    NativeCrypto.set_SSL_psk_server_callback_enabled(sslNativePointer, true);
                    String identityHint = pskCallbacks.chooseServerPSKIdentityHint(pskKeyManager);
                    NativeCrypto.SSL_use_psk_identity_hint(sslNativePointer, identityHint);
                }
            }
        }

        if (useSessionTickets) {
            NativeCrypto.SSL_clear_options(sslNativePointer, NativeCrypto.SSL_OP_NO_TICKET);
        }
        if (getUseSni() && AddressUtils.isValidSniHostname(sniHostname)) {
            NativeCrypto.SSL_set_tlsext_host_name(sslNativePointer, sniHostname);
        }

        // BEAST attack mitigation (1/n-1 record splitting for CBC cipher suites
        // with TLSv1 and SSLv3).
        NativeCrypto.SSL_set_mode(sslNativePointer, NativeCrypto.SSL_MODE_CBC_RECORD_SPLITTING);

        boolean enableSessionCreation = getEnableSessionCreation();
        if (!enableSessionCreation) {
            NativeCrypto.SSL_set_session_creation_enabled(sslNativePointer, enableSessionCreation);
        }
    }

    /**
     * Returns true when the supplied hostname is valid for SNI purposes.
     */
    private static boolean isValidSniHostname(String sniHostname) {
        if (sniHostname == null) {
            return false;
        }

        // Must be a FQDN.
        if (sniHostname.indexOf('.') == -1) {
            return false;
        }

        if (Platform.isLiteralIpAddress(sniHostname)) {
            return false;
        }

        return true;
    }

    /**
     * Returns whether Server Name Indication (SNI) is enabled by default for
     * sockets. For more information on SNI, see RFC 6066 section 3.
     */
    private boolean isSniEnabledByDefault() {
        String enableSNI = System.getProperty("jsse.enableSNIExtension",
                Platform.isSniEnabledByDefault() ? "true" : "false");
        if ("true".equalsIgnoreCase(enableSNI)) {
            return true;
        } else if ("false".equalsIgnoreCase(enableSNI)) {
            return false;
        } else {
            throw new RuntimeException(
                    "Can only set \"jsse.enableSNIExtension\" to \"true\" or \"false\"");
        }
    }

    void setCertificateValidation(long sslNativePointer) throws IOException {
        // setup peer certificate verification
        if (!client_mode) {
            // needing client auth takes priority...
            boolean certRequested;
            if (getNeedClientAuth()) {
                NativeCrypto.SSL_set_verify(sslNativePointer,
                                            NativeCrypto.SSL_VERIFY_PEER
                                            | NativeCrypto.SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
                certRequested = true;
            // ... over just wanting it...
            } else if (getWantClientAuth()) {
                NativeCrypto.SSL_set_verify(sslNativePointer, NativeCrypto.SSL_VERIFY_PEER);
                certRequested = true;
            // ... and we must disable verification if we don't want client auth.
            } else {
                NativeCrypto.SSL_set_verify(sslNativePointer, NativeCrypto.SSL_VERIFY_NONE);
                certRequested = false;
            }

            if (certRequested) {
                X509TrustManager trustManager = getX509TrustManager();
                X509Certificate[] issuers = trustManager.getAcceptedIssuers();
                if (issuers != null && issuers.length != 0) {
                    byte[][] issuersBytes;
                    try {
                        issuersBytes = encodeIssuerX509Principals(issuers);
                    } catch (CertificateEncodingException e) {
                        throw new IOException("Problem encoding principals", e);
                    }
                    NativeCrypto.SSL_set_client_CA_list(sslNativePointer, issuersBytes);
                }
            }
        }
    }

    OpenSSLSessionImpl setupSession(long sslSessionNativePointer, long sslNativePointer,
            final OpenSSLSessionImpl sessionToReuse, String hostname, int port,
            boolean handshakeCompleted) throws IOException {
        OpenSSLSessionImpl sslSession = null;
        byte[] sessionId = NativeCrypto.SSL_SESSION_session_id(sslSessionNativePointer);
        if (sessionToReuse != null && Arrays.equals(sessionToReuse.getId(), sessionId)) {
            sslSession = sessionToReuse;
            sslSession.lastAccessedTime = System.currentTimeMillis();
            NativeCrypto.SSL_SESSION_free(sslSessionNativePointer);
        } else {
            if (!getEnableSessionCreation()) {
                // Should have been prevented by
                // NativeCrypto.SSL_set_session_creation_enabled
                throw new IllegalStateException("SSL Session may not be created");
            }
            X509Certificate[] localCertificates = createCertChain(NativeCrypto
                    .SSL_get_certificate(sslNativePointer));
            X509Certificate[] peerCertificates = createCertChain(NativeCrypto
                    .SSL_get_peer_cert_chain(sslNativePointer));
            sslSession = new OpenSSLSessionImpl(sslSessionNativePointer, localCertificates,
                    peerCertificates, hostname, port, getSessionContext());
            // if not, putSession later in handshakeCompleted() callback
            if (handshakeCompleted) {
                getSessionContext().putSession(sslSession);
            }
        }
        return sslSession;
    }

    void chooseClientCertificate(byte[] keyTypeBytes, byte[][] asn1DerEncodedPrincipals,
            long sslNativePointer, AliasChooser chooser) throws SSLException,
            CertificateEncodingException {
        String[] keyTypes = new String[keyTypeBytes.length];
        for (int i = 0; i < keyTypeBytes.length; i++) {
            keyTypes[i] = getClientKeyType(keyTypeBytes[i]);
        }

        X500Principal[] issuers;
        if (asn1DerEncodedPrincipals == null) {
            issuers = null;
        } else {
            issuers = new X500Principal[asn1DerEncodedPrincipals.length];
            for (int i = 0; i < asn1DerEncodedPrincipals.length; i++) {
                issuers[i] = new X500Principal(asn1DerEncodedPrincipals[i]);
            }
        }
        X509KeyManager keyManager = getX509KeyManager();
        String alias = (keyManager != null) ? chooser.chooseClientAlias(keyManager, issuers,
                keyTypes) : null;
        setCertificate(sslNativePointer, alias);
    }

    /**
     * @see NativeCrypto.SSLHandshakeCallbacks#clientPSKKeyRequested(String, byte[], byte[])
     */
    int clientPSKKeyRequested(
            String identityHint, byte[] identityBytesOut, byte[] key, PSKCallbacks pskCallbacks) {
        PSKKeyManager pskKeyManager = getPSKKeyManager();
        if (pskKeyManager == null) {
            return 0;
        }

        String identity = pskCallbacks.chooseClientPSKIdentity(pskKeyManager, identityHint);
        // Store identity in NULL-terminated modified UTF-8 representation into ientityBytesOut
        byte[] identityBytes;
        if (identity == null) {
            identity = "";
            identityBytes = EmptyArray.BYTE;
        } else if (identity.isEmpty()) {
            identityBytes = EmptyArray.BYTE;
        } else {
            try {
                identityBytes = identity.getBytes("UTF-8");
            } catch (UnsupportedEncodingException e) {
                throw new RuntimeException("UTF-8 encoding not supported", e);
            }
        }
        if (identityBytes.length + 1 > identityBytesOut.length) {
            // Insufficient space in the output buffer
            return 0;
        }
        if (identityBytes.length > 0) {
            System.arraycopy(identityBytes, 0, identityBytesOut, 0, identityBytes.length);
        }
        identityBytesOut[identityBytes.length] = 0;

        SecretKey secretKey = pskCallbacks.getPSKKey(pskKeyManager, identityHint, identity);
        byte[] secretKeyBytes = secretKey.getEncoded();
        if (secretKeyBytes == null) {
            return 0;
        } else if (secretKeyBytes.length > key.length) {
            // Insufficient space in the output buffer
            return 0;
        }
        System.arraycopy(secretKeyBytes, 0, key, 0, secretKeyBytes.length);
        return secretKeyBytes.length;
    }

    /**
     * @see NativeCrypto.SSLHandshakeCallbacks#serverPSKKeyRequested(String, String, byte[])
     */
    int serverPSKKeyRequested(
            String identityHint, String identity, byte[] key, PSKCallbacks pskCallbacks) {
        PSKKeyManager pskKeyManager = getPSKKeyManager();
        if (pskKeyManager == null) {
            return 0;
        }
        SecretKey secretKey = pskCallbacks.getPSKKey(pskKeyManager, identityHint, identity);
        byte[] secretKeyBytes = secretKey.getEncoded();
        if (secretKeyBytes == null) {
            return 0;
        } else if (secretKeyBytes.length > key.length) {
            return 0;
        }
        System.arraycopy(secretKeyBytes, 0, key, 0, secretKeyBytes.length);
        return secretKeyBytes.length;
    }

    /**
     * Gets the suitable session reference from the session cache container.
     */
    OpenSSLSessionImpl getCachedClientSession(ClientSessionContext sessionContext, String hostName,
            int port) {
        if (hostName == null) {
            return null;
        }
        OpenSSLSessionImpl session = (OpenSSLSessionImpl) sessionContext.getSession(hostName, port);
        if (session == null) {
            return null;
        }

        String protocol = session.getProtocol();
        boolean protocolFound = false;
        for (String enabledProtocol : enabledProtocols) {
            if (protocol.equals(enabledProtocol)) {
                protocolFound = true;
                break;
            }
        }
        if (!protocolFound) {
            return null;
        }

        String cipherSuite = session.getCipherSuite();
        boolean cipherSuiteFound = false;
        for (String enabledCipherSuite : enabledCipherSuites) {
            if (cipherSuite.equals(enabledCipherSuite)) {
                cipherSuiteFound = true;
                break;
            }
        }
        if (!cipherSuiteFound) {
            return null;
        }

        return session;
    }

    /**
     * For abstracting the X509KeyManager calls between
     * {@link X509KeyManager#chooseClientAlias(String[], java.security.Principal[], java.net.Socket)}
     * and
     * {@link X509ExtendedKeyManager#chooseEngineClientAlias(String[], java.security.Principal[], javax.net.ssl.SSLEngine)}
     */
    public interface AliasChooser {
        String chooseClientAlias(X509KeyManager keyManager, X500Principal[] issuers,
                String[] keyTypes);

        String chooseServerAlias(X509KeyManager keyManager, String keyType);
    }

    /**
     * For abstracting the {@code PSKKeyManager} calls between those taking an {@code SSLSocket} and
     * those taking an {@code SSLEngine}.
     */
    public interface PSKCallbacks {
        String chooseServerPSKIdentityHint(PSKKeyManager keyManager);
        String chooseClientPSKIdentity(PSKKeyManager keyManager, String identityHint);
        SecretKey getPSKKey(PSKKeyManager keyManager, String identityHint, String identity);
    }

    /**
     * Returns the clone of this object.
     * @return the clone.
     */
    @Override
    protected Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError(e);
        }
    }

    private static X509KeyManager getDefaultX509KeyManager() throws KeyManagementException {
        X509KeyManager result = defaultX509KeyManager;
        if (result == null) {
            // single-check idiom
            defaultX509KeyManager = result = createDefaultX509KeyManager();
        }
        return result;
    }
    private static X509KeyManager createDefaultX509KeyManager() throws KeyManagementException {
        try {
            String algorithm = KeyManagerFactory.getDefaultAlgorithm();
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm);
            kmf.init(null, null);
            KeyManager[] kms = kmf.getKeyManagers();
            X509KeyManager result = findFirstX509KeyManager(kms);
            if (result == null) {
                throw new KeyManagementException("No X509KeyManager among default KeyManagers: "
                        + Arrays.toString(kms));
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            throw new KeyManagementException(e);
        } catch (KeyStoreException e) {
            throw new KeyManagementException(e);
        } catch (UnrecoverableKeyException e) {
            throw new KeyManagementException(e);
        }
    }

    /**
     * Finds the first {@link X509KeyManager} element in the provided array.
     *
     * @return the first {@code X509KeyManager} or {@code null} if not found.
     */
    private static X509KeyManager findFirstX509KeyManager(KeyManager[] kms) {
        for (KeyManager km : kms) {
            if (km instanceof X509KeyManager) {
                return (X509KeyManager)km;
            }
        }
        return null;
    }

    /**
     * Finds the first {@link PSKKeyManager} element in the provided array.
     *
     * @return the first {@code PSKKeyManager} or {@code null} if not found.
     */
    private static PSKKeyManager findFirstPSKKeyManager(KeyManager[] kms) {
        for (KeyManager km : kms) {
            if (km instanceof PSKKeyManager) {
                return (PSKKeyManager)km;
            }
        }
        return null;
    }

    /**
     * Gets the default X.509 trust manager.
     *
     * TODO: Move this to a published API under dalvik.system.
     */
    public static X509TrustManager getDefaultX509TrustManager()
            throws KeyManagementException {
        X509TrustManager result = defaultX509TrustManager;
        if (result == null) {
            // single-check idiom
            defaultX509TrustManager = result = createDefaultX509TrustManager();
        }
        return result;
    }

    private static X509TrustManager createDefaultX509TrustManager()
            throws KeyManagementException {
        try {
            String algorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
            tmf.init((KeyStore) null);
            TrustManager[] tms = tmf.getTrustManagers();
            X509TrustManager trustManager = findFirstX509TrustManager(tms);
            if (trustManager == null) {
                throw new KeyManagementException(
                        "No X509TrustManager in among default TrustManagers: "
                                + Arrays.toString(tms));
            }
            return trustManager;
        } catch (NoSuchAlgorithmException e) {
            throw new KeyManagementException(e);
        } catch (KeyStoreException e) {
            throw new KeyManagementException(e);
        }
    }

    /**
     * Finds the first {@link X509TrustManager} element in the provided array.
     *
     * @return the first {@code X509TrustManager} or {@code null} if not found.
     */
    private static X509TrustManager findFirstX509TrustManager(TrustManager[] tms) {
        for (TrustManager tm : tms) {
            if (tm instanceof X509TrustManager) {
                return (X509TrustManager) tm;
            }
        }
        return null;
    }

    public String getEndpointIdentificationAlgorithm() {
        return endpointIdentificationAlgorithm;
    }

    public void setEndpointIdentificationAlgorithm(String endpointIdentificationAlgorithm) {
        this.endpointIdentificationAlgorithm = endpointIdentificationAlgorithm;
    }

    /** Key type: RSA. */
    private static final String KEY_TYPE_RSA = "RSA";

    /** Key type: DSA. */
    private static final String KEY_TYPE_DSA = "DSA";

    /** Key type: Diffie-Hellman with RSA signature. */
    private static final String KEY_TYPE_DH_RSA = "DH_RSA";

    /** Key type: Diffie-Hellman with DSA signature. */
    private static final String KEY_TYPE_DH_DSA = "DH_DSA";

    /** Key type: Elliptic Curve. */
    private static final String KEY_TYPE_EC = "EC";

    /** Key type: Eliiptic Curve with ECDSA signature. */
    private static final String KEY_TYPE_EC_EC = "EC_EC";

    /** Key type: Eliiptic Curve with RSA signature. */
    private static final String KEY_TYPE_EC_RSA = "EC_RSA";

    /**
     * Returns key type constant suitable for calling X509KeyManager.chooseServerAlias or
     * X509ExtendedKeyManager.chooseEngineServerAlias. Returns {@code null} for key exchanges that
     * do not use X.509 for server authentication.
     */
    private static String getServerX509KeyType(long sslCipherNative) throws SSLException {
        int algorithm_mkey = NativeCrypto.get_SSL_CIPHER_algorithm_mkey(sslCipherNative);
        int algorithm_auth = NativeCrypto.get_SSL_CIPHER_algorithm_auth(sslCipherNative);
        switch (algorithm_mkey) {
            case NativeCrypto.SSL_kRSA:
                return KEY_TYPE_RSA;
            case NativeCrypto.SSL_kEDH:
                switch (algorithm_auth) {
                    case NativeCrypto.SSL_aDSS:
                        return KEY_TYPE_DSA;
                    case NativeCrypto.SSL_aRSA:
                        return KEY_TYPE_RSA;
                    case NativeCrypto.SSL_aNULL:
                        return null;
                }
                break;
            case NativeCrypto.SSL_kECDHr:
                return KEY_TYPE_EC_RSA;
            case NativeCrypto.SSL_kECDHe:
                return KEY_TYPE_EC_EC;
            case NativeCrypto.SSL_kEECDH:
                switch (algorithm_auth) {
                    case NativeCrypto.SSL_aECDSA:
                        return KEY_TYPE_EC_EC;
                    case NativeCrypto.SSL_aRSA:
                        return KEY_TYPE_RSA;
                    case NativeCrypto.SSL_aPSK:
                        return null;
                    case NativeCrypto.SSL_aNULL:
                        return null;
                }
                break;
            case NativeCrypto.SSL_kPSK:
                return null;
        }

        throw new SSLException("Unsupported key exchange. "
                + "mkey: 0x" + Long.toHexString(algorithm_mkey & 0xffffffffL)
                + ", auth: 0x" + Long.toHexString(algorithm_auth & 0xffffffffL));
    }

    /**
     * Similar to getServerKeyType, but returns value given TLS
     * ClientCertificateType byte values from a CertificateRequest
     * message for use with X509KeyManager.chooseClientAlias or
     * X509ExtendedKeyManager.chooseEngineClientAlias.
     */
    public static String getClientKeyType(byte keyType) {
        // See also http://www.ietf.org/assignments/tls-parameters/tls-parameters.xml
        switch (keyType) {
            case NativeCrypto.TLS_CT_RSA_SIGN:
                return KEY_TYPE_RSA; // RFC rsa_sign
            case NativeCrypto.TLS_CT_DSS_SIGN:
                return KEY_TYPE_DSA; // RFC dss_sign
            case NativeCrypto.TLS_CT_RSA_FIXED_DH:
                return KEY_TYPE_DH_RSA; // RFC rsa_fixed_dh
            case NativeCrypto.TLS_CT_DSS_FIXED_DH:
                return KEY_TYPE_DH_DSA; // RFC dss_fixed_dh
            case NativeCrypto.TLS_CT_ECDSA_SIGN:
                return KEY_TYPE_EC; // RFC ecdsa_sign
            case NativeCrypto.TLS_CT_RSA_FIXED_ECDH:
                return KEY_TYPE_EC_RSA; // RFC rsa_fixed_ecdh
            case NativeCrypto.TLS_CT_ECDSA_FIXED_ECDH:
                return KEY_TYPE_EC_EC; // RFC ecdsa_fixed_ecdh
            default:
                return null;
        }
    }

    private static String[] getDefaultCipherSuites(
            boolean x509CipherSuitesNeeded,
            boolean pskCipherSuitesNeeded) {
        if (x509CipherSuitesNeeded) {
            // X.509 based cipher suites need to be listed.
            if (pskCipherSuitesNeeded) {
                // Both X.509 and PSK based cipher suites need to be listed. Because TLS-PSK is not
                // normally used, we assume that when PSK cipher suites are requested here they
                // should be preferred over other cipher suites. Thus, we give PSK cipher suites
                // higher priority than X.509 cipher suites.
                // NOTE: There are cipher suites that use both X.509 and PSK (e.g., those based on
                // RSA_PSK key exchange). However, these cipher suites are not currently supported.
                return concat(
                        NativeCrypto.DEFAULT_PSK_CIPHER_SUITES,
                        NativeCrypto.DEFAULT_X509_CIPHER_SUITES,
                        new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV});
            } else {
                // Only X.509 cipher suites need to be listed.
                return concat(
                        NativeCrypto.DEFAULT_X509_CIPHER_SUITES,
                        new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV});
            }
        } else if (pskCipherSuitesNeeded) {
            // Only PSK cipher suites need to be listed.
            return concat(
                    NativeCrypto.DEFAULT_PSK_CIPHER_SUITES,
                    new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV});
        } else {
            // Neither X.509 nor PSK cipher suites need to be listed.
            return new String[] {NativeCrypto.TLS_EMPTY_RENEGOTIATION_INFO_SCSV};
        }
    }

    private static String[] getDefaultProtocols() {
        return NativeCrypto.DEFAULT_PROTOCOLS.clone();
    }

    private static String[] concat(String[]... arrays) {
        int resultLength = 0;
        for (String[] array : arrays) {
            resultLength += array.length;
        }
        String[] result = new String[resultLength];
        int resultOffset = 0;
        for (String[] array : arrays) {
            System.arraycopy(array, 0, result, resultOffset, array.length);
            resultOffset += array.length;
        }
        return result;
    }
}
