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