Home | History | Annotate | Download | only in native
      1 /*
      2  * Copyright (C) 2007-2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18  * Native glue for Java class org.apache.harmony.xnet.provider.jsse.NativeCrypto
     19  */
     20 
     21 #define LOG_TAG "NativeCrypto"
     22 
     23 #include <fcntl.h>
     24 #include <sys/socket.h>
     25 #include <unistd.h>
     26 
     27 #include <jni.h>
     28 
     29 #include <openssl/dsa.h>
     30 #include <openssl/err.h>
     31 #include <openssl/evp.h>
     32 #include <openssl/rand.h>
     33 #include <openssl/rsa.h>
     34 #include <openssl/ssl.h>
     35 
     36 #include "AsynchronousSocketCloseMonitor.h"
     37 #include "JNIHelp.h"
     38 #include "JniConstants.h"
     39 #include "JniException.h"
     40 #include "LocalArray.h"
     41 #include "NetFd.h"
     42 #include "NetworkUtilities.h"
     43 #include "ScopedLocalRef.h"
     44 #include "ScopedPrimitiveArray.h"
     45 #include "ScopedUtfChars.h"
     46 #include "UniquePtr.h"
     47 
     48 #undef WITH_JNI_TRACE
     49 #ifdef WITH_JNI_TRACE
     50 #define JNI_TRACE(...) \
     51         ((void)LOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__));     \
     52 /*
     53         ((void)printf("I/" LOG_TAG "-jni:"));         \
     54         ((void)printf(__VA_ARGS__));          \
     55         ((void)printf("\n"))
     56 */
     57 #else
     58 #define JNI_TRACE(...) ((void)0)
     59 #endif
     60 
     61 struct BIO_Delete {
     62     void operator()(BIO* p) const {
     63         BIO_free(p);
     64     }
     65 };
     66 typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
     67 
     68 struct BIGNUM_Delete {
     69     void operator()(BIGNUM* p) const {
     70         BN_free(p);
     71     }
     72 };
     73 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
     74 
     75 struct DH_Delete {
     76     void operator()(DH* p) const {
     77         DH_free(p);
     78     }
     79 };
     80 typedef UniquePtr<DH, DH_Delete> Unique_DH;
     81 
     82 struct DSA_Delete {
     83     void operator()(DSA* p) const {
     84         DSA_free(p);
     85     }
     86 };
     87 typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
     88 
     89 struct EVP_PKEY_Delete {
     90     void operator()(EVP_PKEY* p) const {
     91         EVP_PKEY_free(p);
     92     }
     93 };
     94 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
     95 
     96 struct PKCS8_PRIV_KEY_INFO_Delete {
     97     void operator()(PKCS8_PRIV_KEY_INFO* p) const {
     98         PKCS8_PRIV_KEY_INFO_free(p);
     99     }
    100 };
    101 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
    102 
    103 struct RSA_Delete {
    104     void operator()(RSA* p) const {
    105         RSA_free(p);
    106     }
    107 };
    108 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
    109 
    110 struct SSL_Delete {
    111     void operator()(SSL* p) const {
    112         SSL_free(p);
    113     }
    114 };
    115 typedef UniquePtr<SSL, SSL_Delete> Unique_SSL;
    116 
    117 struct SSL_CTX_Delete {
    118     void operator()(SSL_CTX* p) const {
    119         SSL_CTX_free(p);
    120     }
    121 };
    122 typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX;
    123 
    124 struct X509_Delete {
    125     void operator()(X509* p) const {
    126         X509_free(p);
    127     }
    128 };
    129 typedef UniquePtr<X509, X509_Delete> Unique_X509;
    130 
    131 struct X509_NAME_Delete {
    132     void operator()(X509_NAME* p) const {
    133         X509_NAME_free(p);
    134     }
    135 };
    136 typedef UniquePtr<X509_NAME, X509_NAME_Delete> Unique_X509_NAME;
    137 
    138 struct sk_SSL_CIPHER_Delete {
    139     void operator()(STACK_OF(SSL_CIPHER)* p) const {
    140         sk_SSL_CIPHER_free(p);
    141     }
    142 };
    143 typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER;
    144 
    145 struct sk_X509_Delete {
    146     void operator()(STACK_OF(X509)* p) const {
    147         sk_X509_free(p);
    148     }
    149 };
    150 typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509;
    151 
    152 struct sk_X509_NAME_Delete {
    153     void operator()(STACK_OF(X509_NAME)* p) const {
    154         sk_X509_NAME_free(p);
    155     }
    156 };
    157 typedef UniquePtr<STACK_OF(X509_NAME), sk_X509_NAME_Delete> Unique_sk_X509_NAME;
    158 
    159 /**
    160  * Frees the SSL error state.
    161  *
    162  * OpenSSL keeps an "error stack" per thread, and given that this code
    163  * can be called from arbitrary threads that we don't keep track of,
    164  * we err on the side of freeing the error state promptly (instead of,
    165  * say, at thread death).
    166  */
    167 static void freeSslErrorState(void) {
    168     ERR_clear_error();
    169     ERR_remove_state(0);
    170 }
    171 
    172 /*
    173  * Checks this thread's OpenSSL error queue and throws a RuntimeException if
    174  * necessary.
    175  *
    176  * @return 1 if an exception was thrown, 0 if not.
    177  */
    178 static int throwExceptionIfNecessary(JNIEnv* env, const char* location  __attribute__ ((unused))) {
    179     int error = ERR_get_error();
    180     int result = 0;
    181 
    182     if (error != 0) {
    183         char message[256];
    184         ERR_error_string_n(error, message, sizeof(message));
    185         JNI_TRACE("OpenSSL error in %s %d: %s", location, error, message);
    186         jniThrowRuntimeException(env, message);
    187         result = 1;
    188     }
    189 
    190     freeSslErrorState();
    191     return result;
    192 }
    193 
    194 /**
    195  * Throws an SocketTimeoutException with the given string as a message.
    196  */
    197 static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
    198     JNI_TRACE("throwSocketTimeoutException %s", message);
    199     jniThrowException(env, "java/net/SocketTimeoutException", message);
    200 }
    201 
    202 /**
    203  * Throws a javax.net.ssl.SSLException with the given string as a message.
    204  */
    205 static void throwSSLExceptionStr(JNIEnv* env, const char* message) {
    206     JNI_TRACE("throwSSLExceptionStr %s", message);
    207     jniThrowException(env, "javax/net/ssl/SSLException", message);
    208 }
    209 
    210 /**
    211  * Throws a javax.net.ssl.SSLProcotolException with the given string as a message.
    212  */
    213 static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) {
    214     JNI_TRACE("throwSSLProtocolExceptionStr %s", message);
    215     jniThrowException(env, "javax/net/ssl/SSLProtocolException", message);
    216 }
    217 
    218 /**
    219  * Throws an SSLException with a message constructed from the current
    220  * SSL errors. This will also log the errors.
    221  *
    222  * @param env the JNI environment
    223  * @param ssl the possibly NULL SSL
    224  * @param sslErrorCode error code returned from SSL_get_error() or
    225  * SSL_ERROR_NONE to probe with ERR_get_error
    226  * @param message null-ok; general error message
    227  */
    228 static void throwSSLExceptionWithSslErrors(
    229         JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message) {
    230 
    231     if (message == NULL) {
    232         message = "SSL error";
    233     }
    234 
    235     // First consult the SSL error code for the general message.
    236     const char* sslErrorStr = NULL;
    237     switch (sslErrorCode) {
    238         case SSL_ERROR_NONE:
    239             if (ERR_peek_error() == 0) {
    240                 sslErrorStr = "OK";
    241             } else {
    242                 sslErrorStr = "";
    243             }
    244             break;
    245         case SSL_ERROR_SSL:
    246             sslErrorStr = "Failure in SSL library, usually a protocol error";
    247             break;
    248         case SSL_ERROR_WANT_READ:
    249             sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this.";
    250             break;
    251         case SSL_ERROR_WANT_WRITE:
    252             sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this.";
    253             break;
    254         case SSL_ERROR_WANT_X509_LOOKUP:
    255             sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this.";
    256             break;
    257         case SSL_ERROR_SYSCALL:
    258             sslErrorStr = "I/O error during system call";
    259             break;
    260         case SSL_ERROR_ZERO_RETURN:
    261             sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this.";
    262             break;
    263         case SSL_ERROR_WANT_CONNECT:
    264             sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this.";
    265             break;
    266         case SSL_ERROR_WANT_ACCEPT:
    267             sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this.";
    268             break;
    269         default:
    270             sslErrorStr = "Unknown SSL error";
    271     }
    272 
    273     // Prepend either our explicit message or a default one.
    274     char* str;
    275     if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) {
    276         // problem with asprintf, just throw argument message, log everything
    277         throwSSLExceptionStr(env, message);
    278         LOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr);
    279         freeSslErrorState();
    280         return;
    281     }
    282 
    283     char* allocStr = str;
    284 
    285     // For protocol errors, SSL might have more information.
    286     if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) {
    287         // Append each error as an additional line to the message.
    288         for (;;) {
    289             char errStr[256];
    290             const char* file;
    291             int line;
    292             const char* data;
    293             int flags;
    294             unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags);
    295             if (err == 0) {
    296                 break;
    297             }
    298 
    299             ERR_error_string_n(err, errStr, sizeof(errStr));
    300 
    301             int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
    302                                (allocStr == NULL) ? "" : allocStr,
    303                                errStr,
    304                                file,
    305                                line,
    306                                (flags & ERR_TXT_STRING) ? data : "(no data)",
    307                                flags);
    308 
    309             if (ret < 0) {
    310                 break;
    311             }
    312 
    313             free(allocStr);
    314             allocStr = str;
    315         }
    316     // For errors during system calls, errno might be our friend.
    317     } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
    318         if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
    319             free(allocStr);
    320             allocStr = str;
    321         }
    322     // If the error code is invalid, print it.
    323     } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
    324         if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
    325             free(allocStr);
    326             allocStr = str;
    327         }
    328     }
    329 
    330     if (sslErrorCode == SSL_ERROR_SSL) {
    331         throwSSLProtocolExceptionStr(env, allocStr);
    332     } else {
    333         throwSSLExceptionStr(env, allocStr);
    334     }
    335 
    336     LOGV("%s", allocStr);
    337     free(allocStr);
    338     freeSslErrorState();
    339 }
    340 
    341 /**
    342  * Helper function that grabs the casts an ssl pointer and then checks for nullness.
    343  * If this function returns NULL and <code>throwIfNull</code> is
    344  * passed as <code>true</code>, then this function will call
    345  * <code>throwSSLExceptionStr</code> before returning, so in this case of
    346  * NULL, a caller of this function should simply return and allow JNI
    347  * to do its thing.
    348  *
    349  * @param env the JNI environment
    350  * @param ssl_address; the ssl_address pointer as an integer
    351  * @param throwIfNull whether to throw if the SSL pointer is NULL
    352  * @returns the pointer, which may be NULL
    353  */
    354 static SSL_CTX* to_SSL_CTX(JNIEnv* env, int ssl_ctx_address, bool throwIfNull) {
    355     SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
    356     if ((ssl_ctx == NULL) && throwIfNull) {
    357         JNI_TRACE("ssl_ctx == null");
    358         jniThrowNullPointerException(env, "ssl_ctx == null");
    359     }
    360     return ssl_ctx;
    361 }
    362 
    363 static SSL* to_SSL(JNIEnv* env, int ssl_address, bool throwIfNull) {
    364     SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
    365     if ((ssl == NULL) && throwIfNull) {
    366         JNI_TRACE("ssl == null");
    367         jniThrowNullPointerException(env, "ssl == null");
    368     }
    369     return ssl;
    370 }
    371 
    372 static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, int ssl_session_address, bool throwIfNull) {
    373     SSL_SESSION* ssl_session
    374         = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
    375     if ((ssl_session == NULL) && throwIfNull) {
    376         JNI_TRACE("ssl_session == null");
    377         jniThrowNullPointerException(env, "ssl_session == null");
    378     }
    379     return ssl_session;
    380 }
    381 
    382 /**
    383  * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
    384  * fly.
    385  */
    386 static BIGNUM* arrayToBignum(JNIEnv* env, jbyteArray source) {
    387     JNI_TRACE("arrayToBignum(%p)", source);
    388 
    389     ScopedByteArrayRO sourceBytes(env, source);
    390     if (sourceBytes.get() == NULL) {
    391         JNI_TRACE("arrayToBignum(%p) => NULL", source);
    392         return NULL;
    393     }
    394     BIGNUM* bn = BN_bin2bn(reinterpret_cast<const unsigned char*>(sourceBytes.get()),
    395                            sourceBytes.size(),
    396                            NULL);
    397     JNI_TRACE("arrayToBignum(%p) => %p", source, bn);
    398     return bn;
    399 }
    400 
    401 /**
    402  * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
    403  * suppose there are not many other ways to do this on a Linux system (modulo
    404  * isomorphism).
    405  */
    406 #define MUTEX_TYPE pthread_mutex_t
    407 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
    408 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
    409 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
    410 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
    411 #define THREAD_ID pthread_self()
    412 #define THROW_EXCEPTION (-2)
    413 #define THROW_SOCKETTIMEOUTEXCEPTION (-3)
    414 #define THROWN_SOCKETEXCEPTION (-4)
    415 
    416 static MUTEX_TYPE* mutex_buf = NULL;
    417 
    418 static void locking_function(int mode, int n, const char*, int) {
    419     if (mode & CRYPTO_LOCK) {
    420         MUTEX_LOCK(mutex_buf[n]);
    421     } else {
    422         MUTEX_UNLOCK(mutex_buf[n]);
    423     }
    424 }
    425 
    426 static unsigned long id_function(void) {
    427     return ((unsigned long)THREAD_ID);
    428 }
    429 
    430 int THREAD_setup(void) {
    431     mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
    432     if (!mutex_buf) {
    433         return 0;
    434     }
    435 
    436     for (int i = 0; i < CRYPTO_num_locks(); ++i) {
    437         MUTEX_SETUP(mutex_buf[i]);
    438     }
    439 
    440     CRYPTO_set_id_callback(id_function);
    441     CRYPTO_set_locking_callback(locking_function);
    442 
    443     return 1;
    444 }
    445 
    446 int THREAD_cleanup(void) {
    447     if (!mutex_buf) {
    448         return 0;
    449     }
    450 
    451     CRYPTO_set_id_callback(NULL);
    452     CRYPTO_set_locking_callback(NULL);
    453 
    454     for (int i = 0; i < CRYPTO_num_locks( ); i++) {
    455         MUTEX_CLEANUP(mutex_buf[i]);
    456     }
    457 
    458     free(mutex_buf);
    459     mutex_buf = NULL;
    460 
    461     return 1;
    462 }
    463 
    464 /**
    465  * Initialization phase for every OpenSSL job: Loads the Error strings, the
    466  * crypto algorithms and reset the OpenSSL library
    467  */
    468 static void NativeCrypto_clinit(JNIEnv*, jclass)
    469 {
    470     SSL_load_error_strings();
    471     ERR_load_crypto_strings();
    472     SSL_library_init();
    473     OpenSSL_add_all_algorithms();
    474     THREAD_setup();
    475 }
    476 
    477 /**
    478  * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
    479  *                                           byte[] pub_key, byte[] priv_key);
    480  */
    481 static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
    482                                                jbyteArray p, jbyteArray q, jbyteArray g,
    483                                                jbyteArray pub_key, jbyteArray priv_key) {
    484     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
    485               p, q, g, pub_key, priv_key);
    486 
    487     Unique_DSA dsa(DSA_new());
    488     if (dsa.get() == NULL) {
    489         jniThrowRuntimeException(env, "DSA_new failed");
    490         return NULL;
    491     }
    492 
    493     dsa->p = arrayToBignum(env, p);
    494     dsa->q = arrayToBignum(env, q);
    495     dsa->g = arrayToBignum(env, g);
    496     dsa->pub_key = arrayToBignum(env, pub_key);
    497 
    498     if (priv_key != NULL) {
    499         dsa->priv_key = arrayToBignum(env, priv_key);
    500     }
    501 
    502     if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL || dsa->pub_key == NULL) {
    503         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
    504         return NULL;
    505     }
    506 
    507     Unique_EVP_PKEY pkey(EVP_PKEY_new());
    508     if (pkey.get() == NULL) {
    509         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
    510         return NULL;
    511     }
    512     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
    513         jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
    514         return NULL;
    515     }
    516     dsa.release();
    517     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
    518               p, q, g, pub_key, priv_key, pkey.get());
    519     return pkey.release();
    520 }
    521 
    522 /**
    523  * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
    524  */
    525 static EVP_PKEY* NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
    526                                                jbyteArray n, jbyteArray e, jbyteArray d,
    527                                                jbyteArray p, jbyteArray q) {
    528     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p)", n, e, d, p, q);
    529 
    530     Unique_RSA rsa(RSA_new());
    531     if (rsa.get() == NULL) {
    532         jniThrowRuntimeException(env, "RSA_new failed");
    533         return NULL;
    534     }
    535 
    536     rsa->n = arrayToBignum(env, n);
    537     rsa->e = arrayToBignum(env, e);
    538 
    539     if (d != NULL) {
    540         rsa->d = arrayToBignum(env, d);
    541     }
    542 
    543     if (p != NULL) {
    544         rsa->p = arrayToBignum(env, p);
    545     }
    546 
    547     if (q != NULL) {
    548         rsa->q = arrayToBignum(env, q);
    549     }
    550 
    551 #ifdef WITH_JNI_TRACE
    552     if (p != NULL && q != NULL) {
    553         int check = RSA_check_key(rsa.get());
    554         JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check);
    555     }
    556 #endif
    557 
    558     if (rsa->n == NULL || rsa->e == NULL) {
    559         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
    560         return NULL;
    561     }
    562 
    563     Unique_EVP_PKEY pkey(EVP_PKEY_new());
    564     if (pkey.get() == NULL) {
    565         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
    566         return NULL;
    567     }
    568     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
    569         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
    570         return NULL;
    571     }
    572     rsa.release();
    573     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p) => %p", n, e, d, p, q, pkey.get());
    574     return pkey.release();
    575 }
    576 
    577 /**
    578  * private static native void EVP_PKEY_free(int pkey);
    579  */
    580 static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, EVP_PKEY* pkey) {
    581     JNI_TRACE("EVP_PKEY_free(%p)", pkey);
    582 
    583     if (pkey != NULL) {
    584         EVP_PKEY_free(pkey);
    585     }
    586 }
    587 
    588 /*
    589  * public static native int EVP_MD_CTX_create()
    590  */
    591 static jint NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
    592     JNI_TRACE("NativeCrypto_EVP_MD_CTX_create");
    593 
    594     EVP_MD_CTX* ctx = EVP_MD_CTX_create();
    595     if (ctx == NULL) {
    596         jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX");
    597     }
    598     JNI_TRACE("NativeCrypto_EVP_MD_CTX_create => %p", ctx);
    599     return (jint) ctx;
    600 
    601 }
    602 
    603 /*
    604  * public static native void EVP_MD_CTX_destroy(int)
    605  */
    606 static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, EVP_MD_CTX* ctx) {
    607     JNI_TRACE("NativeCrypto_EVP_MD_CTX_destroy(%p)", ctx);
    608 
    609     if (ctx != NULL) {
    610         EVP_MD_CTX_destroy(ctx);
    611     }
    612 }
    613 
    614 /*
    615  * public static native int EVP_MD_CTX_copy(int)
    616  */
    617 static jint NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
    618     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p)", ctx);
    619 
    620     if (ctx == NULL) {
    621         jniThrowNullPointerException(env, NULL);
    622         return NULL;
    623     }
    624     EVP_MD_CTX* copy = EVP_MD_CTX_create();
    625     if (copy == NULL) {
    626         jniThrowOutOfMemoryError(env, "Unable to allocate copy of EVP_MD_CTX");
    627         return NULL;
    628     }
    629     EVP_MD_CTX_init(copy);
    630     int result = EVP_MD_CTX_copy_ex(copy, ctx);
    631     if (result == 0) {
    632         EVP_MD_CTX_destroy(copy);
    633         jniThrowRuntimeException(env, "Unable to copy EVP_MD_CTX");
    634         return NULL;
    635     }
    636     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p) => %p", ctx, copy);
    637     return (jint) copy;
    638 }
    639 
    640 /*
    641  * public static native int EVP_DigestFinal(int, byte[], int)
    642  */
    643 static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx,
    644                                          jbyteArray hash, jint offset) {
    645     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
    646 
    647     if (ctx == NULL || hash == NULL) {
    648         jniThrowNullPointerException(env, NULL);
    649         return -1;
    650     }
    651 
    652     int result = -1;
    653 
    654     ScopedByteArrayRW hashBytes(env, hash);
    655     if (hashBytes.get() == NULL) {
    656         return -1;
    657     }
    658     EVP_DigestFinal(ctx,
    659                     reinterpret_cast<unsigned char*>(hashBytes.get() + offset),
    660                     reinterpret_cast<unsigned int*>(&result));
    661 
    662     throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal");
    663 
    664     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, result);
    665     return result;
    666 }
    667 
    668 /*
    669  * public static native void EVP_DigestInit(int, java.lang.String)
    670  */
    671 static void NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jstring algorithm) {
    672     JNI_TRACE("NativeCrypto_EVP_DigestInit(%p, %p)", ctx, algorithm);
    673 
    674     if (ctx == NULL || algorithm == NULL) {
    675         jniThrowNullPointerException(env, NULL);
    676         return;
    677     }
    678 
    679     ScopedUtfChars algorithmChars(env, algorithm);
    680     if (algorithmChars.c_str() == NULL) {
    681         return;
    682     }
    683 
    684     JNI_TRACE("NativeCrypto_EVP_DigestInit(%p, %s)", ctx, algorithmChars.c_str());
    685     const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
    686 
    687     if (digest == NULL) {
    688         jniThrowRuntimeException(env, "Hash algorithm not found");
    689         return;
    690     }
    691 
    692     EVP_DigestInit(ctx, digest);
    693 
    694     throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit");
    695 }
    696 
    697 /*
    698  * public static native int EVP_MD_CTX_size(int)
    699  */
    700 static jint NativeCrypto_EVP_MD_CTX_size(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
    701     JNI_TRACE("NativeCrypto_EVP_MD_CTX_size(%p)", ctx);
    702 
    703     if (ctx == NULL) {
    704         jniThrowNullPointerException(env, NULL);
    705         return -1;
    706     }
    707 
    708     int result = EVP_MD_CTX_size(ctx);
    709 
    710     throwExceptionIfNecessary(env, "NativeCrypto_EVP_MD_CTX_size");
    711 
    712     JNI_TRACE("NativeCrypto_EVP_MD_CTX_size(%p) => %d", ctx, result);
    713     return result;
    714 }
    715 
    716 /*
    717  * public static int void EVP_MD_CTX_block_size(int)
    718  */
    719 static jint NativeCrypto_EVP_MD_CTX_block_size(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
    720     JNI_TRACE("NativeCrypto_EVP_MD_CTX_block_size(%p)", ctx);
    721 
    722     if (ctx == NULL) {
    723         jniThrowNullPointerException(env, NULL);
    724         return -1;
    725     }
    726 
    727     int result = EVP_MD_CTX_block_size(ctx);
    728 
    729     throwExceptionIfNecessary(env, "NativeCrypto_EVP_MD_CTX_block_size");
    730 
    731     JNI_TRACE("NativeCrypto_EVP_MD_CTX_block_size(%p) => %d", ctx, result);
    732     return result;
    733 }
    734 
    735 /*
    736  * public static native void EVP_DigestUpdate(int, byte[], int, int)
    737  */
    738 static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, EVP_MD_CTX* ctx,
    739                                           jbyteArray buffer, jint offset, jint length) {
    740     JNI_TRACE("NativeCrypto_EVP_DigestUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
    741 
    742     if (offset < 0 || length < 0) {
    743         jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
    744         return;
    745     }
    746 
    747     if (ctx == NULL || buffer == NULL) {
    748         jniThrowNullPointerException(env, NULL);
    749         return;
    750     }
    751 
    752     ScopedByteArrayRO bufferBytes(env, buffer);
    753     if (bufferBytes.get() == NULL) {
    754         return;
    755     }
    756     EVP_DigestUpdate(ctx,
    757                      reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
    758                      length);
    759 
    760     throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate");
    761 }
    762 
    763 /*
    764  * public static native void EVP_VerifyInit(int, java.lang.String)
    765  */
    766 static void NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jstring algorithm) {
    767     JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p, %p)", ctx, algorithm);
    768 
    769     if (ctx == NULL || algorithm == NULL) {
    770         jniThrowNullPointerException(env, NULL);
    771         return;
    772     }
    773 
    774     ScopedUtfChars algorithmChars(env, algorithm);
    775     if (algorithmChars.c_str() == NULL) {
    776         return;
    777     }
    778 
    779     JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p, %s)", ctx, algorithmChars.c_str());
    780     const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
    781 
    782     if (digest == NULL) {
    783         jniThrowRuntimeException(env, "Hash algorithm not found");
    784         return;
    785     }
    786 
    787     EVP_VerifyInit(ctx, digest);
    788 
    789     throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit");
    790 }
    791 
    792 /*
    793  * public static native void EVP_VerifyUpdate(int, byte[], int, int)
    794  */
    795 static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, EVP_MD_CTX* ctx,
    796                                           jbyteArray buffer, jint offset, jint length) {
    797     JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
    798 
    799     if (ctx == NULL || buffer == NULL) {
    800         jniThrowNullPointerException(env, NULL);
    801         return;
    802     }
    803 
    804     ScopedByteArrayRO bufferBytes(env, buffer);
    805     if (bufferBytes.get() == NULL) {
    806         return;
    807     }
    808     EVP_VerifyUpdate(ctx,
    809                      reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
    810                      length);
    811 
    812     throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate");
    813 }
    814 
    815 /*
    816  * public static native int EVP_VerifyFinal(int, byte[], int, int, int)
    817  */
    818 static int NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, EVP_MD_CTX* ctx, jbyteArray buffer,
    819                                         jint offset, jint length, EVP_PKEY* pkey) {
    820     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
    821               ctx, buffer, offset, length, pkey);
    822 
    823     if (ctx == NULL || buffer == NULL || pkey == NULL) {
    824         jniThrowNullPointerException(env, NULL);
    825         return -1;
    826     }
    827 
    828     ScopedByteArrayRO bufferBytes(env, buffer);
    829     if (bufferBytes.get() == NULL) {
    830         return -1;
    831     }
    832     int result = EVP_VerifyFinal(ctx,
    833                                  reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
    834                                  length,
    835                                  pkey);
    836 
    837     throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal");
    838 
    839     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d",
    840               ctx, buffer, offset, length, pkey, result);
    841 
    842     return result;
    843 }
    844 
    845 /**
    846  * Helper function that creates an RSA public key from two buffers containing
    847  * the big-endian bit representation of the modulus and the public exponent.
    848  *
    849  * @param mod The data of the modulus
    850  * @param modLen The length of the modulus data
    851  * @param exp The data of the exponent
    852  * @param expLen The length of the exponent data
    853  *
    854  * @return A pointer to the new RSA structure, or NULL on error
    855  */
    856 static RSA* rsaCreateKey(const jbyte* mod, int modLen, const jbyte* exp, int expLen) {
    857     JNI_TRACE("rsaCreateKey(..., %d, ..., %d)", modLen, expLen);
    858 
    859     Unique_RSA rsa(RSA_new());
    860     if (rsa.get() == NULL) {
    861         return NULL;
    862     }
    863 
    864     rsa->n = BN_bin2bn(reinterpret_cast<const unsigned char*>(mod), modLen, NULL);
    865     rsa->e = BN_bin2bn(reinterpret_cast<const unsigned char*>(exp), expLen, NULL);
    866 
    867     if (rsa->n == NULL || rsa->e == NULL) {
    868         return NULL;
    869     }
    870 
    871     JNI_TRACE("rsaCreateKey(..., %d, ..., %d) => %p", modLen, expLen, rsa.get());
    872     return rsa.release();
    873 }
    874 
    875 /**
    876  * Helper function that verifies a given RSA signature for a given message.
    877  *
    878  * @param msg The message to verify
    879  * @param msgLen The length of the message
    880  * @param sig The signature to verify
    881  * @param sigLen The length of the signature
    882  * @param algorithm The name of the hash/sign algorithm to use, e.g. "RSA-SHA1"
    883  * @param rsa The RSA public key to use
    884  *
    885  * @return 1 on success, 0 on failure, -1 on error (check SSL errors then)
    886  *
    887  */
    888 static int rsaVerify(const jbyte* msg, unsigned int msgLen, const jbyte* sig,
    889                      unsigned int sigLen, const char* algorithm, RSA* rsa) {
    890 
    891     JNI_TRACE("rsaVerify(%p, %d, %p, %d, %s, %p)",
    892               msg, msgLen, sig, sigLen, algorithm, rsa);
    893 
    894     Unique_EVP_PKEY pkey(EVP_PKEY_new());
    895     if (pkey.get() == NULL) {
    896         return -1;
    897     }
    898     EVP_PKEY_set1_RSA(pkey.get(), rsa);
    899 
    900     const EVP_MD* type = EVP_get_digestbyname(algorithm);
    901     if (type == NULL) {
    902         return -1;
    903     }
    904 
    905     EVP_MD_CTX ctx;
    906     EVP_MD_CTX_init(&ctx);
    907     if (EVP_VerifyInit_ex(&ctx, type, NULL) == 0) {
    908         return -1;
    909     }
    910 
    911     EVP_VerifyUpdate(&ctx, msg, msgLen);
    912     int result = EVP_VerifyFinal(&ctx, reinterpret_cast<const unsigned char*>(sig), sigLen,
    913             pkey.get());
    914     EVP_MD_CTX_cleanup(&ctx);
    915 
    916     JNI_TRACE("rsaVerify(%p, %d, %p, %d, %s, %p) => %d",
    917               msg, msgLen, sig, sigLen, algorithm, rsa, result);
    918     return result;
    919 }
    920 
    921 /**
    922  * Verifies an RSA signature.
    923  */
    924 static int NativeCrypto_verifySignature(JNIEnv* env, jclass,
    925         jbyteArray msg, jbyteArray sig, jstring algorithm, jbyteArray mod, jbyteArray exp) {
    926 
    927     JNI_TRACE("NativeCrypto_verifySignature msg=%p sig=%p algorithm=%p mod=%p exp%p",
    928               msg, sig, algorithm, mod, exp);
    929 
    930     ScopedByteArrayRO msgBytes(env, msg);
    931     if (msgBytes.get() == NULL) {
    932         return -1;
    933     }
    934     ScopedByteArrayRO sigBytes(env, sig);
    935     if (sigBytes.get() == NULL) {
    936         return -1;
    937     }
    938     ScopedByteArrayRO modBytes(env, mod);
    939     if (modBytes.get() == NULL) {
    940         return -1;
    941     }
    942     ScopedByteArrayRO expBytes(env, exp);
    943     if (expBytes.get() == NULL) {
    944         return -1;
    945     }
    946 
    947     ScopedUtfChars algorithmChars(env, algorithm);
    948     if (algorithmChars.c_str() == NULL) {
    949         return -1;
    950     }
    951     JNI_TRACE("NativeCrypto_verifySignature algorithmChars=%s", algorithmChars.c_str());
    952 
    953     Unique_RSA rsa(rsaCreateKey(modBytes.get(), modBytes.size(), expBytes.get(), expBytes.size()));
    954     int result = -1;
    955     if (rsa.get() != NULL) {
    956         result = rsaVerify(msgBytes.get(), msgBytes.size(), sigBytes.get(), sigBytes.size(),
    957                 algorithmChars.c_str(), rsa.get());
    958     }
    959 
    960     if (result == -1) {
    961         if (!throwExceptionIfNecessary(env, "NativeCrypto_verifySignature")) {
    962             jniThrowRuntimeException(env, "Internal error during verification");
    963         }
    964     }
    965 
    966     JNI_TRACE("NativeCrypto_verifySignature => %d", result);
    967     return result;
    968 }
    969 
    970 static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) {
    971     JNI_TRACE("NativeCrypto_RAND_seed seed=%p", seed);
    972     ScopedByteArrayRO randseed(env, seed);
    973     if (randseed.get() == NULL) {
    974         return;
    975     }
    976     RAND_seed(randseed.get(), randseed.size());
    977 }
    978 
    979 static int NativeCrypto_RAND_load_file(JNIEnv* env, jclass, jstring filename, jlong max_bytes) {
    980     JNI_TRACE("NativeCrypto_RAND_load_file filename=%p max_bytes=%lld", filename, max_bytes);
    981     ScopedUtfChars file(env, filename);
    982     if (file.c_str() == NULL) {
    983         return -1;
    984     }
    985     int result = RAND_load_file(file.c_str(), max_bytes);
    986     JNI_TRACE("NativeCrypto_RAND_load_file file=%s => %d", file.c_str(), result);
    987     return result;
    988 }
    989 
    990 /**
    991  * Convert ssl version constant to string. Based on SSL_get_version
    992  */
    993 // TODO move to jsse.patch
    994 static const char* get_ssl_version(int ssl_version) {
    995     switch (ssl_version) {
    996         // newest to oldest
    997         case TLS1_VERSION: {
    998           return SSL_TXT_TLSV1;
    999         }
   1000         case SSL3_VERSION: {
   1001           return SSL_TXT_SSLV3;
   1002         }
   1003         case SSL2_VERSION: {
   1004           return SSL_TXT_SSLV2;
   1005         }
   1006         default: {
   1007           return "unknown";
   1008         }
   1009     }
   1010 }
   1011 
   1012 #ifdef WITH_JNI_TRACE
   1013 /**
   1014  * Convert content type constant to string.
   1015  */
   1016 // TODO move to jsse.patch
   1017 static const char* get_content_type(int content_type) {
   1018     switch (content_type) {
   1019         case SSL3_RT_CHANGE_CIPHER_SPEC: {
   1020             return "SSL3_RT_CHANGE_CIPHER_SPEC";
   1021         }
   1022         case SSL3_RT_ALERT: {
   1023             return "SSL3_RT_ALERT";
   1024         }
   1025         case SSL3_RT_HANDSHAKE: {
   1026             return "SSL3_RT_HANDSHAKE";
   1027         }
   1028         case SSL3_RT_APPLICATION_DATA: {
   1029             return "SSL3_RT_APPLICATION_DATA";
   1030         }
   1031         default: {
   1032             LOGD("Unknown TLS/SSL content type %d", content_type);
   1033             return "<unknown>";
   1034         }
   1035     }
   1036 }
   1037 #endif
   1038 
   1039 #ifdef WITH_JNI_TRACE
   1040 /**
   1041  * Simple logging call back to show hand shake messages
   1042  */
   1043 static void ssl_msg_callback_LOG(int write_p, int ssl_version, int content_type,
   1044                                  const void* buf, size_t len, SSL* ssl, void* arg) {
   1045   JNI_TRACE("ssl=%p SSL msg %s %s %s %p %d %p",
   1046            ssl,
   1047            (write_p) ? "send" : "recv",
   1048            get_ssl_version(ssl_version),
   1049            get_content_type(content_type),
   1050            buf,
   1051            len,
   1052            arg);
   1053 }
   1054 #endif
   1055 
   1056 #ifdef WITH_JNI_TRACE
   1057 /**
   1058  * Based on example logging call back from SSL_CTX_set_info_callback man page
   1059  */
   1060 static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, int ret)
   1061 {
   1062     int w = where & ~SSL_ST_MASK;
   1063     const char* str;
   1064     if (w & SSL_ST_CONNECT) {
   1065         str = "SSL_connect";
   1066     } else if (w & SSL_ST_ACCEPT) {
   1067         str = "SSL_accept";
   1068     } else {
   1069         str = "undefined";
   1070     }
   1071 
   1072     if (where & SSL_CB_LOOP) {
   1073         JNI_TRACE("ssl=%p %s:%s %s", s, str, SSL_state_string(s), SSL_state_string_long(s));
   1074     } else if (where & SSL_CB_ALERT) {
   1075         str = (where & SSL_CB_READ) ? "read" : "write";
   1076         JNI_TRACE("ssl=%p SSL3 alert %s:%s:%s %s %s",
   1077                   s,
   1078                   str,
   1079                   SSL_alert_type_string(ret),
   1080                   SSL_alert_desc_string(ret),
   1081                   SSL_alert_type_string_long(ret),
   1082                   SSL_alert_desc_string_long(ret));
   1083     } else if (where & SSL_CB_EXIT) {
   1084         if (ret == 0) {
   1085             JNI_TRACE("ssl=%p %s:failed exit in %s %s",
   1086                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   1087         } else if (ret < 0) {
   1088             JNI_TRACE("ssl=%p %s:error exit in %s %s",
   1089                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   1090         } else if (ret == 1) {
   1091             JNI_TRACE("ssl=%p %s:ok exit in %s %s",
   1092                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   1093         } else {
   1094             JNI_TRACE("ssl=%p %s:unknown exit %d in %s %s",
   1095                       s, str, ret, SSL_state_string(s), SSL_state_string_long(s));
   1096         }
   1097     } else if (where & SSL_CB_HANDSHAKE_START) {
   1098         JNI_TRACE("ssl=%p handshake start in %s %s",
   1099                   s, SSL_state_string(s), SSL_state_string_long(s));
   1100     } else if (where & SSL_CB_HANDSHAKE_DONE) {
   1101         JNI_TRACE("ssl=%p handshake done in %s %s",
   1102                   s, SSL_state_string(s), SSL_state_string_long(s));
   1103     } else {
   1104         JNI_TRACE("ssl=%p %s:unknown where %d in %s %s",
   1105                   s, str, where, SSL_state_string(s), SSL_state_string_long(s));
   1106     }
   1107 }
   1108 #endif
   1109 
   1110 /**
   1111  * Returns an array containing all the X509 certificate's bytes.
   1112  */
   1113 static jobjectArray getCertificateBytes(JNIEnv* env, const STACK_OF(X509)* chain)
   1114 {
   1115     if (chain == NULL) {
   1116         // Chain can be NULL if the associated cipher doesn't do certs.
   1117         return NULL;
   1118     }
   1119 
   1120     int count = sk_X509_num(chain);
   1121     if (count <= 0) {
   1122         return NULL;
   1123     }
   1124 
   1125     jobjectArray joa = env->NewObjectArray(count, JniConstants::byteArrayClass, NULL);
   1126     if (joa == NULL) {
   1127         return NULL;
   1128     }
   1129 
   1130     for (int i = 0; i < count; i++) {
   1131         X509* cert = sk_X509_value(chain, i);
   1132 
   1133         int len = i2d_X509(cert, NULL);
   1134         if (len < 0) {
   1135             return NULL;
   1136         }
   1137         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
   1138         if (byteArray.get() == NULL) {
   1139             return NULL;
   1140         }
   1141         ScopedByteArrayRW bytes(env, byteArray.get());
   1142         if (bytes.get() == NULL) {
   1143             return NULL;
   1144         }
   1145         unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
   1146         int n = i2d_X509(cert, &p);
   1147         if (n < 0) {
   1148             return NULL;
   1149         }
   1150         env->SetObjectArrayElement(joa, i, byteArray.get());
   1151     }
   1152 
   1153     return joa;
   1154 }
   1155 
   1156 /**
   1157  * Returns an array containing all the X500 principal's bytes.
   1158  */
   1159 static jobjectArray getPrincipalBytes(JNIEnv* env, const STACK_OF(X509_NAME)* names)
   1160 {
   1161     if (names == NULL) {
   1162         return NULL;
   1163     }
   1164 
   1165     int count = sk_X509_NAME_num(names);
   1166     if (count <= 0) {
   1167         return NULL;
   1168     }
   1169 
   1170     jobjectArray joa = env->NewObjectArray(count, JniConstants::byteArrayClass, NULL);
   1171     if (joa == NULL) {
   1172         return NULL;
   1173     }
   1174 
   1175     for (int i = 0; i < count; i++) {
   1176         X509_NAME* principal = sk_X509_NAME_value(names, i);
   1177 
   1178         int len = i2d_X509_NAME(principal, NULL);
   1179         if (len < 0) {
   1180             return NULL;
   1181         }
   1182         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
   1183         if (byteArray.get() == NULL) {
   1184             return NULL;
   1185         }
   1186         ScopedByteArrayRW bytes(env, byteArray.get());
   1187         if (bytes.get() == NULL) {
   1188             return NULL;
   1189         }
   1190         unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
   1191         int n = i2d_X509_NAME(principal, &p);
   1192         if (n < 0) {
   1193             return NULL;
   1194         }
   1195         env->SetObjectArrayElement(joa, i, byteArray.get());
   1196     }
   1197 
   1198     return joa;
   1199 }
   1200 
   1201 /**
   1202  * Our additional application data needed for getting synchronization right.
   1203  * This maybe warrants a bit of lengthy prose:
   1204  *
   1205  * (1) We use a flag to reflect whether we consider the SSL connection alive.
   1206  * Any read or write attempt loops will be cancelled once this flag becomes 0.
   1207  *
   1208  * (2) We use an int to count the number of threads that are blocked by the
   1209  * underlying socket. This may be at most two (one reader and one writer), since
   1210  * the Java layer ensures that no more threads will enter the native code at the
   1211  * same time.
   1212  *
   1213  * (3) The pipe is used primarily as a means of cancelling a blocking select()
   1214  * when we want to close the connection (aka "emergency button"). It is also
   1215  * necessary for dealing with a possible race condition situation: There might
   1216  * be cases where both threads see an SSL_ERROR_WANT_READ or
   1217  * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
   1218  * If one leaves the select() successfully before the other enters it, the
   1219  * "success" event is already consumed and the second thread will be blocked,
   1220  * possibly forever (depending on network conditions).
   1221  *
   1222  * The idea for solving the problem looks like this: Whenever a thread is
   1223  * successful in moving around data on the network, and it knows there is
   1224  * another thread stuck in a select(), it will write a byte to the pipe, waking
   1225  * up the other thread. A thread that returned from select(), on the other hand,
   1226  * knows whether it's been woken up by the pipe. If so, it will consume the
   1227  * byte, and the original state of affairs has been restored.
   1228  *
   1229  * The pipe may seem like a bit of overhead, but it fits in nicely with the
   1230  * other file descriptors of the select(), so there's only one condition to wait
   1231  * for.
   1232  *
   1233  * (4) Finally, a mutex is needed to make sure that at most one thread is in
   1234  * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
   1235  * requirement. We use the same mutex to guard the field for counting the
   1236  * waiting threads.
   1237  *
   1238  * Note: The current implementation assumes that we don't have to deal with
   1239  * problems induced by multiple cores or processors and their respective
   1240  * memory caches. One possible problem is that of inconsistent views on the
   1241  * "aliveAndKicking" field. This could be worked around by also enclosing all
   1242  * accesses to that field inside a lock/unlock sequence of our mutex, but
   1243  * currently this seems a bit like overkill. Marking volatile at the very least.
   1244  *
   1245  * During handshaking, additional fields are used to up-call into
   1246  * Java to perform certificate verification and handshake
   1247  * completion. These are also used in any renegotiation.
   1248  *
   1249  * (5) the JNIEnv so we can invoke the Java callback
   1250  *
   1251  * (6) a NativeCrypto.SSLHandshakeCallbacks instance for callbacks from native to Java
   1252  *
   1253  * (7) a java.io.FileDescriptor wrapper to check for socket close
   1254  *
   1255  * Because renegotiation can be requested by the peer at any time,
   1256  * care should be taken to maintain an appropriate JNIEnv on any
   1257  * downcall to openssl since it could result in an upcall to Java. The
   1258  * current code does try to cover these cases by conditionally setting
   1259  * the JNIEnv on calls that can read and write to the SSL such as
   1260  * SSL_do_handshake, SSL_read, SSL_write, and SSL_shutdown.
   1261  *
   1262  * Finally, we have one other piece of state setup by OpenSSL callbacks:
   1263  *
   1264  * (8) a set of ephemeral RSA keys that is lazily generated if a peer
   1265  * wants to use an exportable RSA cipher suite.
   1266  *
   1267  */
   1268 class AppData {
   1269   public:
   1270     volatile int aliveAndKicking;
   1271     int waitingThreads;
   1272     int fdsEmergency[2];
   1273     MUTEX_TYPE mutex;
   1274     JNIEnv* env;
   1275     jobject sslHandshakeCallbacks;
   1276     jobject fileDescriptor;
   1277     Unique_RSA ephemeralRsa;
   1278 
   1279     /**
   1280      * Creates the application data context for the SSL*.
   1281      */
   1282   public:
   1283     static AppData* create() {
   1284         UniquePtr<AppData> appData(new AppData());
   1285         if (pipe(appData.get()->fdsEmergency) == -1) {
   1286             return NULL;
   1287         }
   1288         if (!setBlocking(appData.get()->fdsEmergency[0], false)) {
   1289             return NULL;
   1290         }
   1291         if (MUTEX_SETUP(appData.get()->mutex) == -1) {
   1292             return NULL;
   1293         }
   1294         return appData.release();
   1295     }
   1296 
   1297     ~AppData() {
   1298         aliveAndKicking = 0;
   1299         if (fdsEmergency[0] != -1) {
   1300             close(fdsEmergency[0]);
   1301         }
   1302         if (fdsEmergency[1] != -1) {
   1303             close(fdsEmergency[1]);
   1304         }
   1305         MUTEX_CLEANUP(mutex);
   1306     }
   1307 
   1308   private:
   1309     AppData() :
   1310             aliveAndKicking(1),
   1311             waitingThreads(0),
   1312             env(NULL),
   1313             sslHandshakeCallbacks(NULL),
   1314             ephemeralRsa(NULL) {
   1315         fdsEmergency[0] = -1;
   1316         fdsEmergency[1] = -1;
   1317     }
   1318 
   1319   public:
   1320     /**
   1321      * Used to set the SSL-to-Java callback state before each SSL_*
   1322      * call that may result in a callback. It should be cleared after
   1323      * the operation returns with clearCallbackState.
   1324      *
   1325      * @param env The JNIEnv
   1326      * @param shc The SSLHandshakeCallbacks
   1327      * @param fd The FileDescriptor
   1328      */
   1329     bool setCallbackState(JNIEnv* e, jobject shc, jobject fd) {
   1330         NetFd netFd(e, fd);
   1331         if (netFd.isClosed()) {
   1332             return false;
   1333         }
   1334         env = e;
   1335         sslHandshakeCallbacks = shc;
   1336         fileDescriptor = fd;
   1337         return true;
   1338     }
   1339 
   1340     void clearCallbackState() {
   1341         env = NULL;
   1342         sslHandshakeCallbacks = NULL;
   1343         fileDescriptor = NULL;
   1344     }
   1345 
   1346 };
   1347 
   1348 /**
   1349  * Dark magic helper function that checks, for a given SSL session, whether it
   1350  * can SSL_read() or SSL_write() without blocking. Takes into account any
   1351  * concurrent attempts to close the SSLSocket from the Java side. This is
   1352  * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
   1353  * while thread #2 is sitting in a blocking read or write. The type argument
   1354  * specifies whether we are waiting for readability or writability. It expects
   1355  * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
   1356  * only need to wait in case one of these problems occurs.
   1357  *
   1358  * @param env
   1359  * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
   1360  * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL
   1361  * @param appData The application data structure with mutex info etc.
   1362  * @param timeout The timeout value for select call, with the special value
   1363  *                0 meaning no timeout at all (wait indefinitely). Note: This is
   1364  *                the Java semantics of the timeout value, not the usual
   1365  *                select() semantics.
   1366  * @return The result of the inner select() call,
   1367  * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on
   1368  * additional errors
   1369  */
   1370 static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout) {
   1371     // This loop is an expanded version of the NET_FAILURE_RETRY
   1372     // macro. It cannot simply be used in this case because select
   1373     // cannot be restarted without recreating the fd_sets and timeout
   1374     // structure.
   1375     int result;
   1376     fd_set rfds;
   1377     fd_set wfds;
   1378     do {
   1379         NetFd fd(env, fdObject);
   1380         if (fd.isClosed()) {
   1381             result = THROWN_SOCKETEXCEPTION;
   1382             break;
   1383         }
   1384         int intFd = fd.get();
   1385         JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout=%d",
   1386                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout);
   1387 
   1388         FD_ZERO(&rfds);
   1389         FD_ZERO(&wfds);
   1390 
   1391         if (type == SSL_ERROR_WANT_READ) {
   1392             FD_SET(intFd, &rfds);
   1393         } else {
   1394             FD_SET(intFd, &wfds);
   1395         }
   1396 
   1397         FD_SET(appData->fdsEmergency[0], &rfds);
   1398 
   1399         int maxFd = (intFd > appData->fdsEmergency[0]) ? intFd : appData->fdsEmergency[0];
   1400 
   1401         // Build a struct for the timeout data if we actually want a timeout.
   1402         timeval tv;
   1403         timeval* ptv;
   1404         if (timeout > 0) {
   1405             tv.tv_sec = timeout / 1000;
   1406             tv.tv_usec = 0;
   1407             ptv = &tv;
   1408         } else {
   1409             ptv = NULL;
   1410         }
   1411 
   1412         AsynchronousSocketCloseMonitor monitor(intFd);
   1413         result = select(maxFd + 1, &rfds, &wfds, NULL, ptv);
   1414         JNI_TRACE("sslSelect %s fd=%d appData=%p timeout=%d => %d",
   1415                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE",
   1416                   fd.get(), appData, timeout, result);
   1417         if (result == -1) {
   1418             if (fd.isClosed()) {
   1419                 result = THROWN_SOCKETEXCEPTION;
   1420                 break;
   1421             }
   1422             if (errno != EINTR) {
   1423                 break;
   1424             }
   1425         }
   1426     } while (result == -1);
   1427 
   1428     if (MUTEX_LOCK(appData->mutex) == -1) {
   1429         return -1;
   1430     }
   1431 
   1432     if (result > 0) {
   1433         // If we have been woken up by the emergency pipe. We can't be
   1434         // sure there is a token in it because it could have been read
   1435         // by the thread that wrote it between when when we woke up
   1436         // from select and attempt to read it here. Thus we cannot
   1437         // safely read it in a blocking way (so we make it
   1438         // non-blocking at creation).
   1439         if (FD_ISSET(appData->fdsEmergency[0], &rfds)) {
   1440             char token;
   1441             do {
   1442                 read(appData->fdsEmergency[0], &token, 1);
   1443             } while (errno == EINTR);
   1444         }
   1445     }
   1446 
   1447     // Tell the world that there is now one thread less waiting for the
   1448     // underlying network.
   1449     appData->waitingThreads--;
   1450 
   1451     MUTEX_UNLOCK(appData->mutex);
   1452 
   1453     return result;
   1454 }
   1455 
   1456 /**
   1457  * Helper function that wakes up a thread blocked in select(), in case there is
   1458  * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
   1459  * before closing the connection.
   1460  *
   1461  * @param data The application data structure with mutex info etc.
   1462  */
   1463 static void sslNotify(AppData* appData) {
   1464     // Write a byte to the emergency pipe, so a concurrent select() can return.
   1465     // Note we have to restore the errno of the original system call, since the
   1466     // caller relies on it for generating error messages.
   1467     int errnoBackup = errno;
   1468     char token = '*';
   1469     do {
   1470         errno = 0;
   1471         write(appData->fdsEmergency[1], &token, 1);
   1472     } while (errno == EINTR);
   1473     errno = errnoBackup;
   1474 }
   1475 
   1476 // From private header file external/openssl/ssl_locl.h
   1477 // TODO move dependent code to jsse.patch to avoid dependency
   1478 #define SSL_aRSA                0x00000001L
   1479 #define SSL_aDSS                0x00000002L
   1480 #define SSL_aNULL               0x00000004L
   1481 #define SSL_aDH                 0x00000008L
   1482 #define SSL_aECDH               0x00000010L
   1483 #define SSL_aKRB5               0x00000020L
   1484 #define SSL_aECDSA              0x00000040L
   1485 #define SSL_aPSK                0x00000080L
   1486 
   1487 /**
   1488  * Converts an SSL_CIPHER's algorithms field to a TrustManager auth argument
   1489  */
   1490 // TODO move to jsse.patch
   1491 static const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
   1492 {
   1493     unsigned long alg_auth = cipher->algorithm_auth;
   1494 
   1495     const char* au;
   1496     switch (alg_auth) {
   1497         case SSL_aRSA:
   1498             au="RSA";
   1499             break;
   1500         case SSL_aDSS:
   1501             au="DSS";
   1502             break;
   1503         case SSL_aDH:
   1504             au="DH";
   1505             break;
   1506         case SSL_aKRB5:
   1507             au="KRB5";
   1508             break;
   1509         case SSL_aECDH:
   1510             au = "ECDH";
   1511             break;
   1512         case SSL_aNULL:
   1513             au="None";
   1514             break;
   1515         case SSL_aECDSA:
   1516             au="ECDSA";
   1517             break;
   1518         case SSL_aPSK:
   1519             au="PSK";
   1520             break;
   1521         default:
   1522             au="unknown";
   1523             break;
   1524     }
   1525     return au;
   1526 }
   1527 
   1528 /**
   1529  * Converts an SSL_CIPHER's algorithms field to a TrustManager auth argument
   1530  */
   1531 // TODO move to jsse.patch
   1532 static const char* SSL_authentication_method(SSL* ssl)
   1533 {
   1534     switch (ssl->version) {
   1535       case SSL2_VERSION:
   1536         return "RSA";
   1537       case SSL3_VERSION:
   1538       case TLS1_VERSION:
   1539       case DTLS1_VERSION:
   1540         return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
   1541       default:
   1542         return "unknown";
   1543     }
   1544 }
   1545 
   1546 static AppData* toAppData(const SSL* ssl) {
   1547     return reinterpret_cast<AppData*>(SSL_get_app_data(ssl));
   1548 }
   1549 
   1550 /**
   1551  * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback
   1552  */
   1553 static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused)))
   1554 {
   1555     /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
   1556     SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx,
   1557             SSL_get_ex_data_X509_STORE_CTX_idx()));
   1558     JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg);
   1559 
   1560     AppData* appData = toAppData(ssl);
   1561     JNIEnv* env = appData->env;
   1562     if (env == NULL) {
   1563         LOGE("AppData->env missing in cert_verify_callback");
   1564         JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl);
   1565         return 0;
   1566     }
   1567     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   1568 
   1569     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   1570     jmethodID methodID
   1571         = env->GetMethodID(cls, "verifyCertificateChain", "([[BLjava/lang/String;)V");
   1572 
   1573     jobjectArray objectArray = getCertificateBytes(env, x509_store_ctx->untrusted);
   1574 
   1575     const char* authMethod = SSL_authentication_method(ssl);
   1576     JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s",
   1577               ssl, authMethod);
   1578     jstring authMethodString = env->NewStringUTF(authMethod);
   1579     env->CallVoidMethod(sslHandshakeCallbacks, methodID, objectArray, authMethodString);
   1580 
   1581     int result = (env->ExceptionCheck()) ? 0 : 1;
   1582     JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result);
   1583     return result;
   1584 }
   1585 
   1586 /**
   1587  * Call back to watch for handshake to be completed. This is necessary
   1588  * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake
   1589  * returns before the handshake is completed in this case.
   1590  */
   1591 static void info_callback(const SSL* ssl, int where, int ret __attribute__ ((unused))) {
   1592     JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret);
   1593 #ifdef WITH_JNI_TRACE
   1594     info_callback_LOG(ssl, where, ret);
   1595 #endif
   1596     if (!(where & SSL_CB_HANDSHAKE_DONE)) {
   1597         JNI_TRACE("ssl=%p info_callback ignored", ssl);
   1598         return;
   1599     }
   1600 
   1601     AppData* appData = toAppData(ssl);
   1602     JNIEnv* env = appData->env;
   1603     if (env == NULL) {
   1604         LOGE("AppData->env missing in info_callback");
   1605         JNI_TRACE("ssl=%p info_callback env error", ssl);
   1606         return;
   1607     }
   1608     if (env->ExceptionCheck()) {
   1609         JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
   1610         return;
   1611     }
   1612 
   1613     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   1614 
   1615     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   1616     jmethodID methodID = env->GetMethodID(cls, "handshakeCompleted", "()V");
   1617 
   1618     JNI_TRACE("ssl=%p info_callback calling handshakeCompleted", ssl);
   1619     env->CallVoidMethod(sslHandshakeCallbacks, methodID);
   1620 
   1621     if (env->ExceptionCheck()) {
   1622         JNI_TRACE("ssl=%p info_callback exception", ssl);
   1623     }
   1624     JNI_TRACE("ssl=%p info_callback completed", ssl);
   1625 }
   1626 
   1627 /**
   1628  * Call back to ask for a client certificate
   1629  */
   1630 static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) {
   1631     JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut);
   1632 
   1633     AppData* appData = toAppData(ssl);
   1634     JNIEnv* env = appData->env;
   1635     if (env == NULL) {
   1636         LOGE("AppData->env missing in client_cert_cb");
   1637         JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl);
   1638         return 0;
   1639     }
   1640     if (env->ExceptionCheck()) {
   1641         JNI_TRACE("ssl=%p client_cert_cb already pending exception", ssl);
   1642         return 0;
   1643     }
   1644     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   1645 
   1646     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   1647     jmethodID methodID
   1648         = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V");
   1649 
   1650     // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values
   1651     char ssl2_ctype = SSL3_CT_RSA_SIGN;
   1652     const char* ctype = NULL;
   1653     int ctype_num = 0;
   1654     jobjectArray issuers = NULL;
   1655     switch (ssl->version) {
   1656         case SSL2_VERSION:
   1657             ctype = &ssl2_ctype;
   1658             ctype_num = 1;
   1659             break;
   1660         case SSL3_VERSION:
   1661         case TLS1_VERSION:
   1662         case DTLS1_VERSION:
   1663             ctype = ssl->s3->tmp.ctype;
   1664             ctype_num = ssl->s3->tmp.ctype_num;
   1665             issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names);
   1666             break;
   1667     }
   1668 #ifdef WITH_JNI_TRACE
   1669     for (int i = 0; i < ctype_num; i++) {
   1670         JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]);
   1671     }
   1672 #endif
   1673 
   1674     jbyteArray keyTypes = env->NewByteArray(ctype_num);
   1675     if (keyTypes == NULL) {
   1676         JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl);
   1677         return 0;
   1678     }
   1679     env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype));
   1680 
   1681     JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested "
   1682               "keyTypes=%p issuers=%p", ssl, keyTypes, issuers);
   1683     env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers);
   1684 
   1685     if (env->ExceptionCheck()) {
   1686         JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl);
   1687         return 0;
   1688     }
   1689 
   1690     // Check for values set from Java
   1691     X509*     certificate = SSL_get_certificate(ssl);
   1692     EVP_PKEY* privatekey  = SSL_get_privatekey(ssl);
   1693     int result;
   1694     if (certificate != NULL && privatekey != NULL) {
   1695         *x509Out = certificate;
   1696         *pkeyOut = privatekey;
   1697         result = 1;
   1698     } else {
   1699         *x509Out = NULL;
   1700         *pkeyOut = NULL;
   1701         result = 0;
   1702     }
   1703     JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result);
   1704     return result;
   1705 }
   1706 
   1707 static RSA* rsaGenerateKey(int keylength) {
   1708     Unique_BIGNUM bn(BN_new());
   1709     if (bn.get() == NULL) {
   1710         return NULL;
   1711     }
   1712     int setWordResult = BN_set_word(bn.get(), RSA_F4);
   1713     if (setWordResult != 1) {
   1714         return NULL;
   1715     }
   1716     Unique_RSA rsa(RSA_new());
   1717     if (rsa.get() == NULL) {
   1718         return NULL;
   1719     }
   1720     int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL);
   1721     if (generateResult != 1) {
   1722         return NULL;
   1723     }
   1724     return rsa.release();
   1725 }
   1726 
   1727 /**
   1728  * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5)
   1729  */
   1730 static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)),
   1731                              int is_export __attribute__ ((unused)),
   1732                              int keylength) {
   1733     JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   1734 
   1735     AppData* appData = toAppData(ssl);
   1736     if (appData->ephemeralRsa.get() == NULL) {
   1737         JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl);
   1738         appData->ephemeralRsa.reset(rsaGenerateKey(keylength));
   1739     }
   1740     JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get());
   1741     return appData->ephemeralRsa.get();
   1742 }
   1743 
   1744 static DH* dhGenerateParameters(int keylength) {
   1745 
   1746     /*
   1747      * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two
   1748      * different options for generating DH keys. One is generating the
   1749      * keys using a single set of DH parameters. However, generating
   1750      * DH parameters is slow enough (minutes) that they suggest doing
   1751      * it once at install time. The other is to generate DH keys from
   1752      * DSA parameters. Generating DSA parameters is faster than DH
   1753      * parameters, but to prevent small subgroup attacks, they needed
   1754      * to be regenerated for each set of DH keys. Setting the
   1755      * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back
   1756      * for new DH parameters every type it needs to generate DH keys.
   1757      */
   1758 #if 0
   1759     // Slow path that takes minutes but could be cached
   1760     Unique_DH dh(DH_new());
   1761     if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) {
   1762         return NULL;
   1763     }
   1764     return dh.release();
   1765 #else
   1766     // Faster path but must have SSL_OP_SINGLE_DH_USE set
   1767     Unique_DSA dsa(DSA_new());
   1768     if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) {
   1769         return NULL;
   1770     }
   1771     DH* dh = DSA_dup_DH(dsa.get());
   1772     return dh;
   1773 #endif
   1774 }
   1775 
   1776 /**
   1777  * Call back to ask for Diffie-Hellman parameters
   1778  */
   1779 static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)),
   1780                            int is_export __attribute__ ((unused)),
   1781                            int keylength) {
   1782     JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   1783     DH* tmp_dh = dhGenerateParameters(keylength);
   1784     JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh);
   1785     return tmp_dh;
   1786 }
   1787 
   1788 /*
   1789  * public static native int SSL_CTX_new();
   1790  */
   1791 static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
   1792     Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
   1793     if (sslCtx.get() == NULL) {
   1794         jniThrowRuntimeException(env, "SSL_CTX_new");
   1795         return NULL;
   1796     }
   1797     SSL_CTX_set_options(sslCtx.get(),
   1798                         SSL_OP_ALL
   1799                         // Note: We explicitly do not allow SSLv2 to be used.
   1800                         | SSL_OP_NO_SSLv2
   1801                         // We also disable session tickets for better compatibility b/2682876
   1802                         | SSL_OP_NO_TICKET
   1803                         // We also disable compression for better compatibility b/2710492 b/2710497
   1804                         | SSL_OP_NO_COMPRESSION
   1805                         // Because dhGenerateParameters uses DSA_generate_parameters_ex
   1806                         | SSL_OP_SINGLE_DH_USE);
   1807 
   1808     int mode = SSL_CTX_get_mode(sslCtx.get());
   1809     /*
   1810      * Turn on "partial write" mode. This means that SSL_write() will
   1811      * behave like Posix write() and possibly return after only
   1812      * writing a partial buffer. Note: The alternative, perhaps
   1813      * surprisingly, is not that SSL_write() always does full writes
   1814      * but that it will force you to retry write calls having
   1815      * preserved the full state of the original call. (This is icky
   1816      * and undesirable.)
   1817      */
   1818     mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
   1819 #if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
   1820     mode |= SSL_MODE_SMALL_BUFFERS;  /* lazily allocate record buffers; usually saves
   1821                                       * 44k over the default */
   1822 #endif
   1823 #if defined(SSL_MODE_HANDSHAKE_CUTTHROUGH) /* not all SSL versions have this */
   1824     mode |= SSL_MODE_HANDSHAKE_CUTTHROUGH;  /* enable sending of client data as soon as
   1825                                              * ClientCCS and ClientFinished are sent */
   1826 #endif
   1827     SSL_CTX_set_mode(sslCtx.get(), mode);
   1828 
   1829     SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL);
   1830     SSL_CTX_set_info_callback(sslCtx.get(), info_callback);
   1831     SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb);
   1832     SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback);
   1833     SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback);
   1834 
   1835 #ifdef WITH_JNI_TRACE
   1836     SSL_CTX_set_msg_callback(sslCtx.get(), ssl_msg_callback_LOG); /* enable for message debug */
   1837 #endif
   1838     JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
   1839     return (jint) sslCtx.release();
   1840 }
   1841 
   1842 /**
   1843  * public static native void SSL_CTX_free(int ssl_ctx)
   1844  */
   1845 static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
   1846         jclass, jint ssl_ctx_address)
   1847 {
   1848     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   1849     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
   1850     if (ssl_ctx == NULL) {
   1851         return;
   1852     }
   1853     SSL_CTX_free(ssl_ctx);
   1854 }
   1855 
   1856 /**
   1857  * public static native int SSL_new(int ssl_ctx) throws SSLException;
   1858  */
   1859 static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address)
   1860 {
   1861     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   1862     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
   1863     if (ssl_ctx == NULL) {
   1864         return NULL;
   1865     }
   1866     Unique_SSL ssl(SSL_new(ssl_ctx));
   1867     if (ssl.get() == NULL) {
   1868         throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE,
   1869                 "Unable to create SSL structure");
   1870         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
   1871         return NULL;
   1872     }
   1873 
   1874     /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
   1875      * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
   1876      * (by default disabled), the server will send a certificate which will
   1877      * be checked. The result of the certificate verification process can be
   1878      * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
   1879      * function. The handshake will be continued regardless of the
   1880      * verification result.
   1881      */
   1882     SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL);
   1883 
   1884     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get());
   1885     return (jint) ssl.release();
   1886 }
   1887 
   1888 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass,
   1889                                             jint ssl_address, jbyteArray privatekey)
   1890 {
   1891     SSL* ssl = to_SSL(env, ssl_address, true);
   1892     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey privatekey=%p", ssl, privatekey);
   1893     if (ssl == NULL) {
   1894         return;
   1895     }
   1896 
   1897     ScopedByteArrayRO buf(env, privatekey);
   1898     if (buf.get() == NULL) {
   1899         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => threw exception", ssl);
   1900         return;
   1901     }
   1902     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   1903     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, buf.size()));
   1904     if (pkcs8.get() == NULL) {
   1905         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   1906         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   1907                                        "Error parsing private key from DER to PKCS8");
   1908         SSL_clear(ssl);
   1909         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from DER to PKCS8", ssl);
   1910         return;
   1911     }
   1912 
   1913     Unique_EVP_PKEY privatekeyevp(EVP_PKCS82PKEY(pkcs8.get()));
   1914     if (privatekeyevp.get() == NULL) {
   1915         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   1916         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   1917                                        "Error creating private key from PKCS8");
   1918         SSL_clear(ssl);
   1919         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from PKCS8 to key", ssl);
   1920         return;
   1921     }
   1922 
   1923     int ret = SSL_use_PrivateKey(ssl, privatekeyevp.get());
   1924     if (ret == 1) {
   1925         privatekeyevp.release();
   1926     } else {
   1927         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   1928         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
   1929         SSL_clear(ssl);
   1930         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error", ssl);
   1931         return;
   1932     }
   1933 
   1934     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => ok", ssl);
   1935 }
   1936 
   1937 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
   1938                                              jint ssl_address, jobjectArray certificates)
   1939 {
   1940     SSL* ssl = to_SSL(env, ssl_address, true);
   1941     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
   1942     if (ssl == NULL) {
   1943         return;
   1944     }
   1945 
   1946     if (certificates == NULL) {
   1947         jniThrowNullPointerException(env, "certificates == null");
   1948         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
   1949         return;
   1950     }
   1951 
   1952     int length = env->GetArrayLength(certificates);
   1953     if (length == 0) {
   1954         jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
   1955         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
   1956         return;
   1957     }
   1958 
   1959     Unique_X509 certificatesX509[length];
   1960     for (int i = 0; i < length; i++) {
   1961         ScopedLocalRef<jbyteArray> certificate(env,
   1962                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i)));
   1963         if (certificate.get() == NULL) {
   1964             jniThrowNullPointerException(env, "certificates element == null");
   1965             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl);
   1966             return;
   1967         }
   1968 
   1969         ScopedByteArrayRO buf(env, certificate.get());
   1970         if (buf.get() == NULL) {
   1971             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl);
   1972             return;
   1973         }
   1974         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   1975         certificatesX509[i].reset(d2i_X509(NULL, &tmp, buf.size()));
   1976 
   1977         if (certificatesX509[i].get() == NULL) {
   1978             LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   1979             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
   1980             SSL_clear(ssl);
   1981             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
   1982             return;
   1983         }
   1984     }
   1985 
   1986     int ret = SSL_use_certificate(ssl, certificatesX509[0].get());
   1987     if (ret == 1) {
   1988         certificatesX509[0].release();
   1989     } else {
   1990         LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   1991         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
   1992         SSL_clear(ssl);
   1993         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
   1994         return;
   1995     }
   1996 
   1997     Unique_sk_X509 chain(sk_X509_new_null());
   1998     if (chain.get() == NULL) {
   1999         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
   2000         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
   2001         return;
   2002     }
   2003     for (int i = 1; i < length; i++) {
   2004         if (!sk_X509_push(chain.get(), certificatesX509[i].release())) {
   2005             jniThrowOutOfMemoryError(env, "Unable to push certificate");
   2006             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl);
   2007             return;
   2008         }
   2009     }
   2010     int chainResult = SSL_use_certificate_chain(ssl, chain.get());
   2011     if (chainResult == 0) {
   2012         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
   2013         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
   2014                   ssl);
   2015         return;
   2016     } else {
   2017         chain.release();
   2018     }
   2019 
   2020     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
   2021 }
   2022 
   2023 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jint ssl_address)
   2024 {
   2025     SSL* ssl = to_SSL(env, ssl_address, true);
   2026     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
   2027     if (ssl == NULL) {
   2028         return;
   2029     }
   2030     int ret = SSL_check_private_key(ssl);
   2031     if (ret != 1) {
   2032         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
   2033         SSL_clear(ssl);
   2034         JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
   2035         return;
   2036     }
   2037     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
   2038 }
   2039 
   2040 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
   2041                                                 jint ssl_address, jobjectArray principals)
   2042 {
   2043     SSL* ssl = to_SSL(env, ssl_address, true);
   2044     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
   2045     if (ssl == NULL) {
   2046         return;
   2047     }
   2048 
   2049     if (principals == NULL) {
   2050         jniThrowNullPointerException(env, "principals == null");
   2051         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
   2052         return;
   2053     }
   2054 
   2055     int length = env->GetArrayLength(principals);
   2056     if (length == 0) {
   2057         jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
   2058         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
   2059         return;
   2060     }
   2061 
   2062     Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
   2063     if (principalsStack.get() == NULL) {
   2064         jniThrowOutOfMemoryError(env, "Unable to allocate principal stack");
   2065         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
   2066         return;
   2067     }
   2068     for (int i = 0; i < length; i++) {
   2069         ScopedLocalRef<jbyteArray> principal(env,
   2070                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
   2071         if (principal.get() == NULL) {
   2072             jniThrowNullPointerException(env, "principals element == null");
   2073             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
   2074             return;
   2075         }
   2076 
   2077         ScopedByteArrayRO buf(env, principal.get());
   2078         if (buf.get() == NULL) {
   2079             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
   2080             return;
   2081         }
   2082         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2083         Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
   2084 
   2085         if (principalX509Name.get() == NULL) {
   2086             LOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2087             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
   2088             SSL_clear(ssl);
   2089             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
   2090                       ssl);
   2091             return;
   2092         }
   2093 
   2094         if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
   2095             jniThrowOutOfMemoryError(env, "Unable to push principal");
   2096             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
   2097             return;
   2098         }
   2099     }
   2100 
   2101     SSL_set_client_CA_list(ssl, principalsStack.release());
   2102     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
   2103 }
   2104 
   2105 /**
   2106  * public static native long SSL_get_mode(int ssl);
   2107  */
   2108 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jint ssl_address) {
   2109     SSL* ssl = to_SSL(env, ssl_address, true);
   2110     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
   2111     if (ssl == NULL) {
   2112       return 0;
   2113     }
   2114     long mode = SSL_get_mode(ssl);
   2115     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
   2116     return mode;
   2117 }
   2118 
   2119 /**
   2120  * public static native long SSL_set_mode(int ssl, long mode);
   2121  */
   2122 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
   2123         jint ssl_address, jlong mode) {
   2124     SSL* ssl = to_SSL(env, ssl_address, true);
   2125     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
   2126     if (ssl == NULL) {
   2127       return 0;
   2128     }
   2129     long result = SSL_set_mode(ssl, mode);
   2130     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
   2131     return result;
   2132 }
   2133 
   2134 /**
   2135  * public static native long SSL_clear_mode(int ssl, long mode);
   2136  */
   2137 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
   2138         jint ssl_address, jlong mode) {
   2139     SSL* ssl = to_SSL(env, ssl_address, true);
   2140     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
   2141     if (ssl == NULL) {
   2142       return 0;
   2143     }
   2144     long result = SSL_clear_mode(ssl, mode);
   2145     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
   2146     return result;
   2147 }
   2148 
   2149 /**
   2150  * public static native long SSL_get_options(int ssl);
   2151  */
   2152 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
   2153         jint ssl_address) {
   2154     SSL* ssl = to_SSL(env, ssl_address, true);
   2155     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
   2156     if (ssl == NULL) {
   2157       return 0;
   2158     }
   2159     long options = SSL_get_options(ssl);
   2160     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
   2161     return options;
   2162 }
   2163 
   2164 /**
   2165  * public static native long SSL_set_options(int ssl, long options);
   2166  */
   2167 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
   2168         jint ssl_address, jlong options) {
   2169     SSL* ssl = to_SSL(env, ssl_address, true);
   2170     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
   2171     if (ssl == NULL) {
   2172       return 0;
   2173     }
   2174     long result = SSL_set_options(ssl, options);
   2175     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
   2176     return result;
   2177 }
   2178 
   2179 /**
   2180  * public static native long SSL_clear_options(int ssl, long options);
   2181  */
   2182 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
   2183         jint ssl_address, jlong options) {
   2184     SSL* ssl = to_SSL(env, ssl_address, true);
   2185     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
   2186     if (ssl == NULL) {
   2187       return 0;
   2188     }
   2189     long result = SSL_clear_options(ssl, options);
   2190     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
   2191     return result;
   2192 }
   2193 
   2194 /**
   2195  * Sets the ciphers suites that are enabled in the SSL
   2196  */
   2197 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
   2198         jint ssl_address, jobjectArray cipherSuites)
   2199 {
   2200     SSL* ssl = to_SSL(env, ssl_address, true);
   2201     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
   2202     if (ssl == NULL) {
   2203         return;
   2204     }
   2205     if (cipherSuites == NULL) {
   2206         jniThrowNullPointerException(env, "cipherSuites == null");
   2207         return;
   2208     }
   2209 
   2210     Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
   2211     if (cipherstack.get() == NULL) {
   2212         jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
   2213         return;
   2214     }
   2215 
   2216     const SSL_METHOD* ssl_method = ssl->method;
   2217     int num_ciphers = ssl_method->num_ciphers();
   2218 
   2219     int length = env->GetArrayLength(cipherSuites);
   2220     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
   2221     for (int i = 0; i < length; i++) {
   2222         ScopedLocalRef<jstring> cipherSuite(env,
   2223                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
   2224         ScopedUtfChars c(env, cipherSuite.get());
   2225         if (c.c_str() == NULL) {
   2226             return;
   2227         }
   2228         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
   2229         bool found = false;
   2230         for (int j = 0; j < num_ciphers; j++) {
   2231             const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
   2232             if ((strcmp(c.c_str(), cipher->name) == 0)
   2233                     && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
   2234                 if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
   2235                     jniThrowOutOfMemoryError(env, "Unable to push cipher");
   2236                     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
   2237                     return;
   2238                 }
   2239                 found = true;
   2240             }
   2241         }
   2242         if (!found) {
   2243             jniThrowException(env, "java/lang/IllegalArgumentException",
   2244                               "Could not find cipher suite.");
   2245             return;
   2246         }
   2247     }
   2248 
   2249     int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
   2250     if (rc == 0) {
   2251         freeSslErrorState();
   2252         jniThrowException(env, "java/lang/IllegalArgumentException",
   2253                           "Illegal cipher suite strings.");
   2254     } else {
   2255         cipherstack.release();
   2256     }
   2257 }
   2258 
   2259 /**
   2260  * Sets certificate expectations, especially for server to request client auth
   2261  */
   2262 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
   2263         jclass, jint ssl_address, jint mode)
   2264 {
   2265     SSL* ssl = to_SSL(env, ssl_address, true);
   2266     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
   2267     if (ssl == NULL) {
   2268       return;
   2269     }
   2270     SSL_set_verify(ssl, (int)mode, NULL);
   2271 }
   2272 
   2273 /**
   2274  * Sets the ciphers suites that are enabled in the SSL
   2275  */
   2276 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
   2277         jint ssl_address, jint ssl_session_address)
   2278 {
   2279     SSL* ssl = to_SSL(env, ssl_address, true);
   2280     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
   2281     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
   2282     if (ssl == NULL) {
   2283         return;
   2284     }
   2285 
   2286     int ret = SSL_set_session(ssl, ssl_session);
   2287     if (ret != 1) {
   2288         /*
   2289          * Translate the error, and throw if it turns out to be a real
   2290          * problem.
   2291          */
   2292         int sslErrorCode = SSL_get_error(ssl, ret);
   2293         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
   2294             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
   2295             SSL_clear(ssl);
   2296         }
   2297     }
   2298 }
   2299 
   2300 /**
   2301  * Sets the ciphers suites that are enabled in the SSL
   2302  */
   2303 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
   2304         jint ssl_address, jboolean creation_enabled)
   2305 {
   2306     SSL* ssl = to_SSL(env, ssl_address, true);
   2307     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
   2308               ssl, creation_enabled);
   2309     if (ssl == NULL) {
   2310         return;
   2311     }
   2312     SSL_set_session_creation_enabled(ssl, creation_enabled);
   2313 }
   2314 
   2315 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
   2316         jint ssl_address, jstring hostname)
   2317 {
   2318     SSL* ssl = to_SSL(env, ssl_address, true);
   2319     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
   2320               ssl, hostname);
   2321     if (ssl == NULL) {
   2322         return;
   2323     }
   2324 
   2325     ScopedUtfChars hostnameChars(env, hostname);
   2326     if (hostnameChars.c_str() == NULL) {
   2327         return;
   2328     }
   2329     JNI_TRACE("NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s", hostnameChars.c_str());
   2330 
   2331     int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
   2332     if (ret != 1) {
   2333         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
   2334         SSL_clear(ssl);
   2335         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
   2336         return;
   2337     }
   2338     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
   2339 }
   2340 
   2341 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jint ssl_address) {
   2342     SSL* ssl = to_SSL(env, ssl_address, true);
   2343     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
   2344     if (ssl == NULL) {
   2345         return NULL;
   2346     }
   2347     const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
   2348     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
   2349     return env->NewStringUTF(servername);
   2350 }
   2351 
   2352 /**
   2353  * Perform SSL handshake
   2354  */
   2355 static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass,
   2356     jint ssl_address, jobject fdObject, jobject shc, jint timeout, jboolean client_mode)
   2357 {
   2358     SSL* ssl = to_SSL(env, ssl_address, true);
   2359     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout=%d client_mode=%d",
   2360               ssl, fdObject, shc, timeout, client_mode);
   2361     if (ssl == NULL) {
   2362       return 0;
   2363     }
   2364     if (fdObject == NULL) {
   2365         jniThrowNullPointerException(env, "fd == null");
   2366         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2367         return 0;
   2368     }
   2369     if (shc == NULL) {
   2370         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   2371         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2372         return 0;
   2373     }
   2374 
   2375     NetFd fd(env, fdObject);
   2376     if (fd.isClosed()) {
   2377         // SocketException thrown by NetFd.isClosed
   2378         SSL_clear(ssl);
   2379         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2380         return 0;
   2381     }
   2382 
   2383     int ret = SSL_set_fd(ssl, fd.get());
   2384     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
   2385 
   2386     if (ret != 1) {
   2387         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   2388                                        "Error setting the file descriptor");
   2389         SSL_clear(ssl);
   2390         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2391         return 0;
   2392     }
   2393 
   2394     /*
   2395      * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
   2396      * forever and we can use select() to find out if the socket is ready.
   2397      */
   2398     if (!setBlocking(fd.get(), false)) {
   2399         throwSSLExceptionStr(env, "Unable to make socket non blocking");
   2400         SSL_clear(ssl);
   2401         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2402         return 0;
   2403     }
   2404 
   2405     /*
   2406      * Create our special application data.
   2407      */
   2408     AppData* appData = AppData::create();
   2409     if (appData == NULL) {
   2410         throwSSLExceptionStr(env, "Unable to create application data");
   2411         SSL_clear(ssl);
   2412         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2413         return 0;
   2414     }
   2415     SSL_set_app_data(ssl, reinterpret_cast<char*>(appData));
   2416     JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData);
   2417 
   2418     if (client_mode) {
   2419         SSL_set_connect_state(ssl);
   2420     } else {
   2421         SSL_set_accept_state(ssl);
   2422     }
   2423 
   2424     ret = 0;
   2425     while (appData->aliveAndKicking) {
   2426         errno = 0;
   2427 
   2428         if (!appData->setCallbackState(env, shc, fdObject)) {
   2429             // SocketException thrown by NetFd.isClosed
   2430             SSL_clear(ssl);
   2431             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2432             return 0;
   2433         }
   2434         ret = SSL_do_handshake(ssl);
   2435         appData->clearCallbackState();
   2436         // cert_verify_callback threw exception
   2437         if (env->ExceptionCheck()) {
   2438             SSL_clear(ssl);
   2439             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2440             return 0;
   2441         }
   2442         // success case
   2443         if (ret == 1) {
   2444             break;
   2445         }
   2446         // retry case
   2447         if (errno == EINTR) {
   2448             continue;
   2449         }
   2450         // error case
   2451         int sslError = SSL_get_error(ssl, ret);
   2452         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout=%d",
   2453                   ssl, ret, errno, sslError, timeout);
   2454 
   2455         /*
   2456          * If SSL_do_handshake doesn't succeed due to the socket being
   2457          * either unreadable or unwritable, we use sslSelect to
   2458          * wait for it to become ready. If that doesn't happen
   2459          * before the specified timeout or an error occurs, we
   2460          * cancel the handshake. Otherwise we try the SSL_connect
   2461          * again.
   2462          */
   2463         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   2464             appData->waitingThreads++;
   2465             int selectResult = sslSelect(env, sslError, fdObject, appData, timeout);
   2466 
   2467             if (selectResult == THROWN_SOCKETEXCEPTION) {
   2468                 // SocketException thrown by NetFd.isClosed
   2469                 SSL_clear(ssl);
   2470                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2471                 return 0;
   2472             }
   2473             if (selectResult == -1) {
   2474                 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error");
   2475                 SSL_clear(ssl);
   2476                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2477                 return 0;
   2478             }
   2479             if (selectResult == 0) {
   2480                 throwSocketTimeoutException(env, "SSL handshake timed out");
   2481                 SSL_clear(ssl);
   2482                 freeSslErrorState();
   2483                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2484                 return 0;
   2485             }
   2486         } else {
   2487             // LOGE("Unknown error %d during handshake", error);
   2488             break;
   2489         }
   2490     }
   2491 
   2492     // clean error. See SSL_do_handshake(3SSL) man page.
   2493     if (ret == 0) {
   2494         /*
   2495          * The other side closed the socket before the handshake could be
   2496          * completed, but everything is within the bounds of the TLS protocol.
   2497          * We still might want to find out the real reason of the failure.
   2498          */
   2499         int sslError = SSL_get_error(ssl, ret);
   2500         if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) {
   2501             throwSSLExceptionStr(env, "Connection closed by peer");
   2502         } else {
   2503             throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated");
   2504         }
   2505         SSL_clear(ssl);
   2506         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2507         return 0;
   2508     }
   2509 
   2510     // unclean error. See SSL_do_handshake(3SSL) man page.
   2511     if (ret < 0) {
   2512         /*
   2513          * Translate the error and throw exception. We are sure it is an error
   2514          * at this point.
   2515          */
   2516         int sslError = SSL_get_error(ssl, ret);
   2517         throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted");
   2518         SSL_clear(ssl);
   2519         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => 0", ssl);
   2520         return 0;
   2521     }
   2522     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
   2523     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
   2524     return (jint) ssl_session;
   2525 }
   2526 
   2527 /**
   2528  * Perform SSL renegotiation
   2529  */
   2530 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jint ssl_address)
   2531 {
   2532     SSL* ssl = to_SSL(env, ssl_address, true);
   2533     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
   2534     if (ssl == NULL) {
   2535         return;
   2536     }
   2537     int result = SSL_renegotiate(ssl);
   2538     if (result != 1) {
   2539         throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
   2540         return;
   2541     }
   2542     int ret = SSL_do_handshake(ssl);
   2543     if (ret != 1) {
   2544         int sslError = SSL_get_error(ssl, ret);
   2545         throwSSLExceptionWithSslErrors(env, ssl, sslError,
   2546                                        "Problem with SSL_do_handshake after SSL_renegotiate");
   2547 
   2548         return;
   2549     }
   2550     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
   2551 }
   2552 
   2553 /**
   2554  * public static native byte[][] SSL_get_certificate(int ssl);
   2555  */
   2556 static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jint ssl_address)
   2557 {
   2558     SSL* ssl = to_SSL(env, ssl_address, true);
   2559     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
   2560     if (ssl == NULL) {
   2561         return NULL;
   2562     }
   2563     X509* certificate = SSL_get_certificate(ssl);
   2564     if (certificate == NULL) {
   2565         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   2566         return NULL;
   2567     }
   2568 
   2569     Unique_sk_X509 chain(sk_X509_new_null());
   2570     if (chain.get() == NULL) {
   2571         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
   2572         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
   2573         return NULL;
   2574     }
   2575     if (!sk_X509_push(chain.get(), certificate)) {
   2576         jniThrowOutOfMemoryError(env, "Unable to push local certificate");
   2577         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   2578         return NULL;
   2579     }
   2580     STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
   2581     for (int i=0; i<sk_X509_num(cert_chain); i++) {
   2582         if (!sk_X509_push(chain.get(), sk_X509_value(cert_chain, i))) {
   2583             jniThrowOutOfMemoryError(env, "Unable to push local certificate chain");
   2584             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   2585             return NULL;
   2586         }
   2587     }
   2588 
   2589     jobjectArray objectArray = getCertificateBytes(env, chain.get());
   2590     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray);
   2591     return objectArray;
   2592 }
   2593 
   2594 // Fills a byte[][] with the peer certificates in the chain.
   2595 static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jint ssl_address)
   2596 {
   2597     SSL* ssl = to_SSL(env, ssl_address, true);
   2598     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
   2599     if (ssl == NULL) {
   2600         return NULL;
   2601     }
   2602     STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
   2603     Unique_sk_X509 chain_copy(NULL);
   2604     if (ssl->server) {
   2605         X509* x509 = SSL_get_peer_certificate(ssl);
   2606         if (x509 == NULL) {
   2607             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
   2608             return NULL;
   2609         }
   2610         chain_copy.reset(sk_X509_dup(chain));
   2611         if (chain_copy.get() == NULL) {
   2612             jniThrowOutOfMemoryError(env, "Unable to allocate peer certificate chain");
   2613             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
   2614             return NULL;
   2615         }
   2616         if (!sk_X509_push(chain_copy.get(), x509)) {
   2617             jniThrowOutOfMemoryError(env, "Unable to push server's peer certificate");
   2618             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
   2619             return NULL;
   2620         }
   2621         chain = chain_copy.get();
   2622     }
   2623     jobjectArray objectArray = getCertificateBytes(env, chain);
   2624     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray);
   2625     return objectArray;
   2626 }
   2627 
   2628 /**
   2629  * Helper function which does the actual reading. The Java layer guarantees that
   2630  * at most one thread will enter this function at any given time.
   2631  *
   2632  * @param ssl non-null; the SSL context
   2633  * @param buf non-null; buffer to read into
   2634  * @param len length of the buffer, in bytes
   2635  * @param sslReturnCode original SSL return code
   2636  * @param sslErrorCode filled in with the SSL error code in case of error
   2637  * @return number of bytes read on success, -1 if the connection was
   2638  * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
   2639  */
   2640 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
   2641                    int* sslReturnCode, int* sslErrorCode, int timeout) {
   2642 
   2643     // LOGD("Entering sslRead, caller requests to read %d bytes...", len);
   2644 
   2645     if (len == 0) {
   2646         // Don't bother doing anything in this case.
   2647         return 0;
   2648     }
   2649 
   2650     BIO* bio = SSL_get_rbio(ssl);
   2651 
   2652     AppData* appData = toAppData(ssl);
   2653     if (appData == NULL) {
   2654         return THROW_EXCEPTION;
   2655     }
   2656 
   2657     while (appData->aliveAndKicking) {
   2658         errno = 0;
   2659 
   2660         if (MUTEX_LOCK(appData->mutex) == -1) {
   2661             return -1;
   2662         }
   2663 
   2664         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
   2665 
   2666         // LOGD("Doing SSL_Read()");
   2667         if (!appData->setCallbackState(env, shc, fdObject)) {
   2668             MUTEX_UNLOCK(appData->mutex);
   2669             return THROWN_SOCKETEXCEPTION;
   2670         }
   2671         int result = SSL_read(ssl, buf, len);
   2672         appData->clearCallbackState();
   2673         int sslError = SSL_ERROR_NONE;
   2674         if (result <= 0) {
   2675             sslError = SSL_get_error(ssl, result);
   2676             freeSslErrorState();
   2677         }
   2678         // LOGD("Returned from SSL_Read() with result %d, error code %d", result, sslError);
   2679 
   2680         // If we have been successful in moving data around, check whether it
   2681         // might make sense to wake up other blocked threads, so they can give
   2682         // it a try, too.
   2683         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
   2684                 && appData->waitingThreads > 0) {
   2685             sslNotify(appData);
   2686         }
   2687 
   2688         // If we are blocked by the underlying socket, tell the world that
   2689         // there will be one more waiting thread now.
   2690         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   2691             appData->waitingThreads++;
   2692         }
   2693 
   2694         MUTEX_UNLOCK(appData->mutex);
   2695 
   2696         switch (sslError) {
   2697             // Successfully read at least one byte.
   2698             case SSL_ERROR_NONE: {
   2699                 return result;
   2700             }
   2701 
   2702             // Read zero bytes. End of stream reached.
   2703             case SSL_ERROR_ZERO_RETURN: {
   2704                 return -1;
   2705             }
   2706 
   2707             // Need to wait for availability of underlying layer, then retry.
   2708             case SSL_ERROR_WANT_READ:
   2709             case SSL_ERROR_WANT_WRITE: {
   2710                 int selectResult = sslSelect(env, sslError, fdObject, appData, timeout);
   2711                 if (selectResult == THROWN_SOCKETEXCEPTION) {
   2712                     return THROWN_SOCKETEXCEPTION;
   2713                 }
   2714                 if (selectResult == -1) {
   2715                     *sslReturnCode = -1;
   2716                     *sslErrorCode = sslError;
   2717                     return THROW_EXCEPTION;
   2718                 }
   2719                 if (selectResult == 0) {
   2720                     return THROW_SOCKETTIMEOUTEXCEPTION;
   2721                 }
   2722 
   2723                 break;
   2724             }
   2725 
   2726             // A problem occurred during a system call, but this is not
   2727             // necessarily an error.
   2728             case SSL_ERROR_SYSCALL: {
   2729                 // Connection closed without proper shutdown. Tell caller we
   2730                 // have reached end-of-stream.
   2731                 if (result == 0) {
   2732                     return -1;
   2733                 }
   2734 
   2735                 // System call has been interrupted. Simply retry.
   2736                 if (errno == EINTR) {
   2737                     break;
   2738                 }
   2739 
   2740                 // Note that for all other system call errors we fall through
   2741                 // to the default case, which results in an Exception.
   2742             }
   2743 
   2744             // Everything else is basically an error.
   2745             default: {
   2746                 *sslReturnCode = result;
   2747                 *sslErrorCode = sslError;
   2748                 return THROW_EXCEPTION;
   2749             }
   2750         }
   2751     }
   2752 
   2753     return -1;
   2754 }
   2755 
   2756 /**
   2757  * OpenSSL read function (1): only one chunk is read (returned as jint).
   2758  */
   2759 static jint NativeCrypto_SSL_read_byte(JNIEnv* env, jclass, jint ssl_address,
   2760                                        jobject fdObject, jobject shc, jint timeout)
   2761 {
   2762     SSL* ssl = to_SSL(env, ssl_address, true);
   2763     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte fd=%p shc=%p timeout=%d",
   2764               ssl, fdObject, shc, timeout);
   2765     if (ssl == NULL) {
   2766         return 0;
   2767     }
   2768     if (fdObject == NULL) {
   2769         jniThrowNullPointerException(env, "fd == null");
   2770         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte => 0", ssl);
   2771         return 0;
   2772     }
   2773     if (shc == NULL) {
   2774         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   2775         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte => 0", ssl);
   2776         return 0;
   2777     }
   2778 
   2779     unsigned char byteRead;
   2780     int returnCode = 0;
   2781     int sslErrorCode = SSL_ERROR_NONE;
   2782 
   2783     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(&byteRead), 1,
   2784                       &returnCode, &sslErrorCode, timeout);
   2785 
   2786     int result;
   2787     switch (ret) {
   2788         case THROW_EXCEPTION:
   2789             // See sslRead() regarding improper failure to handle normal cases.
   2790             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
   2791             result = -1;
   2792             break;
   2793         case THROW_SOCKETTIMEOUTEXCEPTION:
   2794             throwSocketTimeoutException(env, "Read timed out");
   2795             result = -1;
   2796             break;
   2797         case THROWN_SOCKETEXCEPTION:
   2798             // SocketException thrown by NetFd.isClosed
   2799             result = -1;
   2800             break;
   2801         case -1:
   2802             // Propagate EOF upwards.
   2803             result = -1;
   2804             break;
   2805         default:
   2806             // Return the actual char read, make sure it stays 8 bits wide.
   2807             result = ((jint) byteRead) & 0xFF;
   2808             break;
   2809     }
   2810     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_byte => %d", ssl, result);
   2811     return result;
   2812 }
   2813 
   2814 /**
   2815  * OpenSSL read function (2): read into buffer at offset n chunks.
   2816  * Returns 1 (success) or value <= 0 (failure).
   2817  */
   2818 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
   2819                                   jobject shc, jbyteArray b, jint offset, jint len, jint timeout)
   2820 {
   2821     SSL* ssl = to_SSL(env, ssl_address, true);
   2822     JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d timeout=%d",
   2823               ssl, fdObject, shc, b, offset, len, timeout);
   2824     if (ssl == NULL) {
   2825         return 0;
   2826     }
   2827     if (fdObject == NULL) {
   2828         jniThrowNullPointerException(env, "fd == null");
   2829         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
   2830         return 0;
   2831     }
   2832     if (shc == NULL) {
   2833         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   2834         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
   2835         return 0;
   2836     }
   2837 
   2838     ScopedByteArrayRW bytes(env, b);
   2839     if (bytes.get() == NULL) {
   2840         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
   2841         return 0;
   2842     }
   2843     int returnCode = 0;
   2844     int sslErrorCode = SSL_ERROR_NONE;;
   2845 
   2846     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
   2847                       &returnCode, &sslErrorCode, timeout);
   2848 
   2849     int result;
   2850     switch (ret) {
   2851         case THROW_EXCEPTION:
   2852             // See sslRead() regarding improper failure to handle normal cases.
   2853             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
   2854             result = -1;
   2855             break;
   2856         case THROW_SOCKETTIMEOUTEXCEPTION:
   2857             throwSocketTimeoutException(env, "Read timed out");
   2858             result = -1;
   2859             break;
   2860         case THROWN_SOCKETEXCEPTION:
   2861             // SocketException thrown by NetFd.isClosed
   2862             result = -1;
   2863             break;
   2864         default:
   2865             result = ret;
   2866             break;
   2867     }
   2868 
   2869     JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
   2870     return result;
   2871 }
   2872 
   2873 /**
   2874  * Helper function which does the actual writing. The Java layer guarantees that
   2875  * at most one thread will enter this function at any given time.
   2876  *
   2877  * @param ssl non-null; the SSL context
   2878  * @param buf non-null; buffer to write
   2879  * @param len length of the buffer, in bytes
   2880  * @param sslReturnCode original SSL return code
   2881  * @param sslErrorCode filled in with the SSL error code in case of error
   2882  * @return number of bytes read on success, -1 if the connection was
   2883  * cleanly shut down, or THROW_EXCEPTION if an exception should be thrown.
   2884  */
   2885 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
   2886                     int* sslReturnCode, int* sslErrorCode) {
   2887 
   2888     // LOGD("Entering sslWrite(), caller requests to write %d bytes...", len);
   2889 
   2890     if (len == 0) {
   2891         // Don't bother doing anything in this case.
   2892         return 0;
   2893     }
   2894 
   2895     BIO* bio = SSL_get_wbio(ssl);
   2896 
   2897     AppData* appData = toAppData(ssl);
   2898     if (appData == NULL) {
   2899         return THROW_EXCEPTION;
   2900     }
   2901 
   2902     int count = len;
   2903 
   2904     while (appData->aliveAndKicking && len > 0) {
   2905         errno = 0;
   2906 
   2907         if (MUTEX_LOCK(appData->mutex) == -1) {
   2908             return -1;
   2909         }
   2910 
   2911         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
   2912 
   2913         // LOGD("Doing SSL_write() with %d bytes to go", len);
   2914         if (!appData->setCallbackState(env, shc, fdObject)) {
   2915             MUTEX_UNLOCK(appData->mutex);
   2916             return THROWN_SOCKETEXCEPTION;
   2917         }
   2918         int result = SSL_write(ssl, buf, len);
   2919         appData->clearCallbackState();
   2920         int sslError = SSL_ERROR_NONE;
   2921         if (result <= 0) {
   2922             sslError = SSL_get_error(ssl, result);
   2923             freeSslErrorState();
   2924         }
   2925         // LOGD("Returned from SSL_write() with result %d, error code %d", result, error);
   2926 
   2927         // If we have been successful in moving data around, check whether it
   2928         // might make sense to wake up other blocked threads, so they can give
   2929         // it a try, too.
   2930         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
   2931                 && appData->waitingThreads > 0) {
   2932             sslNotify(appData);
   2933         }
   2934 
   2935         // If we are blocked by the underlying socket, tell the world that
   2936         // there will be one more waiting thread now.
   2937         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   2938             appData->waitingThreads++;
   2939         }
   2940 
   2941         MUTEX_UNLOCK(appData->mutex);
   2942 
   2943         switch (sslError) {
   2944             // Successfully wrote at least one byte.
   2945             case SSL_ERROR_NONE: {
   2946                 buf += result;
   2947                 len -= result;
   2948                 break;
   2949             }
   2950 
   2951             // Wrote zero bytes. End of stream reached.
   2952             case SSL_ERROR_ZERO_RETURN: {
   2953                 return -1;
   2954             }
   2955 
   2956             // Need to wait for availability of underlying layer, then retry.
   2957             // The concept of a write timeout doesn't really make sense, and
   2958             // it's also not standard Java behavior, so we wait forever here.
   2959             case SSL_ERROR_WANT_READ:
   2960             case SSL_ERROR_WANT_WRITE: {
   2961                 int selectResult = sslSelect(env, sslError, fdObject, appData, 0);
   2962                 if (selectResult == THROWN_SOCKETEXCEPTION) {
   2963                     return THROWN_SOCKETEXCEPTION;
   2964                 }
   2965                 if (selectResult == -1) {
   2966                     *sslReturnCode = -1;
   2967                     *sslErrorCode = sslError;
   2968                     return THROW_EXCEPTION;
   2969                 }
   2970                 if (selectResult == 0) {
   2971                     return THROW_SOCKETTIMEOUTEXCEPTION;
   2972                 }
   2973 
   2974                 break;
   2975             }
   2976 
   2977             // A problem occurred during a system call, but this is not
   2978             // necessarily an error.
   2979             case SSL_ERROR_SYSCALL: {
   2980                 // Connection closed without proper shutdown. Tell caller we
   2981                 // have reached end-of-stream.
   2982                 if (result == 0) {
   2983                     return -1;
   2984                 }
   2985 
   2986                 // System call has been interrupted. Simply retry.
   2987                 if (errno == EINTR) {
   2988                     break;
   2989                 }
   2990 
   2991                 // Note that for all other system call errors we fall through
   2992                 // to the default case, which results in an Exception.
   2993             }
   2994 
   2995             // Everything else is basically an error.
   2996             default: {
   2997                 *sslReturnCode = result;
   2998                 *sslErrorCode = sslError;
   2999                 return THROW_EXCEPTION;
   3000             }
   3001         }
   3002     }
   3003     // LOGD("Successfully wrote %d bytes", count);
   3004 
   3005     return count;
   3006 }
   3007 
   3008 /**
   3009  * OpenSSL write function (1): only one chunk is written.
   3010  */
   3011 static void NativeCrypto_SSL_write_byte(JNIEnv* env, jclass, jint ssl_address,
   3012                                         jobject fdObject, jobject shc, jint b)
   3013 {
   3014     SSL* ssl = to_SSL(env, ssl_address, true);
   3015     JNI_TRACE("ssl=%p NativeCrypto_SSL_write_byte fd=%p shc=%p b=%d", ssl, fdObject, shc, b);
   3016     if (ssl == NULL) {
   3017         return;
   3018     }
   3019     if (fdObject == NULL) {
   3020         jniThrowNullPointerException(env, "fd == null");
   3021         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_byte => fd == null", ssl);
   3022         return;
   3023     }
   3024     if (shc == NULL) {
   3025         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3026         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_byte => sslHandshakeCallbacks == null", ssl);
   3027         return;
   3028     }
   3029 
   3030     int returnCode = 0;
   3031     int sslErrorCode = SSL_ERROR_NONE;
   3032     char buf[1] = { (char) b };
   3033     int ret = sslWrite(env, ssl, fdObject, shc, buf, 1, &returnCode, &sslErrorCode);
   3034 
   3035     switch (ret) {
   3036         case THROW_EXCEPTION:
   3037             // See sslWrite() regarding improper failure to handle normal cases.
   3038             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
   3039             break;
   3040         case THROW_SOCKETTIMEOUTEXCEPTION:
   3041             throwSocketTimeoutException(env, "Write timed out");
   3042             break;
   3043         case THROWN_SOCKETEXCEPTION:
   3044             // SocketException thrown by NetFd.isClosed
   3045             break;
   3046         default:
   3047             break;
   3048     }
   3049 }
   3050 
   3051 /**
   3052  * OpenSSL write function (2): write into buffer at offset n chunks.
   3053  */
   3054 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
   3055                                    jobject shc, jbyteArray b, jint offset, jint len)
   3056 {
   3057     SSL* ssl = to_SSL(env, ssl_address, true);
   3058     JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d",
   3059               ssl, fdObject, shc, b, offset, len);
   3060     if (ssl == NULL) {
   3061         return;
   3062     }
   3063     if (fdObject == NULL) {
   3064         jniThrowNullPointerException(env, "fd == null");
   3065         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
   3066         return;
   3067     }
   3068     if (shc == NULL) {
   3069         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3070         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
   3071         return;
   3072     }
   3073 
   3074     ScopedByteArrayRO bytes(env, b);
   3075     if (bytes.get() == NULL) {
   3076         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
   3077         return;
   3078     }
   3079     int returnCode = 0;
   3080     int sslErrorCode = SSL_ERROR_NONE;
   3081     int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
   3082                        len, &returnCode, &sslErrorCode);
   3083 
   3084     switch (ret) {
   3085         case THROW_EXCEPTION:
   3086             // See sslWrite() regarding improper failure to handle normal cases.
   3087             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
   3088             break;
   3089         case THROW_SOCKETTIMEOUTEXCEPTION:
   3090             throwSocketTimeoutException(env, "Write timed out");
   3091             break;
   3092         case THROWN_SOCKETEXCEPTION:
   3093             // SocketException thrown by NetFd.isClosed
   3094             break;
   3095         default:
   3096             break;
   3097     }
   3098 }
   3099 
   3100 /**
   3101  * Interrupt any pending IO before closing the socket.
   3102  */
   3103 static void NativeCrypto_SSL_interrupt(
   3104         JNIEnv* env, jclass, jint ssl_address) {
   3105     SSL* ssl = to_SSL(env, ssl_address, false);
   3106     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
   3107     if (ssl == NULL) {
   3108         return;
   3109     }
   3110 
   3111     /*
   3112      * Mark the connection as quasi-dead, then send something to the emergency
   3113      * file descriptor, so any blocking select() calls are woken up.
   3114      */
   3115     AppData* appData = toAppData(ssl);
   3116     if (appData != NULL) {
   3117         appData->aliveAndKicking = 0;
   3118 
   3119         // At most two threads can be waiting.
   3120         sslNotify(appData);
   3121         sslNotify(appData);
   3122     }
   3123 }
   3124 
   3125 /**
   3126  * OpenSSL close SSL socket function.
   3127  */
   3128 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jint ssl_address,
   3129                                       jobject fdObject, jobject shc) {
   3130     SSL* ssl = to_SSL(env, ssl_address, false);
   3131     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
   3132     if (ssl == NULL) {
   3133         return;
   3134     }
   3135     if (fdObject == NULL) {
   3136         jniThrowNullPointerException(env, "fd == null");
   3137         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
   3138         return;
   3139     }
   3140     if (shc == NULL) {
   3141         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3142         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
   3143         return;
   3144     }
   3145 
   3146     AppData* appData = toAppData(ssl);
   3147     if (appData != NULL) {
   3148         if (!appData->setCallbackState(env, shc, fdObject)) {
   3149             // SocketException thrown by NetFd.isClosed
   3150             SSL_clear(ssl);
   3151             freeSslErrorState();
   3152             return;
   3153         }
   3154 
   3155         /*
   3156          * Try to make socket blocking again. OpenSSL literature recommends this.
   3157          */
   3158         int fd = SSL_get_fd(ssl);
   3159         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
   3160         if (fd != -1) {
   3161             setBlocking(fd, true);
   3162         }
   3163 
   3164         int ret = SSL_shutdown(ssl);
   3165         switch (ret) {
   3166             case 0:
   3167                 /*
   3168                  * Shutdown was not successful (yet), but there also
   3169                  * is no error. Since we can't know whether the remote
   3170                  * server is actually still there, and we don't want to
   3171                  * get stuck forever in a second SSL_shutdown() call, we
   3172                  * simply return. This is not security a problem as long
   3173                  * as we close the underlying socket, which we actually
   3174                  * do, because that's where we are just coming from.
   3175                  */
   3176                 break;
   3177             case 1:
   3178                 /*
   3179                  * Shutdown was successful. We can safely return. Hooray!
   3180                  */
   3181                 break;
   3182             default:
   3183                 /*
   3184                  * Everything else is a real error condition. We should
   3185                  * let the Java layer know about this by throwing an
   3186                  * exception.
   3187                  */
   3188                 int sslError = SSL_get_error(ssl, ret);
   3189                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
   3190                 break;
   3191         }
   3192         appData->clearCallbackState();
   3193     }
   3194 
   3195     SSL_clear(ssl);
   3196     freeSslErrorState();
   3197 }
   3198 
   3199 /**
   3200  * public static native void SSL_free(int ssl);
   3201  */
   3202 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jint ssl_address)
   3203 {
   3204     SSL* ssl = to_SSL(env, ssl_address, true);
   3205     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
   3206     if (ssl == NULL) {
   3207         return;
   3208     }
   3209 
   3210     AppData* appData = toAppData(ssl);
   3211     SSL_set_app_data(ssl, NULL);
   3212     delete appData;
   3213     SSL_free(ssl);
   3214 }
   3215 
   3216 /**
   3217  * Gets and returns in a byte array the ID of the actual SSL session.
   3218  */
   3219 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
   3220                                                       jint ssl_session_address) {
   3221     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3222     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
   3223     if (ssl_session == NULL) {
   3224         return NULL;
   3225     }
   3226     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
   3227     if (result != NULL) {
   3228         jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
   3229         env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
   3230     }
   3231     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
   3232              ssl_session, result, ssl_session->session_id_length);
   3233     return result;
   3234 }
   3235 
   3236 /**
   3237  * Gets and returns in a long integer the creation's time of the
   3238  * actual SSL session.
   3239  */
   3240 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jint ssl_session_address) {
   3241     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3242     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
   3243     if (ssl_session == NULL) {
   3244         return 0;
   3245     }
   3246     // result must be jlong, not long or *1000 will overflow
   3247     jlong result = SSL_SESSION_get_time(ssl_session);
   3248     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
   3249     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
   3250     return result;
   3251 }
   3252 
   3253 /**
   3254  * Our implementation of what might be considered
   3255  * SSL_SESSION_get_version, based on SSL_get_version.
   3256  * See get_ssl_version above.
   3257  */
   3258 // TODO move to jsse.patch
   3259 static const char* SSL_SESSION_get_version(SSL_SESSION* ssl_session) {
   3260   return get_ssl_version(ssl_session->ssl_version);
   3261 }
   3262 
   3263 /**
   3264  * Gets and returns in a string the version of the SSL protocol. If it
   3265  * returns the string "unknown" it means that no connection is established.
   3266  */
   3267 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jint ssl_session_address) {
   3268     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3269     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
   3270     if (ssl_session == NULL) {
   3271         return NULL;
   3272     }
   3273     const char* protocol = SSL_SESSION_get_version(ssl_session);
   3274     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
   3275     return env->NewStringUTF(protocol);
   3276 }
   3277 
   3278 /**
   3279  * Gets and returns in a string the cipher negotiated for the SSL session.
   3280  */
   3281 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jint ssl_session_address) {
   3282     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3283     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
   3284     if (ssl_session == NULL) {
   3285         return NULL;
   3286     }
   3287     const SSL_CIPHER* cipher = ssl_session->cipher;
   3288     const char* name = SSL_CIPHER_get_name(cipher);
   3289     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
   3290     return env->NewStringUTF(name);
   3291 }
   3292 
   3293 /**
   3294  * Gets and returns in a string the compression method negotiated for the SSL session.
   3295  */
   3296 static jstring NativeCrypto_SSL_SESSION_compress_meth(JNIEnv* env, jclass,
   3297                                                       jint ssl_ctx_address,
   3298                                                       jint ssl_session_address) {
   3299     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   3300     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3301     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth ssl_ctx=%p",
   3302               ssl_session, ssl_ctx);
   3303     if (ssl_ctx == NULL || ssl_session == NULL) {
   3304         return NULL;
   3305     }
   3306 
   3307     int compress_meth = ssl_session->compress_meth;
   3308     if (compress_meth == 0) {
   3309         const char* name = "NULL";
   3310         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
   3311         return env->NewStringUTF(name);
   3312     }
   3313 
   3314     int num_comp_methods = sk_SSL_COMP_num(ssl_ctx->comp_methods);
   3315     for (int i = 0; i < num_comp_methods; i++) {
   3316         SSL_COMP* comp = sk_SSL_COMP_value(ssl_ctx->comp_methods, i);
   3317         if (comp->id != compress_meth) {
   3318             continue;
   3319         }
   3320         const char* name = ((comp->method && comp->method->type == NID_zlib_compression)
   3321                             ? SN_zlib_compression
   3322                             : (comp->name ? comp->name : "UNKNOWN"));
   3323         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
   3324         return env->NewStringUTF(name);
   3325     }
   3326     throwSSLExceptionStr(env, "Unknown compression method");
   3327     return NULL;
   3328 }
   3329 
   3330 /**
   3331  * Frees the SSL session.
   3332  */
   3333 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jint ssl_session_address) {
   3334     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3335     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
   3336     if (ssl_session == NULL) {
   3337         return;
   3338     }
   3339     SSL_SESSION_free(ssl_session);
   3340 }
   3341 
   3342 
   3343 /**
   3344  * Serializes the native state of the session (ID, cipher, and keys but
   3345  * not certificates). Returns a byte[] containing the DER-encoded state.
   3346  * See apache mod_ssl.
   3347  */
   3348 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jint ssl_session_address) {
   3349     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   3350     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
   3351     if (ssl_session == NULL) {
   3352         return NULL;
   3353     }
   3354 
   3355     // Compute the size of the DER data
   3356     int size = i2d_SSL_SESSION(ssl_session, NULL);
   3357     if (size == 0) {
   3358         JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => NULL", ssl_session);
   3359         return NULL;
   3360     }
   3361 
   3362     jbyteArray javaBytes = env->NewByteArray(size);
   3363     if (javaBytes != NULL) {
   3364         ScopedByteArrayRW bytes(env, javaBytes);
   3365         if (bytes.get() == NULL) {
   3366             JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => threw exception",
   3367                       ssl_session);
   3368             return NULL;
   3369         }
   3370         unsigned char* ucp = reinterpret_cast<unsigned char*>(bytes.get());
   3371         i2d_SSL_SESSION(ssl_session, &ucp);
   3372     }
   3373 
   3374     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => size=%d", ssl_session, size);
   3375     return javaBytes;
   3376 }
   3377 
   3378 /**
   3379  * Deserialize the session.
   3380  */
   3381 static jint NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
   3382     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
   3383 
   3384     ScopedByteArrayRO bytes(env, javaBytes);
   3385     if (bytes.get() == NULL) {
   3386         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
   3387         return 0;
   3388     }
   3389     const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
   3390     SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
   3391 
   3392     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
   3393     return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
   3394 }
   3395 
   3396 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
   3397 #define SSL_CALLBACKS "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto$SSLHandshakeCallbacks;"
   3398 static JNINativeMethod sNativeCryptoMethods[] = {
   3399     NATIVE_METHOD(NativeCrypto, clinit, "()V"),
   3400     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)I"),
   3401     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B)I"),
   3402     NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"),
   3403     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()I"),
   3404     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(I)V"),
   3405     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(I)I"),
   3406     NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(I[BI)I"),
   3407     NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(ILjava/lang/String;)V"),
   3408     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_block_size, "(I)I"),
   3409     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_size, "(I)I"),
   3410     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(I[BII)V"),
   3411     NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(ILjava/lang/String;)V"),
   3412     NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(I[BII)V"),
   3413     NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(I[BIII)I"),
   3414     NATIVE_METHOD(NativeCrypto, verifySignature, "([B[BLjava/lang/String;[B[B)I"),
   3415     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
   3416     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
   3417     NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()I"),
   3418     NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(I)V"),
   3419     NATIVE_METHOD(NativeCrypto, SSL_new, "(I)I"),
   3420     NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(I[B)V"),
   3421     NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(I[[B)V"),
   3422     NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(I)V"),
   3423     NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(I[[B)V"),
   3424     NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(I)J"),
   3425     NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(IJ)J"),
   3426     NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(IJ)J"),
   3427     NATIVE_METHOD(NativeCrypto, SSL_get_options, "(I)J"),
   3428     NATIVE_METHOD(NativeCrypto, SSL_set_options, "(IJ)J"),
   3429     NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(IJ)J"),
   3430     NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(I[Ljava/lang/String;)V"),
   3431     NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(II)V"),
   3432     NATIVE_METHOD(NativeCrypto, SSL_set_session, "(II)V"),
   3433     NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(IZ)V"),
   3434     NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(ILjava/lang/String;)V"),
   3435     NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(I)Ljava/lang/String;"),
   3436     NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "IZ)I"),
   3437     NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(I)V"),
   3438     NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(I)[[B"),
   3439     NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(I)[[B"),
   3440     NATIVE_METHOD(NativeCrypto, SSL_read_byte, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "I)I"),
   3441     NATIVE_METHOD(NativeCrypto, SSL_read, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
   3442     NATIVE_METHOD(NativeCrypto, SSL_write_byte, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "I)V"),
   3443     NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BII)V"),
   3444     NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(I)V"),
   3445     NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(I" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
   3446     NATIVE_METHOD(NativeCrypto, SSL_free, "(I)V"),
   3447     NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(I)[B"),
   3448     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(I)J"),
   3449     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(I)Ljava/lang/String;"),
   3450     NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(I)Ljava/lang/String;"),
   3451     NATIVE_METHOD(NativeCrypto, SSL_SESSION_compress_meth, "(II)Ljava/lang/String;"),
   3452     NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(I)V"),
   3453     NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(I)[B"),
   3454     NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)I"),
   3455 };
   3456 
   3457 int register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
   3458     JNI_TRACE("register_org_apache_harmony_xnet_provider_jsse_NativeCrypto");
   3459     // Register org.apache.harmony.xnet.provider.jsse.NativeCrypto methods
   3460     return jniRegisterNativeMethods(env,
   3461                                     "org/apache/harmony/xnet/provider/jsse/NativeCrypto",
   3462                                     sNativeCryptoMethods,
   3463                                     NELEM(sNativeCryptoMethods));
   3464 }
   3465