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