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.conscrypt.NativeCrypto
     19  */
     20 
     21 #define TO_STRING1(x) #x
     22 #define TO_STRING(x) TO_STRING1(x)
     23 #ifndef JNI_JARJAR_PREFIX
     24     #ifndef CONSCRYPT_NOT_UNBUNDLED
     25         #define CONSCRYPT_UNBUNDLED
     26     #endif
     27     #define JNI_JARJAR_PREFIX
     28 #endif
     29 
     30 #define LOG_TAG "NativeCrypto"
     31 
     32 #include <arpa/inet.h>
     33 #include <fcntl.h>
     34 #include <pthread.h>
     35 #include <sys/socket.h>
     36 #include <unistd.h>
     37 
     38 #ifdef CONSCRYPT_UNBUNDLED
     39 #include <dlfcn.h>
     40 #endif
     41 
     42 #include <jni.h>
     43 
     44 #include <openssl/asn1t.h>
     45 #include <openssl/dsa.h>
     46 #include <openssl/engine.h>
     47 #include <openssl/err.h>
     48 #include <openssl/evp.h>
     49 #include <openssl/rand.h>
     50 #include <openssl/rsa.h>
     51 #include <openssl/ssl.h>
     52 #include <openssl/x509v3.h>
     53 #include "crypto/ecdsa/ecs_locl.h"
     54 
     55 #ifndef CONSCRYPT_UNBUNDLED
     56 /* If we're compiled unbundled from Android system image, we use the
     57  * CompatibilityCloseMonitor
     58  */
     59 #include "AsynchronousCloseMonitor.h"
     60 #endif
     61 
     62 #ifndef CONSCRYPT_UNBUNDLED
     63 #include "cutils/log.h"
     64 #else
     65 #include <android/log.h>
     66 #define ALOG(priority, tag, ...) \
     67         __android_log_print(ANDROID_##priority, tag, __VA_ARGS__)
     68 #define ALOGD(...) \
     69         __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
     70 #define ALOGE(...) \
     71         __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
     72 #define ALOGV(...) \
     73         __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
     74 #endif
     75 
     76 #ifndef CONSCRYPT_UNBUNDLED
     77 #include "JNIHelp.h"
     78 #include "JniConstants.h"
     79 #include "JniException.h"
     80 #else
     81 #define NATIVE_METHOD(className, functionName, signature) \
     82   { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName) }
     83 #define REGISTER_NATIVE_METHODS(jni_class_name) \
     84   RegisterNativeMethods(env, jni_class_name, gMethods, arraysize(gMethods))
     85 #endif
     86 
     87 #include "ScopedLocalRef.h"
     88 #include "ScopedPrimitiveArray.h"
     89 #include "ScopedUtfChars.h"
     90 #include "UniquePtr.h"
     91 #include "NetFd.h"
     92 
     93 #undef WITH_JNI_TRACE
     94 #undef WITH_JNI_TRACE_MD
     95 #undef WITH_JNI_TRACE_DATA
     96 
     97 /*
     98  * How to use this for debugging with Wireshark:
     99  *
    100  * 1. Pull lines from logcat to a file that looks like (without quotes):
    101  *     "RSA Session-ID:... Master-Key:..." <CR>
    102  *     "RSA Session-ID:... Master-Key:..." <CR>
    103  *     <etc>
    104  * 2. Start Wireshark
    105  * 3. Go to Edit -> Preferences -> SSL -> (Pre-)Master-Key log and fill in
    106  *    the file you put the lines in above.
    107  * 4. Follow the stream that corresponds to the desired "Session-ID" in
    108  *    the Server Hello.
    109  */
    110 #undef WITH_JNI_TRACE_KEYS
    111 
    112 #ifdef WITH_JNI_TRACE
    113 #define JNI_TRACE(...) \
    114         ((void)ALOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__))
    115 #else
    116 #define JNI_TRACE(...) ((void)0)
    117 #endif
    118 #ifdef WITH_JNI_TRACE_MD
    119 #define JNI_TRACE_MD(...) \
    120         ((void)ALOG(LOG_INFO, LOG_TAG "-jni", __VA_ARGS__));
    121 #else
    122 #define JNI_TRACE_MD(...) ((void)0)
    123 #endif
    124 // don't overwhelm logcat
    125 #define WITH_JNI_TRACE_DATA_CHUNK_SIZE 512
    126 
    127 static JavaVM* gJavaVM;
    128 static jclass cryptoUpcallsClass;
    129 static jclass openSslInputStreamClass;
    130 static jclass openSslNativeReferenceClass;
    131 
    132 static jclass byteArrayClass;
    133 static jclass calendarClass;
    134 static jclass objectClass;
    135 static jclass objectArrayClass;
    136 static jclass integerClass;
    137 static jclass inputStreamClass;
    138 static jclass outputStreamClass;
    139 static jclass stringClass;
    140 
    141 static jfieldID openSslNativeReference_context;
    142 
    143 static jmethodID calendar_setMethod;
    144 static jmethodID inputStream_readMethod;
    145 static jmethodID integer_valueOfMethod;
    146 static jmethodID openSslInputStream_readLineMethod;
    147 static jmethodID outputStream_writeMethod;
    148 static jmethodID outputStream_flushMethod;
    149 
    150 struct OPENSSL_Delete {
    151     void operator()(void* p) const {
    152         OPENSSL_free(p);
    153     }
    154 };
    155 typedef UniquePtr<unsigned char, OPENSSL_Delete> Unique_OPENSSL_str;
    156 
    157 struct BIO_Delete {
    158     void operator()(BIO* p) const {
    159         BIO_free_all(p);
    160     }
    161 };
    162 typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
    163 
    164 struct BIGNUM_Delete {
    165     void operator()(BIGNUM* p) const {
    166         BN_free(p);
    167     }
    168 };
    169 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
    170 
    171 struct ASN1_INTEGER_Delete {
    172     void operator()(ASN1_INTEGER* p) const {
    173         ASN1_INTEGER_free(p);
    174     }
    175 };
    176 typedef UniquePtr<ASN1_INTEGER, ASN1_INTEGER_Delete> Unique_ASN1_INTEGER;
    177 
    178 struct DH_Delete {
    179     void operator()(DH* p) const {
    180         DH_free(p);
    181     }
    182 };
    183 typedef UniquePtr<DH, DH_Delete> Unique_DH;
    184 
    185 struct DSA_Delete {
    186     void operator()(DSA* p) const {
    187         DSA_free(p);
    188     }
    189 };
    190 typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
    191 
    192 struct EC_GROUP_Delete {
    193     void operator()(EC_GROUP* p) const {
    194         EC_GROUP_clear_free(p);
    195     }
    196 };
    197 typedef UniquePtr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
    198 
    199 struct EC_POINT_Delete {
    200     void operator()(EC_POINT* p) const {
    201         EC_POINT_clear_free(p);
    202     }
    203 };
    204 typedef UniquePtr<EC_POINT, EC_POINT_Delete> Unique_EC_POINT;
    205 
    206 struct EC_KEY_Delete {
    207     void operator()(EC_KEY* p) const {
    208         EC_KEY_free(p);
    209     }
    210 };
    211 typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
    212 
    213 struct EVP_MD_CTX_Delete {
    214     void operator()(EVP_MD_CTX* p) const {
    215         EVP_MD_CTX_destroy(p);
    216     }
    217 };
    218 typedef UniquePtr<EVP_MD_CTX, EVP_MD_CTX_Delete> Unique_EVP_MD_CTX;
    219 
    220 struct EVP_CIPHER_CTX_Delete {
    221     void operator()(EVP_CIPHER_CTX* p) const {
    222         EVP_CIPHER_CTX_free(p);
    223     }
    224 };
    225 typedef UniquePtr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Delete> Unique_EVP_CIPHER_CTX;
    226 
    227 struct EVP_PKEY_Delete {
    228     void operator()(EVP_PKEY* p) const {
    229         EVP_PKEY_free(p);
    230     }
    231 };
    232 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
    233 
    234 struct PKCS8_PRIV_KEY_INFO_Delete {
    235     void operator()(PKCS8_PRIV_KEY_INFO* p) const {
    236         PKCS8_PRIV_KEY_INFO_free(p);
    237     }
    238 };
    239 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
    240 
    241 struct RSA_Delete {
    242     void operator()(RSA* p) const {
    243         RSA_free(p);
    244     }
    245 };
    246 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
    247 
    248 struct ASN1_BIT_STRING_Delete {
    249     void operator()(ASN1_BIT_STRING* p) const {
    250         ASN1_BIT_STRING_free(p);
    251     }
    252 };
    253 typedef UniquePtr<ASN1_BIT_STRING, ASN1_BIT_STRING_Delete> Unique_ASN1_BIT_STRING;
    254 
    255 struct ASN1_OBJECT_Delete {
    256     void operator()(ASN1_OBJECT* p) const {
    257         ASN1_OBJECT_free(p);
    258     }
    259 };
    260 typedef UniquePtr<ASN1_OBJECT, ASN1_OBJECT_Delete> Unique_ASN1_OBJECT;
    261 
    262 struct ASN1_GENERALIZEDTIME_Delete {
    263     void operator()(ASN1_GENERALIZEDTIME* p) const {
    264         ASN1_GENERALIZEDTIME_free(p);
    265     }
    266 };
    267 typedef UniquePtr<ASN1_GENERALIZEDTIME, ASN1_GENERALIZEDTIME_Delete> Unique_ASN1_GENERALIZEDTIME;
    268 
    269 struct SSL_Delete {
    270     void operator()(SSL* p) const {
    271         SSL_free(p);
    272     }
    273 };
    274 typedef UniquePtr<SSL, SSL_Delete> Unique_SSL;
    275 
    276 struct SSL_CTX_Delete {
    277     void operator()(SSL_CTX* p) const {
    278         SSL_CTX_free(p);
    279     }
    280 };
    281 typedef UniquePtr<SSL_CTX, SSL_CTX_Delete> Unique_SSL_CTX;
    282 
    283 struct X509_Delete {
    284     void operator()(X509* p) const {
    285         X509_free(p);
    286     }
    287 };
    288 typedef UniquePtr<X509, X509_Delete> Unique_X509;
    289 
    290 struct X509_NAME_Delete {
    291     void operator()(X509_NAME* p) const {
    292         X509_NAME_free(p);
    293     }
    294 };
    295 typedef UniquePtr<X509_NAME, X509_NAME_Delete> Unique_X509_NAME;
    296 
    297 struct PKCS7_Delete {
    298     void operator()(PKCS7* p) const {
    299         PKCS7_free(p);
    300     }
    301 };
    302 typedef UniquePtr<PKCS7, PKCS7_Delete> Unique_PKCS7;
    303 
    304 struct sk_SSL_CIPHER_Delete {
    305     void operator()(STACK_OF(SSL_CIPHER)* p) const {
    306         // We don't own SSL_CIPHER references, so no need for pop_free
    307         sk_SSL_CIPHER_free(p);
    308     }
    309 };
    310 typedef UniquePtr<STACK_OF(SSL_CIPHER), sk_SSL_CIPHER_Delete> Unique_sk_SSL_CIPHER;
    311 
    312 struct sk_X509_Delete {
    313     void operator()(STACK_OF(X509)* p) const {
    314         sk_X509_pop_free(p, X509_free);
    315     }
    316 };
    317 typedef UniquePtr<STACK_OF(X509), sk_X509_Delete> Unique_sk_X509;
    318 
    319 struct sk_X509_NAME_Delete {
    320     void operator()(STACK_OF(X509_NAME)* p) const {
    321         sk_X509_NAME_pop_free(p, X509_NAME_free);
    322     }
    323 };
    324 typedef UniquePtr<STACK_OF(X509_NAME), sk_X509_NAME_Delete> Unique_sk_X509_NAME;
    325 
    326 struct sk_ASN1_OBJECT_Delete {
    327     void operator()(STACK_OF(ASN1_OBJECT)* p) const {
    328         sk_ASN1_OBJECT_pop_free(p, ASN1_OBJECT_free);
    329     }
    330 };
    331 typedef UniquePtr<STACK_OF(ASN1_OBJECT), sk_ASN1_OBJECT_Delete> Unique_sk_ASN1_OBJECT;
    332 
    333 struct sk_GENERAL_NAME_Delete {
    334     void operator()(STACK_OF(GENERAL_NAME)* p) const {
    335         sk_GENERAL_NAME_pop_free(p, GENERAL_NAME_free);
    336     }
    337 };
    338 typedef UniquePtr<STACK_OF(GENERAL_NAME), sk_GENERAL_NAME_Delete> Unique_sk_GENERAL_NAME;
    339 
    340 /**
    341  * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
    342  * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
    343  * without triggering a warning by not using the result of release().
    344  */
    345 #define OWNERSHIP_TRANSFERRED(obj) \
    346     do { typeof (obj.release()) _dummy __attribute__((unused)) = obj.release(); } while(0)
    347 
    348 /**
    349  * Frees the SSL error state.
    350  *
    351  * OpenSSL keeps an "error stack" per thread, and given that this code
    352  * can be called from arbitrary threads that we don't keep track of,
    353  * we err on the side of freeing the error state promptly (instead of,
    354  * say, at thread death).
    355  */
    356 static void freeOpenSslErrorState(void) {
    357     ERR_clear_error();
    358     ERR_remove_state(0);
    359 }
    360 
    361 /**
    362  * Manages the freeing of the OpenSSL error stack. This allows you to
    363  * instantiate this object during an SSL call that may fail and not worry
    364  * about manually calling freeOpenSslErrorState() later.
    365  *
    366  * As an optimization, you can also call .release() for passing as an
    367  * argument to things that free the error stack state as a side-effect.
    368  */
    369 class OpenSslError {
    370 public:
    371     OpenSslError() : sslError_(SSL_ERROR_NONE), released_(false) {
    372     }
    373 
    374     OpenSslError(SSL* ssl, int returnCode) : sslError_(SSL_ERROR_NONE), released_(false) {
    375         reset(ssl, returnCode);
    376     }
    377 
    378     ~OpenSslError() {
    379         if (!released_ && sslError_ != SSL_ERROR_NONE) {
    380             freeOpenSslErrorState();
    381         }
    382     }
    383 
    384     int get() const {
    385         return sslError_;
    386     }
    387 
    388     void reset(SSL* ssl, int returnCode) {
    389         if (returnCode <= 0) {
    390             sslError_ = SSL_get_error(ssl, returnCode);
    391         } else {
    392             sslError_ = SSL_ERROR_NONE;
    393         }
    394     }
    395 
    396     int release() {
    397         released_ = true;
    398         return sslError_;
    399     }
    400 
    401 private:
    402     int sslError_;
    403     bool released_;
    404 };
    405 
    406 /**
    407  * Throws a OutOfMemoryError with the given string as a message.
    408  */
    409 static void jniThrowOutOfMemory(JNIEnv* env, const char* message) {
    410     jniThrowException(env, "java/lang/OutOfMemoryError", message);
    411 }
    412 
    413 /**
    414  * Throws a BadPaddingException with the given string as a message.
    415  */
    416 static void throwBadPaddingException(JNIEnv* env, const char* message) {
    417     JNI_TRACE("throwBadPaddingException %s", message);
    418     jniThrowException(env, "javax/crypto/BadPaddingException", message);
    419 }
    420 
    421 /**
    422  * Throws a SignatureException with the given string as a message.
    423  */
    424 static void throwSignatureException(JNIEnv* env, const char* message) {
    425     JNI_TRACE("throwSignatureException %s", message);
    426     jniThrowException(env, "java/security/SignatureException", message);
    427 }
    428 
    429 /**
    430  * Throws a InvalidKeyException with the given string as a message.
    431  */
    432 static void throwInvalidKeyException(JNIEnv* env, const char* message) {
    433     JNI_TRACE("throwInvalidKeyException %s", message);
    434     jniThrowException(env, "java/security/InvalidKeyException", message);
    435 }
    436 
    437 /**
    438  * Throws a SignatureException with the given string as a message.
    439  */
    440 static void throwIllegalBlockSizeException(JNIEnv* env, const char* message) {
    441     JNI_TRACE("throwIllegalBlockSizeException %s", message);
    442     jniThrowException(env, "javax/crypto/IllegalBlockSizeException", message);
    443 }
    444 
    445 /**
    446  * Throws a NoSuchAlgorithmException with the given string as a message.
    447  */
    448 static void throwNoSuchAlgorithmException(JNIEnv* env, const char* message) {
    449     JNI_TRACE("throwUnknownAlgorithmException %s", message);
    450     jniThrowException(env, "java/security/NoSuchAlgorithmException", message);
    451 }
    452 
    453 static void throwForAsn1Error(JNIEnv* env, int reason, const char *message) {
    454     switch (reason) {
    455     case ASN1_R_UNABLE_TO_DECODE_RSA_KEY:
    456     case ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY:
    457     case ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE:
    458     case ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE:
    459     case ASN1_R_WRONG_PUBLIC_KEY_TYPE:
    460         throwInvalidKeyException(env, message);
    461         break;
    462     case ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM:
    463         throwNoSuchAlgorithmException(env, message);
    464         break;
    465     default:
    466         jniThrowRuntimeException(env, message);
    467         break;
    468     }
    469 }
    470 
    471 static void throwForEvpError(JNIEnv* env, int reason, const char *message) {
    472     switch (reason) {
    473     case EVP_R_BAD_DECRYPT:
    474         throwBadPaddingException(env, message);
    475         break;
    476     case EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH:
    477     case EVP_R_WRONG_FINAL_BLOCK_LENGTH:
    478         throwIllegalBlockSizeException(env, message);
    479         break;
    480     case EVP_R_BAD_KEY_LENGTH:
    481     case EVP_R_BN_DECODE_ERROR:
    482     case EVP_R_BN_PUBKEY_ERROR:
    483     case EVP_R_INVALID_KEY_LENGTH:
    484     case EVP_R_MISSING_PARAMETERS:
    485     case EVP_R_UNSUPPORTED_KEY_SIZE:
    486     case EVP_R_UNSUPPORTED_KEYLENGTH:
    487         throwInvalidKeyException(env, message);
    488         break;
    489     case EVP_R_WRONG_PUBLIC_KEY_TYPE:
    490         throwSignatureException(env, message);
    491         break;
    492     case EVP_R_UNSUPPORTED_ALGORITHM:
    493         throwNoSuchAlgorithmException(env, message);
    494         break;
    495     default:
    496         jniThrowRuntimeException(env, message);
    497         break;
    498     }
    499 }
    500 
    501 static void throwForRsaError(JNIEnv* env, int reason, const char *message) {
    502     switch (reason) {
    503     case RSA_R_BLOCK_TYPE_IS_NOT_01:
    504     case RSA_R_BLOCK_TYPE_IS_NOT_02:
    505     case RSA_R_PKCS_DECODING_ERROR:
    506         throwBadPaddingException(env, message);
    507         break;
    508     case RSA_R_ALGORITHM_MISMATCH:
    509     case RSA_R_BAD_SIGNATURE:
    510     case RSA_R_DATA_GREATER_THAN_MOD_LEN:
    511     case RSA_R_DATA_TOO_LARGE_FOR_MODULUS:
    512     case RSA_R_INVALID_MESSAGE_LENGTH:
    513     case RSA_R_WRONG_SIGNATURE_LENGTH:
    514         throwSignatureException(env, message);
    515         break;
    516     case RSA_R_UNKNOWN_ALGORITHM_TYPE:
    517         throwNoSuchAlgorithmException(env, message);
    518         break;
    519     case RSA_R_MODULUS_TOO_LARGE:
    520     case RSA_R_NO_PUBLIC_EXPONENT:
    521         throwInvalidKeyException(env, message);
    522         break;
    523     default:
    524         jniThrowRuntimeException(env, message);
    525         break;
    526     }
    527 }
    528 
    529 static void throwForX509Error(JNIEnv* env, int reason, const char *message) {
    530     switch (reason) {
    531     case X509_R_UNSUPPORTED_ALGORITHM:
    532         throwNoSuchAlgorithmException(env, message);
    533         break;
    534     default:
    535         jniThrowRuntimeException(env, message);
    536         break;
    537     }
    538 }
    539 
    540 /*
    541  * Checks this thread's OpenSSL error queue and throws a RuntimeException if
    542  * necessary.
    543  *
    544  * @return true if an exception was thrown, false if not.
    545  */
    546 static bool throwExceptionIfNecessary(JNIEnv* env, const char* location  __attribute__ ((unused))) {
    547     const char* file;
    548     int line;
    549     const char* data;
    550     int flags;
    551     unsigned long error = ERR_get_error_line_data(&file, &line, &data, &flags);
    552     int result = false;
    553 
    554     if (error != 0) {
    555         char message[256];
    556         ERR_error_string_n(error, message, sizeof(message));
    557         int library = ERR_GET_LIB(error);
    558         int reason = ERR_GET_REASON(error);
    559         JNI_TRACE("OpenSSL error in %s error=%lx library=%x reason=%x (%s:%d): %s %s",
    560                   location, error, library, reason, file, line, message,
    561                   (flags & ERR_TXT_STRING) ? data : "(no data)");
    562         switch (library) {
    563         case ERR_LIB_RSA:
    564             throwForRsaError(env, reason, message);
    565             break;
    566         case ERR_LIB_ASN1:
    567             throwForAsn1Error(env, reason, message);
    568             break;
    569         case ERR_LIB_EVP:
    570             throwForEvpError(env, reason, message);
    571             break;
    572         case ERR_LIB_X509:
    573             throwForX509Error(env, reason, message);
    574             break;
    575         case ERR_LIB_DSA:
    576             throwInvalidKeyException(env, message);
    577             break;
    578         default:
    579             jniThrowRuntimeException(env, message);
    580             break;
    581         }
    582         result = true;
    583     }
    584 
    585     freeOpenSslErrorState();
    586     return result;
    587 }
    588 
    589 /**
    590  * Throws an SocketTimeoutException with the given string as a message.
    591  */
    592 static void throwSocketTimeoutException(JNIEnv* env, const char* message) {
    593     JNI_TRACE("throwSocketTimeoutException %s", message);
    594     jniThrowException(env, "java/net/SocketTimeoutException", message);
    595 }
    596 
    597 /**
    598  * Throws a javax.net.ssl.SSLException with the given string as a message.
    599  */
    600 static void throwSSLHandshakeExceptionStr(JNIEnv* env, const char* message) {
    601     JNI_TRACE("throwSSLExceptionStr %s", message);
    602     jniThrowException(env, "javax/net/ssl/SSLHandshakeException", message);
    603 }
    604 
    605 /**
    606  * Throws a javax.net.ssl.SSLException with the given string as a message.
    607  */
    608 static void throwSSLExceptionStr(JNIEnv* env, const char* message) {
    609     JNI_TRACE("throwSSLExceptionStr %s", message);
    610     jniThrowException(env, "javax/net/ssl/SSLException", message);
    611 }
    612 
    613 /**
    614  * Throws a javax.net.ssl.SSLProcotolException with the given string as a message.
    615  */
    616 static void throwSSLProtocolExceptionStr(JNIEnv* env, const char* message) {
    617     JNI_TRACE("throwSSLProtocolExceptionStr %s", message);
    618     jniThrowException(env, "javax/net/ssl/SSLProtocolException", message);
    619 }
    620 
    621 /**
    622  * Throws an SSLException with a message constructed from the current
    623  * SSL errors. This will also log the errors.
    624  *
    625  * @param env the JNI environment
    626  * @param ssl the possibly NULL SSL
    627  * @param sslErrorCode error code returned from SSL_get_error() or
    628  * SSL_ERROR_NONE to probe with ERR_get_error
    629  * @param message null-ok; general error message
    630  */
    631 static void throwSSLExceptionWithSslErrors(JNIEnv* env, SSL* ssl, int sslErrorCode,
    632         const char* message, void (*actualThrow)(JNIEnv*, const char*) = throwSSLExceptionStr) {
    633 
    634     if (message == NULL) {
    635         message = "SSL error";
    636     }
    637 
    638     // First consult the SSL error code for the general message.
    639     const char* sslErrorStr = NULL;
    640     switch (sslErrorCode) {
    641         case SSL_ERROR_NONE:
    642             if (ERR_peek_error() == 0) {
    643                 sslErrorStr = "OK";
    644             } else {
    645                 sslErrorStr = "";
    646             }
    647             break;
    648         case SSL_ERROR_SSL:
    649             sslErrorStr = "Failure in SSL library, usually a protocol error";
    650             break;
    651         case SSL_ERROR_WANT_READ:
    652             sslErrorStr = "SSL_ERROR_WANT_READ occurred. You should never see this.";
    653             break;
    654         case SSL_ERROR_WANT_WRITE:
    655             sslErrorStr = "SSL_ERROR_WANT_WRITE occurred. You should never see this.";
    656             break;
    657         case SSL_ERROR_WANT_X509_LOOKUP:
    658             sslErrorStr = "SSL_ERROR_WANT_X509_LOOKUP occurred. You should never see this.";
    659             break;
    660         case SSL_ERROR_SYSCALL:
    661             sslErrorStr = "I/O error during system call";
    662             break;
    663         case SSL_ERROR_ZERO_RETURN:
    664             sslErrorStr = "SSL_ERROR_ZERO_RETURN occurred. You should never see this.";
    665             break;
    666         case SSL_ERROR_WANT_CONNECT:
    667             sslErrorStr = "SSL_ERROR_WANT_CONNECT occurred. You should never see this.";
    668             break;
    669         case SSL_ERROR_WANT_ACCEPT:
    670             sslErrorStr = "SSL_ERROR_WANT_ACCEPT occurred. You should never see this.";
    671             break;
    672         default:
    673             sslErrorStr = "Unknown SSL error";
    674     }
    675 
    676     // Prepend either our explicit message or a default one.
    677     char* str;
    678     if (asprintf(&str, "%s: ssl=%p: %s", message, ssl, sslErrorStr) <= 0) {
    679         // problem with asprintf, just throw argument message, log everything
    680         actualThrow(env, message);
    681         ALOGV("%s: ssl=%p: %s", message, ssl, sslErrorStr);
    682         freeOpenSslErrorState();
    683         return;
    684     }
    685 
    686     char* allocStr = str;
    687 
    688     // For protocol errors, SSL might have more information.
    689     if (sslErrorCode == SSL_ERROR_NONE || sslErrorCode == SSL_ERROR_SSL) {
    690         // Append each error as an additional line to the message.
    691         for (;;) {
    692             char errStr[256];
    693             const char* file;
    694             int line;
    695             const char* data;
    696             int flags;
    697             unsigned long err = ERR_get_error_line_data(&file, &line, &data, &flags);
    698             if (err == 0) {
    699                 break;
    700             }
    701 
    702             ERR_error_string_n(err, errStr, sizeof(errStr));
    703 
    704             int ret = asprintf(&str, "%s\n%s (%s:%d %p:0x%08x)",
    705                                (allocStr == NULL) ? "" : allocStr,
    706                                errStr,
    707                                file,
    708                                line,
    709                                (flags & ERR_TXT_STRING) ? data : "(no data)",
    710                                flags);
    711 
    712             if (ret < 0) {
    713                 break;
    714             }
    715 
    716             free(allocStr);
    717             allocStr = str;
    718         }
    719     // For errors during system calls, errno might be our friend.
    720     } else if (sslErrorCode == SSL_ERROR_SYSCALL) {
    721         if (asprintf(&str, "%s, %s", allocStr, strerror(errno)) >= 0) {
    722             free(allocStr);
    723             allocStr = str;
    724         }
    725     // If the error code is invalid, print it.
    726     } else if (sslErrorCode > SSL_ERROR_WANT_ACCEPT) {
    727         if (asprintf(&str, ", error code is %d", sslErrorCode) >= 0) {
    728             free(allocStr);
    729             allocStr = str;
    730         }
    731     }
    732 
    733     if (sslErrorCode == SSL_ERROR_SSL) {
    734         throwSSLProtocolExceptionStr(env, allocStr);
    735     } else {
    736         actualThrow(env, allocStr);
    737     }
    738 
    739     ALOGV("%s", allocStr);
    740     free(allocStr);
    741     freeOpenSslErrorState();
    742 }
    743 
    744 /**
    745  * Helper function that grabs the casts an ssl pointer and then checks for nullness.
    746  * If this function returns NULL and <code>throwIfNull</code> is
    747  * passed as <code>true</code>, then this function will call
    748  * <code>throwSSLExceptionStr</code> before returning, so in this case of
    749  * NULL, a caller of this function should simply return and allow JNI
    750  * to do its thing.
    751  *
    752  * @param env the JNI environment
    753  * @param ssl_address; the ssl_address pointer as an integer
    754  * @param throwIfNull whether to throw if the SSL pointer is NULL
    755  * @returns the pointer, which may be NULL
    756  */
    757 static SSL_CTX* to_SSL_CTX(JNIEnv* env, jlong ssl_ctx_address, bool throwIfNull) {
    758     SSL_CTX* ssl_ctx = reinterpret_cast<SSL_CTX*>(static_cast<uintptr_t>(ssl_ctx_address));
    759     if ((ssl_ctx == NULL) && throwIfNull) {
    760         JNI_TRACE("ssl_ctx == null");
    761         jniThrowNullPointerException(env, "ssl_ctx == null");
    762     }
    763     return ssl_ctx;
    764 }
    765 
    766 static SSL* to_SSL(JNIEnv* env, jlong ssl_address, bool throwIfNull) {
    767     SSL* ssl = reinterpret_cast<SSL*>(static_cast<uintptr_t>(ssl_address));
    768     if ((ssl == NULL) && throwIfNull) {
    769         JNI_TRACE("ssl == null");
    770         jniThrowNullPointerException(env, "ssl == null");
    771     }
    772     return ssl;
    773 }
    774 
    775 static SSL_SESSION* to_SSL_SESSION(JNIEnv* env, jlong ssl_session_address, bool throwIfNull) {
    776     SSL_SESSION* ssl_session
    777         = reinterpret_cast<SSL_SESSION*>(static_cast<uintptr_t>(ssl_session_address));
    778     if ((ssl_session == NULL) && throwIfNull) {
    779         JNI_TRACE("ssl_session == null");
    780         jniThrowNullPointerException(env, "ssl_session == null");
    781     }
    782     return ssl_session;
    783 }
    784 
    785 static SSL_CIPHER* to_SSL_CIPHER(JNIEnv* env, jlong ssl_cipher_address, bool throwIfNull) {
    786     SSL_CIPHER* ssl_cipher
    787         = reinterpret_cast<SSL_CIPHER*>(static_cast<uintptr_t>(ssl_cipher_address));
    788     if ((ssl_cipher == NULL) && throwIfNull) {
    789         JNI_TRACE("ssl_cipher == null");
    790         jniThrowNullPointerException(env, "ssl_cipher == null");
    791     }
    792     return ssl_cipher;
    793 }
    794 
    795 template<typename T>
    796 static T* fromContextObject(JNIEnv* env, jobject contextObject) {
    797     T* ref = reinterpret_cast<T*>(env->GetLongField(contextObject, openSslNativeReference_context));
    798     if (ref == NULL) {
    799         JNI_TRACE("ctx == null");
    800         jniThrowNullPointerException(env, "ctx == null");
    801     }
    802     return ref;
    803 }
    804 
    805 /**
    806  * Converts a Java byte[] two's complement to an OpenSSL BIGNUM. This will
    807  * allocate the BIGNUM if *dest == NULL. Returns true on success. If the
    808  * return value is false, there is a pending exception.
    809  */
    810 static bool arrayToBignum(JNIEnv* env, jbyteArray source, BIGNUM** dest) {
    811     JNI_TRACE("arrayToBignum(%p, %p)", source, dest);
    812     if (dest == NULL) {
    813         JNI_TRACE("arrayToBignum(%p, %p) => dest is null!", source, dest);
    814         jniThrowNullPointerException(env, "dest == null");
    815         return false;
    816     }
    817     JNI_TRACE("arrayToBignum(%p, %p) *dest == %p", source, dest, *dest);
    818 
    819     ScopedByteArrayRO sourceBytes(env, source);
    820     if (sourceBytes.get() == NULL) {
    821         JNI_TRACE("arrayToBignum(%p, %p) => NULL", source, dest);
    822         return false;
    823     }
    824     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(sourceBytes.get());
    825     size_t tmpSize = sourceBytes.size();
    826 
    827     /* if the array is empty, it is zero. */
    828     if (tmpSize == 0) {
    829         if (*dest == NULL) {
    830             *dest = BN_new();
    831         }
    832         BN_zero(*dest);
    833         return true;
    834     }
    835 
    836     UniquePtr<unsigned char[]> twosComplement;
    837     bool negative = (tmp[0] & 0x80) != 0;
    838     if (negative) {
    839         // Need to convert to two's complement.
    840         twosComplement.reset(new unsigned char[tmpSize]);
    841         unsigned char* twosBytes = reinterpret_cast<unsigned char*>(twosComplement.get());
    842         memcpy(twosBytes, tmp, tmpSize);
    843         tmp = twosBytes;
    844 
    845         bool carry = true;
    846         for (ssize_t i = tmpSize - 1; i >= 0; i--) {
    847             twosBytes[i] ^= 0xFF;
    848             if (carry) {
    849                 carry = (++twosBytes[i]) == 0;
    850             }
    851         }
    852     }
    853     BIGNUM *ret = BN_bin2bn(tmp, tmpSize, *dest);
    854     if (ret == NULL) {
    855         jniThrowRuntimeException(env, "Conversion to BIGNUM failed");
    856         JNI_TRACE("arrayToBignum(%p, %p) => threw exception", source, dest);
    857         return false;
    858     }
    859     BN_set_negative(ret, negative ? 1 : 0);
    860 
    861     *dest = ret;
    862     JNI_TRACE("arrayToBignum(%p, %p) => *dest = %p", source, dest, ret);
    863     return true;
    864 }
    865 
    866 /**
    867  * Converts an OpenSSL BIGNUM to a Java byte[] array in two's complement.
    868  */
    869 static jbyteArray bignumToArray(JNIEnv* env, const BIGNUM* source, const char* sourceName) {
    870     JNI_TRACE("bignumToArray(%p, %s)", source, sourceName);
    871 
    872     if (source == NULL) {
    873         jniThrowNullPointerException(env, sourceName);
    874         return NULL;
    875     }
    876 
    877     size_t numBytes = BN_num_bytes(source) + 1;
    878     jbyteArray javaBytes = env->NewByteArray(numBytes);
    879     ScopedByteArrayRW bytes(env, javaBytes);
    880     if (bytes.get() == NULL) {
    881         JNI_TRACE("bignumToArray(%p, %s) => NULL", source, sourceName);
    882         return NULL;
    883     }
    884 
    885     unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
    886     if (BN_num_bytes(source) > 0 && BN_bn2bin(source, tmp + 1) <= 0) {
    887         throwExceptionIfNecessary(env, "bignumToArray");
    888         return NULL;
    889     }
    890 
    891     // Set the sign and convert to two's complement if necessary for the Java code.
    892     if (BN_is_negative(source)) {
    893         bool carry = true;
    894         for (ssize_t i = numBytes - 1; i >= 0; i--) {
    895             tmp[i] ^= 0xFF;
    896             if (carry) {
    897                 carry = (++tmp[i]) == 0;
    898             }
    899         }
    900         *tmp |= 0x80;
    901     } else {
    902         *tmp = 0x00;
    903     }
    904 
    905     JNI_TRACE("bignumToArray(%p, %s) => %p", source, sourceName, javaBytes);
    906     return javaBytes;
    907 }
    908 
    909 /**
    910  * Converts various OpenSSL ASN.1 types to a jbyteArray with DER-encoded data
    911  * inside. The "i2d_func" function pointer is a function of the "i2d_<TYPE>"
    912  * from the OpenSSL ASN.1 API.
    913  */
    914 template<typename T, int (*i2d_func)(T*, unsigned char**)>
    915 jbyteArray ASN1ToByteArray(JNIEnv* env, T* obj) {
    916     if (obj == NULL) {
    917         jniThrowNullPointerException(env, "ASN1 input == null");
    918         JNI_TRACE("ASN1ToByteArray(%p) => null input", obj);
    919         return NULL;
    920     }
    921 
    922     int derLen = i2d_func(obj, NULL);
    923     if (derLen < 0) {
    924         throwExceptionIfNecessary(env, "ASN1ToByteArray");
    925         JNI_TRACE("ASN1ToByteArray(%p) => measurement failed", obj);
    926         return NULL;
    927     }
    928 
    929     ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(derLen));
    930     if (byteArray.get() == NULL) {
    931         JNI_TRACE("ASN1ToByteArray(%p) => creating byte array failed", obj);
    932         return NULL;
    933     }
    934 
    935     ScopedByteArrayRW bytes(env, byteArray.get());
    936     if (bytes.get() == NULL) {
    937         JNI_TRACE("ASN1ToByteArray(%p) => using byte array failed", obj);
    938         return NULL;
    939     }
    940 
    941     unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
    942     int ret = i2d_func(obj, &p);
    943     if (ret < 0) {
    944         throwExceptionIfNecessary(env, "ASN1ToByteArray");
    945         JNI_TRACE("ASN1ToByteArray(%p) => final conversion failed", obj);
    946         return NULL;
    947     }
    948 
    949     JNI_TRACE("ASN1ToByteArray(%p) => success (%d bytes written)", obj, ret);
    950     return byteArray.release();
    951 }
    952 
    953 template<typename T, T* (*d2i_func)(T**, const unsigned char**, long)>
    954 T* ByteArrayToASN1(JNIEnv* env, jbyteArray byteArray) {
    955     ScopedByteArrayRO bytes(env, byteArray);
    956     if (bytes.get() == NULL) {
    957         JNI_TRACE("ByteArrayToASN1(%p) => using byte array failed", byteArray);
    958         return 0;
    959     }
    960 
    961     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
    962     return d2i_func(NULL, &tmp, bytes.size());
    963 }
    964 
    965 /**
    966  * Converts ASN.1 BIT STRING to a jbooleanArray.
    967  */
    968 jbooleanArray ASN1BitStringToBooleanArray(JNIEnv* env, ASN1_BIT_STRING* bitStr) {
    969     int size = bitStr->length * 8;
    970     if (bitStr->flags & ASN1_STRING_FLAG_BITS_LEFT) {
    971         size -= bitStr->flags & 0x07;
    972     }
    973 
    974     ScopedLocalRef<jbooleanArray> bitsRef(env, env->NewBooleanArray(size));
    975     if (bitsRef.get() == NULL) {
    976         return NULL;
    977     }
    978 
    979     ScopedBooleanArrayRW bitsArray(env, bitsRef.get());
    980     for (int i = 0; i < static_cast<int>(bitsArray.size()); i++) {
    981         bitsArray[i] = ASN1_BIT_STRING_get_bit(bitStr, i);
    982     }
    983 
    984     return bitsRef.release();
    985 }
    986 
    987 /**
    988  * Safely clear SSL sessions and throw an error if there was something already
    989  * in the error stack.
    990  */
    991 static void safeSslClear(SSL* ssl) {
    992     if (SSL_clear(ssl) != 1) {
    993         freeOpenSslErrorState();
    994     }
    995 }
    996 
    997 /**
    998  * To avoid the round-trip to ASN.1 and back in X509_dup, we just up the reference count.
    999  */
   1000 static X509* X509_dup_nocopy(X509* x509) {
   1001     if (x509 == NULL) {
   1002         return NULL;
   1003     }
   1004     CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
   1005     return x509;
   1006 }
   1007 
   1008 /*
   1009  * Sets the read and write BIO for an SSL connection and removes it when it goes out of scope.
   1010  * We hang on to BIO with a JNI GlobalRef and we want to remove them as soon as possible.
   1011  */
   1012 class ScopedSslBio {
   1013 public:
   1014     ScopedSslBio(SSL *ssl, BIO* rbio, BIO* wbio) : ssl_(ssl) {
   1015         SSL_set_bio(ssl_, rbio, wbio);
   1016         CRYPTO_add(&rbio->references,1,CRYPTO_LOCK_BIO);
   1017         CRYPTO_add(&wbio->references,1,CRYPTO_LOCK_BIO);
   1018     }
   1019 
   1020     ~ScopedSslBio() {
   1021         SSL_set_bio(ssl_, NULL, NULL);
   1022     }
   1023 
   1024 private:
   1025     SSL* const ssl_;
   1026 };
   1027 
   1028 /**
   1029  * Obtains the current thread's JNIEnv
   1030  */
   1031 static JNIEnv* getJNIEnv() {
   1032     JNIEnv* env;
   1033     if (gJavaVM->AttachCurrentThread(&env, NULL) < 0) {
   1034         ALOGE("Could not attach JavaVM to find current JNIEnv");
   1035         return NULL;
   1036     }
   1037     return env;
   1038 }
   1039 
   1040 /**
   1041  * BIO for InputStream
   1042  */
   1043 class BIO_Stream {
   1044 public:
   1045     BIO_Stream(jobject stream) :
   1046             mEof(false) {
   1047         JNIEnv* env = getJNIEnv();
   1048         mStream = env->NewGlobalRef(stream);
   1049     }
   1050 
   1051     ~BIO_Stream() {
   1052         JNIEnv* env = getJNIEnv();
   1053 
   1054         env->DeleteGlobalRef(mStream);
   1055     }
   1056 
   1057     bool isEof() const {
   1058         JNI_TRACE("isEof? %s", mEof ? "yes" : "no");
   1059         return mEof;
   1060     }
   1061 
   1062     int flush() {
   1063         JNIEnv* env = getJNIEnv();
   1064         if (env == NULL) {
   1065             return -1;
   1066         }
   1067 
   1068         if (env->ExceptionCheck()) {
   1069             JNI_TRACE("BIO_Stream::flush called with pending exception");
   1070             return -1;
   1071         }
   1072 
   1073         env->CallVoidMethod(mStream, outputStream_flushMethod);
   1074         if (env->ExceptionCheck()) {
   1075             return -1;
   1076         }
   1077 
   1078         return 1;
   1079     }
   1080 
   1081 protected:
   1082     jobject getStream() {
   1083         return mStream;
   1084     }
   1085 
   1086     void setEof(bool eof) {
   1087         mEof = eof;
   1088     }
   1089 
   1090 private:
   1091     jobject mStream;
   1092     bool mEof;
   1093 };
   1094 
   1095 class BIO_InputStream : public BIO_Stream {
   1096 public:
   1097     BIO_InputStream(jobject stream) :
   1098             BIO_Stream(stream) {
   1099     }
   1100 
   1101     int read(char *buf, int len) {
   1102         return read_internal(buf, len, inputStream_readMethod);
   1103     }
   1104 
   1105     int gets(char *buf, int len) {
   1106         if (len > PEM_LINE_LENGTH) {
   1107             len = PEM_LINE_LENGTH;
   1108         }
   1109 
   1110         int read = read_internal(buf, len - 1, openSslInputStream_readLineMethod);
   1111         buf[read] = '\0';
   1112         JNI_TRACE("BIO::gets \"%s\"", buf);
   1113         return read;
   1114     }
   1115 
   1116 private:
   1117     int read_internal(char *buf, int len, jmethodID method) {
   1118         JNIEnv* env = getJNIEnv();
   1119         if (env == NULL) {
   1120             JNI_TRACE("BIO_InputStream::read could not get JNIEnv");
   1121             return -1;
   1122         }
   1123 
   1124         if (env->ExceptionCheck()) {
   1125             JNI_TRACE("BIO_InputStream::read called with pending exception");
   1126             return -1;
   1127         }
   1128 
   1129         ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
   1130         if (javaBytes.get() == NULL) {
   1131             JNI_TRACE("BIO_InputStream::read failed call to NewByteArray");
   1132             return -1;
   1133         }
   1134 
   1135         jint read = env->CallIntMethod(getStream(), method, javaBytes.get());
   1136         if (env->ExceptionCheck()) {
   1137             JNI_TRACE("BIO_InputStream::read failed call to InputStream#read");
   1138             return -1;
   1139         }
   1140 
   1141         /* Java uses -1 to indicate EOF condition. */
   1142         if (read == -1) {
   1143             setEof(true);
   1144             read = 0;
   1145         } else if (read > 0) {
   1146             env->GetByteArrayRegion(javaBytes.get(), 0, read, reinterpret_cast<jbyte*>(buf));
   1147         }
   1148 
   1149         return read;
   1150     }
   1151 
   1152 public:
   1153     /** Length of PEM-encoded line (64) plus CR plus NULL */
   1154     static const int PEM_LINE_LENGTH = 66;
   1155 };
   1156 
   1157 class BIO_OutputStream : public BIO_Stream {
   1158 public:
   1159     BIO_OutputStream(jobject stream) :
   1160             BIO_Stream(stream) {
   1161     }
   1162 
   1163     int write(const char *buf, int len) {
   1164         JNIEnv* env = getJNIEnv();
   1165         if (env == NULL) {
   1166             JNI_TRACE("BIO_OutputStream::write => could not get JNIEnv");
   1167             return -1;
   1168         }
   1169 
   1170         if (env->ExceptionCheck()) {
   1171             JNI_TRACE("BIO_OutputStream::write => called with pending exception");
   1172             return -1;
   1173         }
   1174 
   1175         ScopedLocalRef<jbyteArray> javaBytes(env, env->NewByteArray(len));
   1176         if (javaBytes.get() == NULL) {
   1177             JNI_TRACE("BIO_OutputStream::write => failed call to NewByteArray");
   1178             return -1;
   1179         }
   1180 
   1181         env->SetByteArrayRegion(javaBytes.get(), 0, len, reinterpret_cast<const jbyte*>(buf));
   1182 
   1183         env->CallVoidMethod(getStream(), outputStream_writeMethod, javaBytes.get());
   1184         if (env->ExceptionCheck()) {
   1185             JNI_TRACE("BIO_OutputStream::write => failed call to OutputStream#write");
   1186             return -1;
   1187         }
   1188 
   1189         return len;
   1190     }
   1191 };
   1192 
   1193 static int bio_stream_create(BIO *b) {
   1194     b->init = 1;
   1195     b->num = 0;
   1196     b->ptr = NULL;
   1197     b->flags = 0;
   1198     return 1;
   1199 }
   1200 
   1201 static int bio_stream_destroy(BIO *b) {
   1202     if (b == NULL) {
   1203         return 0;
   1204     }
   1205 
   1206     if (b->ptr != NULL) {
   1207         delete static_cast<BIO_Stream*>(b->ptr);
   1208         b->ptr = NULL;
   1209     }
   1210 
   1211     b->init = 0;
   1212     b->flags = 0;
   1213     return 1;
   1214 }
   1215 
   1216 static int bio_stream_read(BIO *b, char *buf, int len) {
   1217     BIO_clear_retry_flags(b);
   1218     BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
   1219     int ret = stream->read(buf, len);
   1220     if (ret == 0) {
   1221         // EOF is indicated by -1 with a BIO flag.
   1222         BIO_set_retry_read(b);
   1223         return -1;
   1224     }
   1225     return ret;
   1226 }
   1227 
   1228 static int bio_stream_write(BIO *b, const char *buf, int len) {
   1229     BIO_clear_retry_flags(b);
   1230     BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
   1231     return stream->write(buf, len);
   1232 }
   1233 
   1234 static int bio_stream_puts(BIO *b, const char *buf) {
   1235     BIO_OutputStream* stream = static_cast<BIO_OutputStream*>(b->ptr);
   1236     return stream->write(buf, strlen(buf));
   1237 }
   1238 
   1239 static int bio_stream_gets(BIO *b, char *buf, int len) {
   1240     BIO_InputStream* stream = static_cast<BIO_InputStream*>(b->ptr);
   1241     return stream->gets(buf, len);
   1242 }
   1243 
   1244 static void bio_stream_assign(BIO *b, BIO_Stream* stream) {
   1245     b->ptr = static_cast<void*>(stream);
   1246 }
   1247 
   1248 static long bio_stream_ctrl(BIO *b, int cmd, long, void *) {
   1249     BIO_Stream* stream = static_cast<BIO_Stream*>(b->ptr);
   1250 
   1251     switch (cmd) {
   1252     case BIO_CTRL_EOF:
   1253         return stream->isEof() ? 1 : 0;
   1254     case BIO_CTRL_FLUSH:
   1255         return stream->flush();
   1256     default:
   1257         return 0;
   1258     }
   1259 }
   1260 
   1261 static BIO_METHOD stream_bio_method = {
   1262         ( 100 | 0x0400 ), /* source/sink BIO */
   1263         "InputStream/OutputStream BIO",
   1264         bio_stream_write, /* bio_write */
   1265         bio_stream_read, /* bio_read */
   1266         bio_stream_puts, /* bio_puts */
   1267         bio_stream_gets, /* bio_gets */
   1268         bio_stream_ctrl, /* bio_ctrl */
   1269         bio_stream_create, /* bio_create */
   1270         bio_stream_destroy, /* bio_free */
   1271         NULL, /* no bio_callback_ctrl */
   1272 };
   1273 
   1274 static jbyteArray rawSignDigestWithPrivateKey(JNIEnv* env, jobject privateKey,
   1275         const char* message, size_t message_len) {
   1276     ScopedLocalRef<jbyteArray> messageArray(env, env->NewByteArray(message_len));
   1277     if (env->ExceptionCheck()) {
   1278         JNI_TRACE("rawSignDigestWithPrivateKey(%p) => threw exception", privateKey);
   1279         return NULL;
   1280     }
   1281 
   1282     {
   1283         ScopedByteArrayRW messageBytes(env, messageArray.get());
   1284         if (messageBytes.get() == NULL) {
   1285             JNI_TRACE("rawSignDigestWithPrivateKey(%p) => using byte array failed", privateKey);
   1286             return NULL;
   1287         }
   1288 
   1289         memcpy(messageBytes.get(), message, message_len);
   1290     }
   1291 
   1292     jmethodID rawSignMethod = env->GetStaticMethodID(cryptoUpcallsClass,
   1293             "rawSignDigestWithPrivateKey", "(Ljava/security/PrivateKey;[B)[B");
   1294     if (rawSignMethod == NULL) {
   1295         ALOGE("Could not find rawSignDigestWithPrivateKey");
   1296         return NULL;
   1297     }
   1298 
   1299     return reinterpret_cast<jbyteArray>(env->CallStaticObjectMethod(
   1300             cryptoUpcallsClass, rawSignMethod, privateKey, messageArray.get()));
   1301 }
   1302 
   1303 static jbyteArray rawCipherWithPrivateKey(JNIEnv* env, jobject privateKey, jboolean encrypt,
   1304         const char* ciphertext, size_t ciphertext_len) {
   1305     ScopedLocalRef<jbyteArray> ciphertextArray(env, env->NewByteArray(ciphertext_len));
   1306     if (env->ExceptionCheck()) {
   1307         JNI_TRACE("rawCipherWithPrivateKey(%p) => threw exception", privateKey);
   1308         return NULL;
   1309     }
   1310 
   1311     {
   1312         ScopedByteArrayRW ciphertextBytes(env, ciphertextArray.get());
   1313         if (ciphertextBytes.get() == NULL) {
   1314             JNI_TRACE("rawCipherWithPrivateKey(%p) => using byte array failed", privateKey);
   1315             return NULL;
   1316         }
   1317 
   1318         memcpy(ciphertextBytes.get(), ciphertext, ciphertext_len);
   1319     }
   1320 
   1321     jmethodID rawCipherMethod = env->GetStaticMethodID(cryptoUpcallsClass,
   1322             "rawCipherWithPrivateKey", "(Ljava/security/PrivateKey;Z[B)[B");
   1323     if (rawCipherMethod == NULL) {
   1324         ALOGE("Could not find rawCipherWithPrivateKey");
   1325         return NULL;
   1326     }
   1327 
   1328     return reinterpret_cast<jbyteArray>(env->CallStaticObjectMethod(
   1329             cryptoUpcallsClass, rawCipherMethod, privateKey, encrypt, ciphertextArray.get()));
   1330 }
   1331 
   1332 // *********************************************
   1333 // From keystore_openssl.cpp in Chromium source.
   1334 // *********************************************
   1335 
   1336 // Custom RSA_METHOD that uses the platform APIs.
   1337 // Note that for now, only signing through RSA_sign() is really supported.
   1338 // all other method pointers are either stubs returning errors, or no-ops.
   1339 // See <openssl/rsa.h> for exact declaration of RSA_METHOD.
   1340 
   1341 int RsaMethodPubEnc(int /* flen */,
   1342                     const unsigned char* /* from */,
   1343                     unsigned char* /* to */,
   1344                     RSA* /* rsa */,
   1345                     int /* padding */) {
   1346     RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
   1347     return -1;
   1348 }
   1349 
   1350 int RsaMethodPubDec(int flen,
   1351                     const unsigned char* from,
   1352                     unsigned char* to,
   1353                     RSA* rsa,
   1354                     int padding) {
   1355     RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED);
   1356     return -1;
   1357 }
   1358 
   1359 // See RSA_eay_private_encrypt in
   1360 // third_party/openssl/openssl/crypto/rsa/rsa_eay.c for the default
   1361 // implementation of this function.
   1362 int RsaMethodPrivEnc(int flen,
   1363                      const unsigned char *from,
   1364                      unsigned char *to,
   1365                      RSA *rsa,
   1366                      int padding) {
   1367     if (padding != RSA_PKCS1_PADDING) {
   1368         // TODO(davidben): If we need to, we can implement RSA_NO_PADDING
   1369         // by using javax.crypto.Cipher and picking either the
   1370         // "RSA/ECB/NoPadding" or "RSA/ECB/PKCS1Padding" transformation as
   1371         // appropriate. I believe support for both of these was added in
   1372         // the same Android version as the "NONEwithRSA"
   1373         // java.security.Signature algorithm, so the same version checks
   1374         // for GetRsaLegacyKey should work.
   1375         RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
   1376         return -1;
   1377     }
   1378 
   1379     // Retrieve private key JNI reference.
   1380     jobject private_key = reinterpret_cast<jobject>(RSA_get_app_data(rsa));
   1381     if (!private_key) {
   1382         ALOGE("Null JNI reference passed to RsaMethodPrivEnc!");
   1383         RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
   1384         return -1;
   1385     }
   1386 
   1387     JNIEnv* env = getJNIEnv();
   1388     if (env == NULL) {
   1389         return -1;
   1390     }
   1391 
   1392     // For RSA keys, this function behaves as RSA_private_encrypt with
   1393     // PKCS#1 padding.
   1394     ScopedLocalRef<jbyteArray> signature(
   1395             env, rawSignDigestWithPrivateKey(env, private_key,
   1396                                          reinterpret_cast<const char*>(from), flen));
   1397     if (signature.get() == NULL) {
   1398         ALOGE("Could not sign message in RsaMethodPrivEnc!");
   1399         RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
   1400         return -1;
   1401     }
   1402 
   1403     ScopedByteArrayRO signatureBytes(env, signature.get());
   1404     size_t expected_size = static_cast<size_t>(RSA_size(rsa));
   1405     if (signatureBytes.size() > expected_size) {
   1406         ALOGE("RSA Signature size mismatch, actual: %zd, expected <= %zd", signatureBytes.size(),
   1407               expected_size);
   1408         RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
   1409         return -1;
   1410     }
   1411 
   1412     // Copy result to OpenSSL-provided buffer. rawSignDigestWithPrivateKey
   1413     // should pad with leading 0s, but if it doesn't, pad the result.
   1414     size_t zero_pad = expected_size - signatureBytes.size();
   1415     memset(to, 0, zero_pad);
   1416     memcpy(to + zero_pad, signatureBytes.get(), signatureBytes.size());
   1417 
   1418     return expected_size;
   1419 }
   1420 
   1421 int RsaMethodPrivDec(int flen,
   1422                      const unsigned char* from,
   1423                      unsigned char* to,
   1424                      RSA* rsa,
   1425                      int padding) {
   1426     if (padding != RSA_PKCS1_PADDING) {
   1427         RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
   1428         return -1;
   1429     }
   1430 
   1431     // Retrieve private key JNI reference.
   1432     jobject private_key = reinterpret_cast<jobject>(RSA_get_app_data(rsa));
   1433     if (!private_key) {
   1434         ALOGE("Null JNI reference passed to RsaMethodPrivDec!");
   1435         RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
   1436         return -1;
   1437     }
   1438 
   1439     JNIEnv* env = getJNIEnv();
   1440     if (env == NULL) {
   1441         return -1;
   1442     }
   1443 
   1444     // For RSA keys, this function behaves as RSA_private_decrypt with
   1445     // PKCS#1 padding.
   1446     ScopedLocalRef<jbyteArray> cleartext(env, rawCipherWithPrivateKey(env, private_key, false,
   1447                                          reinterpret_cast<const char*>(from), flen));
   1448     if (cleartext.get() == NULL) {
   1449         ALOGE("Could not decrypt message in RsaMethodPrivDec!");
   1450         RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
   1451         return -1;
   1452     }
   1453 
   1454     ScopedByteArrayRO cleartextBytes(env, cleartext.get());
   1455     size_t expected_size = static_cast<size_t>(RSA_size(rsa));
   1456     if (cleartextBytes.size() > expected_size) {
   1457         ALOGE("RSA ciphertext size mismatch, actual: %zd, expected <= %zd", cleartextBytes.size(),
   1458               expected_size);
   1459         RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
   1460         return -1;
   1461     }
   1462 
   1463     // Copy result to OpenSSL-provided buffer.
   1464     memcpy(to, cleartextBytes.get(), cleartextBytes.size());
   1465 
   1466     return cleartextBytes.size();
   1467 }
   1468 
   1469 int RsaMethodInit(RSA*) {
   1470     return 0;
   1471 }
   1472 
   1473 int RsaMethodFinish(RSA* rsa) {
   1474     // Ensure the global JNI reference created with this wrapper is
   1475     // properly destroyed with it.
   1476     jobject key = reinterpret_cast<jobject>(RSA_get_app_data(rsa));
   1477     if (key != NULL) {
   1478         RSA_set_app_data(rsa, NULL);
   1479         JNIEnv* env = getJNIEnv();
   1480         env->DeleteGlobalRef(key);
   1481     }
   1482     // Actual return value is ignored by OpenSSL. There are no docs
   1483     // explaining what this is supposed to be.
   1484     return 0;
   1485 }
   1486 
   1487 const RSA_METHOD android_rsa_method = {
   1488         /* .name = */ "Android signing-only RSA method",
   1489         /* .rsa_pub_enc = */ RsaMethodPubEnc,
   1490         /* .rsa_pub_dec = */ RsaMethodPubDec,
   1491         /* .rsa_priv_enc = */ RsaMethodPrivEnc,
   1492         /* .rsa_priv_dec = */ RsaMethodPrivDec,
   1493         /* .rsa_mod_exp = */ NULL,
   1494         /* .bn_mod_exp = */ NULL,
   1495         /* .init = */ RsaMethodInit,
   1496         /* .finish = */ RsaMethodFinish,
   1497         // This flag is necessary to tell OpenSSL to avoid checking the content
   1498         // (i.e. internal fields) of the private key. Otherwise, it will complain
   1499         // it's not valid for the certificate.
   1500         /* .flags = */ RSA_METHOD_FLAG_NO_CHECK,
   1501         /* .app_data = */ NULL,
   1502         /* .rsa_sign = */ NULL,
   1503         /* .rsa_verify = */ NULL,
   1504         /* .rsa_keygen = */ NULL,
   1505 };
   1506 
   1507 // Custom DSA_METHOD that uses the platform APIs.
   1508 // Note that for now, only signing through DSA_sign() is really supported.
   1509 // all other method pointers are either stubs returning errors, or no-ops.
   1510 // See <openssl/dsa.h> for exact declaration of DSA_METHOD.
   1511 //
   1512 // Note: There is no DSA_set_app_data() and DSA_get_app_data() functions,
   1513 //       but RSA_set_app_data() is defined as a simple macro that calls
   1514 //       RSA_set_ex_data() with a hard-coded index of 0, so this code
   1515 //       does the same thing here.
   1516 
   1517 DSA_SIG* DsaMethodDoSign(const unsigned char* dgst,
   1518                          int dlen,
   1519                          DSA* dsa) {
   1520     // Extract the JNI reference to the PrivateKey object.
   1521     jobject private_key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0));
   1522     if (private_key == NULL) return NULL;
   1523 
   1524     JNIEnv* env = getJNIEnv();
   1525     if (env == NULL) {
   1526         return NULL;
   1527     }
   1528 
   1529     // Sign the message with it, calling platform APIs.
   1530     ScopedLocalRef<jbyteArray> signature(
   1531             env, rawSignDigestWithPrivateKey(env, private_key, reinterpret_cast<const char*>(dgst),
   1532                                              dlen));
   1533     if (signature.get() == NULL) {
   1534         ALOGE("Could not sign message in DsaMethodDoSign!");
   1535         return NULL;
   1536     }
   1537 
   1538     ScopedByteArrayRO signatureBytes(env, signature.get());
   1539     // Note: With DSA, the actual signature might be smaller than DSA_size().
   1540     size_t max_expected_size = static_cast<size_t>(DSA_size(dsa));
   1541     if (signatureBytes.size() > max_expected_size) {
   1542         ALOGE("DSA Signature size mismatch, actual: %zd, expected <= %zd", signatureBytes.size(),
   1543               max_expected_size);
   1544         return NULL;
   1545     }
   1546 
   1547     // Convert the signature into a DSA_SIG object.
   1548     const unsigned char* sigbuf = reinterpret_cast<const unsigned char*>(signatureBytes.get());
   1549     int siglen = static_cast<size_t>(signatureBytes.size());
   1550     DSA_SIG* dsa_sig = d2i_DSA_SIG(NULL, &sigbuf, siglen);
   1551     return dsa_sig;
   1552 }
   1553 
   1554 int DsaMethodSignSetup(DSA* /* dsa */,
   1555                        BN_CTX* /* ctx_in */,
   1556                        BIGNUM** /* kinvp */,
   1557                        BIGNUM** /* rp */,
   1558                        const unsigned char* /* dgst */,
   1559                        int /* dlen */) {
   1560     DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_INVALID_DIGEST_TYPE);
   1561     return -1;
   1562 }
   1563 
   1564 int DsaMethodDoVerify(const unsigned char* /* dgst */,
   1565                       int /* dgst_len */,
   1566                       DSA_SIG* /* sig */,
   1567                       DSA* /* dsa */) {
   1568     DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_INVALID_DIGEST_TYPE);
   1569     return -1;
   1570 }
   1571 
   1572 int DsaMethodFinish(DSA* dsa) {
   1573     // Free the global JNI reference that was created with this
   1574     // wrapper key.
   1575     jobject key = reinterpret_cast<jobject>(DSA_get_ex_data(dsa, 0));
   1576     if (key != NULL) {
   1577         DSA_set_ex_data(dsa, 0, NULL);
   1578         JNIEnv* env = getJNIEnv();
   1579         env->DeleteGlobalRef(key);
   1580     }
   1581     // Actual return value is ignored by OpenSSL. There are no docs
   1582     // explaining what this is supposed to be.
   1583     return 0;
   1584 }
   1585 
   1586 const DSA_METHOD android_dsa_method = {
   1587         /* .name = */ "Android signing-only DSA method",
   1588         /* .dsa_do_sign = */ DsaMethodDoSign,
   1589         /* .dsa_sign_setup = */ DsaMethodSignSetup,
   1590         /* .dsa_do_verify = */ DsaMethodDoVerify,
   1591         /* .dsa_mod_exp = */ NULL,
   1592         /* .bn_mod_exp = */ NULL,
   1593         /* .init = */ NULL,  // nothing to do here.
   1594         /* .finish = */ DsaMethodFinish,
   1595         /* .flags = */ 0,
   1596         /* .app_data = */ NULL,
   1597         /* .dsa_paramgem = */ NULL,
   1598         /* .dsa_keygen = */ NULL};
   1599 
   1600 // Used to ensure that the global JNI reference associated with a custom
   1601 // EC_KEY + ECDSA_METHOD wrapper is released when its EX_DATA is destroyed
   1602 // (this function is called when EVP_PKEY_free() is called on the wrapper).
   1603 void ExDataFree(void* /* parent */,
   1604                 void* ptr,
   1605                 CRYPTO_EX_DATA* ad,
   1606                 int idx,
   1607                 long /* argl */,
   1608                 void* /* argp */) {
   1609     jobject private_key = reinterpret_cast<jobject>(ptr);
   1610     if (private_key == NULL) return;
   1611 
   1612     CRYPTO_set_ex_data(ad, idx, NULL);
   1613     JNIEnv* env = getJNIEnv();
   1614     env->DeleteGlobalRef(private_key);
   1615 }
   1616 
   1617 int ExDataDup(CRYPTO_EX_DATA* /* to */,
   1618               CRYPTO_EX_DATA* /* from */,
   1619               void* /* from_d */,
   1620               int /* idx */,
   1621               long /* argl */,
   1622               void* /* argp */) {
   1623     // This callback shall never be called with the current OpenSSL
   1624     // implementation (the library only ever duplicates EX_DATA items
   1625     // for SSL and BIO objects). But provide this to catch regressions
   1626     // in the future.
   1627     // Return value is currently ignored by OpenSSL.
   1628     return 0;
   1629 }
   1630 
   1631 class EcdsaExDataIndex {
   1632   public:
   1633     int ex_data_index() { return ex_data_index_; }
   1634 
   1635     static EcdsaExDataIndex& Instance() {
   1636         static EcdsaExDataIndex singleton;
   1637         return singleton;
   1638     }
   1639 
   1640   private:
   1641     EcdsaExDataIndex() {
   1642         ex_data_index_ = ECDSA_get_ex_new_index(0, NULL, NULL, ExDataDup, ExDataFree);
   1643     }
   1644     EcdsaExDataIndex(EcdsaExDataIndex const&);
   1645     ~EcdsaExDataIndex() {}
   1646     EcdsaExDataIndex& operator=(EcdsaExDataIndex const&);
   1647 
   1648     int ex_data_index_;
   1649 };
   1650 
   1651 // Returns the index of the custom EX_DATA used to store the JNI reference.
   1652 int EcdsaGetExDataIndex(void) {
   1653     EcdsaExDataIndex& exData = EcdsaExDataIndex::Instance();
   1654     return exData.ex_data_index();
   1655 }
   1656 
   1657 ECDSA_SIG* EcdsaMethodDoSign(const unsigned char* dgst, int dgst_len, const BIGNUM* /* inv */,
   1658                              const BIGNUM* /* rp */, EC_KEY* eckey) {
   1659     // Retrieve private key JNI reference.
   1660     jobject private_key =
   1661             reinterpret_cast<jobject>(ECDSA_get_ex_data(eckey, EcdsaGetExDataIndex()));
   1662     if (!private_key) {
   1663         ALOGE("Null JNI reference passed to EcdsaMethodDoSign!");
   1664         return NULL;
   1665     }
   1666     JNIEnv* env = getJNIEnv();
   1667     if (env == NULL) {
   1668         return NULL;
   1669     }
   1670 
   1671     // Sign message with it through JNI.
   1672     ScopedLocalRef<jbyteArray> signature(
   1673             env, rawSignDigestWithPrivateKey(env, private_key, reinterpret_cast<const char*>(dgst),
   1674                                              dgst_len));
   1675     if (signature.get() == NULL) {
   1676         ALOGE("Could not sign message in EcdsaMethodDoSign!");
   1677         return NULL;
   1678     }
   1679 
   1680     ScopedByteArrayRO signatureBytes(env, signature.get());
   1681     // Note: With ECDSA, the actual signature may be smaller than
   1682     // ECDSA_size().
   1683     size_t max_expected_size = static_cast<size_t>(ECDSA_size(eckey));
   1684     if (signatureBytes.size() > max_expected_size) {
   1685         ALOGE("ECDSA Signature size mismatch, actual: %zd, expected <= %zd", signatureBytes.size(),
   1686               max_expected_size);
   1687         return NULL;
   1688     }
   1689 
   1690     // Convert signature to ECDSA_SIG object
   1691     const unsigned char* sigbuf = reinterpret_cast<const unsigned char*>(signatureBytes.get());
   1692     long siglen = static_cast<long>(signatureBytes.size());
   1693     return d2i_ECDSA_SIG(NULL, &sigbuf, siglen);
   1694 }
   1695 
   1696 int EcdsaMethodSignSetup(EC_KEY* /* eckey */,
   1697                          BN_CTX* /* ctx */,
   1698                          BIGNUM** /* kinv */,
   1699                          BIGNUM** /* r */,
   1700                          const unsigned char*,
   1701                          int) {
   1702     ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ECDSA_R_ERR_EC_LIB);
   1703     return -1;
   1704 }
   1705 
   1706 int EcdsaMethodDoVerify(const unsigned char* /* dgst */,
   1707                         int /* dgst_len */,
   1708                         const ECDSA_SIG* /* sig */,
   1709                         EC_KEY* /* eckey */) {
   1710     ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_ERR_EC_LIB);
   1711     return -1;
   1712 }
   1713 
   1714 const ECDSA_METHOD android_ecdsa_method = {
   1715         /* .name = */ "Android signing-only ECDSA method",
   1716         /* .ecdsa_do_sign = */ EcdsaMethodDoSign,
   1717         /* .ecdsa_sign_setup = */ EcdsaMethodSignSetup,
   1718         /* .ecdsa_do_verify = */ EcdsaMethodDoVerify,
   1719         /* .flags = */ 0,
   1720         /* .app_data = */ NULL,
   1721 };
   1722 
   1723 #ifdef CONSCRYPT_UNBUNDLED
   1724 /*
   1725  * This is a big hack; don't learn from this. Basically what happened is we do
   1726  * not have an API way to insert ourselves into the AsynchronousCloseMonitor
   1727  * that's compiled into the native libraries for libcore when we're unbundled.
   1728  * So we try to look up the symbol from the main library to find it.
   1729  */
   1730 typedef void (*acm_ctor_func)(void*, int);
   1731 typedef void (*acm_dtor_func)(void*);
   1732 static acm_ctor_func async_close_monitor_ctor = NULL;
   1733 static acm_dtor_func async_close_monitor_dtor = NULL;
   1734 
   1735 class CompatibilityCloseMonitor {
   1736 public:
   1737     CompatibilityCloseMonitor(int fd) {
   1738         if (async_close_monitor_ctor != NULL) {
   1739             async_close_monitor_ctor(objBuffer, fd);
   1740         }
   1741     }
   1742 
   1743     ~CompatibilityCloseMonitor() {
   1744         if (async_close_monitor_dtor != NULL) {
   1745             async_close_monitor_dtor(objBuffer);
   1746         }
   1747     }
   1748 private:
   1749     char objBuffer[256];
   1750 #if 0
   1751     static_assert(sizeof(objBuffer) > 2*sizeof(AsynchronousCloseMonitor),
   1752                   "CompatibilityCloseMonitor must be larger than the actual object");
   1753 #endif
   1754 };
   1755 
   1756 static void findAsynchronousCloseMonitorFuncs() {
   1757     void *lib = dlopen("libjavacore.so", RTLD_NOW);
   1758     if (lib != NULL) {
   1759         async_close_monitor_ctor = (acm_ctor_func) dlsym(lib, "_ZN24AsynchronousCloseMonitorC1Ei");
   1760         async_close_monitor_dtor = (acm_dtor_func) dlsym(lib, "_ZN24AsynchronousCloseMonitorD1Ev");
   1761     }
   1762 }
   1763 #endif
   1764 
   1765 /**
   1766  * Copied from libnativehelper NetworkUtilites.cpp
   1767  */
   1768 static bool setBlocking(int fd, bool blocking) {
   1769     int flags = fcntl(fd, F_GETFL);
   1770     if (flags == -1) {
   1771         return false;
   1772     }
   1773 
   1774     if (!blocking) {
   1775         flags |= O_NONBLOCK;
   1776     } else {
   1777         flags &= ~O_NONBLOCK;
   1778     }
   1779 
   1780     int rc = fcntl(fd, F_SETFL, flags);
   1781     return (rc != -1);
   1782 }
   1783 
   1784 /**
   1785  * OpenSSL locking support. Taken from the O'Reilly book by Viega et al., but I
   1786  * suppose there are not many other ways to do this on a Linux system (modulo
   1787  * isomorphism).
   1788  */
   1789 #define MUTEX_TYPE pthread_mutex_t
   1790 #define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
   1791 #define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
   1792 #define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
   1793 #define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
   1794 #define THREAD_ID pthread_self()
   1795 #define THROW_SSLEXCEPTION (-2)
   1796 #define THROW_SOCKETTIMEOUTEXCEPTION (-3)
   1797 #define THROWN_EXCEPTION (-4)
   1798 
   1799 static MUTEX_TYPE* mutex_buf = NULL;
   1800 
   1801 static void locking_function(int mode, int n, const char*, int) {
   1802     if (mode & CRYPTO_LOCK) {
   1803         MUTEX_LOCK(mutex_buf[n]);
   1804     } else {
   1805         MUTEX_UNLOCK(mutex_buf[n]);
   1806     }
   1807 }
   1808 
   1809 static unsigned long id_function(void) {
   1810     return ((unsigned long)THREAD_ID);
   1811 }
   1812 
   1813 int THREAD_setup(void) {
   1814     mutex_buf = new MUTEX_TYPE[CRYPTO_num_locks()];
   1815     if (!mutex_buf) {
   1816         return 0;
   1817     }
   1818 
   1819     for (int i = 0; i < CRYPTO_num_locks(); ++i) {
   1820         MUTEX_SETUP(mutex_buf[i]);
   1821     }
   1822 
   1823     CRYPTO_set_id_callback(id_function);
   1824     CRYPTO_set_locking_callback(locking_function);
   1825 
   1826     return 1;
   1827 }
   1828 
   1829 int THREAD_cleanup(void) {
   1830     if (!mutex_buf) {
   1831         return 0;
   1832     }
   1833 
   1834     CRYPTO_set_id_callback(NULL);
   1835     CRYPTO_set_locking_callback(NULL);
   1836 
   1837     for (int i = 0; i < CRYPTO_num_locks( ); i++) {
   1838         MUTEX_CLEANUP(mutex_buf[i]);
   1839     }
   1840 
   1841     free(mutex_buf);
   1842     mutex_buf = NULL;
   1843 
   1844     return 1;
   1845 }
   1846 
   1847 /**
   1848  * Initialization phase for every OpenSSL job: Loads the Error strings, the
   1849  * crypto algorithms and reset the OpenSSL library
   1850  */
   1851 static void NativeCrypto_clinit(JNIEnv*, jclass)
   1852 {
   1853     SSL_load_error_strings();
   1854     ERR_load_crypto_strings();
   1855     SSL_library_init();
   1856     OpenSSL_add_all_algorithms();
   1857     THREAD_setup();
   1858 }
   1859 
   1860 static void NativeCrypto_ENGINE_load_dynamic(JNIEnv*, jclass) {
   1861     JNI_TRACE("ENGINE_load_dynamic()");
   1862 
   1863     ENGINE_load_dynamic();
   1864 }
   1865 
   1866 static jlong NativeCrypto_ENGINE_by_id(JNIEnv* env, jclass, jstring idJava) {
   1867     JNI_TRACE("ENGINE_by_id(%p)", idJava);
   1868 
   1869     ScopedUtfChars id(env, idJava);
   1870     if (id.c_str() == NULL) {
   1871         JNI_TRACE("ENGINE_by_id(%p) => id == null", idJava);
   1872         return 0;
   1873     }
   1874     JNI_TRACE("ENGINE_by_id(\"%s\")", id.c_str());
   1875 
   1876     ENGINE* e = ENGINE_by_id(id.c_str());
   1877     if (e == NULL) {
   1878         freeOpenSslErrorState();
   1879     }
   1880 
   1881     JNI_TRACE("ENGINE_by_id(\"%s\") => %p", id.c_str(), e);
   1882     return reinterpret_cast<uintptr_t>(e);
   1883 }
   1884 
   1885 static jint NativeCrypto_ENGINE_add(JNIEnv* env, jclass, jlong engineRef) {
   1886     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1887     JNI_TRACE("ENGINE_add(%p)", e);
   1888 
   1889     if (e == NULL) {
   1890         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
   1891         return 0;
   1892     }
   1893 
   1894     int ret = ENGINE_add(e);
   1895 
   1896     /*
   1897      * We tolerate errors, because the most likely error is that
   1898      * the ENGINE is already in the list.
   1899      */
   1900     freeOpenSslErrorState();
   1901 
   1902     JNI_TRACE("ENGINE_add(%p) => %d", e, ret);
   1903     return ret;
   1904 }
   1905 
   1906 static jint NativeCrypto_ENGINE_init(JNIEnv* env, jclass, jlong engineRef) {
   1907     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1908     JNI_TRACE("ENGINE_init(%p)", e);
   1909 
   1910     if (e == NULL) {
   1911         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
   1912         return 0;
   1913     }
   1914 
   1915     int ret = ENGINE_init(e);
   1916     JNI_TRACE("ENGINE_init(%p) => %d", e, ret);
   1917     return ret;
   1918 }
   1919 
   1920 static jint NativeCrypto_ENGINE_finish(JNIEnv* env, jclass, jlong engineRef) {
   1921     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1922     JNI_TRACE("ENGINE_finish(%p)", e);
   1923 
   1924     if (e == NULL) {
   1925         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
   1926         return 0;
   1927     }
   1928 
   1929     int ret = ENGINE_finish(e);
   1930     JNI_TRACE("ENGINE_finish(%p) => %d", e, ret);
   1931     return ret;
   1932 }
   1933 
   1934 static jint NativeCrypto_ENGINE_free(JNIEnv* env, jclass, jlong engineRef) {
   1935     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1936     JNI_TRACE("ENGINE_free(%p)", e);
   1937 
   1938     if (e == NULL) {
   1939         jniThrowException(env, "java/lang/IllegalArgumentException", "engineRef == 0");
   1940         return 0;
   1941     }
   1942 
   1943     int ret = ENGINE_free(e);
   1944     JNI_TRACE("ENGINE_free(%p) => %d", e, ret);
   1945     return ret;
   1946 }
   1947 
   1948 static jlong NativeCrypto_ENGINE_load_private_key(JNIEnv* env, jclass, jlong engineRef,
   1949         jstring idJava) {
   1950     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1951     JNI_TRACE("ENGINE_load_private_key(%p, %p)", e, idJava);
   1952 
   1953     ScopedUtfChars id(env, idJava);
   1954     if (id.c_str() == NULL) {
   1955         jniThrowException(env, "java/lang/IllegalArgumentException", "id == NULL");
   1956         return 0;
   1957     }
   1958 
   1959     Unique_EVP_PKEY pkey(ENGINE_load_private_key(e, id.c_str(), NULL, NULL));
   1960     if (pkey.get() == NULL) {
   1961         throwExceptionIfNecessary(env, "ENGINE_load_private_key");
   1962         return 0;
   1963     }
   1964 
   1965     JNI_TRACE("ENGINE_load_private_key(%p, %p) => %p", e, idJava, pkey.get());
   1966     return reinterpret_cast<uintptr_t>(pkey.release());
   1967 }
   1968 
   1969 static jstring NativeCrypto_ENGINE_get_id(JNIEnv* env, jclass, jlong engineRef)
   1970 {
   1971     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1972     JNI_TRACE("ENGINE_get_id(%p)", e);
   1973 
   1974     if (e == NULL) {
   1975         jniThrowNullPointerException(env, "engine == null");
   1976         JNI_TRACE("ENGINE_get_id(%p) => engine == null", e);
   1977         return NULL;
   1978     }
   1979 
   1980     const char *id = ENGINE_get_id(e);
   1981     ScopedLocalRef<jstring> idJava(env, env->NewStringUTF(id));
   1982 
   1983     JNI_TRACE("ENGINE_get_id(%p) => \"%s\"", e, id);
   1984     return idJava.release();
   1985 }
   1986 
   1987 static jint NativeCrypto_ENGINE_ctrl_cmd_string(JNIEnv* env, jclass, jlong engineRef,
   1988         jstring cmdJava, jstring argJava, jint cmd_optional)
   1989 {
   1990     ENGINE* e = reinterpret_cast<ENGINE*>(static_cast<uintptr_t>(engineRef));
   1991     JNI_TRACE("ENGINE_ctrl_cmd_string(%p, %p, %p, %d)", e, cmdJava, argJava, cmd_optional);
   1992 
   1993     if (e == NULL) {
   1994         jniThrowNullPointerException(env, "engine == null");
   1995         JNI_TRACE("ENGINE_ctrl_cmd_string(%p, %p, %p, %d) => engine == null", e, cmdJava, argJava,
   1996                 cmd_optional);
   1997         return 0;
   1998     }
   1999 
   2000     ScopedUtfChars cmdChars(env, cmdJava);
   2001     if (cmdChars.c_str() == NULL) {
   2002         return 0;
   2003     }
   2004 
   2005     UniquePtr<ScopedUtfChars> arg;
   2006     const char* arg_c_str = NULL;
   2007     if (argJava != NULL) {
   2008         arg.reset(new ScopedUtfChars(env, argJava));
   2009         arg_c_str = arg->c_str();
   2010         if (arg_c_str == NULL) {
   2011             return 0;
   2012         }
   2013     }
   2014     JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d)", e, cmdChars.c_str(), arg_c_str,
   2015             cmd_optional);
   2016 
   2017     int ret = ENGINE_ctrl_cmd_string(e, cmdChars.c_str(), arg_c_str, cmd_optional);
   2018     if (ret != 1) {
   2019         throwExceptionIfNecessary(env, "ENGINE_ctrl_cmd_string");
   2020         JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d) => threw error", e,
   2021                 cmdChars.c_str(), arg_c_str, cmd_optional);
   2022         return 0;
   2023     }
   2024 
   2025     JNI_TRACE("ENGINE_ctrl_cmd_string(%p, \"%s\", \"%s\", %d) => %d", e, cmdChars.c_str(),
   2026             arg_c_str, cmd_optional, ret);
   2027     return ret;
   2028 }
   2029 
   2030 static jlong NativeCrypto_EVP_PKEY_new_DH(JNIEnv* env, jclass,
   2031                                                jbyteArray p, jbyteArray g,
   2032                                                jbyteArray pub_key, jbyteArray priv_key) {
   2033     JNI_TRACE("EVP_PKEY_new_DH(p=%p, g=%p, pub_key=%p, priv_key=%p)",
   2034               p, g, pub_key, priv_key);
   2035 
   2036     Unique_DH dh(DH_new());
   2037     if (dh.get() == NULL) {
   2038         jniThrowRuntimeException(env, "DH_new failed");
   2039         return 0;
   2040     }
   2041 
   2042     if (!arrayToBignum(env, p, &dh->p)) {
   2043         return 0;
   2044     }
   2045 
   2046     if (!arrayToBignum(env, g, &dh->g)) {
   2047         return 0;
   2048     }
   2049 
   2050     if (pub_key != NULL && !arrayToBignum(env, pub_key, &dh->pub_key)) {
   2051         return 0;
   2052     }
   2053 
   2054     if (priv_key != NULL && !arrayToBignum(env, priv_key, &dh->priv_key)) {
   2055         return 0;
   2056     }
   2057 
   2058     if (dh->p == NULL || dh->g == NULL
   2059             || (pub_key != NULL && dh->pub_key == NULL)
   2060             || (priv_key != NULL && dh->priv_key == NULL)) {
   2061         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
   2062         return 0;
   2063     }
   2064 
   2065     /* The public key can be recovered if the private key is available. */
   2066     if (dh->pub_key == NULL && dh->priv_key != NULL) {
   2067         if (!DH_generate_key(dh.get())) {
   2068             jniThrowRuntimeException(env, "EVP_PKEY_new_DH failed during pub_key generation");
   2069             return 0;
   2070         }
   2071     }
   2072 
   2073     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2074     if (pkey.get() == NULL) {
   2075         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
   2076         return 0;
   2077     }
   2078     if (EVP_PKEY_assign_DH(pkey.get(), dh.get()) != 1) {
   2079         jniThrowRuntimeException(env, "EVP_PKEY_assign_DH failed");
   2080         return 0;
   2081     }
   2082     OWNERSHIP_TRANSFERRED(dh);
   2083     JNI_TRACE("EVP_PKEY_new_DH(p=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
   2084               p, g, pub_key, priv_key, pkey.get());
   2085     return reinterpret_cast<jlong>(pkey.release());
   2086 }
   2087 
   2088 /**
   2089  * public static native int EVP_PKEY_new_DSA(byte[] p, byte[] q, byte[] g,
   2090  *                                           byte[] pub_key, byte[] priv_key);
   2091  */
   2092 static jlong NativeCrypto_EVP_PKEY_new_DSA(JNIEnv* env, jclass,
   2093                                                jbyteArray p, jbyteArray q, jbyteArray g,
   2094                                                jbyteArray pub_key, jbyteArray priv_key) {
   2095     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p)",
   2096               p, q, g, pub_key, priv_key);
   2097 
   2098     Unique_DSA dsa(DSA_new());
   2099     if (dsa.get() == NULL) {
   2100         jniThrowRuntimeException(env, "DSA_new failed");
   2101         return 0;
   2102     }
   2103 
   2104     if (!arrayToBignum(env, p, &dsa->p)) {
   2105         return 0;
   2106     }
   2107 
   2108     if (!arrayToBignum(env, q, &dsa->q)) {
   2109         return 0;
   2110     }
   2111 
   2112     if (!arrayToBignum(env, g, &dsa->g)) {
   2113         return 0;
   2114     }
   2115 
   2116     if (pub_key != NULL && !arrayToBignum(env, pub_key, &dsa->pub_key)) {
   2117         return 0;
   2118     }
   2119 
   2120     if (priv_key != NULL && !arrayToBignum(env, priv_key, &dsa->priv_key)) {
   2121         return 0;
   2122     }
   2123 
   2124     if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL
   2125             || (dsa->pub_key == NULL && dsa->priv_key == NULL)) {
   2126         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
   2127         return 0;
   2128     }
   2129 
   2130     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2131     if (pkey.get() == NULL) {
   2132         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
   2133         return 0;
   2134     }
   2135     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
   2136         jniThrowRuntimeException(env, "EVP_PKEY_assign_DSA failed");
   2137         return 0;
   2138     }
   2139     OWNERSHIP_TRANSFERRED(dsa);
   2140     JNI_TRACE("EVP_PKEY_new_DSA(p=%p, q=%p, g=%p, pub_key=%p, priv_key=%p) => %p",
   2141               p, q, g, pub_key, priv_key, pkey.get());
   2142     return reinterpret_cast<jlong>(pkey.release());
   2143 }
   2144 
   2145 /**
   2146  * private static native int EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q);
   2147  */
   2148 static jlong NativeCrypto_EVP_PKEY_new_RSA(JNIEnv* env, jclass,
   2149                                                jbyteArray n, jbyteArray e, jbyteArray d,
   2150                                                jbyteArray p, jbyteArray q,
   2151                                                jbyteArray dmp1, jbyteArray dmq1,
   2152                                                jbyteArray iqmp) {
   2153     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p, dmp1=%p, dmq1=%p, iqmp=%p)",
   2154             n, e, d, p, q, dmp1, dmq1, iqmp);
   2155 
   2156     Unique_RSA rsa(RSA_new());
   2157     if (rsa.get() == NULL) {
   2158         jniThrowRuntimeException(env, "RSA_new failed");
   2159         return 0;
   2160     }
   2161 
   2162     if (e == NULL && d == NULL) {
   2163         jniThrowException(env, "java/lang/IllegalArgumentException", "e == NULL && d == NULL");
   2164         JNI_TRACE("NativeCrypto_EVP_PKEY_new_RSA => e == NULL && d == NULL");
   2165         return 0;
   2166     }
   2167 
   2168     if (!arrayToBignum(env, n, &rsa->n)) {
   2169         return 0;
   2170     }
   2171 
   2172     if (e != NULL && !arrayToBignum(env, e, &rsa->e)) {
   2173         return 0;
   2174     }
   2175 
   2176     if (d != NULL && !arrayToBignum(env, d, &rsa->d)) {
   2177         return 0;
   2178     }
   2179 
   2180     if (p != NULL && !arrayToBignum(env, p, &rsa->p)) {
   2181         return 0;
   2182     }
   2183 
   2184     if (q != NULL && !arrayToBignum(env, q, &rsa->q)) {
   2185         return 0;
   2186     }
   2187 
   2188     if (dmp1 != NULL && !arrayToBignum(env, dmp1, &rsa->dmp1)) {
   2189         return 0;
   2190     }
   2191 
   2192     if (dmq1 != NULL && !arrayToBignum(env, dmq1, &rsa->dmq1)) {
   2193         return 0;
   2194     }
   2195 
   2196     if (iqmp != NULL && !arrayToBignum(env, iqmp, &rsa->iqmp)) {
   2197         return 0;
   2198     }
   2199 
   2200 #ifdef WITH_JNI_TRACE
   2201     if (p != NULL && q != NULL) {
   2202         int check = RSA_check_key(rsa.get());
   2203         JNI_TRACE("EVP_PKEY_new_RSA(...) RSA_check_key returns %d", check);
   2204     }
   2205 #endif
   2206 
   2207     if (rsa->n == NULL || (rsa->e == NULL && rsa->d == NULL)) {
   2208         jniThrowRuntimeException(env, "Unable to convert BigInteger to BIGNUM");
   2209         return 0;
   2210     }
   2211 
   2212     /*
   2213      * If the private exponent is available, there is the potential to do signing
   2214      * operations. If the public exponent is also available, OpenSSL will do RSA
   2215      * blinding. Enable it if possible.
   2216      */
   2217     if (rsa->d != NULL) {
   2218         if (rsa->e != NULL) {
   2219             JNI_TRACE("EVP_PKEY_new_RSA(...) enabling RSA blinding => %p", rsa.get());
   2220             RSA_blinding_on(rsa.get(), NULL);
   2221         } else {
   2222             JNI_TRACE("EVP_PKEY_new_RSA(...) disabling RSA blinding => %p", rsa.get());
   2223             RSA_blinding_off(rsa.get());
   2224         }
   2225     }
   2226 
   2227     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2228     if (pkey.get() == NULL) {
   2229         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
   2230         return 0;
   2231     }
   2232     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
   2233         jniThrowRuntimeException(env, "EVP_PKEY_new failed");
   2234         return 0;
   2235     }
   2236     OWNERSHIP_TRANSFERRED(rsa);
   2237     JNI_TRACE("EVP_PKEY_new_RSA(n=%p, e=%p, d=%p, p=%p, q=%p dmp1=%p, dmq1=%p, iqmp=%p) => %p",
   2238             n, e, d, p, q, dmp1, dmq1, iqmp, pkey.get());
   2239     return reinterpret_cast<uintptr_t>(pkey.release());
   2240 }
   2241 
   2242 static jlong NativeCrypto_EVP_PKEY_new_EC_KEY(JNIEnv* env, jclass, jlong groupRef,
   2243         jlong pubkeyRef, jbyteArray keyJavaBytes) {
   2244     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   2245     const EC_POINT* pubkey = reinterpret_cast<const EC_POINT*>(pubkeyRef);
   2246     JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p)", group, pubkey, keyJavaBytes);
   2247 
   2248     Unique_BIGNUM key(NULL);
   2249     if (keyJavaBytes != NULL) {
   2250         BIGNUM* keyRef = NULL;
   2251         if (!arrayToBignum(env, keyJavaBytes, &keyRef)) {
   2252             return 0;
   2253         }
   2254         key.reset(keyRef);
   2255     }
   2256 
   2257     Unique_EC_KEY eckey(EC_KEY_new());
   2258     if (eckey.get() == NULL) {
   2259         jniThrowRuntimeException(env, "EC_KEY_new failed");
   2260         return 0;
   2261     }
   2262 
   2263     if (EC_KEY_set_group(eckey.get(), group) != 1) {
   2264         JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) > EC_KEY_set_group failed", group, pubkey,
   2265                 keyJavaBytes);
   2266         throwExceptionIfNecessary(env, "EC_KEY_set_group");
   2267         return 0;
   2268     }
   2269 
   2270     if (pubkey != NULL) {
   2271         if (EC_KEY_set_public_key(eckey.get(), pubkey) != 1) {
   2272             JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => EC_KEY_set_private_key failed", group,
   2273                     pubkey, keyJavaBytes);
   2274             throwExceptionIfNecessary(env, "EC_KEY_set_public_key");
   2275             return 0;
   2276         }
   2277     }
   2278 
   2279     if (key.get() != NULL) {
   2280         if (EC_KEY_set_private_key(eckey.get(), key.get()) != 1) {
   2281             JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => EC_KEY_set_private_key failed", group,
   2282                     pubkey, keyJavaBytes);
   2283             throwExceptionIfNecessary(env, "EC_KEY_set_private_key");
   2284             return 0;
   2285         }
   2286         if (pubkey == NULL) {
   2287             Unique_EC_POINT calcPubkey(EC_POINT_new(group));
   2288             if (!EC_POINT_mul(group, calcPubkey.get(), key.get(), NULL, NULL, NULL)) {
   2289                 JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => can't calulate public key", group,
   2290                         pubkey, keyJavaBytes);
   2291                 throwExceptionIfNecessary(env, "EC_KEY_set_private_key");
   2292                 return 0;
   2293             }
   2294             EC_KEY_set_public_key(eckey.get(), calcPubkey.get());
   2295         }
   2296     }
   2297 
   2298     if (!EC_KEY_check_key(eckey.get())) {
   2299         JNI_TRACE("EVP_KEY_new_EC_KEY(%p, %p, %p) => invalid key created", group, pubkey, keyJavaBytes);
   2300         throwExceptionIfNecessary(env, "EC_KEY_check_key");
   2301         return 0;
   2302     }
   2303 
   2304     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2305     if (pkey.get() == NULL) {
   2306         JNI_TRACE("EVP_PKEY_new_EC(%p, %p, %p) => threw error", group, pubkey, keyJavaBytes);
   2307         throwExceptionIfNecessary(env, "EVP_PKEY_new failed");
   2308         return 0;
   2309     }
   2310     if (EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()) != 1) {
   2311         JNI_TRACE("EVP_PKEY_new_EC(%p, %p, %p) => threw error", group, pubkey, keyJavaBytes);
   2312         jniThrowRuntimeException(env, "EVP_PKEY_assign_EC_KEY failed");
   2313         return 0;
   2314     }
   2315     OWNERSHIP_TRANSFERRED(eckey);
   2316 
   2317     JNI_TRACE("EVP_PKEY_new_EC_KEY(%p, %p, %p) => %p", group, pubkey, keyJavaBytes, pkey.get());
   2318     return reinterpret_cast<uintptr_t>(pkey.release());
   2319 }
   2320 
   2321 static jlong NativeCrypto_EVP_PKEY_new_mac_key(JNIEnv* env, jclass, jint pkeyType,
   2322         jbyteArray keyJavaBytes)
   2323 {
   2324     JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p)", pkeyType, keyJavaBytes);
   2325 
   2326     ScopedByteArrayRO key(env, keyJavaBytes);
   2327     if (key.get() == NULL) {
   2328         return 0;
   2329     }
   2330 
   2331     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(key.get());
   2332     Unique_EVP_PKEY pkey(EVP_PKEY_new_mac_key(pkeyType, (ENGINE *) NULL, tmp, key.size()));
   2333     if (pkey.get() == NULL) {
   2334         JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => threw error", pkeyType, keyJavaBytes);
   2335         throwExceptionIfNecessary(env, "ENGINE_load_private_key");
   2336         return 0;
   2337     }
   2338 
   2339     JNI_TRACE("EVP_PKEY_new_mac_key(%d, %p) => %p", pkeyType, keyJavaBytes, pkey.get());
   2340     return reinterpret_cast<uintptr_t>(pkey.release());
   2341 }
   2342 
   2343 static int NativeCrypto_EVP_PKEY_type(JNIEnv* env, jclass, jlong pkeyRef) {
   2344     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2345     JNI_TRACE("EVP_PKEY_type(%p)", pkey);
   2346 
   2347     if (pkey == NULL) {
   2348         jniThrowNullPointerException(env, NULL);
   2349         return -1;
   2350     }
   2351 
   2352     int result = EVP_PKEY_type(pkey->type);
   2353     JNI_TRACE("EVP_PKEY_type(%p) => %d", pkey, result);
   2354     return result;
   2355 }
   2356 
   2357 /**
   2358  * private static native int EVP_PKEY_size(int pkey);
   2359  */
   2360 static int NativeCrypto_EVP_PKEY_size(JNIEnv* env, jclass, jlong pkeyRef) {
   2361     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2362     JNI_TRACE("EVP_PKEY_size(%p)", pkey);
   2363 
   2364     if (pkey == NULL) {
   2365         jniThrowNullPointerException(env, NULL);
   2366         return -1;
   2367     }
   2368 
   2369     int result = EVP_PKEY_size(pkey);
   2370     JNI_TRACE("EVP_PKEY_size(%p) => %d", pkey, result);
   2371     return result;
   2372 }
   2373 
   2374 static jstring NativeCrypto_EVP_PKEY_print_public(JNIEnv* env, jclass, jlong pkeyRef) {
   2375     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2376     JNI_TRACE("EVP_PKEY_print_public(%p)", pkey);
   2377 
   2378     if (pkey == NULL) {
   2379         jniThrowNullPointerException(env, "pkey == null");
   2380         return NULL;
   2381     }
   2382 
   2383     Unique_BIO buffer(BIO_new(BIO_s_mem()));
   2384     if (buffer.get() == NULL) {
   2385         jniThrowOutOfMemory(env, "Unable to allocate BIO");
   2386         return NULL;
   2387     }
   2388 
   2389     if (EVP_PKEY_print_public(buffer.get(), pkey, 0, (ASN1_PCTX*) NULL) != 1) {
   2390         throwExceptionIfNecessary(env, "EVP_PKEY_print_public");
   2391         return NULL;
   2392     }
   2393     // Null terminate this
   2394     BIO_write(buffer.get(), "\0", 1);
   2395 
   2396     char *tmp;
   2397     BIO_get_mem_data(buffer.get(), &tmp);
   2398     jstring description = env->NewStringUTF(tmp);
   2399 
   2400     JNI_TRACE("EVP_PKEY_print_public(%p) => \"%s\"", pkey, tmp);
   2401     return description;
   2402 }
   2403 
   2404 static jstring NativeCrypto_EVP_PKEY_print_private(JNIEnv* env, jclass, jlong pkeyRef) {
   2405     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2406     JNI_TRACE("EVP_PKEY_print_private(%p)", pkey);
   2407 
   2408     if (pkey == NULL) {
   2409         jniThrowNullPointerException(env, "pkey == null");
   2410         return NULL;
   2411     }
   2412 
   2413     Unique_BIO buffer(BIO_new(BIO_s_mem()));
   2414     if (buffer.get() == NULL) {
   2415         jniThrowOutOfMemory(env, "Unable to allocate BIO");
   2416         return NULL;
   2417     }
   2418 
   2419     if (EVP_PKEY_print_private(buffer.get(), pkey, 0, (ASN1_PCTX*) NULL) != 1) {
   2420         throwExceptionIfNecessary(env, "EVP_PKEY_print_private");
   2421         return NULL;
   2422     }
   2423     // Null terminate this
   2424     BIO_write(buffer.get(), "\0", 1);
   2425 
   2426     char *tmp;
   2427     BIO_get_mem_data(buffer.get(), &tmp);
   2428     jstring description = env->NewStringUTF(tmp);
   2429 
   2430     JNI_TRACE("EVP_PKEY_print_private(%p) => \"%s\"", pkey, tmp);
   2431     return description;
   2432 }
   2433 
   2434 static void NativeCrypto_EVP_PKEY_free(JNIEnv*, jclass, jlong pkeyRef) {
   2435     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2436     JNI_TRACE("EVP_PKEY_free(%p)", pkey);
   2437 
   2438     if (pkey != NULL) {
   2439         EVP_PKEY_free(pkey);
   2440     }
   2441 }
   2442 
   2443 static jint NativeCrypto_EVP_PKEY_cmp(JNIEnv* env, jclass, jlong pkey1Ref, jlong pkey2Ref) {
   2444     EVP_PKEY* pkey1 = reinterpret_cast<EVP_PKEY*>(pkey1Ref);
   2445     EVP_PKEY* pkey2 = reinterpret_cast<EVP_PKEY*>(pkey2Ref);
   2446     JNI_TRACE("EVP_PKEY_cmp(%p, %p)", pkey1, pkey2);
   2447 
   2448     if (pkey1 == NULL) {
   2449         JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey1 == NULL", pkey1, pkey2);
   2450         jniThrowNullPointerException(env, "pkey1 == NULL");
   2451         return -1;
   2452     } else if (pkey2 == NULL) {
   2453         JNI_TRACE("EVP_PKEY_cmp(%p, %p) => failed pkey2 == NULL", pkey1, pkey2);
   2454         jniThrowNullPointerException(env, "pkey2 == NULL");
   2455         return -1;
   2456     }
   2457 
   2458     int result = EVP_PKEY_cmp(pkey1, pkey2);
   2459     JNI_TRACE("EVP_PKEY_cmp(%p, %p) => %d", pkey1, pkey2, result);
   2460     return result;
   2461 }
   2462 
   2463 /*
   2464  * static native byte[] i2d_PKCS8_PRIV_KEY_INFO(int, byte[])
   2465  */
   2466 static jbyteArray NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jlong pkeyRef) {
   2467     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2468     JNI_TRACE("i2d_PKCS8_PRIV_KEY_INFO(%p)", pkey);
   2469 
   2470     if (pkey == NULL) {
   2471         jniThrowNullPointerException(env, NULL);
   2472         return NULL;
   2473     }
   2474 
   2475     Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey));
   2476     if (pkcs8.get() == NULL) {
   2477         throwExceptionIfNecessary(env, "NativeCrypto_i2d_PKCS8_PRIV_KEY_INFO");
   2478         JNI_TRACE("key=%p i2d_PKCS8_PRIV_KEY_INFO => error from key to PKCS8", pkey);
   2479         return NULL;
   2480     }
   2481 
   2482     return ASN1ToByteArray<PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO>(env, pkcs8.get());
   2483 }
   2484 
   2485 /*
   2486  * static native int d2i_PKCS8_PRIV_KEY_INFO(byte[])
   2487  */
   2488 static jlong NativeCrypto_d2i_PKCS8_PRIV_KEY_INFO(JNIEnv* env, jclass, jbyteArray keyJavaBytes) {
   2489     JNI_TRACE("d2i_PKCS8_PRIV_KEY_INFO(%p)", keyJavaBytes);
   2490 
   2491     ScopedByteArrayRO bytes(env, keyJavaBytes);
   2492     if (bytes.get() == NULL) {
   2493         JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => threw exception", keyJavaBytes);
   2494         return 0;
   2495     }
   2496 
   2497     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
   2498     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &tmp, bytes.size()));
   2499     if (pkcs8.get() == NULL) {
   2500         throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
   2501         JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from DER to PKCS8", keyJavaBytes);
   2502         return 0;
   2503     }
   2504 
   2505     Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
   2506     if (pkey.get() == NULL) {
   2507         throwExceptionIfNecessary(env, "d2i_PKCS8_PRIV_KEY_INFO");
   2508         JNI_TRACE("ssl=%p d2i_PKCS8_PRIV_KEY_INFO => error from PKCS8 to key", keyJavaBytes);
   2509         return 0;
   2510     }
   2511 
   2512     JNI_TRACE("bytes=%p d2i_PKCS8_PRIV_KEY_INFO => %p", keyJavaBytes, pkey.get());
   2513     return reinterpret_cast<uintptr_t>(pkey.release());
   2514 }
   2515 
   2516 /*
   2517  * static native byte[] i2d_PUBKEY(int)
   2518  */
   2519 static jbyteArray NativeCrypto_i2d_PUBKEY(JNIEnv* env, jclass, jlong pkeyRef) {
   2520     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2521     JNI_TRACE("i2d_PUBKEY(%p)", pkey);
   2522     return ASN1ToByteArray<EVP_PKEY, i2d_PUBKEY>(env, pkey);
   2523 }
   2524 
   2525 /*
   2526  * static native int d2i_PUBKEY(byte[])
   2527  */
   2528 static jlong NativeCrypto_d2i_PUBKEY(JNIEnv* env, jclass, jbyteArray javaBytes) {
   2529     JNI_TRACE("d2i_PUBKEY(%p)", javaBytes);
   2530 
   2531     ScopedByteArrayRO bytes(env, javaBytes);
   2532     if (bytes.get() == NULL) {
   2533         JNI_TRACE("d2i_PUBKEY(%p) => threw error", javaBytes);
   2534         return 0;
   2535     }
   2536 
   2537     const unsigned char* tmp = reinterpret_cast<const unsigned char*>(bytes.get());
   2538     Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, bytes.size()));
   2539     if (pkey.get() == NULL) {
   2540         JNI_TRACE("bytes=%p d2i_PUBKEY => threw exception", javaBytes);
   2541         throwExceptionIfNecessary(env, "d2i_PUBKEY");
   2542         return 0;
   2543     }
   2544 
   2545     return reinterpret_cast<uintptr_t>(pkey.release());
   2546 }
   2547 
   2548 static jlong NativeCrypto_getRSAPrivateKeyWrapper(JNIEnv* env, jclass, jobject javaKey,
   2549         jbyteArray modulusBytes) {
   2550     JNI_TRACE("getRSAPrivateKeyWrapper(%p, %p)", javaKey, modulusBytes);
   2551 
   2552     Unique_RSA rsa(RSA_new());
   2553     if (rsa.get() == NULL) {
   2554         jniThrowOutOfMemory(env, "Unable to allocate RSA key");
   2555         return 0;
   2556     }
   2557 
   2558     RSA_set_method(rsa.get(), &android_rsa_method);
   2559 
   2560     if (!arrayToBignum(env, modulusBytes, &rsa->n)) {
   2561         return 0;
   2562     }
   2563 
   2564     RSA_set_app_data(rsa.get(), env->NewGlobalRef(javaKey));
   2565 
   2566     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2567     if (pkey.get() == NULL) {
   2568         JNI_TRACE("getRSAPrivateKeyWrapper failed");
   2569         jniThrowRuntimeException(env, "NativeCrypto_getRSAPrivateKeyWrapper failed");
   2570         freeOpenSslErrorState();
   2571         return 0;
   2572     }
   2573 
   2574     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
   2575         jniThrowRuntimeException(env, "getRSAPrivateKeyWrapper failed");
   2576         return 0;
   2577     }
   2578     OWNERSHIP_TRANSFERRED(rsa);
   2579     return reinterpret_cast<uintptr_t>(pkey.release());
   2580 }
   2581 
   2582 static jlong NativeCrypto_getDSAPrivateKeyWrapper(JNIEnv* env, jclass, jobject javaKey,
   2583         jbyteArray qBytes) {
   2584     JNI_TRACE("getDSAPrivateKeyWrapper(%p, %p)", javaKey, qBytes);
   2585 
   2586     Unique_DSA dsa(DSA_new());
   2587     if (dsa.get() == NULL) {
   2588         jniThrowOutOfMemory(env, "Unable to allocate DSA key");
   2589         return 0;
   2590     }
   2591 
   2592     if (!arrayToBignum(env, qBytes, &dsa->q)) {
   2593         return 0;
   2594     }
   2595 
   2596     DSA_set_method(dsa.get(), &android_dsa_method);
   2597     DSA_set_ex_data(dsa.get(), 0, env->NewGlobalRef(javaKey));
   2598 
   2599     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2600     if (pkey.get() == NULL) {
   2601         JNI_TRACE("getDSAPrivateKeyWrapper failed");
   2602         jniThrowRuntimeException(env, "NativeCrypto_getDSAPrivateKeyWrapper failed");
   2603         freeOpenSslErrorState();
   2604         return 0;
   2605     }
   2606 
   2607     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
   2608         jniThrowRuntimeException(env, "getDSAPrivateKeyWrapper failed");
   2609         return 0;
   2610     }
   2611     OWNERSHIP_TRANSFERRED(dsa);
   2612     return reinterpret_cast<uintptr_t>(pkey.release());
   2613 }
   2614 
   2615 static jlong NativeCrypto_getECPrivateKeyWrapper(JNIEnv* env, jclass, jobject javaKey, jlong groupRef) {
   2616     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   2617     JNI_TRACE("getECPrivateKeyWrapper(%p, %p)", javaKey, group);
   2618 
   2619     Unique_EC_KEY ecKey(EC_KEY_new());
   2620     if (ecKey.get() == NULL) {
   2621         jniThrowOutOfMemory(env, "Unable to allocate EC key");
   2622         return 0;
   2623     }
   2624 
   2625     JNI_TRACE("EC_GROUP_get_curve_name(%p)", group);
   2626 
   2627     if (group == NULL) {
   2628         JNI_TRACE("EC_GROUP_get_curve_name => group == NULL");
   2629         jniThrowNullPointerException(env, "group == NULL");
   2630         return 0;
   2631     }
   2632 
   2633     EC_KEY_set_group(ecKey.get(), group);
   2634 
   2635     ECDSA_set_method(ecKey.get(), &android_ecdsa_method);
   2636     ECDSA_set_ex_data(ecKey.get(), EcdsaGetExDataIndex(), env->NewGlobalRef(javaKey));
   2637 
   2638     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2639     if (pkey.get() == NULL) {
   2640         JNI_TRACE("getDSAPrivateKeyWrapper failed");
   2641         jniThrowRuntimeException(env, "NativeCrypto_getDSAPrivateKeyWrapper failed");
   2642         freeOpenSslErrorState();
   2643         return 0;
   2644     }
   2645 
   2646     if (EVP_PKEY_assign_EC_KEY(pkey.get(), ecKey.get()) != 1) {
   2647         jniThrowRuntimeException(env, "getECPrivateKeyWrapper failed");
   2648         return 0;
   2649     }
   2650     OWNERSHIP_TRANSFERRED(ecKey);
   2651     return reinterpret_cast<uintptr_t>(pkey.release());
   2652 }
   2653 
   2654 /*
   2655  * public static native int RSA_generate_key(int modulusBits, byte[] publicExponent);
   2656  */
   2657 static jlong NativeCrypto_RSA_generate_key_ex(JNIEnv* env, jclass, jint modulusBits,
   2658         jbyteArray publicExponent) {
   2659     JNI_TRACE("RSA_generate_key_ex(%d, %p)", modulusBits, publicExponent);
   2660 
   2661     BIGNUM* eRef = NULL;
   2662     if (!arrayToBignum(env, publicExponent, &eRef)) {
   2663         return 0;
   2664     }
   2665     Unique_BIGNUM e(eRef);
   2666 
   2667     Unique_RSA rsa(RSA_new());
   2668     if (rsa.get() == NULL) {
   2669         jniThrowOutOfMemory(env, "Unable to allocate RSA key");
   2670         return 0;
   2671     }
   2672 
   2673     if (RSA_generate_key_ex(rsa.get(), modulusBits, e.get(), NULL) < 0) {
   2674         throwExceptionIfNecessary(env, "RSA_generate_key_ex");
   2675         return 0;
   2676     }
   2677 
   2678     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2679     if (pkey.get() == NULL) {
   2680         jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
   2681         return 0;
   2682     }
   2683 
   2684     if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
   2685         jniThrowRuntimeException(env, "RSA_generate_key_ex failed");
   2686         return 0;
   2687     }
   2688 
   2689     OWNERSHIP_TRANSFERRED(rsa);
   2690     JNI_TRACE("RSA_generate_key_ex(n=%d, e=%p) => %p", modulusBits, publicExponent, pkey.get());
   2691     return reinterpret_cast<uintptr_t>(pkey.release());
   2692 }
   2693 
   2694 static jint NativeCrypto_RSA_size(JNIEnv* env, jclass, jlong pkeyRef) {
   2695     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2696     JNI_TRACE("RSA_size(%p)", pkey);
   2697 
   2698     if (pkey == NULL) {
   2699         jniThrowNullPointerException(env, "pkey == null");
   2700         return 0;
   2701     }
   2702 
   2703     Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
   2704     if (rsa.get() == NULL) {
   2705         jniThrowRuntimeException(env, "RSA_size failed");
   2706         return 0;
   2707     }
   2708 
   2709     return static_cast<jint>(RSA_size(rsa.get()));
   2710 }
   2711 
   2712 typedef int RSACryptOperation(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
   2713                               int padding);
   2714 
   2715 static jint RSA_crypt_operation(RSACryptOperation operation,
   2716         const char* caller __attribute__ ((unused)), JNIEnv* env, jint flen,
   2717         jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
   2718     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2719     JNI_TRACE("%s(%d, %p, %p, %p)", caller, flen, fromJavaBytes, toJavaBytes, pkey);
   2720 
   2721     if (pkey == NULL) {
   2722         jniThrowNullPointerException(env, "pkey == null");
   2723         return -1;
   2724     }
   2725 
   2726     Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
   2727     if (rsa.get() == NULL) {
   2728         return -1;
   2729     }
   2730 
   2731     ScopedByteArrayRO from(env, fromJavaBytes);
   2732     if (from.get() == NULL) {
   2733         return -1;
   2734     }
   2735 
   2736     ScopedByteArrayRW to(env, toJavaBytes);
   2737     if (to.get() == NULL) {
   2738         return -1;
   2739     }
   2740 
   2741     int resultSize = operation(static_cast<int>(flen),
   2742             reinterpret_cast<const unsigned char*>(from.get()),
   2743             reinterpret_cast<unsigned char*>(to.get()), rsa.get(), padding);
   2744     if (resultSize == -1) {
   2745         JNI_TRACE("%s => failed", caller);
   2746         throwExceptionIfNecessary(env, "RSA_crypt_operation");
   2747         return -1;
   2748     }
   2749 
   2750     JNI_TRACE("%s(%d, %p, %p, %p) => %d", caller, flen, fromJavaBytes, toJavaBytes, pkey,
   2751               resultSize);
   2752     return static_cast<jint>(resultSize);
   2753 }
   2754 
   2755 static jint NativeCrypto_RSA_private_encrypt(JNIEnv* env, jclass, jint flen,
   2756         jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
   2757     return RSA_crypt_operation(RSA_private_encrypt, __FUNCTION__,
   2758                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
   2759 }
   2760 static jint NativeCrypto_RSA_public_decrypt(JNIEnv* env, jclass, jint flen,
   2761         jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
   2762     return RSA_crypt_operation(RSA_public_decrypt, __FUNCTION__,
   2763                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
   2764 }
   2765 static jint NativeCrypto_RSA_public_encrypt(JNIEnv* env, jclass, jint flen,
   2766         jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
   2767     return RSA_crypt_operation(RSA_public_encrypt, __FUNCTION__,
   2768                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
   2769 }
   2770 static jint NativeCrypto_RSA_private_decrypt(JNIEnv* env, jclass, jint flen,
   2771         jbyteArray fromJavaBytes, jbyteArray toJavaBytes, jlong pkeyRef, jint padding) {
   2772     return RSA_crypt_operation(RSA_private_decrypt, __FUNCTION__,
   2773                                env, flen, fromJavaBytes, toJavaBytes, pkeyRef, padding);
   2774 }
   2775 
   2776 /*
   2777  * public static native byte[][] get_RSA_public_params(long);
   2778  */
   2779 static jobjectArray NativeCrypto_get_RSA_public_params(JNIEnv* env, jclass, jlong pkeyRef) {
   2780     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2781     JNI_TRACE("get_RSA_public_params(%p)", pkey);
   2782 
   2783     if (pkey == NULL) {
   2784         jniThrowNullPointerException(env, "pkey == null");
   2785         return 0;
   2786     }
   2787 
   2788     Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
   2789     if (rsa.get() == NULL) {
   2790         throwExceptionIfNecessary(env, "get_RSA_public_params failed");
   2791         return 0;
   2792     }
   2793 
   2794     jobjectArray joa = env->NewObjectArray(2, byteArrayClass, NULL);
   2795     if (joa == NULL) {
   2796         return NULL;
   2797     }
   2798 
   2799     jbyteArray n = bignumToArray(env, rsa->n, "n");
   2800     if (env->ExceptionCheck()) {
   2801         return NULL;
   2802     }
   2803     env->SetObjectArrayElement(joa, 0, n);
   2804 
   2805     jbyteArray e = bignumToArray(env, rsa->e, "e");
   2806     if (env->ExceptionCheck()) {
   2807         return NULL;
   2808     }
   2809     env->SetObjectArrayElement(joa, 1, e);
   2810 
   2811     return joa;
   2812 }
   2813 
   2814 /*
   2815  * public static native byte[][] get_RSA_private_params(long);
   2816  */
   2817 static jobjectArray NativeCrypto_get_RSA_private_params(JNIEnv* env, jclass, jlong pkeyRef) {
   2818     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2819     JNI_TRACE("get_RSA_public_params(%p)", pkey);
   2820 
   2821     if (pkey == NULL) {
   2822         jniThrowNullPointerException(env, "pkey == null");
   2823         return 0;
   2824     }
   2825 
   2826     Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
   2827     if (rsa.get() == NULL) {
   2828         throwExceptionIfNecessary(env, "get_RSA_public_params failed");
   2829         return 0;
   2830     }
   2831 
   2832     jobjectArray joa = env->NewObjectArray(8, byteArrayClass, NULL);
   2833     if (joa == NULL) {
   2834         return NULL;
   2835     }
   2836 
   2837     jbyteArray n = bignumToArray(env, rsa->n, "n");
   2838     if (env->ExceptionCheck()) {
   2839         return NULL;
   2840     }
   2841     env->SetObjectArrayElement(joa, 0, n);
   2842 
   2843     if (rsa->e != NULL) {
   2844         jbyteArray e = bignumToArray(env, rsa->e, "e");
   2845         if (env->ExceptionCheck()) {
   2846             return NULL;
   2847         }
   2848         env->SetObjectArrayElement(joa, 1, e);
   2849     }
   2850 
   2851     if (rsa->d != NULL) {
   2852         jbyteArray d = bignumToArray(env, rsa->d, "d");
   2853         if (env->ExceptionCheck()) {
   2854             return NULL;
   2855         }
   2856         env->SetObjectArrayElement(joa, 2, d);
   2857     }
   2858 
   2859     if (rsa->p != NULL) {
   2860         jbyteArray p = bignumToArray(env, rsa->p, "p");
   2861         if (env->ExceptionCheck()) {
   2862             return NULL;
   2863         }
   2864         env->SetObjectArrayElement(joa, 3, p);
   2865     }
   2866 
   2867     if (rsa->q != NULL) {
   2868         jbyteArray q = bignumToArray(env, rsa->q, "q");
   2869         if (env->ExceptionCheck()) {
   2870             return NULL;
   2871         }
   2872         env->SetObjectArrayElement(joa, 4, q);
   2873     }
   2874 
   2875     if (rsa->dmp1 != NULL) {
   2876         jbyteArray dmp1 = bignumToArray(env, rsa->dmp1, "dmp1");
   2877         if (env->ExceptionCheck()) {
   2878             return NULL;
   2879         }
   2880         env->SetObjectArrayElement(joa, 5, dmp1);
   2881     }
   2882 
   2883     if (rsa->dmq1 != NULL) {
   2884         jbyteArray dmq1 = bignumToArray(env, rsa->dmq1, "dmq1");
   2885         if (env->ExceptionCheck()) {
   2886             return NULL;
   2887         }
   2888         env->SetObjectArrayElement(joa, 6, dmq1);
   2889     }
   2890 
   2891     if (rsa->iqmp != NULL) {
   2892         jbyteArray iqmp = bignumToArray(env, rsa->iqmp, "iqmp");
   2893         if (env->ExceptionCheck()) {
   2894             return NULL;
   2895         }
   2896         env->SetObjectArrayElement(joa, 7, iqmp);
   2897     }
   2898 
   2899     return joa;
   2900 }
   2901 
   2902 /*
   2903  * public static native int DSA_generate_key(int, byte[], byte[], byte[], byte[]);
   2904  */
   2905 static jlong NativeCrypto_DSA_generate_key(JNIEnv* env, jclass, jint primeBits,
   2906         jbyteArray seedJavaBytes, jbyteArray gBytes, jbyteArray pBytes, jbyteArray qBytes) {
   2907     JNI_TRACE("DSA_generate_key(%d, %p, %p, %p, %p)", primeBits, seedJavaBytes,
   2908             gBytes, pBytes, qBytes);
   2909 
   2910     UniquePtr<unsigned char[]> seedPtr;
   2911     unsigned long seedSize = 0;
   2912     if (seedJavaBytes != NULL) {
   2913         ScopedByteArrayRO seed(env, seedJavaBytes);
   2914         if (seed.get() == NULL) {
   2915             return 0;
   2916         }
   2917 
   2918         seedSize = seed.size();
   2919         seedPtr.reset(new unsigned char[seedSize]);
   2920 
   2921         memcpy(seedPtr.get(), seed.get(), seedSize);
   2922     }
   2923 
   2924     Unique_DSA dsa(DSA_new());
   2925     if (dsa.get() == NULL) {
   2926         JNI_TRACE("DSA_generate_key failed");
   2927         jniThrowOutOfMemory(env, "Unable to allocate DSA key");
   2928         freeOpenSslErrorState();
   2929         return 0;
   2930     }
   2931 
   2932     if (gBytes != NULL && pBytes != NULL && qBytes != NULL) {
   2933         JNI_TRACE("DSA_generate_key parameters specified");
   2934 
   2935         if (!arrayToBignum(env, gBytes, &dsa->g)) {
   2936             return 0;
   2937         }
   2938 
   2939         if (!arrayToBignum(env, pBytes, &dsa->p)) {
   2940             return 0;
   2941         }
   2942 
   2943         if (!arrayToBignum(env, qBytes, &dsa->q)) {
   2944             return 0;
   2945         }
   2946     } else {
   2947         JNI_TRACE("DSA_generate_key generating parameters");
   2948 
   2949         if (!DSA_generate_parameters_ex(dsa.get(), primeBits, seedPtr.get(), seedSize, NULL, NULL, NULL)) {
   2950             JNI_TRACE("DSA_generate_key => param generation failed");
   2951             throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_parameters_ex failed");
   2952             return 0;
   2953         }
   2954     }
   2955 
   2956     if (!DSA_generate_key(dsa.get())) {
   2957         JNI_TRACE("DSA_generate_key failed");
   2958         throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
   2959         return 0;
   2960     }
   2961 
   2962     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   2963     if (pkey.get() == NULL) {
   2964         JNI_TRACE("DSA_generate_key failed");
   2965         jniThrowRuntimeException(env, "NativeCrypto_DSA_generate_key failed");
   2966         freeOpenSslErrorState();
   2967         return 0;
   2968     }
   2969 
   2970     if (EVP_PKEY_assign_DSA(pkey.get(), dsa.get()) != 1) {
   2971         JNI_TRACE("DSA_generate_key failed");
   2972         throwExceptionIfNecessary(env, "NativeCrypto_DSA_generate_key failed");
   2973         return 0;
   2974     }
   2975 
   2976     OWNERSHIP_TRANSFERRED(dsa);
   2977     JNI_TRACE("DSA_generate_key(n=%d, e=%p) => %p", primeBits, seedPtr.get(), pkey.get());
   2978     return reinterpret_cast<uintptr_t>(pkey.release());
   2979 }
   2980 
   2981 /*
   2982  * public static native byte[][] get_DSA_params(long);
   2983  */
   2984 static jobjectArray NativeCrypto_get_DSA_params(JNIEnv* env, jclass, jlong pkeyRef) {
   2985     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   2986     JNI_TRACE("get_DSA_params(%p)", pkey);
   2987 
   2988     if (pkey == NULL) {
   2989         jniThrowNullPointerException(env, "pkey == null");
   2990         return NULL;
   2991     }
   2992 
   2993     Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
   2994     if (dsa.get() == NULL) {
   2995         throwExceptionIfNecessary(env, "get_DSA_params failed");
   2996         return 0;
   2997     }
   2998 
   2999     jobjectArray joa = env->NewObjectArray(5, byteArrayClass, NULL);
   3000     if (joa == NULL) {
   3001         return NULL;
   3002     }
   3003 
   3004     if (dsa->g != NULL) {
   3005         jbyteArray g = bignumToArray(env, dsa->g, "g");
   3006         if (env->ExceptionCheck()) {
   3007             return NULL;
   3008         }
   3009         env->SetObjectArrayElement(joa, 0, g);
   3010     }
   3011 
   3012     if (dsa->p != NULL) {
   3013         jbyteArray p = bignumToArray(env, dsa->p, "p");
   3014         if (env->ExceptionCheck()) {
   3015             return NULL;
   3016         }
   3017         env->SetObjectArrayElement(joa, 1, p);
   3018     }
   3019 
   3020     if (dsa->q != NULL) {
   3021         jbyteArray q = bignumToArray(env, dsa->q, "q");
   3022         if (env->ExceptionCheck()) {
   3023             return NULL;
   3024         }
   3025         env->SetObjectArrayElement(joa, 2, q);
   3026     }
   3027 
   3028     if (dsa->pub_key != NULL) {
   3029         jbyteArray pub_key = bignumToArray(env, dsa->pub_key, "pub_key");
   3030         if (env->ExceptionCheck()) {
   3031             return NULL;
   3032         }
   3033         env->SetObjectArrayElement(joa, 3, pub_key);
   3034     }
   3035 
   3036     if (dsa->priv_key != NULL) {
   3037         jbyteArray priv_key = bignumToArray(env, dsa->priv_key, "priv_key");
   3038         if (env->ExceptionCheck()) {
   3039             return NULL;
   3040         }
   3041         env->SetObjectArrayElement(joa, 4, priv_key);
   3042     }
   3043 
   3044     return joa;
   3045 }
   3046 
   3047 static void NativeCrypto_set_DSA_flag_nonce_from_hash(JNIEnv* env, jclass, jlong pkeyRef)
   3048 {
   3049     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3050     JNI_TRACE("set_DSA_flag_nonce_from_hash(%p)", pkey);
   3051 
   3052     if (pkey == NULL) {
   3053         jniThrowNullPointerException(env, "pkey == null");
   3054         return;
   3055     }
   3056 
   3057     Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
   3058     if (dsa.get() == NULL) {
   3059         throwExceptionIfNecessary(env, "set_DSA_flag_nonce_from_hash failed");
   3060         return;
   3061     }
   3062 
   3063     dsa->flags |= DSA_FLAG_NONCE_FROM_HASH;
   3064 }
   3065 
   3066 static jlong NativeCrypto_DH_generate_parameters_ex(JNIEnv* env, jclass, jint primeBits, jlong generator) {
   3067     JNI_TRACE("DH_generate_parameters_ex(%d, %lld)", primeBits, (long long) generator);
   3068 
   3069     Unique_DH dh(DH_new());
   3070     if (dh.get() == NULL) {
   3071         JNI_TRACE("DH_generate_parameters_ex failed");
   3072         jniThrowOutOfMemory(env, "Unable to allocate DH key");
   3073         freeOpenSslErrorState();
   3074         return 0;
   3075     }
   3076 
   3077     JNI_TRACE("DH_generate_parameters_ex generating parameters");
   3078 
   3079     if (!DH_generate_parameters_ex(dh.get(), primeBits, generator, NULL)) {
   3080         JNI_TRACE("DH_generate_parameters_ex => param generation failed");
   3081         throwExceptionIfNecessary(env, "NativeCrypto_DH_generate_parameters_ex failed");
   3082         return 0;
   3083     }
   3084 
   3085     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   3086     if (pkey.get() == NULL) {
   3087         JNI_TRACE("DH_generate_parameters_ex failed");
   3088         jniThrowRuntimeException(env, "NativeCrypto_DH_generate_parameters_ex failed");
   3089         freeOpenSslErrorState();
   3090         return 0;
   3091     }
   3092 
   3093     if (EVP_PKEY_assign_DH(pkey.get(), dh.get()) != 1) {
   3094         JNI_TRACE("DH_generate_parameters_ex failed");
   3095         throwExceptionIfNecessary(env, "NativeCrypto_DH_generate_parameters_ex failed");
   3096         return 0;
   3097     }
   3098 
   3099     OWNERSHIP_TRANSFERRED(dh);
   3100     JNI_TRACE("DH_generate_parameters_ex(n=%d, g=%lld) => %p", primeBits, (long long) generator,
   3101             pkey.get());
   3102     return reinterpret_cast<uintptr_t>(pkey.release());
   3103 }
   3104 
   3105 static void NativeCrypto_DH_generate_key(JNIEnv* env, jclass, jlong pkeyRef) {
   3106     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3107     JNI_TRACE("DH_generate_key(%p)", pkey);
   3108 
   3109     if (pkey == NULL) {
   3110         jniThrowNullPointerException(env, "pkey == null");
   3111     }
   3112 
   3113     Unique_DH dh(EVP_PKEY_get1_DH(pkey));
   3114     if (dh.get() == NULL) {
   3115         JNI_TRACE("DH_generate_key failed");
   3116         throwExceptionIfNecessary(env, "Unable to get DH key");
   3117         freeOpenSslErrorState();
   3118     }
   3119 
   3120     if (!DH_generate_key(dh.get())) {
   3121         JNI_TRACE("DH_generate_key failed");
   3122         throwExceptionIfNecessary(env, "NativeCrypto_DH_generate_key failed");
   3123     }
   3124 }
   3125 
   3126 static jobjectArray NativeCrypto_get_DH_params(JNIEnv* env, jclass, jlong pkeyRef) {
   3127     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3128     JNI_TRACE("get_DH_params(%p)", pkey);
   3129 
   3130     if (pkey == NULL) {
   3131         jniThrowNullPointerException(env, "pkey == null");
   3132         return NULL;
   3133     }
   3134 
   3135     Unique_DH dh(EVP_PKEY_get1_DH(pkey));
   3136     if (dh.get() == NULL) {
   3137         throwExceptionIfNecessary(env, "get_DH_params failed");
   3138         return 0;
   3139     }
   3140 
   3141     jobjectArray joa = env->NewObjectArray(4, byteArrayClass, NULL);
   3142     if (joa == NULL) {
   3143         return NULL;
   3144     }
   3145 
   3146     if (dh->p != NULL) {
   3147         jbyteArray p = bignumToArray(env, dh->p, "p");
   3148         if (env->ExceptionCheck()) {
   3149             return NULL;
   3150         }
   3151         env->SetObjectArrayElement(joa, 0, p);
   3152     }
   3153 
   3154     if (dh->g != NULL) {
   3155         jbyteArray g = bignumToArray(env, dh->g, "g");
   3156         if (env->ExceptionCheck()) {
   3157             return NULL;
   3158         }
   3159         env->SetObjectArrayElement(joa, 1, g);
   3160     }
   3161 
   3162     if (dh->pub_key != NULL) {
   3163         jbyteArray pub_key = bignumToArray(env, dh->pub_key, "pub_key");
   3164         if (env->ExceptionCheck()) {
   3165             return NULL;
   3166         }
   3167         env->SetObjectArrayElement(joa, 2, pub_key);
   3168     }
   3169 
   3170     if (dh->priv_key != NULL) {
   3171         jbyteArray priv_key = bignumToArray(env, dh->priv_key, "priv_key");
   3172         if (env->ExceptionCheck()) {
   3173             return NULL;
   3174         }
   3175         env->SetObjectArrayElement(joa, 3, priv_key);
   3176     }
   3177 
   3178     return joa;
   3179 }
   3180 
   3181 #define EC_CURVE_GFP 1
   3182 #define EC_CURVE_GF2M 2
   3183 
   3184 /**
   3185  * Return group type or 0 if unknown group.
   3186  * EC_GROUP_GFP or EC_GROUP_GF2M
   3187  */
   3188 static int get_EC_GROUP_type(const EC_GROUP* group)
   3189 {
   3190     const EC_METHOD* method = EC_GROUP_method_of(group);
   3191     if (method == EC_GFp_nist_method()
   3192                 || method == EC_GFp_mont_method()
   3193                 || method == EC_GFp_simple_method()) {
   3194         return EC_CURVE_GFP;
   3195     } else if (method == EC_GF2m_simple_method()) {
   3196         return EC_CURVE_GF2M;
   3197     }
   3198 
   3199     return 0;
   3200 }
   3201 
   3202 static jlong NativeCrypto_EC_GROUP_new_by_curve_name(JNIEnv* env, jclass, jstring curveNameJava)
   3203 {
   3204     JNI_TRACE("EC_GROUP_new_by_curve_name(%p)", curveNameJava);
   3205 
   3206     ScopedUtfChars curveName(env, curveNameJava);
   3207     if (curveName.c_str() == NULL) {
   3208         return 0;
   3209     }
   3210     JNI_TRACE("EC_GROUP_new_by_curve_name(%s)", curveName.c_str());
   3211 
   3212     int nid = OBJ_sn2nid(curveName.c_str());
   3213     if (nid == NID_undef) {
   3214         JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => unknown NID name", curveName.c_str());
   3215         return 0;
   3216     }
   3217 
   3218     EC_GROUP* group = EC_GROUP_new_by_curve_name(nid);
   3219     if (group == NULL) {
   3220         JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => unknown NID %d", curveName.c_str(), nid);
   3221         freeOpenSslErrorState();
   3222         return 0;
   3223     }
   3224 
   3225     JNI_TRACE("EC_GROUP_new_by_curve_name(%s) => %p", curveName.c_str(), group);
   3226     return reinterpret_cast<uintptr_t>(group);
   3227 }
   3228 
   3229 static void NativeCrypto_EC_GROUP_set_asn1_flag(JNIEnv* env, jclass, jlong groupRef,
   3230         jint flag)
   3231 {
   3232     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
   3233     JNI_TRACE("EC_GROUP_set_asn1_flag(%p, %d)", group, flag);
   3234 
   3235     if (group == NULL) {
   3236         JNI_TRACE("EC_GROUP_set_asn1_flag => group == NULL");
   3237         jniThrowNullPointerException(env, "group == NULL");
   3238         return;
   3239     }
   3240 
   3241     EC_GROUP_set_asn1_flag(group, flag);
   3242     JNI_TRACE("EC_GROUP_set_asn1_flag(%p, %d) => success", group, flag);
   3243 }
   3244 
   3245 static void NativeCrypto_EC_GROUP_set_point_conversion_form(JNIEnv* env, jclass,
   3246         jlong groupRef, jint form)
   3247 {
   3248     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
   3249     JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d)", group, form);
   3250 
   3251     if (group == NULL) {
   3252         JNI_TRACE("EC_GROUP_set_point_conversion_form => group == NULL");
   3253         jniThrowNullPointerException(env, "group == NULL");
   3254         return;
   3255     }
   3256 
   3257     EC_GROUP_set_point_conversion_form(group, static_cast<point_conversion_form_t>(form));
   3258     JNI_TRACE("EC_GROUP_set_point_conversion_form(%p, %d) => success", group, form);
   3259 }
   3260 
   3261 static jlong NativeCrypto_EC_GROUP_new_curve(JNIEnv* env, jclass, jint type, jbyteArray pJava,
   3262         jbyteArray aJava, jbyteArray bJava)
   3263 {
   3264     JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p)", type, pJava, aJava, bJava);
   3265 
   3266     BIGNUM* pRef = NULL;
   3267     if (!arrayToBignum(env, pJava, &pRef)) {
   3268         return 0;
   3269     }
   3270     Unique_BIGNUM p(pRef);
   3271 
   3272     BIGNUM* aRef = NULL;
   3273     if (!arrayToBignum(env, aJava, &aRef)) {
   3274         return 0;
   3275     }
   3276     Unique_BIGNUM a(aRef);
   3277 
   3278     BIGNUM* bRef = NULL;
   3279     if (!arrayToBignum(env, bJava, &bRef)) {
   3280         return 0;
   3281     }
   3282     Unique_BIGNUM b(bRef);
   3283 
   3284     EC_GROUP* group;
   3285     switch (type) {
   3286     case EC_CURVE_GFP:
   3287         group = EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), (BN_CTX*) NULL);
   3288         break;
   3289     case EC_CURVE_GF2M:
   3290         group = EC_GROUP_new_curve_GF2m(p.get(), a.get(), b.get(), (BN_CTX*) NULL);
   3291         break;
   3292     default:
   3293         jniThrowRuntimeException(env, "invalid group");
   3294         return 0;
   3295     }
   3296 
   3297     if (group == NULL) {
   3298         throwExceptionIfNecessary(env, "EC_GROUP_new_curve");
   3299     }
   3300 
   3301     JNI_TRACE("EC_GROUP_new_curve(%d, %p, %p, %p) => %p", type, pJava, aJava, bJava, group);
   3302     return reinterpret_cast<uintptr_t>(group);
   3303 }
   3304 
   3305 static jlong NativeCrypto_EC_GROUP_dup(JNIEnv* env, jclass, jlong groupRef) {
   3306     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3307     JNI_TRACE("EC_GROUP_dup(%p)", group);
   3308 
   3309     if (group == NULL) {
   3310          JNI_TRACE("EC_GROUP_dup => group == NULL");
   3311          jniThrowNullPointerException(env, "group == NULL");
   3312          return 0;
   3313      }
   3314 
   3315      EC_GROUP* groupDup = EC_GROUP_dup(group);
   3316      JNI_TRACE("EC_GROUP_dup(%p) => %p", group, groupDup);
   3317      return reinterpret_cast<uintptr_t>(groupDup);
   3318 }
   3319 
   3320 static jstring NativeCrypto_EC_GROUP_get_curve_name(JNIEnv* env, jclass, jlong groupRef) {
   3321     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3322     JNI_TRACE("EC_GROUP_get_curve_name(%p)", group);
   3323 
   3324     if (group == NULL) {
   3325         JNI_TRACE("EC_GROUP_get_curve_name => group == NULL");
   3326         jniThrowNullPointerException(env, "group == NULL");
   3327         return 0;
   3328     }
   3329 
   3330     int nid = EC_GROUP_get_curve_name(group);
   3331     if (nid == NID_undef) {
   3332         JNI_TRACE("EC_GROUP_get_curve_name(%p) => unnamed curve", group);
   3333         return NULL;
   3334     }
   3335 
   3336     const char* shortName = OBJ_nid2sn(nid);
   3337     JNI_TRACE("EC_GROUP_get_curve_name(%p) => \"%s\"", group, shortName);
   3338     return env->NewStringUTF(shortName);
   3339 }
   3340 
   3341 static jobjectArray NativeCrypto_EC_GROUP_get_curve(JNIEnv* env, jclass, jlong groupRef)
   3342 {
   3343     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3344     JNI_TRACE("EC_GROUP_get_curve(%p)", group);
   3345 
   3346     Unique_BIGNUM p(BN_new());
   3347     Unique_BIGNUM a(BN_new());
   3348     Unique_BIGNUM b(BN_new());
   3349 
   3350     int ret;
   3351     switch (get_EC_GROUP_type(group)) {
   3352     case EC_CURVE_GFP:
   3353         ret = EC_GROUP_get_curve_GFp(group, p.get(), a.get(), b.get(), (BN_CTX*) NULL);
   3354         break;
   3355     case EC_CURVE_GF2M:
   3356         ret = EC_GROUP_get_curve_GF2m(group, p.get(), a.get(), b.get(), (BN_CTX*)NULL);
   3357         break;
   3358     default:
   3359         jniThrowRuntimeException(env, "invalid group");
   3360         return NULL;
   3361     }
   3362     if (ret != 1) {
   3363         throwExceptionIfNecessary(env, "EC_GROUP_get_curve");
   3364         return NULL;
   3365     }
   3366 
   3367     jobjectArray joa = env->NewObjectArray(3, byteArrayClass, NULL);
   3368     if (joa == NULL) {
   3369         return NULL;
   3370     }
   3371 
   3372     jbyteArray pArray = bignumToArray(env, p.get(), "p");
   3373     if (env->ExceptionCheck()) {
   3374         return NULL;
   3375     }
   3376     env->SetObjectArrayElement(joa, 0, pArray);
   3377 
   3378     jbyteArray aArray = bignumToArray(env, a.get(), "a");
   3379     if (env->ExceptionCheck()) {
   3380         return NULL;
   3381     }
   3382     env->SetObjectArrayElement(joa, 1, aArray);
   3383 
   3384     jbyteArray bArray = bignumToArray(env, b.get(), "b");
   3385     if (env->ExceptionCheck()) {
   3386         return NULL;
   3387     }
   3388     env->SetObjectArrayElement(joa, 2, bArray);
   3389 
   3390     JNI_TRACE("EC_GROUP_get_curve(%p) => %p", group, joa);
   3391     return joa;
   3392 }
   3393 
   3394 static jbyteArray NativeCrypto_EC_GROUP_get_order(JNIEnv* env, jclass, jlong groupRef)
   3395 {
   3396     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3397     JNI_TRACE("EC_GROUP_get_order(%p)", group);
   3398 
   3399     Unique_BIGNUM order(BN_new());
   3400     if (order.get() == NULL) {
   3401         JNI_TRACE("EC_GROUP_get_order(%p) => can't create BN", group);
   3402         jniThrowOutOfMemory(env, "BN_new");
   3403         return NULL;
   3404     }
   3405 
   3406     if (EC_GROUP_get_order(group, order.get(), NULL) != 1) {
   3407         JNI_TRACE("EC_GROUP_get_order(%p) => threw error", group);
   3408         throwExceptionIfNecessary(env, "EC_GROUP_get_order");
   3409         return NULL;
   3410     }
   3411 
   3412     jbyteArray orderArray = bignumToArray(env, order.get(), "order");
   3413     if (env->ExceptionCheck()) {
   3414         return NULL;
   3415     }
   3416 
   3417     JNI_TRACE("EC_GROUP_get_order(%p) => %p", group, orderArray);
   3418     return orderArray;
   3419 }
   3420 
   3421 static jint NativeCrypto_EC_GROUP_get_degree(JNIEnv* env, jclass, jlong groupRef)
   3422 {
   3423     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3424     JNI_TRACE("EC_GROUP_get_degree(%p)", group);
   3425 
   3426     jint degree = EC_GROUP_get_degree(group);
   3427     if (degree == 0) {
   3428       JNI_TRACE("EC_GROUP_get_degree(%p) => unsupported", group);
   3429       jniThrowRuntimeException(env, "not supported");
   3430       return 0;
   3431     }
   3432 
   3433     JNI_TRACE("EC_GROUP_get_degree(%p) => %d", group, degree);
   3434     return degree;
   3435 }
   3436 
   3437 static jbyteArray NativeCrypto_EC_GROUP_get_cofactor(JNIEnv* env, jclass, jlong groupRef)
   3438 {
   3439     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3440     JNI_TRACE("EC_GROUP_get_cofactor(%p)", group);
   3441 
   3442     Unique_BIGNUM cofactor(BN_new());
   3443     if (cofactor.get() == NULL) {
   3444         JNI_TRACE("EC_GROUP_get_cofactor(%p) => can't create BN", group);
   3445         jniThrowOutOfMemory(env, "BN_new");
   3446         return NULL;
   3447     }
   3448 
   3449     if (EC_GROUP_get_cofactor(group, cofactor.get(), NULL) != 1) {
   3450         JNI_TRACE("EC_GROUP_get_cofactor(%p) => threw error", group);
   3451         throwExceptionIfNecessary(env, "EC_GROUP_get_cofactor");
   3452         return NULL;
   3453     }
   3454 
   3455     jbyteArray cofactorArray = bignumToArray(env, cofactor.get(), "cofactor");
   3456     if (env->ExceptionCheck()) {
   3457         return NULL;
   3458     }
   3459 
   3460     JNI_TRACE("EC_GROUP_get_cofactor(%p) => %p", group, cofactorArray);
   3461     return cofactorArray;
   3462 }
   3463 
   3464 static jint NativeCrypto_get_EC_GROUP_type(JNIEnv* env, jclass, jlong groupRef)
   3465 {
   3466     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3467     JNI_TRACE("get_EC_GROUP_type(%p)", group);
   3468 
   3469     int type = get_EC_GROUP_type(group);
   3470     if (type == 0) {
   3471         JNI_TRACE("get_EC_GROUP_type(%p) => curve type", group);
   3472         jniThrowRuntimeException(env, "unknown curve type");
   3473     } else {
   3474         JNI_TRACE("get_EC_GROUP_type(%p) => %d", group, type);
   3475     }
   3476     return type;
   3477 }
   3478 
   3479 static void NativeCrypto_EC_GROUP_clear_free(JNIEnv* env, jclass, jlong groupRef)
   3480 {
   3481     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
   3482     JNI_TRACE("EC_GROUP_clear_free(%p)", group);
   3483 
   3484     if (group == NULL) {
   3485         JNI_TRACE("EC_GROUP_clear_free => group == NULL");
   3486         jniThrowNullPointerException(env, "group == NULL");
   3487         return;
   3488     }
   3489 
   3490     EC_GROUP_clear_free(group);
   3491     JNI_TRACE("EC_GROUP_clear_free(%p) => success", group);
   3492 }
   3493 
   3494 static jboolean NativeCrypto_EC_GROUP_cmp(JNIEnv* env, jclass, jlong group1Ref, jlong group2Ref)
   3495 {
   3496     const EC_GROUP* group1 = reinterpret_cast<const EC_GROUP*>(group1Ref);
   3497     const EC_GROUP* group2 = reinterpret_cast<const EC_GROUP*>(group2Ref);
   3498     JNI_TRACE("EC_GROUP_cmp(%p, %p)", group1, group2);
   3499 
   3500     if (group1 == NULL || group2 == NULL) {
   3501         JNI_TRACE("EC_GROUP_cmp(%p, %p) => group1 == null || group2 == null", group1, group2);
   3502         jniThrowNullPointerException(env, "group1 == null || group2 == null");
   3503         return false;
   3504     }
   3505 
   3506     int ret = EC_GROUP_cmp(group1, group2, (BN_CTX*)NULL);
   3507 
   3508     JNI_TRACE("ECP_GROUP_cmp(%p, %p) => %d", group1, group2, ret);
   3509     return ret == 0;
   3510 }
   3511 
   3512 static void NativeCrypto_EC_GROUP_set_generator(JNIEnv* env, jclass, jlong groupRef, jlong pointRef, jbyteArray njavaBytes, jbyteArray hjavaBytes)
   3513 {
   3514     EC_GROUP* group = reinterpret_cast<EC_GROUP*>(groupRef);
   3515     const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
   3516     JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p)", group, point, njavaBytes, hjavaBytes);
   3517 
   3518     if (group == NULL || point == NULL) {
   3519         JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => group == null || point == null",
   3520                 group, point, njavaBytes, hjavaBytes);
   3521         jniThrowNullPointerException(env, "group == null || point == null");
   3522         return;
   3523     }
   3524 
   3525     BIGNUM* nRef = NULL;
   3526     if (!arrayToBignum(env, njavaBytes, &nRef)) {
   3527         return;
   3528     }
   3529     Unique_BIGNUM n(nRef);
   3530 
   3531     BIGNUM* hRef = NULL;
   3532     if (!arrayToBignum(env, hjavaBytes, &hRef)) {
   3533         return;
   3534     }
   3535     Unique_BIGNUM h(hRef);
   3536 
   3537     int ret = EC_GROUP_set_generator(group, point, n.get(), h.get());
   3538     if (ret == 0) {
   3539         throwExceptionIfNecessary(env, "EC_GROUP_set_generator");
   3540     }
   3541 
   3542     JNI_TRACE("EC_GROUP_set_generator(%p, %p, %p, %p) => %d", group, point, njavaBytes, hjavaBytes, ret);
   3543 }
   3544 
   3545 static jlong NativeCrypto_EC_GROUP_get_generator(JNIEnv* env, jclass, jlong groupRef)
   3546 {
   3547     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3548     JNI_TRACE("EC_GROUP_get_generator(%p)", group);
   3549 
   3550     if (group == NULL) {
   3551         JNI_TRACE("EC_POINT_get_generator(%p) => group == null", group);
   3552         jniThrowNullPointerException(env, "group == null");
   3553         return 0;
   3554     }
   3555 
   3556     const EC_POINT* generator = EC_GROUP_get0_generator(group);
   3557 
   3558     Unique_EC_POINT dup(EC_POINT_dup(generator, group));
   3559     if (dup.get() == NULL) {
   3560         JNI_TRACE("EC_GROUP_get_generator(%p) => oom error", group);
   3561         jniThrowOutOfMemory(env, "unable to dupe generator");
   3562         return 0;
   3563     }
   3564 
   3565     JNI_TRACE("EC_GROUP_get_generator(%p) => %p", group, dup.get());
   3566     return reinterpret_cast<uintptr_t>(dup.release());
   3567 }
   3568 
   3569 static jlong NativeCrypto_EC_POINT_new(JNIEnv* env, jclass, jlong groupRef)
   3570 {
   3571     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3572     JNI_TRACE("EC_POINT_new(%p)", group);
   3573 
   3574     if (group == NULL) {
   3575         JNI_TRACE("EC_POINT_new(%p) => group == null", group);
   3576         jniThrowNullPointerException(env, "group == null");
   3577         return 0;
   3578     }
   3579 
   3580     EC_POINT* point = EC_POINT_new(group);
   3581     if (point == NULL) {
   3582         jniThrowOutOfMemory(env, "Unable create an EC_POINT");
   3583         return 0;
   3584     }
   3585 
   3586     return reinterpret_cast<uintptr_t>(point);
   3587 }
   3588 
   3589 static void NativeCrypto_EC_POINT_clear_free(JNIEnv* env, jclass, jlong groupRef) {
   3590     EC_POINT* group = reinterpret_cast<EC_POINT*>(groupRef);
   3591     JNI_TRACE("EC_POINT_clear_free(%p)", group);
   3592 
   3593     if (group == NULL) {
   3594         JNI_TRACE("EC_POINT_clear_free => group == NULL");
   3595         jniThrowNullPointerException(env, "group == NULL");
   3596         return;
   3597     }
   3598 
   3599     EC_POINT_clear_free(group);
   3600     JNI_TRACE("EC_POINT_clear_free(%p) => success", group);
   3601 }
   3602 
   3603 static jboolean NativeCrypto_EC_POINT_cmp(JNIEnv* env, jclass, jlong groupRef, jlong point1Ref, jlong point2Ref)
   3604 {
   3605     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3606     const EC_POINT* point1 = reinterpret_cast<const EC_POINT*>(point1Ref);
   3607     const EC_POINT* point2 = reinterpret_cast<const EC_POINT*>(point2Ref);
   3608     JNI_TRACE("EC_POINT_cmp(%p, %p, %p)", group, point1, point2);
   3609 
   3610     if (group == NULL || point1 == NULL || point2 == NULL) {
   3611         JNI_TRACE("EC_POINT_cmp(%p, %p, %p) => group == null || point1 == null || point2 == null",
   3612                 group, point1, point2);
   3613         jniThrowNullPointerException(env, "group == null || point1 == null || point2 == null");
   3614         return false;
   3615     }
   3616 
   3617     int ret = EC_POINT_cmp(group, point1, point2, (BN_CTX*)NULL);
   3618 
   3619     JNI_TRACE("ECP_GROUP_cmp(%p, %p) => %d", point1, point2, ret);
   3620     return ret == 0;
   3621 }
   3622 
   3623 static void NativeCrypto_EC_POINT_set_affine_coordinates(JNIEnv* env, jclass,
   3624         jlong groupRef, jlong pointRef, jbyteArray xjavaBytes, jbyteArray yjavaBytes)
   3625 {
   3626     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3627     EC_POINT* point = reinterpret_cast<EC_POINT*>(pointRef);
   3628     JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p)", group, point, xjavaBytes,
   3629             yjavaBytes);
   3630 
   3631     if (group == NULL || point == NULL) {
   3632         JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) => group == null || point == null",
   3633                 group, point, xjavaBytes, yjavaBytes);
   3634         jniThrowNullPointerException(env, "group == null || point == null");
   3635         return;
   3636     }
   3637 
   3638     BIGNUM* xRef = NULL;
   3639     if (!arrayToBignum(env, xjavaBytes, &xRef)) {
   3640         return;
   3641     }
   3642     Unique_BIGNUM x(xRef);
   3643 
   3644     BIGNUM* yRef = NULL;
   3645     if (!arrayToBignum(env, yjavaBytes, &yRef)) {
   3646         return;
   3647     }
   3648     Unique_BIGNUM y(yRef);
   3649 
   3650     int ret;
   3651     switch (get_EC_GROUP_type(group)) {
   3652     case EC_CURVE_GFP:
   3653         ret = EC_POINT_set_affine_coordinates_GFp(group, point, x.get(), y.get(), NULL);
   3654         break;
   3655     case EC_CURVE_GF2M:
   3656         ret = EC_POINT_set_affine_coordinates_GF2m(group, point, x.get(), y.get(), NULL);
   3657         break;
   3658     default:
   3659         jniThrowRuntimeException(env, "invalid curve type");
   3660         return;
   3661     }
   3662 
   3663     if (ret != 1) {
   3664         throwExceptionIfNecessary(env, "EC_POINT_set_affine_coordinates");
   3665     }
   3666 
   3667     JNI_TRACE("EC_POINT_set_affine_coordinates(%p, %p, %p, %p) => %d", group, point,
   3668             xjavaBytes, yjavaBytes, ret);
   3669 }
   3670 
   3671 static jobjectArray NativeCrypto_EC_POINT_get_affine_coordinates(JNIEnv* env, jclass, jlong groupRef,
   3672         jlong pointRef)
   3673 {
   3674     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3675     const EC_POINT* point = reinterpret_cast<const EC_POINT*>(pointRef);
   3676     JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p)", group, point);
   3677 
   3678     Unique_BIGNUM x(BN_new());
   3679     Unique_BIGNUM y(BN_new());
   3680 
   3681     int ret;
   3682     switch (get_EC_GROUP_type(group)) {
   3683     case EC_CURVE_GFP:
   3684         ret = EC_POINT_get_affine_coordinates_GFp(group, point, x.get(), y.get(), NULL);
   3685         break;
   3686     case EC_CURVE_GF2M:
   3687         ret = EC_POINT_get_affine_coordinates_GF2m(group, point, x.get(), y.get(), NULL);
   3688         break;
   3689     default:
   3690         jniThrowRuntimeException(env, "invalid curve type");
   3691         return NULL;
   3692     }
   3693     if (ret != 1) {
   3694         JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p)", group, point);
   3695         throwExceptionIfNecessary(env, "EC_POINT_get_affine_coordinates");
   3696         return NULL;
   3697     }
   3698 
   3699     jobjectArray joa = env->NewObjectArray(2, byteArrayClass, NULL);
   3700     if (joa == NULL) {
   3701         return NULL;
   3702     }
   3703 
   3704     jbyteArray xBytes = bignumToArray(env, x.get(), "x");
   3705     if (env->ExceptionCheck()) {
   3706         return NULL;
   3707     }
   3708     env->SetObjectArrayElement(joa, 0, xBytes);
   3709 
   3710     jbyteArray yBytes = bignumToArray(env, y.get(), "y");
   3711     if (env->ExceptionCheck()) {
   3712         return NULL;
   3713     }
   3714     env->SetObjectArrayElement(joa, 1, yBytes);
   3715 
   3716     JNI_TRACE("EC_POINT_get_affine_coordinates(%p, %p) => %p", group, point, joa);
   3717     return joa;
   3718 }
   3719 
   3720 static jlong NativeCrypto_EC_KEY_generate_key(JNIEnv* env, jclass, jlong groupRef)
   3721 {
   3722     const EC_GROUP* group = reinterpret_cast<const EC_GROUP*>(groupRef);
   3723     JNI_TRACE("EC_KEY_generate_key(%p)", group);
   3724 
   3725     Unique_EC_KEY eckey(EC_KEY_new());
   3726     if (eckey.get() == NULL) {
   3727         JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_new() oom", group);
   3728         jniThrowOutOfMemory(env, "Unable to create an EC_KEY");
   3729         return 0;
   3730     }
   3731 
   3732     if (EC_KEY_set_group(eckey.get(), group) != 1) {
   3733         JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_set_group error", group);
   3734         throwExceptionIfNecessary(env, "EC_KEY_set_group");
   3735         return 0;
   3736     }
   3737 
   3738     if (EC_KEY_generate_key(eckey.get()) != 1) {
   3739         JNI_TRACE("EC_KEY_generate_key(%p) => EC_KEY_generate_key error", group);
   3740         throwExceptionIfNecessary(env, "EC_KEY_set_group");
   3741         return 0;
   3742     }
   3743 
   3744     Unique_EVP_PKEY pkey(EVP_PKEY_new());
   3745     if (pkey.get() == NULL) {
   3746         JNI_TRACE("EC_KEY_generate_key(%p) => threw error", group);
   3747         throwExceptionIfNecessary(env, "EC_KEY_generate_key");
   3748         return 0;
   3749     }
   3750     if (EVP_PKEY_assign_EC_KEY(pkey.get(), eckey.get()) != 1) {
   3751         jniThrowRuntimeException(env, "EVP_PKEY_assign_EC_KEY failed");
   3752         return 0;
   3753     }
   3754     OWNERSHIP_TRANSFERRED(eckey);
   3755 
   3756     JNI_TRACE("EC_KEY_generate_key(%p) => %p", group, pkey.get());
   3757     return reinterpret_cast<uintptr_t>(pkey.release());
   3758 }
   3759 
   3760 static jlong NativeCrypto_EC_KEY_get0_group(JNIEnv* env, jclass, jlong pkeyRef)
   3761 {
   3762     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3763     JNI_TRACE("EC_KEY_get0_group(%p)", pkey);
   3764 
   3765     if (pkey == NULL) {
   3766         jniThrowNullPointerException(env, "pkey == null");
   3767         JNI_TRACE("EC_KEY_get0_group(%p) => pkey == null", pkey);
   3768         return 0;
   3769     }
   3770 
   3771     if (EVP_PKEY_type(pkey->type) != EVP_PKEY_EC) {
   3772         jniThrowRuntimeException(env, "not EC key");
   3773         JNI_TRACE("EC_KEY_get0_group(%p) => not EC key (type == %d)", pkey,
   3774                 EVP_PKEY_type(pkey->type));
   3775         return 0;
   3776     }
   3777 
   3778     const EC_GROUP* group = EC_KEY_get0_group(pkey->pkey.ec);
   3779     JNI_TRACE("EC_KEY_get0_group(%p) => %p", pkey, group);
   3780     return reinterpret_cast<uintptr_t>(group);
   3781 }
   3782 
   3783 static jbyteArray NativeCrypto_EC_KEY_get_private_key(JNIEnv* env, jclass, jlong pkeyRef)
   3784 {
   3785     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3786     JNI_TRACE("EC_KEY_get_private_key(%p)", pkey);
   3787 
   3788     if (pkey == NULL) {
   3789         jniThrowNullPointerException(env, "pkey == null");
   3790         return NULL;
   3791     }
   3792 
   3793     Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
   3794     if (eckey.get() == NULL) {
   3795         throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
   3796         return NULL;
   3797     }
   3798 
   3799     const BIGNUM *privkey = EC_KEY_get0_private_key(eckey.get());
   3800 
   3801     jbyteArray privBytes = bignumToArray(env, privkey, "privkey");
   3802     if (env->ExceptionCheck()) {
   3803         JNI_TRACE("EC_KEY_get_private_key(%p) => threw error", pkey);
   3804         return NULL;
   3805     }
   3806 
   3807     JNI_TRACE("EC_KEY_get_private_key(%p) => %p", pkey, privBytes);
   3808     return privBytes;
   3809 }
   3810 
   3811 static jlong NativeCrypto_EC_KEY_get_public_key(JNIEnv* env, jclass, jlong pkeyRef)
   3812 {
   3813     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3814     JNI_TRACE("EC_KEY_get_public_key(%p)", pkey);
   3815 
   3816     if (pkey == NULL) {
   3817         jniThrowNullPointerException(env, "pkey == null");
   3818         return 0;
   3819     }
   3820 
   3821     Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
   3822     if (eckey.get() == NULL) {
   3823         throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
   3824         return 0;
   3825     }
   3826 
   3827     Unique_EC_POINT dup(EC_POINT_dup(EC_KEY_get0_public_key(eckey.get()),
   3828             EC_KEY_get0_group(eckey.get())));
   3829     if (dup.get() == NULL) {
   3830         JNI_TRACE("EC_KEY_get_public_key(%p) => can't dup public key", pkey);
   3831         jniThrowRuntimeException(env, "EC_POINT_dup");
   3832         return 0;
   3833     }
   3834 
   3835     JNI_TRACE("EC_KEY_get_public_key(%p) => %p", pkey, dup.get());
   3836     return reinterpret_cast<uintptr_t>(dup.release());
   3837 }
   3838 
   3839 static void NativeCrypto_EC_KEY_set_nonce_from_hash(JNIEnv* env, jclass, jlong pkeyRef,
   3840         jboolean enabled)
   3841 {
   3842     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   3843     JNI_TRACE("EC_KEY_set_nonce_from_hash(%p, %d)", pkey, enabled ? 1 : 0);
   3844 
   3845     if (pkey == NULL) {
   3846         jniThrowNullPointerException(env, "pkey == null");
   3847         return;
   3848     }
   3849 
   3850     Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
   3851     if (eckey.get() == NULL) {
   3852         throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY");
   3853         return;
   3854     }
   3855 
   3856     EC_KEY_set_nonce_from_hash(eckey.get(), enabled ? 1 : 0);
   3857 }
   3858 
   3859 static jint NativeCrypto_ECDH_compute_key(JNIEnv* env, jclass,
   3860      jbyteArray outArray, jint outOffset, jlong pubkeyRef, jlong privkeyRef)
   3861 {
   3862     EVP_PKEY* pubPkey = reinterpret_cast<EVP_PKEY*>(pubkeyRef);
   3863     EVP_PKEY* privPkey = reinterpret_cast<EVP_PKEY*>(privkeyRef);
   3864     JNI_TRACE("ECDH_compute_key(%p, %d, %p, %p)", outArray, outOffset, pubPkey, privPkey);
   3865 
   3866     ScopedByteArrayRW out(env, outArray);
   3867     if (out.get() == NULL) {
   3868         JNI_TRACE("ECDH_compute_key(%p, %d, %p, %p) can't get output buffer",
   3869                 outArray, outOffset, pubPkey, privPkey);
   3870         return -1;
   3871     }
   3872 
   3873     if ((outOffset < 0) || ((size_t) outOffset >= out.size())) {
   3874         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
   3875         return -1;
   3876     }
   3877 
   3878     if (pubPkey == NULL) {
   3879         jniThrowNullPointerException(env, "pubPkey == null");
   3880         return -1;
   3881     }
   3882 
   3883     Unique_EC_KEY pubkey(EVP_PKEY_get1_EC_KEY(pubPkey));
   3884     if (pubkey.get() == NULL) {
   3885         JNI_TRACE("ECDH_compute_key(%p) => can't get public key", pubPkey);
   3886         throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY public");
   3887         return -1;
   3888     }
   3889 
   3890     const EC_POINT* pubkeyPoint = EC_KEY_get0_public_key(pubkey.get());
   3891     if (pubkeyPoint == NULL) {
   3892         JNI_TRACE("ECDH_compute_key(%p) => can't get public key point", pubPkey);
   3893         throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY public");
   3894         return -1;
   3895     }
   3896 
   3897     if (privPkey == NULL) {
   3898         jniThrowNullPointerException(env, "privPkey == null");
   3899         return -1;
   3900     }
   3901 
   3902     Unique_EC_KEY privkey(EVP_PKEY_get1_EC_KEY(privPkey));
   3903     if (privkey.get() == NULL) {
   3904         throwExceptionIfNecessary(env, "EVP_PKEY_get1_EC_KEY private");
   3905         return -1;
   3906     }
   3907 
   3908     int outputLength = ECDH_compute_key(
   3909             &out[outOffset],
   3910             out.size() - outOffset,
   3911             pubkeyPoint,
   3912             privkey.get(),
   3913             NULL // No KDF
   3914             );
   3915     if (outputLength == -1) {
   3916         throwExceptionIfNecessary(env, "ECDH_compute_key");
   3917         return -1;
   3918     }
   3919 
   3920     return outputLength;
   3921 }
   3922 
   3923 static jlong NativeCrypto_EVP_MD_CTX_create(JNIEnv* env, jclass) {
   3924     JNI_TRACE_MD("EVP_MD_CTX_create()");
   3925 
   3926     Unique_EVP_MD_CTX ctx(EVP_MD_CTX_create());
   3927     if (ctx.get() == NULL) {
   3928         jniThrowOutOfMemory(env, "Unable create a EVP_MD_CTX");
   3929         return 0;
   3930     }
   3931 
   3932     JNI_TRACE_MD("EVP_MD_CTX_create() => %p", ctx.get());
   3933     return reinterpret_cast<uintptr_t>(ctx.release());
   3934 }
   3935 
   3936 static void NativeCrypto_EVP_MD_CTX_init(JNIEnv* env, jclass, jobject ctxRef) {
   3937     EVP_MD_CTX* ctx = fromContextObject<EVP_MD_CTX>(env, ctxRef);
   3938     JNI_TRACE_MD("EVP_MD_CTX_init(%p)", ctx);
   3939 
   3940     if (ctx != NULL) {
   3941         EVP_MD_CTX_init(ctx);
   3942     }
   3943 }
   3944 
   3945 static void NativeCrypto_EVP_MD_CTX_destroy(JNIEnv*, jclass, jlong ctxRef) {
   3946     EVP_MD_CTX* ctx = reinterpret_cast<EVP_MD_CTX*>(ctxRef);
   3947     JNI_TRACE_MD("EVP_MD_CTX_destroy(%p)", ctx);
   3948 
   3949     if (ctx != NULL) {
   3950         EVP_MD_CTX_destroy(ctx);
   3951     }
   3952 }
   3953 
   3954 static jint NativeCrypto_EVP_MD_CTX_copy(JNIEnv* env, jclass, jobject dstCtxRef, jobject srcCtxRef) {
   3955     EVP_MD_CTX* dst_ctx = fromContextObject<EVP_MD_CTX>(env, dstCtxRef);
   3956     const EVP_MD_CTX* src_ctx = fromContextObject<EVP_MD_CTX>(env, srcCtxRef);
   3957     JNI_TRACE_MD("EVP_MD_CTX_copy(%p. %p)", dst_ctx, src_ctx);
   3958 
   3959     if (src_ctx == NULL) {
   3960         return 0;
   3961     } else if (dst_ctx == NULL) {
   3962         return 0;
   3963     }
   3964 
   3965     int result = EVP_MD_CTX_copy_ex(dst_ctx, src_ctx);
   3966     if (result == 0) {
   3967         jniThrowRuntimeException(env, "Unable to copy EVP_MD_CTX");
   3968         freeOpenSslErrorState();
   3969     }
   3970 
   3971     JNI_TRACE_MD("EVP_MD_CTX_copy(%p, %p) => %d", dst_ctx, src_ctx, result);
   3972     return result;
   3973 }
   3974 
   3975 /*
   3976  * public static native int EVP_DigestFinal(long, byte[], int)
   3977  */
   3978 static jint NativeCrypto_EVP_DigestFinal(JNIEnv* env, jclass, jobject ctxRef, jbyteArray hash,
   3979         jint offset) {
   3980     EVP_MD_CTX* ctx = fromContextObject<EVP_MD_CTX>(env, ctxRef);
   3981     JNI_TRACE_MD("EVP_DigestFinal(%p, %p, %d)", ctx, hash, offset);
   3982 
   3983     if (ctx == NULL) {
   3984         return -1;
   3985     } else if (hash == NULL) {
   3986         jniThrowNullPointerException(env, "ctx == null || hash == null");
   3987         return -1;
   3988     }
   3989 
   3990     ScopedByteArrayRW hashBytes(env, hash);
   3991     if (hashBytes.get() == NULL) {
   3992         return -1;
   3993     }
   3994     unsigned int bytesWritten = -1;
   3995     int ok = EVP_DigestFinal_ex(ctx,
   3996                              reinterpret_cast<unsigned char*>(hashBytes.get() + offset),
   3997                              &bytesWritten);
   3998     if (ok == 0) {
   3999         throwExceptionIfNecessary(env, "EVP_DigestFinal");
   4000     }
   4001 
   4002     JNI_TRACE_MD("EVP_DigestFinal(%p, %p, %d) => %d", ctx, hash, offset, bytesWritten);
   4003     return bytesWritten;
   4004 }
   4005 
   4006 static jint evpInit(JNIEnv* env, jobject evpMdCtxRef, jlong evpMdRef, const char* jniName,
   4007         int (*init_func)(EVP_MD_CTX*, const EVP_MD*, ENGINE*)) {
   4008     EVP_MD_CTX* ctx = fromContextObject<EVP_MD_CTX>(env, evpMdCtxRef);
   4009     const EVP_MD* evp_md = reinterpret_cast<const EVP_MD*>(evpMdRef);
   4010     JNI_TRACE_MD("%s(%p, %p)", jniName, ctx, evp_md);
   4011 
   4012     if (ctx == NULL) {
   4013         return 0;
   4014     } else if (evp_md == NULL) {
   4015         jniThrowNullPointerException(env, "evp_md == null");
   4016         return 0;
   4017     }
   4018 
   4019     int ok = init_func(ctx, evp_md, NULL);
   4020     if (ok == 0) {
   4021         bool exception = throwExceptionIfNecessary(env, jniName);
   4022         if (exception) {
   4023             JNI_TRACE("%s(%p) => threw exception", jniName, evp_md);
   4024             return 0;
   4025         }
   4026     }
   4027     JNI_TRACE_MD("%s(%p, %p) => %d", jniName, ctx, evp_md, ok);
   4028     return ok;
   4029 }
   4030 
   4031 static jint NativeCrypto_EVP_DigestInit(JNIEnv* env, jclass, jobject evpMdCtxRef, jlong evpMdRef) {
   4032     return evpInit(env, evpMdCtxRef, evpMdRef, "EVP_DigestInit", EVP_DigestInit_ex);
   4033 }
   4034 
   4035 static jint NativeCrypto_EVP_SignInit(JNIEnv* env, jclass, jobject evpMdCtxRef, jlong evpMdRef) {
   4036     return evpInit(env, evpMdCtxRef, evpMdRef, "EVP_SignInit", EVP_DigestInit_ex);
   4037 }
   4038 
   4039 static jint NativeCrypto_EVP_VerifyInit(JNIEnv* env, jclass, jobject evpMdCtxRef, jlong evpMdRef) {
   4040     return evpInit(env, evpMdCtxRef, evpMdRef, "EVP_VerifyInit", EVP_DigestInit_ex);
   4041 }
   4042 
   4043 /*
   4044  * public static native int EVP_get_digestbyname(java.lang.String)
   4045  */
   4046 static jlong NativeCrypto_EVP_get_digestbyname(JNIEnv* env, jclass, jstring algorithm) {
   4047     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%p)", algorithm);
   4048 
   4049     if (algorithm == NULL) {
   4050         jniThrowNullPointerException(env, NULL);
   4051         return -1;
   4052     }
   4053 
   4054     ScopedUtfChars algorithmChars(env, algorithm);
   4055     if (algorithmChars.c_str() == NULL) {
   4056         return 0;
   4057     }
   4058     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s)", algorithmChars.c_str());
   4059 
   4060     const EVP_MD* evp_md = EVP_get_digestbyname(algorithmChars.c_str());
   4061     if (evp_md == NULL) {
   4062         jniThrowRuntimeException(env, "Hash algorithm not found");
   4063         return 0;
   4064     }
   4065 
   4066     JNI_TRACE("NativeCrypto_EVP_get_digestbyname(%s) => %p", algorithmChars.c_str(), evp_md);
   4067     return reinterpret_cast<uintptr_t>(evp_md);
   4068 }
   4069 
   4070 /*
   4071  * public static native int EVP_MD_size(long)
   4072  */
   4073 static jint NativeCrypto_EVP_MD_size(JNIEnv* env, jclass, jlong evpMdRef) {
   4074     EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
   4075     JNI_TRACE("NativeCrypto_EVP_MD_size(%p)", evp_md);
   4076 
   4077     if (evp_md == NULL) {
   4078         jniThrowNullPointerException(env, NULL);
   4079         return -1;
   4080     }
   4081 
   4082     int result = EVP_MD_size(evp_md);
   4083     JNI_TRACE("NativeCrypto_EVP_MD_size(%p) => %d", evp_md, result);
   4084     return result;
   4085 }
   4086 
   4087 /*
   4088  * public static int void EVP_MD_block_size(long)
   4089  */
   4090 static jint NativeCrypto_EVP_MD_block_size(JNIEnv* env, jclass, jlong evpMdRef) {
   4091     EVP_MD* evp_md = reinterpret_cast<EVP_MD*>(evpMdRef);
   4092     JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p)", evp_md);
   4093 
   4094     if (evp_md == NULL) {
   4095         jniThrowNullPointerException(env, NULL);
   4096         return -1;
   4097     }
   4098 
   4099     int result = EVP_MD_block_size(evp_md);
   4100     JNI_TRACE("NativeCrypto_EVP_MD_block_size(%p) => %d", evp_md, result);
   4101     return result;
   4102 }
   4103 
   4104 static void NativeCrypto_EVP_DigestSignInit(JNIEnv* env, jclass, jobject evpMdCtxRef,
   4105         const jlong evpMdRef, jlong pkeyRef) {
   4106     EVP_MD_CTX* mdCtx = fromContextObject<EVP_MD_CTX>(env, evpMdCtxRef);
   4107     const EVP_MD* md = reinterpret_cast<const EVP_MD*>(evpMdRef);
   4108     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   4109     JNI_TRACE("EVP_DigestSignInit(%p, %p, %p)", mdCtx, md, pkey);
   4110 
   4111     if (mdCtx == NULL) {
   4112          return;
   4113     }
   4114 
   4115     if (md == NULL) {
   4116          jniThrowNullPointerException(env, "md == null");
   4117          return;
   4118     }
   4119 
   4120     if (pkey == NULL) {
   4121          jniThrowNullPointerException(env, "pkey == null");
   4122          return;
   4123     }
   4124 
   4125     if (EVP_DigestSignInit(mdCtx, (EVP_PKEY_CTX **) NULL, md, (ENGINE *) NULL, pkey) <= 0) {
   4126         JNI_TRACE("ctx=%p EVP_DigestSignInit => threw exception", mdCtx);
   4127         throwExceptionIfNecessary(env, "EVP_DigestSignInit");
   4128         return;
   4129     }
   4130 
   4131     JNI_TRACE("EVP_DigestSignInit(%p, %p, %p) => success", mdCtx, md, pkey);
   4132 }
   4133 
   4134 static void evpUpdate(JNIEnv* env, jobject evpMdCtxRef, jbyteArray inJavaBytes, jint inOffset,
   4135         jint inLength, const char *jniName, int (*update_func)(EVP_MD_CTX*, const void *,
   4136         size_t))
   4137 {
   4138     EVP_MD_CTX* mdCtx = fromContextObject<EVP_MD_CTX>(env, evpMdCtxRef);
   4139     JNI_TRACE_MD("%s(%p, %p, %d, %d)", jniName, mdCtx, inJavaBytes, inOffset, inLength);
   4140 
   4141     if (mdCtx == NULL) {
   4142          return;
   4143     }
   4144 
   4145     ScopedByteArrayRO inBytes(env, inJavaBytes);
   4146     if (inBytes.get() == NULL) {
   4147         return;
   4148     }
   4149 
   4150     if (inOffset < 0 || size_t(inOffset) > inBytes.size()) {
   4151         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", "inOffset");
   4152         return;
   4153     }
   4154 
   4155     const ssize_t inEnd = inOffset + inLength;
   4156     if (inLength < 0 || inEnd < 0 || size_t(inEnd) > inBytes.size()) {
   4157         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", "inLength");
   4158         return;
   4159     }
   4160 
   4161     const unsigned char *tmp = reinterpret_cast<const unsigned char *>(inBytes.get());
   4162     if (!update_func(mdCtx, tmp + inOffset, inLength)) {
   4163         JNI_TRACE("ctx=%p %s => threw exception", mdCtx, jniName);
   4164         throwExceptionIfNecessary(env, jniName);
   4165     }
   4166 
   4167     JNI_TRACE_MD("%s(%p, %p, %d, %d) => success", jniName, mdCtx, inJavaBytes, inOffset, inLength);
   4168 }
   4169 
   4170 static void NativeCrypto_EVP_DigestUpdate(JNIEnv* env, jclass, jobject evpMdCtxRef,
   4171         jbyteArray inJavaBytes, jint inOffset, jint inLength) {
   4172     evpUpdate(env, evpMdCtxRef, inJavaBytes, inOffset, inLength, "EVP_DigestUpdate",
   4173             EVP_DigestUpdate);
   4174 }
   4175 
   4176 static void NativeCrypto_EVP_DigestSignUpdate(JNIEnv* env, jclass, jobject evpMdCtxRef,
   4177         jbyteArray inJavaBytes, jint inOffset, jint inLength) {
   4178     evpUpdate(env, evpMdCtxRef, inJavaBytes, inOffset, inLength, "EVP_DigestSignUpdate",
   4179             EVP_DigestUpdate);
   4180 }
   4181 
   4182 static void NativeCrypto_EVP_SignUpdate(JNIEnv* env, jclass, jobject evpMdCtxRef,
   4183         jbyteArray inJavaBytes, jint inOffset, jint inLength) {
   4184     evpUpdate(env, evpMdCtxRef, inJavaBytes, inOffset, inLength, "EVP_SignUpdate",
   4185             EVP_DigestUpdate);
   4186 }
   4187 
   4188 static jbyteArray NativeCrypto_EVP_DigestSignFinal(JNIEnv* env, jclass, jobject evpMdCtxRef)
   4189 {
   4190     EVP_MD_CTX* mdCtx = fromContextObject<EVP_MD_CTX>(env, evpMdCtxRef);
   4191     JNI_TRACE("EVP_DigestSignFinal(%p)", mdCtx);
   4192 
   4193     if (mdCtx == NULL) {
   4194          return NULL;
   4195     }
   4196 
   4197     size_t len;
   4198     if (EVP_DigestSignFinal(mdCtx, NULL, &len) != 1) {
   4199         JNI_TRACE("ctx=%p EVP_DigestSignFinal => threw exception", mdCtx);
   4200         throwExceptionIfNecessary(env, "EVP_DigestSignFinal");
   4201         return 0;
   4202     }
   4203     ScopedLocalRef<jbyteArray> outJavaBytes(env, env->NewByteArray(len));
   4204     if (outJavaBytes.get() == NULL) {
   4205         return NULL;
   4206     }
   4207     ScopedByteArrayRW outBytes(env, outJavaBytes.get());
   4208     if (outBytes.get() == NULL) {
   4209         return NULL;
   4210     }
   4211     unsigned char *tmp = reinterpret_cast<unsigned char*>(outBytes.get());
   4212     if (EVP_DigestSignFinal(mdCtx, tmp, &len) != 1) {
   4213         JNI_TRACE("ctx=%p EVP_DigestSignFinal => threw exception", mdCtx);
   4214         throwExceptionIfNecessary(env, "EVP_DigestSignFinal");
   4215         return 0;
   4216     }
   4217 
   4218     JNI_TRACE("EVP_DigestSignFinal(%p) => %p", mdCtx, outJavaBytes.get());
   4219     return outJavaBytes.release();
   4220 }
   4221 
   4222 /*
   4223  * public static native int EVP_SignFinal(long, byte[], int, long)
   4224  */
   4225 static jint NativeCrypto_EVP_SignFinal(JNIEnv* env, jclass, jobject ctxRef, jbyteArray signature,
   4226         jint offset, jlong pkeyRef) {
   4227     EVP_MD_CTX* ctx = fromContextObject<EVP_MD_CTX>(env, ctxRef);
   4228     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   4229     JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p)", ctx, signature, offset, pkey);
   4230 
   4231     if (ctx == NULL) {
   4232         return -1;
   4233     } else if (pkey == NULL) {
   4234         jniThrowNullPointerException(env, NULL);
   4235         return -1;
   4236     }
   4237 
   4238     ScopedByteArrayRW signatureBytes(env, signature);
   4239     if (signatureBytes.get() == NULL) {
   4240         return -1;
   4241     }
   4242     unsigned int bytesWritten = -1;
   4243     int ok = EVP_SignFinal(ctx,
   4244                            reinterpret_cast<unsigned char*>(signatureBytes.get() + offset),
   4245                            &bytesWritten,
   4246                            pkey);
   4247     if (ok == 0) {
   4248         throwExceptionIfNecessary(env, "NativeCrypto_EVP_SignFinal");
   4249     }
   4250     JNI_TRACE("NativeCrypto_EVP_SignFinal(%p, %p, %d, %p) => %u",
   4251               ctx, signature, offset, pkey, bytesWritten);
   4252 
   4253     return bytesWritten;
   4254 }
   4255 
   4256 /*
   4257  * public static native void EVP_VerifyUpdate(long, byte[], int, int)
   4258  */
   4259 static void NativeCrypto_EVP_VerifyUpdate(JNIEnv* env, jclass, jobject ctxRef,
   4260                                           jbyteArray buffer, jint offset, jint length) {
   4261     EVP_MD_CTX* ctx = fromContextObject<EVP_MD_CTX>(env, ctxRef);
   4262     JNI_TRACE("NativeCrypto_EVP_VerifyUpdate(%p, %p, %d, %d)", ctx, buffer, offset, length);
   4263 
   4264     if (ctx == NULL) {
   4265         return;
   4266     } else if (buffer == NULL) {
   4267         jniThrowNullPointerException(env, NULL);
   4268         return;
   4269     }
   4270 
   4271     if (offset < 0 || length < 0) {
   4272         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
   4273         return;
   4274     }
   4275 
   4276     ScopedByteArrayRO bufferBytes(env, buffer);
   4277     if (bufferBytes.get() == NULL) {
   4278         return;
   4279     }
   4280     if (bufferBytes.size() < static_cast<size_t>(offset + length)) {
   4281         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
   4282         return;
   4283     }
   4284 
   4285     int ok = EVP_VerifyUpdate(ctx,
   4286                               reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
   4287                               length);
   4288     if (ok == 0) {
   4289         throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyUpdate");
   4290     }
   4291 }
   4292 
   4293 /*
   4294  * public static native int EVP_VerifyFinal(long, byte[], int, int, long)
   4295  */
   4296 static jint NativeCrypto_EVP_VerifyFinal(JNIEnv* env, jclass, jobject ctxRef, jbyteArray buffer,
   4297                                         jint offset, jint length, jlong pkeyRef) {
   4298     EVP_MD_CTX* ctx = fromContextObject<EVP_MD_CTX>(env, ctxRef);
   4299     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   4300     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p)",
   4301               ctx, buffer, offset, length, pkey);
   4302 
   4303     if (ctx == NULL) {
   4304         return -1;
   4305     } else if (buffer == NULL || pkey == NULL) {
   4306         jniThrowNullPointerException(env, NULL);
   4307         return -1;
   4308     }
   4309 
   4310     ScopedByteArrayRO bufferBytes(env, buffer);
   4311     if (bufferBytes.get() == NULL) {
   4312         return -1;
   4313     }
   4314     int ok = EVP_VerifyFinal(ctx,
   4315                              reinterpret_cast<const unsigned char*>(bufferBytes.get() + offset),
   4316                              length,
   4317                              pkey);
   4318     if (ok < 0) {
   4319         throwExceptionIfNecessary(env, "NativeCrypto_EVP_VerifyFinal");
   4320     }
   4321 
   4322     /*
   4323      * For DSA keys, OpenSSL appears to have a bug where it returns
   4324      * errors for any result != 1. See dsa_ossl.c in dsa_do_verify
   4325      */
   4326     freeOpenSslErrorState();
   4327 
   4328     JNI_TRACE("NativeCrypto_EVP_VerifyFinal(%p, %p, %d, %d, %p) => %d",
   4329               ctx, buffer, offset, length, pkey, ok);
   4330 
   4331     return ok;
   4332 }
   4333 
   4334 static jlong NativeCrypto_EVP_get_cipherbyname(JNIEnv* env, jclass, jstring algorithm) {
   4335     JNI_TRACE("EVP_get_cipherbyname(%p)", algorithm);
   4336     if (algorithm == NULL) {
   4337         JNI_TRACE("EVP_get_cipherbyname(%p) => threw exception algorithm == null", algorithm);
   4338         jniThrowNullPointerException(env, NULL);
   4339         return -1;
   4340     }
   4341 
   4342     ScopedUtfChars algorithmChars(env, algorithm);
   4343     if (algorithmChars.c_str() == NULL) {
   4344         return 0;
   4345     }
   4346     JNI_TRACE("EVP_get_cipherbyname(%p) => algorithm = %s", algorithm, algorithmChars.c_str());
   4347 
   4348     const EVP_CIPHER* evp_cipher = EVP_get_cipherbyname(algorithmChars.c_str());
   4349     if (evp_cipher == NULL) {
   4350         freeOpenSslErrorState();
   4351     }
   4352 
   4353     JNI_TRACE("EVP_get_cipherbyname(%s) => %p", algorithmChars.c_str(), evp_cipher);
   4354     return reinterpret_cast<uintptr_t>(evp_cipher);
   4355 }
   4356 
   4357 static void NativeCrypto_EVP_CipherInit_ex(JNIEnv* env, jclass, jlong ctxRef, jlong evpCipherRef,
   4358         jbyteArray keyArray, jbyteArray ivArray, jboolean encrypting) {
   4359     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4360     const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
   4361     JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %p, %d)", ctx, evpCipher, keyArray, ivArray,
   4362             encrypting ? 1 : 0);
   4363 
   4364     if (ctx == NULL) {
   4365         jniThrowNullPointerException(env, "ctx == null");
   4366         JNI_TRACE("EVP_CipherUpdate => ctx == null");
   4367         return;
   4368     }
   4369 
   4370     // The key can be null if we need to set extra parameters.
   4371     UniquePtr<unsigned char[]> keyPtr;
   4372     if (keyArray != NULL) {
   4373         ScopedByteArrayRO keyBytes(env, keyArray);
   4374         if (keyBytes.get() == NULL) {
   4375             return;
   4376         }
   4377 
   4378         keyPtr.reset(new unsigned char[keyBytes.size()]);
   4379         memcpy(keyPtr.get(), keyBytes.get(), keyBytes.size());
   4380     }
   4381 
   4382     // The IV can be null if we're using ECB.
   4383     UniquePtr<unsigned char[]> ivPtr;
   4384     if (ivArray != NULL) {
   4385         ScopedByteArrayRO ivBytes(env, ivArray);
   4386         if (ivBytes.get() == NULL) {
   4387             return;
   4388         }
   4389 
   4390         ivPtr.reset(new unsigned char[ivBytes.size()]);
   4391         memcpy(ivPtr.get(), ivBytes.get(), ivBytes.size());
   4392     }
   4393 
   4394     if (!EVP_CipherInit_ex(ctx, evpCipher, NULL, keyPtr.get(), ivPtr.get(), encrypting ? 1 : 0)) {
   4395         throwExceptionIfNecessary(env, "EVP_CipherInit_ex");
   4396         JNI_TRACE("EVP_CipherInit_ex => error initializing cipher");
   4397         return;
   4398     }
   4399 
   4400     JNI_TRACE("EVP_CipherInit_ex(%p, %p, %p, %p, %d) => success", ctx, evpCipher, keyArray, ivArray,
   4401             encrypting ? 1 : 0);
   4402 }
   4403 
   4404 /*
   4405  *  public static native int EVP_CipherUpdate(long ctx, byte[] out, int outOffset, byte[] in,
   4406  *          int inOffset, int inLength);
   4407  */
   4408 static jint NativeCrypto_EVP_CipherUpdate(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
   4409         jint outOffset, jbyteArray inArray, jint inOffset, jint inLength) {
   4410     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4411     JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d)", ctx, outArray, outOffset, inArray, inOffset);
   4412 
   4413     if (ctx == NULL) {
   4414         jniThrowNullPointerException(env, "ctx == null");
   4415         JNI_TRACE("ctx=%p EVP_CipherUpdate => ctx == null", ctx);
   4416         return 0;
   4417     }
   4418 
   4419     ScopedByteArrayRO inBytes(env, inArray);
   4420     if (inBytes.get() == NULL) {
   4421         return 0;
   4422     }
   4423     const size_t inSize = inBytes.size();
   4424     if (size_t(inOffset + inLength) > inSize) {
   4425         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException",
   4426                 "in.length < (inSize + inOffset)");
   4427         return 0;
   4428     }
   4429 
   4430     ScopedByteArrayRW outBytes(env, outArray);
   4431     if (outBytes.get() == NULL) {
   4432         return 0;
   4433     }
   4434     const size_t outSize = outBytes.size();
   4435     if (size_t(outOffset + inLength) > outSize) {
   4436         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException",
   4437                 "out.length < inSize + outOffset + blockSize - 1");
   4438         return 0;
   4439     }
   4440 
   4441     JNI_TRACE("ctx=%p EVP_CipherUpdate in=%p in.length=%d inOffset=%d inLength=%d out=%p out.length=%d outOffset=%d",
   4442             ctx, inBytes.get(), inBytes.size(), inOffset, inLength, outBytes.get(), outBytes.size(), outOffset);
   4443 
   4444     unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
   4445     const unsigned char* in = reinterpret_cast<const unsigned char*>(inBytes.get());
   4446 
   4447     int outl;
   4448     if (!EVP_CipherUpdate(ctx, out + outOffset, &outl, in + inOffset, inLength)) {
   4449         throwExceptionIfNecessary(env, "EVP_CipherUpdate");
   4450         JNI_TRACE("ctx=%p EVP_CipherUpdate => threw error", ctx);
   4451         return 0;
   4452     }
   4453 
   4454     JNI_TRACE("EVP_CipherUpdate(%p, %p, %d, %p, %d) => %d", ctx, outArray, outOffset, inArray,
   4455             inOffset, outl);
   4456     return outl;
   4457 }
   4458 
   4459 static jint NativeCrypto_EVP_CipherFinal_ex(JNIEnv* env, jclass, jlong ctxRef, jbyteArray outArray,
   4460         jint outOffset) {
   4461     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4462     JNI_TRACE("EVP_CipherFinal_ex(%p, %p, %d)", ctx, outArray, outOffset);
   4463 
   4464     if (ctx == NULL) {
   4465         jniThrowNullPointerException(env, "ctx == null");
   4466         JNI_TRACE("ctx=%p EVP_CipherFinal_ex => ctx == null", ctx);
   4467         return 0;
   4468     }
   4469 
   4470     ScopedByteArrayRW outBytes(env, outArray);
   4471     if (outBytes.get() == NULL) {
   4472         return 0;
   4473     }
   4474 
   4475     unsigned char* out = reinterpret_cast<unsigned char*>(outBytes.get());
   4476 
   4477     int outl;
   4478     if (!EVP_CipherFinal_ex(ctx, out + outOffset, &outl)) {
   4479         if (throwExceptionIfNecessary(env, "EVP_CipherFinal_ex")) {
   4480             JNI_TRACE("ctx=%p EVP_CipherFinal_ex => threw error", ctx);
   4481         } else {
   4482             throwBadPaddingException(env, "EVP_CipherFinal_ex");
   4483             JNI_TRACE("ctx=%p EVP_CipherFinal_ex => threw padding exception", ctx);
   4484         }
   4485         return 0;
   4486     }
   4487 
   4488     JNI_TRACE("EVP_CipherFinal(%p, %p, %d) => %d", ctx, outArray, outOffset, outl);
   4489     return outl;
   4490 }
   4491 
   4492 static jint NativeCrypto_EVP_CIPHER_iv_length(JNIEnv* env, jclass, jlong evpCipherRef) {
   4493     const EVP_CIPHER* evpCipher = reinterpret_cast<const EVP_CIPHER*>(evpCipherRef);
   4494     JNI_TRACE("EVP_CIPHER_iv_length(%p)", evpCipher);
   4495 
   4496     if (evpCipher == NULL) {
   4497         jniThrowNullPointerException(env, "evpCipher == null");
   4498         JNI_TRACE("EVP_CIPHER_iv_length => evpCipher == null");
   4499         return 0;
   4500     }
   4501 
   4502     const int ivLength = EVP_CIPHER_iv_length(evpCipher);
   4503     JNI_TRACE("EVP_CIPHER_iv_length(%p) => %d", evpCipher, ivLength);
   4504     return ivLength;
   4505 }
   4506 
   4507 static jlong NativeCrypto_EVP_CIPHER_CTX_new(JNIEnv* env, jclass) {
   4508     JNI_TRACE("EVP_CIPHER_CTX_new()");
   4509 
   4510     Unique_EVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
   4511     if (ctx.get() == NULL) {
   4512         jniThrowOutOfMemory(env, "Unable to allocate cipher context");
   4513         JNI_TRACE("EVP_CipherInit_ex => context allocation error");
   4514         return 0;
   4515     }
   4516 
   4517     JNI_TRACE("EVP_CIPHER_CTX_new() => %p", ctx.get());
   4518     return reinterpret_cast<uintptr_t>(ctx.release());
   4519 }
   4520 
   4521 static jint NativeCrypto_EVP_CIPHER_CTX_block_size(JNIEnv* env, jclass, jlong ctxRef) {
   4522     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4523     JNI_TRACE("EVP_CIPHER_CTX_block_size(%p)", ctx);
   4524 
   4525     if (ctx == NULL) {
   4526         jniThrowNullPointerException(env, "ctx == null");
   4527         JNI_TRACE("ctx=%p EVP_CIPHER_CTX_block_size => ctx == null", ctx);
   4528         return 0;
   4529     }
   4530 
   4531     int blockSize = EVP_CIPHER_CTX_block_size(ctx);
   4532     JNI_TRACE("EVP_CIPHER_CTX_block_size(%p) => %d", ctx, blockSize);
   4533     return blockSize;
   4534 }
   4535 
   4536 static jint NativeCrypto_get_EVP_CIPHER_CTX_buf_len(JNIEnv* env, jclass, jlong ctxRef) {
   4537     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4538     JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p)", ctx);
   4539 
   4540     if (ctx == NULL) {
   4541         jniThrowNullPointerException(env, "ctx == null");
   4542         JNI_TRACE("ctx=%p get_EVP_CIPHER_CTX_buf_len => ctx == null", ctx);
   4543         return 0;
   4544     }
   4545 
   4546     int buf_len = ctx->buf_len;
   4547     JNI_TRACE("get_EVP_CIPHER_CTX_buf_len(%p) => %d", ctx, buf_len);
   4548     return buf_len;
   4549 }
   4550 
   4551 static void NativeCrypto_EVP_CIPHER_CTX_set_padding(JNIEnv* env, jclass, jlong ctxRef, jboolean enablePaddingBool) {
   4552     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4553     jint enablePadding = enablePaddingBool ? 1 : 0;
   4554     JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d)", ctx, enablePadding);
   4555 
   4556     if (ctx == NULL) {
   4557         jniThrowNullPointerException(env, "ctx == null");
   4558         JNI_TRACE("ctx=%p EVP_CIPHER_CTX_set_padding => ctx == null", ctx);
   4559         return;
   4560     }
   4561 
   4562     EVP_CIPHER_CTX_set_padding(ctx, enablePadding); // Not void, but always returns 1.
   4563     JNI_TRACE("EVP_CIPHER_CTX_set_padding(%p, %d) => success", ctx, enablePadding);
   4564 }
   4565 
   4566 static void NativeCrypto_EVP_CIPHER_CTX_set_key_length(JNIEnv* env, jclass, jlong ctxRef,
   4567         jint keySizeBits) {
   4568     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4569     JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d)", ctx, keySizeBits);
   4570 
   4571     if (ctx == NULL) {
   4572         jniThrowNullPointerException(env, "ctx == null");
   4573         JNI_TRACE("ctx=%p EVP_CIPHER_CTX_set_key_length => ctx == null", ctx);
   4574         return;
   4575     }
   4576 
   4577     if (!EVP_CIPHER_CTX_set_key_length(ctx, keySizeBits)) {
   4578         throwExceptionIfNecessary(env, "NativeCrypto_EVP_CIPHER_CTX_set_key_length");
   4579         JNI_TRACE("NativeCrypto_EVP_CIPHER_CTX_set_key_length => threw error");
   4580         return;
   4581     }
   4582     JNI_TRACE("EVP_CIPHER_CTX_set_key_length(%p, %d) => success", ctx, keySizeBits);
   4583 }
   4584 
   4585 static void NativeCrypto_EVP_CIPHER_CTX_free(JNIEnv*, jclass, jlong ctxRef) {
   4586     EVP_CIPHER_CTX* ctx = reinterpret_cast<EVP_CIPHER_CTX*>(ctxRef);
   4587     JNI_TRACE("EVP_CIPHER_CTX_free(%p)", ctx);
   4588 
   4589     EVP_CIPHER_CTX_free(ctx);
   4590 }
   4591 
   4592 /**
   4593  * public static native void RAND_seed(byte[]);
   4594  */
   4595 static void NativeCrypto_RAND_seed(JNIEnv* env, jclass, jbyteArray seed) {
   4596     JNI_TRACE("NativeCrypto_RAND_seed seed=%p", seed);
   4597     ScopedByteArrayRO randseed(env, seed);
   4598     if (randseed.get() == NULL) {
   4599         return;
   4600     }
   4601     RAND_seed(randseed.get(), randseed.size());
   4602 }
   4603 
   4604 static jint NativeCrypto_RAND_load_file(JNIEnv* env, jclass, jstring filename, jlong max_bytes) {
   4605     JNI_TRACE("NativeCrypto_RAND_load_file filename=%p max_bytes=%lld", filename, max_bytes);
   4606     ScopedUtfChars file(env, filename);
   4607     if (file.c_str() == NULL) {
   4608         return -1;
   4609     }
   4610     int result = RAND_load_file(file.c_str(), max_bytes);
   4611     JNI_TRACE("NativeCrypto_RAND_load_file file=%s => %d", file.c_str(), result);
   4612     return result;
   4613 }
   4614 
   4615 static void NativeCrypto_RAND_bytes(JNIEnv* env, jclass, jbyteArray output) {
   4616     JNI_TRACE("NativeCrypto_RAND_bytes(%p)", output);
   4617 
   4618     ScopedByteArrayRW outputBytes(env, output);
   4619     if (outputBytes.get() == NULL) {
   4620         return;
   4621     }
   4622 
   4623     unsigned char* tmp = reinterpret_cast<unsigned char*>(outputBytes.get());
   4624     if (RAND_bytes(tmp, outputBytes.size()) <= 0) {
   4625         throwExceptionIfNecessary(env, "NativeCrypto_RAND_bytes");
   4626         JNI_TRACE("tmp=%p NativeCrypto_RAND_bytes => threw error", tmp);
   4627         return;
   4628     }
   4629 
   4630     JNI_TRACE("NativeCrypto_RAND_bytes(%p) => success", output);
   4631 }
   4632 
   4633 static jint NativeCrypto_OBJ_txt2nid(JNIEnv* env, jclass, jstring oidStr) {
   4634     JNI_TRACE("OBJ_txt2nid(%p)", oidStr);
   4635 
   4636     ScopedUtfChars oid(env, oidStr);
   4637     if (oid.c_str() == NULL) {
   4638         return 0;
   4639     }
   4640 
   4641     int nid = OBJ_txt2nid(oid.c_str());
   4642     JNI_TRACE("OBJ_txt2nid(%s) => %d", oid.c_str(), nid);
   4643     return nid;
   4644 }
   4645 
   4646 static jstring NativeCrypto_OBJ_txt2nid_longName(JNIEnv* env, jclass, jstring oidStr) {
   4647     JNI_TRACE("OBJ_txt2nid_longName(%p)", oidStr);
   4648 
   4649     ScopedUtfChars oid(env, oidStr);
   4650     if (oid.c_str() == NULL) {
   4651         return NULL;
   4652     }
   4653 
   4654     JNI_TRACE("OBJ_txt2nid_longName(%s)", oid.c_str());
   4655 
   4656     int nid = OBJ_txt2nid(oid.c_str());
   4657     if (nid == NID_undef) {
   4658         JNI_TRACE("OBJ_txt2nid_longName(%s) => NID_undef", oid.c_str());
   4659         freeOpenSslErrorState();
   4660         return NULL;
   4661     }
   4662 
   4663     const char* longName = OBJ_nid2ln(nid);
   4664     JNI_TRACE("OBJ_txt2nid_longName(%s) => %s", oid.c_str(), longName);
   4665     return env->NewStringUTF(longName);
   4666 }
   4667 
   4668 static jstring ASN1_OBJECT_to_OID_string(JNIEnv* env, ASN1_OBJECT* obj) {
   4669     /*
   4670      * The OBJ_obj2txt API doesn't "measure" if you pass in NULL as the buffer.
   4671      * Just make a buffer that's large enough here. The documentation recommends
   4672      * 80 characters.
   4673      */
   4674     char output[128];
   4675     int ret = OBJ_obj2txt(output, sizeof(output), obj, 1);
   4676     if (ret < 0) {
   4677         throwExceptionIfNecessary(env, "ASN1_OBJECT_to_OID_string");
   4678         return NULL;
   4679     } else if (size_t(ret) >= sizeof(output)) {
   4680         jniThrowRuntimeException(env, "ASN1_OBJECT_to_OID_string buffer too small");
   4681         return NULL;
   4682     }
   4683 
   4684     JNI_TRACE("ASN1_OBJECT_to_OID_string(%p) => %s", obj, output);
   4685     return env->NewStringUTF(output);
   4686 }
   4687 
   4688 static jlong NativeCrypto_create_BIO_InputStream(JNIEnv* env, jclass, jobject streamObj) {
   4689     JNI_TRACE("create_BIO_InputStream(%p)", streamObj);
   4690 
   4691     if (streamObj == NULL) {
   4692         jniThrowNullPointerException(env, "stream == null");
   4693         return 0;
   4694     }
   4695 
   4696     Unique_BIO bio(BIO_new(&stream_bio_method));
   4697     if (bio.get() == NULL) {
   4698         return 0;
   4699     }
   4700 
   4701     bio_stream_assign(bio.get(), new BIO_InputStream(streamObj));
   4702 
   4703     JNI_TRACE("create_BIO_InputStream(%p) => %p", streamObj, bio.get());
   4704     return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
   4705 }
   4706 
   4707 static jlong NativeCrypto_create_BIO_OutputStream(JNIEnv* env, jclass, jobject streamObj) {
   4708     JNI_TRACE("create_BIO_OutputStream(%p)", streamObj);
   4709 
   4710     if (streamObj == NULL) {
   4711         jniThrowNullPointerException(env, "stream == null");
   4712         return 0;
   4713     }
   4714 
   4715     Unique_BIO bio(BIO_new(&stream_bio_method));
   4716     if (bio.get() == NULL) {
   4717         return 0;
   4718     }
   4719 
   4720     bio_stream_assign(bio.get(), new BIO_OutputStream(streamObj));
   4721 
   4722     JNI_TRACE("create_BIO_OutputStream(%p) => %p", streamObj, bio.get());
   4723     return static_cast<jlong>(reinterpret_cast<uintptr_t>(bio.release()));
   4724 }
   4725 
   4726 static int NativeCrypto_BIO_read(JNIEnv* env, jclass, jlong bioRef, jbyteArray outputJavaBytes) {
   4727     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   4728     JNI_TRACE("BIO_read(%p, %p)", bio, outputJavaBytes);
   4729 
   4730     if (outputJavaBytes == NULL) {
   4731         jniThrowNullPointerException(env, "output == null");
   4732         JNI_TRACE("BIO_read(%p, %p) => output == null", bio, outputJavaBytes);
   4733         return 0;
   4734     }
   4735 
   4736     int outputSize = env->GetArrayLength(outputJavaBytes);
   4737 
   4738     UniquePtr<unsigned char[]> buffer(new unsigned char[outputSize]);
   4739     if (buffer.get() == NULL) {
   4740         jniThrowOutOfMemory(env, "Unable to allocate buffer for read");
   4741         return 0;
   4742     }
   4743 
   4744     int read = BIO_read(bio, buffer.get(), outputSize);
   4745     if (read <= 0) {
   4746         jniThrowException(env, "java/io/IOException", "BIO_read");
   4747         JNI_TRACE("BIO_read(%p, %p) => threw IO exception", bio, outputJavaBytes);
   4748         return 0;
   4749     }
   4750 
   4751     env->SetByteArrayRegion(outputJavaBytes, 0, read, reinterpret_cast<jbyte*>(buffer.get()));
   4752     JNI_TRACE("BIO_read(%p, %p) => %d", bio, outputJavaBytes, read);
   4753     return read;
   4754 }
   4755 
   4756 static void NativeCrypto_BIO_write(JNIEnv* env, jclass, jlong bioRef, jbyteArray inputJavaBytes,
   4757         jint offset, jint length) {
   4758     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   4759     JNI_TRACE("BIO_write(%p, %p, %d, %d)", bio, inputJavaBytes, offset, length);
   4760 
   4761     if (inputJavaBytes == NULL) {
   4762         jniThrowNullPointerException(env, "input == null");
   4763         return;
   4764     }
   4765 
   4766     if (offset < 0 || length < 0) {
   4767         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", "offset < 0 || length < 0");
   4768         JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
   4769         return;
   4770     }
   4771 
   4772     int inputSize = env->GetArrayLength(inputJavaBytes);
   4773     if (inputSize < offset + length) {
   4774         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException",
   4775                 "input.length < offset + length");
   4776         JNI_TRACE("BIO_write(%p, %p, %d, %d) => IOOB", bio, inputJavaBytes, offset, length);
   4777         return;
   4778     }
   4779 
   4780     UniquePtr<unsigned char[]> buffer(new unsigned char[length]);
   4781     if (buffer.get() == NULL) {
   4782         jniThrowOutOfMemory(env, "Unable to allocate buffer for write");
   4783         return;
   4784     }
   4785 
   4786     env->GetByteArrayRegion(inputJavaBytes, offset, length, reinterpret_cast<jbyte*>(buffer.get()));
   4787     if (BIO_write(bio, buffer.get(), length) != length) {
   4788         freeOpenSslErrorState();
   4789         jniThrowException(env, "java/io/IOException", "BIO_write");
   4790         JNI_TRACE("BIO_write(%p, %p, %d, %d) => IO error", bio, inputJavaBytes, offset, length);
   4791         return;
   4792     }
   4793 
   4794     JNI_TRACE("BIO_write(%p, %p, %d, %d) => success", bio, inputJavaBytes, offset, length);
   4795 }
   4796 
   4797 static void NativeCrypto_BIO_free_all(JNIEnv* env, jclass, jlong bioRef) {
   4798     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   4799     JNI_TRACE("BIO_free_all(%p)", bio);
   4800 
   4801     if (bio == NULL) {
   4802         jniThrowNullPointerException(env, "bio == null");
   4803         return;
   4804     }
   4805 
   4806     BIO_free_all(bio);
   4807 }
   4808 
   4809 static jstring X509_NAME_to_jstring(JNIEnv* env, X509_NAME* name, unsigned long flags) {
   4810     JNI_TRACE("X509_NAME_to_jstring(%p)", name);
   4811 
   4812     Unique_BIO buffer(BIO_new(BIO_s_mem()));
   4813     if (buffer.get() == NULL) {
   4814         jniThrowOutOfMemory(env, "Unable to allocate BIO");
   4815         JNI_TRACE("X509_NAME_to_jstring(%p) => threw error", name);
   4816         return NULL;
   4817     }
   4818 
   4819     /* Don't interpret the string. */
   4820     flags &= ~(ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_MSB);
   4821 
   4822     /* Write in given format and null terminate. */
   4823     X509_NAME_print_ex(buffer.get(), name, 0, flags);
   4824     BIO_write(buffer.get(), "\0", 1);
   4825 
   4826     char *tmp;
   4827     BIO_get_mem_data(buffer.get(), &tmp);
   4828     JNI_TRACE("X509_NAME_to_jstring(%p) => \"%s\"", name, tmp);
   4829     return env->NewStringUTF(tmp);
   4830 }
   4831 
   4832 
   4833 /**
   4834  * Converts GENERAL_NAME items to the output format expected in
   4835  * X509Certificate#getSubjectAlternativeNames and
   4836  * X509Certificate#getIssuerAlternativeNames return.
   4837  */
   4838 static jobject GENERAL_NAME_to_jobject(JNIEnv* env, GENERAL_NAME* gen) {
   4839     switch (gen->type) {
   4840     case GEN_EMAIL:
   4841     case GEN_DNS:
   4842     case GEN_URI: {
   4843         // This must not be a T61String and must not contain NULLs.
   4844         const char* data = reinterpret_cast<const char*>(ASN1_STRING_data(gen->d.ia5));
   4845         ssize_t len = ASN1_STRING_length(gen->d.ia5);
   4846         if ((len == static_cast<ssize_t>(strlen(data)))
   4847                 && (ASN1_PRINTABLE_type(ASN1_STRING_data(gen->d.ia5), len) != V_ASN1_T61STRING)) {
   4848             JNI_TRACE("GENERAL_NAME_to_jobject(%p) => Email/DNS/URI \"%s\"", gen, data);
   4849             return env->NewStringUTF(data);
   4850         } else {
   4851             jniThrowException(env, "java/security/cert/CertificateParsingException",
   4852                     "Invalid dNSName encoding");
   4853             JNI_TRACE("GENERAL_NAME_to_jobject(%p) => Email/DNS/URI invalid", gen);
   4854             return NULL;
   4855         }
   4856     }
   4857     case GEN_DIRNAME:
   4858         /* Write in RFC 2253 format */
   4859         return X509_NAME_to_jstring(env, gen->d.directoryName, XN_FLAG_RFC2253);
   4860     case GEN_IPADD: {
   4861         const void *ip = reinterpret_cast<const void *>(gen->d.ip->data);
   4862         if (gen->d.ip->length == 4) {
   4863             // IPv4
   4864             UniquePtr<char[]> buffer(new char[INET_ADDRSTRLEN]);
   4865             if (inet_ntop(AF_INET, ip, buffer.get(), INET_ADDRSTRLEN) != NULL) {
   4866                 JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 %s", gen, buffer.get());
   4867                 return env->NewStringUTF(buffer.get());
   4868             } else {
   4869                 JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv4 failed %s", gen, strerror(errno));
   4870             }
   4871         } else if (gen->d.ip->length == 16) {
   4872             // IPv6
   4873             UniquePtr<char[]> buffer(new char[INET6_ADDRSTRLEN]);
   4874             if (inet_ntop(AF_INET6, ip, buffer.get(), INET6_ADDRSTRLEN) != NULL) {
   4875                 JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv6 %s", gen, buffer.get());
   4876                 return env->NewStringUTF(buffer.get());
   4877             } else {
   4878                 JNI_TRACE("GENERAL_NAME_to_jobject(%p) => IPv6 failed %s", gen, strerror(errno));
   4879             }
   4880         }
   4881 
   4882         /* Invalid IP encodings are pruned out without throwing an exception. */
   4883         return NULL;
   4884     }
   4885     case GEN_RID:
   4886         return ASN1_OBJECT_to_OID_string(env, gen->d.registeredID);
   4887     case GEN_OTHERNAME:
   4888     case GEN_X400:
   4889     default:
   4890         return ASN1ToByteArray<GENERAL_NAME, i2d_GENERAL_NAME>(env, gen);
   4891     }
   4892 
   4893     return NULL;
   4894 }
   4895 
   4896 #define GN_STACK_SUBJECT_ALT_NAME 1
   4897 #define GN_STACK_ISSUER_ALT_NAME 2
   4898 
   4899 static jobjectArray NativeCrypto_get_X509_GENERAL_NAME_stack(JNIEnv* env, jclass, jlong x509Ref,
   4900         jint type) {
   4901     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   4902     JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d)", x509, type);
   4903 
   4904     if (x509 == NULL) {
   4905         jniThrowNullPointerException(env, "x509 == null");
   4906         JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => x509 == null", x509, type);
   4907         return NULL;
   4908     }
   4909 
   4910     X509_check_ca(x509);
   4911 
   4912     STACK_OF(GENERAL_NAME)* gn_stack;
   4913     Unique_sk_GENERAL_NAME stackHolder;
   4914     if (type == GN_STACK_SUBJECT_ALT_NAME) {
   4915         gn_stack = x509->altname;
   4916     } else if (type == GN_STACK_ISSUER_ALT_NAME) {
   4917         stackHolder.reset(
   4918                 static_cast<STACK_OF(GENERAL_NAME)*>(X509_get_ext_d2i(x509, NID_issuer_alt_name,
   4919                         NULL, NULL)));
   4920         gn_stack = stackHolder.get();
   4921     } else {
   4922         JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => unknown type", x509, type);
   4923         return NULL;
   4924     }
   4925 
   4926     int count = sk_GENERAL_NAME_num(gn_stack);
   4927     if (count <= 0) {
   4928         JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => null (no entries)", x509, type);
   4929         return NULL;
   4930     }
   4931 
   4932     /*
   4933      * Keep track of how many originally so we can ignore any invalid
   4934      * values later.
   4935      */
   4936     const int origCount = count;
   4937 
   4938     ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, objectArrayClass, NULL));
   4939     for (int i = 0, j = 0; i < origCount; i++, j++) {
   4940         GENERAL_NAME* gen = sk_GENERAL_NAME_value(gn_stack, i);
   4941         ScopedLocalRef<jobject> val(env, GENERAL_NAME_to_jobject(env, gen));
   4942         if (env->ExceptionCheck()) {
   4943             JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => threw exception parsing gen name",
   4944                     x509, type);
   4945             return NULL;
   4946         }
   4947 
   4948         /*
   4949          * If it's NULL, we'll have to skip this, reduce the number of total
   4950          * entries, and fix up the array later.
   4951          */
   4952         if (val.get() == NULL) {
   4953             j--;
   4954             count--;
   4955             continue;
   4956         }
   4957 
   4958         ScopedLocalRef<jobjectArray> item(env, env->NewObjectArray(2, objectClass, NULL));
   4959 
   4960         ScopedLocalRef<jobject> type(env, env->CallStaticObjectMethod(integerClass,
   4961                 integer_valueOfMethod, gen->type));
   4962         env->SetObjectArrayElement(item.get(), 0, type.get());
   4963         env->SetObjectArrayElement(item.get(), 1, val.get());
   4964 
   4965         env->SetObjectArrayElement(joa.get(), j, item.get());
   4966     }
   4967 
   4968     if (count == 0) {
   4969         JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) shrunk from %d to 0; returning NULL",
   4970                 x509, type, origCount);
   4971         joa.reset(NULL);
   4972     } else if (origCount != count) {
   4973         JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) shrunk from %d to %d", x509, type,
   4974                 origCount, count);
   4975 
   4976         ScopedLocalRef<jobjectArray> joa_copy(env, env->NewObjectArray(count, objectArrayClass,
   4977                 NULL));
   4978 
   4979         for (int i = 0; i < count; i++) {
   4980             ScopedLocalRef<jobject> item(env, env->GetObjectArrayElement(joa.get(), i));
   4981             env->SetObjectArrayElement(joa_copy.get(), i, item.get());
   4982         }
   4983 
   4984         joa.reset(joa_copy.release());
   4985     }
   4986 
   4987     JNI_TRACE("get_X509_GENERAL_NAME_stack(%p, %d) => %d entries", x509, type, count);
   4988     return joa.release();
   4989 }
   4990 
   4991 static jlong NativeCrypto_X509_get_notBefore(JNIEnv* env, jclass, jlong x509Ref) {
   4992     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   4993     JNI_TRACE("X509_get_notBefore(%p)", x509);
   4994 
   4995     if (x509 == NULL) {
   4996         jniThrowNullPointerException(env, "x509 == null");
   4997         JNI_TRACE("X509_get_notBefore(%p) => x509 == null", x509);
   4998         return 0;
   4999     }
   5000 
   5001     ASN1_TIME* notBefore = X509_get_notBefore(x509);
   5002     JNI_TRACE("X509_get_notBefore(%p) => %p", x509, notBefore);
   5003     return reinterpret_cast<uintptr_t>(notBefore);
   5004 }
   5005 
   5006 static jlong NativeCrypto_X509_get_notAfter(JNIEnv* env, jclass, jlong x509Ref) {
   5007     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5008     JNI_TRACE("X509_get_notAfter(%p)", x509);
   5009 
   5010     if (x509 == NULL) {
   5011         jniThrowNullPointerException(env, "x509 == null");
   5012         JNI_TRACE("X509_get_notAfter(%p) => x509 == null", x509);
   5013         return 0;
   5014     }
   5015 
   5016     ASN1_TIME* notAfter = X509_get_notAfter(x509);
   5017     JNI_TRACE("X509_get_notAfter(%p) => %p", x509, notAfter);
   5018     return reinterpret_cast<uintptr_t>(notAfter);
   5019 }
   5020 
   5021 static long NativeCrypto_X509_get_version(JNIEnv*, jclass, jlong x509Ref) {
   5022     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5023     JNI_TRACE("X509_get_version(%p)", x509);
   5024 
   5025     long version = X509_get_version(x509);
   5026     JNI_TRACE("X509_get_version(%p) => %ld", x509, version);
   5027     return version;
   5028 }
   5029 
   5030 template<typename T>
   5031 static jbyteArray get_X509Type_serialNumber(JNIEnv* env, T* x509Type, ASN1_INTEGER* (*get_serial_func)(T*)) {
   5032     JNI_TRACE("get_X509Type_serialNumber(%p)", x509Type);
   5033 
   5034     if (x509Type == NULL) {
   5035         jniThrowNullPointerException(env, "x509Type == null");
   5036         JNI_TRACE("get_X509Type_serialNumber(%p) => x509Type == null", x509Type);
   5037         return NULL;
   5038     }
   5039 
   5040     ASN1_INTEGER* serialNumber = get_serial_func(x509Type);
   5041     Unique_BIGNUM serialBn(ASN1_INTEGER_to_BN(serialNumber, NULL));
   5042     if (serialBn.get() == NULL) {
   5043         JNI_TRACE("X509_get_serialNumber(%p) => threw exception", x509Type);
   5044         return NULL;
   5045     }
   5046 
   5047     ScopedLocalRef<jbyteArray> serialArray(env, bignumToArray(env, serialBn.get(), "serialBn"));
   5048     if (env->ExceptionCheck()) {
   5049         JNI_TRACE("X509_get_serialNumber(%p) => threw exception", x509Type);
   5050         return NULL;
   5051     }
   5052 
   5053     JNI_TRACE("X509_get_serialNumber(%p) => %p", x509Type, serialArray.get());
   5054     return serialArray.release();
   5055 }
   5056 
   5057 /* OpenSSL includes set_serialNumber but not get. */
   5058 #if !defined(X509_REVOKED_get_serialNumber)
   5059 static ASN1_INTEGER* X509_REVOKED_get_serialNumber(X509_REVOKED* x) {
   5060     return x->serialNumber;
   5061 }
   5062 #endif
   5063 
   5064 static jbyteArray NativeCrypto_X509_get_serialNumber(JNIEnv* env, jclass, jlong x509Ref) {
   5065     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5066     JNI_TRACE("X509_get_serialNumber(%p)", x509);
   5067     return get_X509Type_serialNumber<X509>(env, x509, X509_get_serialNumber);
   5068 }
   5069 
   5070 static jbyteArray NativeCrypto_X509_REVOKED_get_serialNumber(JNIEnv* env, jclass, jlong x509RevokedRef) {
   5071     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   5072     JNI_TRACE("X509_REVOKED_get_serialNumber(%p)", revoked);
   5073     return get_X509Type_serialNumber<X509_REVOKED>(env, revoked, X509_REVOKED_get_serialNumber);
   5074 }
   5075 
   5076 static void NativeCrypto_X509_verify(JNIEnv* env, jclass, jlong x509Ref, jlong pkeyRef) {
   5077     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5078     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   5079     JNI_TRACE("X509_verify(%p, %p)", x509, pkey);
   5080 
   5081     if (x509 == NULL) {
   5082         jniThrowNullPointerException(env, "x509 == null");
   5083         JNI_TRACE("X509_verify(%p, %p) => x509 == null", x509, pkey);
   5084         return;
   5085     }
   5086 
   5087     if (pkey == NULL) {
   5088         jniThrowNullPointerException(env, "pkey == null");
   5089         JNI_TRACE("X509_verify(%p, %p) => pkey == null", x509, pkey);
   5090         return;
   5091     }
   5092 
   5093     if (X509_verify(x509, pkey) != 1) {
   5094         throwExceptionIfNecessary(env, "X509_verify");
   5095         JNI_TRACE("X509_verify(%p, %p) => verify failure", x509, pkey);
   5096     } else {
   5097         JNI_TRACE("X509_verify(%p, %p) => verify success", x509, pkey);
   5098     }
   5099 }
   5100 
   5101 static jbyteArray NativeCrypto_get_X509_cert_info_enc(JNIEnv* env, jclass, jlong x509Ref) {
   5102     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5103     JNI_TRACE("get_X509_cert_info_enc(%p)", x509);
   5104     return ASN1ToByteArray<X509_CINF, i2d_X509_CINF>(env, x509->cert_info);
   5105 }
   5106 
   5107 static jint NativeCrypto_get_X509_ex_flags(JNIEnv* env, jclass, jlong x509Ref) {
   5108     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5109     JNI_TRACE("get_X509_ex_flags(%p)", x509);
   5110 
   5111     if (x509 == NULL) {
   5112         jniThrowNullPointerException(env, "x509 == null");
   5113         JNI_TRACE("get_X509_ex_flags(%p) => x509 == null", x509);
   5114         return 0;
   5115     }
   5116 
   5117     X509_check_ca(x509);
   5118 
   5119     return x509->ex_flags;
   5120 }
   5121 
   5122 static jboolean NativeCrypto_X509_check_issued(JNIEnv*, jclass, jlong x509Ref1, jlong x509Ref2) {
   5123     X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
   5124     X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
   5125     JNI_TRACE("X509_check_issued(%p, %p)", x509_1, x509_2);
   5126 
   5127     int ret = X509_check_issued(x509_1, x509_2);
   5128     JNI_TRACE("X509_check_issued(%p, %p) => %d", x509_1, x509_2, ret);
   5129     return ret;
   5130 }
   5131 
   5132 static void get_X509_signature(X509 *x509, ASN1_BIT_STRING** signature) {
   5133     *signature = x509->signature;
   5134 }
   5135 
   5136 static void get_X509_CRL_signature(X509_CRL *crl, ASN1_BIT_STRING** signature) {
   5137     *signature = crl->signature;
   5138 }
   5139 
   5140 template<typename T>
   5141 static jbyteArray get_X509Type_signature(JNIEnv* env, T* x509Type, void (*get_signature_func)(T*, ASN1_BIT_STRING**)) {
   5142     JNI_TRACE("get_X509Type_signature(%p)", x509Type);
   5143 
   5144     if (x509Type == NULL) {
   5145         jniThrowNullPointerException(env, "x509Type == null");
   5146         JNI_TRACE("get_X509Type_signature(%p) => x509Type == null", x509Type);
   5147         return NULL;
   5148     }
   5149 
   5150     ASN1_BIT_STRING* signature;
   5151     get_signature_func(x509Type, &signature);
   5152 
   5153     ScopedLocalRef<jbyteArray> signatureArray(env, env->NewByteArray(signature->length));
   5154     if (env->ExceptionCheck()) {
   5155         JNI_TRACE("get_X509Type_signature(%p) => threw exception", x509Type);
   5156         return NULL;
   5157     }
   5158 
   5159     ScopedByteArrayRW signatureBytes(env, signatureArray.get());
   5160     if (signatureBytes.get() == NULL) {
   5161         JNI_TRACE("get_X509Type_signature(%p) => using byte array failed", x509Type);
   5162         return NULL;
   5163     }
   5164 
   5165     memcpy(signatureBytes.get(), signature->data, signature->length);
   5166 
   5167     JNI_TRACE("get_X509Type_signature(%p) => %p (%d bytes)", x509Type, signatureArray.get(),
   5168             signature->length);
   5169     return signatureArray.release();
   5170 }
   5171 
   5172 static jbyteArray NativeCrypto_get_X509_signature(JNIEnv* env, jclass, jlong x509Ref) {
   5173     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5174     JNI_TRACE("get_X509_signature(%p)", x509);
   5175     return get_X509Type_signature<X509>(env, x509, get_X509_signature);
   5176 }
   5177 
   5178 static jbyteArray NativeCrypto_get_X509_CRL_signature(JNIEnv* env, jclass, jlong x509CrlRef) {
   5179     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5180     JNI_TRACE("get_X509_CRL_signature(%p)", crl);
   5181     return get_X509Type_signature<X509_CRL>(env, crl, get_X509_CRL_signature);
   5182 }
   5183 
   5184 static jlong NativeCrypto_X509_CRL_get0_by_cert(JNIEnv* env, jclass, jlong x509crlRef, jlong x509Ref) {
   5185     X509_CRL* x509crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509crlRef));
   5186     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5187     JNI_TRACE("X509_CRL_get0_by_cert(%p, %p)", x509crl, x509);
   5188 
   5189     if (x509crl == NULL) {
   5190         jniThrowNullPointerException(env, "x509crl == null");
   5191         JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => x509crl == null", x509crl, x509);
   5192         return 0;
   5193     } else if (x509 == NULL) {
   5194         jniThrowNullPointerException(env, "x509 == null");
   5195         JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => x509 == null", x509crl, x509);
   5196         return 0;
   5197     }
   5198 
   5199     X509_REVOKED* revoked = NULL;
   5200     int ret = X509_CRL_get0_by_cert(x509crl, &revoked, x509);
   5201     if (ret == 0) {
   5202         JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => none", x509crl, x509);
   5203         return 0;
   5204     }
   5205 
   5206     JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => %p", x509crl, x509, revoked);
   5207     return reinterpret_cast<uintptr_t>(revoked);
   5208 }
   5209 
   5210 static jlong NativeCrypto_X509_CRL_get0_by_serial(JNIEnv* env, jclass, jlong x509crlRef, jbyteArray serialArray) {
   5211     X509_CRL* x509crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509crlRef));
   5212     JNI_TRACE("X509_CRL_get0_by_serial(%p, %p)", x509crl, serialArray);
   5213 
   5214     if (x509crl == NULL) {
   5215         jniThrowNullPointerException(env, "x509crl == null");
   5216         JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => crl == null", x509crl, serialArray);
   5217         return 0;
   5218     }
   5219 
   5220     Unique_BIGNUM serialBn(BN_new());
   5221     if (serialBn.get() == NULL) {
   5222         JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN allocation failed", x509crl, serialArray);
   5223         return 0;
   5224     }
   5225 
   5226     BIGNUM* serialBare = serialBn.get();
   5227     if (!arrayToBignum(env, serialArray, &serialBare)) {
   5228         if (!env->ExceptionCheck()) {
   5229             jniThrowNullPointerException(env, "serial == null");
   5230         }
   5231         JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN conversion failed", x509crl, serialArray);
   5232         return 0;
   5233     }
   5234 
   5235     Unique_ASN1_INTEGER serialInteger(BN_to_ASN1_INTEGER(serialBn.get(), NULL));
   5236     if (serialInteger.get() == NULL) {
   5237         JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => BN conversion failed", x509crl, serialArray);
   5238         return 0;
   5239     }
   5240 
   5241     X509_REVOKED* revoked = NULL;
   5242     int ret = X509_CRL_get0_by_serial(x509crl, &revoked, serialInteger.get());
   5243     if (ret == 0) {
   5244         JNI_TRACE("X509_CRL_get0_by_serial(%p, %p) => none", x509crl, serialArray);
   5245         return 0;
   5246     }
   5247 
   5248     JNI_TRACE("X509_CRL_get0_by_cert(%p, %p) => %p", x509crl, serialArray, revoked);
   5249     return reinterpret_cast<uintptr_t>(revoked);
   5250 }
   5251 
   5252 
   5253 /* This appears to be missing from OpenSSL. */
   5254 #if !defined(X509_REVOKED_dup)
   5255 X509_REVOKED* X509_REVOKED_dup(X509_REVOKED* x) {
   5256     return reinterpret_cast<X509_REVOKED*>(ASN1_item_dup(ASN1_ITEM_rptr(X509_REVOKED), x));
   5257 }
   5258 #endif
   5259 
   5260 static jlongArray NativeCrypto_X509_CRL_get_REVOKED(JNIEnv* env, jclass, jlong x509CrlRef) {
   5261     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5262     JNI_TRACE("X509_CRL_get_REVOKED(%p)", crl);
   5263 
   5264     if (crl == NULL) {
   5265         jniThrowNullPointerException(env, "crl == null");
   5266         return NULL;
   5267     }
   5268 
   5269     STACK_OF(X509_REVOKED)* stack = X509_CRL_get_REVOKED(crl);
   5270     if (stack == NULL) {
   5271         JNI_TRACE("X509_CRL_get_REVOKED(%p) => stack is null", crl);
   5272         return NULL;
   5273     }
   5274 
   5275     size_t size = sk_X509_REVOKED_num(stack);
   5276 
   5277     ScopedLocalRef<jlongArray> revokedArray(env, env->NewLongArray(size));
   5278     ScopedLongArrayRW revoked(env, revokedArray.get());
   5279     for (size_t i = 0; i < size; i++) {
   5280         X509_REVOKED* item = reinterpret_cast<X509_REVOKED*>(sk_X509_REVOKED_value(stack, i));
   5281         revoked[i] = reinterpret_cast<uintptr_t>(X509_REVOKED_dup(item));
   5282     }
   5283 
   5284     JNI_TRACE("X509_CRL_get_REVOKED(%p) => %p [size=%d]", stack, revokedArray.get(), size);
   5285     return revokedArray.release();
   5286 }
   5287 
   5288 static jbyteArray NativeCrypto_i2d_X509_CRL(JNIEnv* env, jclass, jlong x509CrlRef) {
   5289     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5290     JNI_TRACE("i2d_X509_CRL(%p)", crl);
   5291     return ASN1ToByteArray<X509_CRL, i2d_X509_CRL>(env, crl);
   5292 }
   5293 
   5294 static void NativeCrypto_X509_CRL_free(JNIEnv* env, jclass, jlong x509CrlRef) {
   5295     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5296     JNI_TRACE("X509_CRL_free(%p)", crl);
   5297 
   5298     if (crl == NULL) {
   5299         jniThrowNullPointerException(env, "crl == null");
   5300         JNI_TRACE("X509_CRL_free(%p) => crl == null", crl);
   5301         return;
   5302     }
   5303 
   5304     X509_CRL_free(crl);
   5305 }
   5306 
   5307 static void NativeCrypto_X509_CRL_print(JNIEnv* env, jclass, jlong bioRef, jlong x509CrlRef) {
   5308     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5309     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5310     JNI_TRACE("X509_CRL_print(%p, %p)", bio, crl);
   5311 
   5312     if (bio == NULL) {
   5313         jniThrowNullPointerException(env, "bio == null");
   5314         JNI_TRACE("X509_CRL_print(%p, %p) => bio == null", bio, crl);
   5315         return;
   5316     }
   5317 
   5318     if (crl == NULL) {
   5319         jniThrowNullPointerException(env, "crl == null");
   5320         JNI_TRACE("X509_CRL_print(%p, %p) => crl == null", bio, crl);
   5321         return;
   5322     }
   5323 
   5324     if (!X509_CRL_print(bio, crl)) {
   5325         throwExceptionIfNecessary(env, "X509_CRL_print");
   5326         JNI_TRACE("X509_CRL_print(%p, %p) => threw error", bio, crl);
   5327     } else {
   5328         JNI_TRACE("X509_CRL_print(%p, %p) => success", bio, crl);
   5329     }
   5330 }
   5331 
   5332 static jstring NativeCrypto_get_X509_CRL_sig_alg_oid(JNIEnv* env, jclass, jlong x509CrlRef) {
   5333     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5334     JNI_TRACE("get_X509_CRL_sig_alg_oid(%p)", crl);
   5335 
   5336     if (crl == NULL || crl->sig_alg == NULL) {
   5337         jniThrowNullPointerException(env, "crl == NULL || crl->sig_alg == NULL");
   5338         JNI_TRACE("get_X509_CRL_sig_alg_oid(%p) => crl == NULL", crl);
   5339         return NULL;
   5340     }
   5341 
   5342     return ASN1_OBJECT_to_OID_string(env, crl->sig_alg->algorithm);
   5343 }
   5344 
   5345 static jbyteArray NativeCrypto_get_X509_CRL_sig_alg_parameter(JNIEnv* env, jclass, jlong x509CrlRef) {
   5346     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5347     JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p)", crl);
   5348 
   5349     if (crl == NULL) {
   5350         jniThrowNullPointerException(env, "crl == null");
   5351         JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p) => crl == null", crl);
   5352         return NULL;
   5353     }
   5354 
   5355     if (crl->sig_alg->parameter == NULL) {
   5356         JNI_TRACE("get_X509_CRL_sig_alg_parameter(%p) => null", crl);
   5357         return NULL;
   5358     }
   5359 
   5360     return ASN1ToByteArray<ASN1_TYPE, i2d_ASN1_TYPE>(env, crl->sig_alg->parameter);
   5361 }
   5362 
   5363 static jbyteArray NativeCrypto_X509_CRL_get_issuer_name(JNIEnv* env, jclass, jlong x509CrlRef) {
   5364     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5365     JNI_TRACE("X509_CRL_get_issuer_name(%p)", crl);
   5366     return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_CRL_get_issuer(crl));
   5367 }
   5368 
   5369 static long NativeCrypto_X509_CRL_get_version(JNIEnv*, jclass, jlong x509CrlRef) {
   5370     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5371     JNI_TRACE("X509_CRL_get_version(%p)", crl);
   5372 
   5373     long version = X509_CRL_get_version(crl);
   5374     JNI_TRACE("X509_CRL_get_version(%p) => %ld", crl, version);
   5375     return version;
   5376 }
   5377 
   5378 template<typename T, int (*get_ext_by_OBJ_func)(T*, ASN1_OBJECT*, int),
   5379         X509_EXTENSION* (*get_ext_func)(T*, int)>
   5380 static X509_EXTENSION *X509Type_get_ext(JNIEnv* env, T* x509Type, jstring oidString) {
   5381     JNI_TRACE("X509Type_get_ext(%p)", x509Type);
   5382 
   5383     if (x509Type == NULL) {
   5384         jniThrowNullPointerException(env, "x509 == null");
   5385         return NULL;
   5386     }
   5387 
   5388     ScopedUtfChars oid(env, oidString);
   5389     if (oid.c_str() == NULL) {
   5390         return NULL;
   5391     }
   5392 
   5393     Unique_ASN1_OBJECT asn1(OBJ_txt2obj(oid.c_str(), 1));
   5394     if (asn1.get() == NULL) {
   5395         JNI_TRACE("X509Type_get_ext(%p, %s) => oid conversion failed", x509Type, oid.c_str());
   5396         freeOpenSslErrorState();
   5397         return NULL;
   5398     }
   5399 
   5400     int extIndex = get_ext_by_OBJ_func(x509Type, asn1.get(), -1);
   5401     if (extIndex == -1) {
   5402         JNI_TRACE("X509Type_get_ext(%p, %s) => ext not found", x509Type, oid.c_str());
   5403         return NULL;
   5404     }
   5405 
   5406     X509_EXTENSION* ext = get_ext_func(x509Type, extIndex);
   5407     JNI_TRACE("X509Type_get_ext(%p, %s) => %p", x509Type, oid.c_str(), ext);
   5408     return ext;
   5409 }
   5410 
   5411 template<typename T, int (*get_ext_by_OBJ_func)(T*, ASN1_OBJECT*, int),
   5412         X509_EXTENSION* (*get_ext_func)(T*, int)>
   5413 static jbyteArray X509Type_get_ext_oid(JNIEnv* env, T* x509Type, jstring oidString) {
   5414     X509_EXTENSION* ext = X509Type_get_ext<T, get_ext_by_OBJ_func, get_ext_func>(env, x509Type,
   5415             oidString);
   5416     if (ext == NULL) {
   5417         JNI_TRACE("X509Type_get_ext_oid(%p, %p) => fetching extension failed", x509Type, oidString);
   5418         return NULL;
   5419     }
   5420 
   5421     JNI_TRACE("X509Type_get_ext_oid(%p, %p) => %p", x509Type, oidString, ext->value);
   5422     return ASN1ToByteArray<ASN1_OCTET_STRING, i2d_ASN1_OCTET_STRING>(env, ext->value);
   5423 }
   5424 
   5425 static jint NativeCrypto_X509_CRL_get_ext(JNIEnv* env, jclass, jlong x509CrlRef, jstring oid) {
   5426     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5427     JNI_TRACE("X509_CRL_get_ext(%p, %p)", crl, oid);
   5428     X509_EXTENSION* ext = X509Type_get_ext<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(
   5429             env, crl, oid);
   5430     JNI_TRACE("X509_CRL_get_ext(%p, %p) => %p", crl, oid, ext);
   5431     return reinterpret_cast<uintptr_t>(ext);
   5432 }
   5433 
   5434 static jint NativeCrypto_X509_REVOKED_get_ext(JNIEnv* env, jclass, jlong x509RevokedRef,
   5435         jstring oid) {
   5436     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   5437     JNI_TRACE("X509_REVOKED_get_ext(%p, %p)", revoked, oid);
   5438     X509_EXTENSION* ext = X509Type_get_ext<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ,
   5439             X509_REVOKED_get_ext>(env, revoked, oid);
   5440     JNI_TRACE("X509_REVOKED_get_ext(%p, %p) => %p", revoked, oid, ext);
   5441     return reinterpret_cast<uintptr_t>(ext);
   5442 }
   5443 
   5444 static jlong NativeCrypto_X509_REVOKED_dup(JNIEnv* env, jclass, jlong x509RevokedRef) {
   5445     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   5446     JNI_TRACE("X509_REVOKED_dup(%p)", revoked);
   5447 
   5448     if (revoked == NULL) {
   5449         jniThrowNullPointerException(env, "revoked == null");
   5450         JNI_TRACE("X509_REVOKED_dup(%p) => revoked == null", revoked);
   5451         return 0;
   5452     }
   5453 
   5454     X509_REVOKED* dup = X509_REVOKED_dup(revoked);
   5455     JNI_TRACE("X509_REVOKED_dup(%p) => %p", revoked, dup);
   5456     return reinterpret_cast<uintptr_t>(dup);
   5457 }
   5458 
   5459 static jlong NativeCrypto_get_X509_REVOKED_revocationDate(JNIEnv* env, jclass, jlong x509RevokedRef) {
   5460     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   5461     JNI_TRACE("get_X509_REVOKED_revocationDate(%p)", revoked);
   5462 
   5463     if (revoked == NULL) {
   5464         jniThrowNullPointerException(env, "revoked == null");
   5465         JNI_TRACE("get_X509_REVOKED_revocationDate(%p) => revoked == null", revoked);
   5466         return 0;
   5467     }
   5468 
   5469     JNI_TRACE("get_X509_REVOKED_revocationDate(%p) => %p", revoked, revoked->revocationDate);
   5470     return reinterpret_cast<uintptr_t>(revoked->revocationDate);
   5471 }
   5472 
   5473 #pragma GCC diagnostic push
   5474 #pragma GCC diagnostic ignored "-Wwrite-strings"
   5475 static void NativeCrypto_X509_REVOKED_print(JNIEnv* env, jclass, jlong bioRef, jlong x509RevokedRef) {
   5476     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5477     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   5478     JNI_TRACE("X509_REVOKED_print(%p, %p)", bio, revoked);
   5479 
   5480     if (bio == NULL) {
   5481         jniThrowNullPointerException(env, "bio == null");
   5482         JNI_TRACE("X509_REVOKED_print(%p, %p) => bio == null", bio, revoked);
   5483         return;
   5484     }
   5485 
   5486     if (revoked == NULL) {
   5487         jniThrowNullPointerException(env, "revoked == null");
   5488         JNI_TRACE("X509_REVOKED_print(%p, %p) => revoked == null", bio, revoked);
   5489         return;
   5490     }
   5491 
   5492     BIO_printf(bio, "Serial Number: ");
   5493     i2a_ASN1_INTEGER(bio, revoked->serialNumber);
   5494     BIO_printf(bio, "\nRevocation Date: ");
   5495     ASN1_TIME_print(bio, revoked->revocationDate);
   5496     BIO_printf(bio, "\n");
   5497     X509V3_extensions_print(bio, "CRL entry extensions", revoked->extensions, 0, 0);
   5498 }
   5499 #pragma GCC diagnostic pop
   5500 
   5501 static jbyteArray NativeCrypto_get_X509_CRL_crl_enc(JNIEnv* env, jclass, jlong x509CrlRef) {
   5502     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5503     JNI_TRACE("get_X509_CRL_crl_enc(%p)", crl);
   5504     return ASN1ToByteArray<X509_CRL_INFO, i2d_X509_CRL_INFO>(env, crl->crl);
   5505 }
   5506 
   5507 static void NativeCrypto_X509_CRL_verify(JNIEnv* env, jclass, jlong x509CrlRef, jlong pkeyRef) {
   5508     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5509     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   5510     JNI_TRACE("X509_CRL_verify(%p, %p)", crl, pkey);
   5511 
   5512     if (crl == NULL) {
   5513         jniThrowNullPointerException(env, "crl == null");
   5514         JNI_TRACE("X509_CRL_verify(%p, %p) => crl == null", crl, pkey);
   5515         return;
   5516     }
   5517 
   5518     if (pkey == NULL) {
   5519         jniThrowNullPointerException(env, "pkey == null");
   5520         JNI_TRACE("X509_CRL_verify(%p, %p) => pkey == null", crl, pkey);
   5521         return;
   5522     }
   5523 
   5524     if (X509_CRL_verify(crl, pkey) != 1) {
   5525         throwExceptionIfNecessary(env, "X509_CRL_verify");
   5526         JNI_TRACE("X509_CRL_verify(%p, %p) => verify failure", crl, pkey);
   5527     } else {
   5528         JNI_TRACE("X509_CRL_verify(%p, %p) => verify success", crl, pkey);
   5529     }
   5530 }
   5531 
   5532 static jlong NativeCrypto_X509_CRL_get_lastUpdate(JNIEnv* env, jclass, jlong x509CrlRef) {
   5533     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5534     JNI_TRACE("X509_CRL_get_lastUpdate(%p)", crl);
   5535 
   5536     if (crl == NULL) {
   5537         jniThrowNullPointerException(env, "crl == null");
   5538         JNI_TRACE("X509_CRL_get_lastUpdate(%p) => crl == null", crl);
   5539         return 0;
   5540     }
   5541 
   5542     ASN1_TIME* lastUpdate = X509_CRL_get_lastUpdate(crl);
   5543     JNI_TRACE("X509_CRL_get_lastUpdate(%p) => %p", crl, lastUpdate);
   5544     return reinterpret_cast<uintptr_t>(lastUpdate);
   5545 }
   5546 
   5547 static jlong NativeCrypto_X509_CRL_get_nextUpdate(JNIEnv* env, jclass, jlong x509CrlRef) {
   5548     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   5549     JNI_TRACE("X509_CRL_get_nextUpdate(%p)", crl);
   5550 
   5551     if (crl == NULL) {
   5552         jniThrowNullPointerException(env, "crl == null");
   5553         JNI_TRACE("X509_CRL_get_nextUpdate(%p) => crl == null", crl);
   5554         return 0;
   5555     }
   5556 
   5557     ASN1_TIME* nextUpdate = X509_CRL_get_nextUpdate(crl);
   5558     JNI_TRACE("X509_CRL_get_nextUpdate(%p) => %p", crl, nextUpdate);
   5559     return reinterpret_cast<uintptr_t>(nextUpdate);
   5560 }
   5561 
   5562 static jbyteArray NativeCrypto_i2d_X509_REVOKED(JNIEnv* env, jclass, jlong x509RevokedRef) {
   5563     X509_REVOKED* x509Revoked =
   5564             reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   5565     JNI_TRACE("i2d_X509_REVOKED(%p)", x509Revoked);
   5566     return ASN1ToByteArray<X509_REVOKED, i2d_X509_REVOKED>(env, x509Revoked);
   5567 }
   5568 
   5569 static jint NativeCrypto_X509_supported_extension(JNIEnv* env, jclass, jlong x509ExtensionRef) {
   5570     X509_EXTENSION* ext = reinterpret_cast<X509_EXTENSION*>(static_cast<uintptr_t>(x509ExtensionRef));
   5571 
   5572     if (ext == NULL) {
   5573         jniThrowNullPointerException(env, "ext == NULL");
   5574         return 0;
   5575     }
   5576 
   5577     return X509_supported_extension(ext);
   5578 }
   5579 
   5580 static inline void get_ASN1_TIME_data(char **data, int* output, size_t len) {
   5581     char c = **data;
   5582     **data = '\0';
   5583     *data -= len;
   5584     *output = atoi(*data);
   5585     *(*data + len) = c;
   5586 }
   5587 
   5588 static void NativeCrypto_ASN1_TIME_to_Calendar(JNIEnv* env, jclass, jlong asn1TimeRef, jobject calendar) {
   5589     ASN1_TIME* asn1Time = reinterpret_cast<ASN1_TIME*>(static_cast<uintptr_t>(asn1TimeRef));
   5590     JNI_TRACE("ASN1_TIME_to_Calendar(%p, %p)", asn1Time, calendar);
   5591 
   5592     if (asn1Time == NULL) {
   5593         jniThrowNullPointerException(env, "asn1Time == null");
   5594         return;
   5595     }
   5596 
   5597     Unique_ASN1_GENERALIZEDTIME gen(ASN1_TIME_to_generalizedtime(asn1Time, NULL));
   5598     if (gen.get() == NULL) {
   5599         jniThrowNullPointerException(env, "asn1Time == null");
   5600         return;
   5601     }
   5602 
   5603     if (gen->length < 14 || gen->data == NULL) {
   5604         jniThrowNullPointerException(env, "gen->length < 14 || gen->data == NULL");
   5605         return;
   5606     }
   5607 
   5608     int sec, min, hour, mday, mon, year;
   5609 
   5610     char *p = (char*) &gen->data[14];
   5611 
   5612     get_ASN1_TIME_data(&p, &sec, 2);
   5613     get_ASN1_TIME_data(&p, &min, 2);
   5614     get_ASN1_TIME_data(&p, &hour, 2);
   5615     get_ASN1_TIME_data(&p, &mday, 2);
   5616     get_ASN1_TIME_data(&p, &mon, 2);
   5617     get_ASN1_TIME_data(&p, &year, 4);
   5618 
   5619     env->CallVoidMethod(calendar, calendar_setMethod, year, mon - 1, mday, hour, min, sec);
   5620 }
   5621 
   5622 static jstring NativeCrypto_OBJ_txt2nid_oid(JNIEnv* env, jclass, jstring oidStr) {
   5623     JNI_TRACE("OBJ_txt2nid_oid(%p)", oidStr);
   5624 
   5625     ScopedUtfChars oid(env, oidStr);
   5626     if (oid.c_str() == NULL) {
   5627         return NULL;
   5628     }
   5629 
   5630     JNI_TRACE("OBJ_txt2nid_oid(%s)", oid.c_str());
   5631 
   5632     int nid = OBJ_txt2nid(oid.c_str());
   5633     if (nid == NID_undef) {
   5634         JNI_TRACE("OBJ_txt2nid_oid(%s) => NID_undef", oid.c_str());
   5635         freeOpenSslErrorState();
   5636         return NULL;
   5637     }
   5638 
   5639     Unique_ASN1_OBJECT obj(OBJ_nid2obj(nid));
   5640     if (obj.get() == NULL) {
   5641         throwExceptionIfNecessary(env, "OBJ_nid2obj");
   5642         return NULL;
   5643     }
   5644 
   5645     ScopedLocalRef<jstring> ouputStr(env, ASN1_OBJECT_to_OID_string(env, obj.get()));
   5646     JNI_TRACE("OBJ_txt2nid_oid(%s) => %p", oid.c_str(), ouputStr.get());
   5647     return ouputStr.release();
   5648 }
   5649 
   5650 static jstring NativeCrypto_X509_NAME_print_ex(JNIEnv* env, jclass, jlong x509NameRef, jlong jflags) {
   5651     X509_NAME* x509name = reinterpret_cast<X509_NAME*>(static_cast<uintptr_t>(x509NameRef));
   5652     unsigned long flags = static_cast<unsigned long>(jflags);
   5653     JNI_TRACE("X509_NAME_print_ex(%p, %ld)", x509name, flags);
   5654 
   5655     if (x509name == NULL) {
   5656         jniThrowNullPointerException(env, "x509name == null");
   5657         JNI_TRACE("X509_NAME_print_ex(%p, %ld) => x509name == null", x509name, flags);
   5658         return NULL;
   5659     }
   5660 
   5661     return X509_NAME_to_jstring(env, x509name, flags);
   5662 }
   5663 
   5664 template <typename T, T* (*d2i_func)(BIO*, T**)>
   5665 static jlong d2i_ASN1Object_to_jlong(JNIEnv* env, jlong bioRef) {
   5666     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5667     JNI_TRACE("d2i_ASN1Object_to_jlong(%p)", bio);
   5668 
   5669     if (bio == NULL) {
   5670         jniThrowNullPointerException(env, "bio == null");
   5671         return 0;
   5672     }
   5673 
   5674     T* x = d2i_func(bio, NULL);
   5675     if (x == NULL) {
   5676         throwExceptionIfNecessary(env, "d2i_ASN1Object_to_jlong");
   5677         return 0;
   5678     }
   5679 
   5680     return reinterpret_cast<uintptr_t>(x);
   5681 }
   5682 
   5683 static jlong NativeCrypto_d2i_X509_CRL_bio(JNIEnv* env, jclass, jlong bioRef) {
   5684     return d2i_ASN1Object_to_jlong<X509_CRL, d2i_X509_CRL_bio>(env, bioRef);
   5685 }
   5686 
   5687 static jlong NativeCrypto_d2i_X509_bio(JNIEnv* env, jclass, jlong bioRef) {
   5688     return d2i_ASN1Object_to_jlong<X509, d2i_X509_bio>(env, bioRef);
   5689 }
   5690 
   5691 static jlong NativeCrypto_d2i_X509(JNIEnv* env, jclass, jbyteArray certBytes) {
   5692     X509* x = ByteArrayToASN1<X509, d2i_X509>(env, certBytes);
   5693     return reinterpret_cast<uintptr_t>(x);
   5694 }
   5695 
   5696 static jbyteArray NativeCrypto_i2d_X509(JNIEnv* env, jclass, jlong x509Ref) {
   5697     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5698     JNI_TRACE("i2d_X509(%p)", x509);
   5699     return ASN1ToByteArray<X509, i2d_X509>(env, x509);
   5700 }
   5701 
   5702 static jbyteArray NativeCrypto_i2d_X509_PUBKEY(JNIEnv* env, jclass, jlong x509Ref) {
   5703     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5704     JNI_TRACE("i2d_X509_PUBKEY(%p)", x509);
   5705     return ASN1ToByteArray<X509_PUBKEY, i2d_X509_PUBKEY>(env, X509_get_X509_PUBKEY(x509));
   5706 }
   5707 
   5708 
   5709 template<typename T, T* (*PEM_read_func)(BIO*, T**, pem_password_cb*, void*)>
   5710 static jlong PEM_ASN1Object_to_jlong(JNIEnv* env, jlong bioRef) {
   5711     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5712     JNI_TRACE("PEM_ASN1Object_to_jlong(%p)", bio);
   5713 
   5714     if (bio == NULL) {
   5715         jniThrowNullPointerException(env, "bio == null");
   5716         JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => bio == null", bio);
   5717         return 0;
   5718     }
   5719 
   5720     T* x = PEM_read_func(bio, NULL, NULL, NULL);
   5721     if (x == NULL) {
   5722         throwExceptionIfNecessary(env, "PEM_ASN1Object_to_jlong");
   5723         // Sometimes the PEM functions fail without pushing an error
   5724         if (!env->ExceptionCheck()) {
   5725             jniThrowRuntimeException(env, "Failure parsing PEM");
   5726         }
   5727         JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => threw exception", bio);
   5728         return 0;
   5729     }
   5730 
   5731     JNI_TRACE("PEM_ASN1Object_to_jlong(%p) => %p", bio, x);
   5732     return reinterpret_cast<uintptr_t>(x);
   5733 }
   5734 
   5735 static jlong NativeCrypto_PEM_read_bio_X509(JNIEnv* env, jclass, jlong bioRef) {
   5736     JNI_TRACE("PEM_read_bio_X509(0x%llx)", bioRef);
   5737     return PEM_ASN1Object_to_jlong<X509, PEM_read_bio_X509>(env, bioRef);
   5738 }
   5739 
   5740 static jlong NativeCrypto_PEM_read_bio_X509_CRL(JNIEnv* env, jclass, jlong bioRef) {
   5741     JNI_TRACE("PEM_read_bio_X509_CRL(0x%llx)", bioRef);
   5742     return PEM_ASN1Object_to_jlong<X509_CRL, PEM_read_bio_X509_CRL>(env, bioRef);
   5743 }
   5744 
   5745 static STACK_OF(X509)* PKCS7_get_certs(PKCS7* pkcs7) {
   5746     if (PKCS7_type_is_signed(pkcs7)) {
   5747         return pkcs7->d.sign->cert;
   5748     } else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) {
   5749         return pkcs7->d.signed_and_enveloped->cert;
   5750     } else {
   5751         JNI_TRACE("PKCS7_get_certs(%p) => unknown PKCS7 type", pkcs7);
   5752         return NULL;
   5753     }
   5754 }
   5755 
   5756 static STACK_OF(X509_CRL)* PKCS7_get_CRLs(PKCS7* pkcs7) {
   5757     if (PKCS7_type_is_signed(pkcs7)) {
   5758         return pkcs7->d.sign->crl;
   5759     } else if (PKCS7_type_is_signedAndEnveloped(pkcs7)) {
   5760         return pkcs7->d.signed_and_enveloped->crl;
   5761     } else {
   5762         JNI_TRACE("PKCS7_get_CRLs(%p) => unknown PKCS7 type", pkcs7);
   5763         return NULL;
   5764     }
   5765 }
   5766 
   5767 template <typename T, typename T_stack>
   5768 static jlongArray PKCS7_to_ItemArray(JNIEnv* env, T_stack* stack, T* (*dup_func)(T*))
   5769 {
   5770     if (stack == NULL) {
   5771         return NULL;
   5772     }
   5773 
   5774     ScopedLocalRef<jlongArray> ref_array(env, NULL);
   5775     size_t size = sk_num(reinterpret_cast<_STACK*>(stack));
   5776     ref_array.reset(env->NewLongArray(size));
   5777     ScopedLongArrayRW items(env, ref_array.get());
   5778     for (size_t i = 0; i < size; i++) {
   5779         T* item = reinterpret_cast<T*>(sk_value(reinterpret_cast<_STACK*>(stack), i));
   5780         items[i] = reinterpret_cast<uintptr_t>(dup_func(item));
   5781     }
   5782 
   5783     JNI_TRACE("PKCS7_to_ItemArray(%p) => %p [size=%d]", stack, ref_array.get(), size);
   5784     return ref_array.release();
   5785 }
   5786 
   5787 #define PKCS7_CERTS 1
   5788 #define PKCS7_CRLS 2
   5789 
   5790 static jlongArray NativeCrypto_PEM_read_bio_PKCS7(JNIEnv* env, jclass, jlong bioRef, jint which) {
   5791     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5792     JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p)", bio);
   5793 
   5794     if (bio == NULL) {
   5795         jniThrowNullPointerException(env, "bio == null");
   5796         JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p) => bio == null", bio);
   5797         return 0;
   5798     }
   5799 
   5800     Unique_PKCS7 pkcs7(PEM_read_bio_PKCS7(bio, NULL, NULL, NULL));
   5801     if (pkcs7.get() == NULL) {
   5802         throwExceptionIfNecessary(env, "PEM_read_bio_PKCS7_CRLs");
   5803         JNI_TRACE("PEM_read_bio_PKCS7_CRLs(%p) => threw exception", bio);
   5804         return 0;
   5805     }
   5806 
   5807     switch (which) {
   5808     case PKCS7_CERTS:
   5809         return PKCS7_to_ItemArray<X509, STACK_OF(X509)>(env, PKCS7_get_certs(pkcs7.get()), X509_dup);
   5810     case PKCS7_CRLS:
   5811         return PKCS7_to_ItemArray<X509_CRL, STACK_OF(X509_CRL)>(env, PKCS7_get_CRLs(pkcs7.get()),
   5812                 X509_CRL_dup);
   5813     default:
   5814         jniThrowRuntimeException(env, "unknown PKCS7 field");
   5815         return NULL;
   5816     }
   5817 }
   5818 
   5819 static jlongArray NativeCrypto_d2i_PKCS7_bio(JNIEnv* env, jclass, jlong bioRef, jint which) {
   5820     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5821     JNI_TRACE("d2i_PKCS7_bio(%p, %d)", bio, which);
   5822 
   5823     if (bio == NULL) {
   5824         jniThrowNullPointerException(env, "bio == null");
   5825         JNI_TRACE("d2i_PKCS7_bio(%p, %d) => bio == null", bio, which);
   5826         return 0;
   5827     }
   5828 
   5829     Unique_PKCS7 pkcs7(d2i_PKCS7_bio(bio, NULL));
   5830     if (pkcs7.get() == NULL) {
   5831         throwExceptionIfNecessary(env, "d2i_PKCS7_bio");
   5832         JNI_TRACE("d2i_PKCS7_bio(%p, %d) => threw exception", bio, which);
   5833         return 0;
   5834     }
   5835 
   5836     switch (which) {
   5837     case PKCS7_CERTS:
   5838         return PKCS7_to_ItemArray<X509, STACK_OF(X509)>(env, PKCS7_get_certs(pkcs7.get()), X509_dup);
   5839     case PKCS7_CRLS:
   5840         return PKCS7_to_ItemArray<X509_CRL, STACK_OF(X509_CRL)>(env, PKCS7_get_CRLs(pkcs7.get()),
   5841                 X509_CRL_dup);
   5842     default:
   5843         jniThrowRuntimeException(env, "unknown PKCS7 field");
   5844         return NULL;
   5845     }
   5846 }
   5847 
   5848 static jbyteArray NativeCrypto_i2d_PKCS7(JNIEnv* env, jclass, jlongArray certsArray) {
   5849     JNI_TRACE("i2d_PKCS7(%p)", certsArray);
   5850 
   5851     Unique_PKCS7 pkcs7(PKCS7_new());
   5852     if (pkcs7.get() == NULL) {
   5853         jniThrowNullPointerException(env, "pkcs7 == null");
   5854         JNI_TRACE("i2d_PKCS7(%p) => pkcs7 == null", certsArray);
   5855         return NULL;
   5856     }
   5857 
   5858     if (PKCS7_set_type(pkcs7.get(), NID_pkcs7_signed) != 1) {
   5859         throwExceptionIfNecessary(env, "PKCS7_set_type");
   5860         return NULL;
   5861     }
   5862 
   5863     // The EncapsulatedContentInfo must be present in the output, but OpenSSL
   5864     // will fill in a zero-length OID if you don't call PKCS7_set_content on the
   5865     // outer PKCS7 container. So we construct an empty PKCS7 data container and
   5866     // set it as the content.
   5867     Unique_PKCS7 pkcs7Data(PKCS7_new());
   5868     if (PKCS7_set_type(pkcs7Data.get(), NID_pkcs7_data) != 1) {
   5869         throwExceptionIfNecessary(env, "PKCS7_set_type data");
   5870         return NULL;
   5871     }
   5872 
   5873     if (PKCS7_set_content(pkcs7.get(), pkcs7Data.get()) != 1) {
   5874         throwExceptionIfNecessary(env, "PKCS7_set_content");
   5875         return NULL;
   5876     }
   5877     OWNERSHIP_TRANSFERRED(pkcs7Data);
   5878 
   5879     ScopedLongArrayRO certs(env, certsArray);
   5880     for (size_t i = 0; i < certs.size(); i++) {
   5881         X509* item = reinterpret_cast<X509*>(certs[i]);
   5882         if (PKCS7_add_certificate(pkcs7.get(), item) != 1) {
   5883             throwExceptionIfNecessary(env, "i2d_PKCS7");
   5884             return NULL;
   5885         }
   5886     }
   5887 
   5888     JNI_TRACE("i2d_PKCS7(%p) => %d certs", certsArray, certs.size());
   5889     return ASN1ToByteArray<PKCS7, i2d_PKCS7>(env, pkcs7.get());
   5890 }
   5891 
   5892 typedef STACK_OF(X509) PKIPATH;
   5893 
   5894 ASN1_ITEM_TEMPLATE(PKIPATH) =
   5895     ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PkiPath, X509)
   5896 ASN1_ITEM_TEMPLATE_END(PKIPATH)
   5897 
   5898 static jlongArray NativeCrypto_ASN1_seq_unpack_X509_bio(JNIEnv* env, jclass, jlong bioRef) {
   5899     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   5900     JNI_TRACE("ASN1_seq_unpack_X509_bio(%p)", bio);
   5901 
   5902     Unique_sk_X509 path((PKIPATH*) ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKIPATH), bio, NULL));
   5903     if (path.get() == NULL) {
   5904         throwExceptionIfNecessary(env, "ASN1_seq_unpack_X509_bio");
   5905         return NULL;
   5906     }
   5907 
   5908     size_t size = sk_X509_num(path.get());
   5909 
   5910     ScopedLocalRef<jlongArray> certArray(env, env->NewLongArray(size));
   5911     ScopedLongArrayRW certs(env, certArray.get());
   5912     for (size_t i = 0; i < size; i++) {
   5913         X509* item = reinterpret_cast<X509*>(sk_X509_shift(path.get()));
   5914         certs[i] = reinterpret_cast<uintptr_t>(item);
   5915     }
   5916 
   5917     JNI_TRACE("ASN1_seq_unpack_X509_bio(%p) => returns %d items", bio, size);
   5918     return certArray.release();
   5919 }
   5920 
   5921 static jbyteArray NativeCrypto_ASN1_seq_pack_X509(JNIEnv* env, jclass, jlongArray certs) {
   5922     JNI_TRACE("ASN1_seq_pack_X509(%p)", certs);
   5923     ScopedLongArrayRO certsArray(env, certs);
   5924     if (certsArray.get() == NULL) {
   5925         JNI_TRACE("ASN1_seq_pack_X509(%p) => failed to get certs array", certs);
   5926         return NULL;
   5927     }
   5928 
   5929     Unique_sk_X509 certStack(sk_X509_new_null());
   5930     if (certStack.get() == NULL) {
   5931         JNI_TRACE("ASN1_seq_pack_X509(%p) => failed to make cert stack", certs);
   5932         return NULL;
   5933     }
   5934 
   5935     for (size_t i = 0; i < certsArray.size(); i++) {
   5936         X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(certsArray[i]));
   5937         sk_X509_push(certStack.get(), X509_dup_nocopy(x509));
   5938     }
   5939 
   5940     int len;
   5941     Unique_OPENSSL_str encoded(ASN1_seq_pack(
   5942                     reinterpret_cast<STACK_OF(OPENSSL_BLOCK)*>(
   5943                             reinterpret_cast<uintptr_t>(certStack.get())),
   5944                     reinterpret_cast<int (*)(void*, unsigned char**)>(i2d_X509), NULL, &len));
   5945     if (encoded.get() == NULL) {
   5946         JNI_TRACE("ASN1_seq_pack_X509(%p) => trouble encoding", certs);
   5947         return NULL;
   5948     }
   5949 
   5950     ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(len));
   5951     if (byteArray.get() == NULL) {
   5952         JNI_TRACE("ASN1_seq_pack_X509(%p) => creating byte array failed", certs);
   5953         return NULL;
   5954     }
   5955 
   5956     ScopedByteArrayRW bytes(env, byteArray.get());
   5957     if (bytes.get() == NULL) {
   5958         JNI_TRACE("ASN1_seq_pack_X509(%p) => using byte array failed", certs);
   5959         return NULL;
   5960     }
   5961 
   5962     unsigned char* p = reinterpret_cast<unsigned char*>(bytes.get());
   5963     memcpy(p, encoded.get(), len);
   5964 
   5965     return byteArray.release();
   5966 }
   5967 
   5968 static void NativeCrypto_X509_free(JNIEnv* env, jclass, jlong x509Ref) {
   5969     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   5970     JNI_TRACE("X509_free(%p)", x509);
   5971 
   5972     if (x509 == NULL) {
   5973         jniThrowNullPointerException(env, "x509 == null");
   5974         JNI_TRACE("X509_free(%p) => x509 == null", x509);
   5975         return;
   5976     }
   5977 
   5978     X509_free(x509);
   5979 }
   5980 
   5981 static jint NativeCrypto_X509_cmp(JNIEnv* env, jclass, jlong x509Ref1, jlong x509Ref2) {
   5982     X509* x509_1 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref1));
   5983     X509* x509_2 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref2));
   5984     JNI_TRACE("X509_cmp(%p, %p)", x509_1, x509_2);
   5985 
   5986     if (x509_1 == NULL) {
   5987         jniThrowNullPointerException(env, "x509_1 == null");
   5988         JNI_TRACE("X509_cmp(%p, %p) => x509_1 == null", x509_1, x509_2);
   5989         return -1;
   5990     }
   5991 
   5992     if (x509_2 == NULL) {
   5993         jniThrowNullPointerException(env, "x509_2 == null");
   5994         JNI_TRACE("X509_cmp(%p, %p) => x509_2 == null", x509_1, x509_2);
   5995         return -1;
   5996     }
   5997 
   5998     int ret = X509_cmp(x509_1, x509_2);
   5999     JNI_TRACE("X509_cmp(%p, %p) => %d", x509_1, x509_2, ret);
   6000     return ret;
   6001 }
   6002 
   6003 static jint NativeCrypto_get_X509_hashCode(JNIEnv* env, jclass, jlong x509Ref) {
   6004     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6005 
   6006     if (x509 == NULL) {
   6007         jniThrowNullPointerException(env, "x509 == null");
   6008         JNI_TRACE("get_X509_hashCode(%p) => x509 == null", x509);
   6009         return 0;
   6010     }
   6011 
   6012     // Force caching extensions.
   6013     X509_check_ca(x509);
   6014 
   6015     jint hashCode = 0L;
   6016     for (int i = 0; i < SHA_DIGEST_LENGTH; i++) {
   6017         hashCode = 31 * hashCode + x509->sha1_hash[i];
   6018     }
   6019     return hashCode;
   6020 }
   6021 
   6022 static void NativeCrypto_X509_print_ex(JNIEnv* env, jclass, jlong bioRef, jlong x509Ref,
   6023         jlong nmflagJava, jlong certflagJava) {
   6024     BIO* bio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(bioRef));
   6025     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6026     long nmflag = static_cast<long>(nmflagJava);
   6027     long certflag = static_cast<long>(certflagJava);
   6028     JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld)", bio, x509, nmflag, certflag);
   6029 
   6030     if (bio == NULL) {
   6031         jniThrowNullPointerException(env, "bio == null");
   6032         JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => bio == null", bio, x509, nmflag, certflag);
   6033         return;
   6034     }
   6035 
   6036     if (x509 == NULL) {
   6037         jniThrowNullPointerException(env, "x509 == null");
   6038         JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => x509 == null", bio, x509, nmflag, certflag);
   6039         return;
   6040     }
   6041 
   6042     if (!X509_print_ex(bio, x509, nmflag, certflag)) {
   6043         throwExceptionIfNecessary(env, "X509_print_ex");
   6044         JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => threw error", bio, x509, nmflag, certflag);
   6045     } else {
   6046         JNI_TRACE("X509_print_ex(%p, %p, %ld, %ld) => success", bio, x509, nmflag, certflag);
   6047     }
   6048 }
   6049 
   6050 static jlong NativeCrypto_X509_get_pubkey(JNIEnv* env, jclass, jlong x509Ref) {
   6051     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6052     JNI_TRACE("X509_get_pubkey(%p)", x509);
   6053 
   6054     if (x509 == NULL) {
   6055         jniThrowNullPointerException(env, "x509 == null");
   6056         JNI_TRACE("X509_get_pubkey(%p) => x509 == null", x509);
   6057         return 0;
   6058     }
   6059 
   6060     Unique_EVP_PKEY pkey(X509_get_pubkey(x509));
   6061     if (pkey.get() == NULL) {
   6062         throwExceptionIfNecessary(env, "X509_get_pubkey");
   6063         return 0;
   6064     }
   6065 
   6066     JNI_TRACE("X509_get_pubkey(%p) => %p", x509, pkey.get());
   6067     return reinterpret_cast<uintptr_t>(pkey.release());
   6068 }
   6069 
   6070 static jbyteArray NativeCrypto_X509_get_issuer_name(JNIEnv* env, jclass, jlong x509Ref) {
   6071     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6072     JNI_TRACE("X509_get_issuer_name(%p)", x509);
   6073     return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_get_issuer_name(x509));
   6074 }
   6075 
   6076 static jbyteArray NativeCrypto_X509_get_subject_name(JNIEnv* env, jclass, jlong x509Ref) {
   6077     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6078     JNI_TRACE("X509_get_subject_name(%p)", x509);
   6079     return ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env, X509_get_subject_name(x509));
   6080 }
   6081 
   6082 static jstring NativeCrypto_get_X509_pubkey_oid(JNIEnv* env, jclass, jlong x509Ref) {
   6083     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6084     JNI_TRACE("get_X509_pubkey_oid(%p)", x509);
   6085 
   6086     if (x509 == NULL) {
   6087         jniThrowNullPointerException(env, "x509 == null");
   6088         JNI_TRACE("get_X509_pubkey_oid(%p) => x509 == null", x509);
   6089         return NULL;
   6090     }
   6091 
   6092     X509_PUBKEY* pubkey = X509_get_X509_PUBKEY(x509);
   6093     return ASN1_OBJECT_to_OID_string(env, pubkey->algor->algorithm);
   6094 }
   6095 
   6096 static jstring NativeCrypto_get_X509_sig_alg_oid(JNIEnv* env, jclass, jlong x509Ref) {
   6097     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6098     JNI_TRACE("get_X509_sig_alg_oid(%p)", x509);
   6099 
   6100     if (x509 == NULL || x509->sig_alg == NULL) {
   6101         jniThrowNullPointerException(env, "x509 == NULL || x509->sig_alg == NULL");
   6102         JNI_TRACE("get_X509_sig_alg_oid(%p) => x509 == NULL", x509);
   6103         return NULL;
   6104     }
   6105 
   6106     return ASN1_OBJECT_to_OID_string(env, x509->sig_alg->algorithm);
   6107 }
   6108 
   6109 static jbyteArray NativeCrypto_get_X509_sig_alg_parameter(JNIEnv* env, jclass, jlong x509Ref) {
   6110     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6111     JNI_TRACE("get_X509_sig_alg_parameter(%p)", x509);
   6112 
   6113     if (x509 == NULL) {
   6114         jniThrowNullPointerException(env, "x509 == null");
   6115         JNI_TRACE("get_X509_sig_alg_parameter(%p) => x509 == null", x509);
   6116         return NULL;
   6117     }
   6118 
   6119     if (x509->sig_alg->parameter == NULL) {
   6120         JNI_TRACE("get_X509_sig_alg_parameter(%p) => null", x509);
   6121         return NULL;
   6122     }
   6123 
   6124     return ASN1ToByteArray<ASN1_TYPE, i2d_ASN1_TYPE>(env, x509->sig_alg->parameter);
   6125 }
   6126 
   6127 static jbooleanArray NativeCrypto_get_X509_issuerUID(JNIEnv* env, jclass, jlong x509Ref) {
   6128     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6129     JNI_TRACE("get_X509_issuerUID(%p)", x509);
   6130 
   6131     if (x509 == NULL) {
   6132         jniThrowNullPointerException(env, "x509 == null");
   6133         JNI_TRACE("get_X509_issuerUID(%p) => x509 == null", x509);
   6134         return NULL;
   6135     }
   6136 
   6137     if (x509->cert_info->issuerUID == NULL) {
   6138         JNI_TRACE("get_X509_issuerUID(%p) => null", x509);
   6139         return NULL;
   6140     }
   6141 
   6142     return ASN1BitStringToBooleanArray(env, x509->cert_info->issuerUID);
   6143 }
   6144 static jbooleanArray NativeCrypto_get_X509_subjectUID(JNIEnv* env, jclass, jlong x509Ref) {
   6145     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6146     JNI_TRACE("get_X509_subjectUID(%p)", x509);
   6147 
   6148     if (x509 == NULL) {
   6149         jniThrowNullPointerException(env, "x509 == null");
   6150         JNI_TRACE("get_X509_subjectUID(%p) => x509 == null", x509);
   6151         return NULL;
   6152     }
   6153 
   6154     if (x509->cert_info->subjectUID == NULL) {
   6155         JNI_TRACE("get_X509_subjectUID(%p) => null", x509);
   6156         return NULL;
   6157     }
   6158 
   6159     return ASN1BitStringToBooleanArray(env, x509->cert_info->subjectUID);
   6160 }
   6161 
   6162 static jbooleanArray NativeCrypto_get_X509_ex_kusage(JNIEnv* env, jclass, jlong x509Ref) {
   6163     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6164     JNI_TRACE("get_X509_ex_kusage(%p)", x509);
   6165 
   6166     if (x509 == NULL) {
   6167         jniThrowNullPointerException(env, "x509 == null");
   6168         JNI_TRACE("get_X509_ex_kusage(%p) => x509 == null", x509);
   6169         return NULL;
   6170     }
   6171 
   6172     Unique_ASN1_BIT_STRING bitStr(static_cast<ASN1_BIT_STRING*>(
   6173             X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL)));
   6174     if (bitStr.get() == NULL) {
   6175         JNI_TRACE("get_X509_ex_kusage(%p) => null", x509);
   6176         return NULL;
   6177     }
   6178 
   6179     return ASN1BitStringToBooleanArray(env, bitStr.get());
   6180 }
   6181 
   6182 static jobjectArray NativeCrypto_get_X509_ex_xkusage(JNIEnv* env, jclass, jlong x509Ref) {
   6183     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6184     JNI_TRACE("get_X509_ex_xkusage(%p)", x509);
   6185 
   6186     if (x509 == NULL) {
   6187         jniThrowNullPointerException(env, "x509 == null");
   6188         JNI_TRACE("get_X509_ex_xkusage(%p) => x509 == null", x509);
   6189         return NULL;
   6190     }
   6191 
   6192     Unique_sk_ASN1_OBJECT objArray(static_cast<STACK_OF(ASN1_OBJECT)*>(
   6193             X509_get_ext_d2i(x509, NID_ext_key_usage, NULL, NULL)));
   6194     if (objArray.get() == NULL) {
   6195         JNI_TRACE("get_X509_ex_xkusage(%p) => null", x509);
   6196         return NULL;
   6197     }
   6198 
   6199     size_t size = sk_ASN1_OBJECT_num(objArray.get());
   6200     ScopedLocalRef<jobjectArray> exKeyUsage(env, env->NewObjectArray(size, stringClass, NULL));
   6201     if (exKeyUsage.get() == NULL) {
   6202         return NULL;
   6203     }
   6204 
   6205     for (size_t i = 0; i < size; i++) {
   6206         ScopedLocalRef<jstring> oidStr(env, ASN1_OBJECT_to_OID_string(env,
   6207                 sk_ASN1_OBJECT_value(objArray.get(), i)));
   6208         env->SetObjectArrayElement(exKeyUsage.get(), i, oidStr.get());
   6209     }
   6210 
   6211     JNI_TRACE("get_X509_ex_xkusage(%p) => success (%d entries)", x509, size);
   6212     return exKeyUsage.release();
   6213 }
   6214 
   6215 static jint NativeCrypto_get_X509_ex_pathlen(JNIEnv* env, jclass, jlong x509Ref) {
   6216     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6217     JNI_TRACE("get_X509_ex_pathlen(%p)", x509);
   6218 
   6219     if (x509 == NULL) {
   6220         jniThrowNullPointerException(env, "x509 == null");
   6221         JNI_TRACE("get_X509_ex_pathlen(%p) => x509 == null", x509);
   6222         return 0;
   6223     }
   6224 
   6225     /* Just need to do this to cache the ex_* values. */
   6226     X509_check_ca(x509);
   6227 
   6228     JNI_TRACE("get_X509_ex_pathlen(%p) => %ld", x509, x509->ex_pathlen);
   6229     return x509->ex_pathlen;
   6230 }
   6231 
   6232 static jbyteArray NativeCrypto_X509_get_ext_oid(JNIEnv* env, jclass, jlong x509Ref,
   6233         jstring oidString) {
   6234     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
   6235     JNI_TRACE("X509_get_ext_oid(%p, %p)", x509, oidString);
   6236     return X509Type_get_ext_oid<X509, X509_get_ext_by_OBJ, X509_get_ext>(env, x509, oidString);
   6237 }
   6238 
   6239 static jbyteArray NativeCrypto_X509_CRL_get_ext_oid(JNIEnv* env, jclass, jlong x509CrlRef,
   6240         jstring oidString) {
   6241     X509_CRL* crl = reinterpret_cast<X509_CRL*>(static_cast<uintptr_t>(x509CrlRef));
   6242     JNI_TRACE("X509_CRL_get_ext_oid(%p, %p)", crl, oidString);
   6243     return X509Type_get_ext_oid<X509_CRL, X509_CRL_get_ext_by_OBJ, X509_CRL_get_ext>(env, crl,
   6244             oidString);
   6245 }
   6246 
   6247 static jbyteArray NativeCrypto_X509_REVOKED_get_ext_oid(JNIEnv* env, jclass, jlong x509RevokedRef,
   6248         jstring oidString) {
   6249     X509_REVOKED* revoked = reinterpret_cast<X509_REVOKED*>(static_cast<uintptr_t>(x509RevokedRef));
   6250     JNI_TRACE("X509_REVOKED_get_ext_oid(%p, %p)", revoked, oidString);
   6251     return X509Type_get_ext_oid<X509_REVOKED, X509_REVOKED_get_ext_by_OBJ, X509_REVOKED_get_ext>(
   6252             env, revoked, oidString);
   6253 }
   6254 
   6255 template<typename T, int (*get_ext_by_critical_func)(T*, int, int), X509_EXTENSION* (*get_ext_func)(T*, int)>
   6256 static jobjectArray get_X509Type_ext_oids(JNIEnv* env, jlong x509Ref, jint critical) {
   6257     T* x509 = reinterpret_cast<T*>(static_cast<uintptr_t>(x509Ref));
   6258     JNI_TRACE("get_X509Type_ext_oids(%p, %d)", x509, critical);
   6259 
   6260     if (x509 == NULL) {
   6261         jniThrowNullPointerException(env, "x509 == null");
   6262         JNI_TRACE("get_X509Type_ext_oids(%p, %d) => x509 == null", x509, critical);
   6263         return NULL;
   6264     }
   6265 
   6266     int lastPos = -1;
   6267     int count = 0;
   6268     while ((lastPos = get_ext_by_critical_func(x509, critical, lastPos)) != -1) {
   6269         count++;
   6270     }
   6271 
   6272     JNI_TRACE("get_X509Type_ext_oids(%p, %d) has %d entries", x509, critical, count);
   6273 
   6274     ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, stringClass, NULL));
   6275     if (joa.get() == NULL) {
   6276         JNI_TRACE("get_X509Type_ext_oids(%p, %d) => fail to allocate result array", x509, critical);
   6277         return NULL;
   6278     }
   6279 
   6280     lastPos = -1;
   6281     count = 0;
   6282     while ((lastPos = get_ext_by_critical_func(x509, critical, lastPos)) != -1) {
   6283         X509_EXTENSION* ext = get_ext_func(x509, lastPos);
   6284 
   6285         ScopedLocalRef<jstring> extOid(env, ASN1_OBJECT_to_OID_string(env, ext->object));
   6286         if (extOid.get() == NULL) {
   6287             JNI_TRACE("get_X509Type_ext_oids(%p) => couldn't get OID", x509);
   6288             return NULL;
   6289         }
   6290 
   6291         env->SetObjectArrayElement(joa.get(), count++, extOid.get());
   6292     }
   6293 
   6294     JNI_TRACE("get_X509Type_ext_oids(%p, %d) => success", x509, critical);
   6295     return joa.release();
   6296 }
   6297 
   6298 static jobjectArray NativeCrypto_get_X509_ext_oids(JNIEnv* env, jclass, jlong x509Ref,
   6299         jint critical) {
   6300     JNI_TRACE("get_X509_ext_oids(0x%llx, %d)", x509Ref, critical);
   6301     return get_X509Type_ext_oids<X509, X509_get_ext_by_critical, X509_get_ext>(env, x509Ref,
   6302             critical);
   6303 }
   6304 
   6305 static jobjectArray NativeCrypto_get_X509_CRL_ext_oids(JNIEnv* env, jclass, jlong x509CrlRef,
   6306         jint critical) {
   6307     JNI_TRACE("get_X509_CRL_ext_oids(0x%llx, %d)", x509CrlRef, critical);
   6308     return get_X509Type_ext_oids<X509_CRL, X509_CRL_get_ext_by_critical, X509_CRL_get_ext>(env,
   6309             x509CrlRef, critical);
   6310 }
   6311 
   6312 static jobjectArray NativeCrypto_get_X509_REVOKED_ext_oids(JNIEnv* env, jclass, jlong x509RevokedRef,
   6313         jint critical) {
   6314     JNI_TRACE("get_X509_CRL_ext_oids(0x%llx, %d)", x509RevokedRef, critical);
   6315     return get_X509Type_ext_oids<X509_REVOKED, X509_REVOKED_get_ext_by_critical,
   6316             X509_REVOKED_get_ext>(env, x509RevokedRef, critical);
   6317 }
   6318 
   6319 #ifdef WITH_JNI_TRACE
   6320 /**
   6321  * Based on example logging call back from SSL_CTX_set_info_callback man page
   6322  */
   6323 static void info_callback_LOG(const SSL* s __attribute__ ((unused)), int where, int ret)
   6324 {
   6325     int w = where & ~SSL_ST_MASK;
   6326     const char* str;
   6327     if (w & SSL_ST_CONNECT) {
   6328         str = "SSL_connect";
   6329     } else if (w & SSL_ST_ACCEPT) {
   6330         str = "SSL_accept";
   6331     } else {
   6332         str = "undefined";
   6333     }
   6334 
   6335     if (where & SSL_CB_LOOP) {
   6336         JNI_TRACE("ssl=%p %s:%s %s", s, str, SSL_state_string(s), SSL_state_string_long(s));
   6337     } else if (where & SSL_CB_ALERT) {
   6338         str = (where & SSL_CB_READ) ? "read" : "write";
   6339         JNI_TRACE("ssl=%p SSL3 alert %s:%s:%s %s %s",
   6340                   s,
   6341                   str,
   6342                   SSL_alert_type_string(ret),
   6343                   SSL_alert_desc_string(ret),
   6344                   SSL_alert_type_string_long(ret),
   6345                   SSL_alert_desc_string_long(ret));
   6346     } else if (where & SSL_CB_EXIT) {
   6347         if (ret == 0) {
   6348             JNI_TRACE("ssl=%p %s:failed exit in %s %s",
   6349                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   6350         } else if (ret < 0) {
   6351             JNI_TRACE("ssl=%p %s:error exit in %s %s",
   6352                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   6353         } else if (ret == 1) {
   6354             JNI_TRACE("ssl=%p %s:ok exit in %s %s",
   6355                       s, str, SSL_state_string(s), SSL_state_string_long(s));
   6356         } else {
   6357             JNI_TRACE("ssl=%p %s:unknown exit %d in %s %s",
   6358                       s, str, ret, SSL_state_string(s), SSL_state_string_long(s));
   6359         }
   6360     } else if (where & SSL_CB_HANDSHAKE_START) {
   6361         JNI_TRACE("ssl=%p handshake start in %s %s",
   6362                   s, SSL_state_string(s), SSL_state_string_long(s));
   6363     } else if (where & SSL_CB_HANDSHAKE_DONE) {
   6364         JNI_TRACE("ssl=%p handshake done in %s %s",
   6365                   s, SSL_state_string(s), SSL_state_string_long(s));
   6366     } else {
   6367         JNI_TRACE("ssl=%p %s:unknown where %d in %s %s",
   6368                   s, str, where, SSL_state_string(s), SSL_state_string_long(s));
   6369     }
   6370 }
   6371 #endif
   6372 
   6373 /**
   6374  * Returns an array containing all the X509 certificate references
   6375  */
   6376 static jlongArray getCertificateRefs(JNIEnv* env, const STACK_OF(X509)* chain)
   6377 {
   6378     if (chain == NULL) {
   6379         // Chain can be NULL if the associated cipher doesn't do certs.
   6380         return NULL;
   6381     }
   6382     ssize_t count = sk_X509_num(chain);
   6383     if (count <= 0) {
   6384         return NULL;
   6385     }
   6386     ScopedLocalRef<jlongArray> refArray(env, env->NewLongArray(count));
   6387     ScopedLongArrayRW refs(env, refArray.get());
   6388     if (refs.get() == NULL) {
   6389         return NULL;
   6390     }
   6391     for (ssize_t i = 0; i < count; i++) {
   6392         refs[i] = reinterpret_cast<uintptr_t>(X509_dup_nocopy(sk_X509_value(chain, i)));
   6393     }
   6394     return refArray.release();
   6395 }
   6396 
   6397 /**
   6398  * Returns an array containing all the X500 principal's bytes.
   6399  */
   6400 static jobjectArray getPrincipalBytes(JNIEnv* env, const STACK_OF(X509_NAME)* names)
   6401 {
   6402     if (names == NULL) {
   6403         return NULL;
   6404     }
   6405 
   6406     int count = sk_X509_NAME_num(names);
   6407     if (count <= 0) {
   6408         return NULL;
   6409     }
   6410 
   6411     ScopedLocalRef<jobjectArray> joa(env, env->NewObjectArray(count, byteArrayClass, NULL));
   6412     if (joa.get() == NULL) {
   6413         return NULL;
   6414     }
   6415 
   6416     for (int i = 0; i < count; i++) {
   6417         X509_NAME* principal = sk_X509_NAME_value(names, i);
   6418 
   6419         ScopedLocalRef<jbyteArray> byteArray(env, ASN1ToByteArray<X509_NAME, i2d_X509_NAME>(env,
   6420                 principal));
   6421         if (byteArray.get() == NULL) {
   6422             return NULL;
   6423         }
   6424         env->SetObjectArrayElement(joa.get(), i, byteArray.get());
   6425     }
   6426 
   6427     return joa.release();
   6428 }
   6429 
   6430 /**
   6431  * Our additional application data needed for getting synchronization right.
   6432  * This maybe warrants a bit of lengthy prose:
   6433  *
   6434  * (1) We use a flag to reflect whether we consider the SSL connection alive.
   6435  * Any read or write attempt loops will be cancelled once this flag becomes 0.
   6436  *
   6437  * (2) We use an int to count the number of threads that are blocked by the
   6438  * underlying socket. This may be at most two (one reader and one writer), since
   6439  * the Java layer ensures that no more threads will enter the native code at the
   6440  * same time.
   6441  *
   6442  * (3) The pipe is used primarily as a means of cancelling a blocking select()
   6443  * when we want to close the connection (aka "emergency button"). It is also
   6444  * necessary for dealing with a possible race condition situation: There might
   6445  * be cases where both threads see an SSL_ERROR_WANT_READ or
   6446  * SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
   6447  * If one leaves the select() successfully before the other enters it, the
   6448  * "success" event is already consumed and the second thread will be blocked,
   6449  * possibly forever (depending on network conditions).
   6450  *
   6451  * The idea for solving the problem looks like this: Whenever a thread is
   6452  * successful in moving around data on the network, and it knows there is
   6453  * another thread stuck in a select(), it will write a byte to the pipe, waking
   6454  * up the other thread. A thread that returned from select(), on the other hand,
   6455  * knows whether it's been woken up by the pipe. If so, it will consume the
   6456  * byte, and the original state of affairs has been restored.
   6457  *
   6458  * The pipe may seem like a bit of overhead, but it fits in nicely with the
   6459  * other file descriptors of the select(), so there's only one condition to wait
   6460  * for.
   6461  *
   6462  * (4) Finally, a mutex is needed to make sure that at most one thread is in
   6463  * either SSL_read() or SSL_write() at any given time. This is an OpenSSL
   6464  * requirement. We use the same mutex to guard the field for counting the
   6465  * waiting threads.
   6466  *
   6467  * Note: The current implementation assumes that we don't have to deal with
   6468  * problems induced by multiple cores or processors and their respective
   6469  * memory caches. One possible problem is that of inconsistent views on the
   6470  * "aliveAndKicking" field. This could be worked around by also enclosing all
   6471  * accesses to that field inside a lock/unlock sequence of our mutex, but
   6472  * currently this seems a bit like overkill. Marking volatile at the very least.
   6473  *
   6474  * During handshaking, additional fields are used to up-call into
   6475  * Java to perform certificate verification and handshake
   6476  * completion. These are also used in any renegotiation.
   6477  *
   6478  * (5) the JNIEnv so we can invoke the Java callback
   6479  *
   6480  * (6) a NativeCrypto.SSLHandshakeCallbacks instance for callbacks from native to Java
   6481  *
   6482  * (7) a java.io.FileDescriptor wrapper to check for socket close
   6483  *
   6484  * We store the NPN protocols list so we can either send it (from the server) or
   6485  * select a protocol (on the client). We eagerly acquire a pointer to the array
   6486  * data so the callback doesn't need to acquire resources that it cannot
   6487  * release.
   6488  *
   6489  * Because renegotiation can be requested by the peer at any time,
   6490  * care should be taken to maintain an appropriate JNIEnv on any
   6491  * downcall to openssl since it could result in an upcall to Java. The
   6492  * current code does try to cover these cases by conditionally setting
   6493  * the JNIEnv on calls that can read and write to the SSL such as
   6494  * SSL_do_handshake, SSL_read, SSL_write, and SSL_shutdown.
   6495  *
   6496  * Finally, we have two emphemeral keys setup by OpenSSL callbacks:
   6497  *
   6498  * (8) a set of ephemeral RSA keys that is lazily generated if a peer
   6499  * wants to use an exportable RSA cipher suite.
   6500  *
   6501  * (9) a set of ephemeral EC keys that is lazily generated if a peer
   6502  * wants to use an TLS_ECDHE_* cipher suite.
   6503  *
   6504  */
   6505 class AppData {
   6506   public:
   6507     volatile int aliveAndKicking;
   6508     int waitingThreads;
   6509     int fdsEmergency[2];
   6510     MUTEX_TYPE mutex;
   6511     JNIEnv* env;
   6512     jobject sslHandshakeCallbacks;
   6513     jbyteArray npnProtocolsArray;
   6514     jbyte* npnProtocolsData;
   6515     size_t npnProtocolsLength;
   6516     jbyteArray alpnProtocolsArray;
   6517     jbyte* alpnProtocolsData;
   6518     size_t alpnProtocolsLength;
   6519     Unique_RSA ephemeralRsa;
   6520     Unique_EC_KEY ephemeralEc;
   6521 
   6522     /**
   6523      * Creates the application data context for the SSL*.
   6524      */
   6525   public:
   6526     static AppData* create() {
   6527         UniquePtr<AppData> appData(new AppData());
   6528         if (pipe(appData.get()->fdsEmergency) == -1) {
   6529             ALOGE("AppData::create pipe(2) failed: %s", strerror(errno));
   6530             return NULL;
   6531         }
   6532         if (!setBlocking(appData.get()->fdsEmergency[0], false)) {
   6533             ALOGE("AppData::create fcntl(2) failed: %s", strerror(errno));
   6534             return NULL;
   6535         }
   6536         if (MUTEX_SETUP(appData.get()->mutex) == -1) {
   6537             ALOGE("pthread_mutex_init(3) failed: %s", strerror(errno));
   6538             return NULL;
   6539         }
   6540         return appData.release();
   6541     }
   6542 
   6543     ~AppData() {
   6544         aliveAndKicking = 0;
   6545         if (fdsEmergency[0] != -1) {
   6546             close(fdsEmergency[0]);
   6547         }
   6548         if (fdsEmergency[1] != -1) {
   6549             close(fdsEmergency[1]);
   6550         }
   6551         clearCallbackState();
   6552         MUTEX_CLEANUP(mutex);
   6553     }
   6554 
   6555   private:
   6556     AppData() :
   6557             aliveAndKicking(1),
   6558             waitingThreads(0),
   6559             env(NULL),
   6560             sslHandshakeCallbacks(NULL),
   6561             npnProtocolsArray(NULL),
   6562             npnProtocolsData(NULL),
   6563             npnProtocolsLength(-1),
   6564             alpnProtocolsArray(NULL),
   6565             alpnProtocolsData(NULL),
   6566             alpnProtocolsLength(-1),
   6567             ephemeralRsa(NULL),
   6568             ephemeralEc(NULL) {
   6569         fdsEmergency[0] = -1;
   6570         fdsEmergency[1] = -1;
   6571     }
   6572 
   6573   public:
   6574     /**
   6575      * Used to set the SSL-to-Java callback state before each SSL_*
   6576      * call that may result in a callback. It should be cleared after
   6577      * the operation returns with clearCallbackState.
   6578      *
   6579      * @param env The JNIEnv
   6580      * @param shc The SSLHandshakeCallbacks
   6581      * @param fd The FileDescriptor
   6582      * @param npnProtocols NPN protocols so that they may be advertised (by the
   6583      *                     server) or selected (by the client). Has no effect
   6584      *                     unless NPN is enabled.
   6585      * @param alpnProtocols ALPN protocols so that they may be advertised (by the
   6586      *                     server) or selected (by the client). Passing non-NULL
   6587      *                     enables ALPN.
   6588      */
   6589     bool setCallbackState(JNIEnv* e, jobject shc, jobject fd, jbyteArray npnProtocols,
   6590             jbyteArray alpnProtocols) {
   6591         UniquePtr<NetFd> netFd;
   6592         if (fd != NULL) {
   6593             netFd.reset(new NetFd(e, fd));
   6594             if (netFd->isClosed()) {
   6595                 JNI_TRACE("appData=%p setCallbackState => netFd->isClosed() == true", this);
   6596                 return false;
   6597             }
   6598         }
   6599         env = e;
   6600         sslHandshakeCallbacks = shc;
   6601         if (npnProtocols != NULL) {
   6602             npnProtocolsData = e->GetByteArrayElements(npnProtocols, NULL);
   6603             if (npnProtocolsData == NULL) {
   6604                 clearCallbackState();
   6605                 JNI_TRACE("appData=%p setCallbackState => npnProtocolsData == NULL", this);
   6606                 return false;
   6607             }
   6608             npnProtocolsArray = npnProtocols;
   6609             npnProtocolsLength = e->GetArrayLength(npnProtocols);
   6610         }
   6611         if (alpnProtocols != NULL) {
   6612             alpnProtocolsData = e->GetByteArrayElements(alpnProtocols, NULL);
   6613             if (alpnProtocolsData == NULL) {
   6614                 clearCallbackState();
   6615                 JNI_TRACE("appData=%p setCallbackState => alpnProtocolsData == NULL", this);
   6616                 return false;
   6617             }
   6618             alpnProtocolsArray = alpnProtocols;
   6619             alpnProtocolsLength = e->GetArrayLength(alpnProtocols);
   6620         }
   6621         return true;
   6622     }
   6623 
   6624     void clearCallbackState() {
   6625         sslHandshakeCallbacks = NULL;
   6626         if (npnProtocolsArray != NULL) {
   6627             env->ReleaseByteArrayElements(npnProtocolsArray, npnProtocolsData, JNI_ABORT);
   6628             npnProtocolsArray = NULL;
   6629             npnProtocolsData = NULL;
   6630             npnProtocolsLength = -1;
   6631         }
   6632         if (alpnProtocolsArray != NULL) {
   6633             env->ReleaseByteArrayElements(alpnProtocolsArray, alpnProtocolsData, JNI_ABORT);
   6634             alpnProtocolsArray = NULL;
   6635             alpnProtocolsData = NULL;
   6636             alpnProtocolsLength = -1;
   6637         }
   6638         env = NULL;
   6639     }
   6640 
   6641 };
   6642 
   6643 /**
   6644  * Dark magic helper function that checks, for a given SSL session, whether it
   6645  * can SSL_read() or SSL_write() without blocking. Takes into account any
   6646  * concurrent attempts to close the SSLSocket from the Java side. This is
   6647  * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket
   6648  * while thread #2 is sitting in a blocking read or write. The type argument
   6649  * specifies whether we are waiting for readability or writability. It expects
   6650  * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we
   6651  * only need to wait in case one of these problems occurs.
   6652  *
   6653  * @param env
   6654  * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE
   6655  * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL
   6656  * @param appData The application data structure with mutex info etc.
   6657  * @param timeout_millis The timeout value for select call, with the special value
   6658  *                0 meaning no timeout at all (wait indefinitely). Note: This is
   6659  *                the Java semantics of the timeout value, not the usual
   6660  *                select() semantics.
   6661  * @return The result of the inner select() call,
   6662  * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on
   6663  * additional errors
   6664  */
   6665 static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout_millis) {
   6666     // This loop is an expanded version of the NET_FAILURE_RETRY
   6667     // macro. It cannot simply be used in this case because select
   6668     // cannot be restarted without recreating the fd_sets and timeout
   6669     // structure.
   6670     int result;
   6671     fd_set rfds;
   6672     fd_set wfds;
   6673     do {
   6674         NetFd fd(env, fdObject);
   6675         if (fd.isClosed()) {
   6676             result = THROWN_EXCEPTION;
   6677             break;
   6678         }
   6679         int intFd = fd.get();
   6680         JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout_millis=%d",
   6681                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout_millis);
   6682 
   6683         FD_ZERO(&rfds);
   6684         FD_ZERO(&wfds);
   6685 
   6686         if (type == SSL_ERROR_WANT_READ) {
   6687             FD_SET(intFd, &rfds);
   6688         } else {
   6689             FD_SET(intFd, &wfds);
   6690         }
   6691 
   6692         FD_SET(appData->fdsEmergency[0], &rfds);
   6693 
   6694         int maxFd = (intFd > appData->fdsEmergency[0]) ? intFd : appData->fdsEmergency[0];
   6695 
   6696         // Build a struct for the timeout data if we actually want a timeout.
   6697         timeval tv;
   6698         timeval* ptv;
   6699         if (timeout_millis > 0) {
   6700             tv.tv_sec = timeout_millis / 1000;
   6701             tv.tv_usec = (timeout_millis % 1000) * 1000;
   6702             ptv = &tv;
   6703         } else {
   6704             ptv = NULL;
   6705         }
   6706 
   6707 #ifndef CONSCRYPT_UNBUNDLED
   6708         AsynchronousCloseMonitor monitor(intFd);
   6709 #else
   6710         CompatibilityCloseMonitor monitor(intFd);
   6711 #endif
   6712         result = select(maxFd + 1, &rfds, &wfds, NULL, ptv);
   6713         JNI_TRACE("sslSelect %s fd=%d appData=%p timeout_millis=%d => %d",
   6714                   (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE",
   6715                   fd.get(), appData, timeout_millis, result);
   6716         if (result == -1) {
   6717             if (fd.isClosed()) {
   6718                 result = THROWN_EXCEPTION;
   6719                 break;
   6720             }
   6721             if (errno != EINTR) {
   6722                 break;
   6723             }
   6724         }
   6725     } while (result == -1);
   6726 
   6727     if (MUTEX_LOCK(appData->mutex) == -1) {
   6728         return -1;
   6729     }
   6730 
   6731     if (result > 0) {
   6732         // We have been woken up by a token in the emergency pipe. We
   6733         // can't be sure the token is still in the pipe at this point
   6734         // because it could have already been read by the thread that
   6735         // originally wrote it if it entered sslSelect and acquired
   6736         // the mutex before we did. Thus we cannot safely read from
   6737         // the pipe in a blocking way (so we make the pipe
   6738         // non-blocking at creation).
   6739         if (FD_ISSET(appData->fdsEmergency[0], &rfds)) {
   6740             char token;
   6741             do {
   6742                 read(appData->fdsEmergency[0], &token, 1);
   6743             } while (errno == EINTR);
   6744         }
   6745     }
   6746 
   6747     // Tell the world that there is now one thread less waiting for the
   6748     // underlying network.
   6749     appData->waitingThreads--;
   6750 
   6751     MUTEX_UNLOCK(appData->mutex);
   6752 
   6753     return result;
   6754 }
   6755 
   6756 /**
   6757  * Helper function that wakes up a thread blocked in select(), in case there is
   6758  * one. Is being called by sslRead() and sslWrite() as well as by JNI glue
   6759  * before closing the connection.
   6760  *
   6761  * @param data The application data structure with mutex info etc.
   6762  */
   6763 static void sslNotify(AppData* appData) {
   6764     // Write a byte to the emergency pipe, so a concurrent select() can return.
   6765     // Note we have to restore the errno of the original system call, since the
   6766     // caller relies on it for generating error messages.
   6767     int errnoBackup = errno;
   6768     char token = '*';
   6769     do {
   6770         errno = 0;
   6771         write(appData->fdsEmergency[1], &token, 1);
   6772     } while (errno == EINTR);
   6773     errno = errnoBackup;
   6774 }
   6775 
   6776 static AppData* toAppData(const SSL* ssl) {
   6777     return reinterpret_cast<AppData*>(SSL_get_app_data(ssl));
   6778 }
   6779 
   6780 /**
   6781  * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback
   6782  */
   6783 static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused)))
   6784 {
   6785     /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */
   6786     SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx,
   6787             SSL_get_ex_data_X509_STORE_CTX_idx()));
   6788     JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg);
   6789 
   6790     AppData* appData = toAppData(ssl);
   6791     JNIEnv* env = appData->env;
   6792     if (env == NULL) {
   6793         ALOGE("AppData->env missing in cert_verify_callback");
   6794         JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl);
   6795         return 0;
   6796     }
   6797     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   6798 
   6799     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   6800     jmethodID methodID
   6801         = env->GetMethodID(cls, "verifyCertificateChain", "(J[JLjava/lang/String;)V");
   6802 
   6803     jlongArray refArray = getCertificateRefs(env, x509_store_ctx->untrusted);
   6804 
   6805     const char* authMethod = SSL_authentication_method(ssl);
   6806     JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s",
   6807               ssl, authMethod);
   6808     jstring authMethodString = env->NewStringUTF(authMethod);
   6809     env->CallVoidMethod(sslHandshakeCallbacks, methodID,
   6810             static_cast<jlong>(reinterpret_cast<uintptr_t>(SSL_get1_session(ssl))), refArray,
   6811             authMethodString);
   6812 
   6813     int result = (env->ExceptionCheck()) ? 0 : 1;
   6814     JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result);
   6815     return result;
   6816 }
   6817 
   6818 /**
   6819  * Call back to watch for handshake to be completed. This is necessary
   6820  * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake
   6821  * returns before the handshake is completed in this case.
   6822  */
   6823 static void info_callback(const SSL* ssl, int where, int ret) {
   6824     JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret);
   6825 #ifdef WITH_JNI_TRACE
   6826     info_callback_LOG(ssl, where, ret);
   6827 #endif
   6828     if (!(where & SSL_CB_HANDSHAKE_DONE) && !(where & SSL_CB_HANDSHAKE_START)) {
   6829         JNI_TRACE("ssl=%p info_callback ignored", ssl);
   6830         return;
   6831     }
   6832 
   6833     AppData* appData = toAppData(ssl);
   6834     JNIEnv* env = appData->env;
   6835     if (env == NULL) {
   6836         ALOGE("AppData->env missing in info_callback");
   6837         JNI_TRACE("ssl=%p info_callback env error", ssl);
   6838         return;
   6839     }
   6840     if (env->ExceptionCheck()) {
   6841         JNI_TRACE("ssl=%p info_callback already pending exception", ssl);
   6842         return;
   6843     }
   6844 
   6845     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   6846 
   6847     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   6848     jmethodID methodID = env->GetMethodID(cls, "onSSLStateChange", "(JII)V");
   6849 
   6850     JNI_TRACE("ssl=%p info_callback calling onSSLStateChange", ssl);
   6851     env->CallVoidMethod(sslHandshakeCallbacks, methodID, reinterpret_cast<jlong>(ssl), where, ret);
   6852 
   6853     if (env->ExceptionCheck()) {
   6854         JNI_TRACE("ssl=%p info_callback exception", ssl);
   6855     }
   6856     JNI_TRACE("ssl=%p info_callback completed", ssl);
   6857 }
   6858 
   6859 /**
   6860  * Call back to ask for a client certificate. There are three possible exit codes:
   6861  *
   6862  * 1 is success. x509Out and pkeyOut should point to the correct private key and certificate.
   6863  * 0 is unable to find key. x509Out and pkeyOut should be NULL.
   6864  * -1 is error and it doesn't matter what x509Out and pkeyOut are.
   6865  */
   6866 static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) {
   6867     JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut);
   6868 
   6869     /* Clear output of key and certificate in case of early exit due to error. */
   6870     *x509Out = NULL;
   6871     *pkeyOut = NULL;
   6872 
   6873     AppData* appData = toAppData(ssl);
   6874     JNIEnv* env = appData->env;
   6875     if (env == NULL) {
   6876         ALOGE("AppData->env missing in client_cert_cb");
   6877         JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl);
   6878         return 0;
   6879     }
   6880     if (env->ExceptionCheck()) {
   6881         JNI_TRACE("ssl=%p client_cert_cb already pending exception => 0", ssl);
   6882         return -1;
   6883     }
   6884     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   6885 
   6886     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   6887     jmethodID methodID
   6888         = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V");
   6889 
   6890     // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values
   6891     char ssl2_ctype = SSL3_CT_RSA_SIGN;
   6892     const char* ctype = NULL;
   6893     int ctype_num = 0;
   6894     jobjectArray issuers = NULL;
   6895     switch (ssl->version) {
   6896         case SSL2_VERSION:
   6897             ctype = &ssl2_ctype;
   6898             ctype_num = 1;
   6899             break;
   6900         case SSL3_VERSION:
   6901         case TLS1_VERSION:
   6902         case TLS1_1_VERSION:
   6903         case TLS1_2_VERSION:
   6904         case DTLS1_VERSION:
   6905             ctype = ssl->s3->tmp.ctype;
   6906             ctype_num = ssl->s3->tmp.ctype_num;
   6907             issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names);
   6908             break;
   6909     }
   6910 #ifdef WITH_JNI_TRACE
   6911     for (int i = 0; i < ctype_num; i++) {
   6912         JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]);
   6913     }
   6914 #endif
   6915 
   6916     jbyteArray keyTypes = env->NewByteArray(ctype_num);
   6917     if (keyTypes == NULL) {
   6918         JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl);
   6919         return 0;
   6920     }
   6921     env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype));
   6922 
   6923     JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested "
   6924               "keyTypes=%p issuers=%p", ssl, keyTypes, issuers);
   6925     env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers);
   6926 
   6927     if (env->ExceptionCheck()) {
   6928         JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl);
   6929         return -1;
   6930     }
   6931 
   6932     // Check for values set from Java
   6933     X509*     certificate = SSL_get_certificate(ssl);
   6934     EVP_PKEY* privatekey  = SSL_get_privatekey(ssl);
   6935     int result = 0;
   6936     if (certificate != NULL && privatekey != NULL) {
   6937         *x509Out = certificate;
   6938         *pkeyOut = privatekey;
   6939         result = 1;
   6940     } else {
   6941         // Some error conditions return NULL, so make sure it doesn't linger.
   6942         freeOpenSslErrorState();
   6943     }
   6944     JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result);
   6945     return result;
   6946 }
   6947 
   6948 /**
   6949  * Pre-Shared Key (PSK) client callback.
   6950  */
   6951 static unsigned int psk_client_callback(SSL* ssl, const char *hint,
   6952         char *identity, unsigned int max_identity_len,
   6953         unsigned char *psk, unsigned int max_psk_len) {
   6954     JNI_TRACE("ssl=%p psk_client_callback", ssl);
   6955 
   6956     AppData* appData = toAppData(ssl);
   6957     JNIEnv* env = appData->env;
   6958     if (env == NULL) {
   6959         ALOGE("AppData->env missing in psk_client_callback");
   6960         JNI_TRACE("ssl=%p psk_client_callback env error", ssl);
   6961         return 0;
   6962     }
   6963     if (env->ExceptionCheck()) {
   6964         JNI_TRACE("ssl=%p psk_client_callback already pending exception", ssl);
   6965         return 0;
   6966     }
   6967 
   6968     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   6969     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   6970     jmethodID methodID =
   6971             env->GetMethodID(cls, "clientPSKKeyRequested", "(Ljava/lang/String;[B[B)I");
   6972     JNI_TRACE("ssl=%p psk_client_callback calling clientPSKKeyRequested", ssl);
   6973     ScopedLocalRef<jstring> identityHintJava(
   6974             env,
   6975             (hint != NULL) ? env->NewStringUTF(hint) : NULL);
   6976     ScopedLocalRef<jbyteArray> identityJava(env, env->NewByteArray(max_identity_len));
   6977     if (identityJava.get() == NULL) {
   6978         JNI_TRACE("ssl=%p psk_client_callback failed to allocate identity bufffer", ssl);
   6979         return 0;
   6980     }
   6981     ScopedLocalRef<jbyteArray> keyJava(env, env->NewByteArray(max_psk_len));
   6982     if (keyJava.get() == NULL) {
   6983         JNI_TRACE("ssl=%p psk_client_callback failed to allocate key bufffer", ssl);
   6984         return 0;
   6985     }
   6986     jint keyLen = env->CallIntMethod(sslHandshakeCallbacks, methodID,
   6987             identityHintJava.get(), identityJava.get(), keyJava.get());
   6988     if (env->ExceptionCheck()) {
   6989         JNI_TRACE("ssl=%p psk_client_callback exception", ssl);
   6990         return 0;
   6991     }
   6992     if (keyLen <= 0) {
   6993         JNI_TRACE("ssl=%p psk_client_callback failed to get key", ssl);
   6994         return 0;
   6995     } else if ((unsigned int) keyLen > max_psk_len) {
   6996         JNI_TRACE("ssl=%p psk_client_callback got key which is too long", ssl);
   6997         return 0;
   6998     }
   6999     ScopedByteArrayRO keyJavaRo(env, keyJava.get());
   7000     if (keyJavaRo.get() == NULL) {
   7001         JNI_TRACE("ssl=%p psk_client_callback failed to get key bytes", ssl);
   7002         return 0;
   7003     }
   7004     memcpy(psk, keyJavaRo.get(), keyLen);
   7005 
   7006     ScopedByteArrayRO identityJavaRo(env, identityJava.get());
   7007     if (identityJavaRo.get() == NULL) {
   7008         JNI_TRACE("ssl=%p psk_client_callback failed to get identity bytes", ssl);
   7009         return 0;
   7010     }
   7011     memcpy(identity, identityJavaRo.get(), max_identity_len);
   7012 
   7013     JNI_TRACE("ssl=%p psk_client_callback completed", ssl);
   7014     return keyLen;
   7015 }
   7016 
   7017 /**
   7018  * Pre-Shared Key (PSK) server callback.
   7019  */
   7020 static unsigned int psk_server_callback(SSL* ssl, const char *identity,
   7021         unsigned char *psk, unsigned int max_psk_len) {
   7022     JNI_TRACE("ssl=%p psk_server_callback", ssl);
   7023 
   7024     AppData* appData = toAppData(ssl);
   7025     JNIEnv* env = appData->env;
   7026     if (env == NULL) {
   7027         ALOGE("AppData->env missing in psk_server_callback");
   7028         JNI_TRACE("ssl=%p psk_server_callback env error", ssl);
   7029         return 0;
   7030     }
   7031     if (env->ExceptionCheck()) {
   7032         JNI_TRACE("ssl=%p psk_server_callback already pending exception", ssl);
   7033         return 0;
   7034     }
   7035 
   7036     jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks;
   7037     jclass cls = env->GetObjectClass(sslHandshakeCallbacks);
   7038     jmethodID methodID = env->GetMethodID(
   7039             cls, "serverPSKKeyRequested", "(Ljava/lang/String;Ljava/lang/String;[B)I");
   7040     JNI_TRACE("ssl=%p psk_server_callback calling serverPSKKeyRequested", ssl);
   7041     const char* identityHint = SSL_get_psk_identity_hint(ssl);
   7042     // identityHint = NULL;
   7043     // identity = NULL;
   7044     ScopedLocalRef<jstring> identityHintJava(
   7045             env,
   7046             (identityHint != NULL) ? env->NewStringUTF(identityHint) : NULL);
   7047     ScopedLocalRef<jstring> identityJava(
   7048             env,
   7049             (identity != NULL) ? env->NewStringUTF(identity) : NULL);
   7050     ScopedLocalRef<jbyteArray> keyJava(env, env->NewByteArray(max_psk_len));
   7051     if (keyJava.get() == NULL) {
   7052         JNI_TRACE("ssl=%p psk_server_callback failed to allocate key bufffer", ssl);
   7053         return 0;
   7054     }
   7055     jint keyLen = env->CallIntMethod(sslHandshakeCallbacks, methodID,
   7056             identityHintJava.get(), identityJava.get(), keyJava.get());
   7057     if (env->ExceptionCheck()) {
   7058         JNI_TRACE("ssl=%p psk_server_callback exception", ssl);
   7059         return 0;
   7060     }
   7061     if (keyLen <= 0) {
   7062         JNI_TRACE("ssl=%p psk_server_callback failed to get key", ssl);
   7063         return 0;
   7064     } else if ((unsigned int) keyLen > max_psk_len) {
   7065         JNI_TRACE("ssl=%p psk_server_callback got key which is too long", ssl);
   7066         return 0;
   7067     }
   7068     ScopedByteArrayRO keyJavaRo(env, keyJava.get());
   7069     if (keyJavaRo.get() == NULL) {
   7070         JNI_TRACE("ssl=%p psk_server_callback failed to get key bytes", ssl);
   7071         return 0;
   7072     }
   7073     memcpy(psk, keyJavaRo.get(), keyLen);
   7074 
   7075     JNI_TRACE("ssl=%p psk_server_callback completed", ssl);
   7076     return keyLen;
   7077 }
   7078 
   7079 static RSA* rsaGenerateKey(int keylength) {
   7080     Unique_BIGNUM bn(BN_new());
   7081     if (bn.get() == NULL) {
   7082         return NULL;
   7083     }
   7084     int setWordResult = BN_set_word(bn.get(), RSA_F4);
   7085     if (setWordResult != 1) {
   7086         return NULL;
   7087     }
   7088     Unique_RSA rsa(RSA_new());
   7089     if (rsa.get() == NULL) {
   7090         return NULL;
   7091     }
   7092     int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL);
   7093     if (generateResult != 1) {
   7094         return NULL;
   7095     }
   7096     return rsa.release();
   7097 }
   7098 
   7099 /**
   7100  * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5)
   7101  */
   7102 static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)),
   7103                              int is_export __attribute__ ((unused)),
   7104                              int keylength) {
   7105     JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   7106 
   7107     AppData* appData = toAppData(ssl);
   7108     if (appData->ephemeralRsa.get() == NULL) {
   7109         JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl);
   7110         appData->ephemeralRsa.reset(rsaGenerateKey(keylength));
   7111     }
   7112     JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get());
   7113     return appData->ephemeralRsa.get();
   7114 }
   7115 
   7116 static DH* dhGenerateParameters(int keylength) {
   7117 
   7118     /*
   7119      * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two
   7120      * different options for generating DH keys. One is generating the
   7121      * keys using a single set of DH parameters. However, generating
   7122      * DH parameters is slow enough (minutes) that they suggest doing
   7123      * it once at install time. The other is to generate DH keys from
   7124      * DSA parameters. Generating DSA parameters is faster than DH
   7125      * parameters, but to prevent small subgroup attacks, they needed
   7126      * to be regenerated for each set of DH keys. Setting the
   7127      * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back
   7128      * for new DH parameters every type it needs to generate DH keys.
   7129      */
   7130 #if 0
   7131     // Slow path that takes minutes but could be cached
   7132     Unique_DH dh(DH_new());
   7133     if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) {
   7134         return NULL;
   7135     }
   7136     return dh.release();
   7137 #else
   7138     // Faster path but must have SSL_OP_SINGLE_DH_USE set
   7139     Unique_DSA dsa(DSA_new());
   7140     if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) {
   7141         return NULL;
   7142     }
   7143     DH* dh = DSA_dup_DH(dsa.get());
   7144     return dh;
   7145 #endif
   7146 }
   7147 
   7148 /**
   7149  * Call back to ask for Diffie-Hellman parameters
   7150  */
   7151 static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)),
   7152                            int is_export __attribute__ ((unused)),
   7153                            int keylength) {
   7154     JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   7155     DH* tmp_dh = dhGenerateParameters(keylength);
   7156     JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh);
   7157     return tmp_dh;
   7158 }
   7159 
   7160 static EC_KEY* ecGenerateKey(int keylength __attribute__ ((unused))) {
   7161     // TODO selected curve based on keylength
   7162     Unique_EC_KEY ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
   7163     if (ec.get() == NULL) {
   7164         return NULL;
   7165     }
   7166     return ec.release();
   7167 }
   7168 
   7169 /**
   7170  * Call back to ask for an ephemeral EC key for TLS_ECDHE_* cipher suites
   7171  */
   7172 static EC_KEY* tmp_ecdh_callback(SSL* ssl __attribute__ ((unused)),
   7173                                  int is_export __attribute__ ((unused)),
   7174                                  int keylength) {
   7175     JNI_TRACE("ssl=%p tmp_ecdh_callback is_export=%d keylength=%d", ssl, is_export, keylength);
   7176     AppData* appData = toAppData(ssl);
   7177     if (appData->ephemeralEc.get() == NULL) {
   7178         JNI_TRACE("ssl=%p tmp_ecdh_callback generating ephemeral EC key", ssl);
   7179         appData->ephemeralEc.reset(ecGenerateKey(keylength));
   7180     }
   7181     JNI_TRACE("ssl=%p tmp_ecdh_callback => %p", ssl, appData->ephemeralEc.get());
   7182     return appData->ephemeralEc.get();
   7183 }
   7184 
   7185 /*
   7186  * public static native int SSL_CTX_new();
   7187  */
   7188 static jlong NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) {
   7189     Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
   7190     if (sslCtx.get() == NULL) {
   7191         throwExceptionIfNecessary(env, "SSL_CTX_new");
   7192         return 0;
   7193     }
   7194     SSL_CTX_set_options(sslCtx.get(),
   7195                         SSL_OP_ALL
   7196                         // Note: We explicitly do not allow SSLv2 to be used.
   7197                         | SSL_OP_NO_SSLv2
   7198                         // We also disable session tickets for better compatibility b/2682876
   7199                         | SSL_OP_NO_TICKET
   7200                         // We also disable compression for better compatibility b/2710492 b/2710497
   7201                         | SSL_OP_NO_COMPRESSION
   7202                         // Because dhGenerateParameters uses DSA_generate_parameters_ex
   7203                         | SSL_OP_SINGLE_DH_USE
   7204                         // Because ecGenerateParameters uses a fixed named curve
   7205                         | SSL_OP_SINGLE_ECDH_USE);
   7206 
   7207     int mode = SSL_CTX_get_mode(sslCtx.get());
   7208     /*
   7209      * Turn on "partial write" mode. This means that SSL_write() will
   7210      * behave like Posix write() and possibly return after only
   7211      * writing a partial buffer. Note: The alternative, perhaps
   7212      * surprisingly, is not that SSL_write() always does full writes
   7213      * but that it will force you to retry write calls having
   7214      * preserved the full state of the original call. (This is icky
   7215      * and undesirable.)
   7216      */
   7217     mode |= SSL_MODE_ENABLE_PARTIAL_WRITE;
   7218 
   7219     // Reuse empty buffers within the SSL_CTX to save memory
   7220     mode |= SSL_MODE_RELEASE_BUFFERS;
   7221 
   7222     SSL_CTX_set_mode(sslCtx.get(), mode);
   7223 
   7224     SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL);
   7225     SSL_CTX_set_info_callback(sslCtx.get(), info_callback);
   7226     SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb);
   7227     SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback);
   7228     SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback);
   7229     SSL_CTX_set_tmp_ecdh_callback(sslCtx.get(), tmp_ecdh_callback);
   7230 
   7231     // When TLS Channel ID extension is used, use the new version of it.
   7232     sslCtx.get()->tlsext_channel_id_enabled_new = 1;
   7233 
   7234     JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
   7235     return (jlong) sslCtx.release();
   7236 }
   7237 
   7238 /**
   7239  * public static native void SSL_CTX_free(long ssl_ctx)
   7240  */
   7241 static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
   7242         jclass, jlong ssl_ctx_address)
   7243 {
   7244     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   7245     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
   7246     if (ssl_ctx == NULL) {
   7247         return;
   7248     }
   7249     SSL_CTX_free(ssl_ctx);
   7250 }
   7251 
   7252 static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass,
   7253                                                         jlong ssl_ctx_address, jbyteArray sid_ctx)
   7254 {
   7255     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   7256     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx);
   7257     if (ssl_ctx == NULL) {
   7258         return;
   7259     }
   7260 
   7261     ScopedByteArrayRO buf(env, sid_ctx);
   7262     if (buf.get() == NULL) {
   7263         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => threw exception", ssl_ctx);
   7264         return;
   7265     }
   7266 
   7267     unsigned int length = buf.size();
   7268     if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) {
   7269         jniThrowException(env, "java/lang/IllegalArgumentException",
   7270                           "length > SSL_MAX_SSL_SESSION_ID_LENGTH");
   7271         JNI_TRACE("NativeCrypto_SSL_CTX_set_session_id_context => length = %d", length);
   7272         return;
   7273     }
   7274     const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buf.get());
   7275     int result = SSL_CTX_set_session_id_context(ssl_ctx, bytes, length);
   7276     if (result == 0) {
   7277         throwExceptionIfNecessary(env, "NativeCrypto_SSL_CTX_set_session_id_context");
   7278         return;
   7279     }
   7280     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => ok", ssl_ctx);
   7281 }
   7282 
   7283 /**
   7284  * public static native int SSL_new(long ssl_ctx) throws SSLException;
   7285  */
   7286 static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address)
   7287 {
   7288     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   7289     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
   7290     if (ssl_ctx == NULL) {
   7291         return 0;
   7292     }
   7293     Unique_SSL ssl(SSL_new(ssl_ctx));
   7294     if (ssl.get() == NULL) {
   7295         throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE,
   7296                 "Unable to create SSL structure");
   7297         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
   7298         return 0;
   7299     }
   7300 
   7301     /*
   7302      * Create our special application data.
   7303      */
   7304     AppData* appData = AppData::create();
   7305     if (appData == NULL) {
   7306         throwSSLExceptionStr(env, "Unable to create application data");
   7307         freeOpenSslErrorState();
   7308         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new appData => 0", ssl_ctx);
   7309         return 0;
   7310     }
   7311     SSL_set_app_data(ssl.get(), reinterpret_cast<char*>(appData));
   7312 
   7313     /*
   7314      * Java code in class OpenSSLSocketImpl does the verification. Since
   7315      * the callbacks do all the verification of the chain, this flag
   7316      * simply controls whether to send protocol-level alerts or not.
   7317      * SSL_VERIFY_NONE means don't send alerts and anything else means send
   7318      * alerts.
   7319      */
   7320     SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, NULL);
   7321 
   7322     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p appData=%p", ssl_ctx, ssl.get(), appData);
   7323     return (jlong) ssl.release();
   7324 }
   7325 
   7326 
   7327 static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
   7328 {
   7329     SSL* ssl = to_SSL(env, ssl_address, true);
   7330     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_enable_tls_channel_id", ssl);
   7331     if (ssl == NULL) {
   7332         return;
   7333     }
   7334 
   7335     long ret = SSL_enable_tls_channel_id(ssl);
   7336     if (ret != 1L) {
   7337         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7338         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error enabling Channel ID");
   7339         safeSslClear(ssl);
   7340         JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id => error", ssl);
   7341         return;
   7342     }
   7343 }
   7344 
   7345 static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
   7346 {
   7347     SSL* ssl = to_SSL(env, ssl_address, true);
   7348     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id", ssl);
   7349     if (ssl == NULL) {
   7350         return NULL;
   7351     }
   7352 
   7353     // Channel ID is 64 bytes long. Unfortunately, OpenSSL doesn't declare this length
   7354     // as a constant anywhere.
   7355     jbyteArray javaBytes = env->NewByteArray(64);
   7356     ScopedByteArrayRW bytes(env, javaBytes);
   7357     if (bytes.get() == NULL) {
   7358         JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => NULL", ssl);
   7359         return NULL;
   7360     }
   7361 
   7362     unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
   7363     // Unfortunately, the SSL_get_tls_channel_id method below always returns 64 (upon success)
   7364     // regardless of the number of bytes copied into the output buffer "tmp". Thus, the correctness
   7365     // of this code currently relies on the "tmp" buffer being exactly 64 bytes long.
   7366     long ret = SSL_get_tls_channel_id(ssl, tmp, 64);
   7367     if (ret == 0) {
   7368         // Channel ID either not set or did not verify
   7369         JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => not available", ssl);
   7370         return NULL;
   7371     } else if (ret != 64) {
   7372         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7373         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error getting Channel ID");
   7374         safeSslClear(ssl);
   7375         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_tls_channel_id => error, returned %ld", ssl, ret);
   7376         return NULL;
   7377     }
   7378 
   7379     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id() => %p", ssl, javaBytes);
   7380     return javaBytes;
   7381 }
   7382 
   7383 static void NativeCrypto_SSL_set1_tls_channel_id(JNIEnv* env, jclass,
   7384         jlong ssl_address, jlong pkeyRef)
   7385 {
   7386     SSL* ssl = to_SSL(env, ssl_address, true);
   7387     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   7388     JNI_TRACE("ssl=%p SSL_set1_tls_channel_id privatekey=%p", ssl, pkey);
   7389     if (ssl == NULL) {
   7390         return;
   7391     }
   7392 
   7393     if (pkey == NULL) {
   7394         jniThrowNullPointerException(env, "pkey == null");
   7395         JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => pkey == null", ssl);
   7396         return;
   7397     }
   7398 
   7399     // SSL_set1_tls_channel_id requires ssl->server to be set to 0.
   7400     // Unfortunately, the default value is 1 and it's only changed to 0 just
   7401     // before the handshake starts (see NativeCrypto_SSL_do_handshake).
   7402     ssl->server = 0;
   7403     long ret = SSL_set1_tls_channel_id(ssl, pkey);
   7404 
   7405     if (ret != 1L) {
   7406         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7407         throwSSLExceptionWithSslErrors(
   7408                 env, ssl, SSL_ERROR_NONE, "Error setting private key for Channel ID");
   7409         safeSslClear(ssl);
   7410         JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => error", ssl);
   7411         return;
   7412     }
   7413     // SSL_set1_tls_channel_id expects to take ownership of the EVP_PKEY, but
   7414     // we have an external reference from the caller such as an OpenSSLKey,
   7415     // so we manually increment the reference count here.
   7416     CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
   7417 
   7418     JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => ok", ssl);
   7419 }
   7420 
   7421 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, jlong ssl_address, jlong pkeyRef) {
   7422     SSL* ssl = to_SSL(env, ssl_address, true);
   7423     EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef);
   7424     JNI_TRACE("ssl=%p SSL_use_PrivateKey privatekey=%p", ssl, pkey);
   7425     if (ssl == NULL) {
   7426         return;
   7427     }
   7428 
   7429     if (pkey == NULL) {
   7430         jniThrowNullPointerException(env, "pkey == null");
   7431         JNI_TRACE("ssl=%p SSL_use_PrivateKey => pkey == null", ssl);
   7432         return;
   7433     }
   7434 
   7435     int ret = SSL_use_PrivateKey(ssl, pkey);
   7436     if (ret != 1) {
   7437         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7438         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
   7439         safeSslClear(ssl);
   7440         JNI_TRACE("ssl=%p SSL_use_PrivateKey => error", ssl);
   7441         return;
   7442     }
   7443     // SSL_use_PrivateKey expects to take ownership of the EVP_PKEY,
   7444     // but we have an external reference from the caller such as an
   7445     // OpenSSLKey, so we manually increment the reference count here.
   7446     CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY);
   7447 
   7448     JNI_TRACE("ssl=%p SSL_use_PrivateKey => ok", ssl);
   7449 }
   7450 
   7451 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
   7452                                              jlong ssl_address, jlongArray certificatesJava)
   7453 {
   7454     SSL* ssl = to_SSL(env, ssl_address, true);
   7455     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificatesJava);
   7456     if (ssl == NULL) {
   7457         return;
   7458     }
   7459 
   7460     if (certificatesJava == NULL) {
   7461         jniThrowNullPointerException(env, "certificates == null");
   7462         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
   7463         return;
   7464     }
   7465 
   7466     size_t length = env->GetArrayLength(certificatesJava);
   7467     if (length == 0) {
   7468         jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
   7469         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
   7470         return;
   7471     }
   7472 
   7473     ScopedLongArrayRO certificates(env, certificatesJava);
   7474     if (certificates.get() == NULL) {
   7475         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
   7476         return;
   7477     }
   7478 
   7479     Unique_X509 serverCert(
   7480             X509_dup_nocopy(reinterpret_cast<X509*>(static_cast<uintptr_t>(certificates[0]))));
   7481     if (serverCert.get() == NULL) {
   7482         // Note this shouldn't happen since we checked the number of certificates above.
   7483         jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
   7484         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
   7485         return;
   7486     }
   7487 
   7488     Unique_sk_X509 chain(sk_X509_new_null());
   7489     if (chain.get() == NULL) {
   7490         jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
   7491         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
   7492         return;
   7493     }
   7494 
   7495     for (size_t i = 1; i < length; i++) {
   7496         Unique_X509 cert(
   7497                 X509_dup_nocopy(reinterpret_cast<X509*>(static_cast<uintptr_t>(certificates[i]))));
   7498         if (cert.get() == NULL || !sk_X509_push(chain.get(), cert.get())) {
   7499             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7500             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
   7501             safeSslClear(ssl);
   7502             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
   7503             return;
   7504         }
   7505         OWNERSHIP_TRANSFERRED(cert);
   7506     }
   7507 
   7508     int ret = SSL_use_certificate(ssl, serverCert.get());
   7509     if (ret != 1) {
   7510         ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7511         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
   7512         safeSslClear(ssl);
   7513         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
   7514         return;
   7515     }
   7516     OWNERSHIP_TRANSFERRED(serverCert);
   7517 
   7518     int chainResult = SSL_use_certificate_chain(ssl, chain.get());
   7519     if (chainResult == 0) {
   7520         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
   7521         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
   7522                   ssl);
   7523         return;
   7524     }
   7525     OWNERSHIP_TRANSFERRED(chain);
   7526 
   7527     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
   7528 }
   7529 
   7530 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jlong ssl_address)
   7531 {
   7532     SSL* ssl = to_SSL(env, ssl_address, true);
   7533     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
   7534     if (ssl == NULL) {
   7535         return;
   7536     }
   7537     int ret = SSL_check_private_key(ssl);
   7538     if (ret != 1) {
   7539         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
   7540         safeSslClear(ssl);
   7541         JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
   7542         return;
   7543     }
   7544     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
   7545 }
   7546 
   7547 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
   7548                                                 jlong ssl_address, jobjectArray principals)
   7549 {
   7550     SSL* ssl = to_SSL(env, ssl_address, true);
   7551     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
   7552     if (ssl == NULL) {
   7553         return;
   7554     }
   7555 
   7556     if (principals == NULL) {
   7557         jniThrowNullPointerException(env, "principals == null");
   7558         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
   7559         return;
   7560     }
   7561 
   7562     int length = env->GetArrayLength(principals);
   7563     if (length == 0) {
   7564         jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
   7565         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
   7566         return;
   7567     }
   7568 
   7569     Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
   7570     if (principalsStack.get() == NULL) {
   7571         jniThrowOutOfMemory(env, "Unable to allocate principal stack");
   7572         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
   7573         return;
   7574     }
   7575     for (int i = 0; i < length; i++) {
   7576         ScopedLocalRef<jbyteArray> principal(env,
   7577                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
   7578         if (principal.get() == NULL) {
   7579             jniThrowNullPointerException(env, "principals element == null");
   7580             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
   7581             return;
   7582         }
   7583 
   7584         ScopedByteArrayRO buf(env, principal.get());
   7585         if (buf.get() == NULL) {
   7586             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
   7587             return;
   7588         }
   7589         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
   7590         Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size()));
   7591 
   7592         if (principalX509Name.get() == NULL) {
   7593             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
   7594             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
   7595             safeSslClear(ssl);
   7596             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
   7597                       ssl);
   7598             return;
   7599         }
   7600 
   7601         if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
   7602             jniThrowOutOfMemory(env, "Unable to push principal");
   7603             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
   7604             return;
   7605         }
   7606     }
   7607 
   7608     SSL_set_client_CA_list(ssl, principalsStack.release());
   7609     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
   7610 }
   7611 
   7612 /**
   7613  * public static native long SSL_get_mode(long ssl);
   7614  */
   7615 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jlong ssl_address) {
   7616     SSL* ssl = to_SSL(env, ssl_address, true);
   7617     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
   7618     if (ssl == NULL) {
   7619       return 0;
   7620     }
   7621     long mode = SSL_get_mode(ssl);
   7622     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
   7623     return mode;
   7624 }
   7625 
   7626 /**
   7627  * public static native long SSL_set_mode(long ssl, long mode);
   7628  */
   7629 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
   7630         jlong ssl_address, jlong mode) {
   7631     SSL* ssl = to_SSL(env, ssl_address, true);
   7632     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode);
   7633     if (ssl == NULL) {
   7634       return 0;
   7635     }
   7636     long result = SSL_set_mode(ssl, mode);
   7637     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
   7638     return result;
   7639 }
   7640 
   7641 /**
   7642  * public static native long SSL_clear_mode(long ssl, long mode);
   7643  */
   7644 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
   7645         jlong ssl_address, jlong mode) {
   7646     SSL* ssl = to_SSL(env, ssl_address, true);
   7647     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode);
   7648     if (ssl == NULL) {
   7649       return 0;
   7650     }
   7651     long result = SSL_clear_mode(ssl, mode);
   7652     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
   7653     return result;
   7654 }
   7655 
   7656 /**
   7657  * public static native long SSL_get_options(long ssl);
   7658  */
   7659 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
   7660         jlong ssl_address) {
   7661     SSL* ssl = to_SSL(env, ssl_address, true);
   7662     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
   7663     if (ssl == NULL) {
   7664       return 0;
   7665     }
   7666     long options = SSL_get_options(ssl);
   7667     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
   7668     return options;
   7669 }
   7670 
   7671 /**
   7672  * public static native long SSL_set_options(long ssl, long options);
   7673  */
   7674 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
   7675         jlong ssl_address, jlong options) {
   7676     SSL* ssl = to_SSL(env, ssl_address, true);
   7677     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options);
   7678     if (ssl == NULL) {
   7679       return 0;
   7680     }
   7681     long result = SSL_set_options(ssl, options);
   7682     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
   7683     return result;
   7684 }
   7685 
   7686 /**
   7687  * public static native long SSL_clear_options(long ssl, long options);
   7688  */
   7689 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
   7690         jlong ssl_address, jlong options) {
   7691     SSL* ssl = to_SSL(env, ssl_address, true);
   7692     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options);
   7693     if (ssl == NULL) {
   7694       return 0;
   7695     }
   7696     long result = SSL_clear_options(ssl, options);
   7697     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
   7698     return result;
   7699 }
   7700 
   7701 
   7702 static void NativeCrypto_SSL_use_psk_identity_hint(JNIEnv* env, jclass,
   7703         jlong ssl_address, jstring identityHintJava)
   7704 {
   7705     SSL* ssl = to_SSL(env, ssl_address, true);
   7706     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_psk_identity_hint identityHint=%p",
   7707             ssl, identityHintJava);
   7708     if (ssl == NULL)  {
   7709         return;
   7710     }
   7711 
   7712     int ret;
   7713     if (identityHintJava == NULL) {
   7714         ret = SSL_use_psk_identity_hint(ssl, NULL);
   7715     } else {
   7716         ScopedUtfChars identityHint(env, identityHintJava);
   7717         if (identityHint.c_str() == NULL) {
   7718             throwSSLExceptionStr(env, "Failed to obtain identityHint bytes");
   7719             return;
   7720         }
   7721         ret = SSL_use_psk_identity_hint(ssl, identityHint.c_str());
   7722     }
   7723 
   7724     if (ret != 1) {
   7725         int sslErrorCode = SSL_get_error(ssl, ret);
   7726         throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Failed to set PSK identity hint");
   7727         safeSslClear(ssl);
   7728     }
   7729 }
   7730 
   7731 static void NativeCrypto_set_SSL_psk_client_callback_enabled(JNIEnv* env, jclass,
   7732         jlong ssl_address, jboolean enabled)
   7733 {
   7734     SSL* ssl = to_SSL(env, ssl_address, true);
   7735     JNI_TRACE("ssl=%p NativeCrypto_set_SSL_psk_client_callback_enabled(%d)",
   7736             ssl, enabled);
   7737     if (ssl == NULL)  {
   7738         return;
   7739     }
   7740 
   7741     SSL_set_psk_client_callback(ssl, (enabled) ? psk_client_callback : NULL);
   7742 }
   7743 
   7744 static void NativeCrypto_set_SSL_psk_server_callback_enabled(JNIEnv* env, jclass,
   7745         jlong ssl_address, jboolean enabled)
   7746 {
   7747     SSL* ssl = to_SSL(env, ssl_address, true);
   7748     JNI_TRACE("ssl=%p NativeCrypto_set_SSL_psk_server_callback_enabled(%d)",
   7749             ssl, enabled);
   7750     if (ssl == NULL)  {
   7751         return;
   7752     }
   7753 
   7754     SSL_set_psk_server_callback(ssl, (enabled) ? psk_server_callback : NULL);
   7755 }
   7756 
   7757 static jlongArray NativeCrypto_SSL_get_ciphers(JNIEnv* env, jclass, jlong ssl_address)
   7758 {
   7759     SSL* ssl = to_SSL(env, ssl_address, true);
   7760     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_ciphers", ssl);
   7761 
   7762     STACK_OF(SSL_CIPHER)* cipherStack = SSL_get_ciphers(ssl);
   7763     int count = (cipherStack != NULL) ? sk_SSL_CIPHER_num(cipherStack) : 0;
   7764     ScopedLocalRef<jlongArray> ciphersArray(env, env->NewLongArray(count));
   7765     ScopedLongArrayRW ciphers(env, ciphersArray.get());
   7766     for (int i = 0; i < count; i++) {
   7767         ciphers[i] = reinterpret_cast<jlong>(sk_SSL_CIPHER_value(cipherStack, i));
   7768     }
   7769 
   7770     JNI_TRACE("NativeCrypto_SSL_get_ciphers(%p) => %p [size=%d]", ssl, ciphersArray.get(), count);
   7771     return ciphersArray.release();
   7772 }
   7773 
   7774 static jint NativeCrypto_get_SSL_CIPHER_algorithm_mkey(JNIEnv* env, jclass,
   7775         jlong ssl_cipher_address)
   7776 {
   7777     SSL_CIPHER* cipher = to_SSL_CIPHER(env, ssl_cipher_address, true);
   7778     JNI_TRACE("cipher=%p get_SSL_CIPHER_algorithm_mkey => %ld", cipher, cipher->algorithm_mkey);
   7779     return cipher->algorithm_mkey;
   7780 }
   7781 
   7782 static jint NativeCrypto_get_SSL_CIPHER_algorithm_auth(JNIEnv* env, jclass,
   7783         jlong ssl_cipher_address)
   7784 {
   7785     SSL_CIPHER* cipher = to_SSL_CIPHER(env, ssl_cipher_address, true);
   7786     JNI_TRACE("cipher=%p get_SSL_CIPHER_algorithm_auth => %ld", cipher, cipher->algorithm_auth);
   7787     return cipher->algorithm_auth;
   7788 }
   7789 
   7790 /**
   7791  * Sets the ciphers suites that are enabled in the SSL
   7792  */
   7793 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass,
   7794         jlong ssl_address, jobjectArray cipherSuites)
   7795 {
   7796     SSL* ssl = to_SSL(env, ssl_address, true);
   7797     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
   7798     if (ssl == NULL) {
   7799         return;
   7800     }
   7801     if (cipherSuites == NULL) {
   7802         jniThrowNullPointerException(env, "cipherSuites == null");
   7803         return;
   7804     }
   7805 
   7806     Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null());
   7807     if (cipherstack.get() == NULL) {
   7808         jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed");
   7809         return;
   7810     }
   7811 
   7812     const SSL_METHOD* ssl_method = ssl->method;
   7813     int num_ciphers = ssl_method->num_ciphers();
   7814 
   7815     int length = env->GetArrayLength(cipherSuites);
   7816     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length);
   7817     for (int i = 0; i < length; i++) {
   7818         ScopedLocalRef<jstring> cipherSuite(env,
   7819                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
   7820         ScopedUtfChars c(env, cipherSuite.get());
   7821         if (c.c_str() == NULL) {
   7822             return;
   7823         }
   7824         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str());
   7825         bool found = false;
   7826         for (int j = 0; j < num_ciphers; j++) {
   7827             const SSL_CIPHER* cipher = ssl_method->get_cipher(j);
   7828             if ((strcmp(c.c_str(), cipher->name) == 0)
   7829                     && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) {
   7830                 if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) {
   7831                     jniThrowOutOfMemory(env, "Unable to push cipher");
   7832                     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl);
   7833                     return;
   7834                 }
   7835                 found = true;
   7836             }
   7837         }
   7838         if (!found) {
   7839             jniThrowException(env, "java/lang/IllegalArgumentException",
   7840                               "Could not find cipher suite.");
   7841             return;
   7842         }
   7843     }
   7844 
   7845     int rc = SSL_set_cipher_lists(ssl, cipherstack.get());
   7846     if (rc == 0) {
   7847         freeOpenSslErrorState();
   7848         jniThrowException(env, "java/lang/IllegalArgumentException",
   7849                           "Illegal cipher suite strings.");
   7850     } else {
   7851         OWNERSHIP_TRANSFERRED(cipherstack);
   7852     }
   7853 }
   7854 
   7855 static void NativeCrypto_SSL_set_accept_state(JNIEnv* env, jclass, jlong sslRef) {
   7856     SSL* ssl = to_SSL(env, sslRef, true);
   7857     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_accept_state", ssl);
   7858     if (ssl == NULL) {
   7859       return;
   7860     }
   7861     SSL_set_accept_state(ssl);
   7862 }
   7863 
   7864 static void NativeCrypto_SSL_set_connect_state(JNIEnv* env, jclass, jlong sslRef) {
   7865     SSL* ssl = to_SSL(env, sslRef, true);
   7866     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_connect_state", ssl);
   7867     if (ssl == NULL) {
   7868       return;
   7869     }
   7870     SSL_set_connect_state(ssl);
   7871 }
   7872 
   7873 /**
   7874  * Sets certificate expectations, especially for server to request client auth
   7875  */
   7876 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
   7877         jclass, jlong ssl_address, jint mode)
   7878 {
   7879     SSL* ssl = to_SSL(env, ssl_address, true);
   7880     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
   7881     if (ssl == NULL) {
   7882       return;
   7883     }
   7884     SSL_set_verify(ssl, (int)mode, NULL);
   7885 }
   7886 
   7887 /**
   7888  * Sets the ciphers suites that are enabled in the SSL
   7889  */
   7890 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
   7891         jlong ssl_address, jlong ssl_session_address)
   7892 {
   7893     SSL* ssl = to_SSL(env, ssl_address, true);
   7894     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
   7895     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
   7896     if (ssl == NULL) {
   7897         return;
   7898     }
   7899 
   7900     int ret = SSL_set_session(ssl, ssl_session);
   7901     if (ret != 1) {
   7902         /*
   7903          * Translate the error, and throw if it turns out to be a real
   7904          * problem.
   7905          */
   7906         int sslErrorCode = SSL_get_error(ssl, ret);
   7907         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
   7908             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
   7909             safeSslClear(ssl);
   7910         }
   7911     }
   7912 }
   7913 
   7914 /**
   7915  * Sets the ciphers suites that are enabled in the SSL
   7916  */
   7917 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
   7918         jlong ssl_address, jboolean creation_enabled)
   7919 {
   7920     SSL* ssl = to_SSL(env, ssl_address, true);
   7921     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
   7922               ssl, creation_enabled);
   7923     if (ssl == NULL) {
   7924         return;
   7925     }
   7926     SSL_set_session_creation_enabled(ssl, creation_enabled);
   7927 }
   7928 
   7929 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
   7930         jlong ssl_address, jstring hostname)
   7931 {
   7932     SSL* ssl = to_SSL(env, ssl_address, true);
   7933     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
   7934               ssl, hostname);
   7935     if (ssl == NULL) {
   7936         return;
   7937     }
   7938 
   7939     ScopedUtfChars hostnameChars(env, hostname);
   7940     if (hostnameChars.c_str() == NULL) {
   7941         return;
   7942     }
   7943     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s",
   7944               ssl, hostnameChars.c_str());
   7945 
   7946     int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
   7947     if (ret != 1) {
   7948         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
   7949         safeSslClear(ssl);
   7950         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
   7951         return;
   7952     }
   7953     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
   7954 }
   7955 
   7956 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_address) {
   7957     SSL* ssl = to_SSL(env, ssl_address, true);
   7958     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
   7959     if (ssl == NULL) {
   7960         return NULL;
   7961     }
   7962     const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
   7963     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
   7964     return env->NewStringUTF(servername);
   7965 }
   7966 
   7967 /**
   7968  * A common selection path for both NPN and ALPN since they're essentially the
   7969  * same protocol. The list of protocols in "primary" is considered the order
   7970  * which should take precedence.
   7971  */
   7972 static int proto_select(SSL* ssl __attribute__ ((unused)),
   7973         unsigned char **out, unsigned char *outLength,
   7974         const unsigned char *primary, const unsigned int primaryLength,
   7975         const unsigned char *secondary, const unsigned int secondaryLength) {
   7976     if (primary != NULL && secondary != NULL) {
   7977         JNI_TRACE("primary=%p, length=%d", primary, primaryLength);
   7978 
   7979         int status = SSL_select_next_proto(out, outLength, primary, primaryLength, secondary,
   7980                 secondaryLength);
   7981         switch (status) {
   7982         case OPENSSL_NPN_NEGOTIATED:
   7983             JNI_TRACE("ssl=%p proto_select NPN/ALPN negotiated", ssl);
   7984             return SSL_TLSEXT_ERR_OK;
   7985             break;
   7986         case OPENSSL_NPN_UNSUPPORTED:
   7987             JNI_TRACE("ssl=%p proto_select NPN/ALPN unsupported", ssl);
   7988             break;
   7989         case OPENSSL_NPN_NO_OVERLAP:
   7990             JNI_TRACE("ssl=%p proto_select NPN/ALPN no overlap", ssl);
   7991             break;
   7992         }
   7993     } else {
   7994         if (out != NULL && outLength != NULL) {
   7995             *out = NULL;
   7996             *outLength = 0;
   7997         }
   7998         JNI_TRACE("protocols=NULL");
   7999     }
   8000     return SSL_TLSEXT_ERR_NOACK;
   8001 }
   8002 
   8003 /**
   8004  * Callback for the server to select an ALPN protocol.
   8005  */
   8006 static int alpn_select_callback(SSL* ssl, const unsigned char **out, unsigned char *outlen,
   8007         const unsigned char *in, unsigned int inlen, void *) {
   8008     JNI_TRACE("ssl=%p alpn_select_callback", ssl);
   8009 
   8010     AppData* appData = toAppData(ssl);
   8011     JNI_TRACE("AppData=%p", appData);
   8012 
   8013     return proto_select(ssl, const_cast<unsigned char **>(out), outlen,
   8014             reinterpret_cast<unsigned char*>(appData->alpnProtocolsData),
   8015             appData->alpnProtocolsLength, in, inlen);
   8016 }
   8017 
   8018 /**
   8019  * Callback for the client to select an NPN protocol.
   8020  */
   8021 static int next_proto_select_callback(SSL* ssl, unsigned char** out, unsigned char* outlen,
   8022                                       const unsigned char* in, unsigned int inlen, void*)
   8023 {
   8024     JNI_TRACE("ssl=%p next_proto_select_callback", ssl);
   8025 
   8026     AppData* appData = toAppData(ssl);
   8027     JNI_TRACE("AppData=%p", appData);
   8028 
   8029     // Enable False Start on the client if the server understands NPN
   8030     // http://www.imperialviolet.org/2012/04/11/falsestart.html
   8031     SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
   8032 
   8033     return proto_select(ssl, out, outlen, in, inlen,
   8034             reinterpret_cast<unsigned char*>(appData->npnProtocolsData),
   8035             appData->npnProtocolsLength);
   8036 }
   8037 
   8038 /**
   8039  * Callback for the server to advertise available protocols.
   8040  */
   8041 static int next_protos_advertised_callback(SSL* ssl,
   8042         const unsigned char **out, unsigned int *outlen, void *)
   8043 {
   8044     JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl);
   8045     AppData* appData = toAppData(ssl);
   8046     unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
   8047     if (npnProtocols != NULL) {
   8048         *out = npnProtocols;
   8049         *outlen = appData->npnProtocolsLength;
   8050         return SSL_TLSEXT_ERR_OK;
   8051     } else {
   8052         *out = NULL;
   8053         *outlen = 0;
   8054         return SSL_TLSEXT_ERR_NOACK;
   8055     }
   8056 }
   8057 
   8058 static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
   8059 {
   8060     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   8061     if (ssl_ctx == NULL) {
   8062         return;
   8063     }
   8064     SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL); // client
   8065     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server
   8066 }
   8067 
   8068 static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
   8069 {
   8070     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
   8071     if (ssl_ctx == NULL) {
   8072         return;
   8073     }
   8074     SSL_CTX_set_next_proto_select_cb(ssl_ctx, NULL, NULL); // client
   8075     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, NULL, NULL); // server
   8076 }
   8077 
   8078 static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
   8079         jlong ssl_address)
   8080 {
   8081     SSL* ssl = to_SSL(env, ssl_address, true);
   8082     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
   8083     if (ssl == NULL) {
   8084         return NULL;
   8085     }
   8086     const jbyte* npn;
   8087     unsigned npnLength;
   8088     SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
   8089     if (npnLength == 0) {
   8090         return NULL;
   8091     }
   8092     jbyteArray result = env->NewByteArray(npnLength);
   8093     if (result != NULL) {
   8094         env->SetByteArrayRegion(result, 0, npnLength, npn);
   8095     }
   8096     return result;
   8097 }
   8098 
   8099 static int NativeCrypto_SSL_set_alpn_protos(JNIEnv* env, jclass, jlong ssl_address,
   8100         jbyteArray protos) {
   8101     SSL* ssl = to_SSL(env, ssl_address, true);
   8102     if (ssl == NULL) {
   8103         return 0;
   8104     }
   8105 
   8106     JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=%p", ssl, protos);
   8107 
   8108     if (protos == NULL) {
   8109         JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=NULL", ssl);
   8110         return 1;
   8111     }
   8112 
   8113     ScopedByteArrayRO protosBytes(env, protos);
   8114     if (protosBytes.get() == NULL) {
   8115         JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=%p => protosBytes == NULL", ssl,
   8116                 protos);
   8117         return 0;
   8118     }
   8119 
   8120     const unsigned char *tmp = reinterpret_cast<const unsigned char*>(protosBytes.get());
   8121     int ret = SSL_set_alpn_protos(ssl, tmp, protosBytes.size());
   8122     JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=%p => ret=%d", ssl, protos, ret);
   8123     return ret;
   8124 }
   8125 
   8126 static jbyteArray NativeCrypto_SSL_get0_alpn_selected(JNIEnv* env, jclass,
   8127         jlong ssl_address)
   8128 {
   8129     SSL* ssl = to_SSL(env, ssl_address, true);
   8130     JNI_TRACE("ssl=%p SSL_get0_alpn_selected", ssl);
   8131     if (ssl == NULL) {
   8132         return NULL;
   8133     }
   8134     const jbyte* npn;
   8135     unsigned npnLength;
   8136     SSL_get0_alpn_selected(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
   8137     if (npnLength == 0) {
   8138         return NULL;
   8139     }
   8140     jbyteArray result = env->NewByteArray(npnLength);
   8141     if (result != NULL) {
   8142         env->SetByteArrayRegion(result, 0, npnLength, npn);
   8143     }
   8144     return result;
   8145 }
   8146 
   8147 #ifdef WITH_JNI_TRACE_KEYS
   8148 static inline char hex_char(unsigned char in)
   8149 {
   8150     if (in < 10) {
   8151         return '0' + in;
   8152     } else if (in <= 0xF0) {
   8153         return 'A' + in - 10;
   8154     } else {
   8155         return '?';
   8156     }
   8157 }
   8158 
   8159 static void hex_string(char **dest, unsigned char* input, int len)
   8160 {
   8161     *dest = (char*) malloc(len * 2 + 1);
   8162     char *output = *dest;
   8163     for (int i = 0; i < len; i++) {
   8164         *output++ = hex_char(input[i] >> 4);
   8165         *output++ = hex_char(input[i] & 0xF);
   8166     }
   8167     *output = '\0';
   8168 }
   8169 
   8170 static void debug_print_session_key(SSL_SESSION* session)
   8171 {
   8172     char *session_id_str;
   8173     char *master_key_str;
   8174     const char *key_type;
   8175     char *keyline;
   8176 
   8177     hex_string(&session_id_str, session->session_id, session->session_id_length);
   8178     hex_string(&master_key_str, session->master_key, session->master_key_length);
   8179 
   8180     X509* peer = SSL_SESSION_get0_peer(session);
   8181     EVP_PKEY* pkey = X509_PUBKEY_get(peer->cert_info->key);
   8182     switch (EVP_PKEY_type(pkey->type)) {
   8183     case EVP_PKEY_RSA:
   8184         key_type = "RSA";
   8185         break;
   8186     case EVP_PKEY_DSA:
   8187         key_type = "DSA";
   8188         break;
   8189     case EVP_PKEY_EC:
   8190         key_type = "EC";
   8191         break;
   8192     default:
   8193         key_type = "Unknown";
   8194         break;
   8195     }
   8196 
   8197     asprintf(&keyline, "%s Session-ID:%s Master-Key:%s\n", key_type, session_id_str,
   8198             master_key_str);
   8199     JNI_TRACE("ssl_session=%p %s", session, keyline);
   8200 
   8201     free(session_id_str);
   8202     free(master_key_str);
   8203     free(keyline);
   8204 }
   8205 #endif /* WITH_JNI_TRACE_KEYS */
   8206 
   8207 /**
   8208  * Perform SSL handshake
   8209  */
   8210 static jlong NativeCrypto_SSL_do_handshake_bio(JNIEnv* env, jclass, jlong ssl_address,
   8211         jlong rbioRef, jlong wbioRef, jobject shc, jboolean client_mode, jbyteArray npnProtocols,
   8212         jbyteArray alpnProtocols) {
   8213     SSL* ssl = to_SSL(env, ssl_address, true);
   8214     BIO* rbio = reinterpret_cast<BIO*>(rbioRef);
   8215     BIO* wbio = reinterpret_cast<BIO*>(wbioRef);
   8216     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio rbio=%p wbio=%p shc=%p client_mode=%d npn=%p",
   8217               ssl, rbio, wbio, shc, client_mode, npnProtocols);
   8218     if (ssl == NULL) {
   8219         return 0;
   8220     }
   8221     if (shc == NULL) {
   8222         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   8223         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio sslHandshakeCallbacks == null => 0", ssl);
   8224         return 0;
   8225     }
   8226 
   8227     if (rbio == NULL || wbio == NULL) {
   8228         jniThrowNullPointerException(env, "rbio == null || wbio == null");
   8229         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio => rbio == null || wbio == NULL", ssl);
   8230         return 0;
   8231     }
   8232 
   8233     ScopedSslBio sslBio(ssl, rbio, wbio);
   8234 
   8235     AppData* appData = toAppData(ssl);
   8236     if (appData == NULL) {
   8237         throwSSLExceptionStr(env, "Unable to retrieve application data");
   8238         safeSslClear(ssl);
   8239         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
   8240         return 0;
   8241     }
   8242 
   8243     if (!client_mode && alpnProtocols != NULL) {
   8244         SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, NULL);
   8245     }
   8246 
   8247     int ret = 0;
   8248     errno = 0;
   8249 
   8250     if (!appData->setCallbackState(env, shc, NULL, npnProtocols, alpnProtocols)) {
   8251         freeOpenSslErrorState();
   8252         safeSslClear(ssl);
   8253         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio setCallbackState => 0", ssl);
   8254         return 0;
   8255     }
   8256     ret = SSL_do_handshake(ssl);
   8257     appData->clearCallbackState();
   8258     // cert_verify_callback threw exception
   8259     if (env->ExceptionCheck()) {
   8260         freeOpenSslErrorState();
   8261         safeSslClear(ssl);
   8262         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio exception => 0", ssl);
   8263         return 0;
   8264     }
   8265 
   8266     if (ret <= 0) { // error. See SSL_do_handshake(3SSL) man page.
   8267         // error case
   8268         OpenSslError sslError(ssl, ret);
   8269         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio ret=%d errno=%d sslError=%d",
   8270                   ssl, ret, errno, sslError.get());
   8271 
   8272         /*
   8273          * If SSL_do_handshake doesn't succeed due to the socket being
   8274          * either unreadable or unwritable, we need to exit to allow
   8275          * the SSLEngine code to wrap or unwrap.
   8276          */
   8277         if (sslError.get() == SSL_ERROR_NONE ||
   8278                 (sslError.get() == SSL_ERROR_SYSCALL && errno == 0) ||
   8279                 (sslError.get() == SSL_ERROR_ZERO_RETURN)) {
   8280             throwSSLHandshakeExceptionStr(env, "Connection closed by peer");
   8281             safeSslClear(ssl);
   8282         } else if (sslError.get() != SSL_ERROR_WANT_READ &&
   8283                 sslError.get() != SSL_ERROR_WANT_WRITE) {
   8284             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
   8285                     "SSL handshake terminated", throwSSLHandshakeExceptionStr);
   8286             safeSslClear(ssl);
   8287         }
   8288         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio error => 0", ssl);
   8289         return 0;
   8290     }
   8291 
   8292     // success. handshake completed
   8293     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
   8294     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio => ssl_session=%p", ssl, ssl_session);
   8295 #ifdef WITH_JNI_TRACE_KEYS
   8296     debug_print_session_key(ssl_session);
   8297 #endif
   8298     return reinterpret_cast<uintptr_t>(ssl_session);
   8299 }
   8300 
   8301 /**
   8302  * Perform SSL handshake
   8303  */
   8304 static jlong NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
   8305         jobject shc, jint timeout_millis, jboolean client_mode, jbyteArray npnProtocols,
   8306         jbyteArray alpnProtocols) {
   8307     SSL* ssl = to_SSL(env, ssl_address, true);
   8308     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p",
   8309               ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols);
   8310     if (ssl == NULL) {
   8311         return 0;
   8312     }
   8313     if (fdObject == NULL) {
   8314         jniThrowNullPointerException(env, "fd == null");
   8315         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl);
   8316         return 0;
   8317     }
   8318     if (shc == NULL) {
   8319         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   8320         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl);
   8321         return 0;
   8322     }
   8323 
   8324     NetFd fd(env, fdObject);
   8325     if (fd.isClosed()) {
   8326         // SocketException thrown by NetFd.isClosed
   8327         safeSslClear(ssl);
   8328         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
   8329         return 0;
   8330     }
   8331 
   8332     int ret = SSL_set_fd(ssl, fd.get());
   8333     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
   8334 
   8335     if (ret != 1) {
   8336         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
   8337                                        "Error setting the file descriptor");
   8338         safeSslClear(ssl);
   8339         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
   8340         return 0;
   8341     }
   8342 
   8343     /*
   8344      * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
   8345      * forever and we can use select() to find out if the socket is ready.
   8346      */
   8347     if (!setBlocking(fd.get(), false)) {
   8348         throwSSLExceptionStr(env, "Unable to make socket non blocking");
   8349         safeSslClear(ssl);
   8350         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
   8351         return 0;
   8352     }
   8353 
   8354     AppData* appData = toAppData(ssl);
   8355     if (appData == NULL) {
   8356         throwSSLExceptionStr(env, "Unable to retrieve application data");
   8357         safeSslClear(ssl);
   8358         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
   8359         return 0;
   8360     }
   8361 
   8362     if (client_mode) {
   8363         SSL_set_connect_state(ssl);
   8364     } else {
   8365         SSL_set_accept_state(ssl);
   8366         if (alpnProtocols != NULL) {
   8367             SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, NULL);
   8368         }
   8369     }
   8370 
   8371     ret = 0;
   8372     OpenSslError sslError;
   8373     while (appData->aliveAndKicking) {
   8374         errno = 0;
   8375 
   8376         if (!appData->setCallbackState(env, shc, fdObject, npnProtocols, alpnProtocols)) {
   8377             // SocketException thrown by NetFd.isClosed
   8378             safeSslClear(ssl);
   8379             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
   8380             return 0;
   8381         }
   8382         ret = SSL_do_handshake(ssl);
   8383         appData->clearCallbackState();
   8384         // cert_verify_callback threw exception
   8385         if (env->ExceptionCheck()) {
   8386             freeOpenSslErrorState();
   8387             safeSslClear(ssl);
   8388             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
   8389             return 0;
   8390         }
   8391         // success case
   8392         if (ret == 1) {
   8393             break;
   8394         }
   8395         // retry case
   8396         if (errno == EINTR) {
   8397             continue;
   8398         }
   8399         // error case
   8400         sslError.reset(ssl, ret);
   8401         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d",
   8402                   ssl, ret, errno, sslError.get(), timeout_millis);
   8403 
   8404         /*
   8405          * If SSL_do_handshake doesn't succeed due to the socket being
   8406          * either unreadable or unwritable, we use sslSelect to
   8407          * wait for it to become ready. If that doesn't happen
   8408          * before the specified timeout or an error occurs, we
   8409          * cancel the handshake. Otherwise we try the SSL_connect
   8410          * again.
   8411          */
   8412         if (sslError.get() == SSL_ERROR_WANT_READ || sslError.get() == SSL_ERROR_WANT_WRITE) {
   8413             appData->waitingThreads++;
   8414             int selectResult = sslSelect(env, sslError.get(), fdObject, appData, timeout_millis);
   8415 
   8416             if (selectResult == THROWN_EXCEPTION) {
   8417                 // SocketException thrown by NetFd.isClosed
   8418                 safeSslClear(ssl);
   8419                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
   8420                 return 0;
   8421             }
   8422             if (selectResult == -1) {
   8423                 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error",
   8424                         throwSSLHandshakeExceptionStr);
   8425                 safeSslClear(ssl);
   8426                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
   8427                 return 0;
   8428             }
   8429             if (selectResult == 0) {
   8430                 throwSocketTimeoutException(env, "SSL handshake timed out");
   8431                 freeOpenSslErrorState();
   8432                 safeSslClear(ssl);
   8433                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
   8434                 return 0;
   8435             }
   8436         } else {
   8437             // ALOGE("Unknown error %d during handshake", error);
   8438             break;
   8439         }
   8440     }
   8441 
   8442     // clean error. See SSL_do_handshake(3SSL) man page.
   8443     if (ret == 0) {
   8444         /*
   8445          * The other side closed the socket before the handshake could be
   8446          * completed, but everything is within the bounds of the TLS protocol.
   8447          * We still might want to find out the real reason of the failure.
   8448          */
   8449         if (sslError.get() == SSL_ERROR_NONE ||
   8450                 (sslError.get() == SSL_ERROR_SYSCALL && errno == 0) ||
   8451                 (sslError.get() == SSL_ERROR_ZERO_RETURN)) {
   8452             throwSSLHandshakeExceptionStr(env, "Connection closed by peer");
   8453         } else {
   8454             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
   8455                     "SSL handshake terminated", throwSSLHandshakeExceptionStr);
   8456         }
   8457         safeSslClear(ssl);
   8458         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
   8459         return 0;
   8460     }
   8461 
   8462     // unclean error. See SSL_do_handshake(3SSL) man page.
   8463     if (ret < 0) {
   8464         /*
   8465          * Translate the error and throw exception. We are sure it is an error
   8466          * at this point.
   8467          */
   8468         throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "SSL handshake aborted",
   8469                 throwSSLHandshakeExceptionStr);
   8470         safeSslClear(ssl);
   8471         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
   8472         return 0;
   8473     }
   8474     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
   8475     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
   8476 #ifdef WITH_JNI_TRACE_KEYS
   8477     debug_print_session_key(ssl_session);
   8478 #endif
   8479     return (jlong) ssl_session;
   8480 }
   8481 
   8482 /**
   8483  * Perform SSL renegotiation
   8484  */
   8485 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jlong ssl_address)
   8486 {
   8487     SSL* ssl = to_SSL(env, ssl_address, true);
   8488     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
   8489     if (ssl == NULL) {
   8490         return;
   8491     }
   8492     int result = SSL_renegotiate(ssl);
   8493     if (result != 1) {
   8494         throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
   8495         return;
   8496     }
   8497     // first call asks client to perform renegotiation
   8498     int ret = SSL_do_handshake(ssl);
   8499     if (ret != 1) {
   8500         OpenSslError sslError(ssl, ret);
   8501         throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
   8502                                        "Problem with SSL_do_handshake after SSL_renegotiate");
   8503         return;
   8504     }
   8505     // if client agrees, set ssl state and perform renegotiation
   8506     ssl->state = SSL_ST_ACCEPT;
   8507     SSL_do_handshake(ssl);
   8508     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
   8509 }
   8510 
   8511 /**
   8512  * public static native byte[][] SSL_get_certificate(long ssl);
   8513  */
   8514 static jlongArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jlong ssl_address)
   8515 {
   8516     SSL* ssl = to_SSL(env, ssl_address, true);
   8517     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
   8518     if (ssl == NULL) {
   8519         return NULL;
   8520     }
   8521     X509* certificate = SSL_get_certificate(ssl);
   8522     if (certificate == NULL) {
   8523         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   8524         // SSL_get_certificate can return NULL during an error as well.
   8525         freeOpenSslErrorState();
   8526         return NULL;
   8527     }
   8528 
   8529     Unique_sk_X509 chain(sk_X509_new_null());
   8530     if (chain.get() == NULL) {
   8531         jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
   8532         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
   8533         return NULL;
   8534     }
   8535     if (!sk_X509_push(chain.get(), X509_dup_nocopy(certificate))) {
   8536         jniThrowOutOfMemory(env, "Unable to push local certificate");
   8537         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   8538         return NULL;
   8539     }
   8540     STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
   8541     for (int i=0; i<sk_X509_num(cert_chain); i++) {
   8542         if (!sk_X509_push(chain.get(), X509_dup_nocopy(sk_X509_value(cert_chain, i)))) {
   8543             jniThrowOutOfMemory(env, "Unable to push local certificate chain");
   8544             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
   8545             return NULL;
   8546         }
   8547     }
   8548 
   8549     jlongArray refArray = getCertificateRefs(env, chain.get());
   8550     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, refArray);
   8551     return refArray;
   8552 }
   8553 
   8554 // Fills a long[] with the peer certificates in the chain.
   8555 static jlongArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jlong ssl_address)
   8556 {
   8557     SSL* ssl = to_SSL(env, ssl_address, true);
   8558     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
   8559     if (ssl == NULL) {
   8560         return NULL;
   8561     }
   8562     STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
   8563     Unique_sk_X509 chain_copy(NULL);
   8564     if (ssl->server) {
   8565         X509* x509 = SSL_get_peer_certificate(ssl);
   8566         if (x509 == NULL) {
   8567             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
   8568             return NULL;
   8569         }
   8570         chain_copy.reset(sk_X509_new_null());
   8571         if (chain_copy.get() == NULL) {
   8572             jniThrowOutOfMemory(env, "Unable to allocate peer certificate chain");
   8573             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
   8574             return NULL;
   8575         }
   8576         size_t chain_size = sk_X509_num(chain);
   8577         for (size_t i = 0; i < chain_size; i++) {
   8578             if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(sk_X509_value(chain, i)))) {
   8579                 jniThrowOutOfMemory(env, "Unable to push server's peer certificate chain");
   8580                 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate chain push error", ssl);
   8581                 return NULL;
   8582             }
   8583         }
   8584         if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(x509))) {
   8585             jniThrowOutOfMemory(env, "Unable to push server's peer certificate");
   8586             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
   8587             return NULL;
   8588         }
   8589         chain = chain_copy.get();
   8590     }
   8591     jlongArray refArray = getCertificateRefs(env, chain);
   8592     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, refArray);
   8593     return refArray;
   8594 }
   8595 
   8596 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
   8597                    OpenSslError& sslError, int read_timeout_millis) {
   8598     JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
   8599 
   8600     if (len == 0) {
   8601         // Don't bother doing anything in this case.
   8602         return 0;
   8603     }
   8604 
   8605     BIO* rbio = SSL_get_rbio(ssl);
   8606     BIO* wbio = SSL_get_wbio(ssl);
   8607 
   8608     AppData* appData = toAppData(ssl);
   8609     JNI_TRACE("ssl=%p sslRead appData=%p", ssl, appData);
   8610     if (appData == NULL) {
   8611         return THROW_SSLEXCEPTION;
   8612     }
   8613 
   8614     while (appData->aliveAndKicking) {
   8615         errno = 0;
   8616 
   8617         if (MUTEX_LOCK(appData->mutex) == -1) {
   8618             return -1;
   8619         }
   8620 
   8621         if (!SSL_is_init_finished(ssl) && !SSL_cutthrough_complete(ssl) &&
   8622                !SSL_renegotiate_pending(ssl)) {
   8623             JNI_TRACE("ssl=%p sslRead => init is not finished (state=0x%x)", ssl,
   8624                     SSL_get_state(ssl));
   8625             MUTEX_UNLOCK(appData->mutex);
   8626             return THROW_SSLEXCEPTION;
   8627         }
   8628 
   8629         unsigned int bytesMoved = BIO_number_read(rbio) + BIO_number_written(wbio);
   8630 
   8631         if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
   8632             MUTEX_UNLOCK(appData->mutex);
   8633             return THROWN_EXCEPTION;
   8634         }
   8635         int result = SSL_read(ssl, buf, len);
   8636         appData->clearCallbackState();
   8637         // callbacks can happen if server requests renegotiation
   8638         if (env->ExceptionCheck()) {
   8639             safeSslClear(ssl);
   8640             JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
   8641             return THROWN_EXCEPTION;
   8642         }
   8643         sslError.reset(ssl, result);
   8644         JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError.get());
   8645 #ifdef WITH_JNI_TRACE_DATA
   8646         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   8647             int n = result - i;
   8648             if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   8649                 n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
   8650             }
   8651             JNI_TRACE("ssl=%p sslRead data: %d:\n%.*s", ssl, n, n, buf+i);
   8652         }
   8653 #endif
   8654 
   8655         // If we have been successful in moving data around, check whether it
   8656         // might make sense to wake up other blocked threads, so they can give
   8657         // it a try, too.
   8658         if (BIO_number_read(rbio) + BIO_number_written(wbio) != bytesMoved
   8659                 && appData->waitingThreads > 0) {
   8660             sslNotify(appData);
   8661         }
   8662 
   8663         // If we are blocked by the underlying socket, tell the world that
   8664         // there will be one more waiting thread now.
   8665         if (sslError.get() == SSL_ERROR_WANT_READ || sslError.get() == SSL_ERROR_WANT_WRITE) {
   8666             appData->waitingThreads++;
   8667         }
   8668 
   8669         MUTEX_UNLOCK(appData->mutex);
   8670 
   8671         switch (sslError.get()) {
   8672             // Successfully read at least one byte.
   8673             case SSL_ERROR_NONE: {
   8674                 return result;
   8675             }
   8676 
   8677             // Read zero bytes. End of stream reached.
   8678             case SSL_ERROR_ZERO_RETURN: {
   8679                 return -1;
   8680             }
   8681 
   8682             // Need to wait for availability of underlying layer, then retry.
   8683             case SSL_ERROR_WANT_READ:
   8684             case SSL_ERROR_WANT_WRITE: {
   8685                 int selectResult = sslSelect(env, sslError.get(), fdObject, appData, read_timeout_millis);
   8686                 if (selectResult == THROWN_EXCEPTION) {
   8687                     return THROWN_EXCEPTION;
   8688                 }
   8689                 if (selectResult == -1) {
   8690                     return THROW_SSLEXCEPTION;
   8691                 }
   8692                 if (selectResult == 0) {
   8693                     return THROW_SOCKETTIMEOUTEXCEPTION;
   8694                 }
   8695 
   8696                 break;
   8697             }
   8698 
   8699             // A problem occurred during a system call, but this is not
   8700             // necessarily an error.
   8701             case SSL_ERROR_SYSCALL: {
   8702                 // Connection closed without proper shutdown. Tell caller we
   8703                 // have reached end-of-stream.
   8704                 if (result == 0) {
   8705                     return -1;
   8706                 }
   8707 
   8708                 // System call has been interrupted. Simply retry.
   8709                 if (errno == EINTR) {
   8710                     break;
   8711                 }
   8712 
   8713                 // Note that for all other system call errors we fall through
   8714                 // to the default case, which results in an Exception.
   8715             }
   8716 
   8717             // Everything else is basically an error.
   8718             default: {
   8719                 return THROW_SSLEXCEPTION;
   8720             }
   8721         }
   8722     }
   8723 
   8724     return -1;
   8725 }
   8726 
   8727 static jint NativeCrypto_SSL_read_BIO(JNIEnv* env, jclass, jlong sslRef, jbyteArray destJava,
   8728         jint destOffset, jint destLength, jlong sourceBioRef, jlong sinkBioRef, jobject shc) {
   8729     SSL* ssl = to_SSL(env, sslRef, true);
   8730     BIO* rbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sourceBioRef));
   8731     BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sinkBioRef));
   8732     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO dest=%p sourceBio=%p sinkBio=%p shc=%p",
   8733               ssl, destJava, rbio, wbio, shc);
   8734     if (ssl == NULL) {
   8735         return 0;
   8736     }
   8737     if (rbio == NULL || wbio == NULL) {
   8738         jniThrowNullPointerException(env, "rbio == null || wbio == null");
   8739         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => rbio == null || wbio == null", ssl);
   8740         return -1;
   8741     }
   8742     if (shc == NULL) {
   8743         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   8744         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => sslHandshakeCallbacks == null", ssl);
   8745         return -1;
   8746     }
   8747 
   8748     ScopedByteArrayRW dest(env, destJava);
   8749     if (dest.get() == NULL) {
   8750         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => threw exception", ssl);
   8751         return -1;
   8752     }
   8753     if (destOffset < 0 || destOffset > ssize_t(dest.size()) || destLength < 0
   8754             || destLength > (ssize_t) dest.size() - destOffset) {
   8755         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => destOffset=%d, destLength=%d, size=%zd",
   8756                   destOffset, destLength, dest.size());
   8757         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
   8758         return -1;
   8759     }
   8760 
   8761     AppData* appData = toAppData(ssl);
   8762     if (appData == NULL) {
   8763         throwSSLExceptionStr(env, "Unable to retrieve application data");
   8764         safeSslClear(ssl);
   8765         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => appData == NULL", ssl);
   8766         return -1;
   8767     }
   8768 
   8769     errno = 0;
   8770 
   8771     if (MUTEX_LOCK(appData->mutex) == -1) {
   8772         return -1;
   8773     }
   8774 
   8775     if (!appData->setCallbackState(env, shc, NULL, NULL, NULL)) {
   8776         MUTEX_UNLOCK(appData->mutex);
   8777         throwSSLExceptionStr(env, "Unable to set callback state");
   8778         safeSslClear(ssl);
   8779         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => set callback state failed", ssl);
   8780         return -1;
   8781     }
   8782 
   8783     ScopedSslBio sslBio(ssl, rbio, wbio);
   8784 
   8785     int result = SSL_read(ssl, dest.get() + destOffset, destLength);
   8786     appData->clearCallbackState();
   8787     // callbacks can happen if server requests renegotiation
   8788     if (env->ExceptionCheck()) {
   8789         safeSslClear(ssl);
   8790         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => threw exception", ssl);
   8791         return THROWN_EXCEPTION;
   8792     }
   8793     OpenSslError sslError(ssl, result);
   8794     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO SSL_read result=%d sslError=%d", ssl, result,
   8795               sslError.get());
   8796 #ifdef WITH_JNI_TRACE_DATA
   8797     for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   8798         int n = result - i;
   8799         if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   8800             n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
   8801         }
   8802         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO data: %d:\n%.*s", ssl, n, n, buf+i);
   8803     }
   8804 #endif
   8805 
   8806     MUTEX_UNLOCK(appData->mutex);
   8807 
   8808     switch (sslError.get()) {
   8809         // Successfully read at least one byte.
   8810         case SSL_ERROR_NONE:
   8811             break;
   8812 
   8813         // Read zero bytes. End of stream reached.
   8814         case SSL_ERROR_ZERO_RETURN:
   8815             result = -1;
   8816             break;
   8817 
   8818         // Need to wait for availability of underlying layer, then retry.
   8819         case SSL_ERROR_WANT_READ:
   8820         case SSL_ERROR_WANT_WRITE:
   8821             result = 0;
   8822             break;
   8823 
   8824         // A problem occurred during a system call, but this is not
   8825         // necessarily an error.
   8826         case SSL_ERROR_SYSCALL: {
   8827             // Connection closed without proper shutdown. Tell caller we
   8828             // have reached end-of-stream.
   8829             if (result == 0) {
   8830                 result = -1;
   8831                 break;
   8832             } else if (errno == EINTR) {
   8833                 // System call has been interrupted. Simply retry.
   8834                 result = 0;
   8835                 break;
   8836             }
   8837 
   8838             // Note that for all other system call errors we fall through
   8839             // to the default case, which results in an Exception.
   8840         }
   8841 
   8842         // Everything else is basically an error.
   8843         default: {
   8844             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Read error");
   8845             return -1;
   8846         }
   8847     }
   8848     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => %d", ssl, result);
   8849     return result;
   8850 }
   8851 
   8852 /**
   8853  * OpenSSL read function (2): read into buffer at offset n chunks.
   8854  * Returns 1 (success) or value <= 0 (failure).
   8855  */
   8856 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
   8857                                   jobject shc, jbyteArray b, jint offset, jint len,
   8858                                   jint read_timeout_millis)
   8859 {
   8860     SSL* ssl = to_SSL(env, ssl_address, true);
   8861     JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d read_timeout_millis=%d",
   8862               ssl, fdObject, shc, b, offset, len, read_timeout_millis);
   8863     if (ssl == NULL) {
   8864         return 0;
   8865     }
   8866     if (fdObject == NULL) {
   8867         jniThrowNullPointerException(env, "fd == null");
   8868         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
   8869         return 0;
   8870     }
   8871     if (shc == NULL) {
   8872         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   8873         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
   8874         return 0;
   8875     }
   8876 
   8877     ScopedByteArrayRW bytes(env, b);
   8878     if (bytes.get() == NULL) {
   8879         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
   8880         return 0;
   8881     }
   8882 
   8883     OpenSslError sslError;
   8884     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
   8885                       sslError, read_timeout_millis);
   8886 
   8887     int result;
   8888     switch (ret) {
   8889         case THROW_SSLEXCEPTION:
   8890             // See sslRead() regarding improper failure to handle normal cases.
   8891             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Read error");
   8892             result = -1;
   8893             break;
   8894         case THROW_SOCKETTIMEOUTEXCEPTION:
   8895             throwSocketTimeoutException(env, "Read timed out");
   8896             result = -1;
   8897             break;
   8898         case THROWN_EXCEPTION:
   8899             // SocketException thrown by NetFd.isClosed
   8900             // or RuntimeException thrown by callback
   8901             result = -1;
   8902             break;
   8903         default:
   8904             result = ret;
   8905             break;
   8906     }
   8907 
   8908     JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
   8909     return result;
   8910 }
   8911 
   8912 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
   8913                     OpenSslError& sslError, int write_timeout_millis) {
   8914     JNI_TRACE("ssl=%p sslWrite buf=%p len=%d write_timeout_millis=%d",
   8915               ssl, buf, len, write_timeout_millis);
   8916 
   8917     if (len == 0) {
   8918         // Don't bother doing anything in this case.
   8919         return 0;
   8920     }
   8921 
   8922     BIO* rbio = SSL_get_rbio(ssl);
   8923     BIO* wbio = SSL_get_wbio(ssl);
   8924 
   8925     AppData* appData = toAppData(ssl);
   8926     JNI_TRACE("ssl=%p sslWrite appData=%p", ssl, appData);
   8927     if (appData == NULL) {
   8928         return THROW_SSLEXCEPTION;
   8929     }
   8930 
   8931     int count = len;
   8932 
   8933     while (appData->aliveAndKicking && ((len > 0) || (ssl->s3->wbuf.left > 0))) {
   8934         errno = 0;
   8935 
   8936         if (MUTEX_LOCK(appData->mutex) == -1) {
   8937             return -1;
   8938         }
   8939 
   8940         if (!SSL_is_init_finished(ssl) && !SSL_cutthrough_complete(ssl) &&
   8941                !SSL_renegotiate_pending(ssl)) {
   8942             JNI_TRACE("ssl=%p sslWrite => init is not finished (state=0x%x)", ssl,
   8943                     SSL_get_state(ssl));
   8944             MUTEX_UNLOCK(appData->mutex);
   8945             return THROW_SSLEXCEPTION;
   8946         }
   8947 
   8948         unsigned int bytesMoved = BIO_number_read(rbio) + BIO_number_written(wbio);
   8949 
   8950         if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
   8951             MUTEX_UNLOCK(appData->mutex);
   8952             return THROWN_EXCEPTION;
   8953         }
   8954         JNI_TRACE("ssl=%p sslWrite SSL_write len=%d left=%d", ssl, len, ssl->s3->wbuf.left);
   8955         int result = SSL_write(ssl, buf, len);
   8956         appData->clearCallbackState();
   8957         // callbacks can happen if server requests renegotiation
   8958         if (env->ExceptionCheck()) {
   8959             safeSslClear(ssl);
   8960             JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
   8961             return THROWN_EXCEPTION;
   8962         }
   8963         sslError.reset(ssl, result);
   8964         JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d left=%d",
   8965                   ssl, result, sslError.get(), ssl->s3->wbuf.left);
   8966 #ifdef WITH_JNI_TRACE_DATA
   8967         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   8968             int n = result - i;
   8969             if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   8970                 n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
   8971             }
   8972             JNI_TRACE("ssl=%p sslWrite data: %d:\n%.*s", ssl, n, n, buf+i);
   8973         }
   8974 #endif
   8975 
   8976         // If we have been successful in moving data around, check whether it
   8977         // might make sense to wake up other blocked threads, so they can give
   8978         // it a try, too.
   8979         if (BIO_number_read(rbio) + BIO_number_written(wbio) != bytesMoved
   8980                 && appData->waitingThreads > 0) {
   8981             sslNotify(appData);
   8982         }
   8983 
   8984         // If we are blocked by the underlying socket, tell the world that
   8985         // there will be one more waiting thread now.
   8986         if (sslError.get() == SSL_ERROR_WANT_READ || sslError.get() == SSL_ERROR_WANT_WRITE) {
   8987             appData->waitingThreads++;
   8988         }
   8989 
   8990         MUTEX_UNLOCK(appData->mutex);
   8991 
   8992         switch (sslError.get()) {
   8993             // Successfully wrote at least one byte.
   8994             case SSL_ERROR_NONE: {
   8995                 buf += result;
   8996                 len -= result;
   8997                 break;
   8998             }
   8999 
   9000             // Wrote zero bytes. End of stream reached.
   9001             case SSL_ERROR_ZERO_RETURN: {
   9002                 return -1;
   9003             }
   9004 
   9005             // Need to wait for availability of underlying layer, then retry.
   9006             // The concept of a write timeout doesn't really make sense, and
   9007             // it's also not standard Java behavior, so we wait forever here.
   9008             case SSL_ERROR_WANT_READ:
   9009             case SSL_ERROR_WANT_WRITE: {
   9010                 int selectResult = sslSelect(env, sslError.get(), fdObject, appData,
   9011                                              write_timeout_millis);
   9012                 if (selectResult == THROWN_EXCEPTION) {
   9013                     return THROWN_EXCEPTION;
   9014                 }
   9015                 if (selectResult == -1) {
   9016                     return THROW_SSLEXCEPTION;
   9017                 }
   9018                 if (selectResult == 0) {
   9019                     return THROW_SOCKETTIMEOUTEXCEPTION;
   9020                 }
   9021 
   9022                 break;
   9023             }
   9024 
   9025             // A problem occurred during a system call, but this is not
   9026             // necessarily an error.
   9027             case SSL_ERROR_SYSCALL: {
   9028                 // Connection closed without proper shutdown. Tell caller we
   9029                 // have reached end-of-stream.
   9030                 if (result == 0) {
   9031                     return -1;
   9032                 }
   9033 
   9034                 // System call has been interrupted. Simply retry.
   9035                 if (errno == EINTR) {
   9036                     break;
   9037                 }
   9038 
   9039                 // Note that for all other system call errors we fall through
   9040                 // to the default case, which results in an Exception.
   9041             }
   9042 
   9043             // Everything else is basically an error.
   9044             default: {
   9045                 return THROW_SSLEXCEPTION;
   9046             }
   9047         }
   9048     }
   9049     JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count);
   9050 
   9051     return count;
   9052 }
   9053 
   9054 /**
   9055  * OpenSSL write function (2): write into buffer at offset n chunks.
   9056  */
   9057 static int NativeCrypto_SSL_write_BIO(JNIEnv* env, jclass, jlong sslRef, jbyteArray sourceJava, jint len,
   9058         jlong sinkBioRef, jobject shc) {
   9059     SSL* ssl = to_SSL(env, sslRef, true);
   9060     BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sinkBioRef));
   9061     JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO source=%p len=%d wbio=%p shc=%p",
   9062               ssl, sourceJava, len, wbio, shc);
   9063     if (ssl == NULL) {
   9064         return -1;
   9065     }
   9066     if (wbio == NULL) {
   9067         jniThrowNullPointerException(env, "wbio == null");
   9068         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => wbio == null", ssl);
   9069         return -1;
   9070     }
   9071     if (shc == NULL) {
   9072         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   9073         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => sslHandshakeCallbacks == null", ssl);
   9074         return -1;
   9075     }
   9076 
   9077     AppData* appData = toAppData(ssl);
   9078     if (appData == NULL) {
   9079         throwSSLExceptionStr(env, "Unable to retrieve application data");
   9080         safeSslClear(ssl);
   9081         freeOpenSslErrorState();
   9082         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO appData => NULL", ssl);
   9083         return -1;
   9084     }
   9085 
   9086     errno = 0;
   9087 
   9088     if (MUTEX_LOCK(appData->mutex) == -1) {
   9089         return 0;
   9090     }
   9091 
   9092     if (!appData->setCallbackState(env, shc, NULL, NULL, NULL)) {
   9093         MUTEX_UNLOCK(appData->mutex);
   9094         throwSSLExceptionStr(env, "Unable to set appdata callback");
   9095         freeOpenSslErrorState();
   9096         safeSslClear(ssl);
   9097         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => appData can't set callback", ssl);
   9098         return -1;
   9099     }
   9100 
   9101     ScopedByteArrayRO source(env, sourceJava);
   9102     if (source.get() == NULL) {
   9103         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => threw exception", ssl);
   9104         return -1;
   9105     }
   9106 
   9107     Unique_BIO nullBio(BIO_new(BIO_s_null()));
   9108     ScopedSslBio sslBio(ssl, nullBio.get(), wbio);
   9109 
   9110     int result = SSL_write(ssl, reinterpret_cast<const char*>(source.get()), len);
   9111     appData->clearCallbackState();
   9112     // callbacks can happen if server requests renegotiation
   9113     if (env->ExceptionCheck()) {
   9114         freeOpenSslErrorState();
   9115         safeSslClear(ssl);
   9116         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO exception => exception pending (reneg)", ssl);
   9117         return -1;
   9118     }
   9119     OpenSslError sslError(ssl, result);
   9120     JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO SSL_write result=%d sslError=%d left=%d",
   9121               ssl, result, sslError.get(), ssl->s3->wbuf.left);
   9122 #ifdef WITH_JNI_TRACE_DATA
   9123     for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   9124         int n = result - i;
   9125         if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
   9126             n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
   9127         }
   9128         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO data: %d:\n%.*s", ssl, n, n, buf+i);
   9129     }
   9130 #endif
   9131 
   9132     MUTEX_UNLOCK(appData->mutex);
   9133 
   9134     switch (sslError.get()) {
   9135         case SSL_ERROR_NONE:
   9136             return result;
   9137 
   9138         // Wrote zero bytes. End of stream reached.
   9139         case SSL_ERROR_ZERO_RETURN:
   9140             return -1;
   9141 
   9142         case SSL_ERROR_WANT_READ:
   9143         case SSL_ERROR_WANT_WRITE:
   9144             return 0;
   9145 
   9146         case SSL_ERROR_SYSCALL: {
   9147             // Connection closed without proper shutdown. Tell caller we
   9148             // have reached end-of-stream.
   9149             if (result == 0) {
   9150                 return -1;
   9151             }
   9152 
   9153             // System call has been interrupted. Simply retry.
   9154             if (errno == EINTR) {
   9155                 return 0;
   9156             }
   9157 
   9158             // Note that for all other system call errors we fall through
   9159             // to the default case, which results in an Exception.
   9160         }
   9161 
   9162         // Everything else is basically an error.
   9163         default: {
   9164             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Write error");
   9165             break;
   9166         }
   9167     }
   9168     return -1;
   9169 }
   9170 
   9171 /**
   9172  * OpenSSL write function (2): write into buffer at offset n chunks.
   9173  */
   9174 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
   9175                                    jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis)
   9176 {
   9177     SSL* ssl = to_SSL(env, ssl_address, true);
   9178     JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d write_timeout_millis=%d",
   9179               ssl, fdObject, shc, b, offset, len, write_timeout_millis);
   9180     if (ssl == NULL) {
   9181         return;
   9182     }
   9183     if (fdObject == NULL) {
   9184         jniThrowNullPointerException(env, "fd == null");
   9185         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
   9186         return;
   9187     }
   9188     if (shc == NULL) {
   9189         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   9190         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
   9191         return;
   9192     }
   9193 
   9194     ScopedByteArrayRO bytes(env, b);
   9195     if (bytes.get() == NULL) {
   9196         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
   9197         return;
   9198     }
   9199     OpenSslError sslError;
   9200     int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
   9201                        len, sslError, write_timeout_millis);
   9202 
   9203     switch (ret) {
   9204         case THROW_SSLEXCEPTION:
   9205             // See sslWrite() regarding improper failure to handle normal cases.
   9206             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Write error");
   9207             break;
   9208         case THROW_SOCKETTIMEOUTEXCEPTION:
   9209             throwSocketTimeoutException(env, "Write timed out");
   9210             break;
   9211         case THROWN_EXCEPTION:
   9212             // SocketException thrown by NetFd.isClosed
   9213             break;
   9214         default:
   9215             break;
   9216     }
   9217 }
   9218 
   9219 /**
   9220  * Interrupt any pending I/O before closing the socket.
   9221  */
   9222 static void NativeCrypto_SSL_interrupt(
   9223         JNIEnv* env, jclass, jlong ssl_address) {
   9224     SSL* ssl = to_SSL(env, ssl_address, false);
   9225     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
   9226     if (ssl == NULL) {
   9227         return;
   9228     }
   9229 
   9230     /*
   9231      * Mark the connection as quasi-dead, then send something to the emergency
   9232      * file descriptor, so any blocking select() calls are woken up.
   9233      */
   9234     AppData* appData = toAppData(ssl);
   9235     if (appData != NULL) {
   9236         appData->aliveAndKicking = 0;
   9237 
   9238         // At most two threads can be waiting.
   9239         sslNotify(appData);
   9240         sslNotify(appData);
   9241     }
   9242 }
   9243 
   9244 /**
   9245  * OpenSSL close SSL socket function.
   9246  */
   9247 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jlong ssl_address,
   9248                                       jobject fdObject, jobject shc) {
   9249     SSL* ssl = to_SSL(env, ssl_address, false);
   9250     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
   9251     if (ssl == NULL) {
   9252         return;
   9253     }
   9254     if (fdObject == NULL) {
   9255         jniThrowNullPointerException(env, "fd == null");
   9256         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
   9257         return;
   9258     }
   9259     if (shc == NULL) {
   9260         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   9261         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
   9262         return;
   9263     }
   9264 
   9265     AppData* appData = toAppData(ssl);
   9266     if (appData != NULL) {
   9267         if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) {
   9268             // SocketException thrown by NetFd.isClosed
   9269             freeOpenSslErrorState();
   9270             safeSslClear(ssl);
   9271             return;
   9272         }
   9273 
   9274         /*
   9275          * Try to make socket blocking again. OpenSSL literature recommends this.
   9276          */
   9277         int fd = SSL_get_fd(ssl);
   9278         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
   9279         if (fd != -1) {
   9280             setBlocking(fd, true);
   9281         }
   9282 
   9283         int ret = SSL_shutdown(ssl);
   9284         appData->clearCallbackState();
   9285         // callbacks can happen if server requests renegotiation
   9286         if (env->ExceptionCheck()) {
   9287             safeSslClear(ssl);
   9288             JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
   9289             return;
   9290         }
   9291         switch (ret) {
   9292             case 0:
   9293                 /*
   9294                  * Shutdown was not successful (yet), but there also
   9295                  * is no error. Since we can't know whether the remote
   9296                  * server is actually still there, and we don't want to
   9297                  * get stuck forever in a second SSL_shutdown() call, we
   9298                  * simply return. This is not security a problem as long
   9299                  * as we close the underlying socket, which we actually
   9300                  * do, because that's where we are just coming from.
   9301                  */
   9302                 break;
   9303             case 1:
   9304                 /*
   9305                  * Shutdown was successful. We can safely return. Hooray!
   9306                  */
   9307                 break;
   9308             default:
   9309                 /*
   9310                  * Everything else is a real error condition. We should
   9311                  * let the Java layer know about this by throwing an
   9312                  * exception.
   9313                  */
   9314                 int sslError = SSL_get_error(ssl, ret);
   9315                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
   9316                 break;
   9317         }
   9318     }
   9319 
   9320     freeOpenSslErrorState();
   9321     safeSslClear(ssl);
   9322 }
   9323 
   9324 /**
   9325  * OpenSSL close SSL socket function.
   9326  */
   9327 static void NativeCrypto_SSL_shutdown_BIO(JNIEnv* env, jclass, jlong ssl_address, jlong rbioRef,
   9328         jlong wbioRef, jobject shc) {
   9329     SSL* ssl = to_SSL(env, ssl_address, false);
   9330     BIO* rbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(rbioRef));
   9331     BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(wbioRef));
   9332     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown rbio=%p wbio=%p shc=%p", ssl, rbio, wbio, shc);
   9333     if (ssl == NULL) {
   9334         return;
   9335     }
   9336     if (rbio == NULL || wbio == NULL) {
   9337         jniThrowNullPointerException(env, "rbio == null || wbio == null");
   9338         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => rbio == null || wbio == null", ssl);
   9339         return;
   9340     }
   9341     if (shc == NULL) {
   9342         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
   9343         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
   9344         return;
   9345     }
   9346 
   9347     AppData* appData = toAppData(ssl);
   9348     if (appData != NULL) {
   9349         if (!appData->setCallbackState(env, shc, NULL, NULL, NULL)) {
   9350             // SocketException thrown by NetFd.isClosed
   9351             freeOpenSslErrorState();
   9352             safeSslClear(ssl);
   9353             return;
   9354         }
   9355 
   9356         ScopedSslBio scopedBio(ssl, rbio, wbio);
   9357 
   9358         int ret = SSL_shutdown(ssl);
   9359         appData->clearCallbackState();
   9360         // callbacks can happen if server requests renegotiation
   9361         if (env->ExceptionCheck()) {
   9362             safeSslClear(ssl);
   9363             JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
   9364             return;
   9365         }
   9366         switch (ret) {
   9367             case 0:
   9368                 /*
   9369                  * Shutdown was not successful (yet), but there also
   9370                  * is no error. Since we can't know whether the remote
   9371                  * server is actually still there, and we don't want to
   9372                  * get stuck forever in a second SSL_shutdown() call, we
   9373                  * simply return. This is not security a problem as long
   9374                  * as we close the underlying socket, which we actually
   9375                  * do, because that's where we are just coming from.
   9376                  */
   9377                 break;
   9378             case 1:
   9379                 /*
   9380                  * Shutdown was successful. We can safely return. Hooray!
   9381                  */
   9382                 break;
   9383             default:
   9384                 /*
   9385                  * Everything else is a real error condition. We should
   9386                  * let the Java layer know about this by throwing an
   9387                  * exception.
   9388                  */
   9389                 int sslError = SSL_get_error(ssl, ret);
   9390                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
   9391                 break;
   9392         }
   9393     }
   9394 
   9395     freeOpenSslErrorState();
   9396     safeSslClear(ssl);
   9397 }
   9398 
   9399 static jint NativeCrypto_SSL_get_shutdown(JNIEnv* env, jclass, jlong ssl_address) {
   9400     const SSL* ssl = to_SSL(env, ssl_address, true);
   9401     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_shutdown", ssl);
   9402     if (ssl == NULL) {
   9403         jniThrowNullPointerException(env, "ssl == null");
   9404         return 0;
   9405     }
   9406 
   9407     int status = SSL_get_shutdown(ssl);
   9408     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_shutdown => %d", ssl, status);
   9409     return static_cast<jint>(status);
   9410 }
   9411 
   9412 /**
   9413  * public static native void SSL_free(long ssl);
   9414  */
   9415 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jlong ssl_address)
   9416 {
   9417     SSL* ssl = to_SSL(env, ssl_address, true);
   9418     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
   9419     if (ssl == NULL) {
   9420         return;
   9421     }
   9422 
   9423     AppData* appData = toAppData(ssl);
   9424     SSL_set_app_data(ssl, NULL);
   9425     delete appData;
   9426     SSL_free(ssl);
   9427 }
   9428 
   9429 /**
   9430  * Gets and returns in a byte array the ID of the actual SSL session.
   9431  */
   9432 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
   9433                                                       jlong ssl_session_address) {
   9434     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   9435     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
   9436     if (ssl_session == NULL) {
   9437         return NULL;
   9438     }
   9439     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
   9440     if (result != NULL) {
   9441         jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
   9442         env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
   9443     }
   9444     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
   9445              ssl_session, result, ssl_session->session_id_length);
   9446     return result;
   9447 }
   9448 
   9449 /**
   9450  * Gets and returns in a long integer the creation's time of the
   9451  * actual SSL session.
   9452  */
   9453 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jlong ssl_session_address) {
   9454     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   9455     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
   9456     if (ssl_session == NULL) {
   9457         return 0;
   9458     }
   9459     // result must be jlong, not long or *1000 will overflow
   9460     jlong result = SSL_SESSION_get_time(ssl_session);
   9461     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
   9462     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result);
   9463     return result;
   9464 }
   9465 
   9466 /**
   9467  * Gets and returns in a string the version of the SSL protocol. If it
   9468  * returns the string "unknown" it means that no connection is established.
   9469  */
   9470 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jlong ssl_session_address) {
   9471     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   9472     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
   9473     if (ssl_session == NULL) {
   9474         return NULL;
   9475     }
   9476     const char* protocol = SSL_SESSION_get_version(ssl_session);
   9477     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
   9478     return env->NewStringUTF(protocol);
   9479 }
   9480 
   9481 /**
   9482  * Gets and returns in a string the cipher negotiated for the SSL session.
   9483  */
   9484 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jlong ssl_session_address) {
   9485     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   9486     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
   9487     if (ssl_session == NULL) {
   9488         return NULL;
   9489     }
   9490     const SSL_CIPHER* cipher = ssl_session->cipher;
   9491     const char* name = SSL_CIPHER_get_name(cipher);
   9492     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
   9493     return env->NewStringUTF(name);
   9494 }
   9495 
   9496 /**
   9497  * Frees the SSL session.
   9498  */
   9499 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jlong ssl_session_address) {
   9500     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   9501     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
   9502     if (ssl_session == NULL) {
   9503         return;
   9504     }
   9505     SSL_SESSION_free(ssl_session);
   9506 }
   9507 
   9508 
   9509 /**
   9510  * Serializes the native state of the session (ID, cipher, and keys but
   9511  * not certificates). Returns a byte[] containing the DER-encoded state.
   9512  * See apache mod_ssl.
   9513  */
   9514 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jlong ssl_session_address) {
   9515     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
   9516     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
   9517     if (ssl_session == NULL) {
   9518         return NULL;
   9519     }
   9520     return ASN1ToByteArray<SSL_SESSION, i2d_SSL_SESSION>(env, ssl_session);
   9521 }
   9522 
   9523 /**
   9524  * Deserialize the session.
   9525  */
   9526 static jlong NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
   9527     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
   9528 
   9529     ScopedByteArrayRO bytes(env, javaBytes);
   9530     if (bytes.get() == NULL) {
   9531         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
   9532         return 0;
   9533     }
   9534     const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
   9535     SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size());
   9536 
   9537     // Initialize SSL_SESSION cipher field based on cipher_id http://b/7091840
   9538     if (ssl_session != NULL) {
   9539         // based on ssl_get_prev_session
   9540         uint32_t cipher_id_network_order = htonl(ssl_session->cipher_id);
   9541         uint8_t* cipher_id_byte_pointer = reinterpret_cast<uint8_t*>(&cipher_id_network_order);
   9542         if (ssl_session->ssl_version >= SSL3_VERSION_MAJOR) {
   9543             cipher_id_byte_pointer += 2; // skip first two bytes for SSL3+
   9544         } else {
   9545             cipher_id_byte_pointer += 1; // skip first byte for SSL2
   9546         }
   9547         ssl_session->cipher = SSLv23_method()->get_cipher_by_char(cipher_id_byte_pointer);
   9548         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION cipher_id=%lx hton=%x 0=%x 1=%x cipher=%s",
   9549                   ssl_session->cipher_id, cipher_id_network_order,
   9550                   cipher_id_byte_pointer[0], cipher_id_byte_pointer[1],
   9551                   SSL_CIPHER_get_name(ssl_session->cipher));
   9552     } else {
   9553         freeOpenSslErrorState();
   9554     }
   9555 
   9556     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
   9557     return reinterpret_cast<uintptr_t>(ssl_session);
   9558 }
   9559 
   9560 static jlong NativeCrypto_ERR_peek_last_error(JNIEnv*, jclass) {
   9561     return ERR_peek_last_error();
   9562 }
   9563 
   9564 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
   9565 #define SSL_CALLBACKS "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto$SSLHandshakeCallbacks;"
   9566 static JNINativeMethod sNativeCryptoMethods[] = {
   9567     NATIVE_METHOD(NativeCrypto, clinit, "()V"),
   9568     NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
   9569     NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)J"),
   9570     NATIVE_METHOD(NativeCrypto, ENGINE_add, "(J)I"),
   9571     NATIVE_METHOD(NativeCrypto, ENGINE_init, "(J)I"),
   9572     NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(J)I"),
   9573     NATIVE_METHOD(NativeCrypto, ENGINE_free, "(J)I"),
   9574     NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(JLjava/lang/String;)J"),
   9575     NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(J)Ljava/lang/String;"),
   9576     NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(JLjava/lang/String;Ljava/lang/String;I)I"),
   9577     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DH, "([B[B[B[B)J"),
   9578     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)J"),
   9579     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"),
   9580     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(JJ[B)J"),
   9581     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_mac_key, "(I[B)J"),
   9582     NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(J)I"),
   9583     NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(J)I"),
   9584     NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(J)Ljava/lang/String;"),
   9585     NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(J)Ljava/lang/String;"),
   9586     NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(J)V"),
   9587     NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(JJ)I"),
   9588     NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(J)[B"),
   9589     NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)J"),
   9590     NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(J)[B"),
   9591     NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)J"),
   9592     NATIVE_METHOD(NativeCrypto, getRSAPrivateKeyWrapper, "(Ljava/security/interfaces/RSAPrivateKey;[B)J"),
   9593     NATIVE_METHOD(NativeCrypto, getDSAPrivateKeyWrapper, "(Ljava/security/interfaces/DSAPrivateKey;)J"),
   9594     NATIVE_METHOD(NativeCrypto, getECPrivateKeyWrapper, "(Ljava/security/interfaces/ECPrivateKey;J)J"),
   9595     NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)J"),
   9596     NATIVE_METHOD(NativeCrypto, RSA_size, "(J)I"),
   9597     NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[BJI)I"),
   9598     NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[BJI)I"),
   9599     NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[BJI)I"),
   9600     NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[BJI)I"),
   9601     NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(J)[[B"),
   9602     NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(J)[[B"),
   9603     NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)J"),
   9604     NATIVE_METHOD(NativeCrypto, get_DSA_params, "(J)[[B"),
   9605     NATIVE_METHOD(NativeCrypto, set_DSA_flag_nonce_from_hash, "(J)V"),
   9606     NATIVE_METHOD(NativeCrypto, DH_generate_parameters_ex, "(IJ)J"),
   9607     NATIVE_METHOD(NativeCrypto, DH_generate_key, "(J)V"),
   9608     NATIVE_METHOD(NativeCrypto, get_DH_params, "(J)[[B"),
   9609     NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)J"),
   9610     NATIVE_METHOD(NativeCrypto, EC_GROUP_new_curve, "(I[B[B[B)J"),
   9611     NATIVE_METHOD(NativeCrypto, EC_GROUP_dup, "(J)J"),
   9612     NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(JI)V"),
   9613     NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(JI)V"),
   9614     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(J)Ljava/lang/String;"),
   9615     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(J)[[B"),
   9616     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(J)[B"),
   9617     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_degree, "(J)I"),
   9618     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(J)[B"),
   9619     NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"),
   9620     NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(JJ)Z"),
   9621     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(J)J"),
   9622     NATIVE_METHOD(NativeCrypto, EC_GROUP_set_generator, "(JJ[B[B)V"),
   9623     NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(J)I"),
   9624     NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(J)J"),
   9625     NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(J)V"),
   9626     NATIVE_METHOD(NativeCrypto, EC_POINT_cmp, "(JJJ)Z"),
   9627     NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(JJ[B[B)V"),
   9628     NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(JJ)[[B"),
   9629     NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(J)J"),
   9630     NATIVE_METHOD(NativeCrypto, EC_KEY_get0_group, "(J)J"),
   9631     NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(J)[B"),
   9632     NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(J)J"),
   9633     NATIVE_METHOD(NativeCrypto, EC_KEY_set_nonce_from_hash, "(JZ)V"),
   9634     NATIVE_METHOD(NativeCrypto, ECDH_compute_key, "([BIJJ)I"),
   9635     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()J"),
   9636     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_init, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;)V"),
   9637     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(J)V"),
   9638     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;)I"),
   9639     NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;J)I"),
   9640     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[BII)V"),
   9641     NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[BI)I"),
   9642     NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)J"),
   9643     NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(J)I"),
   9644     NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(J)I"),
   9645     NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;J)I"),
   9646     NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[BII)V"),
   9647     NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[BIJ)I"),
   9648     NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;J)I"),
   9649     NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[BII)V"),
   9650     NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[BIIJ)I"),
   9651     NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;JJ)V"),
   9652     NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;[B)V"),
   9653     NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLDigestContext;)[B"),
   9654     NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)J"),
   9655     NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(JJ[B[BZ)V"),
   9656     NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(J[BI[BII)I"),
   9657     NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(J[BI)I"),
   9658     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(J)I"),
   9659     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()J"),
   9660     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(J)I"),
   9661     NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(J)I"),
   9662     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(JZ)V"),
   9663     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(JI)V"),
   9664     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_free, "(J)V"),
   9665     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
   9666     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
   9667     NATIVE_METHOD(NativeCrypto, RAND_bytes, "([B)V"),
   9668     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid, "(Ljava/lang/String;)I"),
   9669     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_longName, "(Ljava/lang/String;)Ljava/lang/String;"),
   9670     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_oid, "(Ljava/lang/String;)Ljava/lang/String;"),
   9671     NATIVE_METHOD(NativeCrypto, create_BIO_InputStream, ("(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream;)J")),
   9672     NATIVE_METHOD(NativeCrypto, create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"),
   9673     NATIVE_METHOD(NativeCrypto, BIO_read, "(J[B)I"),
   9674     NATIVE_METHOD(NativeCrypto, BIO_write, "(J[BII)V"),
   9675     NATIVE_METHOD(NativeCrypto, BIO_free_all, "(J)V"),
   9676     NATIVE_METHOD(NativeCrypto, X509_NAME_print_ex, "(JJ)Ljava/lang/String;"),
   9677     NATIVE_METHOD(NativeCrypto, d2i_X509_bio, "(J)J"),
   9678     NATIVE_METHOD(NativeCrypto, d2i_X509, "([B)J"),
   9679     NATIVE_METHOD(NativeCrypto, i2d_X509, "(J)[B"),
   9680     NATIVE_METHOD(NativeCrypto, i2d_X509_PUBKEY, "(J)[B"),
   9681     NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509, "(J)J"),
   9682     NATIVE_METHOD(NativeCrypto, PEM_read_bio_PKCS7, "(JI)[J"),
   9683     NATIVE_METHOD(NativeCrypto, d2i_PKCS7_bio, "(JI)[J"),
   9684     NATIVE_METHOD(NativeCrypto, i2d_PKCS7, "([J)[B"),
   9685     NATIVE_METHOD(NativeCrypto, ASN1_seq_unpack_X509_bio, "(J)[J"),
   9686     NATIVE_METHOD(NativeCrypto, ASN1_seq_pack_X509, "([J)[B"),
   9687     NATIVE_METHOD(NativeCrypto, X509_free, "(J)V"),
   9688     NATIVE_METHOD(NativeCrypto, X509_cmp, "(JJ)I"),
   9689     NATIVE_METHOD(NativeCrypto, get_X509_hashCode, "(J)I"),
   9690     NATIVE_METHOD(NativeCrypto, X509_print_ex, "(JJJJ)V"),
   9691     NATIVE_METHOD(NativeCrypto, X509_get_pubkey, "(J)J"),
   9692     NATIVE_METHOD(NativeCrypto, X509_get_issuer_name, "(J)[B"),
   9693     NATIVE_METHOD(NativeCrypto, X509_get_subject_name, "(J)[B"),
   9694     NATIVE_METHOD(NativeCrypto, get_X509_pubkey_oid, "(J)Ljava/lang/String;"),
   9695     NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_oid, "(J)Ljava/lang/String;"),
   9696     NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_parameter, "(J)[B"),
   9697     NATIVE_METHOD(NativeCrypto, get_X509_issuerUID, "(J)[Z"),
   9698     NATIVE_METHOD(NativeCrypto, get_X509_subjectUID, "(J)[Z"),
   9699     NATIVE_METHOD(NativeCrypto, get_X509_ex_kusage, "(J)[Z"),
   9700     NATIVE_METHOD(NativeCrypto, get_X509_ex_xkusage, "(J)[Ljava/lang/String;"),
   9701     NATIVE_METHOD(NativeCrypto, get_X509_ex_pathlen, "(J)I"),
   9702     NATIVE_METHOD(NativeCrypto, X509_get_ext_oid, "(JLjava/lang/String;)[B"),
   9703     NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext_oid, "(JLjava/lang/String;)[B"),
   9704     NATIVE_METHOD(NativeCrypto, get_X509_CRL_crl_enc, "(J)[B"),
   9705     NATIVE_METHOD(NativeCrypto, X509_CRL_verify, "(JJ)V"),
   9706     NATIVE_METHOD(NativeCrypto, X509_CRL_get_lastUpdate, "(J)J"),
   9707     NATIVE_METHOD(NativeCrypto, X509_CRL_get_nextUpdate, "(J)J"),
   9708     NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext_oid, "(JLjava/lang/String;)[B"),
   9709     NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_serialNumber, "(J)[B"),
   9710     NATIVE_METHOD(NativeCrypto, X509_REVOKED_print, "(JJ)V"),
   9711     NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_revocationDate, "(J)J"),
   9712     NATIVE_METHOD(NativeCrypto, get_X509_ext_oids, "(JI)[Ljava/lang/String;"),
   9713     NATIVE_METHOD(NativeCrypto, get_X509_CRL_ext_oids, "(JI)[Ljava/lang/String;"),
   9714     NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_ext_oids, "(JI)[Ljava/lang/String;"),
   9715     NATIVE_METHOD(NativeCrypto, get_X509_GENERAL_NAME_stack, "(JI)[[Ljava/lang/Object;"),
   9716     NATIVE_METHOD(NativeCrypto, X509_get_notBefore, "(J)J"),
   9717     NATIVE_METHOD(NativeCrypto, X509_get_notAfter, "(J)J"),
   9718     NATIVE_METHOD(NativeCrypto, X509_get_version, "(J)J"),
   9719     NATIVE_METHOD(NativeCrypto, X509_get_serialNumber, "(J)[B"),
   9720     NATIVE_METHOD(NativeCrypto, X509_verify, "(JJ)V"),
   9721     NATIVE_METHOD(NativeCrypto, get_X509_cert_info_enc, "(J)[B"),
   9722     NATIVE_METHOD(NativeCrypto, get_X509_signature, "(J)[B"),
   9723     NATIVE_METHOD(NativeCrypto, get_X509_CRL_signature, "(J)[B"),
   9724     NATIVE_METHOD(NativeCrypto, get_X509_ex_flags, "(J)I"),
   9725     NATIVE_METHOD(NativeCrypto, X509_check_issued, "(JJ)I"),
   9726     NATIVE_METHOD(NativeCrypto, d2i_X509_CRL_bio, "(J)J"),
   9727     NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509_CRL, "(J)J"),
   9728     NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_cert, "(JJ)J"),
   9729     NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_serial, "(J[B)J"),
   9730     NATIVE_METHOD(NativeCrypto, X509_CRL_get_REVOKED, "(J)[J"),
   9731     NATIVE_METHOD(NativeCrypto, i2d_X509_CRL, "(J)[B"),
   9732     NATIVE_METHOD(NativeCrypto, X509_CRL_free, "(J)V"),
   9733     NATIVE_METHOD(NativeCrypto, X509_CRL_print, "(JJ)V"),
   9734     NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_oid, "(J)Ljava/lang/String;"),
   9735     NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_parameter, "(J)[B"),
   9736     NATIVE_METHOD(NativeCrypto, X509_CRL_get_issuer_name, "(J)[B"),
   9737     NATIVE_METHOD(NativeCrypto, X509_CRL_get_version, "(J)J"),
   9738     NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext, "(JLjava/lang/String;)J"),
   9739     NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext, "(JLjava/lang/String;)J"),
   9740     NATIVE_METHOD(NativeCrypto, X509_REVOKED_dup, "(J)J"),
   9741     NATIVE_METHOD(NativeCrypto, i2d_X509_REVOKED, "(J)[B"),
   9742     NATIVE_METHOD(NativeCrypto, X509_supported_extension, "(J)I"),
   9743     NATIVE_METHOD(NativeCrypto, ASN1_TIME_to_Calendar, "(JLjava/util/Calendar;)V"),
   9744     NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()J"),
   9745     NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(J)V"),
   9746     NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(J[B)V"),
   9747     NATIVE_METHOD(NativeCrypto, SSL_new, "(J)J"),
   9748     NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(J)V"),
   9749     NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(J)[B"),
   9750     NATIVE_METHOD(NativeCrypto, SSL_set1_tls_channel_id, "(JJ)V"),
   9751     NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(JJ)V"),
   9752     NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(J[J)V"),
   9753     NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(J)V"),
   9754     NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(J[[B)V"),
   9755     NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(J)J"),
   9756     NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(JJ)J"),
   9757     NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(JJ)J"),
   9758     NATIVE_METHOD(NativeCrypto, SSL_get_options, "(J)J"),
   9759     NATIVE_METHOD(NativeCrypto, SSL_set_options, "(JJ)J"),
   9760     NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(JJ)J"),
   9761     NATIVE_METHOD(NativeCrypto, SSL_use_psk_identity_hint, "(JLjava/lang/String;)V"),
   9762     NATIVE_METHOD(NativeCrypto, set_SSL_psk_client_callback_enabled, "(JZ)V"),
   9763     NATIVE_METHOD(NativeCrypto, set_SSL_psk_server_callback_enabled, "(JZ)V"),
   9764     NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(J[Ljava/lang/String;)V"),
   9765     NATIVE_METHOD(NativeCrypto, SSL_get_ciphers, "(J)[J"),
   9766     NATIVE_METHOD(NativeCrypto, get_SSL_CIPHER_algorithm_auth, "(J)I"),
   9767     NATIVE_METHOD(NativeCrypto, get_SSL_CIPHER_algorithm_mkey, "(J)I"),
   9768     NATIVE_METHOD(NativeCrypto, SSL_set_accept_state, "(J)V"),
   9769     NATIVE_METHOD(NativeCrypto, SSL_set_connect_state, "(J)V"),
   9770     NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(JI)V"),
   9771     NATIVE_METHOD(NativeCrypto, SSL_set_session, "(JJ)V"),
   9772     NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(JZ)V"),
   9773     NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(JLjava/lang/String;)V"),
   9774     NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(J)Ljava/lang/String;"),
   9775     NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B[B)J"),
   9776     NATIVE_METHOD(NativeCrypto, SSL_do_handshake_bio, "(JJJ" SSL_CALLBACKS "Z[B[B)J"),
   9777     NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(J)V"),
   9778     NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[J"),
   9779     NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[J"),
   9780     NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
   9781     NATIVE_METHOD(NativeCrypto, SSL_read_BIO, "(J[BIIJJ" SSL_CALLBACKS ")I"),
   9782     NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
   9783     NATIVE_METHOD(NativeCrypto, SSL_write_BIO, "(J[BIJ" SSL_CALLBACKS ")I"),
   9784     NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"),
   9785     NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(J" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
   9786     NATIVE_METHOD(NativeCrypto, SSL_shutdown_BIO, "(JJJ" SSL_CALLBACKS ")V"),
   9787     NATIVE_METHOD(NativeCrypto, SSL_get_shutdown, "(J)I"),
   9788     NATIVE_METHOD(NativeCrypto, SSL_free, "(J)V"),
   9789     NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(J)[B"),
   9790     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(J)J"),
   9791     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(J)Ljava/lang/String;"),
   9792     NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(J)Ljava/lang/String;"),
   9793     NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(J)V"),
   9794     NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(J)[B"),
   9795     NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)J"),
   9796     NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(J)V"),
   9797     NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(J)V"),
   9798     NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(J)[B"),
   9799     NATIVE_METHOD(NativeCrypto, SSL_set_alpn_protos, "(J[B)I"),
   9800     NATIVE_METHOD(NativeCrypto, SSL_get0_alpn_selected, "(J)[B"),
   9801     NATIVE_METHOD(NativeCrypto, ERR_peek_last_error, "()J"),
   9802 };
   9803 
   9804 static jclass getGlobalRefToClass(JNIEnv* env, const char* className) {
   9805     ScopedLocalRef<jclass> localClass(env, env->FindClass(className));
   9806     jclass globalRef = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
   9807     if (globalRef == NULL) {
   9808         ALOGE("failed to find class %s", className);
   9809         abort();
   9810     }
   9811     return globalRef;
   9812 }
   9813 
   9814 static jmethodID getStaticMethodRef(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
   9815     jmethodID localMethod = env->GetStaticMethodID(clazz, name, sig);
   9816     if (localMethod == NULL) {
   9817         ALOGE("could not find static method %s", name);
   9818         abort();
   9819     }
   9820     return localMethod;
   9821 }
   9822 
   9823 static jmethodID getMethodRef(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
   9824     jmethodID localMethod = env->GetMethodID(clazz, name, sig);
   9825     if (localMethod == NULL) {
   9826         ALOGE("could not find method %s", name);
   9827         abort();
   9828     }
   9829     return localMethod;
   9830 }
   9831 
   9832 static jfieldID getFieldRef(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
   9833     jfieldID localField = env->GetFieldID(clazz, name, sig);
   9834     if (localField == NULL) {
   9835         ALOGE("could not find field %s", name);
   9836         abort();
   9837     }
   9838     return localField;
   9839 }
   9840 
   9841 static void initialize_conscrypt(JNIEnv* env) {
   9842     jniRegisterNativeMethods(env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto",
   9843                              sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
   9844 
   9845     cryptoUpcallsClass = getGlobalRefToClass(env,
   9846             TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/CryptoUpcalls");
   9847     openSslNativeReferenceClass = getGlobalRefToClass(env,
   9848             TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLNativeReference");
   9849     openSslInputStreamClass = getGlobalRefToClass(env,
   9850             TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream");
   9851 
   9852     openSslNativeReference_context = getFieldRef(env, openSslNativeReferenceClass, "context", "J");
   9853 
   9854     calendar_setMethod = getMethodRef(env, calendarClass, "set", "(IIIIII)V");
   9855     inputStream_readMethod = getMethodRef(env, inputStreamClass, "read", "([B)I");
   9856     integer_valueOfMethod = env->GetStaticMethodID(integerClass, "valueOf",
   9857             "(I)Ljava/lang/Integer;");
   9858     openSslInputStream_readLineMethod = getMethodRef(env, openSslInputStreamClass, "gets",
   9859             "([B)I");
   9860     outputStream_writeMethod = getMethodRef(env, outputStreamClass, "write", "([B)V");
   9861     outputStream_flushMethod = getMethodRef(env, outputStreamClass, "flush", "()V");
   9862 
   9863 #ifdef CONSCRYPT_UNBUNDLED
   9864     findAsynchronousCloseMonitorFuncs();
   9865 #endif
   9866 }
   9867 
   9868 static jclass findClass(JNIEnv* env, const char* name) {
   9869     ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
   9870     jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
   9871     if (result == NULL) {
   9872         ALOGE("failed to find class '%s'", name);
   9873         abort();
   9874     }
   9875     return result;
   9876 }
   9877 
   9878 #ifdef STATIC_LIB
   9879 // Give client libs everything they need to initialize our JNI
   9880 int libconscrypt_JNI_OnLoad(JavaVM *vm, void*) {
   9881 #else
   9882 // Use JNI_OnLoad for when we're standalone
   9883 int JNI_OnLoad(JavaVM *vm, void*) {
   9884     JNI_TRACE("JNI_OnLoad NativeCrypto");
   9885 #endif
   9886     gJavaVM = vm;
   9887 
   9888     JNIEnv *env;
   9889     if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
   9890         ALOGE("Could not get JNIEnv");
   9891         return JNI_ERR;
   9892     }
   9893 
   9894     byteArrayClass = findClass(env, "[B");
   9895     calendarClass = findClass(env, "java/util/Calendar");
   9896     inputStreamClass = findClass(env, "java/io/InputStream");
   9897     integerClass = findClass(env, "java/lang/Integer");
   9898     objectClass = findClass(env, "java/lang/Object");
   9899     objectArrayClass = findClass(env, "[Ljava/lang/Object;");
   9900     outputStreamClass = findClass(env, "java/io/OutputStream");
   9901     stringClass = findClass(env, "java/lang/String");
   9902 
   9903     initialize_conscrypt(env);
   9904     return JNI_VERSION_1_6;
   9905 }
   9906