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