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