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/engine.h>
     32 #include <openssl/err.h>
     33 #include <openssl/evp.h>
     34 #include <openssl/rand.h>
     35 #include <openssl/rsa.h>
     36 #include <openssl/ssl.h>
     37 
     38 #include "AsynchronousSocketCloseMonitor.h"
     39 #include "JNIHelp.h"
     40 #include "JniConstants.h"
     41 #include "JniException.h"
     42 #include "NetFd.h"
     43 #include "NetworkUtilities.h"
     44 #include "ScopedLocalRef.h"
     45 #include "ScopedPrimitiveArray.h"
     46 #include "ScopedUtfChars.h"
     47 #include "UniquePtr.h"
     48 
     49 #undef WITH_JNI_TRACE
     50 #undef WITH_JNI_TRACE_DATA
     51 
     52 #ifdef WITH_JNI_TRACE
     53 #define JNI_TRACE(...) \
     54         ((void)ALOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__));     \
     55 /*
     56         ((void)printf("I/" LOG_TAG "-jni:"));         \
     57         ((void)printf(__VA_ARGS__));          \
     58         ((void)printf("\n"))
     59 */
     60 #else
     61 #define JNI_TRACE(...) ((void)0)
     62 #endif
     63 // don't overwhelm logcat
     64 #define WITH_JNI_TRACE_DATA_CHUNK_SIZE 512
     65 
     66 struct BIO_Delete {
     67     void operator()(BIO* p) const {
     68         BIO_free(p);
     69     }
     70 };
     71 typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
     72 
     73 struct BIGNUM_Delete {
     74     void operator()(BIGNUM* p) const {
     75         BN_free(p);
     76     }
     77 };
     78 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
     79 
     80 struct DH_Delete {
     81     void operator()(DH* p) const {
     82         DH_free(p);
     83     }
     84 };
     85 typedef UniquePtr<DH, DH_Delete> Unique_DH;
     86 
     87 struct DSA_Delete {
     88     void operator()(DSA* p) const {
     89         DSA_free(p);
     90     }
     91 };
     92 typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
     93 
     94 struct EC_KEY_Delete {
     95     void operator()(EC_KEY* p) const {
     96         EC_KEY_free(p);
     97     }
     98 };
     99 typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
    100 
    101 struct EVP_MD_CTX_Delete {
    102     void operator()(EVP_MD_CTX* p) const {
    103         EVP_MD_CTX_destroy(p);
    104     }
    105 };
    106 typedef UniquePtr<EVP_MD_CTX, EVP_MD_CTX_Delete> Unique_EVP_MD_CTX;
    107 
    108 struct EVP_CIPHER_CTX_Delete {
    109     void operator()(EVP_CIPHER_CTX* p) const {
    110         EVP_CIPHER_CTX_cleanup(p);
    111     }
    112 };
    113 typedef UniquePtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Delete> Unique_EVP_CIPHER_CTX;
    114 
    115 struct EVP_PKEY_Delete {
    116     void operator()(EVP_PKEY* p) const {
    117         EVP_PKEY_free(p);
    118     }
    119 };
    120 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
    121 
    122 struct PKCS8_PRIV_KEY_INFO_Delete {
    123     void operator()(PKCS8_PRIV_KEY_INFO* p) const {
    124         PKCS8_PRIV_KEY_INFO_free(p);
    125     }
    126 };
    127 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
    128 
    129 struct RSA_Delete {
    130     void operator()(RSA* p) const {
    131         RSA_free(p);
    132     }
    133 };
    134 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
    135 
    136 struct SSL_Delete {
    137     void operator()(SSL* p) const {
    138         SSL_free(p);
    139     }
    140 };
    141 typedef UniquePtr<SSL, SSL_Delete> Unique_SSL;
    142 
    143 struct SSL_CTX_Delete {
    144     void operator()(SSL_CTX* p) const {
    145         SSL_CTX_free(p);
    146     }
    147 };
    148 typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX;
    149 
    150 struct X509_Delete {
    151     void operator()(X509* p) const {
    152         X509_free(p);
    153     }
    154 };
    155 typedef UniquePtr<X509, X509_Delete> Unique_X509;
    156 
    157 struct X509_NAME_Delete {
    158     void operator()(X509_NAME* p) const {
    159         X509_NAME_free(p);
    160     }
    161 };
    162 typedef UniquePtr<X509_NAME, X509_NAME_Delete> Unique_X509_NAME;
    163 
    164 struct sk_SSL_CIPHER_Delete {
    165     void operator()(STACK_OF(SSL_CIPHER)* p) const {
    166         sk_SSL_CIPHER_free(p);
    167     }
    168 };
    169 typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER;
    170 
    171 struct sk_X509_Delete {
    172     void operator()(STACK_OF(X509)* p) const {
    173         sk_X509_free(p);
    174     }
    175 };
    176 typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509;
    177 
    178 struct sk_X509_NAME_Delete {
    179     void operator()(STACK_OF(X509_NAME)* p) const {
    180         sk_X509_NAME_free(p);
    181     }
    182 };
    183 typedef UniquePtr<STACK_OF(X509_NAME), sk_X509_NAME_Delete> Unique_sk_X509_NAME;
    184 
    185 /**
    186  * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
    187  * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
    188  * without triggering a warning by not using the result of release().
    189  */
    190 #define OWNERSHIP_TRANSFERRED(obj) \
    191     typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
    192 
    193 /**
    194  * Frees the SSL error state.
    195  *
    196  * OpenSSL keeps an "error stack" per thread, and given that this code
    197  * can be called from arbitrary threads that we don't keep track of,
    198  * we err on the side of freeing the error state promptly (instead of,
    199  * say, at thread death).
    200  */
    201 static void freeOpenSslErrorState(void) {
    202     ERR_clear_error();
    203     ERR_remove_state(0);
    204 }
    205 
    206 /*
    207  * Checks this thread's OpenSSL error queue and throws a RuntimeException if
    208  * necessary.
    209  *
    210  * @return true if an exception was thrown, false if not.
    211  */
    212 static bool throwExceptionIfNecessary(JNIEnv* env, const char* location  __attribute__ ((unused))) {
    213     int error = ERR_get_error();
    214     int result = false;
    215 
    216     if (error != 0) {
    217         char message[256];
    218         ERR_error_string_n(error, message, sizeof(message));
    219         JNI_TRACE("OpenSSL error in %s %d: %s", location, error, message);
    220         jniThrowRuntimeException(env, message);
    221         result = true;
    222     }
    223 
    224     freeOpenSslErrorState();
    225     return result;
    226 }
    227 
    228 /**
    229  * Throws an SocketTimeoutException with the given string as a message.
    230  */
    231 static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
    232     JNI_TRACE("throwSocketTimeoutException %s", message);
    233     jniThrowException(env, "java/net/SocketTimeoutException", message);
    234 }
    235 
    236 /**
    237  * Throws a javax.net.ssl.SSLException with the given string as a message.
    238  */
    239 static void throwSSLExceptionStr(JNIEnv* env, const char* message) {
    240     JNI_TRACE("throwSSLExceptionStr %s", message);
    241     jniThrowException(env, "javax/net/ssl/SSLException", message);
    242 }
    243 
    244 /**
    245  * Throws a javax.net.ssl.SSLProcotolException with the given string as a message.
    246  */
    247 static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) {
    248     JNI_TRACE("throwSSLProtocolExceptionStr %s", message);
    249     jniThrowException(env, "javax/net/ssl/SSLProtocolException", message);
    250 }
    251 
    252 /**
    253  * Throws an SSLException with a message constructed from the current
    254  * SSL errors. This will also log the errors.
    255  *
    256  * @param env the JNI environment
    257  * @param ssl the possibly NULL SSL
    258  * @param sslErrorCode error code returned from SSL_get_error() or
    259  * SSL_ERROR_NONE to probe with ERR_get_error
    260  * @param message null-ok; general error message
    261  */
    262 static void throwSSLExceptionWithSslErrors(
    263         JNIEnv* env, SSL* ssl, int sslErrorCode, const char* message) {
    264 
    265     if (message == NULL) {
    266         message = "SSL error";
    267     }
    268 
    269     // First consult the SSL error code for the general message.
    270     const char* sslErrorStr = NULL;
    271     switch (sslErrorCode) {
    272         case SSL_ERROR_NONE:
    273             if (ERR_peek_error() == 0) {
    274                 sslErrorStr = "OK";
    275             } else {
    276                 sslErrorStr = "";
    277             }
    278             break;
    279         case SSL_ERROR_SSL:
    280             sslErrorStr = "Failure in SSL library, usually a protocol error";
    281             break;
    282         case SSL_ERROR_WANT_READ:
    283             sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this.";
    284             break;
    285         case SSL_ERROR_WANT_WRITE:
    286             sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this.";
    287             break;
    288         case SSL_ERROR_WANT_X509_LOOKUP:
    289             sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this.";
    290             break;
    291         case SSL_ERROR_SYSCALL:
    292             sslErrorStr = "I/O error during system call";
    293             break;
    294         case SSL_ERROR_ZERO_RETURN:
    295             sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this.";
    296             break;
    297         case SSL_ERROR_WANT_CONNECT:
    298             sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this.";
    299             break;
    300         case SSL_ERROR_WANT_ACCEPT:
    301             sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this.";
    302             break;
    303         default:
    304             sslErrorStr = "Unknown SSL error";
    305     }
    306 
    307     // Prepend either our explicit message or a default one.
    308     char* str;
    309     if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) {
    310         // problem with asprintf, just throw argument message, log everything
    311         throwSSLExceptionStr(env, message);
    312         ALOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr);
    313         freeOpenSslErrorState();
    314         return;
    315     }
    316 
    317     char* allocStr = str;
    318 
    319     // For protocol errors, SSL might have more information.
    320     if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) {
    321         // Append each error as an additional line to the message.
    322         for (;;) {
    323             char errStr[256];
    324             const char* file;
    325             int line;
    326             const char* data;
    327             int flags;
    328             unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags);
    329             if (err == 0) {
    330                 break;
    331             }
    332 
    333             ERR_error_string_n(err, errStr, sizeof(errStr));
    334 
    335             int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
    336                                (allocStr == NULL) ? "" : allocStr,
    337                                errStr,
    338                                file,
    339                                line,
    340                                (flags & ERR_TXT_STRING) ? data : "(no data)",
    341                                flags);
    342 
    343             if (ret < 0) {
    344                 break;
    345             }
    346 
    347             free(allocStr);
    348             allocStr = str;
    349         }
    350     // For errors during system calls, errno might be our friend.
    351     } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
    352         if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
    353             free(allocStr);
    354             allocStr = str;
    355         }
    356     // If the error code is invalid, print it.
    357     } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
    358         if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
    359             free(allocStr);
    360             allocStr = str;
    361         }
    362     }
    363 
    364     if (sslErrorCode == SSL_ERROR_SSL) {
    365         throwSSLProtocolExceptionStr(env, allocStr);
    366     } else {
    367         throwSSLExceptionStr(env, allocStr);
    368     }
    369 
    370     ALOGV("%s", allocStr);
    371     free(allocStr);
    372     freeOpenSslErrorState();
    373 }
    374 
    375 /**
    376  * Helper function that grabs the casts an ssl pointer and then checks for nullness.
    377  * If this function returns NULL and <code>throwIfNull</code> is
    378  * passed as <code>true</code>, then this function will call
    379  * <code>throwSSLExceptionStr</code> before returning, so in this case of
    380  * NULL, a caller of this function should simply return and allow JNI
    381  * to do its thing.
    382  *
    383  * @param env the JNI environment
    384  * @param ssl_address; the ssl_address pointer as an integer
    385  * @param throwIfNull whether to throw if the SSL pointer is NULL
    386  * @returns the pointer, which may be NULL
    387  */
    388 static SSL_CTX* to_SSL_CTX(JNIEnv* env, int ssl_ctx_address, bool throwIfNull) {
    389     SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
    390     if ((ssl_ctx == NULL) && throwIfNull) {
    391         JNI_TRACE("ssl_ctx == null");
    392         jniThrowNullPointerException(env, "ssl_ctx == null");
    393     }
    394     return ssl_ctx;
    395 }
    396 
    397 static SSL* to_SSL(JNIEnv* env, int ssl_address, bool throwIfNull) {
    398     SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
    399     if ((ssl == NULL) && throwIfNull) {
    400         JNI_TRACE("ssl == null");
    401         jniThrowNullPointerException(env, "ssl == null");
    402     }
    403     return ssl;
    404 }
    405 
    406 static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, int ssl_session_address, bool throwIfNull) {
    407     SSL_SESSION* ssl_session
    408         = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
    409     if ((ssl_session == NULL) && throwIfNull) {
    410         JNI_TRACE("ssl_session == null");
    411         jniThrowNullPointerException(env, "ssl_session == null");
    412     }
    413     return ssl_session;
    414 }
    415 
    416 /**
    417  * Converts a Java byte[] to an OpenSSL BIGNUM, allocating the BIGNUM on the
    418  * fly. Returns true on success. If the return value is false, there is a
    419  * pending exception.
    420  */
    421 static bool arrayToBignum(JNIEnv* env, jbyteArray source, BIGNUM** dest) {
    422     JNI_TRACE("arrayToBignum(%p, %p)", source, *dest);
    423 
    424     ScopedByteArrayRO sourceBytes(env, source);
    425     if (sourceBytes.get() == NULL) {
    426         JNI_TRACE("arrayToBignum(%p) => NULL", source);
    427         return false;
    428     }
    429     *dest = BN_bin2bn(reinterpret_cast<const unsigned char*>(sourceBytes.get()),
    430                            sourceBytes.size(),
    431                            NULL);
    432     if (*dest == NULL) {
    433         jniThrowRuntimeException(env, "Conversion to BIGNUM failed");
    434         JNI_TRACE("arrayToBignum(%p) => threw exception", source);
    435         return false;
    436     }
    437 
    438     JNI_TRACE("arrayToBignum(%p) => %p", source, *dest);
    439     return true;
    440 }
    441 
    442 /**
    443  * Converts an OpenSSL BIGNUM to a Java byte[] array.
    444  */
    445 static jbyteArray bignumToArray(JNIEnv* env, BIGNUM* source) {
    446     JNI_TRACE("bignumToArray(%p)", source);
    447 
    448     if (source == NULL) {
    449         jniThrowNullPointerException(env, NULL);
    450         return NULL;
    451     }
    452 
    453     int len = BN_num_bytes(source) + 1;
    454     jbyteArray javaBytes = env->NewByteArray(len);
    455     ScopedByteArrayRW bytes(env, javaBytes);
    456     if (bytes.get() == NULL) {
    457         JNI_TRACE("bignumToArray(%p) => NULL", source);
    458         return NULL;
    459     }
    460 
    461     unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
    462 
    463     // Set the sign for the Java code.
    464     if (BN_is_negative(source)) {
    465         *tmp = 0xFF;
    466     } else {
    467         *tmp = 0x00;
    468     }
    469 
    470     if (BN_bn2bin(source, tmp + 1) <= 0) {
    471         throwExceptionIfNecessary(env, "bignumToArray");
    472         return NULL;
    473     }
    474 
    475     JNI_TRACE("bignumToArray(%p) => %p", source, javaBytes);
    476     return javaBytes;
    477 }
    478 
    479 /**
    480  * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
    481  * suppose there are not many other ways to do this on a Linux system (modulo
    482  * isomorphism).
    483  */
    484 #define MUTEX_TYPE pthread_mutex_t
    485 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
    486 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
    487 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
    488 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
    489 #define THREAD_ID pthread_self()
    490 #define THROW_SSLEXCEPTION (-2)
    491 #define THROW_SOCKETTIMEOUTEXCEPTION (-3)
    492 #define THROWN_EXCEPTION (-4)
    493 
    494 static MUTEX_TYPE* mutex_buf = NULL;
    495 
    496 static void locking_function(int mode, int n, const char*, int) {
    497     if (mode & CRYPTO_LOCK) {
    498         MUTEX_LOCK(mutex_buf[n]);
    499     } else {
    500         MUTEX_UNLOCK(mutex_buf[n]);
    501     }
    502 }
    503 
    504 static unsigned long id_function(void) {
    505     return ((unsigned long)THREAD_ID);
    506 }
    507 
    508 int THREAD_setup(void) {
    509     mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
    510     if (!mutex_buf) {
    511         return 0;
    512     }
    513 
    514     for (int i = 0; i < CRYPTO_num_locks(); ++i) {
    515         MUTEX_SETUP(mutex_buf[i]);
    516     }
    517 
    518     CRYPTO_set_id_callback(id_function);
    519     CRYPTO_set_locking_callback(locking_function);
    520 
    521     return 1;
    522 }
    523 
    524 int THREAD_cleanup(void) {
    525     if (!mutex_buf) {
    526         return 0;
    527     }
    528 
    529     CRYPTO_set_id_callback(NULL);
    530     CRYPTO_set_locking_callback(NULL);
    531 
    532     for (int i = 0; i < CRYPTO_num_locks( ); i++) {
    533         MUTEX_CLEANUP(mutex_buf[i]);
    534     }
    535 
    536     free(mutex_buf);
    537     mutex_buf = NULL;
    538 
    539     return 1;
    540 }
    541 
    542 /**
    543  * Initialization phase for every OpenSSL job: Loads the Error strings, the
    544  * crypto algorithms and reset the OpenSSL library
    545  */
    546 static void NativeCrypto_clinit(JNIEnv*, jclass)
    547 {
    548     SSL_load_error_strings();
    549     ERR_load_crypto_strings();
    550     SSL_library_init();
    551     OpenSSL_add_all_algorithms();
    552     THREAD_setup();
    553 }
    554 
    555 static void NativeCrypto_ENGINE_load_dynamic(JNIEnv*, jclass) {
    556     JNI_TRACE("ENGINE_load_dynamic()");
    557 
    558     ENGINE_load_dynamic();
    559 }
    560 
    561 static jint NativeCrypto_ENGINE_by_id(JNIEnv* env, jclass, jstring idJava) {
    562     JNI_TRACE("ENGINE_by_id(%p)", idJava);
    563 
    564     ScopedUtfChars id(env, idJava);
    565     if (id.c_str() == NULL) {
    566         jniThrowException(env, "java/lang/IllegalArgumentException", "id == NULL");
    567         return 0;
    568     }
    569 
    570     ENGINE* e = ENGINE_by_id(id.c_str());
    571     if (e == NULL) {
    572         throwExceptionIfNecessary(env, "ENGINE_by_id");
    573         return 0;
    574     }
    575 
    576     JNI_TRACE("ENGINE_by_id(%p) => %p", idJava, e);
    577     return static_cast<jint>(reinterpret_cast<uintptr_t>(e));
    578 }
    579 
    580 static jint NativeCrypto_ENGINE_init(JNIEnv* env, jclass, jint engineRef) {
    581     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
    582     JNI_TRACE("ENGINE_init(%p)", e);
    583 
    584     if (e == NULL) {
    585         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
    586         return 0;
    587     }
    588 
    589     int ret = ENGINE_init(e);
    590     JNI_TRACE("ENGINE_init(%p) => %d", e, ret);
    591     return ret;
    592 }
    593 
    594 static jint NativeCrypto_ENGINE_finish(JNIEnv* env, jclass, jint engineRef) {
    595     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
    596     JNI_TRACE("ENGINE_finish(%p)", e);
    597 
    598     if (e == NULL) {
    599         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
    600         return 0;
    601     }
    602 
    603     int ret = ENGINE_finish(e);
    604     JNI_TRACE("ENGINE_finish(%p) => %d", e, ret);
    605     return ret;
    606 }
    607 
    608 static jint NativeCrypto_ENGINE_free(JNIEnv* env, jclass, jint engineRef) {
    609     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
    610     JNI_TRACE("ENGINE_free(%p)", e);
    611 
    612     if (e == NULL) {
    613         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
    614         return 0;
    615     }
    616 
    617     int ret = ENGINE_free(e);
    618     JNI_TRACE("ENGINE_free(%p) => %d", e, ret);
    619     return ret;
    620 }
    621 
    622 static jint NativeCrypto_ENGINE_load_private_key(JNIEnv* env, jclass, jint engineRef,
    623         jstring idJava) {
    624     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
    625     JNI_TRACE("ENGINE_load_private_key(%p, %p)", e, idJava);
    626 
    627     ScopedUtfChars id(env, idJava);
    628     if (id.c_str() == NULL) {
    629         jniThrowException(env, "java/lang/IllegalArgumentException", "id == NULL");
    630         return 0;
    631     }
    632 
    633     Unique_EVP_PKEY pkey(ENGINE_load_private_key(e, id.c_str(), NULL, NULL));
    634     if (pkey.get() == NULL) {
    635         throwExceptionIfNecessary(env, "ENGINE_load_private_key");
    636         return 0;
    637     }
    638 
    639     JNI_TRACE("ENGINE_load_private_key(%p, %p) => %p", e, idJava, pkey.get());
    640     return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
    641 }
    642 
    643 /**
    644  * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
    645  *                                           byte[] pub_key, byte[] priv_key);
    646  */
    647 static EVP_PKEY* NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
    648                                                jbyteArray p, jbyteArray q, jbyteArray g,
    649                                                jbyteArray pub_key, jbyteArray priv_key) {
    650     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
    651               p, q, g, pub_key, priv_key);
    652 
    653     Unique_DSA dsa(DSA_new());
    654     if (dsa.get() == NULL) {
    655         jniThrowRuntimeException(env, "DSA_new failed");
    656         return NULL;
    657     }
    658 
    659     if (!arrayToBignum(env, p, &dsa->p)) {
    660         return NULL;
    661     }
    662 
    663     if (!arrayToBignum(env, q, &dsa->q)) {
    664         return NULL;
    665     }
    666 
    667     if (!arrayToBignum(env, g, &dsa->g)) {
    668         return NULL;
    669     }
    670 
    671     if (pub_key != NULL && !arrayToBignum(env, pub_key, &dsa->pub_key)) {
    672         return NULL;
    673     }
    674 
    675     if (priv_key != NULL && !arrayToBignum(env, priv_key, &dsa->priv_key)) {
    676         return NULL;
    677     }
    678 
    679     if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL
    680             || (dsa->pub_key == NULL && dsa->priv_key == NULL)) {
    681         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
    682         return NULL;
    683     }
    684 
    685     Unique_EVP_PKEY pkey(EVP_PKEY_new());
    686     if (pkey.get() == NULL) {
    687         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
    688         return NULL;
    689     }
    690     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
    691         jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
    692         return NULL;
    693     }
    694     OWNERSHIP_TRANSFERRED(dsa);
    695     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
    696               p, q, g, pub_key, priv_key, pkey.get());
    697     return pkey.release();
    698 }
    699 
    700 /**
    701  * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
    702  */
    703 static jint NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
    704                                                jbyteArray n, jbyteArray e, jbyteArray d,
    705                                                jbyteArray p, jbyteArray q,
    706                                                jbyteArray dmp1, jbyteArray dmq1,
    707                                                jbyteArray iqmp) {
    708     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p, dmp1=%p, dmq1=%p, iqmp=%p)",
    709             n, e, d, p, q, dmp1, dmq1, iqmp);
    710 
    711     Unique_RSA rsa(RSA_new());
    712     if (rsa.get() == NULL) {
    713         jniThrowRuntimeException(env, "RSA_new failed");
    714         return 0;
    715     }
    716 
    717     if (e == NULL && d == NULL) {
    718         jniThrowException(env, "java/lang/IllegalArgumentException", "e == NULL && d == NULL");
    719         JNI_TRACE("NativeCrypto_EVP_PKEY_new_RSA => e == NULL && d == NULL");
    720         return 0;
    721     }
    722 
    723     if (!arrayToBignum(env, n, &rsa->n)) {
    724         return 0;
    725     }
    726 
    727     if (e != NULL && !arrayToBignum(env, e, &rsa->e)) {
    728         return 0;
    729     }
    730 
    731     if (d != NULL && !arrayToBignum(env, d, &rsa->d)) {
    732         return 0;
    733     }
    734 
    735     if (p != NULL && !arrayToBignum(env, p, &rsa->p)) {
    736         return 0;
    737     }
    738 
    739     if (q != NULL && !arrayToBignum(env, q, &rsa->q)) {
    740         return 0;
    741     }
    742 
    743     if (dmp1 != NULL && !arrayToBignum(env, dmp1, &rsa->dmp1)) {
    744         return 0;
    745     }
    746 
    747     if (dmq1 != NULL && !arrayToBignum(env, dmq1, &rsa->dmq1)) {
    748         return 0;
    749     }
    750 
    751     if (iqmp != NULL && !arrayToBignum(env, iqmp, &rsa->iqmp)) {
    752         return 0;
    753     }
    754 
    755 #ifdef WITH_JNI_TRACE
    756     if (p != NULL && q != NULL) {
    757         int check = RSA_check_key(rsa.get());
    758         JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check);
    759     }
    760 #endif
    761 
    762     if (rsa->n == NULL || (rsa->e == NULL && rsa->d == NULL)) {
    763         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
    764         return 0;
    765     }
    766 
    767     /*
    768      * If the private exponent is available, there is the potential to do signing
    769      * operations. If the public exponent is also available, OpenSSL will do RSA
    770      * blinding. Enable it if possible.
    771      */
    772     if (rsa->d != NULL) {
    773         if (rsa->e != NULL) {
    774             JNI_TRACE("EVP_PKEY_new_RSA(...) enabling RSA blinding => %p", rsa.get());
    775             RSA_blinding_on(rsa.get(), NULL);
    776         } else {
    777             JNI_TRACE("EVP_PKEY_new_RSA(...) disabling RSA blinding => %p", rsa.get());
    778             RSA_blinding_off(rsa.get());
    779         }
    780     }
    781 
    782     Unique_EVP_PKEY pkey(EVP_PKEY_new());
    783     if (pkey.get() == NULL) {
    784         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
    785         return 0;
    786     }
    787     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
    788         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
    789         return 0;
    790     }
    791     OWNERSHIP_TRANSFERRED(rsa);
    792     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p dmp1=%p, dmq1=%p, iqmp=%p) => %p",
    793             n, e, d, p, q, dmp1, dmq1, iqmp, pkey.get());
    794     return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
    795 }
    796 
    797 /**
    798  * private static native int EVP_PKEY_size(int pkey);
    799  */
    800 static int NativeCrypto_EVP_PKEY_type(JNIEnv* env, jclass, jint pkeyRef) {
    801     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
    802     JNI_TRACE("EVP_PKEY_type(%p)", pkey);
    803 
    804     if (pkey == NULL) {
    805         jniThrowNullPointerException(env, NULL);
    806         return -1;
    807     }
    808 
    809     int result = EVP_PKEY_type(pkey->type);
    810     JNI_TRACE("EVP_PKEY_type(%p) => %d", pkey, result);
    811     return result;
    812 }
    813 
    814 /**
    815  * private static native int EVP_PKEY_size(int pkey);
    816  */
    817 static int NativeCrypto_EVP_PKEY_size(JNIEnv* env, jclass, jint pkeyRef) {
    818     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
    819     JNI_TRACE("EVP_PKEY_size(%p)", pkey);
    820 
    821     if (pkey == NULL) {
    822         jniThrowNullPointerException(env, NULL);
    823         return -1;
    824     }
    825 
    826     int result = EVP_PKEY_size(pkey);
    827     JNI_TRACE("EVP_PKEY_size(%p) => %d", pkey, result);
    828     return result;
    829 }
    830 
    831 /**
    832  * private static native void EVP_PKEY_free(int pkey);
    833  */
    834 static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, EVP_PKEY* pkey) {
    835     JNI_TRACE("EVP_PKEY_free(%p)", pkey);
    836 
    837     if (pkey != NULL) {
    838         EVP_PKEY_free(pkey);
    839     }
    840 }
    841 
    842 /*
    843  * static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int, byte[])
    844  */
    845 static jbyteArray NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jint pkeyRef) {
    846     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
    847     JNI_TRACE("i2d_PKCS8_PRIV_KEY_INFO(%p)", pkey);
    848 
    849     if (pkey == NULL) {
    850         jniThrowNullPointerException(env, NULL);
    851         return NULL;
    852     }
    853 
    854     Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey));
    855     if (pkcs8.get() == NULL) {
    856         throwExceptionIfNecessary(env, "NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO");
    857         JNI_TRACE("key=%p i2d_PKCS8_PRIV_KEY_INFO => error from key to PKCS8", pkey);
    858         return NULL;
    859     }
    860 
    861     int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
    862     if (len < 0) {
    863         throwExceptionIfNecessary(env, "i2d_PKCS8_PRIV_KEY_INFO");
    864         return NULL;
    865     }
    866 
    867     jbyteArray javaBytes = env->NewByteArray(len);
    868     ScopedByteArrayRW bytes(env, javaBytes);
    869     if (bytes.get() == NULL) {
    870         return NULL;
    871     }
    872 
    873     unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
    874     if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) < 0) {
    875         throwExceptionIfNecessary(env, "i2d_PKCS8_PRIV_KEY_INFO");
    876         return NULL;
    877     }
    878 
    879     JNI_TRACE("pkey=%p i2d_PKCS8_PRIV_KEY_INFO => size=%d", pkey, len);
    880     return javaBytes;
    881 }
    882 
    883 /*
    884  * static native int d2i_PKCS8_PRIV_KEY_INFO(byte[])
    885  */
    886 static jint NativeCrypto_d2i_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jbyteArray keyJavaBytes) {
    887     JNI_TRACE("d2i_PKCS8_PRIV_KEY_INFO(%p)", keyJavaBytes);
    888 
    889     ScopedByteArrayRO bytes(env, keyJavaBytes);
    890     if (bytes.get() == NULL) {
    891         JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => threw exception", keyJavaBytes);
    892         return 0;
    893     }
    894 
    895     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
    896     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, bytes.size()));
    897     if (pkcs8.get() == NULL) {
    898         throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
    899         JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from DER to PKCS8", keyJavaBytes);
    900         return 0;
    901     }
    902 
    903     Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
    904     if (pkey.get() == NULL) {
    905         throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
    906         JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from PKCS8 to key", keyJavaBytes);
    907         return 0;
    908     }
    909 
    910     JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => %p", keyJavaBytes, pkey.get());
    911     return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
    912 }
    913 
    914 /*
    915  * static native byte[] i2d_PUBKEY(int)
    916  */
    917 static jbyteArray NativeCrypto_i2d_PUBKEY(JNIEnv* env, jclass, jint pkeyRef) {
    918     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
    919     JNI_TRACE("i2d_PUBKEY(%p)", pkey);
    920 
    921     if (pkey == NULL) {
    922         jniThrowNullPointerException(env, NULL);
    923         return NULL;
    924     }
    925 
    926     int len = i2d_PUBKEY(pkey, NULL);
    927     if (len < 0) {
    928         throwExceptionIfNecessary(env, "i2d_PUBKEY");
    929         JNI_TRACE("i2d_PUBKEY(%p) => threw error measuring key", pkey);
    930         return NULL;
    931     }
    932 
    933     jbyteArray javaBytes = env->NewByteArray(len);
    934     ScopedByteArrayRW bytes(env, javaBytes);
    935     if (bytes.get() == NULL) {
    936         return NULL;
    937     }
    938 
    939     unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
    940     if (i2d_PUBKEY(pkey, &tmp) < 0) {
    941         throwExceptionIfNecessary(env, "i2d_PUBKEY");
    942         JNI_TRACE("i2d_PUBKEY(%p) => threw error converting key", pkey);
    943         return NULL;
    944     }
    945 
    946     JNI_TRACE("pkey=%p i2d_PUBKEY => size=%d", pkey, len);
    947     return javaBytes;
    948 }
    949 
    950 /*
    951  * static native int d2i_PUBKEY(byte[])
    952  */
    953 static jint NativeCrypto_d2i_PUBKEY(JNIEnv* env, jclass, jbyteArray javaBytes) {
    954     JNI_TRACE("d2i_PUBKEY(%p)", javaBytes);
    955 
    956     ScopedByteArrayRO bytes(env, javaBytes);
    957     if (bytes.get() == NULL) {
    958         JNI_TRACE("d2i_PUBKEY(%p) => threw error", javaBytes);
    959         return 0;
    960     }
    961 
    962     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
    963     Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, bytes.size()));
    964     if (pkey.get() == NULL) {
    965         JNI_TRACE("bytes=%p d2i_PUBKEY => threw exception", javaBytes);
    966         throwExceptionIfNecessary(env, "d2i_PUBKEY");
    967         return 0;
    968     }
    969 
    970     return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
    971 }
    972 
    973 /*
    974  * public static native int RSA_generate_key(int modulusBits, byte[] publicExponent);
    975  */
    976 static jint NativeCrypto_RSA_generate_key_ex(JNIEnv* env, jclass, jint modulusBits,
    977         jbyteArray publicExponent) {
    978     JNI_TRACE("RSA_generate_key_ex(%d, %p)", modulusBits, publicExponent);
    979 
    980     BIGNUM* eRef;
    981     if (!arrayToBignum(env, publicExponent, &eRef)) {
    982         return 0;
    983     }
    984     Unique_BIGNUM e(eRef);
    985 
    986     Unique_RSA rsa(RSA_new());
    987     if (rsa.get() == NULL) {
    988         jniThrowOutOfMemoryError(env, "Unable to allocate RSA key");
    989         return 0;
    990     }
    991 
    992     if (RSA_generate_key_ex(rsa.get(), modulusBits, e.get(), NULL) < 0) {
    993         throwExceptionIfNecessary(env, "RSA_generate_key_ex");
    994         return 0;
    995     }
    996 
    997     Unique_EVP_PKEY pkey(EVP_PKEY_new());
    998     if (pkey.get() == NULL) {
    999         jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
   1000         return 0;
   1001     }
   1002 
   1003     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
   1004         jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
   1005         return 0;
   1006     }
   1007 
   1008     OWNERSHIP_TRANSFERRED(rsa);
   1009     JNI_TRACE("RSA_generate_key_ex(n=%d, e=%p) => %p", modulusBits, publicExponent, pkey.get());
   1010     return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
   1011 }
   1012 
   1013 /*
   1014  * public static native byte[][] get_RSA_public_params(int);
   1015  */
   1016 static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jint pkeyRef) {
   1017     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   1018     JNI_TRACE("get_RSA_public_params(%p)", pkey);
   1019 
   1020     Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
   1021     if (rsa.get() == NULL) {
   1022         jniThrowRuntimeException(env, "get_RSA_public_params failed");
   1023         return 0;
   1024     }
   1025 
   1026     jobjectArray joa = env->NewObjectArray(2, JniConstants::byteArrayClass, NULL);
   1027     if (joa == NULL) {
   1028         return NULL;
   1029     }
   1030 
   1031     jbyteArray n = bignumToArray(env, rsa->n);
   1032     if (env->ExceptionCheck()) {
   1033         return NULL;
   1034     }
   1035     env->SetObjectArrayElement(joa, 0, n);
   1036 
   1037     jbyteArray e = bignumToArray(env, rsa->e);
   1038     if (env->ExceptionCheck()) {
   1039         return NULL;
   1040     }
   1041     env->SetObjectArrayElement(joa, 1, e);
   1042 
   1043     return joa;
   1044 }
   1045 
   1046 /*
   1047  * public static native byte[][] get_RSA_private_params(int);
   1048  */
   1049 static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jint pkeyRef) {
   1050     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   1051     JNI_TRACE("get_RSA_public_params(%p)", pkey);
   1052 
   1053     Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
   1054     if (rsa.get() == NULL) {
   1055         jniThrowRuntimeException(env, "get_RSA_public_params failed");
   1056         return 0;
   1057     }
   1058 
   1059     jobjectArray joa = env->NewObjectArray(8, JniConstants::byteArrayClass, NULL);
   1060     if (joa == NULL) {
   1061         return NULL;
   1062     }
   1063 
   1064     jbyteArray n = bignumToArray(env, rsa->n);
   1065     if (env->ExceptionCheck()) {
   1066         return NULL;
   1067     }
   1068     env->SetObjectArrayElement(joa, 0, n);
   1069 
   1070     if (rsa->e != NULL) {
   1071         jbyteArray e = bignumToArray(env, rsa->e);
   1072         if (env->ExceptionCheck()) {
   1073             return NULL;
   1074         }
   1075         env->SetObjectArrayElement(joa, 1, e);
   1076     }
   1077 
   1078     if (rsa->d != NULL) {
   1079         jbyteArray d = bignumToArray(env, rsa->d);
   1080         if (env->ExceptionCheck()) {
   1081             return NULL;
   1082         }
   1083         env->SetObjectArrayElement(joa, 2, d);
   1084     }
   1085 
   1086     if (rsa->p != NULL) {
   1087         jbyteArray p = bignumToArray(env, rsa->p);
   1088         if (env->ExceptionCheck()) {
   1089             return NULL;
   1090         }
   1091         env->SetObjectArrayElement(joa, 3, p);
   1092     }
   1093 
   1094     if (rsa->q != NULL) {
   1095         jbyteArray q = bignumToArray(env, rsa->q);
   1096         if (env->ExceptionCheck()) {
   1097             return NULL;
   1098         }
   1099         env->SetObjectArrayElement(joa, 4, q);
   1100     }
   1101 
   1102     if (rsa->dmp1 != NULL) {
   1103         jbyteArray dmp1 = bignumToArray(env, rsa->dmp1);
   1104         if (env->ExceptionCheck()) {
   1105             return NULL;
   1106         }
   1107         env->SetObjectArrayElement(joa, 5, dmp1);
   1108     }
   1109 
   1110     if (rsa->dmq1 != NULL) {
   1111         jbyteArray dmq1 = bignumToArray(env, rsa->dmq1);
   1112         if (env->ExceptionCheck()) {
   1113             return NULL;
   1114         }
   1115         env->SetObjectArrayElement(joa, 6, dmq1);
   1116     }
   1117 
   1118     if (rsa->iqmp != NULL) {
   1119         jbyteArray iqmp = bignumToArray(env, rsa->iqmp);
   1120         if (env->ExceptionCheck()) {
   1121             return NULL;
   1122         }
   1123         env->SetObjectArrayElement(joa, 7, iqmp);
   1124     }
   1125 
   1126     return joa;
   1127 }
   1128 
   1129 /*
   1130  * public static native int DSA_generate_key(int, byte[]);
   1131  */
   1132 static jint NativeCrypto_DSA_generate_key(JNIEnv* env, jclass, jint primeBits,
   1133         jbyteArray seedJavaBytes, jbyteArray gBytes, jbyteArray pBytes, jbyteArray qBytes) {
   1134     JNI_TRACE("DSA_generate_key(%d, %p, %p, %p, %p)", primeBits, seedJavaBytes,
   1135             gBytes, pBytes, qBytes);
   1136 
   1137     UniquePtr<unsigned char[]> seedPtr;
   1138     unsigned long seedSize = 0;
   1139     if (seedJavaBytes != NULL) {
   1140         ScopedByteArrayRO seed(env, seedJavaBytes);
   1141         if (seed.get() == NULL) {
   1142             return 0;
   1143         }
   1144 
   1145         seedSize = seed.size();
   1146         seedPtr.reset(new unsigned char[seedSize]);
   1147 
   1148         memcpy(seedPtr.get(), seed.get(), seedSize);
   1149     }
   1150 
   1151     Unique_DSA dsa(DSA_new());
   1152     if (dsa.get() == NULL) {
   1153         JNI_TRACE("DSA_generate_key failed");
   1154         jniThrowOutOfMemoryError(env, "Unable to allocate DSA key");
   1155         return 0;
   1156     }
   1157 
   1158     if (gBytes != NULL && pBytes != NULL && qBytes != NULL) {
   1159         JNI_TRACE("DSA_generate_key parameters specified");
   1160 
   1161         if (!arrayToBignum(env, gBytes, &dsa->g)) {
   1162             return 0;
   1163         }
   1164 
   1165         if (!arrayToBignum(env, pBytes, &dsa->p)) {
   1166             return 0;
   1167         }
   1168 
   1169         if (!arrayToBignum(env, qBytes, &dsa->q)) {
   1170             return 0;
   1171         }
   1172     } else {
   1173         JNI_TRACE("DSA_generate_key generating parameters");
   1174 
   1175         if (!DSA_generate_parameters_ex(dsa.get(), primeBits, seedPtr.get(), seedSize, NULL, NULL, NULL)) {
   1176             JNI_TRACE("DSA_generate_key => param generation failed");
   1177             throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_parameters_ex failed");
   1178             return 0;
   1179         }
   1180     }
   1181 
   1182     if (!DSA_generate_key(dsa.get())) {
   1183         JNI_TRACE("DSA_generate_key failed");
   1184         throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
   1185         return 0;
   1186     }
   1187 
   1188     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   1189     if (pkey.get() == NULL) {
   1190         JNI_TRACE("DSA_generate_key failed");
   1191         jniThrowRuntimeException(env, "NativeCrypto_DSA_generate_key failed");
   1192         return 0;
   1193     }
   1194 
   1195     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
   1196         JNI_TRACE("DSA_generate_key failed");
   1197         jniThrowRuntimeException(env, "NativeCrypto_DSA_generate_key failed");
   1198         return 0;
   1199     }
   1200 
   1201     OWNERSHIP_TRANSFERRED(dsa);
   1202     JNI_TRACE("DSA_generate_key(n=%d, e=%p) => %p", primeBits, seedPtr.get(), pkey.get());
   1203     return static_cast<jint>(reinterpret_cast<uintptr_t>(pkey.release()));
   1204 }
   1205 
   1206 /*
   1207  * public static native byte[][] get_DSA_params(int);
   1208  */
   1209 static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jint pkeyRef) {
   1210     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   1211     JNI_TRACE("get_DSA_params(%p)", pkey);
   1212 
   1213     Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
   1214     if (dsa.get() == NULL) {
   1215         jniThrowRuntimeException(env, "get_DSA_params failed");
   1216         return 0;
   1217     }
   1218 
   1219     jobjectArray joa = env->NewObjectArray(5, JniConstants::byteArrayClass, NULL);
   1220     if (joa == NULL) {
   1221         return NULL;
   1222     }
   1223 
   1224     jbyteArray g = bignumToArray(env, dsa->g);
   1225     if (env->ExceptionCheck()) {
   1226         return NULL;
   1227     }
   1228     env->SetObjectArrayElement(joa, 0, g);
   1229 
   1230     jbyteArray p = bignumToArray(env, dsa->p);
   1231     if (env->ExceptionCheck()) {
   1232         return NULL;
   1233     }
   1234     env->SetObjectArrayElement(joa, 1, p);
   1235 
   1236     jbyteArray q = bignumToArray(env, dsa->q);
   1237     if (env->ExceptionCheck()) {
   1238         return NULL;
   1239     }
   1240     env->SetObjectArrayElement(joa, 2, q);
   1241 
   1242     if (dsa->pub_key != NULL) {
   1243         jbyteArray pub_key = bignumToArray(env, dsa->pub_key);
   1244         if (env->ExceptionCheck()) {
   1245             return NULL;
   1246         }
   1247         env->SetObjectArrayElement(joa, 3, pub_key);
   1248     }
   1249 
   1250     if (dsa->priv_key != NULL) {
   1251         jbyteArray priv_key = bignumToArray(env, dsa->priv_key);
   1252         if (env->ExceptionCheck()) {
   1253             return NULL;
   1254         }
   1255         env->SetObjectArrayElement(joa, 4, priv_key);
   1256     }
   1257 
   1258     return joa;
   1259 }
   1260 
   1261 /*
   1262  * public static native void EVP_MD_CTX_destroy(int)
   1263  */
   1264 static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, EVP_MD_CTX* ctx) {
   1265     JNI_TRACE("NativeCrypto_EVP_MD_CTX_destroy(%p)", ctx);
   1266 
   1267     if (ctx != NULL) {
   1268         EVP_MD_CTX_destroy(ctx);
   1269     }
   1270 }
   1271 
   1272 /*
   1273  * public static native int EVP_MD_CTX_copy(int)
   1274  */
   1275 static jint NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, EVP_MD_CTX* ctx) {
   1276     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p)", ctx);
   1277 
   1278     if (ctx == NULL) {
   1279         jniThrowNullPointerException(env, NULL);
   1280         return 0;
   1281     }
   1282 
   1283     EVP_MD_CTX* copy = EVP_MD_CTX_create();
   1284     if (copy == NULL) {
   1285         jniThrowOutOfMemoryError(env, "Unable to allocate copy of EVP_MD_CTX");
   1286         return 0;
   1287     }
   1288 
   1289     EVP_MD_CTX_init(copy);
   1290     int result = EVP_MD_CTX_copy_ex(copy, ctx);
   1291     if (result == 0) {
   1292         EVP_MD_CTX_destroy(copy);
   1293         jniThrowRuntimeException(env, "Unable to copy EVP_MD_CTX");
   1294         return 0;
   1295     }
   1296 
   1297     JNI_TRACE("NativeCrypto_EVP_MD_CTX_copy(%p) => %p", ctx, copy);
   1298     return static_cast<jint>(reinterpret_cast<uintptr_t>(copy));
   1299 }
   1300 
   1301 /*
   1302  * public static native int EVP_DigestFinal(int, byte[], int)
   1303  */
   1304 static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, jint ctxRef,
   1305                                          jbyteArray hash, jint offset) {
   1306     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   1307     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
   1308 
   1309     if (ctx == NULL || hash == NULL) {
   1310         jniThrowNullPointerException(env, NULL);
   1311         return -1;
   1312     }
   1313 
   1314     ScopedByteArrayRW hashBytes(env, hash);
   1315     if (hashBytes.get() == NULL) {
   1316         return -1;
   1317     }
   1318     unsigned int bytesWritten = -1;
   1319     int ok = EVP_DigestFinal(ctx,
   1320                              reinterpret_cast<unsigned char*>(hashBytes.get() + offset),
   1321                              &bytesWritten);
   1322     if (ok == 0) {
   1323         throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestFinal");
   1324     }
   1325     EVP_MD_CTX_destroy(ctx);
   1326 
   1327     JNI_TRACE("NativeCrypto_EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, bytesWritten);
   1328     return bytesWritten;
   1329 }
   1330 
   1331 /*
   1332  * public static native int EVP_DigestInit(int)
   1333  */
   1334 static jint NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, jint evpMdRef) {
   1335     EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
   1336     JNI_TRACE("NativeCrypto_EVP_DigestInit(%p)", evp_md);
   1337 
   1338     if (evp_md == NULL) {
   1339         jniThrowNullPointerException(env, NULL);
   1340         return 0;
   1341     }
   1342 
   1343     Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
   1344     if (ctx.get() == NULL) {
   1345         jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX");
   1346         return 0;
   1347     }
   1348     JNI_TRACE("NativeCrypto_EVP_DigestInit ctx=%p", ctx.get());
   1349 
   1350     int ok = EVP_DigestInit(ctx.get(), evp_md);
   1351     if (ok == 0) {
   1352         bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestInit");
   1353         if (exception) {
   1354             return 0;
   1355         }
   1356     }
   1357     return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
   1358 }
   1359 
   1360 /*
   1361  * public static native int EVP_get_digestbyname(java.lang.String)
   1362  */
   1363 static jint NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) {
   1364     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%p)", algorithm);
   1365 
   1366     if (algorithm == NULL) {
   1367         jniThrowNullPointerException(env, NULL);
   1368         return -1;
   1369     }
   1370 
   1371     ScopedUtfChars algorithmChars(env, algorithm);
   1372     if (algorithmChars.c_str() == NULL) {
   1373         return 0;
   1374     }
   1375     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s)", algorithmChars.c_str());
   1376 
   1377     const EVP_MD* evp_md = EVP_get_digestbyname(algorithmChars.c_str());
   1378     if (evp_md == NULL) {
   1379         jniThrowRuntimeException(env, "Hash algorithm not found");
   1380         return 0;
   1381     }
   1382 
   1383     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => %p", algorithmChars.c_str(), evp_md);
   1384     return static_cast<jint>(reinterpret_cast<uintptr_t>(evp_md));
   1385 }
   1386 
   1387 /*
   1388  * public static native int EVP_MD_size(int)
   1389  */
   1390 static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, EVP_MD* evp_md) {
   1391     JNI_TRACE("NativeCrypto_EVP_MD_size(%p)", evp_md);
   1392 
   1393     if (evp_md == NULL) {
   1394         jniThrowNullPointerException(env, NULL);
   1395         return -1;
   1396     }
   1397 
   1398     int result = EVP_MD_size(evp_md);
   1399     JNI_TRACE("NativeCrypto_EVP_MD_size(%p) => %d", evp_md, result);
   1400     return result;
   1401 }
   1402 
   1403 /*
   1404  * public static int void EVP_MD_block_size(int)
   1405  */
   1406 static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, EVP_MD* evp_md) {
   1407     JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p)", evp_md);
   1408 
   1409     if (evp_md == NULL) {
   1410         jniThrowNullPointerException(env, NULL);
   1411         return -1;
   1412     }
   1413 
   1414     int result = EVP_MD_block_size(evp_md);
   1415     JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p) => %d", evp_md, result);
   1416     return result;
   1417 }
   1418 
   1419 /*
   1420  * public static native void EVP_DigestUpdate(int, byte[], int, int)
   1421  */
   1422 static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, jint ctxRef,
   1423                                           jbyteArray buffer, jint offset, jint length) {
   1424     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   1425     JNI_TRACE("NativeCrypto_EVP_DigestUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
   1426 
   1427     if (offset < 0 || length < 0) {
   1428         jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
   1429         return;
   1430     }
   1431 
   1432     if (ctx == NULL || buffer == NULL) {
   1433         jniThrowNullPointerException(env, NULL);
   1434         return;
   1435     }
   1436 
   1437     ScopedByteArrayRO bufferBytes(env, buffer);
   1438     if (bufferBytes.get() == NULL) {
   1439         return;
   1440     }
   1441     int ok = EVP_DigestUpdate(ctx,
   1442                               reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
   1443                               length);
   1444     if (ok == 0) {
   1445         throwExceptionIfNecessary(env, "NativeCrypto_EVP_DigestUpdate");
   1446     }
   1447 }
   1448 
   1449 /*
   1450  * public static native int EVP_SignInit(java.lang.String)
   1451  */
   1452 static jint NativeCrypto_EVP_SignInit(JNIEnv* env, jclass, jstring algorithm) {
   1453     JNI_TRACE("NativeCrypto_EVP_SignInit(%p)", algorithm);
   1454 
   1455     if (algorithm == NULL) {
   1456         jniThrowNullPointerException(env, NULL);
   1457         return 0;
   1458     }
   1459 
   1460     Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
   1461     if (ctx.get() == NULL) {
   1462         jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX");
   1463         return 0;
   1464     }
   1465     JNI_TRACE("NativeCrypto_EVP_SignInit ctx=%p", ctx.get());
   1466 
   1467     ScopedUtfChars algorithmChars(env, algorithm);
   1468     if (algorithmChars.c_str() == NULL) {
   1469         return 0;
   1470     }
   1471     JNI_TRACE("NativeCrypto_EVP_SignInit algorithmChars=%s", algorithmChars.c_str());
   1472 
   1473     const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
   1474     if (digest == NULL) {
   1475         jniThrowRuntimeException(env, "Hash algorithm not found");
   1476         return 0;
   1477     }
   1478 
   1479     int ok = EVP_SignInit(ctx.get(), digest);
   1480     if (ok == 0) {
   1481         bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignInit");
   1482         if (exception) {
   1483             return 0;
   1484         }
   1485     }
   1486     return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
   1487 }
   1488 
   1489 /*
   1490  * public static native void EVP_SignUpdate(int, byte[], int, int)
   1491  */
   1492 static void NativeCrypto_EVP_SignUpdate(JNIEnv* env, jclass, jint ctxRef,
   1493                                           jbyteArray buffer, jint offset, jint length) {
   1494     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   1495     JNI_TRACE("NativeCrypto_EVP_SignUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
   1496 
   1497     if (ctx == NULL || buffer == NULL) {
   1498         jniThrowNullPointerException(env, NULL);
   1499         return;
   1500     }
   1501 
   1502     ScopedByteArrayRO bufferBytes(env, buffer);
   1503     if (bufferBytes.get() == NULL) {
   1504         return;
   1505     }
   1506     int ok = EVP_SignUpdate(ctx,
   1507                             reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
   1508                             length);
   1509     if (ok == 0) {
   1510         throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignUpdate");
   1511     }
   1512 }
   1513 
   1514 /*
   1515  * public static native int EVP_SignFinal(int, byte[], int, int)
   1516  */
   1517 static jint NativeCrypto_EVP_SignFinal(JNIEnv* env, jclass, jint ctxRef, jbyteArray signature,
   1518         jint offset, jint pkeyRef) {
   1519     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   1520     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   1521     JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p)", ctx, signature, offset, pkey);
   1522 
   1523     if (ctx == NULL || pkey == NULL) {
   1524         jniThrowNullPointerException(env, NULL);
   1525         return -1;
   1526     }
   1527 
   1528     ScopedByteArrayRW signatureBytes(env, signature);
   1529     if (signatureBytes.get() == NULL) {
   1530         return -1;
   1531     }
   1532     unsigned int bytesWritten = -1;
   1533     int ok = EVP_SignFinal(ctx,
   1534                            reinterpret_cast<unsigned char*>(signatureBytes.get() + offset),
   1535                            &bytesWritten,
   1536                            pkey);
   1537     if (ok == 0) {
   1538         throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignFinal");
   1539     }
   1540     JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p) => %u",
   1541               ctx, signature, offset, pkey, bytesWritten);
   1542 
   1543     return bytesWritten;
   1544 }
   1545 
   1546 /*
   1547  * public static native int EVP_VerifyInit(java.lang.String)
   1548  */
   1549 static jint NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jstring algorithm) {
   1550     JNI_TRACE("NativeCrypto_EVP_VerifyInit(%p)", algorithm);
   1551 
   1552     if (algorithm == NULL) {
   1553         jniThrowNullPointerException(env, NULL);
   1554         return 0;
   1555     }
   1556 
   1557     Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
   1558     if (ctx.get() == NULL) {
   1559         jniThrowOutOfMemoryError(env, "Unable to allocate EVP_MD_CTX");
   1560         return 0;
   1561     }
   1562     JNI_TRACE("NativeCrypto_EVP_VerifyInit ctx=%p", ctx.get());
   1563 
   1564     ScopedUtfChars algorithmChars(env, algorithm);
   1565     if (algorithmChars.c_str() == NULL) {
   1566         return 0;
   1567     }
   1568     JNI_TRACE("NativeCrypto_EVP_VerifyInit algorithmChars=%s", algorithmChars.c_str());
   1569 
   1570     const EVP_MD* digest = EVP_get_digestbynid(OBJ_txt2nid(algorithmChars.c_str()));
   1571     if (digest == NULL) {
   1572         jniThrowRuntimeException(env, "Hash algorithm not found");
   1573         return 0;
   1574     }
   1575 
   1576     int ok = EVP_VerifyInit(ctx.get(), digest);
   1577     if (ok == 0) {
   1578         bool exception = throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyInit");
   1579         if (exception) {
   1580             return 0;
   1581         }
   1582     }
   1583     return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
   1584 }
   1585 
   1586 /*
   1587  * public static native void EVP_VerifyUpdate(int, byte[], int, int)
   1588  */
   1589 static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, jint ctxRef,
   1590                                           jbyteArray buffer, jint offset, jint length) {
   1591     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   1592     JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
   1593 
   1594     if (ctx == NULL || buffer == NULL) {
   1595         jniThrowNullPointerException(env, NULL);
   1596         return;
   1597     }
   1598 
   1599     ScopedByteArrayRO bufferBytes(env, buffer);
   1600     if (bufferBytes.get() == NULL) {
   1601         return;
   1602     }
   1603     int ok = EVP_VerifyUpdate(ctx,
   1604                               reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
   1605                               length);
   1606     if (ok == 0) {
   1607         throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate");
   1608     }
   1609 }
   1610 
   1611 /*
   1612  * public static native int EVP_VerifyFinal(int, byte[], int, int, int)
   1613  */
   1614 static jint NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, jint ctxRef, jbyteArray buffer,
   1615                                         jint offset, jint length, jint pkeyRef) {
   1616     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   1617     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   1618     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
   1619               ctx, buffer, offset, length, pkey);
   1620 
   1621     if (ctx == NULL || buffer == NULL || pkey == NULL) {
   1622         jniThrowNullPointerException(env, NULL);
   1623         return -1;
   1624     }
   1625 
   1626     ScopedByteArrayRO bufferBytes(env, buffer);
   1627     if (bufferBytes.get() == NULL) {
   1628         return -1;
   1629     }
   1630     int ok = EVP_VerifyFinal(ctx,
   1631                              reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
   1632                              length,
   1633                              pkey);
   1634     if (ok < 0) {
   1635         throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal");
   1636     }
   1637     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d",
   1638               ctx, buffer, offset, length, pkey, ok);
   1639 
   1640     return ok;
   1641 }
   1642 
   1643 /*
   1644  * public static native int EVP_get_cipherbyname(java.lang.String)
   1645  */
   1646 static jint NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algorithm) {
   1647     JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
   1648     if (algorithm == NULL) {
   1649         JNI_TRACE("EVP_get_cipherbyname(%p) => threw exception algorithm == null", algorithm);
   1650         jniThrowNullPointerException(env, NULL);
   1651         return -1;
   1652     }
   1653 
   1654     ScopedUtfChars algorithmChars(env, algorithm);
   1655     if (algorithmChars.c_str() == NULL) {
   1656         return 0;
   1657     }
   1658     JNI_TRACE("EVP_get_cipherbyname(%p) => algorithm = %s", algorithm, algorithmChars.c_str());
   1659 
   1660     const EVP_CIPHER* evp_cipher = EVP_get_cipherbyname(algorithmChars.c_str());
   1661     if (evp_cipher == NULL) {
   1662         jniThrowRuntimeException(env, "Cipher algorithm not found");
   1663         return 0;
   1664     }
   1665 
   1666     JNI_TRACE("EVP_get_cipherbyname(%s) => %p", algorithmChars.c_str(), evp_cipher);
   1667     return static_cast<jint>(reinterpret_cast<uintptr_t>(evp_cipher));
   1668 }
   1669 
   1670 /*
   1671  * public static native int EVP_CipherInit_ex(int cipherNid, byte[] key, byte[] iv,
   1672  *          boolean encrypting);
   1673  */
   1674 static jint NativeCrypto_EVP_CipherInit_ex(JNIEnv* env, jclass, jint cipherRef, jbyteArray keyArray,
   1675         jbyteArray ivArray, jboolean encrypting) {
   1676     const EVP_CIPHER* evp_cipher = reinterpret_cast<const EVP_CIPHER*>(cipherRef);
   1677     JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %d)", evp_cipher, keyArray, ivArray, encrypting ? 1 : 0);
   1678 
   1679     ScopedByteArrayRO keyBytes(env, keyArray);
   1680     if (keyBytes.get() == NULL) {
   1681         return 0;
   1682     }
   1683 
   1684     // The IV can be null if we're using ECB.
   1685     UniquePtr<unsigned char[]> ivPtr;
   1686     if (ivArray != NULL) {
   1687         ScopedByteArrayRO ivBytes(env, ivArray);
   1688         if (ivBytes.get() == NULL) {
   1689             return 0;
   1690         }
   1691 
   1692         ivPtr.reset(new unsigned char[ivBytes.size()]);
   1693         memcpy(ivPtr.get(), ivBytes.get(), ivBytes.size());
   1694     }
   1695 
   1696     Unique_EVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
   1697     if (ctx.get() == NULL) {
   1698         jniThrowOutOfMemoryError(env, "Unable to allocate cipher context");
   1699         JNI_TRACE("ctx=%p EVP_CipherInit_ex => context allocation error", evp_cipher);
   1700         return 0;
   1701     }
   1702 
   1703     const unsigned char* key = reinterpret_cast<const unsigned char*>(keyBytes.get());
   1704     if (!EVP_CipherInit_ex(ctx.get(), evp_cipher, NULL, key, ivPtr.get(), encrypting ? 1 : 0)) {
   1705         throwExceptionIfNecessary(env, "EVP_CipherInit_ex");
   1706         JNI_TRACE("EVP_CipherInit_ex => error initializing cipher");
   1707         return 0;
   1708     }
   1709 
   1710     JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %d) => %p", evp_cipher, keyArray, ivArray,
   1711             encrypting ? 1 : 0, ctx.get());
   1712     return static_cast<jint>(reinterpret_cast<uintptr_t>(ctx.release()));
   1713 }
   1714 
   1715 /*
   1716  *  public static native int EVP_CipherUpdate(int ctx, byte[] out, int outOffset, byte[] in,
   1717  *          int inOffset);
   1718  */
   1719 static jint NativeCrypto_EVP_CipherUpdate(JNIEnv* env, jclass, jint ctxRef, jbyteArray outArray,
   1720         jint outOffset, jbyteArray inArray, jint inOffset) {
   1721     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   1722     JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d)", ctx, outArray, outOffset, inArray, inOffset);
   1723 
   1724     if (ctx == NULL) {
   1725         jniThrowNullPointerException(env, "ctx == null");
   1726         JNI_TRACE("ctx=%p EVP_CipherUpdate => ctx == null", ctx);
   1727         return 0;
   1728     }
   1729 
   1730     ScopedByteArrayRO inBytes(env, inArray);
   1731     if (inBytes.get() == NULL) {
   1732         return 0;
   1733     }
   1734     const size_t inSize = inBytes.size();
   1735     if (size_t(inOffset + EVP_CIPHER_CTX_block_size(ctx)) > inSize) {
   1736         jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
   1737         return 0;
   1738     }
   1739 
   1740     ScopedByteArrayRW outBytes(env, outArray);
   1741     if (outBytes.get() == NULL) {
   1742         return 0;
   1743     }
   1744     const size_t outSize = outBytes.size();
   1745     if (size_t(outOffset + EVP_CIPHER_CTX_block_size(ctx)) > outSize) {
   1746         jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
   1747         return 0;
   1748     }
   1749 
   1750     unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
   1751     const unsigned char* in = reinterpret_cast<const unsigned char*>(inBytes.get());
   1752 
   1753     int outl;
   1754     if (!EVP_CipherUpdate(ctx, out + outOffset, &outl, in+inOffset, inSize - inOffset)) {
   1755         throwExceptionIfNecessary(env, "EVP_CipherInit_ex");
   1756         JNI_TRACE("ctx=%p EVP_CipherUpdate => threw error", ctx);
   1757         return 0;
   1758     }
   1759 
   1760     JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d) => %d", ctx, outArray, outOffset, inArray,
   1761             inOffset, outl);
   1762     return outl;
   1763 }
   1764 
   1765 /*
   1766  *  public static native int EVP_CipherFinal(int ctx, byte[] out, int outOffset);
   1767  */
   1768 static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jint ctxRef, jbyteArray outArray,
   1769         jint outOffset) {
   1770     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   1771     JNI_TRACE("EVP_CipherFinal_ex(%p, %p, %d)", ctx, outArray, outOffset);
   1772 
   1773     if (ctx == NULL) {
   1774         jniThrowNullPointerException(env, "ctx == null");
   1775         JNI_TRACE("ctx=%p EVP_CipherFinal_ex => ctx == null", ctx);
   1776         return 0;
   1777     }
   1778 
   1779     ScopedByteArrayRW outBytes(env, outArray);
   1780     if (outBytes.get() == NULL) {
   1781         return 0;
   1782     }
   1783 
   1784     unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
   1785 
   1786     int outl;
   1787     if (!EVP_CipherFinal_ex(ctx, out + outOffset, &outl)) {
   1788         throwExceptionIfNecessary(env, "EVP_CipherInit_ex");
   1789         JNI_TRACE("ctx=%p EVP_CipherUpdate => threw error", ctx);
   1790         return 0;
   1791     }
   1792 
   1793     JNI_TRACE("EVP_CipherFinal(%p, %p, %d) => %d", ctx, outArray, outOffset, outl);
   1794     return outl;
   1795 }
   1796 
   1797 /*
   1798  * public static native void EVP_CIPHER_CTX_cleanup(int ctx);
   1799  */
   1800 static void NativeCrypto_EVP_CIPHER_CTX_cleanup(JNIEnv*, jclass, jint ctxRef) {
   1801     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   1802 
   1803     if (ctx != NULL) {
   1804         EVP_CIPHER_CTX_cleanup(ctx);
   1805     }
   1806 }
   1807 
   1808 /**
   1809  * public static native void RAND_seed(byte[]);
   1810  */
   1811 static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) {
   1812     JNI_TRACE("NativeCrypto_RAND_seed seed=%p", seed);
   1813     ScopedByteArrayRO randseed(env, seed);
   1814     if (randseed.get() == NULL) {
   1815         return;
   1816     }
   1817     RAND_seed(randseed.get(), randseed.size());
   1818 }
   1819 
   1820 static jint NativeCrypto_RAND_load_file(JNIEnv* env, jclass, jstring filename, jlong max_bytes) {
   1821     JNI_TRACE("NativeCrypto_RAND_load_file filename=%p max_bytes=%lld", filename, max_bytes);
   1822     ScopedUtfChars file(env, filename);
   1823     if (file.c_str() == NULL) {
   1824         return -1;
   1825     }
   1826     int result = RAND_load_file(file.c_str(), max_bytes);
   1827     JNI_TRACE("NativeCrypto_RAND_load_file file=%s => %d", file.c_str(), result);
   1828     return result;
   1829 }
   1830 
   1831 #ifdef WITH_JNI_TRACE
   1832 /**
   1833  * Based on example logging call back from SSL_CTX_set_info_callback man page
   1834  */
   1835 static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, int ret)
   1836 {
   1837     int w = where & ~SSL_ST_MASK;
   1838     const char* str;
   1839     if (w & SSL_ST_CONNECT) {
   1840         str = "SSL_connect";
   1841     } else if (w & SSL_ST_ACCEPT) {
   1842         str = "SSL_accept";
   1843     } else {
   1844         str = "undefined";
   1845     }
   1846 
   1847     if (where & SSL_CB_LOOP) {
   1848         JNI_TRACE("ssl=%p %s:%s %s", s, str, SSL_state_string(s), SSL_state_string_long(s));
   1849     } else if (where & SSL_CB_ALERT) {
   1850         str = (where & SSL_CB_READ) ? "read" : "write";
   1851         JNI_TRACE("ssl=%p SSL3 alert %s:%s:%s %s %s",
   1852                   s,
   1853                   str,
   1854                   SSL_alert_type_string(ret),
   1855                   SSL_alert_desc_string(ret),
   1856                   SSL_alert_type_string_long(ret),
   1857                   SSL_alert_desc_string_long(ret));
   1858     } else if (where & SSL_CB_EXIT) {
   1859         if (ret == 0) {
   1860             JNI_TRACE("ssl=%p %s:failed exit in %s %s",
   1861                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   1862         } else if (ret < 0) {
   1863             JNI_TRACE("ssl=%p %s:error exit in %s %s",
   1864                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   1865         } else if (ret == 1) {
   1866             JNI_TRACE("ssl=%p %s:ok exit in %s %s",
   1867                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   1868         } else {
   1869             JNI_TRACE("ssl=%p %s:unknown exit %d in %s %s",
   1870                       s, str, ret, SSL_state_string(s), SSL_state_string_long(s));
   1871         }
   1872     } else if (where & SSL_CB_HANDSHAKE_START) {
   1873         JNI_TRACE("ssl=%p handshake start in %s %s",
   1874                   s, SSL_state_string(s), SSL_state_string_long(s));
   1875     } else if (where & SSL_CB_HANDSHAKE_DONE) {
   1876         JNI_TRACE("ssl=%p handshake done in %s %s",
   1877                   s, SSL_state_string(s), SSL_state_string_long(s));
   1878     } else {
   1879         JNI_TRACE("ssl=%p %s:unknown where %d in %s %s",
   1880                   s, str, where, SSL_state_string(s), SSL_state_string_long(s));
   1881     }
   1882 }
   1883 #endif
   1884 
   1885 /**
   1886  * Returns an array containing all the X509 certificate's bytes.
   1887  */
   1888 static jobjectArray getCertificateBytes(JNIEnv* env, const STACK_OF(X509)* chain)
   1889 {
   1890     if (chain == NULL) {
   1891         // Chain can be NULL if the associated cipher doesn't do certs.
   1892         return NULL;
   1893     }
   1894 
   1895     int count = sk_X509_num(chain);
   1896     if (count <= 0) {
   1897         return NULL;
   1898     }
   1899 
   1900     jobjectArray joa = env->NewObjectArray(count, JniConstants::byteArrayClass, NULL);
   1901     if (joa == NULL) {
   1902         return NULL;
   1903     }
   1904 
   1905     for (int i = 0; i < count; i++) {
   1906         X509* cert = sk_X509_value(chain, i);
   1907 
   1908         int len = i2d_X509(cert, NULL);
   1909         if (len < 0) {
   1910             return NULL;
   1911         }
   1912         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
   1913         if (byteArray.get() == NULL) {
   1914             return NULL;
   1915         }
   1916         ScopedByteArrayRW bytes(env, byteArray.get());
   1917         if (bytes.get() == NULL) {
   1918             return NULL;
   1919         }
   1920         unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
   1921         int n = i2d_X509(cert, &p);
   1922         if (n < 0) {
   1923             return NULL;
   1924         }
   1925         env->SetObjectArrayElement(joa, i, byteArray.get());
   1926     }
   1927 
   1928     return joa;
   1929 }
   1930 
   1931 /**
   1932  * Returns an array containing all the X500 principal's bytes.
   1933  */
   1934 static jobjectArray getPrincipalBytes(JNIEnv* env, const STACK_OF(X509_NAME)* names)
   1935 {
   1936     if (names == NULL) {
   1937         return NULL;
   1938     }
   1939 
   1940     int count = sk_X509_NAME_num(names);
   1941     if (count <= 0) {
   1942         return NULL;
   1943     }
   1944 
   1945     jobjectArray joa = env->NewObjectArray(count, JniConstants::byteArrayClass, NULL);
   1946     if (joa == NULL) {
   1947         return NULL;
   1948     }
   1949 
   1950     for (int i = 0; i < count; i++) {
   1951         X509_NAME* principal = sk_X509_NAME_value(names, i);
   1952 
   1953         int len = i2d_X509_NAME(principal, NULL);
   1954         if (len < 0) {
   1955             return NULL;
   1956         }
   1957         ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
   1958         if (byteArray.get() == NULL) {
   1959             return NULL;
   1960         }
   1961         ScopedByteArrayRW bytes(env, byteArray.get());
   1962         if (bytes.get() == NULL) {
   1963             return NULL;
   1964         }
   1965         unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
   1966         int n = i2d_X509_NAME(principal, &p);
   1967         if (n < 0) {
   1968             return NULL;
   1969         }
   1970         env->SetObjectArrayElement(joa, i, byteArray.get());
   1971     }
   1972 
   1973     return joa;
   1974 }
   1975 
   1976 /**
   1977  * Our additional application data needed for getting synchronization right.
   1978  * This maybe warrants a bit of lengthy prose:
   1979  *
   1980  * (1) We use a flag to reflect whether we consider the SSL connection alive.
   1981  * Any read or write attempt loops will be cancelled once this flag becomes 0.
   1982  *
   1983  * (2) We use an int to count the number of threads that are blocked by the
   1984  * underlying socket. This may be at most two (one reader and one writer), since
   1985  * the Java layer ensures that no more threads will enter the native code at the
   1986  * same time.
   1987  *
   1988  * (3) The pipe is used primarily as a means of cancelling a blocking select()
   1989  * when we want to close the connection (aka "emergency button"). It is also
   1990  * necessary for dealing with a possible race condition situation: There might
   1991  * be cases where both threads see an SSL_ERROR_WANT_READ or
   1992  * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
   1993  * If one leaves the select() successfully before the other enters it, the
   1994  * "success" event is already consumed and the second thread will be blocked,
   1995  * possibly forever (depending on network conditions).
   1996  *
   1997  * The idea for solving the problem looks like this: Whenever a thread is
   1998  * successful in moving around data on the network, and it knows there is
   1999  * another thread stuck in a select(), it will write a byte to the pipe, waking
   2000  * up the other thread. A thread that returned from select(), on the other hand,
   2001  * knows whether it's been woken up by the pipe. If so, it will consume the
   2002  * byte, and the original state of affairs has been restored.
   2003  *
   2004  * The pipe may seem like a bit of overhead, but it fits in nicely with the
   2005  * other file descriptors of the select(), so there's only one condition to wait
   2006  * for.
   2007  *
   2008  * (4) Finally, a mutex is needed to make sure that at most one thread is in
   2009  * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
   2010  * requirement. We use the same mutex to guard the field for counting the
   2011  * waiting threads.
   2012  *
   2013  * Note: The current implementation assumes that we don't have to deal with
   2014  * problems induced by multiple cores or processors and their respective
   2015  * memory caches. One possible problem is that of inconsistent views on the
   2016  * "aliveAndKicking" field. This could be worked around by also enclosing all
   2017  * accesses to that field inside a lock/unlock sequence of our mutex, but
   2018  * currently this seems a bit like overkill. Marking volatile at the very least.
   2019  *
   2020  * During handshaking, additional fields are used to up-call into
   2021  * Java to perform certificate verification and handshake
   2022  * completion. These are also used in any renegotiation.
   2023  *
   2024  * (5) the JNIEnv so we can invoke the Java callback
   2025  *
   2026  * (6) a NativeCrypto.SSLHandshakeCallbacks instance for callbacks from native to Java
   2027  *
   2028  * (7) a java.io.FileDescriptor wrapper to check for socket close
   2029  *
   2030  * We store the NPN protocols list so we can either send it (from the server) or
   2031  * select a protocol (on the client). We eagerly acquire a pointer to the array
   2032  * data so the callback doesn't need to acquire resources that it cannot
   2033  * release.
   2034  *
   2035  * Because renegotiation can be requested by the peer at any time,
   2036  * care should be taken to maintain an appropriate JNIEnv on any
   2037  * downcall to openssl since it could result in an upcall to Java. The
   2038  * current code does try to cover these cases by conditionally setting
   2039  * the JNIEnv on calls that can read and write to the SSL such as
   2040  * SSL_do_handshake, SSL_read, SSL_write, and SSL_shutdown.
   2041  *
   2042  * Finally, we have two emphemeral keys setup by OpenSSL callbacks:
   2043  *
   2044  * (8) a set of ephemeral RSA keys that is lazily generated if a peer
   2045  * wants to use an exportable RSA cipher suite.
   2046  *
   2047  * (9) a set of ephemeral EC keys that is lazily generated if a peer
   2048  * wants to use an TLS_ECDHE_* cipher suite.
   2049  *
   2050  */
   2051 class AppData {
   2052   public:
   2053     volatile int aliveAndKicking;
   2054     int waitingThreads;
   2055     int fdsEmergency[2];
   2056     MUTEX_TYPE mutex;
   2057     JNIEnv* env;
   2058     jobject sslHandshakeCallbacks;
   2059     jobject fileDescriptor;
   2060     jbyteArray npnProtocolsArray;
   2061     jbyte* npnProtocolsData;
   2062     size_t npnProtocolsLength;
   2063     Unique_RSA ephemeralRsa;
   2064     Unique_EC_KEY ephemeralEc;
   2065 
   2066     /**
   2067      * Creates the application data context for the SSL*.
   2068      */
   2069   public:
   2070     static AppData* create() {
   2071         UniquePtr<AppData> appData(new AppData());
   2072         if (pipe(appData.get()->fdsEmergency) == -1) {
   2073             return NULL;
   2074         }
   2075         if (!setBlocking(appData.get()->fdsEmergency[0], false)) {
   2076             return NULL;
   2077         }
   2078         if (MUTEX_SETUP(appData.get()->mutex) == -1) {
   2079             return NULL;
   2080         }
   2081         return appData.release();
   2082     }
   2083 
   2084     ~AppData() {
   2085         aliveAndKicking = 0;
   2086         if (fdsEmergency[0] != -1) {
   2087             close(fdsEmergency[0]);
   2088         }
   2089         if (fdsEmergency[1] != -1) {
   2090             close(fdsEmergency[1]);
   2091         }
   2092         MUTEX_CLEANUP(mutex);
   2093     }
   2094 
   2095   private:
   2096     AppData() :
   2097             aliveAndKicking(1),
   2098             waitingThreads(0),
   2099             env(NULL),
   2100             sslHandshakeCallbacks(NULL),
   2101             npnProtocolsArray(NULL),
   2102             npnProtocolsData(NULL),
   2103             npnProtocolsLength(-1),
   2104             ephemeralRsa(NULL),
   2105             ephemeralEc(NULL) {
   2106         fdsEmergency[0] = -1;
   2107         fdsEmergency[1] = -1;
   2108     }
   2109 
   2110   public:
   2111     /**
   2112      * Used to set the SSL-to-Java callback state before each SSL_*
   2113      * call that may result in a callback. It should be cleared after
   2114      * the operation returns with clearCallbackState.
   2115      *
   2116      * @param env The JNIEnv
   2117      * @param shc The SSLHandshakeCallbacks
   2118      * @param fd The FileDescriptor
   2119      * @param npnProtocols NPN protocols so that they may be advertised (by the
   2120      *                     server) or selected (by the client). Has no effect
   2121      *                     unless NPN is enabled.
   2122      */
   2123     bool setCallbackState(JNIEnv* e, jobject shc, jobject fd, jbyteArray npnProtocols) {
   2124         NetFd netFd(e, fd);
   2125         if (netFd.isClosed()) {
   2126             return false;
   2127         }
   2128         env = e;
   2129         sslHandshakeCallbacks = shc;
   2130         fileDescriptor = fd;
   2131         if (npnProtocols != NULL) {
   2132             npnProtocolsArray = npnProtocols;
   2133             npnProtocolsLength = e->GetArrayLength(npnProtocols);
   2134             npnProtocolsData = e->GetByteArrayElements(npnProtocols, NULL);
   2135             if (npnProtocolsData == NULL) {
   2136                 return false;
   2137             }
   2138         }
   2139         return true;
   2140     }
   2141 
   2142     void clearCallbackState() {
   2143         sslHandshakeCallbacks = NULL;
   2144         fileDescriptor = NULL;
   2145         if (npnProtocolsArray != NULL) {
   2146             env->ReleaseByteArrayElements(npnProtocolsArray, npnProtocolsData, JNI_ABORT);
   2147             npnProtocolsArray = NULL;
   2148             npnProtocolsData = NULL;
   2149             npnProtocolsLength = -1;
   2150         }
   2151         env = NULL;
   2152     }
   2153 
   2154 };
   2155 
   2156 /**
   2157  * Dark magic helper function that checks, for a given SSL session, whether it
   2158  * can SSL_read() or SSL_write() without blocking. Takes into account any
   2159  * concurrent attempts to close the SSLSocket from the Java side. This is
   2160  * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
   2161  * while thread #2 is sitting in a blocking read or write. The type argument
   2162  * specifies whether we are waiting for readability or writability. It expects
   2163  * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
   2164  * only need to wait in case one of these problems occurs.
   2165  *
   2166  * @param env
   2167  * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
   2168  * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL
   2169  * @param appData The application data structure with mutex info etc.
   2170  * @param timeout_millis The timeout value for select call, with the special value
   2171  *                0 meaning no timeout at all (wait indefinitely). Note: This is
   2172  *                the Java semantics of the timeout value, not the usual
   2173  *                select() semantics.
   2174  * @return The result of the inner select() call,
   2175  * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on
   2176  * additional errors
   2177  */
   2178 static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout_millis) {
   2179     // This loop is an expanded version of the NET_FAILURE_RETRY
   2180     // macro. It cannot simply be used in this case because select
   2181     // cannot be restarted without recreating the fd_sets and timeout
   2182     // structure.
   2183     int result;
   2184     fd_set rfds;
   2185     fd_set wfds;
   2186     do {
   2187         NetFd fd(env, fdObject);
   2188         if (fd.isClosed()) {
   2189             result = THROWN_EXCEPTION;
   2190             break;
   2191         }
   2192         int intFd = fd.get();
   2193         JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout_millis=%d",
   2194                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout_millis);
   2195 
   2196         FD_ZERO(&rfds);
   2197         FD_ZERO(&wfds);
   2198 
   2199         if (type == SSL_ERROR_WANT_READ) {
   2200             FD_SET(intFd, &rfds);
   2201         } else {
   2202             FD_SET(intFd, &wfds);
   2203         }
   2204 
   2205         FD_SET(appData->fdsEmergency[0], &rfds);
   2206 
   2207         int maxFd = (intFd > appData->fdsEmergency[0]) ? intFd : appData->fdsEmergency[0];
   2208 
   2209         // Build a struct for the timeout data if we actually want a timeout.
   2210         timeval tv;
   2211         timeval* ptv;
   2212         if (timeout_millis > 0) {
   2213             tv.tv_sec = timeout_millis / 1000;
   2214             tv.tv_usec = (timeout_millis % 1000) * 1000;
   2215             ptv = &tv;
   2216         } else {
   2217             ptv = NULL;
   2218         }
   2219 
   2220         AsynchronousSocketCloseMonitor monitor(intFd);
   2221         result = select(maxFd + 1, &rfds, &wfds, NULL, ptv);
   2222         JNI_TRACE("sslSelect %s fd=%d appData=%p timeout_millis=%d => %d",
   2223                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE",
   2224                   fd.get(), appData, timeout_millis, result);
   2225         if (result == -1) {
   2226             if (fd.isClosed()) {
   2227                 result = THROWN_EXCEPTION;
   2228                 break;
   2229             }
   2230             if (errno != EINTR) {
   2231                 break;
   2232             }
   2233         }
   2234     } while (result == -1);
   2235 
   2236     if (MUTEX_LOCK(appData->mutex) == -1) {
   2237         return -1;
   2238     }
   2239 
   2240     if (result > 0) {
   2241         // We have been woken up by a token in the emergency pipe. We
   2242         // can't be sure the token is still in the pipe at this point
   2243         // because it could have already been read by the thread that
   2244         // originally wrote it if it entered sslSelect and acquired
   2245         // the mutex before we did. Thus we cannot safely read from
   2246         // the pipe in a blocking way (so we make the pipe
   2247         // non-blocking at creation).
   2248         if (FD_ISSET(appData->fdsEmergency[0], &rfds)) {
   2249             char token;
   2250             do {
   2251                 read(appData->fdsEmergency[0], &token, 1);
   2252             } while (errno == EINTR);
   2253         }
   2254     }
   2255 
   2256     // Tell the world that there is now one thread less waiting for the
   2257     // underlying network.
   2258     appData->waitingThreads--;
   2259 
   2260     MUTEX_UNLOCK(appData->mutex);
   2261 
   2262     return result;
   2263 }
   2264 
   2265 /**
   2266  * Helper function that wakes up a thread blocked in select(), in case there is
   2267  * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
   2268  * before closing the connection.
   2269  *
   2270  * @param data The application data structure with mutex info etc.
   2271  */
   2272 static void sslNotify(AppData* appData) {
   2273     // Write a byte to the emergency pipe, so a concurrent select() can return.
   2274     // Note we have to restore the errno of the original system call, since the
   2275     // caller relies on it for generating error messages.
   2276     int errnoBackup = errno;
   2277     char token = '*';
   2278     do {
   2279         errno = 0;
   2280         write(appData->fdsEmergency[1], &token, 1);
   2281     } while (errno == EINTR);
   2282     errno = errnoBackup;
   2283 }
   2284 
   2285 static AppData* toAppData(const SSL* ssl) {
   2286     return reinterpret_cast<AppData*>(SSL_get_app_data(ssl));
   2287 }
   2288 
   2289 /**
   2290  * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback
   2291  */
   2292 static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused)))
   2293 {
   2294     /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
   2295     SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx,
   2296             SSL_get_ex_data_X509_STORE_CTX_idx()));
   2297     JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg);
   2298 
   2299     AppData* appData = toAppData(ssl);
   2300     JNIEnv* env = appData->env;
   2301     if (env == NULL) {
   2302         ALOGE("AppData->env missing in cert_verify_callback");
   2303         JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl);
   2304         return 0;
   2305     }
   2306     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   2307 
   2308     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   2309     jmethodID methodID
   2310         = env->GetMethodID(cls, "verifyCertificateChain", "([[BLjava/lang/String;)V");
   2311 
   2312     jobjectArray objectArray = getCertificateBytes(env, x509_store_ctx->untrusted);
   2313 
   2314     const char* authMethod = SSL_authentication_method(ssl);
   2315     JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s",
   2316               ssl, authMethod);
   2317     jstring authMethodString = env->NewStringUTF(authMethod);
   2318     env->CallVoidMethod(sslHandshakeCallbacks, methodID, objectArray, authMethodString);
   2319 
   2320     int result = (env->ExceptionCheck()) ? 0 : 1;
   2321     JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result);
   2322     return result;
   2323 }
   2324 
   2325 /**
   2326  * Call back to watch for handshake to be completed. This is necessary
   2327  * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake
   2328  * returns before the handshake is completed in this case.
   2329  */
   2330 static void info_callback(const SSL* ssl, int where, int ret __attribute__ ((unused))) {
   2331     JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret);
   2332 #ifdef WITH_JNI_TRACE
   2333     info_callback_LOG(ssl, where, ret);
   2334 #endif
   2335     if (!(where & SSL_CB_HANDSHAKE_DONE)) {
   2336         JNI_TRACE("ssl=%p info_callback ignored", ssl);
   2337         return;
   2338     }
   2339 
   2340     AppData* appData = toAppData(ssl);
   2341     JNIEnv* env = appData->env;
   2342     if (env == NULL) {
   2343         ALOGE("AppData->env missing in info_callback");
   2344         JNI_TRACE("ssl=%p info_callback env error", ssl);
   2345         return;
   2346     }
   2347     if (env->ExceptionCheck()) {
   2348         JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
   2349         return;
   2350     }
   2351 
   2352     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   2353 
   2354     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   2355     jmethodID methodID = env->GetMethodID(cls, "handshakeCompleted", "()V");
   2356 
   2357     JNI_TRACE("ssl=%p info_callback calling handshakeCompleted", ssl);
   2358     env->CallVoidMethod(sslHandshakeCallbacks, methodID);
   2359 
   2360     if (env->ExceptionCheck()) {
   2361         JNI_TRACE("ssl=%p info_callback exception", ssl);
   2362     }
   2363     JNI_TRACE("ssl=%p info_callback completed", ssl);
   2364 }
   2365 
   2366 /**
   2367  * Call back to ask for a client certificate
   2368  */
   2369 static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) {
   2370     JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut);
   2371 
   2372     AppData* appData = toAppData(ssl);
   2373     JNIEnv* env = appData->env;
   2374     if (env == NULL) {
   2375         ALOGE("AppData->env missing in client_cert_cb");
   2376         JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl);
   2377         return 0;
   2378     }
   2379     if (env->ExceptionCheck()) {
   2380         JNI_TRACE("ssl=%p client_cert_cb already pending exception => 0", ssl);
   2381         return 0;
   2382     }
   2383     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   2384 
   2385     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   2386     jmethodID methodID
   2387         = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V");
   2388 
   2389     // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values
   2390     char ssl2_ctype = SSL3_CT_RSA_SIGN;
   2391     const char* ctype = NULL;
   2392     int ctype_num = 0;
   2393     jobjectArray issuers = NULL;
   2394     switch (ssl->version) {
   2395         case SSL2_VERSION:
   2396             ctype = &ssl2_ctype;
   2397             ctype_num = 1;
   2398             break;
   2399         case SSL3_VERSION:
   2400         case TLS1_VERSION:
   2401         case TLS1_1_VERSION:
   2402         case TLS1_2_VERSION:
   2403         case DTLS1_VERSION:
   2404             ctype = ssl->s3->tmp.ctype;
   2405             ctype_num = ssl->s3->tmp.ctype_num;
   2406             issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names);
   2407             break;
   2408     }
   2409 #ifdef WITH_JNI_TRACE
   2410     for (int i = 0; i < ctype_num; i++) {
   2411         JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]);
   2412     }
   2413 #endif
   2414 
   2415     jbyteArray keyTypes = env->NewByteArray(ctype_num);
   2416     if (keyTypes == NULL) {
   2417         JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl);
   2418         return 0;
   2419     }
   2420     env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype));
   2421 
   2422     JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested "
   2423               "keyTypes=%p issuers=%p", ssl, keyTypes, issuers);
   2424     env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers);
   2425 
   2426     if (env->ExceptionCheck()) {
   2427         JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl);
   2428         return 0;
   2429     }
   2430 
   2431     // Check for values set from Java
   2432     X509*     certificate = SSL_get_certificate(ssl);
   2433     EVP_PKEY* privatekey  = SSL_get_privatekey(ssl);
   2434     int result;
   2435     if (certificate != NULL && privatekey != NULL) {
   2436         *x509Out = certificate;
   2437         *pkeyOut = privatekey;
   2438         result = 1;
   2439     } else {
   2440         *x509Out = NULL;
   2441         *pkeyOut = NULL;
   2442         result = 0;
   2443     }
   2444     JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result);
   2445     return result;
   2446 }
   2447 
   2448 static RSA* rsaGenerateKey(int keylength) {
   2449     Unique_BIGNUM bn(BN_new());
   2450     if (bn.get() == NULL) {
   2451         return NULL;
   2452     }
   2453     int setWordResult = BN_set_word(bn.get(), RSA_F4);
   2454     if (setWordResult != 1) {
   2455         return NULL;
   2456     }
   2457     Unique_RSA rsa(RSA_new());
   2458     if (rsa.get() == NULL) {
   2459         return NULL;
   2460     }
   2461     int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL);
   2462     if (generateResult != 1) {
   2463         return NULL;
   2464     }
   2465     return rsa.release();
   2466 }
   2467 
   2468 /**
   2469  * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5)
   2470  */
   2471 static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)),
   2472                              int is_export __attribute__ ((unused)),
   2473                              int keylength) {
   2474     JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   2475 
   2476     AppData* appData = toAppData(ssl);
   2477     if (appData->ephemeralRsa.get() == NULL) {
   2478         JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl);
   2479         appData->ephemeralRsa.reset(rsaGenerateKey(keylength));
   2480     }
   2481     JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get());
   2482     return appData->ephemeralRsa.get();
   2483 }
   2484 
   2485 static DH* dhGenerateParameters(int keylength) {
   2486 
   2487     /*
   2488      * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two
   2489      * different options for generating DH keys. One is generating the
   2490      * keys using a single set of DH parameters. However, generating
   2491      * DH parameters is slow enough (minutes) that they suggest doing
   2492      * it once at install time. The other is to generate DH keys from
   2493      * DSA parameters. Generating DSA parameters is faster than DH
   2494      * parameters, but to prevent small subgroup attacks, they needed
   2495      * to be regenerated for each set of DH keys. Setting the
   2496      * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back
   2497      * for new DH parameters every type it needs to generate DH keys.
   2498      */
   2499 #if 0
   2500     // Slow path that takes minutes but could be cached
   2501     Unique_DH dh(DH_new());
   2502     if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) {
   2503         return NULL;
   2504     }
   2505     return dh.release();
   2506 #else
   2507     // Faster path but must have SSL_OP_SINGLE_DH_USE set
   2508     Unique_DSA dsa(DSA_new());
   2509     if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) {
   2510         return NULL;
   2511     }
   2512     DH* dh = DSA_dup_DH(dsa.get());
   2513     return dh;
   2514 #endif
   2515 }
   2516 
   2517 /**
   2518  * Call back to ask for Diffie-Hellman parameters
   2519  */
   2520 static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)),
   2521                            int is_export __attribute__ ((unused)),
   2522                            int keylength) {
   2523     JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   2524     DH* tmp_dh = dhGenerateParameters(keylength);
   2525     JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh);
   2526     return tmp_dh;
   2527 }
   2528 
   2529 static EC_KEY* ecGenerateKey(int keylength __attribute__ ((unused))) {
   2530     // TODO selected curve based on keylength
   2531     Unique_EC_KEY ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
   2532     if (ec.get() == NULL) {
   2533         return NULL;
   2534     }
   2535     return ec.release();
   2536 }
   2537 
   2538 /**
   2539  * Call back to ask for an ephemeral EC key for TLS_ECDHE_* cipher suites
   2540  */
   2541 static EC_KEY* tmp_ecdh_callback(SSL* ssl __attribute__ ((unused)),
   2542                                  int is_export __attribute__ ((unused)),
   2543                                  int keylength) {
   2544     JNI_TRACE("ssl=%p tmp_ecdh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   2545     AppData* appData = toAppData(ssl);
   2546     if (appData->ephemeralEc.get() == NULL) {
   2547         JNI_TRACE("ssl=%p tmp_ecdh_callback generating ephemeral EC key", ssl);
   2548         appData->ephemeralEc.reset(ecGenerateKey(keylength));
   2549     }
   2550     JNI_TRACE("ssl=%p tmp_ecdh_callback => %p", ssl, appData->ephemeralEc.get());
   2551     return appData->ephemeralEc.get();
   2552 }
   2553 
   2554 /*
   2555  * public static native int SSL_CTX_new();
   2556  */
   2557 static int NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
   2558     Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
   2559     if (sslCtx.get() == NULL) {
   2560         jniThrowRuntimeException(env, "SSL_CTX_new");
   2561         return 0;
   2562     }
   2563     SSL_CTX_set_options(sslCtx.get(),
   2564                         SSL_OP_ALL
   2565                         // Note: We explicitly do not allow SSLv2 to be used.
   2566                         | SSL_OP_NO_SSLv2
   2567                         // We also disable session tickets for better compatibility b/2682876
   2568                         | SSL_OP_NO_TICKET
   2569                         // We also disable compression for better compatibility b/2710492 b/2710497
   2570                         | SSL_OP_NO_COMPRESSION
   2571                         // Because dhGenerateParameters uses DSA_generate_parameters_ex
   2572                         | SSL_OP_SINGLE_DH_USE
   2573                         // Because ecGenerateParameters uses a fixed named curve
   2574                         | SSL_OP_SINGLE_ECDH_USE);
   2575 
   2576     int mode = SSL_CTX_get_mode(sslCtx.get());
   2577     /*
   2578      * Turn on "partial write" mode. This means that SSL_write() will
   2579      * behave like Posix write() and possibly return after only
   2580      * writing a partial buffer. Note: The alternative, perhaps
   2581      * surprisingly, is not that SSL_write() always does full writes
   2582      * but that it will force you to retry write calls having
   2583      * preserved the full state of the original call. (This is icky
   2584      * and undesirable.)
   2585      */
   2586     mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
   2587 #if defined(SSL_MODE_SMALL_BUFFERS) /* not all SSL versions have this */
   2588     mode |= SSL_MODE_SMALL_BUFFERS;  /* lazily allocate record buffers; usually saves
   2589                                       * 44k over the default */
   2590 #endif
   2591     SSL_CTX_set_mode(sslCtx.get(), mode);
   2592 
   2593     SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL);
   2594     SSL_CTX_set_info_callback(sslCtx.get(), info_callback);
   2595     SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb);
   2596     SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback);
   2597     SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback);
   2598     SSL_CTX_set_tmp_ecdh_callback(sslCtx.get(), tmp_ecdh_callback);
   2599 
   2600     JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
   2601     return (jint) sslCtx.release();
   2602 }
   2603 
   2604 /**
   2605  * public static native void SSL_CTX_free(int ssl_ctx)
   2606  */
   2607 static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
   2608         jclass, jint ssl_ctx_address)
   2609 {
   2610     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   2611     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
   2612     if (ssl_ctx == NULL) {
   2613         return;
   2614     }
   2615     SSL_CTX_free(ssl_ctx);
   2616 }
   2617 
   2618 static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass,
   2619                                                         jint ssl_ctx_address, jbyteArray sid_ctx)
   2620 {
   2621     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   2622     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx);
   2623     if (ssl_ctx == NULL) {
   2624         return;
   2625     }
   2626 
   2627     ScopedByteArrayRO buf(env, sid_ctx);
   2628     if (buf.get() == NULL) {
   2629         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => threw exception", ssl_ctx);
   2630         return;
   2631     }
   2632 
   2633     unsigned int length = buf.size();
   2634     if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) {
   2635         jniThrowException(env, "java/lang/IllegalArgumentException",
   2636                           "length > SSL_MAX_SSL_SESSION_ID_LENGTH");
   2637         JNI_TRACE("NativeCrypto_SSL_CTX_set_session_id_context => length = %d", length);
   2638         return;
   2639     }
   2640     const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buf.get());
   2641     int result = SSL_CTX_set_session_id_context(ssl_ctx, bytes, length);
   2642     if (result == 0) {
   2643         throwExceptionIfNecessary(env, "NativeCrypto_SSL_CTX_set_session_id_context");
   2644         return;
   2645     }
   2646     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => ok", ssl_ctx);
   2647 }
   2648 
   2649 /**
   2650  * public static native int SSL_new(int ssl_ctx) throws SSLException;
   2651  */
   2652 static jint NativeCrypto_SSL_new(JNIEnv* env, jclass, jint ssl_ctx_address)
   2653 {
   2654     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   2655     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
   2656     if (ssl_ctx == NULL) {
   2657         return 0;
   2658     }
   2659     Unique_SSL ssl(SSL_new(ssl_ctx));
   2660     if (ssl.get() == NULL) {
   2661         throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE,
   2662                 "Unable to create SSL structure");
   2663         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
   2664         return 0;
   2665     }
   2666 
   2667     /* Java code in class OpenSSLSocketImpl does the verification. Meaning of
   2668      * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher
   2669      * (by default disabled), the server will send a certificate which will
   2670      * be checked. The result of the certificate verification process can be
   2671      * checked after the TLS/SSL handshake using the SSL_get_verify_result(3)
   2672      * function. The handshake will be continued regardless of the
   2673      * verification result.
   2674      */
   2675     SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL);
   2676 
   2677     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get());
   2678     return (jint) ssl.release();
   2679 }
   2680 
   2681 static void NativeCrypto_SSL_use_OpenSSL_PrivateKey(JNIEnv* env, jclass, jint ssl_address, jint pkeyRef) {
   2682     SSL* ssl = to_SSL(env, ssl_address, true);
   2683     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2684     JNI_TRACE("ssl=%p SSL_use_OpenSSL_PrivateKey privatekey=%p", ssl, pkey);
   2685     if (ssl == NULL) {
   2686         return;
   2687     }
   2688 
   2689     if (pkey == NULL) {
   2690         return;
   2691     }
   2692 
   2693     int ret = SSL_use_PrivateKey(ssl, pkey);
   2694     if (ret != 1) {
   2695         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2696         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
   2697         SSL_clear(ssl);
   2698         JNI_TRACE("ssl=%p SSL_use_OpenSSL_PrivateKey => error", ssl);
   2699         return;
   2700     }
   2701     // SSL_use_PrivateKey expects to take ownership of the EVP_PKEY,
   2702     // but we have an external reference from the caller such as an
   2703     // OpenSSLKey, so we manually increment the reference count here.
   2704     CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
   2705 
   2706     JNI_TRACE("ssl=%p SSL_use_OpenSSL_PrivateKey => ok", ssl);
   2707 }
   2708 
   2709 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass,
   2710                                             jint ssl_address, jbyteArray privatekey)
   2711 {
   2712     SSL* ssl = to_SSL(env, ssl_address, true);
   2713     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey privatekey=%p", ssl, privatekey);
   2714     if (ssl == NULL) {
   2715         return;
   2716     }
   2717 
   2718     ScopedByteArrayRO buf(env, privatekey);
   2719     if (buf.get() == NULL) {
   2720         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => threw exception", ssl);
   2721         return;
   2722     }
   2723     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2724     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, buf.size()));
   2725     if (pkcs8.get() == NULL) {
   2726         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2727         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   2728                                        "Error parsing private key from DER to PKCS8");
   2729         SSL_clear(ssl);
   2730         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from DER to PKCS8", ssl);
   2731         return;
   2732     }
   2733 
   2734     Unique_EVP_PKEY privatekeyevp(EVP_PKCS82PKEY(pkcs8.get()));
   2735     if (privatekeyevp.get() == NULL) {
   2736         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2737         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   2738                                        "Error creating private key from PKCS8");
   2739         SSL_clear(ssl);
   2740         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from PKCS8 to key", ssl);
   2741         return;
   2742     }
   2743 
   2744     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey EVP_PKEY_type=%d",
   2745               ssl, EVP_PKEY_type(privatekeyevp.get()->type));
   2746     int ret = SSL_use_PrivateKey(ssl, privatekeyevp.get());
   2747     if (ret == 1) {
   2748         OWNERSHIP_TRANSFERRED(privatekeyevp);
   2749     } else {
   2750         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2751         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
   2752         SSL_clear(ssl);
   2753         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error", ssl);
   2754         return;
   2755     }
   2756 
   2757     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => ok", ssl);
   2758 }
   2759 
   2760 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
   2761                                              jint ssl_address, jobjectArray certificates)
   2762 {
   2763     SSL* ssl = to_SSL(env, ssl_address, true);
   2764     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
   2765     if (ssl == NULL) {
   2766         return;
   2767     }
   2768 
   2769     if (certificates == NULL) {
   2770         jniThrowNullPointerException(env, "certificates == null");
   2771         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
   2772         return;
   2773     }
   2774 
   2775     int length = env->GetArrayLength(certificates);
   2776     if (length == 0) {
   2777         jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
   2778         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
   2779         return;
   2780     }
   2781 
   2782     Unique_X509 certificatesX509[length];
   2783     for (int i = 0; i < length; i++) {
   2784         ScopedLocalRef<jbyteArray> certificate(env,
   2785                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i)));
   2786         if (certificate.get() == NULL) {
   2787             jniThrowNullPointerException(env, "certificates element == null");
   2788             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl);
   2789             return;
   2790         }
   2791 
   2792         ScopedByteArrayRO buf(env, certificate.get());
   2793         if (buf.get() == NULL) {
   2794             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl);
   2795             return;
   2796         }
   2797         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2798         certificatesX509[i].reset(d2i_X509(NULL, &tmp, buf.size()));
   2799 
   2800         if (certificatesX509[i].get() == NULL) {
   2801             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2802             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
   2803             SSL_clear(ssl);
   2804             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
   2805             return;
   2806         }
   2807     }
   2808 
   2809     int ret = SSL_use_certificate(ssl, certificatesX509[0].get());
   2810     if (ret == 1) {
   2811         OWNERSHIP_TRANSFERRED(certificatesX509[0]);
   2812     } else {
   2813         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2814         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
   2815         SSL_clear(ssl);
   2816         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
   2817         return;
   2818     }
   2819 
   2820     Unique_sk_X509 chain(sk_X509_new_null());
   2821     if (chain.get() == NULL) {
   2822         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
   2823         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
   2824         return;
   2825     }
   2826     for (int i = 1; i < length; i++) {
   2827         if (!sk_X509_push(chain.get(), certificatesX509[i].release())) {
   2828             jniThrowOutOfMemoryError(env, "Unable to push certificate");
   2829             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl);
   2830             return;
   2831         }
   2832     }
   2833     int chainResult = SSL_use_certificate_chain(ssl, chain.get());
   2834     if (chainResult == 0) {
   2835         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
   2836         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
   2837                   ssl);
   2838         return;
   2839     } else {
   2840         OWNERSHIP_TRANSFERRED(chain);
   2841     }
   2842 
   2843     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
   2844 }
   2845 
   2846 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jint ssl_address)
   2847 {
   2848     SSL* ssl = to_SSL(env, ssl_address, true);
   2849     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
   2850     if (ssl == NULL) {
   2851         return;
   2852     }
   2853     int ret = SSL_check_private_key(ssl);
   2854     if (ret != 1) {
   2855         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
   2856         SSL_clear(ssl);
   2857         JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
   2858         return;
   2859     }
   2860     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
   2861 }
   2862 
   2863 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
   2864                                                 jint ssl_address, jobjectArray principals)
   2865 {
   2866     SSL* ssl = to_SSL(env, ssl_address, true);
   2867     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
   2868     if (ssl == NULL) {
   2869         return;
   2870     }
   2871 
   2872     if (principals == NULL) {
   2873         jniThrowNullPointerException(env, "principals == null");
   2874         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
   2875         return;
   2876     }
   2877 
   2878     int length = env->GetArrayLength(principals);
   2879     if (length == 0) {
   2880         jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
   2881         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
   2882         return;
   2883     }
   2884 
   2885     Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
   2886     if (principalsStack.get() == NULL) {
   2887         jniThrowOutOfMemoryError(env, "Unable to allocate principal stack");
   2888         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
   2889         return;
   2890     }
   2891     for (int i = 0; i < length; i++) {
   2892         ScopedLocalRef<jbyteArray> principal(env,
   2893                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
   2894         if (principal.get() == NULL) {
   2895             jniThrowNullPointerException(env, "principals element == null");
   2896             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
   2897             return;
   2898         }
   2899 
   2900         ScopedByteArrayRO buf(env, principal.get());
   2901         if (buf.get() == NULL) {
   2902             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
   2903             return;
   2904         }
   2905         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2906         Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
   2907 
   2908         if (principalX509Name.get() == NULL) {
   2909             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2910             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
   2911             SSL_clear(ssl);
   2912             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
   2913                       ssl);
   2914             return;
   2915         }
   2916 
   2917         if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
   2918             jniThrowOutOfMemoryError(env, "Unable to push principal");
   2919             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
   2920             return;
   2921         }
   2922     }
   2923 
   2924     SSL_set_client_CA_list(ssl, principalsStack.release());
   2925     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
   2926 }
   2927 
   2928 /**
   2929  * public static native long SSL_get_mode(int ssl);
   2930  */
   2931 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jint ssl_address) {
   2932     SSL* ssl = to_SSL(env, ssl_address, true);
   2933     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
   2934     if (ssl == NULL) {
   2935       return 0;
   2936     }
   2937     long mode = SSL_get_mode(ssl);
   2938     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
   2939     return mode;
   2940 }
   2941 
   2942 /**
   2943  * public static native long SSL_set_mode(int ssl, long mode);
   2944  */
   2945 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
   2946         jint ssl_address, jlong mode) {
   2947     SSL* ssl = to_SSL(env, ssl_address, true);
   2948     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
   2949     if (ssl == NULL) {
   2950       return 0;
   2951     }
   2952     long result = SSL_set_mode(ssl, mode);
   2953     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
   2954     return result;
   2955 }
   2956 
   2957 /**
   2958  * public static native long SSL_clear_mode(int ssl, long mode);
   2959  */
   2960 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
   2961         jint ssl_address, jlong mode) {
   2962     SSL* ssl = to_SSL(env, ssl_address, true);
   2963     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
   2964     if (ssl == NULL) {
   2965       return 0;
   2966     }
   2967     long result = SSL_clear_mode(ssl, mode);
   2968     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
   2969     return result;
   2970 }
   2971 
   2972 /**
   2973  * public static native long SSL_get_options(int ssl);
   2974  */
   2975 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
   2976         jint ssl_address) {
   2977     SSL* ssl = to_SSL(env, ssl_address, true);
   2978     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
   2979     if (ssl == NULL) {
   2980       return 0;
   2981     }
   2982     long options = SSL_get_options(ssl);
   2983     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
   2984     return options;
   2985 }
   2986 
   2987 /**
   2988  * public static native long SSL_set_options(int ssl, long options);
   2989  */
   2990 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
   2991         jint ssl_address, jlong options) {
   2992     SSL* ssl = to_SSL(env, ssl_address, true);
   2993     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
   2994     if (ssl == NULL) {
   2995       return 0;
   2996     }
   2997     long result = SSL_set_options(ssl, options);
   2998     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
   2999     return result;
   3000 }
   3001 
   3002 /**
   3003  * public static native long SSL_clear_options(int ssl, long options);
   3004  */
   3005 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
   3006         jint ssl_address, jlong options) {
   3007     SSL* ssl = to_SSL(env, ssl_address, true);
   3008     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
   3009     if (ssl == NULL) {
   3010       return 0;
   3011     }
   3012     long result = SSL_clear_options(ssl, options);
   3013     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
   3014     return result;
   3015 }
   3016 
   3017 /**
   3018  * Sets the ciphers suites that are enabled in the SSL
   3019  */
   3020 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
   3021         jint ssl_address, jobjectArray cipherSuites)
   3022 {
   3023     SSL* ssl = to_SSL(env, ssl_address, true);
   3024     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
   3025     if (ssl == NULL) {
   3026         return;
   3027     }
   3028     if (cipherSuites == NULL) {
   3029         jniThrowNullPointerException(env, "cipherSuites == null");
   3030         return;
   3031     }
   3032 
   3033     Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
   3034     if (cipherstack.get() == NULL) {
   3035         jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
   3036         return;
   3037     }
   3038 
   3039     const SSL_METHOD* ssl_method = ssl->method;
   3040     int num_ciphers = ssl_method->num_ciphers();
   3041 
   3042     int length = env->GetArrayLength(cipherSuites);
   3043     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
   3044     for (int i = 0; i < length; i++) {
   3045         ScopedLocalRef<jstring> cipherSuite(env,
   3046                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
   3047         ScopedUtfChars c(env, cipherSuite.get());
   3048         if (c.c_str() == NULL) {
   3049             return;
   3050         }
   3051         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
   3052         bool found = false;
   3053         for (int j = 0; j < num_ciphers; j++) {
   3054             const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
   3055             if ((strcmp(c.c_str(), cipher->name) == 0)
   3056                     && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
   3057                 if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
   3058                     jniThrowOutOfMemoryError(env, "Unable to push cipher");
   3059                     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
   3060                     return;
   3061                 }
   3062                 found = true;
   3063             }
   3064         }
   3065         if (!found) {
   3066             jniThrowException(env, "java/lang/IllegalArgumentException",
   3067                               "Could not find cipher suite.");
   3068             return;
   3069         }
   3070     }
   3071 
   3072     int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
   3073     if (rc == 0) {
   3074         freeOpenSslErrorState();
   3075         jniThrowException(env, "java/lang/IllegalArgumentException",
   3076                           "Illegal cipher suite strings.");
   3077     } else {
   3078         OWNERSHIP_TRANSFERRED(cipherstack);
   3079     }
   3080 }
   3081 
   3082 /**
   3083  * Sets certificate expectations, especially for server to request client auth
   3084  */
   3085 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
   3086         jclass, jint ssl_address, jint mode)
   3087 {
   3088     SSL* ssl = to_SSL(env, ssl_address, true);
   3089     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
   3090     if (ssl == NULL) {
   3091       return;
   3092     }
   3093     SSL_set_verify(ssl, (int)mode, NULL);
   3094 }
   3095 
   3096 /**
   3097  * Sets the ciphers suites that are enabled in the SSL
   3098  */
   3099 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
   3100         jint ssl_address, jint ssl_session_address)
   3101 {
   3102     SSL* ssl = to_SSL(env, ssl_address, true);
   3103     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
   3104     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
   3105     if (ssl == NULL) {
   3106         return;
   3107     }
   3108 
   3109     int ret = SSL_set_session(ssl, ssl_session);
   3110     if (ret != 1) {
   3111         /*
   3112          * Translate the error, and throw if it turns out to be a real
   3113          * problem.
   3114          */
   3115         int sslErrorCode = SSL_get_error(ssl, ret);
   3116         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
   3117             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
   3118             SSL_clear(ssl);
   3119         }
   3120     }
   3121 }
   3122 
   3123 /**
   3124  * Sets the ciphers suites that are enabled in the SSL
   3125  */
   3126 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
   3127         jint ssl_address, jboolean creation_enabled)
   3128 {
   3129     SSL* ssl = to_SSL(env, ssl_address, true);
   3130     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
   3131               ssl, creation_enabled);
   3132     if (ssl == NULL) {
   3133         return;
   3134     }
   3135     SSL_set_session_creation_enabled(ssl, creation_enabled);
   3136 }
   3137 
   3138 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
   3139         jint ssl_address, jstring hostname)
   3140 {
   3141     SSL* ssl = to_SSL(env, ssl_address, true);
   3142     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
   3143               ssl, hostname);
   3144     if (ssl == NULL) {
   3145         return;
   3146     }
   3147 
   3148     ScopedUtfChars hostnameChars(env, hostname);
   3149     if (hostnameChars.c_str() == NULL) {
   3150         return;
   3151     }
   3152     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s",
   3153               ssl, hostnameChars.c_str());
   3154 
   3155     int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
   3156     if (ret != 1) {
   3157         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
   3158         SSL_clear(ssl);
   3159         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
   3160         return;
   3161     }
   3162     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
   3163 }
   3164 
   3165 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jint ssl_address) {
   3166     SSL* ssl = to_SSL(env, ssl_address, true);
   3167     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
   3168     if (ssl == NULL) {
   3169         return NULL;
   3170     }
   3171     const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
   3172     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
   3173     return env->NewStringUTF(servername);
   3174 }
   3175 
   3176 /**
   3177  * Callback for the client to select a protocol.
   3178  */
   3179 static int next_proto_select_callback(SSL* ssl, unsigned char **out, unsigned char *outlen,
   3180         const unsigned char *in, unsigned int inlen, void *)
   3181 {
   3182     JNI_TRACE("ssl=%p next_proto_select_callback", ssl);
   3183 
   3184     // Enable False Start on the client if the server understands NPN
   3185     // http://www.imperialviolet.org/2012/04/11/falsestart.html
   3186     SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
   3187 
   3188     AppData* appData = toAppData(ssl);
   3189     unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
   3190     size_t npnProtocolsLength = appData->npnProtocolsLength;
   3191 
   3192     int status = SSL_select_next_proto(out, outlen, in, inlen, npnProtocols, npnProtocolsLength);
   3193     switch (status) {
   3194       case OPENSSL_NPN_NEGOTIATED:
   3195         JNI_TRACE("ssl=%p next_proto_select_callback NPN negotiated", ssl);
   3196         break;
   3197       case OPENSSL_NPN_UNSUPPORTED:
   3198         JNI_TRACE("ssl=%p next_proto_select_callback NPN unsupported", ssl);
   3199         break;
   3200       case OPENSSL_NPN_NO_OVERLAP:
   3201         JNI_TRACE("ssl=%p next_proto_select_callback NPN no overlap", ssl);
   3202         break;
   3203     }
   3204     return SSL_TLSEXT_ERR_OK;
   3205 }
   3206 
   3207 /**
   3208  * Callback for the server to advertise available protocols.
   3209  */
   3210 static int next_protos_advertised_callback(SSL* ssl,
   3211         const unsigned char **out, unsigned int *outlen, void *)
   3212 {
   3213     JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl);
   3214     AppData* appData = toAppData(ssl);
   3215     unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
   3216     if (npnProtocols != NULL) {
   3217         *out = npnProtocols;
   3218         *outlen = appData->npnProtocolsLength;
   3219     }
   3220     return SSL_TLSEXT_ERR_OK;
   3221 }
   3222 
   3223 static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jint ssl_ctx_address)
   3224 {
   3225     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   3226     if (ssl_ctx == NULL) {
   3227         return;
   3228     }
   3229     SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL); // client
   3230     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server
   3231 }
   3232 
   3233 static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jint ssl_ctx_address)
   3234 {
   3235     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   3236     if (ssl_ctx == NULL) {
   3237         return;
   3238     }
   3239     SSL_CTX_set_next_proto_select_cb(ssl_ctx, NULL, NULL); // client
   3240     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, NULL, NULL); // server
   3241 }
   3242 
   3243 static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
   3244         jint ssl_address)
   3245 {
   3246     SSL* ssl = to_SSL(env, ssl_address, true);
   3247     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
   3248     if (ssl == NULL) {
   3249         return NULL;
   3250     }
   3251     const jbyte* npn;
   3252     unsigned npnLength;
   3253     SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
   3254     if (npnLength == 0) {
   3255         return NULL;
   3256     }
   3257     jbyteArray result = env->NewByteArray(npnLength);
   3258     if (result != NULL) {
   3259         env->SetByteArrayRegion(result, 0, npnLength, npn);
   3260     }
   3261     return result;
   3262 }
   3263 
   3264 /**
   3265  * Perform SSL handshake
   3266  */
   3267 static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jint ssl_address,
   3268         jobject fdObject, jobject shc, jint timeout_millis, jboolean client_mode,
   3269         jbyteArray npnProtocols)
   3270 {
   3271     SSL* ssl = to_SSL(env, ssl_address, true);
   3272     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p",
   3273               ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols);
   3274     if (ssl == NULL) {
   3275       return 0;
   3276     }
   3277     if (fdObject == NULL) {
   3278         jniThrowNullPointerException(env, "fd == null");
   3279         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl);
   3280         return 0;
   3281     }
   3282     if (shc == NULL) {
   3283         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3284         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl);
   3285         return 0;
   3286     }
   3287 
   3288     NetFd fd(env, fdObject);
   3289     if (fd.isClosed()) {
   3290         // SocketException thrown by NetFd.isClosed
   3291         SSL_clear(ssl);
   3292         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
   3293         return 0;
   3294     }
   3295 
   3296     int ret = SSL_set_fd(ssl, fd.get());
   3297     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
   3298 
   3299     if (ret != 1) {
   3300         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   3301                                        "Error setting the file descriptor");
   3302         SSL_clear(ssl);
   3303         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
   3304         return 0;
   3305     }
   3306 
   3307     /*
   3308      * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
   3309      * forever and we can use select() to find out if the socket is ready.
   3310      */
   3311     if (!setBlocking(fd.get(), false)) {
   3312         throwSSLExceptionStr(env, "Unable to make socket non blocking");
   3313         SSL_clear(ssl);
   3314         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
   3315         return 0;
   3316     }
   3317 
   3318     /*
   3319      * Create our special application data.
   3320      */
   3321     AppData* appData = AppData::create();
   3322     if (appData == NULL) {
   3323         throwSSLExceptionStr(env, "Unable to create application data");
   3324         SSL_clear(ssl);
   3325         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
   3326         return 0;
   3327     }
   3328 
   3329     SSL_set_app_data(ssl, reinterpret_cast<char*>(appData));
   3330     JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData);
   3331 
   3332     if (client_mode) {
   3333         SSL_set_connect_state(ssl);
   3334     } else {
   3335         SSL_set_accept_state(ssl);
   3336     }
   3337 
   3338     ret = 0;
   3339     while (appData->aliveAndKicking) {
   3340         errno = 0;
   3341 
   3342         if (!appData->setCallbackState(env, shc, fdObject, npnProtocols)) {
   3343             // SocketException thrown by NetFd.isClosed
   3344             SSL_clear(ssl);
   3345             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
   3346             return 0;
   3347         }
   3348         ret = SSL_do_handshake(ssl);
   3349         appData->clearCallbackState();
   3350         // cert_verify_callback threw exception
   3351         if (env->ExceptionCheck()) {
   3352             SSL_clear(ssl);
   3353             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
   3354             return 0;
   3355         }
   3356         // success case
   3357         if (ret == 1) {
   3358             break;
   3359         }
   3360         // retry case
   3361         if (errno == EINTR) {
   3362             continue;
   3363         }
   3364         // error case
   3365         int sslError = SSL_get_error(ssl, ret);
   3366         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d",
   3367                   ssl, ret, errno, sslError, timeout_millis);
   3368 
   3369         /*
   3370          * If SSL_do_handshake doesn't succeed due to the socket being
   3371          * either unreadable or unwritable, we use sslSelect to
   3372          * wait for it to become ready. If that doesn't happen
   3373          * before the specified timeout or an error occurs, we
   3374          * cancel the handshake. Otherwise we try the SSL_connect
   3375          * again.
   3376          */
   3377         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   3378             appData->waitingThreads++;
   3379             int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
   3380 
   3381             if (selectResult == THROWN_EXCEPTION) {
   3382                 // SocketException thrown by NetFd.isClosed
   3383                 SSL_clear(ssl);
   3384                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
   3385                 return 0;
   3386             }
   3387             if (selectResult == -1) {
   3388                 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error");
   3389                 SSL_clear(ssl);
   3390                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
   3391                 return 0;
   3392             }
   3393             if (selectResult == 0) {
   3394                 throwSocketTimeoutException(env, "SSL handshake timed out");
   3395                 SSL_clear(ssl);
   3396                 freeOpenSslErrorState();
   3397                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
   3398                 return 0;
   3399             }
   3400         } else {
   3401             // ALOGE("Unknown error %d during handshake", error);
   3402             break;
   3403         }
   3404     }
   3405 
   3406     // clean error. See SSL_do_handshake(3SSL) man page.
   3407     if (ret == 0) {
   3408         /*
   3409          * The other side closed the socket before the handshake could be
   3410          * completed, but everything is within the bounds of the TLS protocol.
   3411          * We still might want to find out the real reason of the failure.
   3412          */
   3413         int sslError = SSL_get_error(ssl, ret);
   3414         if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) {
   3415             throwSSLExceptionStr(env, "Connection closed by peer");
   3416         } else {
   3417             throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated");
   3418         }
   3419         SSL_clear(ssl);
   3420         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
   3421         return 0;
   3422     }
   3423 
   3424     // unclean error. See SSL_do_handshake(3SSL) man page.
   3425     if (ret < 0) {
   3426         /*
   3427          * Translate the error and throw exception. We are sure it is an error
   3428          * at this point.
   3429          */
   3430         int sslError = SSL_get_error(ssl, ret);
   3431         throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted");
   3432         SSL_clear(ssl);
   3433         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
   3434         return 0;
   3435     }
   3436     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
   3437     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
   3438     return (jint) ssl_session;
   3439 }
   3440 
   3441 /**
   3442  * Perform SSL renegotiation
   3443  */
   3444 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jint ssl_address)
   3445 {
   3446     SSL* ssl = to_SSL(env, ssl_address, true);
   3447     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
   3448     if (ssl == NULL) {
   3449         return;
   3450     }
   3451     int result = SSL_renegotiate(ssl);
   3452     if (result != 1) {
   3453         throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
   3454         return;
   3455     }
   3456     // first call asks client to perform renegotiation
   3457     int ret = SSL_do_handshake(ssl);
   3458     if (ret != 1) {
   3459         int sslError = SSL_get_error(ssl, ret);
   3460         throwSSLExceptionWithSslErrors(env, ssl, sslError,
   3461                                        "Problem with SSL_do_handshake after SSL_renegotiate");
   3462         return;
   3463     }
   3464     // if client agrees, set ssl state and perform renegotiation
   3465     ssl->state = SSL_ST_ACCEPT;
   3466     SSL_do_handshake(ssl);
   3467     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
   3468 }
   3469 
   3470 /**
   3471  * public static native byte[][] SSL_get_certificate(int ssl);
   3472  */
   3473 static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jint ssl_address)
   3474 {
   3475     SSL* ssl = to_SSL(env, ssl_address, true);
   3476     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
   3477     if (ssl == NULL) {
   3478         return NULL;
   3479     }
   3480     X509* certificate = SSL_get_certificate(ssl);
   3481     if (certificate == NULL) {
   3482         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   3483         return NULL;
   3484     }
   3485 
   3486     Unique_sk_X509 chain(sk_X509_new_null());
   3487     if (chain.get() == NULL) {
   3488         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
   3489         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
   3490         return NULL;
   3491     }
   3492     if (!sk_X509_push(chain.get(), certificate)) {
   3493         jniThrowOutOfMemoryError(env, "Unable to push local certificate");
   3494         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   3495         return NULL;
   3496     }
   3497     STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
   3498     for (int i=0; i<sk_X509_num(cert_chain); i++) {
   3499         if (!sk_X509_push(chain.get(), sk_X509_value(cert_chain, i))) {
   3500             jniThrowOutOfMemoryError(env, "Unable to push local certificate chain");
   3501             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   3502             return NULL;
   3503         }
   3504     }
   3505 
   3506     jobjectArray objectArray = getCertificateBytes(env, chain.get());
   3507     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray);
   3508     return objectArray;
   3509 }
   3510 
   3511 // Fills a byte[][] with the peer certificates in the chain.
   3512 static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jint ssl_address)
   3513 {
   3514     SSL* ssl = to_SSL(env, ssl_address, true);
   3515     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
   3516     if (ssl == NULL) {
   3517         return NULL;
   3518     }
   3519     STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
   3520     Unique_sk_X509 chain_copy(NULL);
   3521     if (ssl->server) {
   3522         X509* x509 = SSL_get_peer_certificate(ssl);
   3523         if (x509 == NULL) {
   3524             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
   3525             return NULL;
   3526         }
   3527         chain_copy.reset(sk_X509_dup(chain));
   3528         if (chain_copy.get() == NULL) {
   3529             jniThrowOutOfMemoryError(env, "Unable to allocate peer certificate chain");
   3530             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
   3531             return NULL;
   3532         }
   3533         if (!sk_X509_push(chain_copy.get(), x509)) {
   3534             jniThrowOutOfMemoryError(env, "Unable to push server's peer certificate");
   3535             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
   3536             return NULL;
   3537         }
   3538         chain = chain_copy.get();
   3539     }
   3540     jobjectArray objectArray = getCertificateBytes(env, chain);
   3541     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray);
   3542     return objectArray;
   3543 }
   3544 
   3545 /**
   3546  * Helper function which does the actual reading. The Java layer guarantees that
   3547  * at most one thread will enter this function at any given time.
   3548  *
   3549  * @param ssl non-null; the SSL context
   3550  * @param buf non-null; buffer to read into
   3551  * @param len length of the buffer, in bytes
   3552  * @param sslReturnCode original SSL return code
   3553  * @param sslErrorCode filled in with the SSL error code in case of error
   3554  * @return number of bytes read on success, -1 if the connection was
   3555  * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
   3556  */
   3557 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
   3558                    int* sslReturnCode, int* sslErrorCode, int timeout_millis) {
   3559     JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
   3560 
   3561     if (len == 0) {
   3562         // Don't bother doing anything in this case.
   3563         return 0;
   3564     }
   3565 
   3566     BIO* bio = SSL_get_rbio(ssl);
   3567 
   3568     AppData* appData = toAppData(ssl);
   3569     if (appData == NULL) {
   3570         return THROW_SSLEXCEPTION;
   3571     }
   3572 
   3573     while (appData->aliveAndKicking) {
   3574         errno = 0;
   3575 
   3576         if (MUTEX_LOCK(appData->mutex) == -1) {
   3577             return -1;
   3578         }
   3579 
   3580         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
   3581 
   3582         if (!appData->setCallbackState(env, shc, fdObject, NULL)) {
   3583             MUTEX_UNLOCK(appData->mutex);
   3584             return THROWN_EXCEPTION;
   3585         }
   3586         int result = SSL_read(ssl, buf, len);
   3587         appData->clearCallbackState();
   3588         // callbacks can happen if server requests renegotiation
   3589         if (env->ExceptionCheck()) {
   3590             SSL_clear(ssl);
   3591             JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
   3592             return THROWN_EXCEPTION;
   3593         }
   3594         int sslError = SSL_ERROR_NONE;
   3595         if (result <= 0) {
   3596             sslError = SSL_get_error(ssl, result);
   3597             freeOpenSslErrorState();
   3598         }
   3599         JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError);
   3600 #ifdef WITH_JNI_TRACE_DATA
   3601         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   3602             int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
   3603             JNI_TRACE("ssl=%p sslRead data: %d:\n%*s", ssl, n, n, buf+i);
   3604         }
   3605 #endif
   3606 
   3607         // If we have been successful in moving data around, check whether it
   3608         // might make sense to wake up other blocked threads, so they can give
   3609         // it a try, too.
   3610         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
   3611                 && appData->waitingThreads > 0) {
   3612             sslNotify(appData);
   3613         }
   3614 
   3615         // If we are blocked by the underlying socket, tell the world that
   3616         // there will be one more waiting thread now.
   3617         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   3618             appData->waitingThreads++;
   3619         }
   3620 
   3621         MUTEX_UNLOCK(appData->mutex);
   3622 
   3623         switch (sslError) {
   3624             // Successfully read at least one byte.
   3625             case SSL_ERROR_NONE: {
   3626                 return result;
   3627             }
   3628 
   3629             // Read zero bytes. End of stream reached.
   3630             case SSL_ERROR_ZERO_RETURN: {
   3631                 return -1;
   3632             }
   3633 
   3634             // Need to wait for availability of underlying layer, then retry.
   3635             case SSL_ERROR_WANT_READ:
   3636             case SSL_ERROR_WANT_WRITE: {
   3637                 int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
   3638                 if (selectResult == THROWN_EXCEPTION) {
   3639                     return THROWN_EXCEPTION;
   3640                 }
   3641                 if (selectResult == -1) {
   3642                     *sslReturnCode = -1;
   3643                     *sslErrorCode = sslError;
   3644                     return THROW_SSLEXCEPTION;
   3645                 }
   3646                 if (selectResult == 0) {
   3647                     return THROW_SOCKETTIMEOUTEXCEPTION;
   3648                 }
   3649 
   3650                 break;
   3651             }
   3652 
   3653             // A problem occurred during a system call, but this is not
   3654             // necessarily an error.
   3655             case SSL_ERROR_SYSCALL: {
   3656                 // Connection closed without proper shutdown. Tell caller we
   3657                 // have reached end-of-stream.
   3658                 if (result == 0) {
   3659                     return -1;
   3660                 }
   3661 
   3662                 // System call has been interrupted. Simply retry.
   3663                 if (errno == EINTR) {
   3664                     break;
   3665                 }
   3666 
   3667                 // Note that for all other system call errors we fall through
   3668                 // to the default case, which results in an Exception.
   3669             }
   3670 
   3671             // Everything else is basically an error.
   3672             default: {
   3673                 *sslReturnCode = result;
   3674                 *sslErrorCode = sslError;
   3675                 return THROW_SSLEXCEPTION;
   3676             }
   3677         }
   3678     }
   3679 
   3680     return -1;
   3681 }
   3682 
   3683 /**
   3684  * OpenSSL read function (2): read into buffer at offset n chunks.
   3685  * Returns 1 (success) or value <= 0 (failure).
   3686  */
   3687 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
   3688                                   jobject shc, jbyteArray b, jint offset, jint len,
   3689                                   jint timeout_millis)
   3690 {
   3691     SSL* ssl = to_SSL(env, ssl_address, true);
   3692     JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d timeout_millis=%d",
   3693               ssl, fdObject, shc, b, offset, len, timeout_millis);
   3694     if (ssl == NULL) {
   3695         return 0;
   3696     }
   3697     if (fdObject == NULL) {
   3698         jniThrowNullPointerException(env, "fd == null");
   3699         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
   3700         return 0;
   3701     }
   3702     if (shc == NULL) {
   3703         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3704         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
   3705         return 0;
   3706     }
   3707 
   3708     ScopedByteArrayRW bytes(env, b);
   3709     if (bytes.get() == NULL) {
   3710         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
   3711         return 0;
   3712     }
   3713     int returnCode = 0;
   3714     int sslErrorCode = SSL_ERROR_NONE;;
   3715 
   3716     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
   3717                       &returnCode, &sslErrorCode, timeout_millis);
   3718 
   3719     int result;
   3720     switch (ret) {
   3721         case THROW_SSLEXCEPTION:
   3722             // See sslRead() regarding improper failure to handle normal cases.
   3723             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
   3724             result = -1;
   3725             break;
   3726         case THROW_SOCKETTIMEOUTEXCEPTION:
   3727             throwSocketTimeoutException(env, "Read timed out");
   3728             result = -1;
   3729             break;
   3730         case THROWN_EXCEPTION:
   3731             // SocketException thrown by NetFd.isClosed
   3732             // or RuntimeException thrown by callback
   3733             result = -1;
   3734             break;
   3735         default:
   3736             result = ret;
   3737             break;
   3738     }
   3739 
   3740     JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
   3741     return result;
   3742 }
   3743 
   3744 /**
   3745  * Helper function which does the actual writing. The Java layer guarantees that
   3746  * at most one thread will enter this function at any given time.
   3747  *
   3748  * @param ssl non-null; the SSL context
   3749  * @param buf non-null; buffer to write
   3750  * @param len length of the buffer, in bytes
   3751  * @param sslReturnCode original SSL return code
   3752  * @param sslErrorCode filled in with the SSL error code in case of error
   3753  * @return number of bytes read on success, -1 if the connection was
   3754  * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
   3755  */
   3756 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
   3757                     int* sslReturnCode, int* sslErrorCode) {
   3758     JNI_TRACE("ssl=%p sslWrite buf=%p len=%d", ssl, buf, len);
   3759 
   3760     if (len == 0) {
   3761         // Don't bother doing anything in this case.
   3762         return 0;
   3763     }
   3764 
   3765     BIO* bio = SSL_get_wbio(ssl);
   3766 
   3767     AppData* appData = toAppData(ssl);
   3768     if (appData == NULL) {
   3769         return THROW_SSLEXCEPTION;
   3770     }
   3771 
   3772     int count = len;
   3773 
   3774     while (appData->aliveAndKicking && len > 0) {
   3775         errno = 0;
   3776 
   3777         if (MUTEX_LOCK(appData->mutex) == -1) {
   3778             return -1;
   3779         }
   3780 
   3781         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
   3782 
   3783         // ALOGD("Doing SSL_write() with %d bytes to go", len);
   3784         if (!appData->setCallbackState(env, shc, fdObject, NULL)) {
   3785             MUTEX_UNLOCK(appData->mutex);
   3786             return THROWN_EXCEPTION;
   3787         }
   3788         int result = SSL_write(ssl, buf, len);
   3789         appData->clearCallbackState();
   3790         // callbacks can happen if server requests renegotiation
   3791         if (env->ExceptionCheck()) {
   3792             SSL_clear(ssl);
   3793             JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
   3794             return THROWN_EXCEPTION;
   3795         }
   3796         int sslError = SSL_ERROR_NONE;
   3797         if (result <= 0) {
   3798             sslError = SSL_get_error(ssl, result);
   3799             freeOpenSslErrorState();
   3800         }
   3801         JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d", ssl, result, sslError);
   3802 #ifdef WITH_JNI_TRACE_DATA
   3803         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   3804             int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
   3805             JNI_TRACE("ssl=%p sslWrite data: %d:\n%*s", ssl, n, n, buf+i);
   3806         }
   3807 #endif
   3808 
   3809         // If we have been successful in moving data around, check whether it
   3810         // might make sense to wake up other blocked threads, so they can give
   3811         // it a try, too.
   3812         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
   3813                 && appData->waitingThreads > 0) {
   3814             sslNotify(appData);
   3815         }
   3816 
   3817         // If we are blocked by the underlying socket, tell the world that
   3818         // there will be one more waiting thread now.
   3819         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   3820             appData->waitingThreads++;
   3821         }
   3822 
   3823         MUTEX_UNLOCK(appData->mutex);
   3824 
   3825         switch (sslError) {
   3826             // Successfully wrote at least one byte.
   3827             case SSL_ERROR_NONE: {
   3828                 buf += result;
   3829                 len -= result;
   3830                 break;
   3831             }
   3832 
   3833             // Wrote zero bytes. End of stream reached.
   3834             case SSL_ERROR_ZERO_RETURN: {
   3835                 return -1;
   3836             }
   3837 
   3838             // Need to wait for availability of underlying layer, then retry.
   3839             // The concept of a write timeout doesn't really make sense, and
   3840             // it's also not standard Java behavior, so we wait forever here.
   3841             case SSL_ERROR_WANT_READ:
   3842             case SSL_ERROR_WANT_WRITE: {
   3843                 int selectResult = sslSelect(env, sslError, fdObject, appData, 0);
   3844                 if (selectResult == THROWN_EXCEPTION) {
   3845                     return THROWN_EXCEPTION;
   3846                 }
   3847                 if (selectResult == -1) {
   3848                     *sslReturnCode = -1;
   3849                     *sslErrorCode = sslError;
   3850                     return THROW_SSLEXCEPTION;
   3851                 }
   3852                 if (selectResult == 0) {
   3853                     return THROW_SOCKETTIMEOUTEXCEPTION;
   3854                 }
   3855 
   3856                 break;
   3857             }
   3858 
   3859             // A problem occurred during a system call, but this is not
   3860             // necessarily an error.
   3861             case SSL_ERROR_SYSCALL: {
   3862                 // Connection closed without proper shutdown. Tell caller we
   3863                 // have reached end-of-stream.
   3864                 if (result == 0) {
   3865                     return -1;
   3866                 }
   3867 
   3868                 // System call has been interrupted. Simply retry.
   3869                 if (errno == EINTR) {
   3870                     break;
   3871                 }
   3872 
   3873                 // Note that for all other system call errors we fall through
   3874                 // to the default case, which results in an Exception.
   3875             }
   3876 
   3877             // Everything else is basically an error.
   3878             default: {
   3879                 *sslReturnCode = result;
   3880                 *sslErrorCode = sslError;
   3881                 return THROW_SSLEXCEPTION;
   3882             }
   3883         }
   3884     }
   3885     JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count);
   3886 
   3887     return count;
   3888 }
   3889 
   3890 /**
   3891  * OpenSSL write function (2): write into buffer at offset n chunks.
   3892  */
   3893 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
   3894                                    jobject shc, jbyteArray b, jint offset, jint len)
   3895 {
   3896     SSL* ssl = to_SSL(env, ssl_address, true);
   3897     JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d",
   3898               ssl, fdObject, shc, b, offset, len);
   3899     if (ssl == NULL) {
   3900         return;
   3901     }
   3902     if (fdObject == NULL) {
   3903         jniThrowNullPointerException(env, "fd == null");
   3904         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
   3905         return;
   3906     }
   3907     if (shc == NULL) {
   3908         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3909         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
   3910         return;
   3911     }
   3912 
   3913     ScopedByteArrayRO bytes(env, b);
   3914     if (bytes.get() == NULL) {
   3915         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
   3916         return;
   3917     }
   3918     int returnCode = 0;
   3919     int sslErrorCode = SSL_ERROR_NONE;
   3920     int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
   3921                        len, &returnCode, &sslErrorCode);
   3922 
   3923     switch (ret) {
   3924         case THROW_SSLEXCEPTION:
   3925             // See sslWrite() regarding improper failure to handle normal cases.
   3926             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
   3927             break;
   3928         case THROW_SOCKETTIMEOUTEXCEPTION:
   3929             throwSocketTimeoutException(env, "Write timed out");
   3930             break;
   3931         case THROWN_EXCEPTION:
   3932             // SocketException thrown by NetFd.isClosed
   3933             break;
   3934         default:
   3935             break;
   3936     }
   3937 }
   3938 
   3939 /**
   3940  * Interrupt any pending IO before closing the socket.
   3941  */
   3942 static void NativeCrypto_SSL_interrupt(
   3943         JNIEnv* env, jclass, jint ssl_address) {
   3944     SSL* ssl = to_SSL(env, ssl_address, false);
   3945     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
   3946     if (ssl == NULL) {
   3947         return;
   3948     }
   3949 
   3950     /*
   3951      * Mark the connection as quasi-dead, then send something to the emergency
   3952      * file descriptor, so any blocking select() calls are woken up.
   3953      */
   3954     AppData* appData = toAppData(ssl);
   3955     if (appData != NULL) {
   3956         appData->aliveAndKicking = 0;
   3957 
   3958         // At most two threads can be waiting.
   3959         sslNotify(appData);
   3960         sslNotify(appData);
   3961     }
   3962 }
   3963 
   3964 /**
   3965  * OpenSSL close SSL socket function.
   3966  */
   3967 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jint ssl_address,
   3968                                       jobject fdObject, jobject shc) {
   3969     SSL* ssl = to_SSL(env, ssl_address, false);
   3970     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
   3971     if (ssl == NULL) {
   3972         return;
   3973     }
   3974     if (fdObject == NULL) {
   3975         jniThrowNullPointerException(env, "fd == null");
   3976         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
   3977         return;
   3978     }
   3979     if (shc == NULL) {
   3980         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3981         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
   3982         return;
   3983     }
   3984 
   3985     AppData* appData = toAppData(ssl);
   3986     if (appData != NULL) {
   3987         if (!appData->setCallbackState(env, shc, fdObject, NULL)) {
   3988             // SocketException thrown by NetFd.isClosed
   3989             SSL_clear(ssl);
   3990             freeOpenSslErrorState();
   3991             return;
   3992         }
   3993 
   3994         /*
   3995          * Try to make socket blocking again. OpenSSL literature recommends this.
   3996          */
   3997         int fd = SSL_get_fd(ssl);
   3998         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
   3999         if (fd != -1) {
   4000             setBlocking(fd, true);
   4001         }
   4002 
   4003         int ret = SSL_shutdown(ssl);
   4004         appData->clearCallbackState();
   4005         // callbacks can happen if server requests renegotiation
   4006         if (env->ExceptionCheck()) {
   4007             SSL_clear(ssl);
   4008             JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
   4009             return;
   4010         }
   4011         switch (ret) {
   4012             case 0:
   4013                 /*
   4014                  * Shutdown was not successful (yet), but there also
   4015                  * is no error. Since we can't know whether the remote
   4016                  * server is actually still there, and we don't want to
   4017                  * get stuck forever in a second SSL_shutdown() call, we
   4018                  * simply return. This is not security a problem as long
   4019                  * as we close the underlying socket, which we actually
   4020                  * do, because that's where we are just coming from.
   4021                  */
   4022                 break;
   4023             case 1:
   4024                 /*
   4025                  * Shutdown was successful. We can safely return. Hooray!
   4026                  */
   4027                 break;
   4028             default:
   4029                 /*
   4030                  * Everything else is a real error condition. We should
   4031                  * let the Java layer know about this by throwing an
   4032                  * exception.
   4033                  */
   4034                 int sslError = SSL_get_error(ssl, ret);
   4035                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
   4036                 break;
   4037         }
   4038     }
   4039 
   4040     SSL_clear(ssl);
   4041     freeOpenSslErrorState();
   4042 }
   4043 
   4044 /**
   4045  * public static native void SSL_free(int ssl);
   4046  */
   4047 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jint ssl_address)
   4048 {
   4049     SSL* ssl = to_SSL(env, ssl_address, true);
   4050     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
   4051     if (ssl == NULL) {
   4052         return;
   4053     }
   4054 
   4055     AppData* appData = toAppData(ssl);
   4056     SSL_set_app_data(ssl, NULL);
   4057     delete appData;
   4058     SSL_free(ssl);
   4059 }
   4060 
   4061 /**
   4062  * Gets and returns in a byte array the ID of the actual SSL session.
   4063  */
   4064 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
   4065                                                       jint ssl_session_address) {
   4066     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4067     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
   4068     if (ssl_session == NULL) {
   4069         return NULL;
   4070     }
   4071     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
   4072     if (result != NULL) {
   4073         jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
   4074         env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
   4075     }
   4076     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
   4077              ssl_session, result, ssl_session->session_id_length);
   4078     return result;
   4079 }
   4080 
   4081 /**
   4082  * Gets and returns in a long integer the creation's time of the
   4083  * actual SSL session.
   4084  */
   4085 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jint ssl_session_address) {
   4086     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4087     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
   4088     if (ssl_session == NULL) {
   4089         return 0;
   4090     }
   4091     // result must be jlong, not long or *1000 will overflow
   4092     jlong result = SSL_SESSION_get_time(ssl_session);
   4093     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
   4094     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
   4095     return result;
   4096 }
   4097 
   4098 /**
   4099  * Gets and returns in a string the version of the SSL protocol. If it
   4100  * returns the string "unknown" it means that no connection is established.
   4101  */
   4102 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jint ssl_session_address) {
   4103     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4104     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
   4105     if (ssl_session == NULL) {
   4106         return NULL;
   4107     }
   4108     const char* protocol = SSL_SESSION_get_version(ssl_session);
   4109     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
   4110     return env->NewStringUTF(protocol);
   4111 }
   4112 
   4113 /**
   4114  * Gets and returns in a string the cipher negotiated for the SSL session.
   4115  */
   4116 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jint ssl_session_address) {
   4117     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4118     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
   4119     if (ssl_session == NULL) {
   4120         return NULL;
   4121     }
   4122     const SSL_CIPHER* cipher = ssl_session->cipher;
   4123     const char* name = SSL_CIPHER_get_name(cipher);
   4124     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
   4125     return env->NewStringUTF(name);
   4126 }
   4127 
   4128 /**
   4129  * Gets and returns in a string the compression method negotiated for the SSL session.
   4130  */
   4131 static jstring NativeCrypto_SSL_SESSION_compress_meth(JNIEnv* env, jclass,
   4132                                                       jint ssl_ctx_address,
   4133                                                       jint ssl_session_address) {
   4134     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   4135     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4136     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth ssl_ctx=%p",
   4137               ssl_session, ssl_ctx);
   4138     if (ssl_ctx == NULL || ssl_session == NULL) {
   4139         return NULL;
   4140     }
   4141 
   4142     int compress_meth = ssl_session->compress_meth;
   4143     if (compress_meth == 0) {
   4144         const char* name = "NULL";
   4145         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
   4146         return env->NewStringUTF(name);
   4147     }
   4148 
   4149     int num_comp_methods = sk_SSL_COMP_num(ssl_ctx->comp_methods);
   4150     for (int i = 0; i < num_comp_methods; i++) {
   4151         SSL_COMP* comp = sk_SSL_COMP_value(ssl_ctx->comp_methods, i);
   4152         if (comp->id != compress_meth) {
   4153             continue;
   4154         }
   4155         const char* name = ((comp->method && comp->method->type == NID_zlib_compression)
   4156                             ? SN_zlib_compression
   4157                             : (comp->name ? comp->name : "UNKNOWN"));
   4158         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
   4159         return env->NewStringUTF(name);
   4160     }
   4161     throwSSLExceptionStr(env, "Unknown compression method");
   4162     return NULL;
   4163 }
   4164 
   4165 /**
   4166  * Frees the SSL session.
   4167  */
   4168 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jint ssl_session_address) {
   4169     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4170     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
   4171     if (ssl_session == NULL) {
   4172         return;
   4173     }
   4174     SSL_SESSION_free(ssl_session);
   4175 }
   4176 
   4177 
   4178 /**
   4179  * Serializes the native state of the session (ID, cipher, and keys but
   4180  * not certificates). Returns a byte[] containing the DER-encoded state.
   4181  * See apache mod_ssl.
   4182  */
   4183 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jint ssl_session_address) {
   4184     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4185     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
   4186     if (ssl_session == NULL) {
   4187         return NULL;
   4188     }
   4189 
   4190     // Compute the size of the DER data
   4191     int size = i2d_SSL_SESSION(ssl_session, NULL);
   4192     if (size == 0) {
   4193         JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => NULL", ssl_session);
   4194         return NULL;
   4195     }
   4196 
   4197     jbyteArray javaBytes = env->NewByteArray(size);
   4198     if (javaBytes != NULL) {
   4199         ScopedByteArrayRW bytes(env, javaBytes);
   4200         if (bytes.get() == NULL) {
   4201             JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => threw exception",
   4202                       ssl_session);
   4203             return NULL;
   4204         }
   4205         unsigned char* ucp = reinterpret_cast<unsigned char*>(bytes.get());
   4206         i2d_SSL_SESSION(ssl_session, &ucp);
   4207     }
   4208 
   4209     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => size=%d", ssl_session, size);
   4210     return javaBytes;
   4211 }
   4212 
   4213 /**
   4214  * Deserialize the session.
   4215  */
   4216 static jint NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
   4217     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
   4218 
   4219     ScopedByteArrayRO bytes(env, javaBytes);
   4220     if (bytes.get() == NULL) {
   4221         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
   4222         return 0;
   4223     }
   4224     const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
   4225     SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
   4226 
   4227     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
   4228     return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
   4229 }
   4230 
   4231 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
   4232 #define SSL_CALLBACKS "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto$SSLHandshakeCallbacks;"
   4233 static JNINativeMethod sNativeCryptoMethods[] = {
   4234     NATIVE_METHOD(NativeCrypto, clinit, "()V"),
   4235     NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
   4236     NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)I"),
   4237     NATIVE_METHOD(NativeCrypto, ENGINE_init, "(I)I"),
   4238     NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(I)I"),
   4239     NATIVE_METHOD(NativeCrypto, ENGINE_free, "(I)I"),
   4240     NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(ILjava/lang/String;)I"),
   4241     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)I"),
   4242     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)I"),
   4243     NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(I)I"),
   4244     NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(I)I"),
   4245     NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"),
   4246     NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(I)[B"),
   4247     NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)I"),
   4248     NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(I)[B"),
   4249     NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)I"),
   4250     NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)I"),
   4251     NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(I)[[B"),
   4252     NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(I)[[B"),
   4253     NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)I"),
   4254     NATIVE_METHOD(NativeCrypto, get_DSA_params, "(I)[[B"),
   4255     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(I)V"),
   4256     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(I)I"),
   4257     NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(I[BI)I"),
   4258     NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(I)I"),
   4259     NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)I"),
   4260     NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(I)I"),
   4261     NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(I)I"),
   4262     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(I[BII)V"),
   4263     NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)I"),
   4264     NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(I[BII)V"),
   4265     NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(I[BII)I"),
   4266     NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)I"),
   4267     NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(I[BII)V"),
   4268     NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(I[BIII)I"),
   4269     NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)I"),
   4270     NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(I[B[BZ)I"),
   4271     NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(I[BI[BI)I"),
   4272     NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(I[BI)I"),
   4273     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(I)V"),
   4274     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
   4275     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
   4276     NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()I"),
   4277     NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(I)V"),
   4278     NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(I[B)V"),
   4279     NATIVE_METHOD(NativeCrypto, SSL_new, "(I)I"),
   4280     NATIVE_METHOD(NativeCrypto, SSL_use_OpenSSL_PrivateKey, "(II)V"),
   4281     NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(I[B)V"),
   4282     NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(I[[B)V"),
   4283     NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(I)V"),
   4284     NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(I[[B)V"),
   4285     NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(I)J"),
   4286     NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(IJ)J"),
   4287     NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(IJ)J"),
   4288     NATIVE_METHOD(NativeCrypto, SSL_get_options, "(I)J"),
   4289     NATIVE_METHOD(NativeCrypto, SSL_set_options, "(IJ)J"),
   4290     NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(IJ)J"),
   4291     NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(I[Ljava/lang/String;)V"),
   4292     NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(II)V"),
   4293     NATIVE_METHOD(NativeCrypto, SSL_set_session, "(II)V"),
   4294     NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(IZ)V"),
   4295     NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(ILjava/lang/String;)V"),
   4296     NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(I)Ljava/lang/String;"),
   4297     NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B)I"),
   4298     NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(I)V"),
   4299     NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(I)[[B"),
   4300     NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(I)[[B"),
   4301     NATIVE_METHOD(NativeCrypto, SSL_read, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
   4302     NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BII)V"),
   4303     NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(I)V"),
   4304     NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(I" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
   4305     NATIVE_METHOD(NativeCrypto, SSL_free, "(I)V"),
   4306     NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(I)[B"),
   4307     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(I)J"),
   4308     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(I)Ljava/lang/String;"),
   4309     NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(I)Ljava/lang/String;"),
   4310     NATIVE_METHOD(NativeCrypto, SSL_SESSION_compress_meth, "(II)Ljava/lang/String;"),
   4311     NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(I)V"),
   4312     NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(I)[B"),
   4313     NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)I"),
   4314     NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(I)V"),
   4315     NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(I)V"),
   4316     NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(I)[B"),
   4317 };
   4318 
   4319 void register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
   4320     JNI_TRACE("register_org_apache_harmony_xnet_provider_jsse_NativeCrypto");
   4321     // Register org.apache.harmony.xnet.provider.jsse.NativeCrypto methods
   4322     jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/NativeCrypto", sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
   4323 }
   4324