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 
   2702     JNI_TRACE("ssl=%p SSL_use_OpenSSL_PrivateKey => ok", ssl);
   2703 }
   2704 
   2705 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass,
   2706                                             jint ssl_address, jbyteArray privatekey)
   2707 {
   2708     SSL* ssl = to_SSL(env, ssl_address, true);
   2709     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey privatekey=%p", ssl, privatekey);
   2710     if (ssl == NULL) {
   2711         return;
   2712     }
   2713 
   2714     ScopedByteArrayRO buf(env, privatekey);
   2715     if (buf.get() == NULL) {
   2716         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => threw exception", ssl);
   2717         return;
   2718     }
   2719     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2720     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, buf.size()));
   2721     if (pkcs8.get() == NULL) {
   2722         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2723         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   2724                                        "Error parsing private key from DER to PKCS8");
   2725         SSL_clear(ssl);
   2726         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from DER to PKCS8", ssl);
   2727         return;
   2728     }
   2729 
   2730     Unique_EVP_PKEY privatekeyevp(EVP_PKCS82PKEY(pkcs8.get()));
   2731     if (privatekeyevp.get() == NULL) {
   2732         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2733         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   2734                                        "Error creating private key from PKCS8");
   2735         SSL_clear(ssl);
   2736         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error from PKCS8 to key", ssl);
   2737         return;
   2738     }
   2739 
   2740     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey EVP_PKEY_type=%d",
   2741               ssl, EVP_PKEY_type(privatekeyevp.get()->type));
   2742     int ret = SSL_use_PrivateKey(ssl, privatekeyevp.get());
   2743     if (ret == 1) {
   2744         OWNERSHIP_TRANSFERRED(privatekeyevp);
   2745     } else {
   2746         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2747         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
   2748         SSL_clear(ssl);
   2749         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => error", ssl);
   2750         return;
   2751     }
   2752 
   2753     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_PrivateKey => ok", ssl);
   2754 }
   2755 
   2756 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
   2757                                              jint ssl_address, jobjectArray certificates)
   2758 {
   2759     SSL* ssl = to_SSL(env, ssl_address, true);
   2760     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates);
   2761     if (ssl == NULL) {
   2762         return;
   2763     }
   2764 
   2765     if (certificates == NULL) {
   2766         jniThrowNullPointerException(env, "certificates == null");
   2767         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
   2768         return;
   2769     }
   2770 
   2771     int length = env->GetArrayLength(certificates);
   2772     if (length == 0) {
   2773         jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
   2774         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
   2775         return;
   2776     }
   2777 
   2778     Unique_X509 certificatesX509[length];
   2779     for (int i = 0; i < length; i++) {
   2780         ScopedLocalRef<jbyteArray> certificate(env,
   2781                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i)));
   2782         if (certificate.get() == NULL) {
   2783             jniThrowNullPointerException(env, "certificates element == null");
   2784             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl);
   2785             return;
   2786         }
   2787 
   2788         ScopedByteArrayRO buf(env, certificate.get());
   2789         if (buf.get() == NULL) {
   2790             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl);
   2791             return;
   2792         }
   2793         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2794         certificatesX509[i].reset(d2i_X509(NULL, &tmp, buf.size()));
   2795 
   2796         if (certificatesX509[i].get() == NULL) {
   2797             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2798             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
   2799             SSL_clear(ssl);
   2800             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
   2801             return;
   2802         }
   2803     }
   2804 
   2805     int ret = SSL_use_certificate(ssl, certificatesX509[0].get());
   2806     if (ret == 1) {
   2807         OWNERSHIP_TRANSFERRED(certificatesX509[0]);
   2808     } else {
   2809         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2810         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
   2811         SSL_clear(ssl);
   2812         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
   2813         return;
   2814     }
   2815 
   2816     Unique_sk_X509 chain(sk_X509_new_null());
   2817     if (chain.get() == NULL) {
   2818         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
   2819         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
   2820         return;
   2821     }
   2822     for (int i = 1; i < length; i++) {
   2823         if (!sk_X509_push(chain.get(), certificatesX509[i].release())) {
   2824             jniThrowOutOfMemoryError(env, "Unable to push certificate");
   2825             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl);
   2826             return;
   2827         }
   2828     }
   2829     int chainResult = SSL_use_certificate_chain(ssl, chain.get());
   2830     if (chainResult == 0) {
   2831         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
   2832         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
   2833                   ssl);
   2834         return;
   2835     } else {
   2836         OWNERSHIP_TRANSFERRED(chain);
   2837     }
   2838 
   2839     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
   2840 }
   2841 
   2842 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jint ssl_address)
   2843 {
   2844     SSL* ssl = to_SSL(env, ssl_address, true);
   2845     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
   2846     if (ssl == NULL) {
   2847         return;
   2848     }
   2849     int ret = SSL_check_private_key(ssl);
   2850     if (ret != 1) {
   2851         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
   2852         SSL_clear(ssl);
   2853         JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
   2854         return;
   2855     }
   2856     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
   2857 }
   2858 
   2859 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
   2860                                                 jint ssl_address, jobjectArray principals)
   2861 {
   2862     SSL* ssl = to_SSL(env, ssl_address, true);
   2863     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
   2864     if (ssl == NULL) {
   2865         return;
   2866     }
   2867 
   2868     if (principals == NULL) {
   2869         jniThrowNullPointerException(env, "principals == null");
   2870         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
   2871         return;
   2872     }
   2873 
   2874     int length = env->GetArrayLength(principals);
   2875     if (length == 0) {
   2876         jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
   2877         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
   2878         return;
   2879     }
   2880 
   2881     Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
   2882     if (principalsStack.get() == NULL) {
   2883         jniThrowOutOfMemoryError(env, "Unable to allocate principal stack");
   2884         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
   2885         return;
   2886     }
   2887     for (int i = 0; i < length; i++) {
   2888         ScopedLocalRef<jbyteArray> principal(env,
   2889                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
   2890         if (principal.get() == NULL) {
   2891             jniThrowNullPointerException(env, "principals element == null");
   2892             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
   2893             return;
   2894         }
   2895 
   2896         ScopedByteArrayRO buf(env, principal.get());
   2897         if (buf.get() == NULL) {
   2898             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
   2899             return;
   2900         }
   2901         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   2902         Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
   2903 
   2904         if (principalX509Name.get() == NULL) {
   2905             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   2906             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
   2907             SSL_clear(ssl);
   2908             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
   2909                       ssl);
   2910             return;
   2911         }
   2912 
   2913         if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
   2914             jniThrowOutOfMemoryError(env, "Unable to push principal");
   2915             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
   2916             return;
   2917         }
   2918     }
   2919 
   2920     SSL_set_client_CA_list(ssl, principalsStack.release());
   2921     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
   2922 }
   2923 
   2924 /**
   2925  * public static native long SSL_get_mode(int ssl);
   2926  */
   2927 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jint ssl_address) {
   2928     SSL* ssl = to_SSL(env, ssl_address, true);
   2929     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
   2930     if (ssl == NULL) {
   2931       return 0;
   2932     }
   2933     long mode = SSL_get_mode(ssl);
   2934     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
   2935     return mode;
   2936 }
   2937 
   2938 /**
   2939  * public static native long SSL_set_mode(int ssl, long mode);
   2940  */
   2941 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
   2942         jint ssl_address, jlong mode) {
   2943     SSL* ssl = to_SSL(env, ssl_address, true);
   2944     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
   2945     if (ssl == NULL) {
   2946       return 0;
   2947     }
   2948     long result = SSL_set_mode(ssl, mode);
   2949     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
   2950     return result;
   2951 }
   2952 
   2953 /**
   2954  * public static native long SSL_clear_mode(int ssl, long mode);
   2955  */
   2956 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
   2957         jint ssl_address, jlong mode) {
   2958     SSL* ssl = to_SSL(env, ssl_address, true);
   2959     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
   2960     if (ssl == NULL) {
   2961       return 0;
   2962     }
   2963     long result = SSL_clear_mode(ssl, mode);
   2964     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
   2965     return result;
   2966 }
   2967 
   2968 /**
   2969  * public static native long SSL_get_options(int ssl);
   2970  */
   2971 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
   2972         jint ssl_address) {
   2973     SSL* ssl = to_SSL(env, ssl_address, true);
   2974     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
   2975     if (ssl == NULL) {
   2976       return 0;
   2977     }
   2978     long options = SSL_get_options(ssl);
   2979     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
   2980     return options;
   2981 }
   2982 
   2983 /**
   2984  * public static native long SSL_set_options(int ssl, long options);
   2985  */
   2986 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
   2987         jint ssl_address, jlong options) {
   2988     SSL* ssl = to_SSL(env, ssl_address, true);
   2989     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
   2990     if (ssl == NULL) {
   2991       return 0;
   2992     }
   2993     long result = SSL_set_options(ssl, options);
   2994     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
   2995     return result;
   2996 }
   2997 
   2998 /**
   2999  * public static native long SSL_clear_options(int ssl, long options);
   3000  */
   3001 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
   3002         jint ssl_address, jlong options) {
   3003     SSL* ssl = to_SSL(env, ssl_address, true);
   3004     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
   3005     if (ssl == NULL) {
   3006       return 0;
   3007     }
   3008     long result = SSL_clear_options(ssl, options);
   3009     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
   3010     return result;
   3011 }
   3012 
   3013 /**
   3014  * Sets the ciphers suites that are enabled in the SSL
   3015  */
   3016 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
   3017         jint ssl_address, jobjectArray cipherSuites)
   3018 {
   3019     SSL* ssl = to_SSL(env, ssl_address, true);
   3020     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
   3021     if (ssl == NULL) {
   3022         return;
   3023     }
   3024     if (cipherSuites == NULL) {
   3025         jniThrowNullPointerException(env, "cipherSuites == null");
   3026         return;
   3027     }
   3028 
   3029     Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
   3030     if (cipherstack.get() == NULL) {
   3031         jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
   3032         return;
   3033     }
   3034 
   3035     const SSL_METHOD* ssl_method = ssl->method;
   3036     int num_ciphers = ssl_method->num_ciphers();
   3037 
   3038     int length = env->GetArrayLength(cipherSuites);
   3039     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
   3040     for (int i = 0; i < length; i++) {
   3041         ScopedLocalRef<jstring> cipherSuite(env,
   3042                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
   3043         ScopedUtfChars c(env, cipherSuite.get());
   3044         if (c.c_str() == NULL) {
   3045             return;
   3046         }
   3047         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
   3048         bool found = false;
   3049         for (int j = 0; j < num_ciphers; j++) {
   3050             const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
   3051             if ((strcmp(c.c_str(), cipher->name) == 0)
   3052                     && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
   3053                 if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
   3054                     jniThrowOutOfMemoryError(env, "Unable to push cipher");
   3055                     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
   3056                     return;
   3057                 }
   3058                 found = true;
   3059             }
   3060         }
   3061         if (!found) {
   3062             jniThrowException(env, "java/lang/IllegalArgumentException",
   3063                               "Could not find cipher suite.");
   3064             return;
   3065         }
   3066     }
   3067 
   3068     int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
   3069     if (rc == 0) {
   3070         freeOpenSslErrorState();
   3071         jniThrowException(env, "java/lang/IllegalArgumentException",
   3072                           "Illegal cipher suite strings.");
   3073     } else {
   3074         OWNERSHIP_TRANSFERRED(cipherstack);
   3075     }
   3076 }
   3077 
   3078 /**
   3079  * Sets certificate expectations, especially for server to request client auth
   3080  */
   3081 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
   3082         jclass, jint ssl_address, jint mode)
   3083 {
   3084     SSL* ssl = to_SSL(env, ssl_address, true);
   3085     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
   3086     if (ssl == NULL) {
   3087       return;
   3088     }
   3089     SSL_set_verify(ssl, (int)mode, NULL);
   3090 }
   3091 
   3092 /**
   3093  * Sets the ciphers suites that are enabled in the SSL
   3094  */
   3095 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
   3096         jint ssl_address, jint ssl_session_address)
   3097 {
   3098     SSL* ssl = to_SSL(env, ssl_address, true);
   3099     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
   3100     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
   3101     if (ssl == NULL) {
   3102         return;
   3103     }
   3104 
   3105     int ret = SSL_set_session(ssl, ssl_session);
   3106     if (ret != 1) {
   3107         /*
   3108          * Translate the error, and throw if it turns out to be a real
   3109          * problem.
   3110          */
   3111         int sslErrorCode = SSL_get_error(ssl, ret);
   3112         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
   3113             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
   3114             SSL_clear(ssl);
   3115         }
   3116     }
   3117 }
   3118 
   3119 /**
   3120  * Sets the ciphers suites that are enabled in the SSL
   3121  */
   3122 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
   3123         jint ssl_address, jboolean creation_enabled)
   3124 {
   3125     SSL* ssl = to_SSL(env, ssl_address, true);
   3126     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
   3127               ssl, creation_enabled);
   3128     if (ssl == NULL) {
   3129         return;
   3130     }
   3131     SSL_set_session_creation_enabled(ssl, creation_enabled);
   3132 }
   3133 
   3134 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
   3135         jint ssl_address, jstring hostname)
   3136 {
   3137     SSL* ssl = to_SSL(env, ssl_address, true);
   3138     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
   3139               ssl, hostname);
   3140     if (ssl == NULL) {
   3141         return;
   3142     }
   3143 
   3144     ScopedUtfChars hostnameChars(env, hostname);
   3145     if (hostnameChars.c_str() == NULL) {
   3146         return;
   3147     }
   3148     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s",
   3149               ssl, hostnameChars.c_str());
   3150 
   3151     int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
   3152     if (ret != 1) {
   3153         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
   3154         SSL_clear(ssl);
   3155         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
   3156         return;
   3157     }
   3158     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
   3159 }
   3160 
   3161 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jint ssl_address) {
   3162     SSL* ssl = to_SSL(env, ssl_address, true);
   3163     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
   3164     if (ssl == NULL) {
   3165         return NULL;
   3166     }
   3167     const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
   3168     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
   3169     return env->NewStringUTF(servername);
   3170 }
   3171 
   3172 /**
   3173  * Callback for the client to select a protocol.
   3174  */
   3175 static int next_proto_select_callback(SSL* ssl, unsigned char **out, unsigned char *outlen,
   3176         const unsigned char *in, unsigned int inlen, void *)
   3177 {
   3178     JNI_TRACE("ssl=%p next_proto_select_callback", ssl);
   3179 
   3180     // Enable False Start on the client if the server understands NPN
   3181     // http://www.imperialviolet.org/2012/04/11/falsestart.html
   3182     SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
   3183 
   3184     AppData* appData = toAppData(ssl);
   3185     unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
   3186     size_t npnProtocolsLength = appData->npnProtocolsLength;
   3187 
   3188     int status = SSL_select_next_proto(out, outlen, in, inlen, npnProtocols, npnProtocolsLength);
   3189     switch (status) {
   3190       case OPENSSL_NPN_NEGOTIATED:
   3191         JNI_TRACE("ssl=%p next_proto_select_callback NPN negotiated", ssl);
   3192         break;
   3193       case OPENSSL_NPN_UNSUPPORTED:
   3194         JNI_TRACE("ssl=%p next_proto_select_callback NPN unsupported", ssl);
   3195         break;
   3196       case OPENSSL_NPN_NO_OVERLAP:
   3197         JNI_TRACE("ssl=%p next_proto_select_callback NPN no overlap", ssl);
   3198         break;
   3199     }
   3200     return SSL_TLSEXT_ERR_OK;
   3201 }
   3202 
   3203 /**
   3204  * Callback for the server to advertise available protocols.
   3205  */
   3206 static int next_protos_advertised_callback(SSL* ssl,
   3207         const unsigned char **out, unsigned int *outlen, void *)
   3208 {
   3209     JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl);
   3210     AppData* appData = toAppData(ssl);
   3211     unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
   3212     if (npnProtocols != NULL) {
   3213         *out = npnProtocols;
   3214         *outlen = appData->npnProtocolsLength;
   3215     }
   3216     return SSL_TLSEXT_ERR_OK;
   3217 }
   3218 
   3219 static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jint ssl_ctx_address)
   3220 {
   3221     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   3222     if (ssl_ctx == NULL) {
   3223         return;
   3224     }
   3225     SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL); // client
   3226     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server
   3227 }
   3228 
   3229 static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jint ssl_ctx_address)
   3230 {
   3231     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   3232     if (ssl_ctx == NULL) {
   3233         return;
   3234     }
   3235     SSL_CTX_set_next_proto_select_cb(ssl_ctx, NULL, NULL); // client
   3236     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, NULL, NULL); // server
   3237 }
   3238 
   3239 static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
   3240         jint ssl_address)
   3241 {
   3242     SSL* ssl = to_SSL(env, ssl_address, true);
   3243     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
   3244     if (ssl == NULL) {
   3245         return NULL;
   3246     }
   3247     const jbyte* npn;
   3248     unsigned npnLength;
   3249     SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
   3250     if (npnLength == 0) {
   3251         return NULL;
   3252     }
   3253     jbyteArray result = env->NewByteArray(npnLength);
   3254     if (result != NULL) {
   3255         env->SetByteArrayRegion(result, 0, npnLength, npn);
   3256     }
   3257     return result;
   3258 }
   3259 
   3260 /**
   3261  * Perform SSL handshake
   3262  */
   3263 static jint NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jint ssl_address,
   3264         jobject fdObject, jobject shc, jint timeout_millis, jboolean client_mode,
   3265         jbyteArray npnProtocols)
   3266 {
   3267     SSL* ssl = to_SSL(env, ssl_address, true);
   3268     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p",
   3269               ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols);
   3270     if (ssl == NULL) {
   3271       return 0;
   3272     }
   3273     if (fdObject == NULL) {
   3274         jniThrowNullPointerException(env, "fd == null");
   3275         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl);
   3276         return 0;
   3277     }
   3278     if (shc == NULL) {
   3279         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3280         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl);
   3281         return 0;
   3282     }
   3283 
   3284     NetFd fd(env, fdObject);
   3285     if (fd.isClosed()) {
   3286         // SocketException thrown by NetFd.isClosed
   3287         SSL_clear(ssl);
   3288         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
   3289         return 0;
   3290     }
   3291 
   3292     int ret = SSL_set_fd(ssl, fd.get());
   3293     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
   3294 
   3295     if (ret != 1) {
   3296         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   3297                                        "Error setting the file descriptor");
   3298         SSL_clear(ssl);
   3299         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
   3300         return 0;
   3301     }
   3302 
   3303     /*
   3304      * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
   3305      * forever and we can use select() to find out if the socket is ready.
   3306      */
   3307     if (!setBlocking(fd.get(), false)) {
   3308         throwSSLExceptionStr(env, "Unable to make socket non blocking");
   3309         SSL_clear(ssl);
   3310         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
   3311         return 0;
   3312     }
   3313 
   3314     /*
   3315      * Create our special application data.
   3316      */
   3317     AppData* appData = AppData::create();
   3318     if (appData == NULL) {
   3319         throwSSLExceptionStr(env, "Unable to create application data");
   3320         SSL_clear(ssl);
   3321         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
   3322         return 0;
   3323     }
   3324 
   3325     SSL_set_app_data(ssl, reinterpret_cast<char*>(appData));
   3326     JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData);
   3327 
   3328     if (client_mode) {
   3329         SSL_set_connect_state(ssl);
   3330     } else {
   3331         SSL_set_accept_state(ssl);
   3332     }
   3333 
   3334     ret = 0;
   3335     while (appData->aliveAndKicking) {
   3336         errno = 0;
   3337 
   3338         if (!appData->setCallbackState(env, shc, fdObject, npnProtocols)) {
   3339             // SocketException thrown by NetFd.isClosed
   3340             SSL_clear(ssl);
   3341             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
   3342             return 0;
   3343         }
   3344         ret = SSL_do_handshake(ssl);
   3345         appData->clearCallbackState();
   3346         // cert_verify_callback threw exception
   3347         if (env->ExceptionCheck()) {
   3348             SSL_clear(ssl);
   3349             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
   3350             return 0;
   3351         }
   3352         // success case
   3353         if (ret == 1) {
   3354             break;
   3355         }
   3356         // retry case
   3357         if (errno == EINTR) {
   3358             continue;
   3359         }
   3360         // error case
   3361         int sslError = SSL_get_error(ssl, ret);
   3362         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d",
   3363                   ssl, ret, errno, sslError, timeout_millis);
   3364 
   3365         /*
   3366          * If SSL_do_handshake doesn't succeed due to the socket being
   3367          * either unreadable or unwritable, we use sslSelect to
   3368          * wait for it to become ready. If that doesn't happen
   3369          * before the specified timeout or an error occurs, we
   3370          * cancel the handshake. Otherwise we try the SSL_connect
   3371          * again.
   3372          */
   3373         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   3374             appData->waitingThreads++;
   3375             int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
   3376 
   3377             if (selectResult == THROWN_EXCEPTION) {
   3378                 // SocketException thrown by NetFd.isClosed
   3379                 SSL_clear(ssl);
   3380                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
   3381                 return 0;
   3382             }
   3383             if (selectResult == -1) {
   3384                 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error");
   3385                 SSL_clear(ssl);
   3386                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
   3387                 return 0;
   3388             }
   3389             if (selectResult == 0) {
   3390                 throwSocketTimeoutException(env, "SSL handshake timed out");
   3391                 SSL_clear(ssl);
   3392                 freeOpenSslErrorState();
   3393                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
   3394                 return 0;
   3395             }
   3396         } else {
   3397             // ALOGE("Unknown error %d during handshake", error);
   3398             break;
   3399         }
   3400     }
   3401 
   3402     // clean error. See SSL_do_handshake(3SSL) man page.
   3403     if (ret == 0) {
   3404         /*
   3405          * The other side closed the socket before the handshake could be
   3406          * completed, but everything is within the bounds of the TLS protocol.
   3407          * We still might want to find out the real reason of the failure.
   3408          */
   3409         int sslError = SSL_get_error(ssl, ret);
   3410         if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) {
   3411             throwSSLExceptionStr(env, "Connection closed by peer");
   3412         } else {
   3413             throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated");
   3414         }
   3415         SSL_clear(ssl);
   3416         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
   3417         return 0;
   3418     }
   3419 
   3420     // unclean error. See SSL_do_handshake(3SSL) man page.
   3421     if (ret < 0) {
   3422         /*
   3423          * Translate the error and throw exception. We are sure it is an error
   3424          * at this point.
   3425          */
   3426         int sslError = SSL_get_error(ssl, ret);
   3427         throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted");
   3428         SSL_clear(ssl);
   3429         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
   3430         return 0;
   3431     }
   3432     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
   3433     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
   3434     return (jint) ssl_session;
   3435 }
   3436 
   3437 /**
   3438  * Perform SSL renegotiation
   3439  */
   3440 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jint ssl_address)
   3441 {
   3442     SSL* ssl = to_SSL(env, ssl_address, true);
   3443     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
   3444     if (ssl == NULL) {
   3445         return;
   3446     }
   3447     int result = SSL_renegotiate(ssl);
   3448     if (result != 1) {
   3449         throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
   3450         return;
   3451     }
   3452     // first call asks client to perform renegotiation
   3453     int ret = SSL_do_handshake(ssl);
   3454     if (ret != 1) {
   3455         int sslError = SSL_get_error(ssl, ret);
   3456         throwSSLExceptionWithSslErrors(env, ssl, sslError,
   3457                                        "Problem with SSL_do_handshake after SSL_renegotiate");
   3458         return;
   3459     }
   3460     // if client agrees, set ssl state and perform renegotiation
   3461     ssl->state = SSL_ST_ACCEPT;
   3462     SSL_do_handshake(ssl);
   3463     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
   3464 }
   3465 
   3466 /**
   3467  * public static native byte[][] SSL_get_certificate(int ssl);
   3468  */
   3469 static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jint ssl_address)
   3470 {
   3471     SSL* ssl = to_SSL(env, ssl_address, true);
   3472     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
   3473     if (ssl == NULL) {
   3474         return NULL;
   3475     }
   3476     X509* certificate = SSL_get_certificate(ssl);
   3477     if (certificate == NULL) {
   3478         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   3479         return NULL;
   3480     }
   3481 
   3482     Unique_sk_X509 chain(sk_X509_new_null());
   3483     if (chain.get() == NULL) {
   3484         jniThrowOutOfMemoryError(env, "Unable to allocate local certificate chain");
   3485         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
   3486         return NULL;
   3487     }
   3488     if (!sk_X509_push(chain.get(), certificate)) {
   3489         jniThrowOutOfMemoryError(env, "Unable to push local certificate");
   3490         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   3491         return NULL;
   3492     }
   3493     STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
   3494     for (int i=0; i<sk_X509_num(cert_chain); i++) {
   3495         if (!sk_X509_push(chain.get(), sk_X509_value(cert_chain, i))) {
   3496             jniThrowOutOfMemoryError(env, "Unable to push local certificate chain");
   3497             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   3498             return NULL;
   3499         }
   3500     }
   3501 
   3502     jobjectArray objectArray = getCertificateBytes(env, chain.get());
   3503     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray);
   3504     return objectArray;
   3505 }
   3506 
   3507 // Fills a byte[][] with the peer certificates in the chain.
   3508 static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jint ssl_address)
   3509 {
   3510     SSL* ssl = to_SSL(env, ssl_address, true);
   3511     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
   3512     if (ssl == NULL) {
   3513         return NULL;
   3514     }
   3515     STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
   3516     Unique_sk_X509 chain_copy(NULL);
   3517     if (ssl->server) {
   3518         X509* x509 = SSL_get_peer_certificate(ssl);
   3519         if (x509 == NULL) {
   3520             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
   3521             return NULL;
   3522         }
   3523         chain_copy.reset(sk_X509_dup(chain));
   3524         if (chain_copy.get() == NULL) {
   3525             jniThrowOutOfMemoryError(env, "Unable to allocate peer certificate chain");
   3526             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
   3527             return NULL;
   3528         }
   3529         if (!sk_X509_push(chain_copy.get(), x509)) {
   3530             jniThrowOutOfMemoryError(env, "Unable to push server's peer certificate");
   3531             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
   3532             return NULL;
   3533         }
   3534         chain = chain_copy.get();
   3535     }
   3536     jobjectArray objectArray = getCertificateBytes(env, chain);
   3537     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray);
   3538     return objectArray;
   3539 }
   3540 
   3541 /**
   3542  * Helper function which does the actual reading. The Java layer guarantees that
   3543  * at most one thread will enter this function at any given time.
   3544  *
   3545  * @param ssl non-null; the SSL context
   3546  * @param buf non-null; buffer to read into
   3547  * @param len length of the buffer, in bytes
   3548  * @param sslReturnCode original SSL return code
   3549  * @param sslErrorCode filled in with the SSL error code in case of error
   3550  * @return number of bytes read on success, -1 if the connection was
   3551  * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
   3552  */
   3553 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
   3554                    int* sslReturnCode, int* sslErrorCode, int timeout_millis) {
   3555     JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
   3556 
   3557     if (len == 0) {
   3558         // Don't bother doing anything in this case.
   3559         return 0;
   3560     }
   3561 
   3562     BIO* bio = SSL_get_rbio(ssl);
   3563 
   3564     AppData* appData = toAppData(ssl);
   3565     if (appData == NULL) {
   3566         return THROW_SSLEXCEPTION;
   3567     }
   3568 
   3569     while (appData->aliveAndKicking) {
   3570         errno = 0;
   3571 
   3572         if (MUTEX_LOCK(appData->mutex) == -1) {
   3573             return -1;
   3574         }
   3575 
   3576         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
   3577 
   3578         if (!appData->setCallbackState(env, shc, fdObject, NULL)) {
   3579             MUTEX_UNLOCK(appData->mutex);
   3580             return THROWN_EXCEPTION;
   3581         }
   3582         int result = SSL_read(ssl, buf, len);
   3583         appData->clearCallbackState();
   3584         // callbacks can happen if server requests renegotiation
   3585         if (env->ExceptionCheck()) {
   3586             SSL_clear(ssl);
   3587             JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
   3588             return THROWN_EXCEPTION;
   3589         }
   3590         int sslError = SSL_ERROR_NONE;
   3591         if (result <= 0) {
   3592             sslError = SSL_get_error(ssl, result);
   3593             freeOpenSslErrorState();
   3594         }
   3595         JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError);
   3596 #ifdef WITH_JNI_TRACE_DATA
   3597         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   3598             int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
   3599             JNI_TRACE("ssl=%p sslRead data: %d:\n%*s", ssl, n, n, buf+i);
   3600         }
   3601 #endif
   3602 
   3603         // If we have been successful in moving data around, check whether it
   3604         // might make sense to wake up other blocked threads, so they can give
   3605         // it a try, too.
   3606         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
   3607                 && appData->waitingThreads > 0) {
   3608             sslNotify(appData);
   3609         }
   3610 
   3611         // If we are blocked by the underlying socket, tell the world that
   3612         // there will be one more waiting thread now.
   3613         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   3614             appData->waitingThreads++;
   3615         }
   3616 
   3617         MUTEX_UNLOCK(appData->mutex);
   3618 
   3619         switch (sslError) {
   3620             // Successfully read at least one byte.
   3621             case SSL_ERROR_NONE: {
   3622                 return result;
   3623             }
   3624 
   3625             // Read zero bytes. End of stream reached.
   3626             case SSL_ERROR_ZERO_RETURN: {
   3627                 return -1;
   3628             }
   3629 
   3630             // Need to wait for availability of underlying layer, then retry.
   3631             case SSL_ERROR_WANT_READ:
   3632             case SSL_ERROR_WANT_WRITE: {
   3633                 int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis);
   3634                 if (selectResult == THROWN_EXCEPTION) {
   3635                     return THROWN_EXCEPTION;
   3636                 }
   3637                 if (selectResult == -1) {
   3638                     *sslReturnCode = -1;
   3639                     *sslErrorCode = sslError;
   3640                     return THROW_SSLEXCEPTION;
   3641                 }
   3642                 if (selectResult == 0) {
   3643                     return THROW_SOCKETTIMEOUTEXCEPTION;
   3644                 }
   3645 
   3646                 break;
   3647             }
   3648 
   3649             // A problem occurred during a system call, but this is not
   3650             // necessarily an error.
   3651             case SSL_ERROR_SYSCALL: {
   3652                 // Connection closed without proper shutdown. Tell caller we
   3653                 // have reached end-of-stream.
   3654                 if (result == 0) {
   3655                     return -1;
   3656                 }
   3657 
   3658                 // System call has been interrupted. Simply retry.
   3659                 if (errno == EINTR) {
   3660                     break;
   3661                 }
   3662 
   3663                 // Note that for all other system call errors we fall through
   3664                 // to the default case, which results in an Exception.
   3665             }
   3666 
   3667             // Everything else is basically an error.
   3668             default: {
   3669                 *sslReturnCode = result;
   3670                 *sslErrorCode = sslError;
   3671                 return THROW_SSLEXCEPTION;
   3672             }
   3673         }
   3674     }
   3675 
   3676     return -1;
   3677 }
   3678 
   3679 /**
   3680  * OpenSSL read function (2): read into buffer at offset n chunks.
   3681  * Returns 1 (success) or value <= 0 (failure).
   3682  */
   3683 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
   3684                                   jobject shc, jbyteArray b, jint offset, jint len,
   3685                                   jint timeout_millis)
   3686 {
   3687     SSL* ssl = to_SSL(env, ssl_address, true);
   3688     JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d timeout_millis=%d",
   3689               ssl, fdObject, shc, b, offset, len, timeout_millis);
   3690     if (ssl == NULL) {
   3691         return 0;
   3692     }
   3693     if (fdObject == NULL) {
   3694         jniThrowNullPointerException(env, "fd == null");
   3695         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
   3696         return 0;
   3697     }
   3698     if (shc == NULL) {
   3699         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3700         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
   3701         return 0;
   3702     }
   3703 
   3704     ScopedByteArrayRW bytes(env, b);
   3705     if (bytes.get() == NULL) {
   3706         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
   3707         return 0;
   3708     }
   3709     int returnCode = 0;
   3710     int sslErrorCode = SSL_ERROR_NONE;;
   3711 
   3712     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
   3713                       &returnCode, &sslErrorCode, timeout_millis);
   3714 
   3715     int result;
   3716     switch (ret) {
   3717         case THROW_SSLEXCEPTION:
   3718             // See sslRead() regarding improper failure to handle normal cases.
   3719             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error");
   3720             result = -1;
   3721             break;
   3722         case THROW_SOCKETTIMEOUTEXCEPTION:
   3723             throwSocketTimeoutException(env, "Read timed out");
   3724             result = -1;
   3725             break;
   3726         case THROWN_EXCEPTION:
   3727             // SocketException thrown by NetFd.isClosed
   3728             // or RuntimeException thrown by callback
   3729             result = -1;
   3730             break;
   3731         default:
   3732             result = ret;
   3733             break;
   3734     }
   3735 
   3736     JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
   3737     return result;
   3738 }
   3739 
   3740 /**
   3741  * Helper function which does the actual writing. The Java layer guarantees that
   3742  * at most one thread will enter this function at any given time.
   3743  *
   3744  * @param ssl non-null; the SSL context
   3745  * @param buf non-null; buffer to write
   3746  * @param len length of the buffer, in bytes
   3747  * @param sslReturnCode original SSL return code
   3748  * @param sslErrorCode filled in with the SSL error code in case of error
   3749  * @return number of bytes read on success, -1 if the connection was
   3750  * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown.
   3751  */
   3752 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
   3753                     int* sslReturnCode, int* sslErrorCode) {
   3754     JNI_TRACE("ssl=%p sslWrite buf=%p len=%d", ssl, buf, len);
   3755 
   3756     if (len == 0) {
   3757         // Don't bother doing anything in this case.
   3758         return 0;
   3759     }
   3760 
   3761     BIO* bio = SSL_get_wbio(ssl);
   3762 
   3763     AppData* appData = toAppData(ssl);
   3764     if (appData == NULL) {
   3765         return THROW_SSLEXCEPTION;
   3766     }
   3767 
   3768     int count = len;
   3769 
   3770     while (appData->aliveAndKicking && len > 0) {
   3771         errno = 0;
   3772 
   3773         if (MUTEX_LOCK(appData->mutex) == -1) {
   3774             return -1;
   3775         }
   3776 
   3777         unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio);
   3778 
   3779         // ALOGD("Doing SSL_write() with %d bytes to go", len);
   3780         if (!appData->setCallbackState(env, shc, fdObject, NULL)) {
   3781             MUTEX_UNLOCK(appData->mutex);
   3782             return THROWN_EXCEPTION;
   3783         }
   3784         int result = SSL_write(ssl, buf, len);
   3785         appData->clearCallbackState();
   3786         // callbacks can happen if server requests renegotiation
   3787         if (env->ExceptionCheck()) {
   3788             SSL_clear(ssl);
   3789             JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
   3790             return THROWN_EXCEPTION;
   3791         }
   3792         int sslError = SSL_ERROR_NONE;
   3793         if (result <= 0) {
   3794             sslError = SSL_get_error(ssl, result);
   3795             freeOpenSslErrorState();
   3796         }
   3797         JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d", ssl, result, sslError);
   3798 #ifdef WITH_JNI_TRACE_DATA
   3799         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   3800             int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE);
   3801             JNI_TRACE("ssl=%p sslWrite data: %d:\n%*s", ssl, n, n, buf+i);
   3802         }
   3803 #endif
   3804 
   3805         // If we have been successful in moving data around, check whether it
   3806         // might make sense to wake up other blocked threads, so they can give
   3807         // it a try, too.
   3808         if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved
   3809                 && appData->waitingThreads > 0) {
   3810             sslNotify(appData);
   3811         }
   3812 
   3813         // If we are blocked by the underlying socket, tell the world that
   3814         // there will be one more waiting thread now.
   3815         if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) {
   3816             appData->waitingThreads++;
   3817         }
   3818 
   3819         MUTEX_UNLOCK(appData->mutex);
   3820 
   3821         switch (sslError) {
   3822             // Successfully wrote at least one byte.
   3823             case SSL_ERROR_NONE: {
   3824                 buf += result;
   3825                 len -= result;
   3826                 break;
   3827             }
   3828 
   3829             // Wrote zero bytes. End of stream reached.
   3830             case SSL_ERROR_ZERO_RETURN: {
   3831                 return -1;
   3832             }
   3833 
   3834             // Need to wait for availability of underlying layer, then retry.
   3835             // The concept of a write timeout doesn't really make sense, and
   3836             // it's also not standard Java behavior, so we wait forever here.
   3837             case SSL_ERROR_WANT_READ:
   3838             case SSL_ERROR_WANT_WRITE: {
   3839                 int selectResult = sslSelect(env, sslError, fdObject, appData, 0);
   3840                 if (selectResult == THROWN_EXCEPTION) {
   3841                     return THROWN_EXCEPTION;
   3842                 }
   3843                 if (selectResult == -1) {
   3844                     *sslReturnCode = -1;
   3845                     *sslErrorCode = sslError;
   3846                     return THROW_SSLEXCEPTION;
   3847                 }
   3848                 if (selectResult == 0) {
   3849                     return THROW_SOCKETTIMEOUTEXCEPTION;
   3850                 }
   3851 
   3852                 break;
   3853             }
   3854 
   3855             // A problem occurred during a system call, but this is not
   3856             // necessarily an error.
   3857             case SSL_ERROR_SYSCALL: {
   3858                 // Connection closed without proper shutdown. Tell caller we
   3859                 // have reached end-of-stream.
   3860                 if (result == 0) {
   3861                     return -1;
   3862                 }
   3863 
   3864                 // System call has been interrupted. Simply retry.
   3865                 if (errno == EINTR) {
   3866                     break;
   3867                 }
   3868 
   3869                 // Note that for all other system call errors we fall through
   3870                 // to the default case, which results in an Exception.
   3871             }
   3872 
   3873             // Everything else is basically an error.
   3874             default: {
   3875                 *sslReturnCode = result;
   3876                 *sslErrorCode = sslError;
   3877                 return THROW_SSLEXCEPTION;
   3878             }
   3879         }
   3880     }
   3881     JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count);
   3882 
   3883     return count;
   3884 }
   3885 
   3886 /**
   3887  * OpenSSL write function (2): write into buffer at offset n chunks.
   3888  */
   3889 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jint ssl_address, jobject fdObject,
   3890                                    jobject shc, jbyteArray b, jint offset, jint len)
   3891 {
   3892     SSL* ssl = to_SSL(env, ssl_address, true);
   3893     JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d",
   3894               ssl, fdObject, shc, b, offset, len);
   3895     if (ssl == NULL) {
   3896         return;
   3897     }
   3898     if (fdObject == NULL) {
   3899         jniThrowNullPointerException(env, "fd == null");
   3900         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
   3901         return;
   3902     }
   3903     if (shc == NULL) {
   3904         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3905         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
   3906         return;
   3907     }
   3908 
   3909     ScopedByteArrayRO bytes(env, b);
   3910     if (bytes.get() == NULL) {
   3911         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
   3912         return;
   3913     }
   3914     int returnCode = 0;
   3915     int sslErrorCode = SSL_ERROR_NONE;
   3916     int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
   3917                        len, &returnCode, &sslErrorCode);
   3918 
   3919     switch (ret) {
   3920         case THROW_SSLEXCEPTION:
   3921             // See sslWrite() regarding improper failure to handle normal cases.
   3922             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error");
   3923             break;
   3924         case THROW_SOCKETTIMEOUTEXCEPTION:
   3925             throwSocketTimeoutException(env, "Write timed out");
   3926             break;
   3927         case THROWN_EXCEPTION:
   3928             // SocketException thrown by NetFd.isClosed
   3929             break;
   3930         default:
   3931             break;
   3932     }
   3933 }
   3934 
   3935 /**
   3936  * Interrupt any pending IO before closing the socket.
   3937  */
   3938 static void NativeCrypto_SSL_interrupt(
   3939         JNIEnv* env, jclass, jint ssl_address) {
   3940     SSL* ssl = to_SSL(env, ssl_address, false);
   3941     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
   3942     if (ssl == NULL) {
   3943         return;
   3944     }
   3945 
   3946     /*
   3947      * Mark the connection as quasi-dead, then send something to the emergency
   3948      * file descriptor, so any blocking select() calls are woken up.
   3949      */
   3950     AppData* appData = toAppData(ssl);
   3951     if (appData != NULL) {
   3952         appData->aliveAndKicking = 0;
   3953 
   3954         // At most two threads can be waiting.
   3955         sslNotify(appData);
   3956         sslNotify(appData);
   3957     }
   3958 }
   3959 
   3960 /**
   3961  * OpenSSL close SSL socket function.
   3962  */
   3963 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jint ssl_address,
   3964                                       jobject fdObject, jobject shc) {
   3965     SSL* ssl = to_SSL(env, ssl_address, false);
   3966     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
   3967     if (ssl == NULL) {
   3968         return;
   3969     }
   3970     if (fdObject == NULL) {
   3971         jniThrowNullPointerException(env, "fd == null");
   3972         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
   3973         return;
   3974     }
   3975     if (shc == NULL) {
   3976         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   3977         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
   3978         return;
   3979     }
   3980 
   3981     AppData* appData = toAppData(ssl);
   3982     if (appData != NULL) {
   3983         if (!appData->setCallbackState(env, shc, fdObject, NULL)) {
   3984             // SocketException thrown by NetFd.isClosed
   3985             SSL_clear(ssl);
   3986             freeOpenSslErrorState();
   3987             return;
   3988         }
   3989 
   3990         /*
   3991          * Try to make socket blocking again. OpenSSL literature recommends this.
   3992          */
   3993         int fd = SSL_get_fd(ssl);
   3994         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
   3995         if (fd != -1) {
   3996             setBlocking(fd, true);
   3997         }
   3998 
   3999         int ret = SSL_shutdown(ssl);
   4000         appData->clearCallbackState();
   4001         // callbacks can happen if server requests renegotiation
   4002         if (env->ExceptionCheck()) {
   4003             SSL_clear(ssl);
   4004             JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
   4005             return;
   4006         }
   4007         switch (ret) {
   4008             case 0:
   4009                 /*
   4010                  * Shutdown was not successful (yet), but there also
   4011                  * is no error. Since we can't know whether the remote
   4012                  * server is actually still there, and we don't want to
   4013                  * get stuck forever in a second SSL_shutdown() call, we
   4014                  * simply return. This is not security a problem as long
   4015                  * as we close the underlying socket, which we actually
   4016                  * do, because that's where we are just coming from.
   4017                  */
   4018                 break;
   4019             case 1:
   4020                 /*
   4021                  * Shutdown was successful. We can safely return. Hooray!
   4022                  */
   4023                 break;
   4024             default:
   4025                 /*
   4026                  * Everything else is a real error condition. We should
   4027                  * let the Java layer know about this by throwing an
   4028                  * exception.
   4029                  */
   4030                 int sslError = SSL_get_error(ssl, ret);
   4031                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
   4032                 break;
   4033         }
   4034     }
   4035 
   4036     SSL_clear(ssl);
   4037     freeOpenSslErrorState();
   4038 }
   4039 
   4040 /**
   4041  * public static native void SSL_free(int ssl);
   4042  */
   4043 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jint ssl_address)
   4044 {
   4045     SSL* ssl = to_SSL(env, ssl_address, true);
   4046     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
   4047     if (ssl == NULL) {
   4048         return;
   4049     }
   4050 
   4051     AppData* appData = toAppData(ssl);
   4052     SSL_set_app_data(ssl, NULL);
   4053     delete appData;
   4054     SSL_free(ssl);
   4055 }
   4056 
   4057 /**
   4058  * Gets and returns in a byte array the ID of the actual SSL session.
   4059  */
   4060 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
   4061                                                       jint ssl_session_address) {
   4062     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4063     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
   4064     if (ssl_session == NULL) {
   4065         return NULL;
   4066     }
   4067     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
   4068     if (result != NULL) {
   4069         jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
   4070         env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
   4071     }
   4072     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
   4073              ssl_session, result, ssl_session->session_id_length);
   4074     return result;
   4075 }
   4076 
   4077 /**
   4078  * Gets and returns in a long integer the creation's time of the
   4079  * actual SSL session.
   4080  */
   4081 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jint ssl_session_address) {
   4082     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4083     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
   4084     if (ssl_session == NULL) {
   4085         return 0;
   4086     }
   4087     // result must be jlong, not long or *1000 will overflow
   4088     jlong result = SSL_SESSION_get_time(ssl_session);
   4089     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
   4090     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
   4091     return result;
   4092 }
   4093 
   4094 /**
   4095  * Gets and returns in a string the version of the SSL protocol. If it
   4096  * returns the string "unknown" it means that no connection is established.
   4097  */
   4098 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jint ssl_session_address) {
   4099     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4100     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
   4101     if (ssl_session == NULL) {
   4102         return NULL;
   4103     }
   4104     const char* protocol = SSL_SESSION_get_version(ssl_session);
   4105     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
   4106     return env->NewStringUTF(protocol);
   4107 }
   4108 
   4109 /**
   4110  * Gets and returns in a string the cipher negotiated for the SSL session.
   4111  */
   4112 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jint ssl_session_address) {
   4113     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4114     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
   4115     if (ssl_session == NULL) {
   4116         return NULL;
   4117     }
   4118     const SSL_CIPHER* cipher = ssl_session->cipher;
   4119     const char* name = SSL_CIPHER_get_name(cipher);
   4120     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
   4121     return env->NewStringUTF(name);
   4122 }
   4123 
   4124 /**
   4125  * Gets and returns in a string the compression method negotiated for the SSL session.
   4126  */
   4127 static jstring NativeCrypto_SSL_SESSION_compress_meth(JNIEnv* env, jclass,
   4128                                                       jint ssl_ctx_address,
   4129                                                       jint ssl_session_address) {
   4130     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   4131     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4132     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth ssl_ctx=%p",
   4133               ssl_session, ssl_ctx);
   4134     if (ssl_ctx == NULL || ssl_session == NULL) {
   4135         return NULL;
   4136     }
   4137 
   4138     int compress_meth = ssl_session->compress_meth;
   4139     if (compress_meth == 0) {
   4140         const char* name = "NULL";
   4141         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
   4142         return env->NewStringUTF(name);
   4143     }
   4144 
   4145     int num_comp_methods = sk_SSL_COMP_num(ssl_ctx->comp_methods);
   4146     for (int i = 0; i < num_comp_methods; i++) {
   4147         SSL_COMP* comp = sk_SSL_COMP_value(ssl_ctx->comp_methods, i);
   4148         if (comp->id != compress_meth) {
   4149             continue;
   4150         }
   4151         const char* name = ((comp->method && comp->method->type == NID_zlib_compression)
   4152                             ? SN_zlib_compression
   4153                             : (comp->name ? comp->name : "UNKNOWN"));
   4154         JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_compress_meth => %s", ssl_session, name);
   4155         return env->NewStringUTF(name);
   4156     }
   4157     throwSSLExceptionStr(env, "Unknown compression method");
   4158     return NULL;
   4159 }
   4160 
   4161 /**
   4162  * Frees the SSL session.
   4163  */
   4164 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jint ssl_session_address) {
   4165     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4166     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
   4167     if (ssl_session == NULL) {
   4168         return;
   4169     }
   4170     SSL_SESSION_free(ssl_session);
   4171 }
   4172 
   4173 
   4174 /**
   4175  * Serializes the native state of the session (ID, cipher, and keys but
   4176  * not certificates). Returns a byte[] containing the DER-encoded state.
   4177  * See apache mod_ssl.
   4178  */
   4179 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jint ssl_session_address) {
   4180     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   4181     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
   4182     if (ssl_session == NULL) {
   4183         return NULL;
   4184     }
   4185 
   4186     // Compute the size of the DER data
   4187     int size = i2d_SSL_SESSION(ssl_session, NULL);
   4188     if (size == 0) {
   4189         JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => NULL", ssl_session);
   4190         return NULL;
   4191     }
   4192 
   4193     jbyteArray javaBytes = env->NewByteArray(size);
   4194     if (javaBytes != NULL) {
   4195         ScopedByteArrayRW bytes(env, javaBytes);
   4196         if (bytes.get() == NULL) {
   4197             JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => threw exception",
   4198                       ssl_session);
   4199             return NULL;
   4200         }
   4201         unsigned char* ucp = reinterpret_cast<unsigned char*>(bytes.get());
   4202         i2d_SSL_SESSION(ssl_session, &ucp);
   4203     }
   4204 
   4205     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION => size=%d", ssl_session, size);
   4206     return javaBytes;
   4207 }
   4208 
   4209 /**
   4210  * Deserialize the session.
   4211  */
   4212 static jint NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
   4213     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
   4214 
   4215     ScopedByteArrayRO bytes(env, javaBytes);
   4216     if (bytes.get() == NULL) {
   4217         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
   4218         return 0;
   4219     }
   4220     const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
   4221     SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
   4222 
   4223     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
   4224     return static_cast<jint>(reinterpret_cast<uintptr_t>(ssl_session));
   4225 }
   4226 
   4227 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
   4228 #define SSL_CALLBACKS "Lorg/apache/harmony/xnet/provider/jsse/NativeCrypto$SSLHandshakeCallbacks;"
   4229 static JNINativeMethod sNativeCryptoMethods[] = {
   4230     NATIVE_METHOD(NativeCrypto, clinit, "()V"),
   4231     NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
   4232     NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)I"),
   4233     NATIVE_METHOD(NativeCrypto, ENGINE_init, "(I)I"),
   4234     NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(I)I"),
   4235     NATIVE_METHOD(NativeCrypto, ENGINE_free, "(I)I"),
   4236     NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(ILjava/lang/String;)I"),
   4237     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)I"),
   4238     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)I"),
   4239     NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(I)I"),
   4240     NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(I)I"),
   4241     NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(I)V"),
   4242     NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(I)[B"),
   4243     NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)I"),
   4244     NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(I)[B"),
   4245     NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)I"),
   4246     NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)I"),
   4247     NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(I)[[B"),
   4248     NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(I)[[B"),
   4249     NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)I"),
   4250     NATIVE_METHOD(NativeCrypto, get_DSA_params, "(I)[[B"),
   4251     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(I)V"),
   4252     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(I)I"),
   4253     NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(I[BI)I"),
   4254     NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(I)I"),
   4255     NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)I"),
   4256     NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(I)I"),
   4257     NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(I)I"),
   4258     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(I[BII)V"),
   4259     NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)I"),
   4260     NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(I[BII)V"),
   4261     NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(I[BII)I"),
   4262     NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)I"),
   4263     NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(I[BII)V"),
   4264     NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(I[BIII)I"),
   4265     NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)I"),
   4266     NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(I[B[BZ)I"),
   4267     NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(I[BI[BI)I"),
   4268     NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(I[BI)I"),
   4269     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(I)V"),
   4270     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
   4271     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
   4272     NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()I"),
   4273     NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(I)V"),
   4274     NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(I[B)V"),
   4275     NATIVE_METHOD(NativeCrypto, SSL_new, "(I)I"),
   4276     NATIVE_METHOD(NativeCrypto, SSL_use_OpenSSL_PrivateKey, "(II)V"),
   4277     NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(I[B)V"),
   4278     NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(I[[B)V"),
   4279     NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(I)V"),
   4280     NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(I[[B)V"),
   4281     NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(I)J"),
   4282     NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(IJ)J"),
   4283     NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(IJ)J"),
   4284     NATIVE_METHOD(NativeCrypto, SSL_get_options, "(I)J"),
   4285     NATIVE_METHOD(NativeCrypto, SSL_set_options, "(IJ)J"),
   4286     NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(IJ)J"),
   4287     NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(I[Ljava/lang/String;)V"),
   4288     NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(II)V"),
   4289     NATIVE_METHOD(NativeCrypto, SSL_set_session, "(II)V"),
   4290     NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(IZ)V"),
   4291     NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(ILjava/lang/String;)V"),
   4292     NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(I)Ljava/lang/String;"),
   4293     NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B)I"),
   4294     NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(I)V"),
   4295     NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(I)[[B"),
   4296     NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(I)[[B"),
   4297     NATIVE_METHOD(NativeCrypto, SSL_read, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
   4298     NATIVE_METHOD(NativeCrypto, SSL_write, "(I" FILE_DESCRIPTOR SSL_CALLBACKS "[BII)V"),
   4299     NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(I)V"),
   4300     NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(I" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
   4301     NATIVE_METHOD(NativeCrypto, SSL_free, "(I)V"),
   4302     NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(I)[B"),
   4303     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(I)J"),
   4304     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(I)Ljava/lang/String;"),
   4305     NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(I)Ljava/lang/String;"),
   4306     NATIVE_METHOD(NativeCrypto, SSL_SESSION_compress_meth, "(II)Ljava/lang/String;"),
   4307     NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(I)V"),
   4308     NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(I)[B"),
   4309     NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)I"),
   4310     NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(I)V"),
   4311     NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(I)V"),
   4312     NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(I)[B"),
   4313 };
   4314 
   4315 void register_org_apache_harmony_xnet_provider_jsse_NativeCrypto(JNIEnv* env) {
   4316     JNI_TRACE("register_org_apache_harmony_xnet_provider_jsse_NativeCrypto");
   4317     // Register org.apache.harmony.xnet.provider.jsse.NativeCrypto methods
   4318     jniRegisterNativeMethods(env, "org/apache/harmony/xnet/provider/jsse/NativeCrypto", sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
   4319 }
   4320