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