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