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