/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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 java.io.FileDescriptor;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.nio.Buffer;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SignatureException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateParsingException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.net.ssl.SSLException;
import javax.security.auth.x500.X500Principal;

/**
 * Provides the Java side of our JNI glue for OpenSSL.
 */
public final class NativeCrypto {

    public static final boolean isBoringSSL;

    // --- OpenSSL library initialization --------------------------------------
    static {
        NativeCryptoJni.init();
        isBoringSSL = clinit();
    }

    private native static boolean clinit();

    // --- ENGINE functions ----------------------------------------------------
    public static native void ENGINE_load_dynamic();

    public static native long ENGINE_by_id(String id);

    public static native int ENGINE_add(long e);

    public static native int ENGINE_init(long e);

    public static native int ENGINE_finish(long e);

    public static native int ENGINE_free(long e);

    public static native long ENGINE_load_private_key(long e, String key_id) throws InvalidKeyException;

    public static native String ENGINE_get_id(long engineRef);

    public static native int ENGINE_ctrl_cmd_string(long engineRef, String cmd, String arg,
            int cmd_optional);

    // --- DSA/RSA public/private key handling functions -----------------------

    public static native long EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
                                               byte[] pub_key, byte[] priv_key);

    public static native long EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
            byte[] dmp1, byte[] dmq1, byte[] iqmp);

    public static native int EVP_PKEY_size(NativeRef.EVP_PKEY pkey);

    public static native int EVP_PKEY_type(NativeRef.EVP_PKEY pkey);

    public static native String EVP_PKEY_print_public(NativeRef.EVP_PKEY pkeyRef);

    public static native String EVP_PKEY_print_params(NativeRef.EVP_PKEY pkeyRef);

    public static native void EVP_PKEY_free(long pkey);

    public static native int EVP_PKEY_cmp(NativeRef.EVP_PKEY pkey1, NativeRef.EVP_PKEY pkey2);

    public static native byte[] i2d_PKCS8_PRIV_KEY_INFO(NativeRef.EVP_PKEY pkey);

    public static native long d2i_PKCS8_PRIV_KEY_INFO(byte[] data);

    public static native byte[] i2d_PUBKEY(NativeRef.EVP_PKEY pkey);

    public static native long d2i_PUBKEY(byte[] data);

    public static native long PEM_read_bio_PUBKEY(long bioCtx);

    public static native long PEM_read_bio_PrivateKey(long bioCtx);

    public static native long getRSAPrivateKeyWrapper(PrivateKey key, byte[] modulus);

    public static native long getECPrivateKeyWrapper(PrivateKey key,
            NativeRef.EC_GROUP ecGroupRef);

    public static native long RSA_generate_key_ex(int modulusBits, byte[] publicExponent);

    public static native int RSA_size(NativeRef.EVP_PKEY pkey);

    public static native int RSA_private_encrypt(int flen, byte[] from, byte[] to,
            NativeRef.EVP_PKEY pkey, int padding);

    public static native int RSA_public_decrypt(int flen, byte[] from, byte[] to,
            NativeRef.EVP_PKEY pkey, int padding) throws BadPaddingException, SignatureException;

    public static native int RSA_public_encrypt(int flen, byte[] from, byte[] to,
            NativeRef.EVP_PKEY pkey, int padding);

    public static native int RSA_private_decrypt(int flen, byte[] from, byte[] to,
            NativeRef.EVP_PKEY pkey, int padding) throws BadPaddingException, SignatureException;

    /**
     * @return array of {n, e}
     */
    public static native byte[][] get_RSA_public_params(NativeRef.EVP_PKEY rsa);

    /**
     * @return array of {n, e, d, p, q, dmp1, dmq1, iqmp}
     */
    public static native byte[][] get_RSA_private_params(NativeRef.EVP_PKEY rsa);

    public static native byte[] i2d_RSAPublicKey(NativeRef.EVP_PKEY rsa);

    public static native byte[] i2d_RSAPrivateKey(NativeRef.EVP_PKEY rsa);

    // --- EC functions --------------------------

    /**
     * Used to request EC_GROUP_new_curve_GFp to EC_GROUP_new_curve
     */
    public static final int EC_CURVE_GFP = 1;

    /**
     * Used to request EC_GROUP_new_curve_GF2m to EC_GROUP_new_curve
     */
    public static final int EC_CURVE_GF2M = 2;

    public static native long EVP_PKEY_new_EC_KEY(NativeRef.EC_GROUP groupRef,
            NativeRef.EC_POINT pubkeyRef, byte[] privkey);

    public static native long EC_GROUP_new_by_curve_name(String curveName);

    public static native long EC_GROUP_new_arbitrary(byte[] p, byte[] a, byte[] b, byte[] x,
                                                     byte[] y, byte[] order, int cofactor);

    public static native void EC_GROUP_set_asn1_flag(NativeRef.EC_GROUP groupRef, int flag);

    public static native void EC_GROUP_set_point_conversion_form(NativeRef.EC_GROUP groupRef,
            int form);

    public static native String EC_GROUP_get_curve_name(NativeRef.EC_GROUP groupRef);

    public static native byte[][] EC_GROUP_get_curve(NativeRef.EC_GROUP groupRef);

    public static native void EC_GROUP_clear_free(long groupRef);

    public static native long EC_GROUP_get_generator(NativeRef.EC_GROUP groupRef);

    public static native int get_EC_GROUP_type(NativeRef.EC_GROUP groupRef);

    public static native byte[] EC_GROUP_get_order(NativeRef.EC_GROUP groupRef);

    public static native int EC_GROUP_get_degree(NativeRef.EC_GROUP groupRef);

    public static native byte[] EC_GROUP_get_cofactor(NativeRef.EC_GROUP groupRef);

    public static native long EC_POINT_new(NativeRef.EC_GROUP groupRef);

    public static native void EC_POINT_clear_free(long pointRef);

    public static native byte[][] EC_POINT_get_affine_coordinates(NativeRef.EC_GROUP groupRef,
            NativeRef.EC_POINT pointRef);

    public static native void EC_POINT_set_affine_coordinates(NativeRef.EC_GROUP groupRef,
            NativeRef.EC_POINT pointRef, byte[] x, byte[] y);

    public static native long EC_KEY_generate_key(NativeRef.EC_GROUP groupRef);

    public static native long EC_KEY_get1_group(NativeRef.EVP_PKEY pkeyRef);

    public static native byte[] EC_KEY_get_private_key(NativeRef.EVP_PKEY keyRef);

    public static native long EC_KEY_get_public_key(NativeRef.EVP_PKEY keyRef);

    public static native void EC_KEY_set_nonce_from_hash(NativeRef.EVP_PKEY keyRef,
            boolean enabled);

    public static native int ECDH_compute_key(byte[] out, int outOffset,
            NativeRef.EVP_PKEY publicKeyRef, NativeRef.EVP_PKEY privateKeyRef) throws
            InvalidKeyException;

    // --- Message digest functions --------------

    // These return const references
    public static native long EVP_get_digestbyname(String name);

    public static native int EVP_MD_size(long evp_md_const);

    public static native int EVP_MD_block_size(long evp_md_const);

    // --- Message digest context functions --------------

    public static native long EVP_MD_CTX_create();

    public static native void EVP_MD_CTX_cleanup(NativeRef.EVP_MD_CTX ctx);

    public static native void EVP_MD_CTX_destroy(long ctx);

    public static native int EVP_MD_CTX_copy_ex(NativeRef.EVP_MD_CTX dst_ctx,
            NativeRef.EVP_MD_CTX src_ctx);

    // --- Digest handling functions -------------------------------------------

    public static native int EVP_DigestInit_ex(NativeRef.EVP_MD_CTX ctx, long evp_md);

    public static native void EVP_DigestUpdate(NativeRef.EVP_MD_CTX ctx,
            byte[] buffer, int offset, int length);

    public static native void EVP_DigestUpdateDirect(NativeRef.EVP_MD_CTX ctx,
            long ptr, int length);

    public static native int EVP_DigestFinal_ex(NativeRef.EVP_MD_CTX ctx, byte[] hash,
            int offset);

    // --- Signature handling functions ----------------------------------------

    public static native long EVP_DigestSignInit(NativeRef.EVP_MD_CTX ctx,
            long evpMdRef, NativeRef.EVP_PKEY key);

    public static native long EVP_DigestVerifyInit(NativeRef.EVP_MD_CTX ctx,
            long evpMdRef, NativeRef.EVP_PKEY key);

    public static native void EVP_DigestSignUpdate(NativeRef.EVP_MD_CTX ctx,
            byte[] buffer, int offset, int length);

    public static native void EVP_DigestSignUpdateDirect(NativeRef.EVP_MD_CTX ctx,
            long ptr, int length);

    public static native void EVP_DigestVerifyUpdate(NativeRef.EVP_MD_CTX ctx,
            byte[] buffer, int offset, int length);

    public static native void EVP_DigestVerifyUpdateDirect(NativeRef.EVP_MD_CTX ctx,
            long ptr, int length);

    public static native byte[] EVP_DigestSignFinal(NativeRef.EVP_MD_CTX ctx);

    public static native boolean EVP_DigestVerifyFinal(NativeRef.EVP_MD_CTX ctx,
            byte[] signature, int offset, int length);

    public static native void EVP_PKEY_CTX_set_rsa_padding(long ctx, int pad);

    public static native void EVP_PKEY_CTX_set_rsa_pss_saltlen(long ctx, int len);

    public static native void EVP_PKEY_CTX_set_rsa_mgf1_md(long ctx, long evpMdRef);

    // --- Block ciphers -------------------------------------------------------

    // These return const references
    public static native long EVP_get_cipherbyname(String string);

    public static native void EVP_CipherInit_ex(NativeRef.EVP_CIPHER_CTX ctx, long evpCipher,
            byte[] key, byte[] iv, boolean encrypting);

    public static native int EVP_CipherUpdate(NativeRef.EVP_CIPHER_CTX ctx, byte[] out,
            int outOffset, byte[] in, int inOffset, int inLength);

    public static native int EVP_CipherFinal_ex(NativeRef.EVP_CIPHER_CTX ctx, byte[] out,
            int outOffset) throws BadPaddingException, IllegalBlockSizeException;

    public static native int EVP_CIPHER_iv_length(long evpCipher);

    public static native long EVP_CIPHER_CTX_new();

    public static native int EVP_CIPHER_CTX_block_size(NativeRef.EVP_CIPHER_CTX ctx);

    public static native int get_EVP_CIPHER_CTX_buf_len(NativeRef.EVP_CIPHER_CTX ctx);

    public static native boolean get_EVP_CIPHER_CTX_final_used(NativeRef.EVP_CIPHER_CTX ctx);

    public static native void EVP_CIPHER_CTX_set_padding(NativeRef.EVP_CIPHER_CTX ctx,
            boolean enablePadding);

    public static native void EVP_CIPHER_CTX_set_key_length(NativeRef.EVP_CIPHER_CTX ctx,
            int keyBitSize);

    public static native void EVP_CIPHER_CTX_free(long ctx);

    // --- AEAD ----------------------------------------------------------------
    public static native long EVP_aead_aes_128_gcm();

    public static native long EVP_aead_aes_256_gcm();

    public static native long EVP_AEAD_CTX_init(long evpAead, byte[] key, int tagLen);

    public static native void EVP_AEAD_CTX_cleanup(long ctx);

    public static native int EVP_AEAD_max_overhead(long evpAead);

    public static native int EVP_AEAD_nonce_length(long evpAead);

    public static native int EVP_AEAD_max_tag_len(long evpAead);

    public static native int EVP_AEAD_CTX_seal(NativeRef.EVP_AEAD_CTX ctx, byte[] out,
            int outOffset, byte[] nonce, byte[] in, int inOffset, int inLength, byte[] ad)
            throws BadPaddingException;

    public static native int EVP_AEAD_CTX_open(NativeRef.EVP_AEAD_CTX ctx, byte[] out,
            int outOffset, byte[] nonce, byte[] in, int inOffset, int inLength, byte[] ad)
            throws BadPaddingException;

    // --- HMAC functions ------------------------------------------------------

    public static native long HMAC_CTX_new();

    public static native void HMAC_CTX_free(long ctx);

    public static native void HMAC_Init_ex(NativeRef.HMAC_CTX ctx, byte[] key, long evp_md);

    public static native void HMAC_Update(NativeRef.HMAC_CTX ctx, byte[] in, int inOffset, int inLength);

    public static native void HMAC_UpdateDirect(NativeRef.HMAC_CTX ctx, long inPtr, int inLength);

    public static native byte[] HMAC_Final(NativeRef.HMAC_CTX ctx);

    // --- RAND seeding --------------------------------------------------------

    public static final int RAND_SEED_LENGTH_IN_BYTES = 1024;

    public static native void RAND_seed(byte[] seed);

    public static native int RAND_load_file(String filename, long max_bytes);

    public static native void RAND_bytes(byte[] output);

    // --- ASN.1 objects -------------------------------------------------------

    public static native int OBJ_txt2nid(String oid);

    public static native String OBJ_txt2nid_longName(String oid);

    public static native String OBJ_txt2nid_oid(String oid);

    // --- X509_NAME -----------------------------------------------------------

    public static int X509_NAME_hash(X500Principal principal) {
        return X509_NAME_hash(principal, "SHA1");
    }
    public static int X509_NAME_hash_old(X500Principal principal) {
        return X509_NAME_hash(principal, "MD5");
    }
    private static int X509_NAME_hash(X500Principal principal, String algorithm) {
        try {
            byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
            int offset = 0;
            return (((digest[offset++] & 0xff) <<  0) |
                    ((digest[offset++] & 0xff) <<  8) |
                    ((digest[offset++] & 0xff) << 16) |
                    ((digest[offset  ] & 0xff) << 24));
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }

    public static native String X509_NAME_print_ex(long x509nameCtx, long flags);

    // --- X509 ----------------------------------------------------------------

    /** Used to request get_X509_GENERAL_NAME_stack get the "altname" field. */
    public static final int GN_STACK_SUBJECT_ALT_NAME = 1;

    /**
     * Used to request get_X509_GENERAL_NAME_stack get the issuerAlternativeName
     * extension.
     */
    public static final int GN_STACK_ISSUER_ALT_NAME = 2;

    /**
     * Used to request only non-critical types in get_X509*_ext_oids.
     */
    public static final int EXTENSION_TYPE_NON_CRITICAL = 0;

    /**
     * Used to request only critical types in get_X509*_ext_oids.
     */
    public static final int EXTENSION_TYPE_CRITICAL = 1;

    public static native long d2i_X509_bio(long bioCtx);

    public static native long d2i_X509(byte[] encoded);

    public static native long PEM_read_bio_X509(long bioCtx);

    public static native byte[] i2d_X509(long x509ctx);

    /** Takes an X509 context not an X509_PUBKEY context. */
    public static native byte[] i2d_X509_PUBKEY(long x509ctx);

    public static native byte[] ASN1_seq_pack_X509(long[] x509CertRefs);

    public static native long[] ASN1_seq_unpack_X509_bio(long bioRef);

    public static native void X509_free(long x509ctx);

    public static native long X509_dup(long x509ctx);

    public static native int X509_cmp(long x509ctx1, long x509ctx2);

    public static native int get_X509_hashCode(long x509ctx);

    public static native void X509_print_ex(long bioCtx, long x509ctx, long nmflag, long certflag);

    public static native byte[] X509_get_issuer_name(long x509ctx);

    public static native byte[] X509_get_subject_name(long x509ctx);

    public static native String get_X509_sig_alg_oid(long x509ctx);

    public static native byte[] get_X509_sig_alg_parameter(long x509ctx);

    public static native boolean[] get_X509_issuerUID(long x509ctx);

    public static native boolean[] get_X509_subjectUID(long x509ctx);

    public static native long X509_get_pubkey(long x509ctx) throws NoSuchAlgorithmException;

    public static native String get_X509_pubkey_oid(long x509ctx);

    public static native byte[] X509_get_ext_oid(long x509ctx, String oid);

    public static native String[] get_X509_ext_oids(long x509ctx, int critical);

    public static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx, int type)
            throws CertificateParsingException;

    public static native boolean[] get_X509_ex_kusage(long x509ctx);

    public static native String[] get_X509_ex_xkusage(long x509ctx);

    public static native int get_X509_ex_pathlen(long x509ctx);

    public static native long X509_get_notBefore(long x509ctx);

    public static native long X509_get_notAfter(long x509ctx);

    public static native long X509_get_version(long x509ctx);

    public static native byte[] X509_get_serialNumber(long x509ctx);

    public static native void X509_verify(long x509ctx, NativeRef.EVP_PKEY pkeyCtx)
            throws BadPaddingException;

    public static native byte[] get_X509_cert_info_enc(long x509ctx);

    public static native byte[] get_X509_signature(long x509ctx);

    public static native int get_X509_ex_flags(long x509ctx);

    public static native int X509_check_issued(long ctx, long ctx2);

    // --- PKCS7 ---------------------------------------------------------------

    /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
    public static final int PKCS7_CERTS = 1;

    /** Used as the "which" field in d2i_PKCS7_bio and PEM_read_bio_PKCS7. */
    public static final int PKCS7_CRLS = 2;

    /** Returns an array of X509 or X509_CRL pointers. */
    public static native long[] d2i_PKCS7_bio(long bioCtx, int which);

    /** Returns an array of X509 or X509_CRL pointers. */
    public static native byte[] i2d_PKCS7(long[] certs);

    /** Returns an array of X509 or X509_CRL pointers. */
    public static native long[] PEM_read_bio_PKCS7(long bioCtx, int which);

    // --- X509_CRL ------------------------------------------------------------

    public static native long d2i_X509_CRL_bio(long bioCtx);

    public static native long PEM_read_bio_X509_CRL(long bioCtx);

    public static native byte[] i2d_X509_CRL(long x509CrlCtx);

    public static native void X509_CRL_free(long x509CrlCtx);

    public static native void X509_CRL_print(long bioCtx, long x509CrlCtx);

    public static native String get_X509_CRL_sig_alg_oid(long x509CrlCtx);

    public static native byte[] get_X509_CRL_sig_alg_parameter(long x509CrlCtx);

    public static native byte[] X509_CRL_get_issuer_name(long x509CrlCtx);

    /** Returns X509_REVOKED reference that is not duplicated! */
    public static native long X509_CRL_get0_by_cert(long x509CrlCtx, long x509Ctx);

    /** Returns X509_REVOKED reference that is not duplicated! */
    public static native long X509_CRL_get0_by_serial(long x509CrlCtx, byte[] serial);

    /** Returns an array of X509_REVOKED that are owned by the caller. */
    public static native long[] X509_CRL_get_REVOKED(long x509CrlCtx);

    public static native String[] get_X509_CRL_ext_oids(long x509ctx, int critical);

    public static native byte[] X509_CRL_get_ext_oid(long x509CrlCtx, String oid);

    public static native void X509_delete_ext(long x509, String oid);

    public static native long X509_CRL_get_version(long x509CrlCtx);

    public static native long X509_CRL_get_ext(long x509CrlCtx, String oid);

    public static native byte[] get_X509_CRL_signature(long x509ctx);

    public static native void X509_CRL_verify(long x509CrlCtx, NativeRef.EVP_PKEY pkeyCtx);

    public static native byte[] get_X509_CRL_crl_enc(long x509CrlCtx);

    public static native long X509_CRL_get_lastUpdate(long x509CrlCtx);

    public static native long X509_CRL_get_nextUpdate(long x509CrlCtx);

    // --- X509_REVOKED --------------------------------------------------------

    public static native long X509_REVOKED_dup(long x509RevokedCtx);

    public static native byte[] i2d_X509_REVOKED(long x509RevokedCtx);

    public static native String[] get_X509_REVOKED_ext_oids(long x509ctx, int critical);

    public static native byte[] X509_REVOKED_get_ext_oid(long x509RevokedCtx, String oid);

    public static native byte[] X509_REVOKED_get_serialNumber(long x509RevokedCtx);

    public static native long X509_REVOKED_get_ext(long x509RevokedCtx, String oid);

    /** Returns ASN1_TIME reference. */
    public static native long get_X509_REVOKED_revocationDate(long x509RevokedCtx);

    public static native void X509_REVOKED_print(long bioRef, long x509RevokedCtx);

    // --- X509_EXTENSION ------------------------------------------------------

    public static native int X509_supported_extension(long x509ExtensionRef);

    // --- ASN1_TIME -----------------------------------------------------------

    public static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal);

    // --- BIO stream creation -------------------------------------------------

    public static native long create_BIO_InputStream(OpenSSLBIOInputStream is, boolean isFinite);

    public static native long create_BIO_OutputStream(OutputStream os);

    public static native int BIO_read(long bioRef, byte[] buffer);

    public static native void BIO_write(long bioRef, byte[] buffer, int offset, int length)
            throws IOException;

    public static native void BIO_free_all(long bioRef);

    // --- SSL handling --------------------------------------------------------

    private static final String SUPPORTED_PROTOCOL_SSLV3 = "SSLv3";
    private static final String SUPPORTED_PROTOCOL_TLSV1 = "TLSv1";
    private static final String SUPPORTED_PROTOCOL_TLSV1_1 = "TLSv1.1";
    private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";

    // STANDARD_TO_OPENSSL_CIPHER_SUITES is a map from OpenSSL-style
    // cipher-suite names to the standard name for the same (i.e. the name that
    // is registered with IANA).
    public static final Map<String, String> OPENSSL_TO_STANDARD_CIPHER_SUITES
            = new HashMap<String, String>();

    // STANDARD_TO_OPENSSL_CIPHER_SUITES is a map from "standard" cipher suite
    // names (i.e. the names that are registered with IANA) to the
    // OpenSSL-style name for the same.
    public static final Map<String, String> STANDARD_TO_OPENSSL_CIPHER_SUITES
            = new LinkedHashMap<String, String>();

    // SUPPORTED_CIPHER_SUITES_SET contains all the cipher suites supported by
    // OpenSSL, named using "standard" (as opposed to OpenSSL-style) names.
    public static final Set<String> SUPPORTED_CIPHER_SUITES_SET = new HashSet<String>();

    private static void add(String openssl, String standard) {
        OPENSSL_TO_STANDARD_CIPHER_SUITES.put(openssl, standard);
        STANDARD_TO_OPENSSL_CIPHER_SUITES.put(standard, openssl);
    }

    /**
     * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation
     * indication signaling cipher suite value. It is not a real
     * cipher suite. It is just an indication in the default and
     * supported cipher suite lists indicates that the implementation
     * supports secure renegotiation.
     * <p>
     * In the RI, its presence means that the SCSV is sent in the
     * cipher suite list to indicate secure renegotiation support and
     * its absense means to send an empty TLS renegotiation info
     * extension instead.
     * <p>
     * However, OpenSSL doesn't provide an API to give this level of
     * control, instead always sending the SCSV and always including
     * the empty renegotiation info if TLS is used (as opposed to
     * SSL). So we simply allow TLS_EMPTY_RENEGOTIATION_INFO_SCSV to
     * be passed for compatibility as to provide the hint that we
     * support secure renegotiation.
     */
    public static final String TLS_EMPTY_RENEGOTIATION_INFO_SCSV
            = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";

    /**
     * TLS_FALLBACK_SCSV is from
     * https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
     * to indicate to the server that this is a fallback protocol
     * request.
     */
    public static final String TLS_FALLBACK_SCSV = "TLS_FALLBACK_SCSV";

    static {
        add("ADH-AES128-GCM-SHA256",		"TLS_DH_anon_WITH_AES_128_GCM_SHA256");
        add("ADH-AES128-SHA",			"TLS_DH_anon_WITH_AES_128_CBC_SHA");
        add("ADH-AES128-SHA256",		"TLS_DH_anon_WITH_AES_128_CBC_SHA256");
        add("ADH-AES256-GCM-SHA384",		"TLS_DH_anon_WITH_AES_256_GCM_SHA384");
        add("ADH-AES256-SHA",			"TLS_DH_anon_WITH_AES_256_CBC_SHA");
        add("ADH-AES256-SHA256",		"TLS_DH_anon_WITH_AES_256_CBC_SHA256");
        add("ADH-DES-CBC-SHA",			"SSL_DH_anon_WITH_DES_CBC_SHA");
        add("ADH-DES-CBC3-SHA",			"SSL_DH_anon_WITH_3DES_EDE_CBC_SHA");
        add("ADH-RC4-MD5",			"SSL_DH_anon_WITH_RC4_128_MD5");
        add("AECDH-AES128-SHA",			"TLS_ECDH_anon_WITH_AES_128_CBC_SHA");
        add("AECDH-AES256-SHA",			"TLS_ECDH_anon_WITH_AES_256_CBC_SHA");
        add("AECDH-DES-CBC3-SHA",		"TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA");
        add("AECDH-NULL-SHA",			"TLS_ECDH_anon_WITH_NULL_SHA");
        add("AECDH-RC4-SHA",			"TLS_ECDH_anon_WITH_RC4_128_SHA");
        add("AES128-GCM-SHA256",		"TLS_RSA_WITH_AES_128_GCM_SHA256");
        add("AES128-SHA",			"TLS_RSA_WITH_AES_128_CBC_SHA");
        add("AES128-SHA256",			"TLS_RSA_WITH_AES_128_CBC_SHA256");
        add("AES256-GCM-SHA384",		"TLS_RSA_WITH_AES_256_GCM_SHA384");
        add("AES256-SHA",			"TLS_RSA_WITH_AES_256_CBC_SHA");
        add("AES256-SHA256",			"TLS_RSA_WITH_AES_256_CBC_SHA256");
        add("DES-CBC-SHA",			"SSL_RSA_WITH_DES_CBC_SHA");
        add("DES-CBC3-SHA",			"SSL_RSA_WITH_3DES_EDE_CBC_SHA");
        add("DHE-RSA-AES128-GCM-SHA256",	"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256");
        add("DHE-RSA-AES128-SHA",		"TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
        add("DHE-RSA-AES128-SHA256",		"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256");
        add("DHE-RSA-AES256-GCM-SHA384",	"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384");
        add("DHE-RSA-AES256-SHA",		"TLS_DHE_RSA_WITH_AES_256_CBC_SHA");
        add("DHE-RSA-AES256-SHA256",		"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256");
        add("DHE-RSA-CHACHA20-POLY1305",	"TLS_DHE_RSA_WITH_CHACHA20_POLY1305");
        add("ECDH-ECDSA-AES128-GCM-SHA256",    	"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256");
        add("ECDH-ECDSA-AES128-SHA",		"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA");
        add("ECDH-ECDSA-AES128-SHA256",		"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256");
        add("ECDH-ECDSA-AES256-GCM-SHA384",    	"TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384");
        add("ECDH-ECDSA-AES256-SHA",		"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA");
        add("ECDH-ECDSA-AES256-SHA384",		"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384");
        add("ECDH-ECDSA-DES-CBC3-SHA",		"TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA");
        add("ECDH-ECDSA-NULL-SHA",		"TLS_ECDH_ECDSA_WITH_NULL_SHA");
        add("ECDH-ECDSA-RC4-SHA",		"TLS_ECDH_ECDSA_WITH_RC4_128_SHA");
        add("ECDH-RSA-AES128-GCM-SHA256",      	"TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256");
        add("ECDH-RSA-AES128-SHA",		"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA");
        add("ECDH-RSA-AES128-SHA256",		"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256");
        add("ECDH-RSA-AES256-GCM-SHA384",      	"TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384");
        add("ECDH-RSA-AES256-SHA",		"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA");
        add("ECDH-RSA-AES256-SHA384",		"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384");
        add("ECDH-RSA-DES-CBC3-SHA",		"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA");
        add("ECDH-RSA-NULL-SHA",		"TLS_ECDH_RSA_WITH_NULL_SHA");
        add("ECDH-RSA-RC4-SHA",			"TLS_ECDH_RSA_WITH_RC4_128_SHA");
        add("ECDHE-ECDSA-AES128-GCM-SHA256",   	"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
        add("ECDHE-ECDSA-AES128-SHA",		"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA");
        add("ECDHE-ECDSA-AES128-SHA256",	"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256");
        add("ECDHE-ECDSA-AES256-GCM-SHA384",   	"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384");
        add("ECDHE-ECDSA-AES256-SHA",		"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA");
        add("ECDHE-ECDSA-AES256-SHA384",	"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384");
        add("ECDHE-ECDSA-CHACHA20-POLY1305",   	"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305");
        add("ECDHE-ECDSA-DES-CBC3-SHA",		"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA");
        add("ECDHE-ECDSA-NULL-SHA",		"TLS_ECDHE_ECDSA_WITH_NULL_SHA");
        add("ECDHE-ECDSA-RC4-SHA",		"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA");
        add("ECDHE-PSK-AES128-CBC-SHA",		"TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA");
        add("ECDHE-PSK-AES128-GCM-SHA256",     	"TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256");
        add("ECDHE-PSK-AES256-CBC-SHA",		"TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA");
        add("ECDHE-PSK-AES256-GCM-SHA384",     	"TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384");
        add("ECDHE-RSA-AES128-GCM-SHA256",     	"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
        add("ECDHE-RSA-AES128-SHA",		"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA");
        add("ECDHE-RSA-AES128-SHA256",		"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256");
        add("ECDHE-RSA-AES256-GCM-SHA384",     	"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384");
        add("ECDHE-RSA-AES256-SHA",		"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA");
        add("ECDHE-RSA-AES256-SHA384",		"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384");
        add("ECDHE-RSA-CHACHA20-POLY1305",     	"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305");
        add("ECDHE-RSA-DES-CBC3-SHA",		"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA");
        add("ECDHE-RSA-NULL-SHA",		"TLS_ECDHE_RSA_WITH_NULL_SHA");
        add("ECDHE-RSA-RC4-SHA",		"TLS_ECDHE_RSA_WITH_RC4_128_SHA");
        add("EDH-RSA-DES-CBC-SHA",		"SSL_DHE_RSA_WITH_DES_CBC_SHA");
        add("EDH-RSA-DES-CBC3-SHA",		"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA");
        add("EXP-ADH-DES-CBC-SHA",		"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA");
        add("EXP-ADH-RC4-MD5",			"SSL_DH_anon_EXPORT_WITH_RC4_40_MD5");
        add("EXP-DES-CBC-SHA",			"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA");
        add("EXP-EDH-RSA-DES-CBC-SHA",		"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA");
        add("EXP-RC4-MD5",			"SSL_RSA_EXPORT_WITH_RC4_40_MD5");
        add("NULL-MD5",				"SSL_RSA_WITH_NULL_MD5");
        add("NULL-SHA",				"SSL_RSA_WITH_NULL_SHA");
        add("NULL-SHA256",			"TLS_RSA_WITH_NULL_SHA256");
        add("PSK-3DES-EDE-CBC-SHA",		"TLS_PSK_WITH_3DES_EDE_CBC_SHA");
        add("PSK-AES128-CBC-SHA",		"TLS_PSK_WITH_AES_128_CBC_SHA");
        add("PSK-AES256-CBC-SHA",		"TLS_PSK_WITH_AES_256_CBC_SHA");
        add("PSK-RC4-SHA",			"TLS_PSK_WITH_RC4_128_SHA");
        add("RC4-MD5",				"SSL_RSA_WITH_RC4_128_MD5");
        add("RC4-SHA",				"SSL_RSA_WITH_RC4_128_SHA");

        // Signaling Cipher Suite Value for secure renegotiation handled as special case.
        // add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV", null);

        // Similarly, the fallback SCSV is handled as a special case.
        // add("TLS_FALLBACK_SCSV", null);
    }

    private static final String[] SUPPORTED_CIPHER_SUITES;
    static {
        // Cipher selection string must work with OpenSSL and BoringSSL.
        String[] allOpenSSLCipherSuites = get_cipher_names("ALL:-EXP:-SRP:-SEED:-CAMELLIA:-DSS:-RC2:-DES-CBC-MD5:-DES-CBC3-MD5");

        int size = allOpenSSLCipherSuites.length;
        SUPPORTED_CIPHER_SUITES = new String[size + 2];
        for (int i = 0; i < size; i++) {
            String standardName = OPENSSL_TO_STANDARD_CIPHER_SUITES.get(allOpenSSLCipherSuites[i]);
            if (standardName == null) {
                throw new IllegalArgumentException("Unknown cipher suite supported by native code: " +
                                                   allOpenSSLCipherSuites[i]);
            }
            SUPPORTED_CIPHER_SUITES[i] = standardName;
            SUPPORTED_CIPHER_SUITES_SET.add(standardName);
        }
        SUPPORTED_CIPHER_SUITES[size] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
        SUPPORTED_CIPHER_SUITES[size + 1] = TLS_FALLBACK_SCSV;
    }

    public static native long SSL_CTX_new();

    // IMPLEMENTATION NOTE: The default list of cipher suites is a trade-off between what we'd like
    // to use and what servers currently support. We strive to be secure enough by default. We thus
    // avoid unacceptably weak suites (e.g., those with bulk cipher secret key shorter than 128
    // bits), while maintaining the capability to connect to the majority of servers.
    //
    // Cipher suites are listed in preference order (favorite choice first) of the client. However,
    // servers are not required to honor the order. The key rules governing the preference order
    // are:
    // * Prefer Forward Secrecy (i.e., cipher suites that use ECDHE and DHE for key agreement).
    // * Prefer AES-GCM to AES-CBC whose MAC-pad-then-encrypt approach leads to weaknesses (e.g.,
    //   Lucky 13).
    // * Prefer AES to RC4 whose foundations are a bit shaky. See http://www.isg.rhul.ac.uk/tls/.
    //   BEAST and Lucky13 mitigations are enabled.
    // * Prefer 128-bit bulk encryption to 256-bit one, because 128-bit is safe enough while
    //   consuming less CPU/time/energy.
    //
    // NOTE: Removing cipher suites from this list needs to be done with caution, because this may
    // prevent apps from connecting to servers they were previously able to connect to.

    /** X.509 based cipher suites enabled by default (if requested), in preference order. */
    static final String[] DEFAULT_X509_CIPHER_SUITES = new String[] {
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
        "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
        "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
        "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
        "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
        "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
        "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
        "TLS_RSA_WITH_AES_128_GCM_SHA256",
        "TLS_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_RSA_WITH_AES_128_CBC_SHA",
        "TLS_RSA_WITH_AES_256_CBC_SHA",
        "SSL_RSA_WITH_RC4_128_SHA",
    };

    /** TLS-PSK cipher suites enabled by default (if requested), in preference order. */
    static final String[] DEFAULT_PSK_CIPHER_SUITES = new String[] {
        "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
        "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA",
        "TLS_PSK_WITH_AES_128_CBC_SHA",
        "TLS_PSK_WITH_AES_256_CBC_SHA",
    };

    public static String[] getSupportedCipherSuites() {
        return SUPPORTED_CIPHER_SUITES.clone();
    }

    public static native void SSL_CTX_free(long ssl_ctx);

    public static native void SSL_CTX_set_session_id_context(long ssl_ctx, byte[] sid_ctx);

    public static native long SSL_new(long ssl_ctx) throws SSLException;

    public static native void SSL_enable_tls_channel_id(long ssl) throws SSLException;

    public static native byte[] SSL_get_tls_channel_id(long ssl) throws SSLException;

    public static native void SSL_set1_tls_channel_id(long ssl, NativeRef.EVP_PKEY pkey);

    public static native void SSL_use_certificate(long ssl, long[] x509refs);

    public static native void SSL_use_PrivateKey(long ssl, NativeRef.EVP_PKEY pkey);

    public static native void SSL_check_private_key(long ssl) throws SSLException;

    public static native void SSL_set_client_CA_list(long ssl, byte[][] asn1DerEncodedX500Principals);

    public static native long SSL_get_mode(long ssl);

    public static native long SSL_set_mode(long ssl, long mode);

    public static native long SSL_clear_mode(long ssl, long mode);

    public static native long SSL_get_options(long ssl);

    public static native long SSL_set_options(long ssl, long options);

    public static native long SSL_clear_options(long ssl, long options);

    public static native void SSL_enable_signed_cert_timestamps(long ssl);

    public static native byte[] SSL_get_signed_cert_timestamp_list(long ssl);

    public static native void SSL_CTX_set_signed_cert_timestamp_list(long ssl, byte[] list);

    public static native void SSL_enable_ocsp_stapling(long ssl);

    public static native byte[] SSL_get_ocsp_response(long ssl);

    public static native void SSL_CTX_set_ocsp_response(long ssl, byte[] response);

    public static native void SSL_use_psk_identity_hint(long ssl, String identityHint)
            throws SSLException;

    public static native void set_SSL_psk_client_callback_enabled(long ssl, boolean enabled);

    public static native void set_SSL_psk_server_callback_enabled(long ssl, boolean enabled);

    /** Protocols to enable by default when "TLSv1.2" is requested. */
    public static final String[] TLSV12_PROTOCOLS = new String[] {
        SUPPORTED_PROTOCOL_TLSV1,
        SUPPORTED_PROTOCOL_TLSV1_1,
        SUPPORTED_PROTOCOL_TLSV1_2,
    };

    /** Protocols to enable by default when "TLSv1.1" is requested. */
    public static final String[] TLSV11_PROTOCOLS = new String[] {
        SUPPORTED_PROTOCOL_TLSV1,
        SUPPORTED_PROTOCOL_TLSV1_1,
        SUPPORTED_PROTOCOL_TLSV1_2,
    };

    /** Protocols to enable by default when "TLSv1" is requested. */
    public static final String[] TLSV1_PROTOCOLS  = new String[] {
        SUPPORTED_PROTOCOL_TLSV1,
        SUPPORTED_PROTOCOL_TLSV1_1,
        SUPPORTED_PROTOCOL_TLSV1_2,
    };

    /** Protocols to enable by default when "SSLv3" is requested. */
    public static final String[] SSLV3_PROTOCOLS  = new String[] {
        SUPPORTED_PROTOCOL_SSLV3,
        SUPPORTED_PROTOCOL_TLSV1,
        SUPPORTED_PROTOCOL_TLSV1_1,
        SUPPORTED_PROTOCOL_TLSV1_2,
    };

    public static final String[] DEFAULT_PROTOCOLS = TLSV12_PROTOCOLS;

    public static String[] getSupportedProtocols() {
        return new String[] { SUPPORTED_PROTOCOL_SSLV3,
                              SUPPORTED_PROTOCOL_TLSV1,
                              SUPPORTED_PROTOCOL_TLSV1_1,
                              SUPPORTED_PROTOCOL_TLSV1_2,
        };
    }

    public static void setEnabledProtocols(long ssl, String[] protocols) {
        checkEnabledProtocols(protocols);
        // openssl uses negative logic letting you disable protocols.
        // so first, assume we need to set all (disable all) and clear none (enable none).
        // in the loop, selectively move bits from set to clear (from disable to enable)
        long optionsToSet = (NativeConstants.SSL_OP_NO_SSLv3 | NativeConstants.SSL_OP_NO_TLSv1 | NativeConstants.SSL_OP_NO_TLSv1_1 | NativeConstants.SSL_OP_NO_TLSv1_2);
        long optionsToClear = 0;
        for (int i = 0; i < protocols.length; i++) {
            String protocol = protocols[i];
            if (protocol.equals(SUPPORTED_PROTOCOL_SSLV3)) {
                optionsToSet &= ~NativeConstants.SSL_OP_NO_SSLv3;
                optionsToClear |= NativeConstants.SSL_OP_NO_SSLv3;
            } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1)) {
                optionsToSet &= ~NativeConstants.SSL_OP_NO_TLSv1;
                optionsToClear |= NativeConstants.SSL_OP_NO_TLSv1;
            } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1)) {
                optionsToSet &= ~NativeConstants.SSL_OP_NO_TLSv1_1;
                optionsToClear |= NativeConstants.SSL_OP_NO_TLSv1_1;
            } else if (protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2)) {
                optionsToSet &= ~NativeConstants.SSL_OP_NO_TLSv1_2;
                optionsToClear |= NativeConstants.SSL_OP_NO_TLSv1_2;
            } else {
                // error checked by checkEnabledProtocols
                throw new IllegalStateException();
            }
        }

        SSL_set_options(ssl, optionsToSet);
        SSL_clear_options(ssl, optionsToClear);
    }

    public static String[] checkEnabledProtocols(String[] protocols) {
        if (protocols == null) {
            throw new IllegalArgumentException("protocols == null");
        }
        for (int i = 0; i < protocols.length; i++) {
            String protocol = protocols[i];
            if (protocol == null) {
                throw new IllegalArgumentException("protocols[" + i + "] == null");
            }
            if ((!protocol.equals(SUPPORTED_PROTOCOL_SSLV3))
                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1))
                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_1))
                    && (!protocol.equals(SUPPORTED_PROTOCOL_TLSV1_2))) {
                throw new IllegalArgumentException("protocol " + protocol
                                                   + " is not supported");
            }
        }
        return protocols;
    }

    public static native void SSL_set_cipher_lists(long ssl, String[] ciphers);

    /**
     * Gets the list of cipher suites enabled for the provided {@code SSL} instance.
     *
     * @return array of {@code SSL_CIPHER} references.
     */
    public static native long[] SSL_get_ciphers(long ssl);

    public static void setEnabledCipherSuites(long ssl, String[] cipherSuites) {
        checkEnabledCipherSuites(cipherSuites);
        List<String> opensslSuites = new ArrayList<String>();
        for (int i = 0; i < cipherSuites.length; i++) {
            String cipherSuite = cipherSuites[i];
            if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV)) {
                continue;
            }
            if (cipherSuite.equals(TLS_FALLBACK_SCSV)) {
                SSL_set_mode(ssl, NativeConstants.SSL_MODE_SEND_FALLBACK_SCSV);
                continue;
            }
            String openssl = STANDARD_TO_OPENSSL_CIPHER_SUITES.get(cipherSuite);
            String cs = (openssl == null) ? cipherSuite : openssl;
            opensslSuites.add(cs);
        }
        SSL_set_cipher_lists(ssl, opensslSuites.toArray(new String[opensslSuites.size()]));
    }

    public static String[] checkEnabledCipherSuites(String[] cipherSuites) {
        if (cipherSuites == null) {
            throw new IllegalArgumentException("cipherSuites == null");
        }
        // makes sure all suites are valid, throwing on error
        for (int i = 0; i < cipherSuites.length; i++) {
            String cipherSuite = cipherSuites[i];
            if (cipherSuite == null) {
                throw new IllegalArgumentException("cipherSuites[" + i + "] == null");
            }
            if (cipherSuite.equals(TLS_EMPTY_RENEGOTIATION_INFO_SCSV) ||
                    cipherSuite.equals(TLS_FALLBACK_SCSV)) {
                continue;
            }
            if (SUPPORTED_CIPHER_SUITES_SET.contains(cipherSuite)) {
                continue;
            }

            // For backwards compatibility, it's allowed for |cipherSuite| to
            // be an OpenSSL-style cipher-suite name.
            String standardName = OPENSSL_TO_STANDARD_CIPHER_SUITES.get(cipherSuite);
            if (standardName != null && SUPPORTED_CIPHER_SUITES_SET.contains(standardName)) {
                // TODO log warning about using backward compatability
                continue;
            }
            throw new IllegalArgumentException("cipherSuite " + cipherSuite + " is not supported.");
        }
        return cipherSuites;
    }

    /*
     * See the OpenSSL ssl.h header file for more information.
     */
    public static final int SSL_VERIFY_NONE =                 0x00;
    public static final int SSL_VERIFY_PEER =                 0x01;
    public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 0x02;

    public static native void SSL_set_accept_state(long sslNativePointer);

    public static native void SSL_set_connect_state(long sslNativePointer);

    public static native void SSL_set_verify(long sslNativePointer, int mode);

    public static native void SSL_set_session(long sslNativePointer, long sslSessionNativePointer)
        throws SSLException;

    public static native void SSL_set_session_creation_enabled(
            long sslNativePointer, boolean creationEnabled) throws SSLException;

    public static native void SSL_set_reject_peer_renegotiations(
            long sslNativePointer, boolean renegotiationRejected) throws SSLException;

    public static native void SSL_set_tlsext_host_name(long sslNativePointer, String hostname)
            throws SSLException;
    public static native String SSL_get_servername(long sslNativePointer);

    /**
     * Enables NPN for all SSL connections in the context.
     *
     * <p>For clients this causes the NPN extension to be included in the
     * ClientHello message.
     *
     * <p>For servers this causes the NPN extension to be included in the
     * ServerHello message. The NPN extension will not be included in the
     * ServerHello response if the client didn't include it in the ClientHello
     * request.
     *
     * <p>In either case the caller should pass a non-null byte array of NPN
     * protocols to {@link #SSL_do_handshake}.
     */
    public static native void SSL_CTX_enable_npn(long sslCtxNativePointer);

    /**
     * Disables NPN for all SSL connections in the context.
     */
    public static native void SSL_CTX_disable_npn(long sslCtxNativePointer);

    /**
     * For clients, sets the list of supported ALPN protocols in wire-format
     * (length-prefixed 8-bit strings).
     */
    public static native int SSL_set_alpn_protos(long sslPointer, byte[] protos);

    /**
     * Returns the selected ALPN protocol. If the server did not select a
     * protocol, {@code null} will be returned.
     */
    public static native byte[] SSL_get0_alpn_selected(long sslPointer);

    /**
     * Returns the sslSessionNativePointer of the negotiated session. If this is
     * a server negotiation, supplying the {@code alpnProtocols} will enable
     * ALPN negotiation.
     */
    public static native long SSL_do_handshake(long sslNativePointer,
                                               FileDescriptor fd,
                                               SSLHandshakeCallbacks shc,
                                               int timeoutMillis,
                                               boolean client_mode,
                                               byte[] npnProtocols,
                                               byte[] alpnProtocols)
        throws SSLException, SocketTimeoutException, CertificateException;

    /**
     * Returns the sslSessionNativePointer of the negotiated session. If this is
     * a server negotiation, supplying the {@code alpnProtocols} will enable
     * ALPN negotiation.
     */
    public static native long SSL_do_handshake_bio(long sslNativePointer,
                                                   long sourceBioRef,
                                                   long sinkBioRef,
                                                   SSLHandshakeCallbacks shc,
                                                   boolean client_mode,
                                                   byte[] npnProtocols,
                                                   byte[] alpnProtocols)
        throws SSLException, SocketTimeoutException, CertificateException;

    public static native byte[] SSL_get_npn_negotiated_protocol(long sslNativePointer);

    /**
     * Currently only intended for forcing renegotiation for testing.
     * Not used within OpenSSLSocketImpl.
     */
    public static native void SSL_renegotiate(long sslNativePointer) throws SSLException;

    /**
     * Returns the local X509 certificate references. Must X509_free when done.
     */
    public static native long[] SSL_get_certificate(long sslNativePointer);

    /**
     * Returns the peer X509 certificate references. Must X509_free when done.
     */
    public static native long[] SSL_get_peer_cert_chain(long sslNativePointer);

    /**
     * Reads with the native SSL_read function from the encrypted data stream
     * @return -1 if error or the end of the stream is reached.
     */
    public static native int SSL_read(long sslNativePointer,
                                      FileDescriptor fd,
                                      SSLHandshakeCallbacks shc,
                                      byte[] b, int off, int len, int readTimeoutMillis)
        throws IOException;

    public static native int SSL_read_BIO(long sslNativePointer,
                                          byte[] dest,
                                          int destOffset,
                                          int destLength,
                                          long sourceBioRef,
                                          long sinkBioRef,
                                          SSLHandshakeCallbacks shc)
        throws IOException;

    /**
     * Writes with the native SSL_write function to the encrypted data stream.
     */
    public static native void SSL_write(long sslNativePointer,
                                        FileDescriptor fd,
                                        SSLHandshakeCallbacks shc,
                                        byte[] b, int off, int len, int writeTimeoutMillis)
        throws IOException;

    public static native int SSL_write_BIO(long sslNativePointer,
                                           byte[] source,
                                           int length,
                                           long sinkBioRef,
                                           SSLHandshakeCallbacks shc)
        throws IOException;

    public static native void SSL_interrupt(long sslNativePointer);
    public static native void SSL_shutdown(long sslNativePointer,
                                           FileDescriptor fd,
                                           SSLHandshakeCallbacks shc) throws IOException;

    public static native void SSL_shutdown_BIO(long sslNativePointer,
                                               long sourceBioRef, long sinkBioRef,
                                               SSLHandshakeCallbacks shc) throws IOException;

    public static native int SSL_get_shutdown(long sslNativePointer);

    public static native void SSL_free(long sslNativePointer);

    public static native byte[] SSL_SESSION_session_id(long sslSessionNativePointer);

    public static native long SSL_SESSION_get_time(long sslSessionNativePointer);

    public static native String SSL_SESSION_get_version(long sslSessionNativePointer);

    public static native String SSL_SESSION_cipher(long sslSessionNativePointer);

    public static native void SSL_SESSION_free(long sslSessionNativePointer);

    public static native byte[] i2d_SSL_SESSION(long sslSessionNativePointer);

    public static native long d2i_SSL_SESSION(byte[] data);

    /**
     * A collection of callbacks from the native OpenSSL code that are
     * related to the SSL handshake initiated by SSL_do_handshake.
     */
    public interface SSLHandshakeCallbacks {
        /**
         * Verify that we trust the certificate chain is trusted.
         *
         * @param sslSessionNativePtr pointer to a reference of the SSL_SESSION
         * @param certificateChainRefs chain of X.509 certificate references
         * @param authMethod auth algorithm name
         *
         * @throws CertificateException if the certificate is untrusted
         */
        public void verifyCertificateChain(long sslSessionNativePtr, long[] certificateChainRefs,
                String authMethod) throws CertificateException;

        /**
         * Called on an SSL client when the server requests (or
         * requires a certificate). The client can respond by using
         * SSL_use_certificate and SSL_use_PrivateKey to set a
         * certificate if has an appropriate one available, similar to
         * how the server provides its certificate.
         *
         * @param keyTypes key types supported by the server,
         * convertible to strings with #keyType
         * @param asn1DerEncodedX500Principals CAs known to the server
         */
        public void clientCertificateRequested(byte[] keyTypes,
                                               byte[][] asn1DerEncodedX500Principals)
            throws CertificateEncodingException, SSLException;

        /**
         * Gets the key to be used in client mode for this connection in Pre-Shared Key (PSK) key
         * exchange.
         *
         * @param identityHint PSK identity hint provided by the server or {@code null} if no hint
         *        provided.
         * @param identity buffer to be populated with PSK identity (NULL-terminated modified UTF-8)
         *        by this method. This identity will be provided to the server.
         * @param key buffer to be populated with key material by this method.
         *
         * @return number of bytes this method stored in the {@code key} buffer or {@code 0} if an
         *         error occurred in which case the handshake will be aborted.
         */
        public int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key);

        /**
         * Gets the key to be used in server mode for this connection in Pre-Shared Key (PSK) key
         * exchange.
         *
         * @param identityHint PSK identity hint provided by this server to the client or
         *        {@code null} if no hint was provided.
         * @param identity PSK identity provided by the client.
         * @param key buffer to be populated with key material by this method.
         *
         * @return number of bytes this method stored in the {@code key} buffer or {@code 0} if an
         *         error occurred in which case the handshake will be aborted.
         */
        public int serverPSKKeyRequested(String identityHint, String identity, byte[] key);

        /**
         * Called when SSL state changes. This could be handshake completion.
         */
        public void onSSLStateChange(long sslSessionNativePtr, int type, int val);
    }

    public static native long ERR_peek_last_error();

    public static native String SSL_CIPHER_get_kx_name(long cipherAddress);

    public static native String[] get_cipher_names(String selection);

    public static native byte[] get_ocsp_single_extension(byte[] ocspResponse, String oid,
                                                          long x509Ref, long issuerX509Ref);

    /**
     * Returns the starting address of the memory region referenced by the provided direct
     * {@link Buffer} or {@code 0} if the provided buffer is not direct or if such access to direct
     * buffers is not supported by the platform.
     *
     * <p>NOTE: This method ignores the buffer's current {@code position}.
     */
    public static native long getDirectBufferAddress(Buffer buf);
}
