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 {
operator ()OPENSSL_Delete157     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 {
operator ()BIO_Delete164     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 {
operator ()BIGNUM_Delete171     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 {
operator ()BN_CTX_Delete178     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 {
operator ()ASN1_INTEGER_Delete185     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 {
operator ()DSA_Delete192     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 {
operator ()EC_GROUP_Delete199     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 {
operator ()EC_POINT_Delete206     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 {
operator ()EC_KEY_Delete213     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 {
operator ()EVP_MD_CTX_Delete220     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 {
operator ()EVP_AEAD_CTX_Delete228     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 {
operator ()EVP_CIPHER_CTX_Delete237     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 {
operator ()EVP_PKEY_Delete244     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 {
operator ()PKCS8_PRIV_KEY_INFO_Delete251     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 {
operator ()RSA_Delete258     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 {
operator ()ASN1_BIT_STRING_Delete265     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 {
operator ()ASN1_OBJECT_Delete272     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 {
operator ()ASN1_GENERALIZEDTIME_Delete279     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 {
operator ()SSL_Delete286     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 {
operator ()SSL_CTX_Delete293     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 {
operator ()X509_Delete300     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 {
operator ()X509_NAME_Delete307     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 {
operator ()X509_EXTENSIONS_Delete314     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 {
operator ()PKCS7_Delete322     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 {
operator ()sk_SSL_CIPHER_Delete330     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 {
operator ()sk_X509_Delete338     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 {
operator ()sk_X509_CRL_Delete346     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 {
operator ()sk_X509_NAME_Delete354     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 {
operator ()sk_ASN1_OBJECT_Delete361     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 {
operator ()sk_GENERAL_NAME_Delete368     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  */
freeOpenSslErrorState(void)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:
OpenSslError()425     OpenSslError() : sslError_(SSL_ERROR_NONE), released_(false) {
426     }
427 
OpenSslError(SSL * ssl,int returnCode)428     OpenSslError(SSL* ssl, int returnCode) : sslError_(SSL_ERROR_NONE), released_(false) {
429         reset(ssl, returnCode);
430     }
431 
~OpenSslError()432     ~OpenSslError() {
433         if (!released_ && sslError_ != SSL_ERROR_NONE) {
434             freeOpenSslErrorState();
435         }
436     }
437 
get() const438     int get() const {
439         return sslError_;
440     }
441 
reset(SSL * ssl,int returnCode)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 
release()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  */
jniThrowOutOfMemory(JNIEnv * env,const char * message)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  */
throwBadPaddingException(JNIEnv * env,const char * message)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  */
throwSignatureException(JNIEnv * env,const char * message)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  */
throwInvalidKeyException(JNIEnv * env,const char * message)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  */
throwIllegalBlockSizeException(JNIEnv * env,const char * message)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  */
throwNoSuchAlgorithmException(JNIEnv * env,const char * message)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  */
throwIOException(JNIEnv * env,const char * message)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  */
throwParsingException(JNIEnv * env,const char * message)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 
throwForAsn1Error(JNIEnv * env,int reason,const char * message,int (* defaultThrow)(JNIEnv *,const char *))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)
throwForCipherError(JNIEnv * env,int reason,const char * message,int (* defaultThrow)(JNIEnv *,const char *))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 
throwForEvpError(JNIEnv * env,int reason,const char * message,int (* defaultThrow)(JNIEnv *,const char *))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
throwForEvpError(JNIEnv * env,int reason,const char * message,int (* defaultThrow)(JNIEnv *,const char *))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 
throwForRsaError(JNIEnv * env,int reason,const char * message,int (* defaultThrow)(JNIEnv *,const char *))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 
throwForX509Error(JNIEnv * env,int reason,const char * message,int (* defaultThrow)(JNIEnv *,const char *))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  */
throwExceptionIfNecessary(JNIEnv * env,const char * location,int (* defaultThrow)(JNIEnv *,const char *)=jniThrowRuntimeException)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  */
throwSocketTimeoutException(JNIEnv * env,const char * message)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  */
throwSSLHandshakeExceptionStr(JNIEnv * env,const char * message)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  */
throwSSLExceptionStr(JNIEnv * env,const char * message)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  */
throwSSLProtocolExceptionStr(JNIEnv * env,const char * message)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  */
throwSSLExceptionWithSslErrors(JNIEnv * env,SSL * ssl,int sslErrorCode,const char * message,int (* actualThrow)(JNIEnv *,const char *)=throwSSLExceptionStr)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  */
to_SSL_CTX(JNIEnv * env,jlong ssl_ctx_address,bool throwIfNull)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 
to_SSL(JNIEnv * env,jlong ssl_address,bool throwIfNull)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 
to_SSL_SESSION(JNIEnv * env,jlong ssl_session_address,bool throwIfNull)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 
to_SSL_CIPHER(JNIEnv * env,jlong ssl_cipher_address,bool throwIfNull)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>
fromContextObject(JNIEnv * env,jobject contextObject)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  */
arrayToBignum(JNIEnv * env,jbyteArray source,BIGNUM ** dest)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  */
arrayToBignumSize(JNIEnv * env,jbyteArray source,size_t * out_size)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  */
bignumToArray(JNIEnv * env,const BIGNUM * source,const char * sourceName)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>
ASN1ToByteArray(JNIEnv * env,T * obj,int (* i2d_func)(T *,unsigned char **))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)>
ByteArrayToASN1(JNIEnv * env,jbyteArray byteArray)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  */
ASN1BitStringToBooleanArray(JNIEnv * env,ASN1_BIT_STRING * bitStr)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  */
safeSslClear(SSL * ssl)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  */
X509_dup_nocopy(X509 * x509)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:
ScopedSslBio(SSL * ssl,BIO * rbio,BIO * wbio)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 
~ScopedSslBio()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  */
getJNIEnv()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_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     // If negotiating ECDH, use P-256.
8117     Unique_EC_KEY ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
8118     if (ec.get() == nullptr) {
8119         throwExceptionIfNecessary(env, "EC_KEY_new_by_curve_name");
8120         return 0;
8121     }
8122     SSL_CTX_set_tmp_ecdh(sslCtx.get(), ec.get());
8123 
8124     JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get());
8125     return (jlong) sslCtx.release();
8126 }
8127 
8128 /**
8129  * public static native void SSL_CTX_free(long ssl_ctx)
8130  */
8131 static void NativeCrypto_SSL_CTX_free(JNIEnv* env,
8132         jclass, jlong ssl_ctx_address)
8133 {
8134     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
8135     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx);
8136     if (ssl_ctx == nullptr) {
8137         return;
8138     }
8139     SSL_CTX_free(ssl_ctx);
8140 }
8141 
8142 static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass,
8143                                                         jlong ssl_ctx_address, jbyteArray sid_ctx)
8144 {
8145     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
8146     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx);
8147     if (ssl_ctx == nullptr) {
8148         return;
8149     }
8150 
8151     ScopedByteArrayRO buf(env, sid_ctx);
8152     if (buf.get() == nullptr) {
8153         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => threw exception", ssl_ctx);
8154         return;
8155     }
8156 
8157     unsigned int length = buf.size();
8158     if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) {
8159         jniThrowException(env, "java/lang/IllegalArgumentException",
8160                           "length > SSL_MAX_SSL_SESSION_ID_LENGTH");
8161         JNI_TRACE("NativeCrypto_SSL_CTX_set_session_id_context => length = %d", length);
8162         return;
8163     }
8164     const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buf.get());
8165     int result = SSL_CTX_set_session_id_context(ssl_ctx, bytes, length);
8166     if (result == 0) {
8167         throwExceptionIfNecessary(env, "NativeCrypto_SSL_CTX_set_session_id_context");
8168         return;
8169     }
8170     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => ok", ssl_ctx);
8171 }
8172 
8173 /**
8174  * public static native int SSL_new(long ssl_ctx) throws SSLException;
8175  */
8176 static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address)
8177 {
8178     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
8179     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx);
8180     if (ssl_ctx == nullptr) {
8181         return 0;
8182     }
8183     Unique_SSL ssl(SSL_new(ssl_ctx));
8184     if (ssl.get() == nullptr) {
8185         throwSSLExceptionWithSslErrors(env, nullptr, SSL_ERROR_NONE,
8186                                        "Unable to create SSL structure");
8187         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx);
8188         return 0;
8189     }
8190 
8191     /*
8192      * Create our special application data.
8193      */
8194     AppData* appData = AppData::create();
8195     if (appData == nullptr) {
8196         throwSSLExceptionStr(env, "Unable to create application data");
8197         freeOpenSslErrorState();
8198         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new appData => 0", ssl_ctx);
8199         return 0;
8200     }
8201     SSL_set_app_data(ssl.get(), reinterpret_cast<char*>(appData));
8202 
8203     /*
8204      * Java code in class OpenSSLSocketImpl does the verification. Since
8205      * the callbacks do all the verification of the chain, this flag
8206      * simply controls whether to send protocol-level alerts or not.
8207      * SSL_VERIFY_NONE means don't send alerts and anything else means send
8208      * alerts.
8209      */
8210     SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, nullptr);
8211 
8212     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p appData=%p", ssl_ctx, ssl.get(), appData);
8213     return (jlong) ssl.release();
8214 }
8215 
8216 
8217 static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
8218 {
8219     SSL* ssl = to_SSL(env, ssl_address, true);
8220     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_enable_tls_channel_id", ssl);
8221     if (ssl == nullptr) {
8222         return;
8223     }
8224 
8225     long ret = SSL_enable_tls_channel_id(ssl);
8226     if (ret != 1L) {
8227         ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8228         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error enabling Channel ID");
8229         safeSslClear(ssl);
8230         JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id => error", ssl);
8231         return;
8232     }
8233 }
8234 
8235 static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address)
8236 {
8237     SSL* ssl = to_SSL(env, ssl_address, true);
8238     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id", ssl);
8239     if (ssl == nullptr) {
8240         return nullptr;
8241     }
8242 
8243     // Channel ID is 64 bytes long. Unfortunately, OpenSSL doesn't declare this length
8244     // as a constant anywhere.
8245     jbyteArray javaBytes = env->NewByteArray(64);
8246     ScopedByteArrayRW bytes(env, javaBytes);
8247     if (bytes.get() == nullptr) {
8248         JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => NULL", ssl);
8249         return nullptr;
8250     }
8251 
8252     unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
8253     // Unfortunately, the SSL_get_tls_channel_id method below always returns 64 (upon success)
8254     // regardless of the number of bytes copied into the output buffer "tmp". Thus, the correctness
8255     // of this code currently relies on the "tmp" buffer being exactly 64 bytes long.
8256     long ret = SSL_get_tls_channel_id(ssl, tmp, 64);
8257     if (ret == 0) {
8258         // Channel ID either not set or did not verify
8259         JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => not available", ssl);
8260         return nullptr;
8261     } else if (ret != 64) {
8262         ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8263         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error getting Channel ID");
8264         safeSslClear(ssl);
8265         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_tls_channel_id => error, returned %ld", ssl, ret);
8266         return nullptr;
8267     }
8268 
8269     JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id() => %p", ssl, javaBytes);
8270     return javaBytes;
8271 }
8272 
8273 static void NativeCrypto_SSL_set1_tls_channel_id(JNIEnv* env, jclass,
8274         jlong ssl_address, jobject pkeyRef)
8275 {
8276     SSL* ssl = to_SSL(env, ssl_address, true);
8277     EVP_PKEY* pkey = fromContextObject<EVP_PKEY>(env, pkeyRef);
8278     JNI_TRACE("ssl=%p SSL_set1_tls_channel_id privatekey=%p", ssl, pkey);
8279     if (ssl == nullptr) {
8280         return;
8281     }
8282 
8283     if (pkey == nullptr) {
8284         JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => pkey == null", ssl);
8285         return;
8286     }
8287 
8288 #if !defined(OPENSSL_IS_BORINGSSL)
8289     // SSL_set1_tls_channel_id requires ssl->server to be set to 0.
8290     // Unfortunately, the default value is 1 and it's only changed to 0 just
8291     // before the handshake starts (see NativeCrypto_SSL_do_handshake).
8292     ssl->server = 0;
8293 #endif
8294     long ret = SSL_set1_tls_channel_id(ssl, pkey);
8295 
8296     if (ret != 1L) {
8297         ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8298         throwSSLExceptionWithSslErrors(
8299                 env, ssl, SSL_ERROR_NONE, "Error setting private key for Channel ID");
8300         safeSslClear(ssl);
8301         JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => error", ssl);
8302         return;
8303     }
8304     // SSL_set1_tls_channel_id expects to take ownership of the EVP_PKEY, but
8305     // we have an external reference from the caller such as an OpenSSLKey,
8306     // so we manually increment the reference count here.
8307     EVP_PKEY_up_ref(pkey);
8308 
8309     JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => ok", ssl);
8310 }
8311 
8312 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, jlong ssl_address,
8313                                             jobject pkeyRef) {
8314     SSL* ssl = to_SSL(env, ssl_address, true);
8315     EVP_PKEY* pkey = fromContextObject<EVP_PKEY>(env, pkeyRef);
8316     JNI_TRACE("ssl=%p SSL_use_PrivateKey privatekey=%p", ssl, pkey);
8317     if (ssl == nullptr) {
8318         return;
8319     }
8320 
8321     if (pkey == nullptr) {
8322         JNI_TRACE("ssl=%p SSL_use_PrivateKey => pkey == null", ssl);
8323         return;
8324     }
8325 
8326     int ret = SSL_use_PrivateKey(ssl, pkey);
8327     if (ret != 1) {
8328         ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8329         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key");
8330         safeSslClear(ssl);
8331         JNI_TRACE("ssl=%p SSL_use_PrivateKey => error", ssl);
8332         return;
8333     }
8334     // SSL_use_PrivateKey expects to take ownership of the EVP_PKEY,
8335     // but we have an external reference from the caller such as an
8336     // OpenSSLKey, so we manually increment the reference count here.
8337     EVP_PKEY_up_ref(pkey);
8338 
8339     JNI_TRACE("ssl=%p SSL_use_PrivateKey => ok", ssl);
8340 }
8341 
8342 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass,
8343                                              jlong ssl_address, jlongArray certificatesJava)
8344 {
8345     SSL* ssl = to_SSL(env, ssl_address, true);
8346     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificatesJava);
8347     if (ssl == nullptr) {
8348         return;
8349     }
8350 
8351     if (certificatesJava == nullptr) {
8352         jniThrowNullPointerException(env, "certificates == null");
8353         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
8354         return;
8355     }
8356 
8357     size_t length = env->GetArrayLength(certificatesJava);
8358     if (length == 0) {
8359         jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0");
8360         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl);
8361         return;
8362     }
8363 
8364     ScopedLongArrayRO certificates(env, certificatesJava);
8365     if (certificates.get() == nullptr) {
8366         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl);
8367         return;
8368     }
8369 
8370     Unique_X509 serverCert(
8371             X509_dup_nocopy(reinterpret_cast<X509*>(static_cast<uintptr_t>(certificates[0]))));
8372     if (serverCert.get() == nullptr) {
8373         // Note this shouldn't happen since we checked the number of certificates above.
8374         jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
8375         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
8376         return;
8377     }
8378 
8379     int ret = SSL_use_certificate(ssl, serverCert.get());
8380     if (ret != 1) {
8381         ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8382         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate");
8383         safeSslClear(ssl);
8384         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl);
8385         return;
8386     }
8387     OWNERSHIP_TRANSFERRED(serverCert);
8388 
8389 #if !defined(OPENSSL_IS_BORINGSSL)
8390     Unique_sk_X509 chain(sk_X509_new_null());
8391     if (chain.get() == NULL) {
8392         jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
8393         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl);
8394         return;
8395     }
8396 
8397     for (size_t i = 1; i < length; i++) {
8398         Unique_X509 cert(
8399                 X509_dup_nocopy(reinterpret_cast<X509*>(static_cast<uintptr_t>(certificates[i]))));
8400         if (cert.get() == NULL || !sk_X509_push(chain.get(), cert.get())) {
8401             ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL));
8402             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
8403             safeSslClear(ssl);
8404             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
8405             return;
8406         }
8407         OWNERSHIP_TRANSFERRED(cert);
8408     }
8409 
8410     int chainResult = SSL_use_certificate_chain(ssl, chain.get());
8411     if (chainResult == 0) {
8412         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain");
8413         JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error",
8414                   ssl);
8415         return;
8416     }
8417     OWNERSHIP_TRANSFERRED(chain);
8418 #else
8419     for (size_t i = 1; i < length; i++) {
8420         Unique_X509 cert(
8421                 X509_dup_nocopy(reinterpret_cast<X509*>(static_cast<uintptr_t>(certificates[i]))));
8422         if (cert.get() == nullptr || !SSL_add0_chain_cert(ssl, cert.get())) {
8423             ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8424             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate");
8425             safeSslClear(ssl);
8426             JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl);
8427             return;
8428         }
8429         OWNERSHIP_TRANSFERRED(cert);
8430     }
8431 #endif
8432 
8433     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl);
8434 }
8435 
8436 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jlong ssl_address)
8437 {
8438     SSL* ssl = to_SSL(env, ssl_address, true);
8439     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl);
8440     if (ssl == nullptr) {
8441         return;
8442     }
8443     int ret = SSL_check_private_key(ssl);
8444     if (ret != 1) {
8445         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key");
8446         safeSslClear(ssl);
8447         JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl);
8448         return;
8449     }
8450     JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl);
8451 }
8452 
8453 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass,
8454                                                 jlong ssl_address, jobjectArray principals)
8455 {
8456     SSL* ssl = to_SSL(env, ssl_address, true);
8457     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals);
8458     if (ssl == nullptr) {
8459         return;
8460     }
8461 
8462     if (principals == nullptr) {
8463         jniThrowNullPointerException(env, "principals == null");
8464         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl);
8465         return;
8466     }
8467 
8468     int length = env->GetArrayLength(principals);
8469     if (length == 0) {
8470         jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0");
8471         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl);
8472         return;
8473     }
8474 
8475     Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null());
8476     if (principalsStack.get() == nullptr) {
8477         jniThrowOutOfMemory(env, "Unable to allocate principal stack");
8478         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl);
8479         return;
8480     }
8481     for (int i = 0; i < length; i++) {
8482         ScopedLocalRef<jbyteArray> principal(env,
8483                 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i)));
8484         if (principal.get() == nullptr) {
8485             jniThrowNullPointerException(env, "principals element == null");
8486             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl);
8487             return;
8488         }
8489 
8490         ScopedByteArrayRO buf(env, principal.get());
8491         if (buf.get() == nullptr) {
8492             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl);
8493             return;
8494         }
8495         const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get());
8496         Unique_X509_NAME principalX509Name(d2i_X509_NAME(nullptr, &tmp, buf.size()));
8497 
8498         if (principalX509Name.get() == nullptr) {
8499             ALOGE("%s", ERR_error_string(ERR_peek_error(), nullptr));
8500             throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal");
8501             safeSslClear(ssl);
8502             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error",
8503                       ssl);
8504             return;
8505         }
8506 
8507         if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) {
8508             jniThrowOutOfMemory(env, "Unable to push principal");
8509             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl);
8510             return;
8511         }
8512     }
8513 
8514     SSL_set_client_CA_list(ssl, principalsStack.release());
8515     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl);
8516 }
8517 
8518 /**
8519  * public static native long SSL_get_mode(long ssl);
8520  */
8521 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jlong ssl_address) {
8522     SSL* ssl = to_SSL(env, ssl_address, true);
8523     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl);
8524     if (ssl == nullptr) {
8525         return 0;
8526     }
8527     long mode = SSL_get_mode(ssl);
8528     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode);
8529     return mode;
8530 }
8531 
8532 /**
8533  * public static native long SSL_set_mode(long ssl, long mode);
8534  */
8535 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass,
8536         jlong ssl_address, jlong mode) {
8537     SSL* ssl = to_SSL(env, ssl_address, true);
8538     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, (long long) mode);
8539     if (ssl == nullptr) {
8540         return 0;
8541     }
8542     long result = SSL_set_mode(ssl, mode);
8543     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result);
8544     return result;
8545 }
8546 
8547 /**
8548  * public static native long SSL_clear_mode(long ssl, long mode);
8549  */
8550 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass,
8551         jlong ssl_address, jlong mode) {
8552     SSL* ssl = to_SSL(env, ssl_address, true);
8553     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, (long long) mode);
8554     if (ssl == nullptr) {
8555         return 0;
8556     }
8557     long result = SSL_clear_mode(ssl, mode);
8558     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result);
8559     return result;
8560 }
8561 
8562 /**
8563  * public static native long SSL_get_options(long ssl);
8564  */
8565 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass,
8566         jlong ssl_address) {
8567     SSL* ssl = to_SSL(env, ssl_address, true);
8568     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl);
8569     if (ssl == nullptr) {
8570         return 0;
8571     }
8572     long options = SSL_get_options(ssl);
8573     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options);
8574     return options;
8575 }
8576 
8577 /**
8578  * public static native long SSL_set_options(long ssl, long options);
8579  */
8580 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass,
8581         jlong ssl_address, jlong options) {
8582     SSL* ssl = to_SSL(env, ssl_address, true);
8583     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, (long long) options);
8584     if (ssl == nullptr) {
8585         return 0;
8586     }
8587     long result = SSL_set_options(ssl, options);
8588     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result);
8589     return result;
8590 }
8591 
8592 /**
8593  * public static native long SSL_clear_options(long ssl, long options);
8594  */
8595 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass,
8596         jlong ssl_address, jlong options) {
8597     SSL* ssl = to_SSL(env, ssl_address, true);
8598     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, (long long) options);
8599     if (ssl == nullptr) {
8600         return 0;
8601     }
8602     long result = SSL_clear_options(ssl, options);
8603     JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result);
8604     return result;
8605 }
8606 
8607 
8608 /**
8609  * public static native void SSL_enable_signed_cert_timestamps(long ssl);
8610  */
8611 static void NativeCrypto_SSL_enable_signed_cert_timestamps(JNIEnv *env, jclass,
8612         jlong ssl_address) {
8613     SSL* ssl = to_SSL(env, ssl_address, true);
8614     JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_signed_cert_timestamps", ssl);
8615     if (ssl == nullptr) {
8616         return;
8617     }
8618 
8619 #if defined(OPENSSL_IS_BORINGSSL)
8620     SSL_enable_signed_cert_timestamps(ssl);
8621 #endif
8622 }
8623 
8624 /**
8625  * public static native byte[] SSL_get_signed_cert_timestamp_list(long ssl);
8626  */
8627 static jbyteArray NativeCrypto_SSL_get_signed_cert_timestamp_list(JNIEnv *env, jclass,
8628         jlong ssl_address) {
8629     SSL* ssl = to_SSL(env, ssl_address, true);
8630     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_signed_cert_timestamp_list", ssl);
8631     if (ssl == nullptr) {
8632         return nullptr;
8633     }
8634 
8635 #if defined(OPENSSL_IS_BORINGSSL)
8636     const uint8_t *data;
8637     size_t data_len;
8638     SSL_get0_signed_cert_timestamp_list(ssl, &data, &data_len);
8639 
8640     if (data_len == 0) {
8641         JNI_TRACE("NativeCrypto_SSL_get_signed_cert_timestamp_list(%p) => NULL",
8642                 ssl);
8643         return nullptr;
8644     }
8645 
8646     jbyteArray result = env->NewByteArray(data_len);
8647     if (result != nullptr) {
8648         env->SetByteArrayRegion(result, 0, data_len, (const jbyte*)data);
8649     }
8650     return result;
8651 #else
8652     return NULL;
8653 #endif
8654 }
8655 
8656 /*
8657  * public static native void SSL_CTX_set_signed_cert_timestamp_list(long ssl, byte[] response);
8658  */
8659 static void NativeCrypto_SSL_CTX_set_signed_cert_timestamp_list(JNIEnv *env, jclass,
8660         jlong ssl_ctx_address, jbyteArray list) {
8661     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
8662     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_signed_cert_timestamp_list", ssl_ctx);
8663     if (ssl_ctx == nullptr) {
8664         return;
8665     }
8666 
8667     ScopedByteArrayRO listBytes(env, list);
8668     if (listBytes.get() == nullptr) {
8669         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_signed_cert_timestamp_list =>"
8670                   " list == NULL", ssl_ctx);
8671         return;
8672     }
8673 
8674 #if defined(OPENSSL_IS_BORINGSSL)
8675     if (!SSL_CTX_set_signed_cert_timestamp_list(ssl_ctx,
8676                 reinterpret_cast<const uint8_t *>(listBytes.get()),
8677                 listBytes.size())) {
8678         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_signed_cert_timestamp_list => fail", ssl_ctx);
8679     } else {
8680         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_signed_cert_timestamp_list => ok", ssl_ctx);
8681     }
8682 #endif
8683 }
8684 
8685 /*
8686  * public static native void SSL_enable_ocsp_stapling(long ssl);
8687  */
8688 static void NativeCrypto_SSL_enable_ocsp_stapling(JNIEnv *env, jclass,
8689         jlong ssl_address) {
8690     SSL* ssl = to_SSL(env, ssl_address, true);
8691     JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_ocsp_stapling", ssl);
8692     if (ssl == nullptr) {
8693         return;
8694     }
8695 
8696 #if defined(OPENSSL_IS_BORINGSSL)
8697     SSL_enable_ocsp_stapling(ssl);
8698 #endif
8699 }
8700 
8701 /*
8702  * public static native byte[] SSL_get_ocsp_response(long ssl);
8703  */
8704 static jbyteArray NativeCrypto_SSL_get_ocsp_response(JNIEnv *env, jclass,
8705         jlong ssl_address) {
8706     SSL* ssl = to_SSL(env, ssl_address, true);
8707     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_ocsp_response", ssl);
8708     if (ssl == nullptr) {
8709         return nullptr;
8710     }
8711 
8712 #if defined(OPENSSL_IS_BORINGSSL)
8713     const uint8_t *data;
8714     size_t data_len;
8715     SSL_get0_ocsp_response(ssl, &data, &data_len);
8716 
8717     if (data_len == 0) {
8718         JNI_TRACE("NativeCrypto_SSL_get_ocsp_response(%p) => NULL", ssl);
8719         return nullptr;
8720     }
8721 
8722     ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(data_len));
8723     if (byteArray.get() == nullptr) {
8724         JNI_TRACE("NativeCrypto_SSL_get_ocsp_response(%p) => creating byte array failed", ssl);
8725         return nullptr;
8726     }
8727 
8728     env->SetByteArrayRegion(byteArray.get(), 0, data_len, (const jbyte*)data);
8729     JNI_TRACE("NativeCrypto_SSL_get_ocsp_response(%p) => %p [size=%zd]",
8730               ssl, byteArray.get(), data_len);
8731 
8732     return byteArray.release();
8733 #else
8734     return NULL;
8735 #endif
8736 }
8737 
8738 /*
8739  * public static native void SSL_CTX_set_ocsp_response(long ssl, byte[] response);
8740  */
8741 static void NativeCrypto_SSL_CTX_set_ocsp_response(JNIEnv *env, jclass,
8742         jlong ssl_ctx_address, jbyteArray response) {
8743     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
8744     JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_ocsp_response", ssl_ctx);
8745     if (ssl_ctx == nullptr) {
8746         return;
8747     }
8748 
8749     ScopedByteArrayRO responseBytes(env, response);
8750     if (responseBytes.get() == nullptr) {
8751         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_ocsp_response => response == NULL", ssl_ctx);
8752         return;
8753     }
8754 
8755 #if defined(OPENSSL_IS_BORINGSSL)
8756     if (!SSL_CTX_set_ocsp_response(ssl_ctx,
8757                 reinterpret_cast<const uint8_t *>(responseBytes.get()),
8758                 responseBytes.size())) {
8759         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_ocsp_response => fail", ssl_ctx);
8760     } else {
8761         JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_ocsp_response => ok", ssl_ctx);
8762     }
8763 #endif
8764 }
8765 
8766 static void NativeCrypto_SSL_use_psk_identity_hint(JNIEnv* env, jclass,
8767         jlong ssl_address, jstring identityHintJava)
8768 {
8769     SSL* ssl = to_SSL(env, ssl_address, true);
8770     JNI_TRACE("ssl=%p NativeCrypto_SSL_use_psk_identity_hint identityHint=%p",
8771             ssl, identityHintJava);
8772     if (ssl == nullptr) {
8773         return;
8774     }
8775 
8776     int ret;
8777     if (identityHintJava == nullptr) {
8778         ret = SSL_use_psk_identity_hint(ssl, nullptr);
8779     } else {
8780         ScopedUtfChars identityHint(env, identityHintJava);
8781         if (identityHint.c_str() == nullptr) {
8782             throwSSLExceptionStr(env, "Failed to obtain identityHint bytes");
8783             return;
8784         }
8785         ret = SSL_use_psk_identity_hint(ssl, identityHint.c_str());
8786     }
8787 
8788     if (ret != 1) {
8789         int sslErrorCode = SSL_get_error(ssl, ret);
8790         throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Failed to set PSK identity hint");
8791         safeSslClear(ssl);
8792     }
8793 }
8794 
8795 static void NativeCrypto_set_SSL_psk_client_callback_enabled(JNIEnv* env, jclass,
8796         jlong ssl_address, jboolean enabled)
8797 {
8798     SSL* ssl = to_SSL(env, ssl_address, true);
8799     JNI_TRACE("ssl=%p NativeCrypto_set_SSL_psk_client_callback_enabled(%d)",
8800             ssl, enabled);
8801     if (ssl == nullptr) {
8802         return;
8803     }
8804 
8805     SSL_set_psk_client_callback(ssl, (enabled) ? psk_client_callback : nullptr);
8806 }
8807 
8808 static void NativeCrypto_set_SSL_psk_server_callback_enabled(JNIEnv* env, jclass,
8809         jlong ssl_address, jboolean enabled)
8810 {
8811     SSL* ssl = to_SSL(env, ssl_address, true);
8812     JNI_TRACE("ssl=%p NativeCrypto_set_SSL_psk_server_callback_enabled(%d)",
8813             ssl, enabled);
8814     if (ssl == nullptr) {
8815         return;
8816     }
8817 
8818     SSL_set_psk_server_callback(ssl, (enabled) ? psk_server_callback : nullptr);
8819 }
8820 
8821 static jlongArray NativeCrypto_SSL_get_ciphers(JNIEnv* env, jclass, jlong ssl_address)
8822 {
8823     SSL* ssl = to_SSL(env, ssl_address, true);
8824     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_ciphers", ssl);
8825 
8826     STACK_OF(SSL_CIPHER)* cipherStack = SSL_get_ciphers(ssl);
8827     int count = (cipherStack != nullptr) ? sk_SSL_CIPHER_num(cipherStack) : 0;
8828     ScopedLocalRef<jlongArray> ciphersArray(env, env->NewLongArray(count));
8829     ScopedLongArrayRW ciphers(env, ciphersArray.get());
8830     for (int i = 0; i < count; i++) {
8831         ciphers[i] = reinterpret_cast<jlong>(sk_SSL_CIPHER_value(cipherStack, i));
8832     }
8833 
8834     JNI_TRACE("NativeCrypto_SSL_get_ciphers(%p) => %p [size=%d]", ssl, ciphersArray.get(), count);
8835     return ciphersArray.release();
8836 }
8837 
8838 /**
8839  * Sets the ciphers suites that are enabled in the SSL
8840  */
8841 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass, jlong ssl_address,
8842                                               jobjectArray cipherSuites) {
8843     SSL* ssl = to_SSL(env, ssl_address, true);
8844     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites);
8845     if (ssl == nullptr) {
8846         return;
8847     }
8848     if (cipherSuites == nullptr) {
8849         jniThrowNullPointerException(env, "cipherSuites == null");
8850         return;
8851     }
8852 
8853     int length = env->GetArrayLength(cipherSuites);
8854 
8855     /*
8856      * Special case for empty cipher list. This is considered an error by the
8857      * SSL_set_cipher_list API, but Java allows this silly configuration.
8858      * However, the SSL cipher list is still set even when SSL_set_cipher_list
8859      * returns 0 in this case. Just to make sure, we check the resulting cipher
8860      * list to make sure it's zero length.
8861      */
8862     if (length == 0) {
8863         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=empty", ssl);
8864         SSL_set_cipher_list(ssl, "");
8865         freeOpenSslErrorState();
8866         if (sk_SSL_CIPHER_num(SSL_get_ciphers(ssl)) != 0) {
8867             JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=empty => error", ssl);
8868             jniThrowRuntimeException(env, "SSL_set_cipher_list did not update ciphers!");
8869         }
8870         return;
8871     }
8872 
8873     static const char noSSLv2[] = "!SSLv2";
8874     size_t cipherStringLen = strlen(noSSLv2);
8875 
8876     for (int i = 0; i < length; i++) {
8877         ScopedLocalRef<jstring> cipherSuite(env,
8878                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
8879         ScopedUtfChars c(env, cipherSuite.get());
8880         if (c.c_str() == nullptr) {
8881             return;
8882         }
8883 
8884         if (cipherStringLen + 1 < cipherStringLen) {
8885           jniThrowException(env, "java/lang/IllegalArgumentException",
8886                             "Overflow in cipher suite strings");
8887           return;
8888         }
8889         cipherStringLen += 1;  /* For the separating colon */
8890 
8891         if (cipherStringLen + c.size() < cipherStringLen) {
8892           jniThrowException(env, "java/lang/IllegalArgumentException",
8893                             "Overflow in cipher suite strings");
8894           return;
8895         }
8896         cipherStringLen += c.size();
8897     }
8898 
8899     if (cipherStringLen + 1 < cipherStringLen) {
8900       jniThrowException(env, "java/lang/IllegalArgumentException",
8901                         "Overflow in cipher suite strings");
8902       return;
8903     }
8904     cipherStringLen += 1;  /* For final NUL. */
8905 
8906     UniquePtr<char[]> cipherString(new char[cipherStringLen]);
8907     if (cipherString.get() == nullptr) {
8908         jniThrowOutOfMemory(env, "Unable to alloc cipher string");
8909         return;
8910     }
8911     memcpy(cipherString.get(), noSSLv2, strlen(noSSLv2));
8912     size_t j = strlen(noSSLv2);
8913 
8914     for (int i = 0; i < length; i++) {
8915         ScopedLocalRef<jstring> cipherSuite(env,
8916                 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i)));
8917         ScopedUtfChars c(env, cipherSuite.get());
8918 
8919         cipherString[j++] = ':';
8920         memcpy(&cipherString[j], c.c_str(), c.size());
8921         j += c.size();
8922     }
8923 
8924     cipherString[j++] = 0;
8925     if (j != cipherStringLen) {
8926         jniThrowException(env, "java/lang/IllegalArgumentException",
8927                           "Internal error");
8928         return;
8929     }
8930 
8931     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%s", ssl, cipherString.get());
8932     if (!SSL_set_cipher_list(ssl, cipherString.get())) {
8933         freeOpenSslErrorState();
8934         jniThrowException(env, "java/lang/IllegalArgumentException",
8935                           "Illegal cipher suite strings.");
8936         return;
8937     }
8938 }
8939 
8940 static void NativeCrypto_SSL_set_accept_state(JNIEnv* env, jclass, jlong sslRef) {
8941     SSL* ssl = to_SSL(env, sslRef, true);
8942     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_accept_state", ssl);
8943     if (ssl == nullptr) {
8944         return;
8945     }
8946     SSL_set_accept_state(ssl);
8947 }
8948 
8949 static void NativeCrypto_SSL_set_connect_state(JNIEnv* env, jclass, jlong sslRef) {
8950     SSL* ssl = to_SSL(env, sslRef, true);
8951     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_connect_state", ssl);
8952     if (ssl == nullptr) {
8953         return;
8954     }
8955     SSL_set_connect_state(ssl);
8956 }
8957 
8958 /**
8959  * Sets certificate expectations, especially for server to request client auth
8960  */
8961 static void NativeCrypto_SSL_set_verify(JNIEnv* env,
8962         jclass, jlong ssl_address, jint mode)
8963 {
8964     SSL* ssl = to_SSL(env, ssl_address, true);
8965     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode);
8966     if (ssl == nullptr) {
8967         return;
8968     }
8969     SSL_set_verify(ssl, (int)mode, nullptr);
8970 }
8971 
8972 /**
8973  * Sets the ciphers suites that are enabled in the SSL
8974  */
8975 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass,
8976         jlong ssl_address, jlong ssl_session_address)
8977 {
8978     SSL* ssl = to_SSL(env, ssl_address, true);
8979     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false);
8980     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session);
8981     if (ssl == nullptr) {
8982         return;
8983     }
8984 
8985     int ret = SSL_set_session(ssl, ssl_session);
8986     if (ret != 1) {
8987         /*
8988          * Translate the error, and throw if it turns out to be a real
8989          * problem.
8990          */
8991         int sslErrorCode = SSL_get_error(ssl, ret);
8992         if (sslErrorCode != SSL_ERROR_ZERO_RETURN) {
8993             throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set");
8994             safeSslClear(ssl);
8995         }
8996     }
8997 }
8998 
8999 /**
9000  * Sets the ciphers suites that are enabled in the SSL
9001  */
9002 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass,
9003         jlong ssl_address, jboolean creation_enabled)
9004 {
9005     SSL* ssl = to_SSL(env, ssl_address, true);
9006     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d",
9007               ssl, creation_enabled);
9008     if (ssl == nullptr) {
9009         return;
9010     }
9011 
9012 #if !defined(OPENSSL_IS_BORINGSSL)
9013     SSL_set_session_creation_enabled(ssl, creation_enabled);
9014 #else
9015     if (creation_enabled) {
9016         SSL_clear_mode(ssl, SSL_MODE_NO_SESSION_CREATION);
9017     } else {
9018         SSL_set_mode(ssl, SSL_MODE_NO_SESSION_CREATION);
9019     }
9020 #endif
9021 }
9022 
9023 static jboolean NativeCrypto_SSL_session_reused(JNIEnv* env, jclass, jlong ssl_address) {
9024     SSL* ssl = to_SSL(env, ssl_address, true);
9025     JNI_TRACE("ssl=%p NativeCrypto_SSL_session_reused", ssl);
9026     if (ssl == nullptr) {
9027         return JNI_FALSE;
9028     }
9029 
9030     int reused = SSL_session_reused(ssl);
9031     JNI_TRACE("ssl=%p NativeCrypto_SSL_session_reused => %d", ssl, reused);
9032     return reused == 1 ? JNI_TRUE : JNI_FALSE;
9033 }
9034 
9035 static void NativeCrypto_SSL_set_reject_peer_renegotiations(JNIEnv* env, jclass,
9036         jlong ssl_address, jboolean reject_renegotiations)
9037 {
9038     SSL* ssl = to_SSL(env, ssl_address, true);
9039     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_reject_peer_renegotiations reject_renegotiations=%d",
9040               ssl, reject_renegotiations);
9041     if (ssl == nullptr) {
9042         return;
9043     }
9044 
9045 #if defined(OPENSSL_IS_BORINGSSL)
9046     SSL_set_reject_peer_renegotiations(ssl, reject_renegotiations);
9047 #else
9048     (void) reject_renegotiations;
9049     /* OpenSSL doesn't support this call and accepts renegotiation requests by
9050      * default. */
9051 #endif
9052 }
9053 
9054 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass,
9055         jlong ssl_address, jstring hostname)
9056 {
9057     SSL* ssl = to_SSL(env, ssl_address, true);
9058     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p",
9059               ssl, hostname);
9060     if (ssl == nullptr) {
9061         return;
9062     }
9063 
9064     ScopedUtfChars hostnameChars(env, hostname);
9065     if (hostnameChars.c_str() == nullptr) {
9066         return;
9067     }
9068     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s",
9069               ssl, hostnameChars.c_str());
9070 
9071     int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str());
9072     if (ret != 1) {
9073         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name");
9074         safeSslClear(ssl);
9075         JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl);
9076         return;
9077     }
9078     JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl);
9079 }
9080 
9081 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_address) {
9082     SSL* ssl = to_SSL(env, ssl_address, true);
9083     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl);
9084     if (ssl == nullptr) {
9085         return nullptr;
9086     }
9087     const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
9088     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername);
9089     return env->NewStringUTF(servername);
9090 }
9091 
9092 /**
9093  * A common selection path for both NPN and ALPN since they're essentially the
9094  * same protocol. The list of protocols in "primary" is considered the order
9095  * which should take precedence.
9096  */
9097 static int proto_select(SSL* ssl __attribute__ ((unused)),
9098         unsigned char **out, unsigned char *outLength,
9099         const unsigned char *primary, const unsigned int primaryLength,
9100         const unsigned char *secondary, const unsigned int secondaryLength) {
9101     if (primary != nullptr && secondary != nullptr) {
9102         JNI_TRACE("primary=%p, length=%d", primary, primaryLength);
9103 
9104         int status = SSL_select_next_proto(out, outLength, primary, primaryLength, secondary,
9105                 secondaryLength);
9106         switch (status) {
9107         case OPENSSL_NPN_NEGOTIATED:
9108             JNI_TRACE("ssl=%p proto_select NPN/ALPN negotiated", ssl);
9109             return SSL_TLSEXT_ERR_OK;
9110             break;
9111         case OPENSSL_NPN_UNSUPPORTED:
9112             JNI_TRACE("ssl=%p proto_select NPN/ALPN unsupported", ssl);
9113             break;
9114         case OPENSSL_NPN_NO_OVERLAP:
9115             JNI_TRACE("ssl=%p proto_select NPN/ALPN no overlap", ssl);
9116             break;
9117         }
9118     } else {
9119         if (out != nullptr && outLength != nullptr) {
9120             *out = nullptr;
9121             *outLength = 0;
9122         }
9123         JNI_TRACE("protocols=NULL");
9124     }
9125     return SSL_TLSEXT_ERR_NOACK;
9126 }
9127 
9128 /**
9129  * Callback for the server to select an ALPN protocol.
9130  */
9131 static int alpn_select_callback(SSL* ssl, const unsigned char **out, unsigned char *outlen,
9132         const unsigned char *in, unsigned int inlen, void *) {
9133     JNI_TRACE("ssl=%p alpn_select_callback", ssl);
9134 
9135     AppData* appData = toAppData(ssl);
9136     JNI_TRACE("AppData=%p", appData);
9137 
9138     return proto_select(ssl, const_cast<unsigned char **>(out), outlen,
9139             reinterpret_cast<unsigned char*>(appData->alpnProtocolsData),
9140             appData->alpnProtocolsLength, in, inlen);
9141 }
9142 
9143 /**
9144  * Callback for the client to select an NPN protocol.
9145  */
9146 static int next_proto_select_callback(SSL* ssl, unsigned char** out, unsigned char* outlen,
9147                                       const unsigned char* in, unsigned int inlen, void*)
9148 {
9149     JNI_TRACE("ssl=%p next_proto_select_callback", ssl);
9150 
9151     AppData* appData = toAppData(ssl);
9152     JNI_TRACE("AppData=%p", appData);
9153 
9154 #if !defined(OPENSSL_IS_BORINGSSL)
9155     // Enable False Start on the client if the server understands NPN. Unlike BoringSSL,
9156     // OpenSSL doesn't implement this check internally.
9157     // http://www.imperialviolet.org/2012/04/11/falsestart.html
9158     SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH);
9159 #endif
9160 
9161     return proto_select(ssl, out, outlen, in, inlen,
9162             reinterpret_cast<unsigned char*>(appData->npnProtocolsData),
9163             appData->npnProtocolsLength);
9164 }
9165 
9166 /**
9167  * Callback for the server to advertise available protocols.
9168  */
9169 static int next_protos_advertised_callback(SSL* ssl,
9170         const unsigned char **out, unsigned int *outlen, void *)
9171 {
9172     JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl);
9173     AppData* appData = toAppData(ssl);
9174     unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData);
9175     if (npnProtocols != nullptr) {
9176         *out = npnProtocols;
9177         *outlen = appData->npnProtocolsLength;
9178         return SSL_TLSEXT_ERR_OK;
9179     } else {
9180         *out = nullptr;
9181         *outlen = 0;
9182         return SSL_TLSEXT_ERR_NOACK;
9183     }
9184 }
9185 
9186 static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
9187 {
9188     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
9189     if (ssl_ctx == nullptr) {
9190         return;
9191     }
9192     SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, nullptr);  // client
9193     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback,
9194                                           nullptr);  // server
9195 }
9196 
9197 static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address)
9198 {
9199     SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true);
9200     if (ssl_ctx == nullptr) {
9201         return;
9202     }
9203     SSL_CTX_set_next_proto_select_cb(ssl_ctx, nullptr, nullptr);       // client
9204     SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, nullptr, nullptr);  // server
9205 }
9206 
9207 static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass,
9208         jlong ssl_address)
9209 {
9210     SSL* ssl = to_SSL(env, ssl_address, true);
9211     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl);
9212     if (ssl == nullptr) {
9213         return nullptr;
9214     }
9215     const jbyte* npn;
9216     unsigned npnLength;
9217     SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
9218     if (npnLength == 0) {
9219         return nullptr;
9220     }
9221     jbyteArray result = env->NewByteArray(npnLength);
9222     if (result != nullptr) {
9223         env->SetByteArrayRegion(result, 0, npnLength, npn);
9224     }
9225     return result;
9226 }
9227 
9228 static int NativeCrypto_SSL_set_alpn_protos(JNIEnv* env, jclass, jlong ssl_address,
9229         jbyteArray protos) {
9230     SSL* ssl = to_SSL(env, ssl_address, true);
9231     if (ssl == nullptr) {
9232         return 0;
9233     }
9234 
9235     JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=%p", ssl, protos);
9236 
9237     if (protos == nullptr) {
9238         JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=NULL", ssl);
9239         return 1;
9240     }
9241 
9242     ScopedByteArrayRO protosBytes(env, protos);
9243     if (protosBytes.get() == nullptr) {
9244         JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=%p => protosBytes == NULL", ssl,
9245                 protos);
9246         return 0;
9247     }
9248 
9249     const unsigned char *tmp = reinterpret_cast<const unsigned char*>(protosBytes.get());
9250     int ret = SSL_set_alpn_protos(ssl, tmp, protosBytes.size());
9251     JNI_TRACE("ssl=%p SSL_set_alpn_protos protos=%p => ret=%d", ssl, protos, ret);
9252     return ret;
9253 }
9254 
9255 static jbyteArray NativeCrypto_SSL_get0_alpn_selected(JNIEnv* env, jclass,
9256         jlong ssl_address)
9257 {
9258     SSL* ssl = to_SSL(env, ssl_address, true);
9259     JNI_TRACE("ssl=%p SSL_get0_alpn_selected", ssl);
9260     if (ssl == nullptr) {
9261         return nullptr;
9262     }
9263     const jbyte* npn;
9264     unsigned npnLength;
9265     SSL_get0_alpn_selected(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength);
9266     if (npnLength == 0) {
9267         return nullptr;
9268     }
9269     jbyteArray result = env->NewByteArray(npnLength);
9270     if (result != nullptr) {
9271         env->SetByteArrayRegion(result, 0, npnLength, npn);
9272     }
9273     return result;
9274 }
9275 
9276 #ifdef WITH_JNI_TRACE_KEYS
9277 static inline char hex_char(unsigned char in)
9278 {
9279     if (in < 10) {
9280         return '0' + in;
9281     } else if (in <= 0xF0) {
9282         return 'A' + in - 10;
9283     } else {
9284         return '?';
9285     }
9286 }
9287 
9288 static void hex_string(char **dest, unsigned char* input, int len)
9289 {
9290     *dest = (char*) malloc(len * 2 + 1);
9291     char *output = *dest;
9292     for (int i = 0; i < len; i++) {
9293         *output++ = hex_char(input[i] >> 4);
9294         *output++ = hex_char(input[i] & 0xF);
9295     }
9296     *output = '\0';
9297 }
9298 
9299 static void debug_print_session_key(SSL_SESSION* session)
9300 {
9301     char *session_id_str;
9302     char *master_key_str;
9303     const char *key_type;
9304     char *keyline;
9305 
9306     hex_string(&session_id_str, session->session_id, session->session_id_length);
9307     hex_string(&master_key_str, session->master_key, session->master_key_length);
9308 
9309     X509* peer = SSL_SESSION_get0_peer(session);
9310     EVP_PKEY* pkey = X509_PUBKEY_get(peer->cert_info->key);
9311     switch (EVP_PKEY_type(pkey->type)) {
9312     case EVP_PKEY_RSA:
9313         key_type = "RSA";
9314         break;
9315     case EVP_PKEY_DSA:
9316         key_type = "DSA";
9317         break;
9318     case EVP_PKEY_EC:
9319         key_type = "EC";
9320         break;
9321     default:
9322         key_type = "Unknown";
9323         break;
9324     }
9325 
9326     asprintf(&keyline, "%s Session-ID:%s Master-Key:%s\n", key_type, session_id_str,
9327             master_key_str);
9328     JNI_TRACE("ssl_session=%p %s", session, keyline);
9329 
9330     free(session_id_str);
9331     free(master_key_str);
9332     free(keyline);
9333 }
9334 #endif /* WITH_JNI_TRACE_KEYS */
9335 
9336 /**
9337  * Perform SSL handshake
9338  */
9339 static jlong NativeCrypto_SSL_do_handshake_bio(JNIEnv* env, jclass, jlong ssl_address,
9340         jlong rbioRef, jlong wbioRef, jobject shc, jboolean client_mode, jbyteArray npnProtocols,
9341         jbyteArray alpnProtocols) {
9342     SSL* ssl = to_SSL(env, ssl_address, true);
9343     BIO* rbio = reinterpret_cast<BIO*>(rbioRef);
9344     BIO* wbio = reinterpret_cast<BIO*>(wbioRef);
9345     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio rbio=%p wbio=%p shc=%p client_mode=%d npn=%p",
9346               ssl, rbio, wbio, shc, client_mode, npnProtocols);
9347     if (ssl == nullptr) {
9348         return 0;
9349     }
9350     if (shc == nullptr) {
9351         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
9352         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio sslHandshakeCallbacks == null => 0", ssl);
9353         return 0;
9354     }
9355 
9356     if (rbio == nullptr || wbio == nullptr) {
9357         jniThrowNullPointerException(env, "rbio == null || wbio == null");
9358         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio => rbio == null || wbio == NULL", ssl);
9359         return 0;
9360     }
9361 
9362     AppData* appData = toAppData(ssl);
9363     if (appData == nullptr) {
9364         throwSSLExceptionStr(env, "Unable to retrieve application data");
9365         safeSslClear(ssl);
9366         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
9367         return 0;
9368     }
9369 
9370     UniqueMutex appDataLock(&appData->mutex);
9371 
9372     if (!client_mode && alpnProtocols != nullptr) {
9373         SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, nullptr);
9374     }
9375 
9376     int ret = 0;
9377     errno = 0;
9378 
9379     if (!appData->setCallbackState(env, shc, nullptr, npnProtocols, alpnProtocols)) {
9380         freeOpenSslErrorState();
9381         safeSslClear(ssl);
9382         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio setCallbackState => 0", ssl);
9383         return 0;
9384     }
9385 
9386     ScopedSslBio sslBio(ssl, rbio, wbio);
9387 
9388     ret = SSL_do_handshake(ssl);
9389     appData->clearCallbackState();
9390     // cert_verify_callback threw exception
9391     if (env->ExceptionCheck()) {
9392         freeOpenSslErrorState();
9393         safeSslClear(ssl);
9394         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio exception => 0", ssl);
9395         return 0;
9396     }
9397 
9398     if (ret <= 0) { // error. See SSL_do_handshake(3SSL) man page.
9399         // error case
9400         OpenSslError sslError(ssl, ret);
9401         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio ret=%d errno=%d sslError=%d",
9402                   ssl, ret, errno, sslError.get());
9403 
9404         /*
9405          * If SSL_do_handshake doesn't succeed due to the socket being
9406          * either unreadable or unwritable, we need to exit to allow
9407          * the SSLEngine code to wrap or unwrap.
9408          */
9409         if (sslError.get() == SSL_ERROR_NONE ||
9410                 (sslError.get() == SSL_ERROR_SYSCALL && errno == 0) ||
9411                 (sslError.get() == SSL_ERROR_ZERO_RETURN)) {
9412             throwSSLHandshakeExceptionStr(env, "Connection closed by peer");
9413             safeSslClear(ssl);
9414         } else if (sslError.get() != SSL_ERROR_WANT_READ &&
9415                 sslError.get() != SSL_ERROR_WANT_WRITE) {
9416             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
9417                     "SSL handshake terminated", throwSSLHandshakeExceptionStr);
9418             safeSslClear(ssl);
9419         }
9420         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio error => 0", ssl);
9421         return 0;
9422     }
9423 
9424     // success. handshake completed
9425     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
9426     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake_bio => ssl_session=%p", ssl, ssl_session);
9427 #ifdef WITH_JNI_TRACE_KEYS
9428     debug_print_session_key(ssl_session);
9429 #endif
9430     return reinterpret_cast<uintptr_t>(ssl_session);
9431 }
9432 
9433 /**
9434  * Perform SSL handshake
9435  */
9436 static jlong NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
9437         jobject shc, jint timeout_millis, jboolean client_mode, jbyteArray npnProtocols,
9438         jbyteArray alpnProtocols) {
9439     SSL* ssl = to_SSL(env, ssl_address, true);
9440     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p",
9441               ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols);
9442     if (ssl == nullptr) {
9443         return 0;
9444     }
9445     if (fdObject == nullptr) {
9446         jniThrowNullPointerException(env, "fd == null");
9447         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl);
9448         return 0;
9449     }
9450     if (shc == nullptr) {
9451         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
9452         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl);
9453         return 0;
9454     }
9455 
9456     NetFd fd(env, fdObject);
9457     if (fd.isClosed()) {
9458         // SocketException thrown by NetFd.isClosed
9459         safeSslClear(ssl);
9460         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl);
9461         return 0;
9462     }
9463 
9464     int ret = SSL_set_fd(ssl, fd.get());
9465     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get());
9466 
9467     if (ret != 1) {
9468         throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE,
9469                                        "Error setting the file descriptor");
9470         safeSslClear(ssl);
9471         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl);
9472         return 0;
9473     }
9474 
9475     /*
9476      * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang
9477      * forever and we can use select() to find out if the socket is ready.
9478      */
9479     if (!setBlocking(fd.get(), false)) {
9480         throwSSLExceptionStr(env, "Unable to make socket non blocking");
9481         safeSslClear(ssl);
9482         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl);
9483         return 0;
9484     }
9485 
9486     AppData* appData = toAppData(ssl);
9487     if (appData == nullptr) {
9488         throwSSLExceptionStr(env, "Unable to retrieve application data");
9489         safeSslClear(ssl);
9490         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl);
9491         return 0;
9492     }
9493 
9494     if (client_mode) {
9495         SSL_set_connect_state(ssl);
9496     } else {
9497         SSL_set_accept_state(ssl);
9498         if (alpnProtocols != nullptr) {
9499             SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, nullptr);
9500         }
9501     }
9502 
9503     ret = 0;
9504     OpenSslError sslError;
9505     while (appData->aliveAndKicking) {
9506         errno = 0;
9507 
9508         if (!appData->setCallbackState(env, shc, fdObject, npnProtocols, alpnProtocols)) {
9509             // SocketException thrown by NetFd.isClosed
9510             safeSslClear(ssl);
9511             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl);
9512             return 0;
9513         }
9514         ret = SSL_do_handshake(ssl);
9515         appData->clearCallbackState();
9516         // cert_verify_callback threw exception
9517         if (env->ExceptionCheck()) {
9518             freeOpenSslErrorState();
9519             safeSslClear(ssl);
9520             JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl);
9521             return 0;
9522         }
9523         // success case
9524         if (ret == 1) {
9525             break;
9526         }
9527         // retry case
9528         if (errno == EINTR) {
9529             continue;
9530         }
9531         // error case
9532         sslError.reset(ssl, ret);
9533         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d",
9534                   ssl, ret, errno, sslError.get(), timeout_millis);
9535 
9536         /*
9537          * If SSL_do_handshake doesn't succeed due to the socket being
9538          * either unreadable or unwritable, we use sslSelect to
9539          * wait for it to become ready. If that doesn't happen
9540          * before the specified timeout or an error occurs, we
9541          * cancel the handshake. Otherwise we try the SSL_connect
9542          * again.
9543          */
9544         if (sslError.get() == SSL_ERROR_WANT_READ || sslError.get() == SSL_ERROR_WANT_WRITE) {
9545             appData->waitingThreads++;
9546             int selectResult = sslSelect(env, sslError.get(), fdObject, appData, timeout_millis);
9547 
9548             if (selectResult == THROWN_EXCEPTION) {
9549                 // SocketException thrown by NetFd.isClosed
9550                 safeSslClear(ssl);
9551                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl);
9552                 return 0;
9553             }
9554             if (selectResult == -1) {
9555                 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error",
9556                         throwSSLHandshakeExceptionStr);
9557                 safeSslClear(ssl);
9558                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl);
9559                 return 0;
9560             }
9561             if (selectResult == 0) {
9562                 throwSocketTimeoutException(env, "SSL handshake timed out");
9563                 freeOpenSslErrorState();
9564                 safeSslClear(ssl);
9565                 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl);
9566                 return 0;
9567             }
9568         } else {
9569             // ALOGE("Unknown error %d during handshake", error);
9570             break;
9571         }
9572     }
9573 
9574     // clean error. See SSL_do_handshake(3SSL) man page.
9575     if (ret == 0) {
9576         /*
9577          * The other side closed the socket before the handshake could be
9578          * completed, but everything is within the bounds of the TLS protocol.
9579          * We still might want to find out the real reason of the failure.
9580          */
9581         if (sslError.get() == SSL_ERROR_NONE ||
9582                 (sslError.get() == SSL_ERROR_SYSCALL && errno == 0) ||
9583                 (sslError.get() == SSL_ERROR_ZERO_RETURN)) {
9584             throwSSLHandshakeExceptionStr(env, "Connection closed by peer");
9585         } else {
9586             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
9587                     "SSL handshake terminated", throwSSLHandshakeExceptionStr);
9588         }
9589         safeSslClear(ssl);
9590         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl);
9591         return 0;
9592     }
9593 
9594     // unclean error. See SSL_do_handshake(3SSL) man page.
9595     if (ret < 0) {
9596         /*
9597          * Translate the error and throw exception. We are sure it is an error
9598          * at this point.
9599          */
9600         throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "SSL handshake aborted",
9601                 throwSSLHandshakeExceptionStr);
9602         safeSslClear(ssl);
9603         JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl);
9604         return 0;
9605     }
9606     SSL_SESSION* ssl_session = SSL_get1_session(ssl);
9607     JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session);
9608 #ifdef WITH_JNI_TRACE_KEYS
9609     debug_print_session_key(ssl_session);
9610 #endif
9611     return (jlong) ssl_session;
9612 }
9613 
9614 /**
9615  * Perform SSL renegotiation
9616  */
9617 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jlong ssl_address)
9618 {
9619     SSL* ssl = to_SSL(env, ssl_address, true);
9620     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl);
9621     if (ssl == nullptr) {
9622         return;
9623     }
9624     int result = SSL_renegotiate(ssl);
9625     if (result != 1) {
9626         throwSSLExceptionStr(env, "Problem with SSL_renegotiate");
9627         return;
9628     }
9629     // first call asks client to perform renegotiation
9630     int ret = SSL_do_handshake(ssl);
9631     if (ret != 1) {
9632         OpenSslError sslError(ssl, ret);
9633         throwSSLExceptionWithSslErrors(env, ssl, sslError.release(),
9634                                        "Problem with SSL_do_handshake after SSL_renegotiate");
9635         return;
9636     }
9637     // if client agrees, set ssl state and perform renegotiation
9638     SSL_set_state(ssl, SSL_ST_ACCEPT);
9639     SSL_do_handshake(ssl);
9640     JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl);
9641 }
9642 
9643 /**
9644  * public static native byte[][] SSL_get_certificate(long ssl);
9645  */
9646 static jlongArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jlong ssl_address)
9647 {
9648     SSL* ssl = to_SSL(env, ssl_address, true);
9649     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl);
9650     if (ssl == nullptr) {
9651         return nullptr;
9652     }
9653     X509* certificate = SSL_get_certificate(ssl);
9654     if (certificate == nullptr) {
9655         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
9656         // SSL_get_certificate can return NULL during an error as well.
9657         freeOpenSslErrorState();
9658         return nullptr;
9659     }
9660 
9661     Unique_sk_X509 chain(sk_X509_new_null());
9662     if (chain.get() == nullptr) {
9663         jniThrowOutOfMemory(env, "Unable to allocate local certificate chain");
9664         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl);
9665         return nullptr;
9666     }
9667     if (!sk_X509_push(chain.get(), X509_dup_nocopy(certificate))) {
9668         jniThrowOutOfMemory(env, "Unable to push local certificate");
9669         JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
9670         return nullptr;
9671     }
9672 
9673 #if !defined(OPENSSL_IS_BORINGSSL)
9674     STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate);
9675     for (int i=0; i<sk_X509_num(cert_chain); i++) {
9676         if (!sk_X509_push(chain.get(), X509_dup_nocopy(sk_X509_value(cert_chain, i)))) {
9677             jniThrowOutOfMemory(env, "Unable to push local certificate chain");
9678             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
9679             return NULL;
9680         }
9681     }
9682 #else
9683     STACK_OF(X509)* cert_chain = nullptr;
9684     if (!SSL_get0_chain_certs(ssl, &cert_chain)) {
9685         JNI_TRACE("ssl=%p NativeCrypto_SSL_get0_chain_certs => NULL", ssl);
9686         freeOpenSslErrorState();
9687         return nullptr;
9688     }
9689 
9690     for (size_t i=0; i<sk_X509_num(cert_chain); i++) {
9691         if (!sk_X509_push(chain.get(), X509_dup_nocopy(sk_X509_value(cert_chain, i)))) {
9692             jniThrowOutOfMemory(env, "Unable to push local certificate chain");
9693             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl);
9694             return nullptr;
9695         }
9696     }
9697 #endif
9698 
9699     jlongArray refArray = getCertificateRefs(env, chain.get());
9700     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, refArray);
9701     return refArray;
9702 }
9703 
9704 #if !defined(OPENSSL_IS_BORINGSSL)
9705 // Compatibility shim for SSL_is_server, available in BoringSSL (and OpenSSL 1.0.2).
9706 static int SSL_is_server(SSL* ssl)
9707 {
9708     return ssl->server;
9709 }
9710 #endif
9711 
9712 // Fills a long[] with the peer certificates in the chain.
9713 static jlongArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jlong ssl_address)
9714 {
9715     SSL* ssl = to_SSL(env, ssl_address, true);
9716     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl);
9717     if (ssl == nullptr) {
9718         return nullptr;
9719     }
9720     STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl);
9721     Unique_sk_X509 chain_copy(nullptr);
9722     if (SSL_is_server(ssl)) {
9723         X509* x509 = SSL_get_peer_certificate(ssl);
9724         if (x509 == nullptr) {
9725             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl);
9726             return nullptr;
9727         }
9728         chain_copy.reset(sk_X509_new_null());
9729         if (chain_copy.get() == nullptr) {
9730             jniThrowOutOfMemory(env, "Unable to allocate peer certificate chain");
9731             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl);
9732             return nullptr;
9733         }
9734         size_t chain_size = sk_X509_num(chain);
9735         for (size_t i = 0; i < chain_size; i++) {
9736             if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(sk_X509_value(chain, i)))) {
9737                 jniThrowOutOfMemory(env, "Unable to push server's peer certificate chain");
9738                 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate chain push error", ssl);
9739                 return nullptr;
9740             }
9741         }
9742         if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(x509))) {
9743             jniThrowOutOfMemory(env, "Unable to push server's peer certificate");
9744             JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl);
9745             return nullptr;
9746         }
9747         chain = chain_copy.get();
9748     }
9749     jlongArray refArray = getCertificateRefs(env, chain);
9750     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, refArray);
9751     return refArray;
9752 }
9753 
9754 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len,
9755                    OpenSslError& sslError, int read_timeout_millis) {
9756     JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len);
9757 
9758     if (len == 0) {
9759         // Don't bother doing anything in this case.
9760         return 0;
9761     }
9762 
9763     BIO* rbio = SSL_get_rbio(ssl);
9764     BIO* wbio = SSL_get_wbio(ssl);
9765 
9766     AppData* appData = toAppData(ssl);
9767     JNI_TRACE("ssl=%p sslRead appData=%p", ssl, appData);
9768     if (appData == nullptr) {
9769         return THROW_SSLEXCEPTION;
9770     }
9771 
9772     while (appData->aliveAndKicking) {
9773         errno = 0;
9774 
9775         UniqueMutex appDataLock(&appData->mutex);
9776 
9777         if (!SSL_is_init_finished(ssl) && !SSL_cutthrough_complete(ssl) &&
9778                !SSL_renegotiate_pending(ssl)) {
9779             JNI_TRACE("ssl=%p sslRead => init is not finished (state=0x%x)", ssl,
9780                     SSL_get_state(ssl));
9781             return THROW_SSLEXCEPTION;
9782         }
9783 
9784         unsigned int bytesMoved = BIO_number_read(rbio) + BIO_number_written(wbio);
9785 
9786         if (!appData->setCallbackState(env, shc, fdObject, nullptr, nullptr)) {
9787             return THROWN_EXCEPTION;
9788         }
9789         int result = SSL_read(ssl, buf, len);
9790         appData->clearCallbackState();
9791         // callbacks can happen if server requests renegotiation
9792         if (env->ExceptionCheck()) {
9793             safeSslClear(ssl);
9794             JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl);
9795             return THROWN_EXCEPTION;
9796         }
9797         sslError.reset(ssl, result);
9798         JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError.get());
9799 #ifdef WITH_JNI_TRACE_DATA
9800         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
9801             int n = result - i;
9802             if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
9803                 n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
9804             }
9805             JNI_TRACE("ssl=%p sslRead data: %d:\n%.*s", ssl, n, n, buf+i);
9806         }
9807 #endif
9808 
9809         // If we have been successful in moving data around, check whether it
9810         // might make sense to wake up other blocked threads, so they can give
9811         // it a try, too.
9812         if (BIO_number_read(rbio) + BIO_number_written(wbio) != bytesMoved
9813                 && appData->waitingThreads > 0) {
9814             sslNotify(appData);
9815         }
9816 
9817         // If we are blocked by the underlying socket, tell the world that
9818         // there will be one more waiting thread now.
9819         if (sslError.get() == SSL_ERROR_WANT_READ || sslError.get() == SSL_ERROR_WANT_WRITE) {
9820             appData->waitingThreads++;
9821         }
9822 
9823         appDataLock.unlock();
9824 
9825         switch (sslError.get()) {
9826             // Successfully read at least one byte.
9827             case SSL_ERROR_NONE: {
9828                 return result;
9829             }
9830 
9831             // Read zero bytes. End of stream reached.
9832             case SSL_ERROR_ZERO_RETURN: {
9833                 return -1;
9834             }
9835 
9836             // Need to wait for availability of underlying layer, then retry.
9837             case SSL_ERROR_WANT_READ:
9838             case SSL_ERROR_WANT_WRITE: {
9839                 int selectResult = sslSelect(env, sslError.get(), fdObject, appData, read_timeout_millis);
9840                 if (selectResult == THROWN_EXCEPTION) {
9841                     return THROWN_EXCEPTION;
9842                 }
9843                 if (selectResult == -1) {
9844                     return THROW_SSLEXCEPTION;
9845                 }
9846                 if (selectResult == 0) {
9847                     return THROW_SOCKETTIMEOUTEXCEPTION;
9848                 }
9849 
9850                 break;
9851             }
9852 
9853             // A problem occurred during a system call, but this is not
9854             // necessarily an error.
9855             case SSL_ERROR_SYSCALL: {
9856                 // Connection closed without proper shutdown. Tell caller we
9857                 // have reached end-of-stream.
9858                 if (result == 0) {
9859                     return -1;
9860                 }
9861 
9862                 // System call has been interrupted. Simply retry.
9863                 if (errno == EINTR) {
9864                     break;
9865                 }
9866 
9867                 // Note that for all other system call errors we fall through
9868                 // to the default case, which results in an Exception.
9869                 FALLTHROUGH_INTENDED;
9870             }
9871 
9872             // Everything else is basically an error.
9873             default: {
9874                 return THROW_SSLEXCEPTION;
9875             }
9876         }
9877     }
9878 
9879     return -1;
9880 }
9881 
9882 static jint NativeCrypto_SSL_read_BIO(JNIEnv* env, jclass, jlong sslRef, jbyteArray destJava,
9883         jint destOffset, jint destLength, jlong sourceBioRef, jlong sinkBioRef, jobject shc) {
9884     SSL* ssl = to_SSL(env, sslRef, true);
9885     BIO* rbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sourceBioRef));
9886     BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sinkBioRef));
9887     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO dest=%p sourceBio=%p sinkBio=%p shc=%p",
9888               ssl, destJava, rbio, wbio, shc);
9889     if (ssl == nullptr) {
9890         return 0;
9891     }
9892     if (rbio == nullptr || wbio == nullptr) {
9893         jniThrowNullPointerException(env, "rbio == null || wbio == null");
9894         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => rbio == null || wbio == null", ssl);
9895         return -1;
9896     }
9897     if (shc == nullptr) {
9898         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
9899         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => sslHandshakeCallbacks == null", ssl);
9900         return -1;
9901     }
9902 
9903     ScopedByteArrayRW dest(env, destJava);
9904     if (dest.get() == nullptr) {
9905         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => threw exception", ssl);
9906         return -1;
9907     }
9908     if (ARRAY_OFFSET_LENGTH_INVALID(dest, destOffset, destLength)) {
9909         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => destOffset=%d, destLength=%d, size=%zd",
9910                   ssl, destOffset, destLength, dest.size());
9911         jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", nullptr);
9912         return -1;
9913     }
9914 
9915     AppData* appData = toAppData(ssl);
9916     if (appData == nullptr) {
9917         throwSSLExceptionStr(env, "Unable to retrieve application data");
9918         safeSslClear(ssl);
9919         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => appData == NULL", ssl);
9920         return -1;
9921     }
9922 
9923     errno = 0;
9924 
9925     UniqueMutex appDataLock(&appData->mutex);
9926 
9927     if (!appData->setCallbackState(env, shc, nullptr, nullptr, nullptr)) {
9928         throwSSLExceptionStr(env, "Unable to set callback state");
9929         safeSslClear(ssl);
9930         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => set callback state failed", ssl);
9931         return -1;
9932     }
9933 
9934     ScopedSslBio sslBio(ssl, rbio, wbio);
9935 
9936     int result = SSL_read(ssl, dest.get() + destOffset, destLength);
9937     appData->clearCallbackState();
9938     // callbacks can happen if server requests renegotiation
9939     if (env->ExceptionCheck()) {
9940         safeSslClear(ssl);
9941         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => threw exception", ssl);
9942         return THROWN_EXCEPTION;
9943     }
9944     OpenSslError sslError(ssl, result);
9945     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO SSL_read result=%d sslError=%d", ssl, result,
9946               sslError.get());
9947 #ifdef WITH_JNI_TRACE_DATA
9948     for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
9949         int n = result - i;
9950         if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
9951             n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
9952         }
9953         JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO data: %d:\n%.*s", ssl, n, n, dest.get() + i);
9954     }
9955 #endif
9956 
9957     switch (sslError.get()) {
9958         // Successfully read at least one byte.
9959         case SSL_ERROR_NONE:
9960             break;
9961 
9962         // Read zero bytes. End of stream reached.
9963         case SSL_ERROR_ZERO_RETURN:
9964             result = -1;
9965             break;
9966 
9967         // Need to wait for availability of underlying layer, then retry.
9968         case SSL_ERROR_WANT_READ:
9969         case SSL_ERROR_WANT_WRITE:
9970             result = 0;
9971             break;
9972 
9973         // A problem occurred during a system call, but this is not
9974         // necessarily an error.
9975         case SSL_ERROR_SYSCALL: {
9976             // Connection closed without proper shutdown. Tell caller we
9977             // have reached end-of-stream.
9978             if (result == 0) {
9979                 result = -1;
9980                 break;
9981             } else if (errno == EINTR) {
9982                 // System call has been interrupted. Simply retry.
9983                 result = 0;
9984                 break;
9985             }
9986 
9987             // Note that for all other system call errors we fall through
9988             // to the default case, which results in an Exception.
9989             FALLTHROUGH_INTENDED;
9990         }
9991 
9992         // Everything else is basically an error.
9993         default: {
9994             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Read error");
9995             return -1;
9996         }
9997     }
9998     JNI_TRACE("ssl=%p NativeCrypto_SSL_read_BIO => %d", ssl, result);
9999     return result;
10000 }
10001 
10002 /**
10003  * OpenSSL read function (2): read into buffer at offset n chunks.
10004  * Returns 1 (success) or value <= 0 (failure).
10005  */
10006 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
10007                                   jobject shc, jbyteArray b, jint offset, jint len,
10008                                   jint read_timeout_millis)
10009 {
10010     SSL* ssl = to_SSL(env, ssl_address, true);
10011     JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d read_timeout_millis=%d",
10012               ssl, fdObject, shc, b, offset, len, read_timeout_millis);
10013     if (ssl == nullptr) {
10014         return 0;
10015     }
10016     if (fdObject == nullptr) {
10017         jniThrowNullPointerException(env, "fd == null");
10018         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl);
10019         return 0;
10020     }
10021     if (shc == nullptr) {
10022         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
10023         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl);
10024         return 0;
10025     }
10026 
10027     ScopedByteArrayRW bytes(env, b);
10028     if (bytes.get() == nullptr) {
10029         JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl);
10030         return 0;
10031     }
10032 
10033     OpenSslError sslError;
10034     int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len,
10035                       sslError, read_timeout_millis);
10036 
10037     int result;
10038     switch (ret) {
10039         case THROW_SSLEXCEPTION:
10040             // See sslRead() regarding improper failure to handle normal cases.
10041             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Read error");
10042             result = -1;
10043             break;
10044         case THROW_SOCKETTIMEOUTEXCEPTION:
10045             throwSocketTimeoutException(env, "Read timed out");
10046             result = -1;
10047             break;
10048         case THROWN_EXCEPTION:
10049             // SocketException thrown by NetFd.isClosed
10050             // or RuntimeException thrown by callback
10051             result = -1;
10052             break;
10053         default:
10054             result = ret;
10055             break;
10056     }
10057 
10058     JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result);
10059     return result;
10060 }
10061 
10062 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len,
10063                     OpenSslError& sslError, int write_timeout_millis) {
10064     JNI_TRACE("ssl=%p sslWrite buf=%p len=%d write_timeout_millis=%d",
10065               ssl, buf, len, write_timeout_millis);
10066 
10067     if (len == 0) {
10068         // Don't bother doing anything in this case.
10069         return 0;
10070     }
10071 
10072     BIO* rbio = SSL_get_rbio(ssl);
10073     BIO* wbio = SSL_get_wbio(ssl);
10074 
10075     AppData* appData = toAppData(ssl);
10076     JNI_TRACE("ssl=%p sslWrite appData=%p", ssl, appData);
10077     if (appData == nullptr) {
10078         return THROW_SSLEXCEPTION;
10079     }
10080 
10081     int count = len;
10082 
10083     while (appData->aliveAndKicking && len > 0) {
10084         errno = 0;
10085 
10086         UniqueMutex appDataLock(&appData->mutex);
10087 
10088         if (!SSL_is_init_finished(ssl) && !SSL_cutthrough_complete(ssl) &&
10089                !SSL_renegotiate_pending(ssl)) {
10090             JNI_TRACE("ssl=%p sslWrite => init is not finished (state=0x%x)", ssl,
10091                     SSL_get_state(ssl));
10092             return THROW_SSLEXCEPTION;
10093         }
10094 
10095         unsigned int bytesMoved = BIO_number_read(rbio) + BIO_number_written(wbio);
10096 
10097         if (!appData->setCallbackState(env, shc, fdObject, nullptr, nullptr)) {
10098             return THROWN_EXCEPTION;
10099         }
10100         JNI_TRACE("ssl=%p sslWrite SSL_write len=%d", ssl, len);
10101         int result = SSL_write(ssl, buf, len);
10102         appData->clearCallbackState();
10103         // callbacks can happen if server requests renegotiation
10104         if (env->ExceptionCheck()) {
10105             safeSslClear(ssl);
10106             JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl);
10107             return THROWN_EXCEPTION;
10108         }
10109         sslError.reset(ssl, result);
10110         JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d",
10111                   ssl, result, sslError.get());
10112 #ifdef WITH_JNI_TRACE_DATA
10113         for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
10114             int n = result - i;
10115             if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
10116                 n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
10117             }
10118             JNI_TRACE("ssl=%p sslWrite data: %d:\n%.*s", ssl, n, n, buf+i);
10119         }
10120 #endif
10121 
10122         // If we have been successful in moving data around, check whether it
10123         // might make sense to wake up other blocked threads, so they can give
10124         // it a try, too.
10125         if (BIO_number_read(rbio) + BIO_number_written(wbio) != bytesMoved
10126                 && appData->waitingThreads > 0) {
10127             sslNotify(appData);
10128         }
10129 
10130         // If we are blocked by the underlying socket, tell the world that
10131         // there will be one more waiting thread now.
10132         if (sslError.get() == SSL_ERROR_WANT_READ || sslError.get() == SSL_ERROR_WANT_WRITE) {
10133             appData->waitingThreads++;
10134         }
10135 
10136         appDataLock.unlock();
10137 
10138         switch (sslError.get()) {
10139             // Successfully wrote at least one byte.
10140             case SSL_ERROR_NONE: {
10141                 buf += result;
10142                 len -= result;
10143                 break;
10144             }
10145 
10146             // Wrote zero bytes. End of stream reached.
10147             case SSL_ERROR_ZERO_RETURN: {
10148                 return -1;
10149             }
10150 
10151             // Need to wait for availability of underlying layer, then retry.
10152             // The concept of a write timeout doesn't really make sense, and
10153             // it's also not standard Java behavior, so we wait forever here.
10154             case SSL_ERROR_WANT_READ:
10155             case SSL_ERROR_WANT_WRITE: {
10156                 int selectResult = sslSelect(env, sslError.get(), fdObject, appData,
10157                                              write_timeout_millis);
10158                 if (selectResult == THROWN_EXCEPTION) {
10159                     return THROWN_EXCEPTION;
10160                 }
10161                 if (selectResult == -1) {
10162                     return THROW_SSLEXCEPTION;
10163                 }
10164                 if (selectResult == 0) {
10165                     return THROW_SOCKETTIMEOUTEXCEPTION;
10166                 }
10167 
10168                 break;
10169             }
10170 
10171             // A problem occurred during a system call, but this is not
10172             // necessarily an error.
10173             case SSL_ERROR_SYSCALL: {
10174                 // Connection closed without proper shutdown. Tell caller we
10175                 // have reached end-of-stream.
10176                 if (result == 0) {
10177                     return -1;
10178                 }
10179 
10180                 // System call has been interrupted. Simply retry.
10181                 if (errno == EINTR) {
10182                     break;
10183                 }
10184 
10185                 // Note that for all other system call errors we fall through
10186                 // to the default case, which results in an Exception.
10187                 FALLTHROUGH_INTENDED;
10188             }
10189 
10190             // Everything else is basically an error.
10191             default: {
10192                 return THROW_SSLEXCEPTION;
10193             }
10194         }
10195     }
10196     JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count);
10197 
10198     return count;
10199 }
10200 
10201 /**
10202  * OpenSSL write function (2): write into buffer at offset n chunks.
10203  */
10204 static int NativeCrypto_SSL_write_BIO(JNIEnv* env, jclass, jlong sslRef, jbyteArray sourceJava, jint len,
10205         jlong sinkBioRef, jobject shc) {
10206     SSL* ssl = to_SSL(env, sslRef, true);
10207     BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(sinkBioRef));
10208     JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO source=%p len=%d wbio=%p shc=%p",
10209               ssl, sourceJava, len, wbio, shc);
10210     if (ssl == nullptr) {
10211         return -1;
10212     }
10213     if (wbio == nullptr) {
10214         jniThrowNullPointerException(env, "wbio == null");
10215         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => wbio == null", ssl);
10216         return -1;
10217     }
10218     if (shc == nullptr) {
10219         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
10220         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => sslHandshakeCallbacks == null", ssl);
10221         return -1;
10222     }
10223 
10224     AppData* appData = toAppData(ssl);
10225     if (appData == nullptr) {
10226         throwSSLExceptionStr(env, "Unable to retrieve application data");
10227         safeSslClear(ssl);
10228         freeOpenSslErrorState();
10229         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO appData => NULL", ssl);
10230         return -1;
10231     }
10232 
10233     errno = 0;
10234 
10235     UniqueMutex appDataLock(&appData->mutex);
10236 
10237     if (!appData->setCallbackState(env, shc, nullptr, nullptr, nullptr)) {
10238         throwSSLExceptionStr(env, "Unable to set appdata callback");
10239         freeOpenSslErrorState();
10240         safeSslClear(ssl);
10241         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => appData can't set callback", ssl);
10242         return -1;
10243     }
10244 
10245     ScopedByteArrayRO source(env, sourceJava);
10246     if (source.get() == nullptr) {
10247         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO => threw exception", ssl);
10248         return -1;
10249     }
10250 
10251 #if defined(OPENSSL_IS_BORINGSSL)
10252     Unique_BIO nullBio(BIO_new_mem_buf(nullptr, 0));
10253 #else
10254     Unique_BIO nullBio(BIO_new(BIO_s_null()));
10255 #endif
10256     ScopedSslBio sslBio(ssl, nullBio.get(), wbio);
10257 
10258     int result = SSL_write(ssl, reinterpret_cast<const char*>(source.get()), len);
10259     appData->clearCallbackState();
10260     // callbacks can happen if server requests renegotiation
10261     if (env->ExceptionCheck()) {
10262         freeOpenSslErrorState();
10263         safeSslClear(ssl);
10264         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO exception => exception pending (reneg)", ssl);
10265         return -1;
10266     }
10267     OpenSslError sslError(ssl, result);
10268     JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO SSL_write result=%d sslError=%d",
10269               ssl, result, sslError.get());
10270 #ifdef WITH_JNI_TRACE_DATA
10271     for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
10272         int n = result - i;
10273         if (n > WITH_JNI_TRACE_DATA_CHUNK_SIZE) {
10274             n = WITH_JNI_TRACE_DATA_CHUNK_SIZE;
10275         }
10276         JNI_TRACE("ssl=%p NativeCrypto_SSL_write_BIO data: %d:\n%.*s", ssl, n, n, source.get() + i);
10277     }
10278 #endif
10279 
10280     switch (sslError.get()) {
10281         case SSL_ERROR_NONE:
10282             return result;
10283 
10284         // Wrote zero bytes. End of stream reached.
10285         case SSL_ERROR_ZERO_RETURN:
10286             return -1;
10287 
10288         case SSL_ERROR_WANT_READ:
10289         case SSL_ERROR_WANT_WRITE:
10290             return 0;
10291 
10292         case SSL_ERROR_SYSCALL: {
10293             // Connection closed without proper shutdown. Tell caller we
10294             // have reached end-of-stream.
10295             if (result == 0) {
10296                 return -1;
10297             }
10298 
10299             // System call has been interrupted. Simply retry.
10300             if (errno == EINTR) {
10301                 return 0;
10302             }
10303 
10304             // Note that for all other system call errors we fall through
10305             // to the default case, which results in an Exception.
10306             FALLTHROUGH_INTENDED;
10307         }
10308 
10309         // Everything else is basically an error.
10310         default: {
10311             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Write error");
10312             break;
10313         }
10314     }
10315     return -1;
10316 }
10317 
10318 /**
10319  * OpenSSL write function (2): write into buffer at offset n chunks.
10320  */
10321 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject,
10322                                    jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis)
10323 {
10324     SSL* ssl = to_SSL(env, ssl_address, true);
10325     JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d write_timeout_millis=%d",
10326               ssl, fdObject, shc, b, offset, len, write_timeout_millis);
10327     if (ssl == nullptr) {
10328         return;
10329     }
10330     if (fdObject == nullptr) {
10331         jniThrowNullPointerException(env, "fd == null");
10332         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl);
10333         return;
10334     }
10335     if (shc == nullptr) {
10336         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
10337         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl);
10338         return;
10339     }
10340 
10341     ScopedByteArrayRO bytes(env, b);
10342     if (bytes.get() == nullptr) {
10343         JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl);
10344         return;
10345     }
10346     OpenSslError sslError;
10347     int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset),
10348                        len, sslError, write_timeout_millis);
10349 
10350     switch (ret) {
10351         case THROW_SSLEXCEPTION:
10352             // See sslWrite() regarding improper failure to handle normal cases.
10353             throwSSLExceptionWithSslErrors(env, ssl, sslError.release(), "Write error");
10354             break;
10355         case THROW_SOCKETTIMEOUTEXCEPTION:
10356             throwSocketTimeoutException(env, "Write timed out");
10357             break;
10358         case THROWN_EXCEPTION:
10359             // SocketException thrown by NetFd.isClosed
10360             break;
10361         default:
10362             break;
10363     }
10364 }
10365 
10366 /**
10367  * Interrupt any pending I/O before closing the socket.
10368  */
10369 static void NativeCrypto_SSL_interrupt(
10370         JNIEnv* env, jclass, jlong ssl_address) {
10371     SSL* ssl = to_SSL(env, ssl_address, false);
10372     JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl);
10373     if (ssl == nullptr) {
10374         return;
10375     }
10376 
10377     /*
10378      * Mark the connection as quasi-dead, then send something to the emergency
10379      * file descriptor, so any blocking select() calls are woken up.
10380      */
10381     AppData* appData = toAppData(ssl);
10382     if (appData != nullptr) {
10383         appData->aliveAndKicking = 0;
10384 
10385         // At most two threads can be waiting.
10386         sslNotify(appData);
10387         sslNotify(appData);
10388     }
10389 }
10390 
10391 /**
10392  * OpenSSL close SSL socket function.
10393  */
10394 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jlong ssl_address,
10395                                       jobject fdObject, jobject shc) {
10396     SSL* ssl = to_SSL(env, ssl_address, false);
10397     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc);
10398     if (ssl == nullptr) {
10399         return;
10400     }
10401     if (fdObject == nullptr) {
10402         jniThrowNullPointerException(env, "fd == null");
10403         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl);
10404         return;
10405     }
10406     if (shc == nullptr) {
10407         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
10408         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
10409         return;
10410     }
10411 
10412     AppData* appData = toAppData(ssl);
10413     if (appData != nullptr) {
10414         if (!appData->setCallbackState(env, shc, fdObject, nullptr, nullptr)) {
10415             // SocketException thrown by NetFd.isClosed
10416             freeOpenSslErrorState();
10417             safeSslClear(ssl);
10418             return;
10419         }
10420 
10421         /*
10422          * Try to make socket blocking again. OpenSSL literature recommends this.
10423          */
10424         int fd = SSL_get_fd(ssl);
10425         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd);
10426         if (fd != -1) {
10427             setBlocking(fd, true);
10428         }
10429 
10430         int ret = SSL_shutdown(ssl);
10431         appData->clearCallbackState();
10432         // callbacks can happen if server requests renegotiation
10433         if (env->ExceptionCheck()) {
10434             safeSslClear(ssl);
10435             JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
10436             return;
10437         }
10438         switch (ret) {
10439             case 0:
10440                 /*
10441                  * Shutdown was not successful (yet), but there also
10442                  * is no error. Since we can't know whether the remote
10443                  * server is actually still there, and we don't want to
10444                  * get stuck forever in a second SSL_shutdown() call, we
10445                  * simply return. This is not security a problem as long
10446                  * as we close the underlying socket, which we actually
10447                  * do, because that's where we are just coming from.
10448                  */
10449                 break;
10450             case 1:
10451                 /*
10452                  * Shutdown was successful. We can safely return. Hooray!
10453                  */
10454                 break;
10455             default:
10456                 /*
10457                  * Everything else is a real error condition. We should
10458                  * let the Java layer know about this by throwing an
10459                  * exception.
10460                  */
10461                 int sslError = SSL_get_error(ssl, ret);
10462                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
10463                 break;
10464         }
10465     }
10466 
10467     freeOpenSslErrorState();
10468     safeSslClear(ssl);
10469 }
10470 
10471 /**
10472  * OpenSSL close SSL socket function.
10473  */
10474 static void NativeCrypto_SSL_shutdown_BIO(JNIEnv* env, jclass, jlong ssl_address, jlong rbioRef,
10475         jlong wbioRef, jobject shc) {
10476     SSL* ssl = to_SSL(env, ssl_address, false);
10477     BIO* rbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(rbioRef));
10478     BIO* wbio = reinterpret_cast<BIO*>(static_cast<uintptr_t>(wbioRef));
10479     JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown rbio=%p wbio=%p shc=%p", ssl, rbio, wbio, shc);
10480     if (ssl == nullptr) {
10481         return;
10482     }
10483     if (rbio == nullptr || wbio == nullptr) {
10484         jniThrowNullPointerException(env, "rbio == null || wbio == null");
10485         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => rbio == null || wbio == null", ssl);
10486         return;
10487     }
10488     if (shc == nullptr) {
10489         jniThrowNullPointerException(env, "sslHandshakeCallbacks == null");
10490         JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl);
10491         return;
10492     }
10493 
10494     AppData* appData = toAppData(ssl);
10495     if (appData != nullptr) {
10496         UniqueMutex appDataLock(&appData->mutex);
10497 
10498         if (!appData->setCallbackState(env, shc, nullptr, nullptr, nullptr)) {
10499             // SocketException thrown by NetFd.isClosed
10500             freeOpenSslErrorState();
10501             safeSslClear(ssl);
10502             return;
10503         }
10504 
10505         ScopedSslBio scopedBio(ssl, rbio, wbio);
10506 
10507         int ret = SSL_shutdown(ssl);
10508         appData->clearCallbackState();
10509         // callbacks can happen if server requests renegotiation
10510         if (env->ExceptionCheck()) {
10511             safeSslClear(ssl);
10512             JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl);
10513             return;
10514         }
10515         switch (ret) {
10516             case 0:
10517                 /*
10518                  * Shutdown was not successful (yet), but there also
10519                  * is no error. Since we can't know whether the remote
10520                  * server is actually still there, and we don't want to
10521                  * get stuck forever in a second SSL_shutdown() call, we
10522                  * simply return. This is not security a problem as long
10523                  * as we close the underlying socket, which we actually
10524                  * do, because that's where we are just coming from.
10525                  */
10526                 break;
10527             case 1:
10528                 /*
10529                  * Shutdown was successful. We can safely return. Hooray!
10530                  */
10531                 break;
10532             default:
10533                 /*
10534                  * Everything else is a real error condition. We should
10535                  * let the Java layer know about this by throwing an
10536                  * exception.
10537                  */
10538                 int sslError = SSL_get_error(ssl, ret);
10539                 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed");
10540                 break;
10541         }
10542     }
10543 
10544     freeOpenSslErrorState();
10545     safeSslClear(ssl);
10546 }
10547 
10548 static jint NativeCrypto_SSL_get_shutdown(JNIEnv* env, jclass, jlong ssl_address) {
10549     const SSL* ssl = to_SSL(env, ssl_address, true);
10550     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_shutdown", ssl);
10551     if (ssl == nullptr) {
10552         jniThrowNullPointerException(env, "ssl == null");
10553         return 0;
10554     }
10555 
10556     int status = SSL_get_shutdown(ssl);
10557     JNI_TRACE("ssl=%p NativeCrypto_SSL_get_shutdown => %d", ssl, status);
10558     return static_cast<jint>(status);
10559 }
10560 
10561 /**
10562  * public static native void SSL_free(long ssl);
10563  */
10564 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jlong ssl_address)
10565 {
10566     SSL* ssl = to_SSL(env, ssl_address, true);
10567     JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl);
10568     if (ssl == nullptr) {
10569         return;
10570     }
10571 
10572     AppData* appData = toAppData(ssl);
10573     SSL_set_app_data(ssl, nullptr);
10574     delete appData;
10575     SSL_free(ssl);
10576 }
10577 
10578 /**
10579  * Gets and returns in a byte array the ID of the actual SSL session.
10580  */
10581 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass,
10582                                                       jlong ssl_session_address) {
10583     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
10584     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session);
10585     if (ssl_session == nullptr) {
10586         return nullptr;
10587     }
10588     jbyteArray result = env->NewByteArray(ssl_session->session_id_length);
10589     if (result != nullptr) {
10590         jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id);
10591         env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src);
10592     }
10593     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d",
10594              ssl_session, result, ssl_session->session_id_length);
10595     return result;
10596 }
10597 
10598 /**
10599  * Gets and returns in a long integer the creation's time of the
10600  * actual SSL session.
10601  */
10602 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jlong ssl_session_address) {
10603     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
10604     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session);
10605     if (ssl_session == nullptr) {
10606         return 0;
10607     }
10608     // result must be jlong, not long or *1000 will overflow
10609     jlong result = SSL_SESSION_get_time(ssl_session);
10610     result *= 1000; // OpenSSL uses seconds, Java uses milliseconds.
10611     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, (long long) result);
10612     return result;
10613 }
10614 
10615 /**
10616  * Gets and returns in a string the version of the SSL protocol. If it
10617  * returns the string "unknown" it means that no connection is established.
10618  */
10619 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jlong ssl_session_address) {
10620     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
10621     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session);
10622     if (ssl_session == nullptr) {
10623         return nullptr;
10624     }
10625     const char* protocol = SSL_SESSION_get_version(ssl_session);
10626     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol);
10627     return env->NewStringUTF(protocol);
10628 }
10629 
10630 /**
10631  * Gets and returns in a string the cipher negotiated for the SSL session.
10632  */
10633 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jlong ssl_session_address) {
10634     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
10635     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session);
10636     if (ssl_session == nullptr) {
10637         return nullptr;
10638     }
10639     const SSL_CIPHER* cipher = ssl_session->cipher;
10640     const char* name = SSL_CIPHER_get_name(cipher);
10641     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name);
10642     return env->NewStringUTF(name);
10643 }
10644 
10645 static jstring NativeCrypto_get_SSL_SESSION_tlsext_hostname(JNIEnv* env, jclass, jlong sessionJava) {
10646     SSL_SESSION* ssl_session = to_SSL_SESSION(env, sessionJava, true);
10647     JNI_TRACE("ssl_session=%p NativeCrypto_get_SSL_SESSION_tlsext_hostname", ssl_session);
10648     if (ssl_session == nullptr || ssl_session->tlsext_hostname == nullptr) {
10649         JNI_TRACE("ssl_session=%p NativeCrypto_get_SSL_SESSION_tlsext_hostname => null",
10650                   ssl_session);
10651         return nullptr;
10652     }
10653     JNI_TRACE("ssl_session=%p NativeCrypto_get_SSL_SESSION_tlsext_hostname => \"%s\"",
10654               ssl_session, ssl_session->tlsext_hostname);
10655     return env->NewStringUTF(ssl_session->tlsext_hostname);
10656 }
10657 
10658 /**
10659  * Frees the SSL session.
10660  */
10661 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jlong ssl_session_address) {
10662     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
10663     JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session);
10664     if (ssl_session == nullptr) {
10665         return;
10666     }
10667     SSL_SESSION_free(ssl_session);
10668 }
10669 
10670 
10671 /**
10672  * Serializes the native state of the session (ID, cipher, and keys but
10673  * not certificates). Returns a byte[] containing the DER-encoded state.
10674  * See apache mod_ssl.
10675  */
10676 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jlong ssl_session_address) {
10677     SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true);
10678     JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session);
10679     if (ssl_session == nullptr) {
10680         return nullptr;
10681     }
10682     return ASN1ToByteArray<SSL_SESSION>(env, ssl_session, i2d_SSL_SESSION);
10683 }
10684 
10685 /**
10686  * Deserialize the session.
10687  */
10688 static jlong NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) {
10689     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes);
10690 
10691     ScopedByteArrayRO bytes(env, javaBytes);
10692     if (bytes.get() == nullptr) {
10693         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception");
10694         return 0;
10695     }
10696     const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get());
10697     SSL_SESSION* ssl_session = d2i_SSL_SESSION(nullptr, &ucp, bytes.size());
10698 
10699 #if !defined(OPENSSL_IS_BORINGSSL)
10700     // Initialize SSL_SESSION cipher field based on cipher_id http://b/7091840
10701     if (ssl_session != NULL) {
10702         // based on ssl_get_prev_session
10703         uint32_t cipher_id_network_order = htonl(ssl_session->cipher_id);
10704         uint8_t* cipher_id_byte_pointer = reinterpret_cast<uint8_t*>(&cipher_id_network_order);
10705         if (ssl_session->ssl_version >= SSL3_VERSION_MAJOR) {
10706             cipher_id_byte_pointer += 2; // skip first two bytes for SSL3+
10707         } else {
10708             cipher_id_byte_pointer += 1; // skip first byte for SSL2
10709         }
10710         ssl_session->cipher = SSLv23_method()->get_cipher_by_char(cipher_id_byte_pointer);
10711         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION cipher_id=%lx hton=%x 0=%x 1=%x cipher=%s",
10712                   ssl_session->cipher_id, cipher_id_network_order,
10713                   cipher_id_byte_pointer[0], cipher_id_byte_pointer[1],
10714                   SSL_CIPHER_get_name(ssl_session->cipher));
10715     }
10716 #endif
10717 
10718     if (ssl_session == nullptr ||
10719         ucp != (reinterpret_cast<const unsigned char*>(bytes.get()) + bytes.size())) {
10720         if (!throwExceptionIfNecessary(env, "d2i_SSL_SESSION", throwIOException)) {
10721             throwIOException(env, "d2i_SSL_SESSION");
10722         }
10723         JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => failure to convert");
10724         return 0L;
10725     }
10726 
10727     JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session);
10728     return reinterpret_cast<uintptr_t>(ssl_session);
10729 }
10730 
10731 static jlong NativeCrypto_ERR_peek_last_error(JNIEnv*, jclass) {
10732     return ERR_peek_last_error();
10733 }
10734 
10735 static jstring NativeCrypto_SSL_CIPHER_get_kx_name(JNIEnv* env, jclass, jlong cipher_address) {
10736     const SSL_CIPHER* cipher = to_SSL_CIPHER(env, cipher_address, true);
10737     const char* kx_name = nullptr;
10738 
10739 #if defined(OPENSSL_IS_BORINGSSL)
10740     kx_name = SSL_CIPHER_get_kx_name(cipher);
10741 #else
10742     kx_name = SSL_CIPHER_authentication_method(cipher);
10743 #endif
10744 
10745     return env->NewStringUTF(kx_name);
10746 }
10747 
10748 static jobjectArray NativeCrypto_get_cipher_names(JNIEnv *env, jclass, jstring selectorJava) {
10749     ScopedUtfChars selector(env, selectorJava);
10750     if (selector.c_str() == nullptr) {
10751         jniThrowException(env, "java/lang/IllegalArgumentException", "selector == NULL");
10752         return nullptr;
10753     }
10754 
10755     JNI_TRACE("NativeCrypto_get_cipher_names %s", selector.c_str());
10756 
10757     Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method()));
10758     Unique_SSL ssl(SSL_new(sslCtx.get()));
10759 
10760     if (!SSL_set_cipher_list(ssl.get(), selector.c_str())) {
10761         jniThrowException(env, "java/lang/IllegalArgumentException", "Unable to set SSL cipher list");
10762         return nullptr;
10763     }
10764     STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl.get());
10765 
10766     size_t size = sk_SSL_CIPHER_num(ciphers);
10767     ScopedLocalRef<jobjectArray> cipherNamesArray(env,
10768                                                   env->NewObjectArray(size, stringClass, nullptr));
10769     if (cipherNamesArray.get() == nullptr) {
10770         return nullptr;
10771     }
10772 
10773     for (size_t i = 0; i < size; i++) {
10774         const char *name = SSL_CIPHER_get_name(sk_SSL_CIPHER_value(ciphers, i));
10775         ScopedLocalRef<jstring> cipherName(env, env->NewStringUTF(name));
10776         env->SetObjectArrayElement(cipherNamesArray.get(), i, cipherName.get());
10777     }
10778 
10779     JNI_TRACE("NativeCrypto_get_cipher_names(%s) => success (%zd entries)", selector.c_str(), size);
10780     return cipherNamesArray.release();
10781 }
10782 
10783 #if defined(OPENSSL_IS_BORINGSSL)
10784 
10785 /**
10786  * Compare the given CertID with a certificate and it's issuer.
10787  * True is returned if the CertID matches.
10788  */
10789 static bool ocsp_cert_id_matches_certificate(CBS *cert_id, X509 *x509, X509 *issuerX509) {
10790     // Get the hash algorithm used by this CertID
10791     CBS hash_algorithm, hash;
10792     if (!CBS_get_asn1(cert_id, &hash_algorithm, CBS_ASN1_SEQUENCE) ||
10793         !CBS_get_asn1(&hash_algorithm, &hash, CBS_ASN1_OBJECT)) {
10794         return false;
10795     }
10796 
10797     // Get the issuer's name hash from the CertID
10798     CBS issuer_name_hash;
10799     if (!CBS_get_asn1(cert_id, &issuer_name_hash, CBS_ASN1_OCTETSTRING)) {
10800         return false;
10801     }
10802 
10803     // Get the issuer's key hash from the CertID
10804     CBS issuer_key_hash;
10805     if (!CBS_get_asn1(cert_id, &issuer_key_hash, CBS_ASN1_OCTETSTRING)) {
10806         return false;
10807     }
10808 
10809     // Get the serial number from the CertID
10810     CBS serial;
10811     if (!CBS_get_asn1(cert_id, &serial, CBS_ASN1_INTEGER)) {
10812         return false;
10813     }
10814 
10815     // Compare the certificate's serial number with the one from the Cert ID
10816     const uint8_t *p = CBS_data(&serial);
10817     Unique_ASN1_INTEGER serial_number(c2i_ASN1_INTEGER(nullptr, &p, CBS_len(&serial)));
10818     ASN1_INTEGER *expected_serial_number = X509_get_serialNumber(x509);
10819     if (serial_number.get() == nullptr ||
10820         ASN1_INTEGER_cmp(expected_serial_number, serial_number.get()) != 0) {
10821         return false;
10822     }
10823 
10824     // Find the hash algorithm to be used
10825     const EVP_MD *digest = EVP_get_digestbynid(OBJ_cbs2nid(&hash));
10826     if (digest == nullptr) {
10827         return false;
10828     }
10829 
10830     // Hash the issuer's name and compare the hash with the one from the Cert ID
10831     uint8_t md[EVP_MAX_MD_SIZE];
10832     X509_NAME *issuer_name = X509_get_subject_name(issuerX509);
10833     if (!X509_NAME_digest(issuer_name, digest, md, nullptr) ||
10834         !CBS_mem_equal(&issuer_name_hash, md, EVP_MD_size(digest))) {
10835         return false;
10836     }
10837 
10838     // Same thing with the issuer's key
10839     ASN1_BIT_STRING *issuer_key = X509_get0_pubkey_bitstr(issuerX509);
10840     if (!EVP_Digest(issuer_key->data, issuer_key->length, md, nullptr, digest, nullptr) ||
10841         !CBS_mem_equal(&issuer_key_hash, md, EVP_MD_size(digest))) {
10842         return false;
10843     }
10844 
10845     return true;
10846 }
10847 
10848 /**
10849  * Get a SingleResponse whose CertID matches the given certificate and issuer from a
10850  * SEQUENCE OF SingleResponse.
10851  *
10852  * If found, |out_single_response| is set to the response, and true is returned. Otherwise if an
10853  * error occured or no response matches the certificate, false is returned and |out_single_response|
10854  * is unchanged.
10855  */
10856 static bool find_ocsp_single_response(CBS* responses, X509 *x509, X509 *issuerX509,
10857                                       CBS *out_single_response) {
10858     // Iterate over all the SingleResponses, until one matches the certificate
10859     while (CBS_len(responses) > 0) {
10860         // Get the next available SingleResponse from the sequence
10861         CBS single_response;
10862         if (!CBS_get_asn1(responses, &single_response, CBS_ASN1_SEQUENCE)) {
10863             return false;
10864         }
10865 
10866         // Make a copy of the stream so we pass it back to the caller
10867         CBS single_response_original = single_response;
10868 
10869         // Get the SingleResponse's CertID
10870         // If this fails ignore the current response and move to the next one
10871         CBS cert_id;
10872         if (!CBS_get_asn1(&single_response, &cert_id, CBS_ASN1_SEQUENCE)) {
10873             continue;
10874         }
10875 
10876         // Compare the CertID with the given certificate and issuer
10877         if (ocsp_cert_id_matches_certificate(&cert_id, x509, issuerX509)) {
10878             *out_single_response = single_response_original;
10879             return true;
10880         }
10881     }
10882 
10883     return false;
10884 }
10885 
10886 /**
10887  * Get the BasicOCSPResponse from an OCSPResponse.
10888  * If parsing succeeds and the response is of type basic, |basic_response| is set to it, and true is
10889  * returned.
10890  */
10891 static bool get_ocsp_basic_response(CBS *ocsp_response, CBS *basic_response) {
10892     CBS tagged_response_bytes, response_bytes, response_type, response;
10893 
10894     // Get the ResponseBytes out of the OCSPResponse
10895     if (!CBS_get_asn1(ocsp_response, nullptr /* responseStatus */, CBS_ASN1_ENUMERATED) ||
10896         !CBS_get_asn1(ocsp_response, &tagged_response_bytes,
10897                       CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
10898         !CBS_get_asn1(&tagged_response_bytes, &response_bytes, CBS_ASN1_SEQUENCE)) {
10899         return false;
10900     }
10901 
10902     // Parse the response type and data out of the ResponseBytes
10903     if (!CBS_get_asn1(&response_bytes, &response_type, CBS_ASN1_OBJECT) ||
10904         !CBS_get_asn1(&response_bytes, &response, CBS_ASN1_OCTETSTRING)) {
10905         return false;
10906     }
10907 
10908     // Only basic OCSP responses are supported
10909     if (OBJ_cbs2nid(&response_type) != NID_id_pkix_OCSP_basic) {
10910         return false;
10911     }
10912 
10913     // Parse the octet string as a BasicOCSPResponse
10914     return CBS_get_asn1(&response, basic_response, CBS_ASN1_SEQUENCE);
10915 }
10916 
10917 /**
10918  * Get the SEQUENCE OF SingleResponse from a BasicOCSPResponse.
10919  * If parsing succeeds, |single_responses| is set to point to the sequence of SingleResponse, and
10920  * true is returned.
10921  */
10922 static bool get_ocsp_single_responses(CBS *basic_response, CBS *single_responses) {
10923     // Parse the ResponseData out of the BasicOCSPResponse. Ignore the rest.
10924     CBS response_data;
10925     if (!CBS_get_asn1(basic_response, &response_data, CBS_ASN1_SEQUENCE)) {
10926         return false;
10927     }
10928 
10929     // Skip the version, responderID and producedAt fields
10930     if (!CBS_get_optional_asn1(&response_data, nullptr /* version */, nullptr,
10931                                CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
10932         !CBS_get_any_asn1_element(&response_data, nullptr /* responderID */, nullptr, nullptr) ||
10933         !CBS_get_any_asn1_element(&response_data, nullptr /* producedAt */, nullptr, nullptr)) {
10934         return false;
10935     }
10936 
10937     // Extract the list of SingleResponse.
10938     return CBS_get_asn1(&response_data, single_responses, CBS_ASN1_SEQUENCE);
10939 }
10940 
10941 /**
10942  * Get the SEQUENCE OF Extension from a SingleResponse.
10943  * If parsing succeeds, |extensions| is set to point the the extension sequence and true is
10944  * returned.
10945  */
10946 static bool get_ocsp_single_response_extensions(CBS *single_response, CBS *extensions) {
10947     // Skip the certID, certStatus, thisUpdate and optional nextUpdate fields.
10948     if (!CBS_get_any_asn1_element(single_response, nullptr /* certID */, nullptr, nullptr) ||
10949         !CBS_get_any_asn1_element(single_response, nullptr /* certStatus */, nullptr, nullptr) ||
10950         !CBS_get_any_asn1_element(single_response, nullptr /* thisUpdate */, nullptr, nullptr) ||
10951         !CBS_get_optional_asn1(single_response, nullptr /* nextUpdate */, nullptr,
10952                                CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
10953         return false;
10954     }
10955 
10956     // Get the list of Extension
10957     return CBS_get_asn1(single_response, extensions,
10958             CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1);
10959 }
10960 
10961 /*
10962  * X509v3_get_ext_by_OBJ and X509v3_get_ext take const arguments, unlike the other *_get_ext
10963  * functions.
10964  * This means they cannot be used with X509Type_get_ext_oid, so these wrapper functions are used
10965  * instead.
10966  */
10967 static int _X509v3_get_ext_by_OBJ(X509_EXTENSIONS *exts, ASN1_OBJECT *obj, int lastpos) {
10968     return X509v3_get_ext_by_OBJ(exts, obj, lastpos);
10969 }
10970 static X509_EXTENSION *_X509v3_get_ext(X509_EXTENSIONS* exts, int loc) {
10971     return X509v3_get_ext(exts, loc);
10972 }
10973 
10974 /*
10975     public static native byte[] get_ocsp_single_extension(byte[] ocspData, String oid,
10976                                                           long x509Ref, long issuerX509Ref);
10977 */
10978 static jbyteArray NativeCrypto_get_ocsp_single_extension(JNIEnv *env, jclass,
10979         jbyteArray ocspDataBytes, jstring oid, jlong x509Ref, jlong issuerX509Ref) {
10980     ScopedByteArrayRO ocspData(env, ocspDataBytes);
10981     if (ocspData.get() == nullptr) {
10982         return nullptr;
10983     }
10984 
10985     CBS cbs;
10986     CBS_init(&cbs, reinterpret_cast<const uint8_t*>(ocspData.get()), ocspData.size());
10987 
10988     // Start parsing the OCSPResponse
10989     CBS ocsp_response;
10990     if (!CBS_get_asn1(&cbs, &ocsp_response, CBS_ASN1_SEQUENCE)) {
10991         return nullptr;
10992     }
10993 
10994     // Get the BasicOCSPResponse from the OCSP Response
10995     CBS basic_response;
10996     if (!get_ocsp_basic_response(&ocsp_response, &basic_response)) {
10997         return nullptr;
10998     }
10999 
11000     // Get the list of SingleResponses from the BasicOCSPResponse
11001     CBS responses;
11002     if (!get_ocsp_single_responses(&basic_response, &responses)) {
11003         return nullptr;
11004     }
11005 
11006     // Find the response matching the certificate
11007     X509* x509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(x509Ref));
11008     X509* issuerX509 = reinterpret_cast<X509*>(static_cast<uintptr_t>(issuerX509Ref));
11009     CBS single_response;
11010     if (!find_ocsp_single_response(&responses, x509, issuerX509, &single_response)) {
11011         return nullptr;
11012     }
11013 
11014     // Get the extensions from the SingleResponse
11015     CBS extensions;
11016     if (!get_ocsp_single_response_extensions(&single_response, &extensions)) {
11017         return nullptr;
11018     }
11019 
11020     const uint8_t* ptr = CBS_data(&extensions);
11021     Unique_X509_EXTENSIONS x509_exts(d2i_X509_EXTENSIONS(nullptr, &ptr, CBS_len(&extensions)));
11022     if (x509_exts.get() == nullptr) {
11023         return nullptr;
11024     }
11025 
11026     return X509Type_get_ext_oid<X509_EXTENSIONS, _X509v3_get_ext_by_OBJ, _X509v3_get_ext>(
11027             env, x509_exts.get(), oid);
11028 }
11029 
11030 #else
11031 
11032 static jbyteArray NativeCrypto_get_ocsp_single_extension(JNIEnv*, jclass, jbyteArray, jstring,
11033                                                          jlong, jlong) {
11034     return NULL;
11035 }
11036 #endif
11037 
11038 static jlong NativeCrypto_getDirectBufferAddress(JNIEnv *env, jclass, jobject buffer) {
11039     return reinterpret_cast<jlong>(env->GetDirectBufferAddress(buffer));
11040 }
11041 
11042 
11043 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;"
11044 #define SSL_CALLBACKS "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto$SSLHandshakeCallbacks;"
11045 #define REF_EC_GROUP "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EC_GROUP;"
11046 #define REF_EC_POINT "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EC_POINT;"
11047 #define REF_EVP_AEAD_CTX "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_AEAD_CTX;"
11048 #define REF_EVP_CIPHER_CTX "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_CIPHER_CTX;"
11049 #define REF_EVP_PKEY "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_PKEY;"
11050 #define REF_HMAC_CTX "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$HMAC_CTX;"
11051 static JNINativeMethod sNativeCryptoMethods[] = {
11052     NATIVE_METHOD(NativeCrypto, clinit, "()Z"),
11053     NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"),
11054     NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)J"),
11055     NATIVE_METHOD(NativeCrypto, ENGINE_add, "(J)I"),
11056     NATIVE_METHOD(NativeCrypto, ENGINE_init, "(J)I"),
11057     NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(J)I"),
11058     NATIVE_METHOD(NativeCrypto, ENGINE_free, "(J)I"),
11059     NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(JLjava/lang/String;)J"),
11060     NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(J)Ljava/lang/String;"),
11061     NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(JLjava/lang/String;Ljava/lang/String;I)I"),
11062     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"),
11063     NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(" REF_EC_GROUP REF_EC_POINT "[B)J"),
11064     NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(" REF_EVP_PKEY ")I"),
11065     NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(" REF_EVP_PKEY ")I"),
11066     NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(" REF_EVP_PKEY ")Ljava/lang/String;"),
11067     NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_params, "(" REF_EVP_PKEY ")Ljava/lang/String;"),
11068     NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(J)V"),
11069     NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(" REF_EVP_PKEY REF_EVP_PKEY ")I"),
11070     NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(" REF_EVP_PKEY ")[B"),
11071     NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)J"),
11072     NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(" REF_EVP_PKEY ")[B"),
11073     NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)J"),
11074     NATIVE_METHOD(NativeCrypto, PEM_read_bio_PUBKEY, "(J)J"),
11075     NATIVE_METHOD(NativeCrypto, PEM_read_bio_PrivateKey, "(J)J"),
11076     NATIVE_METHOD(NativeCrypto, getRSAPrivateKeyWrapper, "(Ljava/security/PrivateKey;[B)J"),
11077     NATIVE_METHOD(NativeCrypto, getECPrivateKeyWrapper, "(Ljava/security/PrivateKey;" REF_EC_GROUP ")J"),
11078     NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)J"),
11079     NATIVE_METHOD(NativeCrypto, RSA_size, "(" REF_EVP_PKEY ")I"),
11080     NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[B" REF_EVP_PKEY "I)I"),
11081     NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[B" REF_EVP_PKEY "I)I"),
11082     NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[B" REF_EVP_PKEY "I)I"),
11083     NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[B" REF_EVP_PKEY "I)I"),
11084     NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(" REF_EVP_PKEY ")[[B"),
11085     NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(" REF_EVP_PKEY ")[[B"),
11086     NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)J"),
11087     NATIVE_METHOD(NativeCrypto, EC_GROUP_new_arbitrary, "([B[B[B[B[B[BI)J"),
11088     NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(" REF_EC_GROUP "I)V"),
11089     NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(" REF_EC_GROUP "I)V"),
11090     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(" REF_EC_GROUP ")Ljava/lang/String;"),
11091     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(" REF_EC_GROUP ")[[B"),
11092     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(" REF_EC_GROUP ")[B"),
11093     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_degree, "(" REF_EC_GROUP ")I"),
11094     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(" REF_EC_GROUP ")[B"),
11095     NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"),
11096     NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(" REF_EC_GROUP ")J"),
11097     NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(" REF_EC_GROUP ")I"),
11098     NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(" REF_EC_GROUP ")J"),
11099     NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(J)V"),
11100     NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(" REF_EC_GROUP REF_EC_POINT "[B[B)V"),
11101     NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(" REF_EC_GROUP REF_EC_POINT ")[[B"),
11102     NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(" REF_EC_GROUP ")J"),
11103     NATIVE_METHOD(NativeCrypto, EC_KEY_get1_group, "(" REF_EVP_PKEY ")J"),
11104     NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(" REF_EVP_PKEY ")[B"),
11105     NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(" REF_EVP_PKEY ")J"),
11106     NATIVE_METHOD(NativeCrypto, EC_KEY_set_nonce_from_hash, "(" REF_EVP_PKEY "Z)V"),
11107     NATIVE_METHOD(NativeCrypto, ECDH_compute_key, "([BI" REF_EVP_PKEY REF_EVP_PKEY ")I"),
11108     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()J"),
11109     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_cleanup, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;)V"),
11110     NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(J)V"),
11111     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"),
11112     NATIVE_METHOD(NativeCrypto, EVP_DigestInit_ex, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;J)I"),
11113     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;[BII)V"),
11114     NATIVE_METHOD(NativeCrypto, EVP_DigestUpdateDirect, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;JI)V"),
11115     NATIVE_METHOD(NativeCrypto, EVP_DigestFinal_ex, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;[BI)I"),
11116     NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)J"),
11117     NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(J)I"),
11118     NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(J)I"),
11119     NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;J" REF_EVP_PKEY ")J"),
11120     NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;[BII)V"),
11121     NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdateDirect, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;JI)V"),
11122     NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;)[B"),
11123     NATIVE_METHOD(NativeCrypto, EVP_DigestVerifyInit, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;J" REF_EVP_PKEY ")J"),
11124     NATIVE_METHOD(NativeCrypto, EVP_DigestVerifyUpdate, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;[BII)V"),
11125     NATIVE_METHOD(NativeCrypto, EVP_DigestVerifyUpdateDirect, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;JI)V"),
11126     NATIVE_METHOD(NativeCrypto, EVP_DigestVerifyFinal, "(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef$EVP_MD_CTX;[BII)Z"),
11127     NATIVE_METHOD(NativeCrypto, EVP_PKEY_CTX_set_rsa_padding, "(JI)V"),
11128     NATIVE_METHOD(NativeCrypto, EVP_PKEY_CTX_set_rsa_pss_saltlen, "(JI)V"),
11129     NATIVE_METHOD(NativeCrypto, EVP_PKEY_CTX_set_rsa_mgf1_md, "(JJ)V"),
11130     NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)J"),
11131     NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(" REF_EVP_CIPHER_CTX "J[B[BZ)V"),
11132     NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(" REF_EVP_CIPHER_CTX "[BI[BII)I"),
11133     NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(" REF_EVP_CIPHER_CTX "[BI)I"),
11134     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(J)I"),
11135     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()J"),
11136     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(" REF_EVP_CIPHER_CTX ")I"),
11137     NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(" REF_EVP_CIPHER_CTX ")I"),
11138     NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_final_used, "(" REF_EVP_CIPHER_CTX ")Z"),
11139     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(" REF_EVP_CIPHER_CTX "Z)V"),
11140     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(" REF_EVP_CIPHER_CTX "I)V"),
11141     NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_free, "(J)V"),
11142     NATIVE_METHOD(NativeCrypto, EVP_aead_aes_128_gcm, "()J"),
11143     NATIVE_METHOD(NativeCrypto, EVP_aead_aes_256_gcm, "()J"),
11144     NATIVE_METHOD(NativeCrypto, EVP_AEAD_CTX_init, "(J[BI)J"),
11145     NATIVE_METHOD(NativeCrypto, EVP_AEAD_CTX_cleanup, "(J)V"),
11146     NATIVE_METHOD(NativeCrypto, EVP_AEAD_max_overhead, "(J)I"),
11147     NATIVE_METHOD(NativeCrypto, EVP_AEAD_nonce_length, "(J)I"),
11148     NATIVE_METHOD(NativeCrypto, EVP_AEAD_max_tag_len, "(J)I"),
11149     NATIVE_METHOD(NativeCrypto, EVP_AEAD_CTX_seal, "(" REF_EVP_AEAD_CTX "[BI[B[BII[B)I"),
11150     NATIVE_METHOD(NativeCrypto, EVP_AEAD_CTX_open, "(" REF_EVP_AEAD_CTX "[BI[B[BII[B)I"),
11151     NATIVE_METHOD(NativeCrypto, HMAC_CTX_new, "()J"),
11152     NATIVE_METHOD(NativeCrypto, HMAC_CTX_free, "(J)V"),
11153     NATIVE_METHOD(NativeCrypto, HMAC_Init_ex, "(" REF_HMAC_CTX "[BJ)V"),
11154     NATIVE_METHOD(NativeCrypto, HMAC_Update, "(" REF_HMAC_CTX "[BII)V"),
11155     NATIVE_METHOD(NativeCrypto, HMAC_UpdateDirect, "(" REF_HMAC_CTX "JI)V"),
11156     NATIVE_METHOD(NativeCrypto, HMAC_Final, "(" REF_HMAC_CTX ")[B"),
11157     NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"),
11158     NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"),
11159     NATIVE_METHOD(NativeCrypto, RAND_bytes, "([B)V"),
11160     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid, "(Ljava/lang/String;)I"),
11161     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_longName, "(Ljava/lang/String;)Ljava/lang/String;"),
11162     NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_oid, "(Ljava/lang/String;)Ljava/lang/String;"),
11163     NATIVE_METHOD(NativeCrypto, create_BIO_InputStream, ("(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream;Z)J")),
11164     NATIVE_METHOD(NativeCrypto, create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"),
11165     NATIVE_METHOD(NativeCrypto, BIO_read, "(J[B)I"),
11166     NATIVE_METHOD(NativeCrypto, BIO_write, "(J[BII)V"),
11167     NATIVE_METHOD(NativeCrypto, BIO_free_all, "(J)V"),
11168     NATIVE_METHOD(NativeCrypto, X509_NAME_print_ex, "(JJ)Ljava/lang/String;"),
11169     NATIVE_METHOD(NativeCrypto, d2i_X509_bio, "(J)J"),
11170     NATIVE_METHOD(NativeCrypto, d2i_X509, "([B)J"),
11171     NATIVE_METHOD(NativeCrypto, i2d_X509, "(J)[B"),
11172     NATIVE_METHOD(NativeCrypto, i2d_X509_PUBKEY, "(J)[B"),
11173     NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509, "(J)J"),
11174     NATIVE_METHOD(NativeCrypto, PEM_read_bio_PKCS7, "(JI)[J"),
11175     NATIVE_METHOD(NativeCrypto, d2i_PKCS7_bio, "(JI)[J"),
11176     NATIVE_METHOD(NativeCrypto, i2d_PKCS7, "([J)[B"),
11177     NATIVE_METHOD(NativeCrypto, ASN1_seq_unpack_X509_bio, "(J)[J"),
11178     NATIVE_METHOD(NativeCrypto, ASN1_seq_pack_X509, "([J)[B"),
11179     NATIVE_METHOD(NativeCrypto, X509_free, "(J)V"),
11180     NATIVE_METHOD(NativeCrypto, X509_dup, "(J)J"),
11181     NATIVE_METHOD(NativeCrypto, X509_cmp, "(JJ)I"),
11182     NATIVE_METHOD(NativeCrypto, X509_print_ex, "(JJJJ)V"),
11183     NATIVE_METHOD(NativeCrypto, X509_get_pubkey, "(J)J"),
11184     NATIVE_METHOD(NativeCrypto, X509_get_issuer_name, "(J)[B"),
11185     NATIVE_METHOD(NativeCrypto, X509_get_subject_name, "(J)[B"),
11186     NATIVE_METHOD(NativeCrypto, get_X509_pubkey_oid, "(J)Ljava/lang/String;"),
11187     NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_oid, "(J)Ljava/lang/String;"),
11188     NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_parameter, "(J)[B"),
11189     NATIVE_METHOD(NativeCrypto, get_X509_issuerUID, "(J)[Z"),
11190     NATIVE_METHOD(NativeCrypto, get_X509_subjectUID, "(J)[Z"),
11191     NATIVE_METHOD(NativeCrypto, get_X509_ex_kusage, "(J)[Z"),
11192     NATIVE_METHOD(NativeCrypto, get_X509_ex_xkusage, "(J)[Ljava/lang/String;"),
11193     NATIVE_METHOD(NativeCrypto, get_X509_ex_pathlen, "(J)I"),
11194     NATIVE_METHOD(NativeCrypto, X509_get_ext_oid, "(JLjava/lang/String;)[B"),
11195     NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext_oid, "(JLjava/lang/String;)[B"),
11196     NATIVE_METHOD(NativeCrypto, X509_delete_ext, "(JLjava/lang/String;)V"),
11197     NATIVE_METHOD(NativeCrypto, get_X509_CRL_crl_enc, "(J)[B"),
11198     NATIVE_METHOD(NativeCrypto, X509_CRL_verify, "(J" REF_EVP_PKEY ")V"),
11199     NATIVE_METHOD(NativeCrypto, X509_CRL_get_lastUpdate, "(J)J"),
11200     NATIVE_METHOD(NativeCrypto, X509_CRL_get_nextUpdate, "(J)J"),
11201     NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext_oid, "(JLjava/lang/String;)[B"),
11202     NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_serialNumber, "(J)[B"),
11203     NATIVE_METHOD(NativeCrypto, X509_REVOKED_print, "(JJ)V"),
11204     NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_revocationDate, "(J)J"),
11205     NATIVE_METHOD(NativeCrypto, get_X509_ext_oids, "(JI)[Ljava/lang/String;"),
11206     NATIVE_METHOD(NativeCrypto, get_X509_CRL_ext_oids, "(JI)[Ljava/lang/String;"),
11207     NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_ext_oids, "(JI)[Ljava/lang/String;"),
11208     NATIVE_METHOD(NativeCrypto, get_X509_GENERAL_NAME_stack, "(JI)[[Ljava/lang/Object;"),
11209     NATIVE_METHOD(NativeCrypto, X509_get_notBefore, "(J)J"),
11210     NATIVE_METHOD(NativeCrypto, X509_get_notAfter, "(J)J"),
11211     NATIVE_METHOD(NativeCrypto, X509_get_version, "(J)J"),
11212     NATIVE_METHOD(NativeCrypto, X509_get_serialNumber, "(J)[B"),
11213     NATIVE_METHOD(NativeCrypto, X509_verify, "(J" REF_EVP_PKEY ")V"),
11214     NATIVE_METHOD(NativeCrypto, get_X509_cert_info_enc, "(J)[B"),
11215     NATIVE_METHOD(NativeCrypto, get_X509_signature, "(J)[B"),
11216     NATIVE_METHOD(NativeCrypto, get_X509_CRL_signature, "(J)[B"),
11217     NATIVE_METHOD(NativeCrypto, get_X509_ex_flags, "(J)I"),
11218     NATIVE_METHOD(NativeCrypto, X509_check_issued, "(JJ)I"),
11219     NATIVE_METHOD(NativeCrypto, d2i_X509_CRL_bio, "(J)J"),
11220     NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509_CRL, "(J)J"),
11221     NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_cert, "(JJ)J"),
11222     NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_serial, "(J[B)J"),
11223     NATIVE_METHOD(NativeCrypto, X509_CRL_get_REVOKED, "(J)[J"),
11224     NATIVE_METHOD(NativeCrypto, i2d_X509_CRL, "(J)[B"),
11225     NATIVE_METHOD(NativeCrypto, X509_CRL_free, "(J)V"),
11226     NATIVE_METHOD(NativeCrypto, X509_CRL_print, "(JJ)V"),
11227     NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_oid, "(J)Ljava/lang/String;"),
11228     NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_parameter, "(J)[B"),
11229     NATIVE_METHOD(NativeCrypto, X509_CRL_get_issuer_name, "(J)[B"),
11230     NATIVE_METHOD(NativeCrypto, X509_CRL_get_version, "(J)J"),
11231     NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext, "(JLjava/lang/String;)J"),
11232     NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext, "(JLjava/lang/String;)J"),
11233     NATIVE_METHOD(NativeCrypto, X509_REVOKED_dup, "(J)J"),
11234     NATIVE_METHOD(NativeCrypto, i2d_X509_REVOKED, "(J)[B"),
11235     NATIVE_METHOD(NativeCrypto, X509_supported_extension, "(J)I"),
11236     NATIVE_METHOD(NativeCrypto, ASN1_TIME_to_Calendar, "(JLjava/util/Calendar;)V"),
11237     NATIVE_METHOD(NativeCrypto, EVP_has_aes_hardware, "()I"),
11238     NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()J"),
11239     NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(J)V"),
11240     NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(J[B)V"),
11241     NATIVE_METHOD(NativeCrypto, SSL_new, "(J)J"),
11242     NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(J)V"),
11243     NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(J)[B"),
11244     NATIVE_METHOD(NativeCrypto, SSL_set1_tls_channel_id, "(J" REF_EVP_PKEY ")V"),
11245     NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(J" REF_EVP_PKEY ")V"),
11246     NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(J[J)V"),
11247     NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(J)V"),
11248     NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(J[[B)V"),
11249     NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(J)J"),
11250     NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(JJ)J"),
11251     NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(JJ)J"),
11252     NATIVE_METHOD(NativeCrypto, SSL_get_options, "(J)J"),
11253     NATIVE_METHOD(NativeCrypto, SSL_set_options, "(JJ)J"),
11254     NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(JJ)J"),
11255     NATIVE_METHOD(NativeCrypto, SSL_enable_signed_cert_timestamps, "(J)V"),
11256     NATIVE_METHOD(NativeCrypto, SSL_get_signed_cert_timestamp_list, "(J)[B"),
11257     NATIVE_METHOD(NativeCrypto, SSL_CTX_set_signed_cert_timestamp_list, "(J[B)V"),
11258     NATIVE_METHOD(NativeCrypto, SSL_enable_ocsp_stapling, "(J)V"),
11259     NATIVE_METHOD(NativeCrypto, SSL_get_ocsp_response, "(J)[B"),
11260     NATIVE_METHOD(NativeCrypto, SSL_CTX_set_ocsp_response, "(J[B)V"),
11261     NATIVE_METHOD(NativeCrypto, SSL_use_psk_identity_hint, "(JLjava/lang/String;)V"),
11262     NATIVE_METHOD(NativeCrypto, set_SSL_psk_client_callback_enabled, "(JZ)V"),
11263     NATIVE_METHOD(NativeCrypto, set_SSL_psk_server_callback_enabled, "(JZ)V"),
11264     NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(J[Ljava/lang/String;)V"),
11265     NATIVE_METHOD(NativeCrypto, SSL_get_ciphers, "(J)[J"),
11266     NATIVE_METHOD(NativeCrypto, SSL_set_accept_state, "(J)V"),
11267     NATIVE_METHOD(NativeCrypto, SSL_set_connect_state, "(J)V"),
11268     NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(JI)V"),
11269     NATIVE_METHOD(NativeCrypto, SSL_set_session, "(JJ)V"),
11270     NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(JZ)V"),
11271     NATIVE_METHOD(NativeCrypto, SSL_session_reused, "(J)Z"),
11272     NATIVE_METHOD(NativeCrypto, SSL_set_reject_peer_renegotiations, "(JZ)V"),
11273     NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(JLjava/lang/String;)V"),
11274     NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(J)Ljava/lang/String;"),
11275     NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B[B)J"),
11276     NATIVE_METHOD(NativeCrypto, SSL_do_handshake_bio, "(JJJ" SSL_CALLBACKS "Z[B[B)J"),
11277     NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(J)V"),
11278     NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[J"),
11279     NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[J"),
11280     NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"),
11281     NATIVE_METHOD(NativeCrypto, SSL_read_BIO, "(J[BIIJJ" SSL_CALLBACKS ")I"),
11282     NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"),
11283     NATIVE_METHOD(NativeCrypto, SSL_write_BIO, "(J[BIJ" SSL_CALLBACKS ")I"),
11284     NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"),
11285     NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(J" FILE_DESCRIPTOR SSL_CALLBACKS ")V"),
11286     NATIVE_METHOD(NativeCrypto, SSL_shutdown_BIO, "(JJJ" SSL_CALLBACKS ")V"),
11287     NATIVE_METHOD(NativeCrypto, SSL_get_shutdown, "(J)I"),
11288     NATIVE_METHOD(NativeCrypto, SSL_free, "(J)V"),
11289     NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(J)[B"),
11290     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(J)J"),
11291     NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(J)Ljava/lang/String;"),
11292     NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(J)Ljava/lang/String;"),
11293     NATIVE_METHOD(NativeCrypto, get_SSL_SESSION_tlsext_hostname, "(J)Ljava/lang/String;"),
11294     NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(J)V"),
11295     NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(J)[B"),
11296     NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)J"),
11297     NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(J)V"),
11298     NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(J)V"),
11299     NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(J)[B"),
11300     NATIVE_METHOD(NativeCrypto, SSL_set_alpn_protos, "(J[B)I"),
11301     NATIVE_METHOD(NativeCrypto, SSL_get0_alpn_selected, "(J)[B"),
11302     NATIVE_METHOD(NativeCrypto, ERR_peek_last_error, "()J"),
11303     NATIVE_METHOD(NativeCrypto, SSL_CIPHER_get_kx_name, "(J)Ljava/lang/String;"),
11304     NATIVE_METHOD(NativeCrypto, get_cipher_names, "(Ljava/lang/String;)[Ljava/lang/String;"),
11305     NATIVE_METHOD(NativeCrypto, get_ocsp_single_extension, "([BLjava/lang/String;JJ)[B"),
11306     NATIVE_METHOD(NativeCrypto, getDirectBufferAddress, "(Ljava/nio/Buffer;)J"),
11307 };
11308 
11309 static jclass getGlobalRefToClass(JNIEnv* env, const char* className) {
11310     ScopedLocalRef<jclass> localClass(env, env->FindClass(className));
11311     jclass globalRef = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
11312     if (globalRef == nullptr) {
11313         ALOGE("failed to find class %s", className);
11314         abort();
11315     }
11316     return globalRef;
11317 }
11318 
11319 static jmethodID getMethodRef(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
11320     jmethodID localMethod = env->GetMethodID(clazz, name, sig);
11321     if (localMethod == nullptr) {
11322         ALOGE("could not find method %s", name);
11323         abort();
11324     }
11325     return localMethod;
11326 }
11327 
11328 static jfieldID getFieldRef(JNIEnv* env, jclass clazz, const char* name, const char* sig) {
11329     jfieldID localField = env->GetFieldID(clazz, name, sig);
11330     if (localField == nullptr) {
11331         ALOGE("could not find field %s", name);
11332         abort();
11333     }
11334     return localField;
11335 }
11336 
11337 static void initialize_conscrypt(JNIEnv* env) {
11338     jniRegisterNativeMethods(env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto",
11339                              sNativeCryptoMethods, NELEM(sNativeCryptoMethods));
11340 
11341     cryptoUpcallsClass = getGlobalRefToClass(env,
11342             TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/CryptoUpcalls");
11343     nativeRefClass = getGlobalRefToClass(env,
11344             TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeRef");
11345     openSslInputStreamClass = getGlobalRefToClass(env,
11346             TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream");
11347 
11348     nativeRef_context = getFieldRef(env, nativeRefClass, "context", "J");
11349 
11350     calendar_setMethod = getMethodRef(env, calendarClass, "set", "(IIIIII)V");
11351     inputStream_readMethod = getMethodRef(env, inputStreamClass, "read", "([B)I");
11352     integer_valueOfMethod = env->GetStaticMethodID(integerClass, "valueOf",
11353             "(I)Ljava/lang/Integer;");
11354     openSslInputStream_readLineMethod = getMethodRef(env, openSslInputStreamClass, "gets",
11355             "([B)I");
11356     outputStream_writeMethod = getMethodRef(env, outputStreamClass, "write", "([B)V");
11357     outputStream_flushMethod = getMethodRef(env, outputStreamClass, "flush", "()V");
11358 
11359 #ifdef CONSCRYPT_UNBUNDLED
11360     findAsynchronousCloseMonitorFuncs();
11361 #endif
11362 }
11363 
11364 static jclass findClass(JNIEnv* env, const char* name) {
11365     ScopedLocalRef<jclass> localClass(env, env->FindClass(name));
11366     jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get()));
11367     if (result == nullptr) {
11368         ALOGE("failed to find class '%s'", name);
11369         abort();
11370     }
11371     return result;
11372 }
11373 
11374 #ifdef STATIC_LIB
11375 // Give client libs everything they need to initialize our JNI
11376 int libconscrypt_JNI_OnLoad(JavaVM *vm, void*) {
11377 #else
11378 // Use JNI_OnLoad for when we're standalone
11379 int JNI_OnLoad(JavaVM *vm, void*) {
11380     JNI_TRACE("JNI_OnLoad NativeCrypto");
11381 #endif
11382     gJavaVM = vm;
11383 
11384     JNIEnv *env;
11385     if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) {
11386         ALOGE("Could not get JNIEnv");
11387         return JNI_ERR;
11388     }
11389 
11390     byteArrayClass = findClass(env, "[B");
11391     calendarClass = findClass(env, "java/util/Calendar");
11392     inputStreamClass = findClass(env, "java/io/InputStream");
11393     integerClass = findClass(env, "java/lang/Integer");
11394     objectClass = findClass(env, "java/lang/Object");
11395     objectArrayClass = findClass(env, "[Ljava/lang/Object;");
11396     outputStreamClass = findClass(env, "java/io/OutputStream");
11397     stringClass = findClass(env, "java/lang/String");
11398 
11399     initialize_conscrypt(env);
11400     return JNI_VERSION_1_6;
11401 }
11402 
11403 /* vim: softtabstop=4:shiftwidth=4:expandtab */
11404 
11405 /* Local Variables: */
11406 /* mode: c++ */
11407 /* tab-width: 4 */
11408 /* indent-tabs-mode: nil */
11409 /* c-basic-offset: 4 */
11410 /* End: */
11411