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