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