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