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 clearCallbackState(); 5623 MUTEX_CLEANUP(mutex); 5624 } 5625 5626 private: 5627 AppData() : 5628 aliveAndKicking(1), 5629 waitingThreads(0), 5630 env(NULL), 5631 sslHandshakeCallbacks(NULL), 5632 npnProtocolsArray(NULL), 5633 npnProtocolsData(NULL), 5634 npnProtocolsLength(-1), 5635 alpnProtocolsArray(NULL), 5636 alpnProtocolsData(NULL), 5637 alpnProtocolsLength(-1), 5638 ephemeralRsa(NULL), 5639 ephemeralEc(NULL) { 5640 fdsEmergency[0] = -1; 5641 fdsEmergency[1] = -1; 5642 } 5643 5644 public: 5645 /** 5646 * Used to set the SSL-to-Java callback state before each SSL_* 5647 * call that may result in a callback. It should be cleared after 5648 * the operation returns with clearCallbackState. 5649 * 5650 * @param env The JNIEnv 5651 * @param shc The SSLHandshakeCallbacks 5652 * @param fd The FileDescriptor 5653 * @param npnProtocols NPN protocols so that they may be advertised (by the 5654 * server) or selected (by the client). Has no effect 5655 * unless NPN is enabled. 5656 * @param alpnProtocols ALPN protocols so that they may be advertised (by the 5657 * server) or selected (by the client). Passing non-NULL 5658 * enables ALPN. 5659 */ 5660 bool setCallbackState(JNIEnv* e, jobject shc, jobject fd, jbyteArray npnProtocols, 5661 jbyteArray alpnProtocols) { 5662 NetFd netFd(e, fd); 5663 if (netFd.isClosed()) { 5664 return false; 5665 } 5666 env = e; 5667 sslHandshakeCallbacks = shc; 5668 fileDescriptor = fd; 5669 if (npnProtocols != NULL) { 5670 npnProtocolsData = e->GetByteArrayElements(npnProtocols, NULL); 5671 if (npnProtocolsData == NULL) { 5672 clearCallbackState(); 5673 return false; 5674 } 5675 npnProtocolsArray = npnProtocols; 5676 npnProtocolsLength = e->GetArrayLength(npnProtocols); 5677 } 5678 if (alpnProtocols != NULL) { 5679 alpnProtocolsData = e->GetByteArrayElements(alpnProtocols, NULL); 5680 if (alpnProtocolsData == NULL) { 5681 clearCallbackState(); 5682 return false; 5683 } 5684 alpnProtocolsArray = alpnProtocols; 5685 alpnProtocolsLength = e->GetArrayLength(alpnProtocols); 5686 } 5687 return true; 5688 } 5689 5690 void clearCallbackState() { 5691 sslHandshakeCallbacks = NULL; 5692 fileDescriptor = NULL; 5693 if (npnProtocolsArray != NULL) { 5694 env->ReleaseByteArrayElements(npnProtocolsArray, npnProtocolsData, JNI_ABORT); 5695 npnProtocolsArray = NULL; 5696 npnProtocolsData = NULL; 5697 npnProtocolsLength = -1; 5698 } 5699 if (alpnProtocolsArray != NULL) { 5700 env->ReleaseByteArrayElements(alpnProtocolsArray, alpnProtocolsData, JNI_ABORT); 5701 alpnProtocolsArray = NULL; 5702 alpnProtocolsData = NULL; 5703 alpnProtocolsLength = -1; 5704 } 5705 env = NULL; 5706 } 5707 5708 }; 5709 5710 /** 5711 * Dark magic helper function that checks, for a given SSL session, whether it 5712 * can SSL_read() or SSL_write() without blocking. Takes into account any 5713 * concurrent attempts to close the SSLSocket from the Java side. This is 5714 * needed to get rid of the hangs that occur when thread #1 closes the SSLSocket 5715 * while thread #2 is sitting in a blocking read or write. The type argument 5716 * specifies whether we are waiting for readability or writability. It expects 5717 * to be passed either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE, since we 5718 * only need to wait in case one of these problems occurs. 5719 * 5720 * @param env 5721 * @param type Either SSL_ERROR_WANT_READ or SSL_ERROR_WANT_WRITE 5722 * @param fdObject The FileDescriptor, since appData->fileDescriptor should be NULL 5723 * @param appData The application data structure with mutex info etc. 5724 * @param timeout_millis The timeout value for select call, with the special value 5725 * 0 meaning no timeout at all (wait indefinitely). Note: This is 5726 * the Java semantics of the timeout value, not the usual 5727 * select() semantics. 5728 * @return The result of the inner select() call, 5729 * THROW_SOCKETEXCEPTION if a SocketException was thrown, -1 on 5730 * additional errors 5731 */ 5732 static int sslSelect(JNIEnv* env, int type, jobject fdObject, AppData* appData, int timeout_millis) { 5733 // This loop is an expanded version of the NET_FAILURE_RETRY 5734 // macro. It cannot simply be used in this case because select 5735 // cannot be restarted without recreating the fd_sets and timeout 5736 // structure. 5737 int result; 5738 fd_set rfds; 5739 fd_set wfds; 5740 do { 5741 NetFd fd(env, fdObject); 5742 if (fd.isClosed()) { 5743 result = THROWN_EXCEPTION; 5744 break; 5745 } 5746 int intFd = fd.get(); 5747 JNI_TRACE("sslSelect type=%s fd=%d appData=%p timeout_millis=%d", 5748 (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", intFd, appData, timeout_millis); 5749 5750 FD_ZERO(&rfds); 5751 FD_ZERO(&wfds); 5752 5753 if (type == SSL_ERROR_WANT_READ) { 5754 FD_SET(intFd, &rfds); 5755 } else { 5756 FD_SET(intFd, &wfds); 5757 } 5758 5759 FD_SET(appData->fdsEmergency[0], &rfds); 5760 5761 int maxFd = (intFd > appData->fdsEmergency[0]) ? intFd : appData->fdsEmergency[0]; 5762 5763 // Build a struct for the timeout data if we actually want a timeout. 5764 timeval tv; 5765 timeval* ptv; 5766 if (timeout_millis > 0) { 5767 tv.tv_sec = timeout_millis / 1000; 5768 tv.tv_usec = (timeout_millis % 1000) * 1000; 5769 ptv = &tv; 5770 } else { 5771 ptv = NULL; 5772 } 5773 5774 AsynchronousSocketCloseMonitor monitor(intFd); 5775 result = select(maxFd + 1, &rfds, &wfds, NULL, ptv); 5776 JNI_TRACE("sslSelect %s fd=%d appData=%p timeout_millis=%d => %d", 5777 (type == SSL_ERROR_WANT_READ) ? "READ" : "WRITE", 5778 fd.get(), appData, timeout_millis, result); 5779 if (result == -1) { 5780 if (fd.isClosed()) { 5781 result = THROWN_EXCEPTION; 5782 break; 5783 } 5784 if (errno != EINTR) { 5785 break; 5786 } 5787 } 5788 } while (result == -1); 5789 5790 if (MUTEX_LOCK(appData->mutex) == -1) { 5791 return -1; 5792 } 5793 5794 if (result > 0) { 5795 // We have been woken up by a token in the emergency pipe. We 5796 // can't be sure the token is still in the pipe at this point 5797 // because it could have already been read by the thread that 5798 // originally wrote it if it entered sslSelect and acquired 5799 // the mutex before we did. Thus we cannot safely read from 5800 // the pipe in a blocking way (so we make the pipe 5801 // non-blocking at creation). 5802 if (FD_ISSET(appData->fdsEmergency[0], &rfds)) { 5803 char token; 5804 do { 5805 read(appData->fdsEmergency[0], &token, 1); 5806 } while (errno == EINTR); 5807 } 5808 } 5809 5810 // Tell the world that there is now one thread less waiting for the 5811 // underlying network. 5812 appData->waitingThreads--; 5813 5814 MUTEX_UNLOCK(appData->mutex); 5815 5816 return result; 5817 } 5818 5819 /** 5820 * Helper function that wakes up a thread blocked in select(), in case there is 5821 * one. Is being called by sslRead() and sslWrite() as well as by JNI glue 5822 * before closing the connection. 5823 * 5824 * @param data The application data structure with mutex info etc. 5825 */ 5826 static void sslNotify(AppData* appData) { 5827 // Write a byte to the emergency pipe, so a concurrent select() can return. 5828 // Note we have to restore the errno of the original system call, since the 5829 // caller relies on it for generating error messages. 5830 int errnoBackup = errno; 5831 char token = '*'; 5832 do { 5833 errno = 0; 5834 write(appData->fdsEmergency[1], &token, 1); 5835 } while (errno == EINTR); 5836 errno = errnoBackup; 5837 } 5838 5839 static AppData* toAppData(const SSL* ssl) { 5840 return reinterpret_cast<AppData*>(SSL_get_app_data(ssl)); 5841 } 5842 5843 /** 5844 * Verify the X509 certificate via SSL_CTX_set_cert_verify_callback 5845 */ 5846 static int cert_verify_callback(X509_STORE_CTX* x509_store_ctx, void* arg __attribute__ ((unused))) 5847 { 5848 /* Get the correct index to the SSLobject stored into X509_STORE_CTX. */ 5849 SSL* ssl = reinterpret_cast<SSL*>(X509_STORE_CTX_get_ex_data(x509_store_ctx, 5850 SSL_get_ex_data_X509_STORE_CTX_idx())); 5851 JNI_TRACE("ssl=%p cert_verify_callback x509_store_ctx=%p arg=%p", ssl, x509_store_ctx, arg); 5852 5853 AppData* appData = toAppData(ssl); 5854 JNIEnv* env = appData->env; 5855 if (env == NULL) { 5856 ALOGE("AppData->env missing in cert_verify_callback"); 5857 JNI_TRACE("ssl=%p cert_verify_callback => 0", ssl); 5858 return 0; 5859 } 5860 jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks; 5861 5862 jclass cls = env->GetObjectClass(sslHandshakeCallbacks); 5863 jmethodID methodID 5864 = env->GetMethodID(cls, "verifyCertificateChain", "([[BLjava/lang/String;)V"); 5865 5866 jobjectArray objectArray = getCertificateBytes(env, x509_store_ctx->untrusted); 5867 5868 const char* authMethod = SSL_authentication_method(ssl); 5869 JNI_TRACE("ssl=%p cert_verify_callback calling verifyCertificateChain authMethod=%s", 5870 ssl, authMethod); 5871 jstring authMethodString = env->NewStringUTF(authMethod); 5872 env->CallVoidMethod(sslHandshakeCallbacks, methodID, objectArray, authMethodString); 5873 5874 int result = (env->ExceptionCheck()) ? 0 : 1; 5875 JNI_TRACE("ssl=%p cert_verify_callback => %d", ssl, result); 5876 return result; 5877 } 5878 5879 /** 5880 * Call back to watch for handshake to be completed. This is necessary 5881 * for SSL_MODE_HANDSHAKE_CUTTHROUGH support, since SSL_do_handshake 5882 * returns before the handshake is completed in this case. 5883 */ 5884 static void info_callback(const SSL* ssl, int where, int ret __attribute__ ((unused))) { 5885 JNI_TRACE("ssl=%p info_callback where=0x%x ret=%d", ssl, where, ret); 5886 #ifdef WITH_JNI_TRACE 5887 info_callback_LOG(ssl, where, ret); 5888 #endif 5889 if (!(where & SSL_CB_HANDSHAKE_DONE)) { 5890 JNI_TRACE("ssl=%p info_callback ignored", ssl); 5891 return; 5892 } 5893 5894 AppData* appData = toAppData(ssl); 5895 JNIEnv* env = appData->env; 5896 if (env == NULL) { 5897 ALOGE("AppData->env missing in info_callback"); 5898 JNI_TRACE("ssl=%p info_callback env error", ssl); 5899 return; 5900 } 5901 if (env->ExceptionCheck()) { 5902 JNI_TRACE("ssl=%p info_callback already pending exception", ssl); 5903 return; 5904 } 5905 5906 jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks; 5907 5908 jclass cls = env->GetObjectClass(sslHandshakeCallbacks); 5909 jmethodID methodID = env->GetMethodID(cls, "handshakeCompleted", "()V"); 5910 5911 JNI_TRACE("ssl=%p info_callback calling handshakeCompleted", ssl); 5912 env->CallVoidMethod(sslHandshakeCallbacks, methodID); 5913 5914 if (env->ExceptionCheck()) { 5915 JNI_TRACE("ssl=%p info_callback exception", ssl); 5916 } 5917 JNI_TRACE("ssl=%p info_callback completed", ssl); 5918 } 5919 5920 /** 5921 * Call back to ask for a client certificate. There are three possible exit codes: 5922 * 5923 * 1 is success. x509Out and pkeyOut should point to the correct private key and certificate. 5924 * 0 is unable to find key. x509Out and pkeyOut should be NULL. 5925 * -1 is error and it doesn't matter what x509Out and pkeyOut are. 5926 */ 5927 static int client_cert_cb(SSL* ssl, X509** x509Out, EVP_PKEY** pkeyOut) { 5928 JNI_TRACE("ssl=%p client_cert_cb x509Out=%p pkeyOut=%p", ssl, x509Out, pkeyOut); 5929 5930 /* Clear output of key and certificate in case of early exit due to error. */ 5931 *x509Out = NULL; 5932 *pkeyOut = NULL; 5933 5934 AppData* appData = toAppData(ssl); 5935 JNIEnv* env = appData->env; 5936 if (env == NULL) { 5937 ALOGE("AppData->env missing in client_cert_cb"); 5938 JNI_TRACE("ssl=%p client_cert_cb env error => 0", ssl); 5939 return 0; 5940 } 5941 if (env->ExceptionCheck()) { 5942 JNI_TRACE("ssl=%p client_cert_cb already pending exception => 0", ssl); 5943 return -1; 5944 } 5945 jobject sslHandshakeCallbacks = appData->sslHandshakeCallbacks; 5946 5947 jclass cls = env->GetObjectClass(sslHandshakeCallbacks); 5948 jmethodID methodID 5949 = env->GetMethodID(cls, "clientCertificateRequested", "([B[[B)V"); 5950 5951 // Call Java callback which can use SSL_use_certificate and SSL_use_PrivateKey to set values 5952 char ssl2_ctype = SSL3_CT_RSA_SIGN; 5953 const char* ctype = NULL; 5954 int ctype_num = 0; 5955 jobjectArray issuers = NULL; 5956 switch (ssl->version) { 5957 case SSL2_VERSION: 5958 ctype = &ssl2_ctype; 5959 ctype_num = 1; 5960 break; 5961 case SSL3_VERSION: 5962 case TLS1_VERSION: 5963 case TLS1_1_VERSION: 5964 case TLS1_2_VERSION: 5965 case DTLS1_VERSION: 5966 ctype = ssl->s3->tmp.ctype; 5967 ctype_num = ssl->s3->tmp.ctype_num; 5968 issuers = getPrincipalBytes(env, ssl->s3->tmp.ca_names); 5969 break; 5970 } 5971 #ifdef WITH_JNI_TRACE 5972 for (int i = 0; i < ctype_num; i++) { 5973 JNI_TRACE("ssl=%p clientCertificateRequested keyTypes[%d]=%d", ssl, i, ctype[i]); 5974 } 5975 #endif 5976 5977 jbyteArray keyTypes = env->NewByteArray(ctype_num); 5978 if (keyTypes == NULL) { 5979 JNI_TRACE("ssl=%p client_cert_cb bytes == null => 0", ssl); 5980 return 0; 5981 } 5982 env->SetByteArrayRegion(keyTypes, 0, ctype_num, reinterpret_cast<const jbyte*>(ctype)); 5983 5984 JNI_TRACE("ssl=%p clientCertificateRequested calling clientCertificateRequested " 5985 "keyTypes=%p issuers=%p", ssl, keyTypes, issuers); 5986 env->CallVoidMethod(sslHandshakeCallbacks, methodID, keyTypes, issuers); 5987 5988 if (env->ExceptionCheck()) { 5989 JNI_TRACE("ssl=%p client_cert_cb exception => 0", ssl); 5990 return -1; 5991 } 5992 5993 // Check for values set from Java 5994 X509* certificate = SSL_get_certificate(ssl); 5995 EVP_PKEY* privatekey = SSL_get_privatekey(ssl); 5996 int result = 0; 5997 if (certificate != NULL && privatekey != NULL) { 5998 *x509Out = certificate; 5999 *pkeyOut = privatekey; 6000 result = 1; 6001 } else { 6002 // Some error conditions return NULL, so make sure it doesn't linger. 6003 freeOpenSslErrorState(); 6004 } 6005 JNI_TRACE("ssl=%p client_cert_cb => *x509=%p *pkey=%p %d", ssl, *x509Out, *pkeyOut, result); 6006 return result; 6007 } 6008 6009 static RSA* rsaGenerateKey(int keylength) { 6010 Unique_BIGNUM bn(BN_new()); 6011 if (bn.get() == NULL) { 6012 return NULL; 6013 } 6014 int setWordResult = BN_set_word(bn.get(), RSA_F4); 6015 if (setWordResult != 1) { 6016 return NULL; 6017 } 6018 Unique_RSA rsa(RSA_new()); 6019 if (rsa.get() == NULL) { 6020 return NULL; 6021 } 6022 int generateResult = RSA_generate_key_ex(rsa.get(), keylength, bn.get(), NULL); 6023 if (generateResult != 1) { 6024 return NULL; 6025 } 6026 return rsa.release(); 6027 } 6028 6029 /** 6030 * Call back to ask for an ephemeral RSA key for SSL_RSA_EXPORT_WITH_RC4_40_MD5 (aka EXP-RC4-MD5) 6031 */ 6032 static RSA* tmp_rsa_callback(SSL* ssl __attribute__ ((unused)), 6033 int is_export __attribute__ ((unused)), 6034 int keylength) { 6035 JNI_TRACE("ssl=%p tmp_rsa_callback is_export=%d keylength=%d", ssl, is_export, keylength); 6036 6037 AppData* appData = toAppData(ssl); 6038 if (appData->ephemeralRsa.get() == NULL) { 6039 JNI_TRACE("ssl=%p tmp_rsa_callback generating ephemeral RSA key", ssl); 6040 appData->ephemeralRsa.reset(rsaGenerateKey(keylength)); 6041 } 6042 JNI_TRACE("ssl=%p tmp_rsa_callback => %p", ssl, appData->ephemeralRsa.get()); 6043 return appData->ephemeralRsa.get(); 6044 } 6045 6046 static DH* dhGenerateParameters(int keylength) { 6047 6048 /* 6049 * The SSL_CTX_set_tmp_dh_callback(3SSL) man page discusses two 6050 * different options for generating DH keys. One is generating the 6051 * keys using a single set of DH parameters. However, generating 6052 * DH parameters is slow enough (minutes) that they suggest doing 6053 * it once at install time. The other is to generate DH keys from 6054 * DSA parameters. Generating DSA parameters is faster than DH 6055 * parameters, but to prevent small subgroup attacks, they needed 6056 * to be regenerated for each set of DH keys. Setting the 6057 * SSL_OP_SINGLE_DH_USE option make sure OpenSSL will call back 6058 * for new DH parameters every type it needs to generate DH keys. 6059 */ 6060 #if 0 6061 // Slow path that takes minutes but could be cached 6062 Unique_DH dh(DH_new()); 6063 if (!DH_generate_parameters_ex(dh.get(), keylength, 2, NULL)) { 6064 return NULL; 6065 } 6066 return dh.release(); 6067 #else 6068 // Faster path but must have SSL_OP_SINGLE_DH_USE set 6069 Unique_DSA dsa(DSA_new()); 6070 if (!DSA_generate_parameters_ex(dsa.get(), keylength, NULL, 0, NULL, NULL, NULL)) { 6071 return NULL; 6072 } 6073 DH* dh = DSA_dup_DH(dsa.get()); 6074 return dh; 6075 #endif 6076 } 6077 6078 /** 6079 * Call back to ask for Diffie-Hellman parameters 6080 */ 6081 static DH* tmp_dh_callback(SSL* ssl __attribute__ ((unused)), 6082 int is_export __attribute__ ((unused)), 6083 int keylength) { 6084 JNI_TRACE("ssl=%p tmp_dh_callback is_export=%d keylength=%d", ssl, is_export, keylength); 6085 DH* tmp_dh = dhGenerateParameters(keylength); 6086 JNI_TRACE("ssl=%p tmp_dh_callback => %p", ssl, tmp_dh); 6087 return tmp_dh; 6088 } 6089 6090 static EC_KEY* ecGenerateKey(int keylength __attribute__ ((unused))) { 6091 // TODO selected curve based on keylength 6092 Unique_EC_KEY ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); 6093 if (ec.get() == NULL) { 6094 return NULL; 6095 } 6096 return ec.release(); 6097 } 6098 6099 /** 6100 * Call back to ask for an ephemeral EC key for TLS_ECDHE_* cipher suites 6101 */ 6102 static EC_KEY* tmp_ecdh_callback(SSL* ssl __attribute__ ((unused)), 6103 int is_export __attribute__ ((unused)), 6104 int keylength) { 6105 JNI_TRACE("ssl=%p tmp_ecdh_callback is_export=%d keylength=%d", ssl, is_export, keylength); 6106 AppData* appData = toAppData(ssl); 6107 if (appData->ephemeralEc.get() == NULL) { 6108 JNI_TRACE("ssl=%p tmp_ecdh_callback generating ephemeral EC key", ssl); 6109 appData->ephemeralEc.reset(ecGenerateKey(keylength)); 6110 } 6111 JNI_TRACE("ssl=%p tmp_ecdh_callback => %p", ssl, appData->ephemeralEc.get()); 6112 return appData->ephemeralEc.get(); 6113 } 6114 6115 /* 6116 * public static native int SSL_CTX_new(); 6117 */ 6118 static jlong NativeCrypto_SSL_CTX_new(JNIEnv* env, jclass) { 6119 Unique_SSL_CTX sslCtx(SSL_CTX_new(SSLv23_method())); 6120 if (sslCtx.get() == NULL) { 6121 throwExceptionIfNecessary(env, "SSL_CTX_new"); 6122 return 0; 6123 } 6124 SSL_CTX_set_options(sslCtx.get(), 6125 SSL_OP_ALL 6126 // Note: We explicitly do not allow SSLv2 to be used. 6127 | SSL_OP_NO_SSLv2 6128 // We also disable session tickets for better compatibility b/2682876 6129 | SSL_OP_NO_TICKET 6130 // We also disable compression for better compatibility b/2710492 b/2710497 6131 | SSL_OP_NO_COMPRESSION 6132 // Because dhGenerateParameters uses DSA_generate_parameters_ex 6133 | SSL_OP_SINGLE_DH_USE 6134 // Because ecGenerateParameters uses a fixed named curve 6135 | SSL_OP_SINGLE_ECDH_USE); 6136 6137 int mode = SSL_CTX_get_mode(sslCtx.get()); 6138 /* 6139 * Turn on "partial write" mode. This means that SSL_write() will 6140 * behave like Posix write() and possibly return after only 6141 * writing a partial buffer. Note: The alternative, perhaps 6142 * surprisingly, is not that SSL_write() always does full writes 6143 * but that it will force you to retry write calls having 6144 * preserved the full state of the original call. (This is icky 6145 * and undesirable.) 6146 */ 6147 mode |= SSL_MODE_ENABLE_PARTIAL_WRITE; 6148 6149 // Reuse empty buffers within the SSL_CTX to save memory 6150 mode |= SSL_MODE_RELEASE_BUFFERS; 6151 6152 SSL_CTX_set_mode(sslCtx.get(), mode); 6153 6154 SSL_CTX_set_cert_verify_callback(sslCtx.get(), cert_verify_callback, NULL); 6155 SSL_CTX_set_info_callback(sslCtx.get(), info_callback); 6156 SSL_CTX_set_client_cert_cb(sslCtx.get(), client_cert_cb); 6157 SSL_CTX_set_tmp_rsa_callback(sslCtx.get(), tmp_rsa_callback); 6158 SSL_CTX_set_tmp_dh_callback(sslCtx.get(), tmp_dh_callback); 6159 SSL_CTX_set_tmp_ecdh_callback(sslCtx.get(), tmp_ecdh_callback); 6160 6161 JNI_TRACE("NativeCrypto_SSL_CTX_new => %p", sslCtx.get()); 6162 return (jlong) sslCtx.release(); 6163 } 6164 6165 /** 6166 * public static native void SSL_CTX_free(int ssl_ctx) 6167 */ 6168 static void NativeCrypto_SSL_CTX_free(JNIEnv* env, 6169 jclass, jlong ssl_ctx_address) 6170 { 6171 SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); 6172 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_free", ssl_ctx); 6173 if (ssl_ctx == NULL) { 6174 return; 6175 } 6176 SSL_CTX_free(ssl_ctx); 6177 } 6178 6179 static void NativeCrypto_SSL_CTX_set_session_id_context(JNIEnv* env, jclass, 6180 jlong ssl_ctx_address, jbyteArray sid_ctx) 6181 { 6182 SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); 6183 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context sid_ctx=%p", ssl_ctx, sid_ctx); 6184 if (ssl_ctx == NULL) { 6185 return; 6186 } 6187 6188 ScopedByteArrayRO buf(env, sid_ctx); 6189 if (buf.get() == NULL) { 6190 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => threw exception", ssl_ctx); 6191 return; 6192 } 6193 6194 unsigned int length = buf.size(); 6195 if (length > SSL_MAX_SSL_SESSION_ID_LENGTH) { 6196 jniThrowException(env, "java/lang/IllegalArgumentException", 6197 "length > SSL_MAX_SSL_SESSION_ID_LENGTH"); 6198 JNI_TRACE("NativeCrypto_SSL_CTX_set_session_id_context => length = %d", length); 6199 return; 6200 } 6201 const unsigned char* bytes = reinterpret_cast<const unsigned char*>(buf.get()); 6202 int result = SSL_CTX_set_session_id_context(ssl_ctx, bytes, length); 6203 if (result == 0) { 6204 throwExceptionIfNecessary(env, "NativeCrypto_SSL_CTX_set_session_id_context"); 6205 return; 6206 } 6207 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_CTX_set_session_id_context => ok", ssl_ctx); 6208 } 6209 6210 /** 6211 * public static native int SSL_new(int ssl_ctx) throws SSLException; 6212 */ 6213 static jlong NativeCrypto_SSL_new(JNIEnv* env, jclass, jlong ssl_ctx_address) 6214 { 6215 SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); 6216 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new", ssl_ctx); 6217 if (ssl_ctx == NULL) { 6218 return 0; 6219 } 6220 Unique_SSL ssl(SSL_new(ssl_ctx)); 6221 if (ssl.get() == NULL) { 6222 throwSSLExceptionWithSslErrors(env, NULL, SSL_ERROR_NONE, 6223 "Unable to create SSL structure"); 6224 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => NULL", ssl_ctx); 6225 return 0; 6226 } 6227 6228 /* Java code in class OpenSSLSocketImpl does the verification. Meaning of 6229 * SSL_VERIFY_NONE flag in client mode: if not using an anonymous cipher 6230 * (by default disabled), the server will send a certificate which will 6231 * be checked. The result of the certificate verification process can be 6232 * checked after the TLS/SSL handshake using the SSL_get_verify_result(3) 6233 * function. The handshake will be continued regardless of the 6234 * verification result. 6235 */ 6236 SSL_set_verify(ssl.get(), SSL_VERIFY_NONE, NULL); 6237 6238 JNI_TRACE("ssl_ctx=%p NativeCrypto_SSL_new => ssl=%p", ssl_ctx, ssl.get()); 6239 return (jlong) ssl.release(); 6240 } 6241 6242 6243 static void NativeCrypto_SSL_enable_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address) 6244 { 6245 SSL* ssl = to_SSL(env, ssl_address, true); 6246 JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_enable_tls_channel_id", ssl); 6247 if (ssl == NULL) { 6248 return; 6249 } 6250 6251 long ret = SSL_enable_tls_channel_id(ssl); 6252 if (ret != 1L) { 6253 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6254 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error enabling Channel ID"); 6255 SSL_clear(ssl); 6256 JNI_TRACE("ssl=%p NativeCrypto_SSL_enable_tls_channel_id => error", ssl); 6257 return; 6258 } 6259 } 6260 6261 static jbyteArray NativeCrypto_SSL_get_tls_channel_id(JNIEnv* env, jclass, jlong ssl_address) 6262 { 6263 SSL* ssl = to_SSL(env, ssl_address, true); 6264 JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id", ssl); 6265 if (ssl == NULL) { 6266 return NULL; 6267 } 6268 6269 // Channel ID is 64 bytes long. Unfortunately, OpenSSL doesn't declare this length 6270 // as a constant anywhere. 6271 jbyteArray javaBytes = env->NewByteArray(64); 6272 ScopedByteArrayRW bytes(env, javaBytes); 6273 if (bytes.get() == NULL) { 6274 JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => NULL", ssl); 6275 return NULL; 6276 } 6277 6278 unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get()); 6279 // Unfortunately, the SSL_get_tls_channel_id method below always returns 64 (upon success) 6280 // regardless of the number of bytes copied into the output buffer "tmp". Thus, the correctness 6281 // of this code currently relies on the "tmp" buffer being exactly 64 bytes long. 6282 long ret = SSL_get_tls_channel_id(ssl, tmp, 64); 6283 if (ret == 0) { 6284 // Channel ID either not set or did not verify 6285 JNI_TRACE("NativeCrypto_SSL_get_tls_channel_id(%p) => not available", ssl); 6286 return NULL; 6287 } else if (ret != 64) { 6288 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6289 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error getting Channel ID"); 6290 SSL_clear(ssl); 6291 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_tls_channel_id => error, returned %ld", ssl, ret); 6292 return NULL; 6293 } 6294 6295 JNI_TRACE("ssl=%p NativeCrypto_NativeCrypto_SSL_get_tls_channel_id() => %p", ssl, javaBytes); 6296 return javaBytes; 6297 } 6298 6299 static void NativeCrypto_SSL_set1_tls_channel_id(JNIEnv* env, jclass, 6300 jlong ssl_address, jlong pkeyRef) 6301 { 6302 SSL* ssl = to_SSL(env, ssl_address, true); 6303 EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef); 6304 JNI_TRACE("ssl=%p SSL_set1_tls_channel_id privatekey=%p", ssl, pkey); 6305 if (ssl == NULL) { 6306 return; 6307 } 6308 6309 if (pkey == NULL) { 6310 jniThrowNullPointerException(env, "pkey == null"); 6311 JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => pkey == null", ssl); 6312 return; 6313 } 6314 6315 // SSL_set1_tls_channel_id requires ssl->server to be set to 0. 6316 // Unfortunately, the default value is 1 and it's only changed to 0 just 6317 // before the handshake starts (see NativeCrypto_SSL_do_handshake). 6318 ssl->server = 0; 6319 long ret = SSL_set1_tls_channel_id(ssl, pkey); 6320 6321 if (ret != 1L) { 6322 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6323 throwSSLExceptionWithSslErrors( 6324 env, ssl, SSL_ERROR_NONE, "Error setting private key for Channel ID"); 6325 SSL_clear(ssl); 6326 JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => error", ssl); 6327 return; 6328 } 6329 // SSL_set1_tls_channel_id expects to take ownership of the EVP_PKEY, but 6330 // we have an external reference from the caller such as an OpenSSLKey, 6331 // so we manually increment the reference count here. 6332 CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY); 6333 6334 JNI_TRACE("ssl=%p SSL_set1_tls_channel_id => ok", ssl); 6335 } 6336 6337 static void NativeCrypto_SSL_use_PrivateKey(JNIEnv* env, jclass, jlong ssl_address, jlong pkeyRef) { 6338 SSL* ssl = to_SSL(env, ssl_address, true); 6339 EVP_PKEY* pkey = reinterpret_cast<EVP_PKEY*>(pkeyRef); 6340 JNI_TRACE("ssl=%p SSL_use_PrivateKey privatekey=%p", ssl, pkey); 6341 if (ssl == NULL) { 6342 return; 6343 } 6344 6345 if (pkey == NULL) { 6346 jniThrowNullPointerException(env, "pkey == null"); 6347 JNI_TRACE("ssl=%p SSL_use_PrivateKey => pkey == null", ssl); 6348 return; 6349 } 6350 6351 int ret = SSL_use_PrivateKey(ssl, pkey); 6352 if (ret != 1) { 6353 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6354 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting private key"); 6355 SSL_clear(ssl); 6356 JNI_TRACE("ssl=%p SSL_use_PrivateKey => error", ssl); 6357 return; 6358 } 6359 // SSL_use_PrivateKey expects to take ownership of the EVP_PKEY, 6360 // but we have an external reference from the caller such as an 6361 // OpenSSLKey, so we manually increment the reference count here. 6362 CRYPTO_add(&pkey->references,+1,CRYPTO_LOCK_EVP_PKEY); 6363 6364 JNI_TRACE("ssl=%p SSL_use_PrivateKey => ok", ssl); 6365 } 6366 6367 static void NativeCrypto_SSL_use_certificate(JNIEnv* env, jclass, 6368 jlong ssl_address, jobjectArray certificates) 6369 { 6370 SSL* ssl = to_SSL(env, ssl_address, true); 6371 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate certificates=%p", ssl, certificates); 6372 if (ssl == NULL) { 6373 return; 6374 } 6375 6376 if (certificates == NULL) { 6377 jniThrowNullPointerException(env, "certificates == null"); 6378 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates == null", ssl); 6379 return; 6380 } 6381 6382 int length = env->GetArrayLength(certificates); 6383 if (length == 0) { 6384 jniThrowException(env, "java/lang/IllegalArgumentException", "certificates.length == 0"); 6385 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates.length == 0", ssl); 6386 return; 6387 } 6388 6389 X509Chain certificatesX509(length); 6390 for (int i = 0; i < length; i++) { 6391 ScopedLocalRef<jbyteArray> certificate(env, 6392 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(certificates, i))); 6393 if (certificate.get() == NULL) { 6394 jniThrowNullPointerException(env, "certificates element == null"); 6395 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates element null", ssl); 6396 return; 6397 } 6398 6399 ScopedByteArrayRO buf(env, certificate.get()); 6400 if (buf.get() == NULL) { 6401 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => threw exception", ssl); 6402 return; 6403 } 6404 const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get()); 6405 certificatesX509[i] = d2i_X509(NULL, &tmp, buf.size()); 6406 6407 if (certificatesX509[i] == NULL) { 6408 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6409 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing certificate"); 6410 SSL_clear(ssl); 6411 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificates parsing error", ssl); 6412 return; 6413 } 6414 } 6415 6416 int ret = SSL_use_certificate(ssl, certificatesX509[0]); 6417 if (ret == 1) { 6418 certificatesX509.release(0); 6419 } else { 6420 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6421 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate"); 6422 SSL_clear(ssl); 6423 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate error", ssl); 6424 return; 6425 } 6426 6427 Unique_sk_X509 chain(sk_X509_new_null()); 6428 if (chain.get() == NULL) { 6429 jniThrowOutOfMemory(env, "Unable to allocate local certificate chain"); 6430 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => chain allocation error", ssl); 6431 return; 6432 } 6433 for (int i = 1; i < length; i++) { 6434 if (!sk_X509_push(chain.get(), certificatesX509.release(i))) { 6435 jniThrowOutOfMemory(env, "Unable to push certificate"); 6436 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => certificate push error", ssl); 6437 return; 6438 } 6439 } 6440 int chainResult = SSL_use_certificate_chain(ssl, chain.get()); 6441 if (chainResult == 0) { 6442 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting certificate chain"); 6443 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => SSL_use_certificate_chain error", 6444 ssl); 6445 return; 6446 } else { 6447 OWNERSHIP_TRANSFERRED(chain); 6448 } 6449 6450 JNI_TRACE("ssl=%p NativeCrypto_SSL_use_certificate => ok", ssl); 6451 } 6452 6453 static void NativeCrypto_SSL_check_private_key(JNIEnv* env, jclass, jlong ssl_address) 6454 { 6455 SSL* ssl = to_SSL(env, ssl_address, true); 6456 JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key", ssl); 6457 if (ssl == NULL) { 6458 return; 6459 } 6460 int ret = SSL_check_private_key(ssl); 6461 if (ret != 1) { 6462 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error checking private key"); 6463 SSL_clear(ssl); 6464 JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => error", ssl); 6465 return; 6466 } 6467 JNI_TRACE("ssl=%p NativeCrypto_SSL_check_private_key => ok", ssl); 6468 } 6469 6470 static void NativeCrypto_SSL_set_client_CA_list(JNIEnv* env, jclass, 6471 jlong ssl_address, jobjectArray principals) 6472 { 6473 SSL* ssl = to_SSL(env, ssl_address, true); 6474 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list principals=%p", ssl, principals); 6475 if (ssl == NULL) { 6476 return; 6477 } 6478 6479 if (principals == NULL) { 6480 jniThrowNullPointerException(env, "principals == null"); 6481 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals == null", ssl); 6482 return; 6483 } 6484 6485 int length = env->GetArrayLength(principals); 6486 if (length == 0) { 6487 jniThrowException(env, "java/lang/IllegalArgumentException", "principals.length == 0"); 6488 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals.length == 0", ssl); 6489 return; 6490 } 6491 6492 Unique_sk_X509_NAME principalsStack(sk_X509_NAME_new_null()); 6493 if (principalsStack.get() == NULL) { 6494 jniThrowOutOfMemory(env, "Unable to allocate principal stack"); 6495 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => stack allocation error", ssl); 6496 return; 6497 } 6498 for (int i = 0; i < length; i++) { 6499 ScopedLocalRef<jbyteArray> principal(env, 6500 reinterpret_cast<jbyteArray>(env->GetObjectArrayElement(principals, i))); 6501 if (principal.get() == NULL) { 6502 jniThrowNullPointerException(env, "principals element == null"); 6503 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals element null", ssl); 6504 return; 6505 } 6506 6507 ScopedByteArrayRO buf(env, principal.get()); 6508 if (buf.get() == NULL) { 6509 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => threw exception", ssl); 6510 return; 6511 } 6512 const unsigned char* tmp = reinterpret_cast<const unsigned char*>(buf.get()); 6513 Unique_X509_NAME principalX509Name(d2i_X509_NAME(NULL, &tmp, buf.size())); 6514 6515 if (principalX509Name.get() == NULL) { 6516 ALOGE("%s", ERR_error_string(ERR_peek_error(), NULL)); 6517 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error parsing principal"); 6518 SSL_clear(ssl); 6519 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principals parsing error", 6520 ssl); 6521 return; 6522 } 6523 6524 if (!sk_X509_NAME_push(principalsStack.get(), principalX509Name.release())) { 6525 jniThrowOutOfMemory(env, "Unable to push principal"); 6526 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => principal push error", ssl); 6527 return; 6528 } 6529 } 6530 6531 SSL_set_client_CA_list(ssl, principalsStack.release()); 6532 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_client_CA_list => ok", ssl); 6533 } 6534 6535 /** 6536 * public static native long SSL_get_mode(int ssl); 6537 */ 6538 static jlong NativeCrypto_SSL_get_mode(JNIEnv* env, jclass, jlong ssl_address) { 6539 SSL* ssl = to_SSL(env, ssl_address, true); 6540 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode", ssl); 6541 if (ssl == NULL) { 6542 return 0; 6543 } 6544 long mode = SSL_get_mode(ssl); 6545 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_mode => 0x%lx", ssl, mode); 6546 return mode; 6547 } 6548 6549 /** 6550 * public static native long SSL_set_mode(int ssl, long mode); 6551 */ 6552 static jlong NativeCrypto_SSL_set_mode(JNIEnv* env, jclass, 6553 jlong ssl_address, jlong mode) { 6554 SSL* ssl = to_SSL(env, ssl_address, true); 6555 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode mode=0x%llx", ssl, mode); 6556 if (ssl == NULL) { 6557 return 0; 6558 } 6559 long result = SSL_set_mode(ssl, mode); 6560 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_mode => 0x%lx", ssl, result); 6561 return result; 6562 } 6563 6564 /** 6565 * public static native long SSL_clear_mode(int ssl, long mode); 6566 */ 6567 static jlong NativeCrypto_SSL_clear_mode(JNIEnv* env, jclass, 6568 jlong ssl_address, jlong mode) { 6569 SSL* ssl = to_SSL(env, ssl_address, true); 6570 JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode mode=0x%llx", ssl, mode); 6571 if (ssl == NULL) { 6572 return 0; 6573 } 6574 long result = SSL_clear_mode(ssl, mode); 6575 JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_mode => 0x%lx", ssl, result); 6576 return result; 6577 } 6578 6579 /** 6580 * public static native long SSL_get_options(int ssl); 6581 */ 6582 static jlong NativeCrypto_SSL_get_options(JNIEnv* env, jclass, 6583 jlong ssl_address) { 6584 SSL* ssl = to_SSL(env, ssl_address, true); 6585 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options", ssl); 6586 if (ssl == NULL) { 6587 return 0; 6588 } 6589 long options = SSL_get_options(ssl); 6590 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_options => 0x%lx", ssl, options); 6591 return options; 6592 } 6593 6594 /** 6595 * public static native long SSL_set_options(int ssl, long options); 6596 */ 6597 static jlong NativeCrypto_SSL_set_options(JNIEnv* env, jclass, 6598 jlong ssl_address, jlong options) { 6599 SSL* ssl = to_SSL(env, ssl_address, true); 6600 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options options=0x%llx", ssl, options); 6601 if (ssl == NULL) { 6602 return 0; 6603 } 6604 long result = SSL_set_options(ssl, options); 6605 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_options => 0x%lx", ssl, result); 6606 return result; 6607 } 6608 6609 /** 6610 * public static native long SSL_clear_options(int ssl, long options); 6611 */ 6612 static jlong NativeCrypto_SSL_clear_options(JNIEnv* env, jclass, 6613 jlong ssl_address, jlong options) { 6614 SSL* ssl = to_SSL(env, ssl_address, true); 6615 JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options options=0x%llx", ssl, options); 6616 if (ssl == NULL) { 6617 return 0; 6618 } 6619 long result = SSL_clear_options(ssl, options); 6620 JNI_TRACE("ssl=%p NativeCrypto_SSL_clear_options => 0x%lx", ssl, result); 6621 return result; 6622 } 6623 6624 /** 6625 * Sets the ciphers suites that are enabled in the SSL 6626 */ 6627 static void NativeCrypto_SSL_set_cipher_lists(JNIEnv* env, jclass, 6628 jlong ssl_address, jobjectArray cipherSuites) 6629 { 6630 SSL* ssl = to_SSL(env, ssl_address, true); 6631 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuites=%p", ssl, cipherSuites); 6632 if (ssl == NULL) { 6633 return; 6634 } 6635 if (cipherSuites == NULL) { 6636 jniThrowNullPointerException(env, "cipherSuites == null"); 6637 return; 6638 } 6639 6640 Unique_sk_SSL_CIPHER cipherstack(sk_SSL_CIPHER_new_null()); 6641 if (cipherstack.get() == NULL) { 6642 jniThrowRuntimeException(env, "sk_SSL_CIPHER_new_null failed"); 6643 return; 6644 } 6645 6646 const SSL_METHOD* ssl_method = ssl->method; 6647 int num_ciphers = ssl_method->num_ciphers(); 6648 6649 int length = env->GetArrayLength(cipherSuites); 6650 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists length=%d", ssl, length); 6651 for (int i = 0; i < length; i++) { 6652 ScopedLocalRef<jstring> cipherSuite(env, 6653 reinterpret_cast<jstring>(env->GetObjectArrayElement(cipherSuites, i))); 6654 ScopedUtfChars c(env, cipherSuite.get()); 6655 if (c.c_str() == NULL) { 6656 return; 6657 } 6658 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists cipherSuite=%s", ssl, c.c_str()); 6659 bool found = false; 6660 for (int j = 0; j < num_ciphers; j++) { 6661 const SSL_CIPHER* cipher = ssl_method->get_cipher(j); 6662 if ((strcmp(c.c_str(), cipher->name) == 0) 6663 && (strcmp(SSL_CIPHER_get_version(cipher), "SSLv2"))) { 6664 if (!sk_SSL_CIPHER_push(cipherstack.get(), cipher)) { 6665 jniThrowOutOfMemory(env, "Unable to push cipher"); 6666 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_cipher_lists => cipher push error", ssl); 6667 return; 6668 } 6669 found = true; 6670 } 6671 } 6672 if (!found) { 6673 jniThrowException(env, "java/lang/IllegalArgumentException", 6674 "Could not find cipher suite."); 6675 return; 6676 } 6677 } 6678 6679 int rc = SSL_set_cipher_lists(ssl, cipherstack.get()); 6680 if (rc == 0) { 6681 freeOpenSslErrorState(); 6682 jniThrowException(env, "java/lang/IllegalArgumentException", 6683 "Illegal cipher suite strings."); 6684 } else { 6685 OWNERSHIP_TRANSFERRED(cipherstack); 6686 } 6687 } 6688 6689 /** 6690 * Sets certificate expectations, especially for server to request client auth 6691 */ 6692 static void NativeCrypto_SSL_set_verify(JNIEnv* env, 6693 jclass, jlong ssl_address, jint mode) 6694 { 6695 SSL* ssl = to_SSL(env, ssl_address, true); 6696 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_verify mode=%x", ssl, mode); 6697 if (ssl == NULL) { 6698 return; 6699 } 6700 SSL_set_verify(ssl, (int)mode, NULL); 6701 } 6702 6703 /** 6704 * Sets the ciphers suites that are enabled in the SSL 6705 */ 6706 static void NativeCrypto_SSL_set_session(JNIEnv* env, jclass, 6707 jlong ssl_address, jlong ssl_session_address) 6708 { 6709 SSL* ssl = to_SSL(env, ssl_address, true); 6710 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, false); 6711 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session ssl_session=%p", ssl, ssl_session); 6712 if (ssl == NULL) { 6713 return; 6714 } 6715 6716 int ret = SSL_set_session(ssl, ssl_session); 6717 if (ret != 1) { 6718 /* 6719 * Translate the error, and throw if it turns out to be a real 6720 * problem. 6721 */ 6722 int sslErrorCode = SSL_get_error(ssl, ret); 6723 if (sslErrorCode != SSL_ERROR_ZERO_RETURN) { 6724 throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "SSL session set"); 6725 SSL_clear(ssl); 6726 } 6727 } 6728 } 6729 6730 /** 6731 * Sets the ciphers suites that are enabled in the SSL 6732 */ 6733 static void NativeCrypto_SSL_set_session_creation_enabled(JNIEnv* env, jclass, 6734 jlong ssl_address, jboolean creation_enabled) 6735 { 6736 SSL* ssl = to_SSL(env, ssl_address, true); 6737 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_session_creation_enabled creation_enabled=%d", 6738 ssl, creation_enabled); 6739 if (ssl == NULL) { 6740 return; 6741 } 6742 SSL_set_session_creation_enabled(ssl, creation_enabled); 6743 } 6744 6745 static void NativeCrypto_SSL_set_tlsext_host_name(JNIEnv* env, jclass, 6746 jlong ssl_address, jstring hostname) 6747 { 6748 SSL* ssl = to_SSL(env, ssl_address, true); 6749 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostname=%p", 6750 ssl, hostname); 6751 if (ssl == NULL) { 6752 return; 6753 } 6754 6755 ScopedUtfChars hostnameChars(env, hostname); 6756 if (hostnameChars.c_str() == NULL) { 6757 return; 6758 } 6759 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name hostnameChars=%s", 6760 ssl, hostnameChars.c_str()); 6761 6762 int ret = SSL_set_tlsext_host_name(ssl, hostnameChars.c_str()); 6763 if (ret != 1) { 6764 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, "Error setting host name"); 6765 SSL_clear(ssl); 6766 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => error", ssl); 6767 return; 6768 } 6769 JNI_TRACE("ssl=%p NativeCrypto_SSL_set_tlsext_host_name => ok", ssl); 6770 } 6771 6772 static jstring NativeCrypto_SSL_get_servername(JNIEnv* env, jclass, jlong ssl_address) { 6773 SSL* ssl = to_SSL(env, ssl_address, true); 6774 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername", ssl); 6775 if (ssl == NULL) { 6776 return NULL; 6777 } 6778 const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); 6779 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_servername => %s", ssl, servername); 6780 return env->NewStringUTF(servername); 6781 } 6782 6783 /** 6784 * A common selection path for both NPN and ALPN since they're essentially the 6785 * same protocol. The list of protocols in "primary" is considered the order 6786 * which should take precedence. 6787 */ 6788 static int proto_select(SSL* ssl __attribute__ ((unused)), 6789 unsigned char **out, unsigned char *outLength, 6790 const unsigned char *primary, const unsigned int primaryLength, 6791 const unsigned char *secondary, const unsigned int secondaryLength) { 6792 if (primary != NULL) { 6793 JNI_TRACE("primary=%p, length=%d", primary, primaryLength); 6794 6795 int status = SSL_select_next_proto(out, outLength, primary, primaryLength, secondary, 6796 secondaryLength); 6797 switch (status) { 6798 case OPENSSL_NPN_NEGOTIATED: 6799 JNI_TRACE("ssl=%p proto_select NPN/ALPN negotiated", ssl); 6800 return SSL_TLSEXT_ERR_OK; 6801 break; 6802 case OPENSSL_NPN_UNSUPPORTED: 6803 JNI_TRACE("ssl=%p proto_select NPN/ALPN unsupported", ssl); 6804 break; 6805 case OPENSSL_NPN_NO_OVERLAP: 6806 JNI_TRACE("ssl=%p proto_select NPN/ALPN no overlap", ssl); 6807 break; 6808 } 6809 } else { 6810 if (out != NULL && outLength != NULL) { 6811 *out = NULL; 6812 *outLength = 0; 6813 } 6814 JNI_TRACE("protocols=NULL"); 6815 } 6816 return SSL_TLSEXT_ERR_NOACK; 6817 } 6818 6819 /** 6820 * Callback for the server to select an ALPN protocol. 6821 */ 6822 static int alpn_select_callback(SSL* ssl, const unsigned char **out, unsigned char *outlen, 6823 const unsigned char *in, unsigned int inlen, void *) { 6824 JNI_TRACE("ssl=%p alpn_select_callback", ssl); 6825 6826 AppData* appData = toAppData(ssl); 6827 JNI_TRACE("AppData=%p", appData); 6828 6829 return proto_select(ssl, const_cast<unsigned char **>(out), outlen, 6830 reinterpret_cast<unsigned char*>(appData->alpnProtocolsData), 6831 appData->alpnProtocolsLength, in, inlen); 6832 } 6833 6834 /** 6835 * Callback for the client to select an NPN protocol. 6836 */ 6837 static int next_proto_select_callback(SSL* ssl, unsigned char** out, unsigned char* outlen, 6838 const unsigned char* in, unsigned int inlen, void*) 6839 { 6840 JNI_TRACE("ssl=%p next_proto_select_callback", ssl); 6841 6842 AppData* appData = toAppData(ssl); 6843 JNI_TRACE("AppData=%p", appData); 6844 6845 // Enable False Start on the client if the server understands NPN 6846 // http://www.imperialviolet.org/2012/04/11/falsestart.html 6847 SSL_set_mode(ssl, SSL_MODE_HANDSHAKE_CUTTHROUGH); 6848 6849 return proto_select(ssl, out, outlen, in, inlen, 6850 reinterpret_cast<unsigned char*>(appData->npnProtocolsData), 6851 appData->npnProtocolsLength); 6852 } 6853 6854 /** 6855 * Callback for the server to advertise available protocols. 6856 */ 6857 static int next_protos_advertised_callback(SSL* ssl, 6858 const unsigned char **out, unsigned int *outlen, void *) 6859 { 6860 JNI_TRACE("ssl=%p next_protos_advertised_callback", ssl); 6861 AppData* appData = toAppData(ssl); 6862 unsigned char* npnProtocols = reinterpret_cast<unsigned char*>(appData->npnProtocolsData); 6863 if (npnProtocols != NULL) { 6864 *out = npnProtocols; 6865 *outlen = appData->npnProtocolsLength; 6866 return SSL_TLSEXT_ERR_OK; 6867 } else { 6868 *out = NULL; 6869 *outlen = 0; 6870 return SSL_TLSEXT_ERR_NOACK; 6871 } 6872 } 6873 6874 static void NativeCrypto_SSL_CTX_enable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address) 6875 { 6876 SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); 6877 if (ssl_ctx == NULL) { 6878 return; 6879 } 6880 SSL_CTX_set_next_proto_select_cb(ssl_ctx, next_proto_select_callback, NULL); // client 6881 SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_protos_advertised_callback, NULL); // server 6882 } 6883 6884 static void NativeCrypto_SSL_CTX_disable_npn(JNIEnv* env, jclass, jlong ssl_ctx_address) 6885 { 6886 SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); 6887 if (ssl_ctx == NULL) { 6888 return; 6889 } 6890 SSL_CTX_set_next_proto_select_cb(ssl_ctx, NULL, NULL); // client 6891 SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, NULL, NULL); // server 6892 } 6893 6894 static jbyteArray NativeCrypto_SSL_get_npn_negotiated_protocol(JNIEnv* env, jclass, 6895 jlong ssl_address) 6896 { 6897 SSL* ssl = to_SSL(env, ssl_address, true); 6898 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_npn_negotiated_protocol", ssl); 6899 if (ssl == NULL) { 6900 return NULL; 6901 } 6902 const jbyte* npn; 6903 unsigned npnLength; 6904 SSL_get0_next_proto_negotiated(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength); 6905 if (npnLength == 0) { 6906 return NULL; 6907 } 6908 jbyteArray result = env->NewByteArray(npnLength); 6909 if (result != NULL) { 6910 env->SetByteArrayRegion(result, 0, npnLength, npn); 6911 } 6912 return result; 6913 } 6914 6915 static int NativeCrypto_SSL_CTX_set_alpn_protos(JNIEnv* env, jclass, jlong ssl_ctx_address, 6916 jbyteArray protos) { 6917 SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); 6918 if (ssl_ctx == NULL) { 6919 return 0; 6920 } 6921 6922 JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p", ssl_ctx, protos); 6923 6924 if (protos == NULL) { 6925 JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=NULL", ssl_ctx); 6926 return 1; 6927 } 6928 6929 ScopedByteArrayRO protosBytes(env, protos); 6930 if (protosBytes.get() == NULL) { 6931 JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p => protosBytes == NULL", ssl_ctx, 6932 protos); 6933 return 0; 6934 } 6935 6936 const unsigned char *tmp = reinterpret_cast<const unsigned char*>(protosBytes.get()); 6937 int ret = SSL_CTX_set_alpn_protos(ssl_ctx, tmp, protosBytes.size()); 6938 JNI_TRACE("ssl_ctx=%p SSL_CTX_set_alpn_protos protos=%p => ret=%d", ssl_ctx, protos, ret); 6939 return ret; 6940 } 6941 6942 static jbyteArray NativeCrypto_SSL_get0_alpn_selected(JNIEnv* env, jclass, 6943 jlong ssl_address) 6944 { 6945 SSL* ssl = to_SSL(env, ssl_address, true); 6946 JNI_TRACE("ssl=%p SSL_get0_alpn_selected", ssl); 6947 if (ssl == NULL) { 6948 return NULL; 6949 } 6950 const jbyte* npn; 6951 unsigned npnLength; 6952 SSL_get0_alpn_selected(ssl, reinterpret_cast<const unsigned char**>(&npn), &npnLength); 6953 if (npnLength == 0) { 6954 return NULL; 6955 } 6956 jbyteArray result = env->NewByteArray(npnLength); 6957 if (result != NULL) { 6958 env->SetByteArrayRegion(result, 0, npnLength, npn); 6959 } 6960 return result; 6961 } 6962 6963 #ifdef WITH_JNI_TRACE_KEYS 6964 static inline char hex_char(unsigned char in) 6965 { 6966 if (in < 10) { 6967 return '0' + in; 6968 } else if (in <= 0xF0) { 6969 return 'A' + in - 10; 6970 } else { 6971 return '?'; 6972 } 6973 } 6974 6975 static void hex_string(char **dest, unsigned char* input, int len) 6976 { 6977 *dest = (char*) malloc(len * 2 + 1); 6978 char *output = *dest; 6979 for (int i = 0; i < len; i++) { 6980 *output++ = hex_char(input[i] >> 4); 6981 *output++ = hex_char(input[i] & 0xF); 6982 } 6983 *output = '\0'; 6984 } 6985 6986 static void debug_print_session_key(SSL_SESSION* session) 6987 { 6988 char *session_id_str; 6989 char *master_key_str; 6990 const char *key_type; 6991 char *keyline; 6992 6993 hex_string(&session_id_str, session->session_id, session->session_id_length); 6994 hex_string(&master_key_str, session->master_key, session->master_key_length); 6995 6996 X509* peer = SSL_SESSION_get0_peer(session); 6997 EVP_PKEY* pkey = X509_PUBKEY_get(peer->cert_info->key); 6998 switch (EVP_PKEY_type(pkey->type)) { 6999 case EVP_PKEY_RSA: 7000 key_type = "RSA"; 7001 break; 7002 case EVP_PKEY_DSA: 7003 key_type = "DSA"; 7004 break; 7005 case EVP_PKEY_EC: 7006 key_type = "EC"; 7007 break; 7008 default: 7009 key_type = "Unknown"; 7010 break; 7011 } 7012 7013 asprintf(&keyline, "%s Session-ID:%s Master-Key:%s\n", key_type, session_id_str, 7014 master_key_str); 7015 JNI_TRACE("ssl_session=%p %s", session, keyline); 7016 7017 free(session_id_str); 7018 free(master_key_str); 7019 free(keyline); 7020 } 7021 #endif /* WITH_JNI_TRACE_KEYS */ 7022 7023 /** 7024 * Perform SSL handshake 7025 */ 7026 static jlong NativeCrypto_SSL_do_handshake(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject, 7027 jobject shc, jint timeout_millis, jboolean client_mode, jbyteArray npnProtocols, 7028 jbyteArray alpnProtocols) { 7029 SSL* ssl = to_SSL(env, ssl_address, true); 7030 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd=%p shc=%p timeout_millis=%d client_mode=%d npn=%p", 7031 ssl, fdObject, shc, timeout_millis, client_mode, npnProtocols); 7032 if (ssl == NULL) { 7033 return 0; 7034 } 7035 if (fdObject == NULL) { 7036 jniThrowNullPointerException(env, "fd == null"); 7037 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd == null => 0", ssl); 7038 return 0; 7039 } 7040 if (shc == NULL) { 7041 jniThrowNullPointerException(env, "sslHandshakeCallbacks == null"); 7042 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslHandshakeCallbacks == null => 0", ssl); 7043 return 0; 7044 } 7045 7046 NetFd fd(env, fdObject); 7047 if (fd.isClosed()) { 7048 // SocketException thrown by NetFd.isClosed 7049 SSL_clear(ssl); 7050 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake fd.isClosed() => 0", ssl); 7051 return 0; 7052 } 7053 7054 int ret = SSL_set_fd(ssl, fd.get()); 7055 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake s=%d", ssl, fd.get()); 7056 7057 if (ret != 1) { 7058 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_NONE, 7059 "Error setting the file descriptor"); 7060 SSL_clear(ssl); 7061 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake SSL_set_fd => 0", ssl); 7062 return 0; 7063 } 7064 7065 /* 7066 * Make socket non-blocking, so SSL_connect SSL_read() and SSL_write() don't hang 7067 * forever and we can use select() to find out if the socket is ready. 7068 */ 7069 if (!setBlocking(fd.get(), false)) { 7070 throwSSLExceptionStr(env, "Unable to make socket non blocking"); 7071 SSL_clear(ssl); 7072 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setBlocking => 0", ssl); 7073 return 0; 7074 } 7075 7076 /* 7077 * Create our special application data. 7078 */ 7079 AppData* appData = AppData::create(); 7080 if (appData == NULL) { 7081 throwSSLExceptionStr(env, "Unable to create application data"); 7082 SSL_clear(ssl); 7083 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake appData => 0", ssl); 7084 return 0; 7085 } 7086 7087 SSL_set_app_data(ssl, reinterpret_cast<char*>(appData)); 7088 JNI_TRACE("ssl=%p AppData::create => %p", ssl, appData); 7089 7090 if (client_mode) { 7091 SSL_set_connect_state(ssl); 7092 } else { 7093 SSL_set_accept_state(ssl); 7094 if (alpnProtocols != NULL) { 7095 SSL_CTX_set_alpn_select_cb(SSL_get_SSL_CTX(ssl), alpn_select_callback, NULL); 7096 } 7097 } 7098 7099 ret = 0; 7100 while (appData->aliveAndKicking) { 7101 errno = 0; 7102 7103 if (!appData->setCallbackState(env, shc, fdObject, npnProtocols, alpnProtocols)) { 7104 // SocketException thrown by NetFd.isClosed 7105 SSL_clear(ssl); 7106 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake setCallbackState => 0", ssl); 7107 return 0; 7108 } 7109 ret = SSL_do_handshake(ssl); 7110 appData->clearCallbackState(); 7111 // cert_verify_callback threw exception 7112 if (env->ExceptionCheck()) { 7113 SSL_clear(ssl); 7114 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake exception => 0", ssl); 7115 return 0; 7116 } 7117 // success case 7118 if (ret == 1) { 7119 break; 7120 } 7121 // retry case 7122 if (errno == EINTR) { 7123 continue; 7124 } 7125 // error case 7126 int sslError = SSL_get_error(ssl, ret); 7127 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake ret=%d errno=%d sslError=%d timeout_millis=%d", 7128 ssl, ret, errno, sslError, timeout_millis); 7129 7130 /* 7131 * If SSL_do_handshake doesn't succeed due to the socket being 7132 * either unreadable or unwritable, we use sslSelect to 7133 * wait for it to become ready. If that doesn't happen 7134 * before the specified timeout or an error occurs, we 7135 * cancel the handshake. Otherwise we try the SSL_connect 7136 * again. 7137 */ 7138 if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) { 7139 appData->waitingThreads++; 7140 int selectResult = sslSelect(env, sslError, fdObject, appData, timeout_millis); 7141 7142 if (selectResult == THROWN_EXCEPTION) { 7143 // SocketException thrown by NetFd.isClosed 7144 SSL_clear(ssl); 7145 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake sslSelect => 0", ssl); 7146 return 0; 7147 } 7148 if (selectResult == -1) { 7149 throwSSLExceptionWithSslErrors(env, ssl, SSL_ERROR_SYSCALL, "handshake error"); 7150 SSL_clear(ssl); 7151 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == -1 => 0", ssl); 7152 return 0; 7153 } 7154 if (selectResult == 0) { 7155 throwSocketTimeoutException(env, "SSL handshake timed out"); 7156 SSL_clear(ssl); 7157 freeOpenSslErrorState(); 7158 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake selectResult == 0 => 0", ssl); 7159 return 0; 7160 } 7161 } else { 7162 // ALOGE("Unknown error %d during handshake", error); 7163 break; 7164 } 7165 } 7166 7167 // clean error. See SSL_do_handshake(3SSL) man page. 7168 if (ret == 0) { 7169 /* 7170 * The other side closed the socket before the handshake could be 7171 * completed, but everything is within the bounds of the TLS protocol. 7172 * We still might want to find out the real reason of the failure. 7173 */ 7174 int sslError = SSL_get_error(ssl, ret); 7175 if (sslError == SSL_ERROR_NONE || (sslError == SSL_ERROR_SYSCALL && errno == 0)) { 7176 throwSSLExceptionStr(env, "Connection closed by peer"); 7177 } else { 7178 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake terminated"); 7179 } 7180 SSL_clear(ssl); 7181 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake clean error => 0", ssl); 7182 return 0; 7183 } 7184 7185 // unclean error. See SSL_do_handshake(3SSL) man page. 7186 if (ret < 0) { 7187 /* 7188 * Translate the error and throw exception. We are sure it is an error 7189 * at this point. 7190 */ 7191 int sslError = SSL_get_error(ssl, ret); 7192 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL handshake aborted"); 7193 SSL_clear(ssl); 7194 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake unclean error => 0", ssl); 7195 return 0; 7196 } 7197 SSL_SESSION* ssl_session = SSL_get1_session(ssl); 7198 JNI_TRACE("ssl=%p NativeCrypto_SSL_do_handshake => ssl_session=%p", ssl, ssl_session); 7199 #ifdef WITH_JNI_TRACE_KEYS 7200 debug_print_session_key(ssl_session); 7201 #endif 7202 return (jlong) ssl_session; 7203 } 7204 7205 /** 7206 * Perform SSL renegotiation 7207 */ 7208 static void NativeCrypto_SSL_renegotiate(JNIEnv* env, jclass, jlong ssl_address) 7209 { 7210 SSL* ssl = to_SSL(env, ssl_address, true); 7211 JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate", ssl); 7212 if (ssl == NULL) { 7213 return; 7214 } 7215 int result = SSL_renegotiate(ssl); 7216 if (result != 1) { 7217 throwSSLExceptionStr(env, "Problem with SSL_renegotiate"); 7218 return; 7219 } 7220 // first call asks client to perform renegotiation 7221 int ret = SSL_do_handshake(ssl); 7222 if (ret != 1) { 7223 int sslError = SSL_get_error(ssl, ret); 7224 throwSSLExceptionWithSslErrors(env, ssl, sslError, 7225 "Problem with SSL_do_handshake after SSL_renegotiate"); 7226 return; 7227 } 7228 // if client agrees, set ssl state and perform renegotiation 7229 ssl->state = SSL_ST_ACCEPT; 7230 SSL_do_handshake(ssl); 7231 JNI_TRACE("ssl=%p NativeCrypto_SSL_renegotiate =>", ssl); 7232 } 7233 7234 /** 7235 * public static native byte[][] SSL_get_certificate(int ssl); 7236 */ 7237 static jobjectArray NativeCrypto_SSL_get_certificate(JNIEnv* env, jclass, jlong ssl_address) 7238 { 7239 SSL* ssl = to_SSL(env, ssl_address, true); 7240 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate", ssl); 7241 if (ssl == NULL) { 7242 return NULL; 7243 } 7244 X509* certificate = SSL_get_certificate(ssl); 7245 if (certificate == NULL) { 7246 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl); 7247 // SSL_get_certificate can return NULL during an error as well. 7248 freeOpenSslErrorState(); 7249 return NULL; 7250 } 7251 7252 Unique_sk_X509 chain(sk_X509_new_null()); 7253 if (chain.get() == NULL) { 7254 jniThrowOutOfMemory(env, "Unable to allocate local certificate chain"); 7255 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => threw exception", ssl); 7256 return NULL; 7257 } 7258 if (!sk_X509_push(chain.get(), X509_dup_nocopy(certificate))) { 7259 jniThrowOutOfMemory(env, "Unable to push local certificate"); 7260 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl); 7261 return NULL; 7262 } 7263 STACK_OF(X509)* cert_chain = SSL_get_certificate_chain(ssl, certificate); 7264 for (int i=0; i<sk_X509_num(cert_chain); i++) { 7265 if (!sk_X509_push(chain.get(), X509_dup_nocopy(sk_X509_value(cert_chain, i)))) { 7266 jniThrowOutOfMemory(env, "Unable to push local certificate chain"); 7267 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => NULL", ssl); 7268 return NULL; 7269 } 7270 } 7271 7272 jobjectArray objectArray = getCertificateBytes(env, chain.get()); 7273 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_certificate => %p", ssl, objectArray); 7274 return objectArray; 7275 } 7276 7277 // Fills a byte[][] with the peer certificates in the chain. 7278 static jobjectArray NativeCrypto_SSL_get_peer_cert_chain(JNIEnv* env, jclass, jlong ssl_address) 7279 { 7280 SSL* ssl = to_SSL(env, ssl_address, true); 7281 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain", ssl); 7282 if (ssl == NULL) { 7283 return NULL; 7284 } 7285 STACK_OF(X509)* chain = SSL_get_peer_cert_chain(ssl); 7286 Unique_sk_X509 chain_copy(NULL); 7287 if (ssl->server) { 7288 X509* x509 = SSL_get_peer_certificate(ssl); 7289 if (x509 == NULL) { 7290 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => NULL", ssl); 7291 return NULL; 7292 } 7293 chain_copy.reset(sk_X509_new_null()); 7294 if (chain_copy.get() == NULL) { 7295 jniThrowOutOfMemory(env, "Unable to allocate peer certificate chain"); 7296 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate dup error", ssl); 7297 return NULL; 7298 } 7299 size_t chain_size = sk_X509_num(chain); 7300 for (size_t i = 0; i < chain_size; i++) { 7301 if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(sk_X509_value(chain, i)))) { 7302 jniThrowOutOfMemory(env, "Unable to push server's peer certificate chain"); 7303 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate chain push error", ssl); 7304 return NULL; 7305 } 7306 } 7307 if (!sk_X509_push(chain_copy.get(), X509_dup_nocopy(x509))) { 7308 jniThrowOutOfMemory(env, "Unable to push server's peer certificate"); 7309 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => certificate push error", ssl); 7310 return NULL; 7311 } 7312 chain = chain_copy.get(); 7313 } 7314 jobjectArray objectArray = getCertificateBytes(env, chain); 7315 JNI_TRACE("ssl=%p NativeCrypto_SSL_get_peer_cert_chain => %p", ssl, objectArray); 7316 return objectArray; 7317 } 7318 7319 /** 7320 * Helper function which does the actual reading. The Java layer guarantees that 7321 * at most one thread will enter this function at any given time. 7322 * 7323 * @param ssl non-null; the SSL context 7324 * @param buf non-null; buffer to read into 7325 * @param len length of the buffer, in bytes 7326 * @param sslReturnCode original SSL return code 7327 * @param sslErrorCode filled in with the SSL error code in case of error 7328 * @return number of bytes read on success, -1 if the connection was 7329 * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown. 7330 */ 7331 static int sslRead(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, char* buf, jint len, 7332 int* sslReturnCode, int* sslErrorCode, int read_timeout_millis) { 7333 JNI_TRACE("ssl=%p sslRead buf=%p len=%d", ssl, buf, len); 7334 7335 if (len == 0) { 7336 // Don't bother doing anything in this case. 7337 return 0; 7338 } 7339 7340 BIO* bio = SSL_get_rbio(ssl); 7341 7342 AppData* appData = toAppData(ssl); 7343 if (appData == NULL) { 7344 return THROW_SSLEXCEPTION; 7345 } 7346 7347 while (appData->aliveAndKicking) { 7348 errno = 0; 7349 7350 if (MUTEX_LOCK(appData->mutex) == -1) { 7351 return -1; 7352 } 7353 7354 unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio); 7355 7356 if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) { 7357 MUTEX_UNLOCK(appData->mutex); 7358 return THROWN_EXCEPTION; 7359 } 7360 int result = SSL_read(ssl, buf, len); 7361 appData->clearCallbackState(); 7362 // callbacks can happen if server requests renegotiation 7363 if (env->ExceptionCheck()) { 7364 SSL_clear(ssl); 7365 JNI_TRACE("ssl=%p sslRead => THROWN_EXCEPTION", ssl); 7366 return THROWN_EXCEPTION; 7367 } 7368 int sslError = SSL_ERROR_NONE; 7369 if (result <= 0) { 7370 sslError = SSL_get_error(ssl, result); 7371 freeOpenSslErrorState(); 7372 } 7373 JNI_TRACE("ssl=%p sslRead SSL_read result=%d sslError=%d", ssl, result, sslError); 7374 #ifdef WITH_JNI_TRACE_DATA 7375 for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) { 7376 int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE); 7377 JNI_TRACE("ssl=%p sslRead data: %d:\n%.*s", ssl, n, n, buf+i); 7378 } 7379 #endif 7380 7381 // If we have been successful in moving data around, check whether it 7382 // might make sense to wake up other blocked threads, so they can give 7383 // it a try, too. 7384 if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved 7385 && appData->waitingThreads > 0) { 7386 sslNotify(appData); 7387 } 7388 7389 // If we are blocked by the underlying socket, tell the world that 7390 // there will be one more waiting thread now. 7391 if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) { 7392 appData->waitingThreads++; 7393 } 7394 7395 MUTEX_UNLOCK(appData->mutex); 7396 7397 switch (sslError) { 7398 // Successfully read at least one byte. 7399 case SSL_ERROR_NONE: { 7400 return result; 7401 } 7402 7403 // Read zero bytes. End of stream reached. 7404 case SSL_ERROR_ZERO_RETURN: { 7405 return -1; 7406 } 7407 7408 // Need to wait for availability of underlying layer, then retry. 7409 case SSL_ERROR_WANT_READ: 7410 case SSL_ERROR_WANT_WRITE: { 7411 int selectResult = sslSelect(env, sslError, fdObject, appData, read_timeout_millis); 7412 if (selectResult == THROWN_EXCEPTION) { 7413 return THROWN_EXCEPTION; 7414 } 7415 if (selectResult == -1) { 7416 *sslReturnCode = -1; 7417 *sslErrorCode = sslError; 7418 return THROW_SSLEXCEPTION; 7419 } 7420 if (selectResult == 0) { 7421 return THROW_SOCKETTIMEOUTEXCEPTION; 7422 } 7423 7424 break; 7425 } 7426 7427 // A problem occurred during a system call, but this is not 7428 // necessarily an error. 7429 case SSL_ERROR_SYSCALL: { 7430 // Connection closed without proper shutdown. Tell caller we 7431 // have reached end-of-stream. 7432 if (result == 0) { 7433 return -1; 7434 } 7435 7436 // System call has been interrupted. Simply retry. 7437 if (errno == EINTR) { 7438 break; 7439 } 7440 7441 // Note that for all other system call errors we fall through 7442 // to the default case, which results in an Exception. 7443 } 7444 7445 // Everything else is basically an error. 7446 default: { 7447 *sslReturnCode = result; 7448 *sslErrorCode = sslError; 7449 return THROW_SSLEXCEPTION; 7450 } 7451 } 7452 } 7453 7454 return -1; 7455 } 7456 7457 /** 7458 * OpenSSL read function (2): read into buffer at offset n chunks. 7459 * Returns 1 (success) or value <= 0 (failure). 7460 */ 7461 static jint NativeCrypto_SSL_read(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject, 7462 jobject shc, jbyteArray b, jint offset, jint len, 7463 jint read_timeout_millis) 7464 { 7465 SSL* ssl = to_SSL(env, ssl_address, true); 7466 JNI_TRACE("ssl=%p NativeCrypto_SSL_read fd=%p shc=%p b=%p offset=%d len=%d read_timeout_millis=%d", 7467 ssl, fdObject, shc, b, offset, len, read_timeout_millis); 7468 if (ssl == NULL) { 7469 return 0; 7470 } 7471 if (fdObject == NULL) { 7472 jniThrowNullPointerException(env, "fd == null"); 7473 JNI_TRACE("ssl=%p NativeCrypto_SSL_read => fd == null", ssl); 7474 return 0; 7475 } 7476 if (shc == NULL) { 7477 jniThrowNullPointerException(env, "sslHandshakeCallbacks == null"); 7478 JNI_TRACE("ssl=%p NativeCrypto_SSL_read => sslHandshakeCallbacks == null", ssl); 7479 return 0; 7480 } 7481 7482 ScopedByteArrayRW bytes(env, b); 7483 if (bytes.get() == NULL) { 7484 JNI_TRACE("ssl=%p NativeCrypto_SSL_read => threw exception", ssl); 7485 return 0; 7486 } 7487 int returnCode = 0; 7488 int sslErrorCode = SSL_ERROR_NONE;; 7489 7490 int ret = sslRead(env, ssl, fdObject, shc, reinterpret_cast<char*>(bytes.get() + offset), len, 7491 &returnCode, &sslErrorCode, read_timeout_millis); 7492 7493 int result; 7494 switch (ret) { 7495 case THROW_SSLEXCEPTION: 7496 // See sslRead() regarding improper failure to handle normal cases. 7497 throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Read error"); 7498 result = -1; 7499 break; 7500 case THROW_SOCKETTIMEOUTEXCEPTION: 7501 throwSocketTimeoutException(env, "Read timed out"); 7502 result = -1; 7503 break; 7504 case THROWN_EXCEPTION: 7505 // SocketException thrown by NetFd.isClosed 7506 // or RuntimeException thrown by callback 7507 result = -1; 7508 break; 7509 default: 7510 result = ret; 7511 break; 7512 } 7513 7514 JNI_TRACE("ssl=%p NativeCrypto_SSL_read => %d", ssl, result); 7515 return result; 7516 } 7517 7518 /** 7519 * Helper function which does the actual writing. The Java layer guarantees that 7520 * at most one thread will enter this function at any given time. 7521 * 7522 * @param ssl non-null; the SSL context 7523 * @param buf non-null; buffer to write 7524 * @param len length of the buffer, in bytes 7525 * @param sslReturnCode original SSL return code 7526 * @param sslErrorCode filled in with the SSL error code in case of error 7527 * @return number of bytes read on success, -1 if the connection was 7528 * cleanly shut down, or THROW_SSLEXCEPTION if an exception should be thrown. 7529 */ 7530 static int sslWrite(JNIEnv* env, SSL* ssl, jobject fdObject, jobject shc, const char* buf, jint len, 7531 int* sslReturnCode, int* sslErrorCode, int write_timeout_millis) { 7532 JNI_TRACE("ssl=%p sslWrite buf=%p len=%d write_timeout_millis=%d", 7533 ssl, buf, len, write_timeout_millis); 7534 7535 if (len == 0) { 7536 // Don't bother doing anything in this case. 7537 return 0; 7538 } 7539 7540 BIO* bio = SSL_get_wbio(ssl); 7541 7542 AppData* appData = toAppData(ssl); 7543 if (appData == NULL) { 7544 return THROW_SSLEXCEPTION; 7545 } 7546 7547 int count = len; 7548 7549 while (appData->aliveAndKicking && ((len > 0) || (ssl->s3->wbuf.left > 0))) { 7550 errno = 0; 7551 7552 if (MUTEX_LOCK(appData->mutex) == -1) { 7553 return -1; 7554 } 7555 7556 unsigned int bytesMoved = BIO_number_read(bio) + BIO_number_written(bio); 7557 7558 if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) { 7559 MUTEX_UNLOCK(appData->mutex); 7560 return THROWN_EXCEPTION; 7561 } 7562 JNI_TRACE("ssl=%p sslWrite SSL_write len=%d left=%d", ssl, len, ssl->s3->wbuf.left); 7563 int result = SSL_write(ssl, buf, len); 7564 appData->clearCallbackState(); 7565 // callbacks can happen if server requests renegotiation 7566 if (env->ExceptionCheck()) { 7567 SSL_clear(ssl); 7568 JNI_TRACE("ssl=%p sslWrite exception => THROWN_EXCEPTION", ssl); 7569 return THROWN_EXCEPTION; 7570 } 7571 int sslError = SSL_ERROR_NONE; 7572 if (result <= 0) { 7573 sslError = SSL_get_error(ssl, result); 7574 freeOpenSslErrorState(); 7575 } 7576 JNI_TRACE("ssl=%p sslWrite SSL_write result=%d sslError=%d left=%d", 7577 ssl, result, sslError, ssl->s3->wbuf.left); 7578 #ifdef WITH_JNI_TRACE_DATA 7579 for (int i = 0; i < result; i+= WITH_JNI_TRACE_DATA_CHUNK_SIZE) { 7580 int n = std::min(result - i, WITH_JNI_TRACE_DATA_CHUNK_SIZE); 7581 JNI_TRACE("ssl=%p sslWrite data: %d:\n%.*s", ssl, n, n, buf+i); 7582 } 7583 #endif 7584 7585 // If we have been successful in moving data around, check whether it 7586 // might make sense to wake up other blocked threads, so they can give 7587 // it a try, too. 7588 if (BIO_number_read(bio) + BIO_number_written(bio) != bytesMoved 7589 && appData->waitingThreads > 0) { 7590 sslNotify(appData); 7591 } 7592 7593 // If we are blocked by the underlying socket, tell the world that 7594 // there will be one more waiting thread now. 7595 if (sslError == SSL_ERROR_WANT_READ || sslError == SSL_ERROR_WANT_WRITE) { 7596 appData->waitingThreads++; 7597 } 7598 7599 MUTEX_UNLOCK(appData->mutex); 7600 7601 switch (sslError) { 7602 // Successfully wrote at least one byte. 7603 case SSL_ERROR_NONE: { 7604 buf += result; 7605 len -= result; 7606 break; 7607 } 7608 7609 // Wrote zero bytes. End of stream reached. 7610 case SSL_ERROR_ZERO_RETURN: { 7611 return -1; 7612 } 7613 7614 // Need to wait for availability of underlying layer, then retry. 7615 // The concept of a write timeout doesn't really make sense, and 7616 // it's also not standard Java behavior, so we wait forever here. 7617 case SSL_ERROR_WANT_READ: 7618 case SSL_ERROR_WANT_WRITE: { 7619 int selectResult = sslSelect(env, sslError, fdObject, appData, write_timeout_millis); 7620 if (selectResult == THROWN_EXCEPTION) { 7621 return THROWN_EXCEPTION; 7622 } 7623 if (selectResult == -1) { 7624 *sslReturnCode = -1; 7625 *sslErrorCode = sslError; 7626 return THROW_SSLEXCEPTION; 7627 } 7628 if (selectResult == 0) { 7629 return THROW_SOCKETTIMEOUTEXCEPTION; 7630 } 7631 7632 break; 7633 } 7634 7635 // A problem occurred during a system call, but this is not 7636 // necessarily an error. 7637 case SSL_ERROR_SYSCALL: { 7638 // Connection closed without proper shutdown. Tell caller we 7639 // have reached end-of-stream. 7640 if (result == 0) { 7641 return -1; 7642 } 7643 7644 // System call has been interrupted. Simply retry. 7645 if (errno == EINTR) { 7646 break; 7647 } 7648 7649 // Note that for all other system call errors we fall through 7650 // to the default case, which results in an Exception. 7651 } 7652 7653 // Everything else is basically an error. 7654 default: { 7655 *sslReturnCode = result; 7656 *sslErrorCode = sslError; 7657 return THROW_SSLEXCEPTION; 7658 } 7659 } 7660 } 7661 JNI_TRACE("ssl=%p sslWrite => count=%d", ssl, count); 7662 7663 return count; 7664 } 7665 7666 /** 7667 * OpenSSL write function (2): write into buffer at offset n chunks. 7668 */ 7669 static void NativeCrypto_SSL_write(JNIEnv* env, jclass, jlong ssl_address, jobject fdObject, 7670 jobject shc, jbyteArray b, jint offset, jint len, jint write_timeout_millis) 7671 { 7672 SSL* ssl = to_SSL(env, ssl_address, true); 7673 JNI_TRACE("ssl=%p NativeCrypto_SSL_write fd=%p shc=%p b=%p offset=%d len=%d write_timeout_millis=%d", 7674 ssl, fdObject, shc, b, offset, len, write_timeout_millis); 7675 if (ssl == NULL) { 7676 return; 7677 } 7678 if (fdObject == NULL) { 7679 jniThrowNullPointerException(env, "fd == null"); 7680 JNI_TRACE("ssl=%p NativeCrypto_SSL_write => fd == null", ssl); 7681 return; 7682 } 7683 if (shc == NULL) { 7684 jniThrowNullPointerException(env, "sslHandshakeCallbacks == null"); 7685 JNI_TRACE("ssl=%p NativeCrypto_SSL_write => sslHandshakeCallbacks == null", ssl); 7686 return; 7687 } 7688 7689 ScopedByteArrayRO bytes(env, b); 7690 if (bytes.get() == NULL) { 7691 JNI_TRACE("ssl=%p NativeCrypto_SSL_write => threw exception", ssl); 7692 return; 7693 } 7694 int returnCode = 0; 7695 int sslErrorCode = SSL_ERROR_NONE; 7696 int ret = sslWrite(env, ssl, fdObject, shc, reinterpret_cast<const char*>(bytes.get() + offset), 7697 len, &returnCode, &sslErrorCode, write_timeout_millis); 7698 7699 switch (ret) { 7700 case THROW_SSLEXCEPTION: 7701 // See sslWrite() regarding improper failure to handle normal cases. 7702 throwSSLExceptionWithSslErrors(env, ssl, sslErrorCode, "Write error"); 7703 break; 7704 case THROW_SOCKETTIMEOUTEXCEPTION: 7705 throwSocketTimeoutException(env, "Write timed out"); 7706 break; 7707 case THROWN_EXCEPTION: 7708 // SocketException thrown by NetFd.isClosed 7709 break; 7710 default: 7711 break; 7712 } 7713 } 7714 7715 /** 7716 * Interrupt any pending I/O before closing the socket. 7717 */ 7718 static void NativeCrypto_SSL_interrupt( 7719 JNIEnv* env, jclass, jlong ssl_address) { 7720 SSL* ssl = to_SSL(env, ssl_address, false); 7721 JNI_TRACE("ssl=%p NativeCrypto_SSL_interrupt", ssl); 7722 if (ssl == NULL) { 7723 return; 7724 } 7725 7726 /* 7727 * Mark the connection as quasi-dead, then send something to the emergency 7728 * file descriptor, so any blocking select() calls are woken up. 7729 */ 7730 AppData* appData = toAppData(ssl); 7731 if (appData != NULL) { 7732 appData->aliveAndKicking = 0; 7733 7734 // At most two threads can be waiting. 7735 sslNotify(appData); 7736 sslNotify(appData); 7737 } 7738 } 7739 7740 /** 7741 * OpenSSL close SSL socket function. 7742 */ 7743 static void NativeCrypto_SSL_shutdown(JNIEnv* env, jclass, jlong ssl_address, 7744 jobject fdObject, jobject shc) { 7745 SSL* ssl = to_SSL(env, ssl_address, false); 7746 JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown fd=%p shc=%p", ssl, fdObject, shc); 7747 if (ssl == NULL) { 7748 return; 7749 } 7750 if (fdObject == NULL) { 7751 jniThrowNullPointerException(env, "fd == null"); 7752 JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => fd == null", ssl); 7753 return; 7754 } 7755 if (shc == NULL) { 7756 jniThrowNullPointerException(env, "sslHandshakeCallbacks == null"); 7757 JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => sslHandshakeCallbacks == null", ssl); 7758 return; 7759 } 7760 7761 AppData* appData = toAppData(ssl); 7762 if (appData != NULL) { 7763 if (!appData->setCallbackState(env, shc, fdObject, NULL, NULL)) { 7764 // SocketException thrown by NetFd.isClosed 7765 SSL_clear(ssl); 7766 freeOpenSslErrorState(); 7767 return; 7768 } 7769 7770 /* 7771 * Try to make socket blocking again. OpenSSL literature recommends this. 7772 */ 7773 int fd = SSL_get_fd(ssl); 7774 JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown s=%d", ssl, fd); 7775 if (fd != -1) { 7776 setBlocking(fd, true); 7777 } 7778 7779 int ret = SSL_shutdown(ssl); 7780 appData->clearCallbackState(); 7781 // callbacks can happen if server requests renegotiation 7782 if (env->ExceptionCheck()) { 7783 SSL_clear(ssl); 7784 JNI_TRACE("ssl=%p NativeCrypto_SSL_shutdown => exception", ssl); 7785 return; 7786 } 7787 switch (ret) { 7788 case 0: 7789 /* 7790 * Shutdown was not successful (yet), but there also 7791 * is no error. Since we can't know whether the remote 7792 * server is actually still there, and we don't want to 7793 * get stuck forever in a second SSL_shutdown() call, we 7794 * simply return. This is not security a problem as long 7795 * as we close the underlying socket, which we actually 7796 * do, because that's where we are just coming from. 7797 */ 7798 break; 7799 case 1: 7800 /* 7801 * Shutdown was successful. We can safely return. Hooray! 7802 */ 7803 break; 7804 default: 7805 /* 7806 * Everything else is a real error condition. We should 7807 * let the Java layer know about this by throwing an 7808 * exception. 7809 */ 7810 int sslError = SSL_get_error(ssl, ret); 7811 throwSSLExceptionWithSslErrors(env, ssl, sslError, "SSL shutdown failed"); 7812 break; 7813 } 7814 } 7815 7816 SSL_clear(ssl); 7817 freeOpenSslErrorState(); 7818 } 7819 7820 /** 7821 * public static native void SSL_free(int ssl); 7822 */ 7823 static void NativeCrypto_SSL_free(JNIEnv* env, jclass, jlong ssl_address) 7824 { 7825 SSL* ssl = to_SSL(env, ssl_address, true); 7826 JNI_TRACE("ssl=%p NativeCrypto_SSL_free", ssl); 7827 if (ssl == NULL) { 7828 return; 7829 } 7830 7831 AppData* appData = toAppData(ssl); 7832 SSL_set_app_data(ssl, NULL); 7833 delete appData; 7834 SSL_free(ssl); 7835 } 7836 7837 /** 7838 * Gets and returns in a byte array the ID of the actual SSL session. 7839 */ 7840 static jbyteArray NativeCrypto_SSL_SESSION_session_id(JNIEnv* env, jclass, 7841 jlong ssl_session_address) { 7842 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true); 7843 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id", ssl_session); 7844 if (ssl_session == NULL) { 7845 return NULL; 7846 } 7847 jbyteArray result = env->NewByteArray(ssl_session->session_id_length); 7848 if (result != NULL) { 7849 jbyte* src = reinterpret_cast<jbyte*>(ssl_session->session_id); 7850 env->SetByteArrayRegion(result, 0, ssl_session->session_id_length, src); 7851 } 7852 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_session_id => %p session_id_length=%d", 7853 ssl_session, result, ssl_session->session_id_length); 7854 return result; 7855 } 7856 7857 /** 7858 * Gets and returns in a long integer the creation's time of the 7859 * actual SSL session. 7860 */ 7861 static jlong NativeCrypto_SSL_SESSION_get_time(JNIEnv* env, jclass, jlong ssl_session_address) { 7862 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true); 7863 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time", ssl_session); 7864 if (ssl_session == NULL) { 7865 return 0; 7866 } 7867 // result must be jlong, not long or *1000 will overflow 7868 jlong result = SSL_SESSION_get_time(ssl_session); 7869 result *= 1000; // OpenSSL uses seconds, Java uses milliseconds. 7870 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_time => %lld", ssl_session, result); 7871 return result; 7872 } 7873 7874 /** 7875 * Gets and returns in a string the version of the SSL protocol. If it 7876 * returns the string "unknown" it means that no connection is established. 7877 */ 7878 static jstring NativeCrypto_SSL_SESSION_get_version(JNIEnv* env, jclass, jlong ssl_session_address) { 7879 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true); 7880 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version", ssl_session); 7881 if (ssl_session == NULL) { 7882 return NULL; 7883 } 7884 const char* protocol = SSL_SESSION_get_version(ssl_session); 7885 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_get_version => %s", ssl_session, protocol); 7886 return env->NewStringUTF(protocol); 7887 } 7888 7889 /** 7890 * Gets and returns in a string the cipher negotiated for the SSL session. 7891 */ 7892 static jstring NativeCrypto_SSL_SESSION_cipher(JNIEnv* env, jclass, jlong ssl_session_address) { 7893 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true); 7894 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher", ssl_session); 7895 if (ssl_session == NULL) { 7896 return NULL; 7897 } 7898 const SSL_CIPHER* cipher = ssl_session->cipher; 7899 const char* name = SSL_CIPHER_get_name(cipher); 7900 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_cipher => %s", ssl_session, name); 7901 return env->NewStringUTF(name); 7902 } 7903 7904 /** 7905 * Frees the SSL session. 7906 */ 7907 static void NativeCrypto_SSL_SESSION_free(JNIEnv* env, jclass, jlong ssl_session_address) { 7908 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true); 7909 JNI_TRACE("ssl_session=%p NativeCrypto_SSL_SESSION_free", ssl_session); 7910 if (ssl_session == NULL) { 7911 return; 7912 } 7913 SSL_SESSION_free(ssl_session); 7914 } 7915 7916 7917 /** 7918 * Serializes the native state of the session (ID, cipher, and keys but 7919 * not certificates). Returns a byte[] containing the DER-encoded state. 7920 * See apache mod_ssl. 7921 */ 7922 static jbyteArray NativeCrypto_i2d_SSL_SESSION(JNIEnv* env, jclass, jlong ssl_session_address) { 7923 SSL_SESSION* ssl_session = to_SSL_SESSION(env, ssl_session_address, true); 7924 JNI_TRACE("ssl_session=%p NativeCrypto_i2d_SSL_SESSION", ssl_session); 7925 if (ssl_session == NULL) { 7926 return NULL; 7927 } 7928 return ASN1ToByteArray<SSL_SESSION, i2d_SSL_SESSION>(env, ssl_session); 7929 } 7930 7931 /** 7932 * Deserialize the session. 7933 */ 7934 static jlong NativeCrypto_d2i_SSL_SESSION(JNIEnv* env, jclass, jbyteArray javaBytes) { 7935 JNI_TRACE("NativeCrypto_d2i_SSL_SESSION bytes=%p", javaBytes); 7936 7937 ScopedByteArrayRO bytes(env, javaBytes); 7938 if (bytes.get() == NULL) { 7939 JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => threw exception"); 7940 return 0; 7941 } 7942 const unsigned char* ucp = reinterpret_cast<const unsigned char*>(bytes.get()); 7943 SSL_SESSION* ssl_session = d2i_SSL_SESSION(NULL, &ucp, bytes.size()); 7944 7945 // Initialize SSL_SESSION cipher field based on cipher_id http://b/7091840 7946 if (ssl_session != NULL) { 7947 // based on ssl_get_prev_session 7948 uint32_t cipher_id_network_order = htonl(ssl_session->cipher_id); 7949 uint8_t* cipher_id_byte_pointer = reinterpret_cast<uint8_t*>(&cipher_id_network_order); 7950 if (ssl_session->ssl_version >= SSL3_VERSION_MAJOR) { 7951 cipher_id_byte_pointer += 2; // skip first two bytes for SSL3+ 7952 } else { 7953 cipher_id_byte_pointer += 1; // skip first byte for SSL2 7954 } 7955 ssl_session->cipher = SSLv23_method()->get_cipher_by_char(cipher_id_byte_pointer); 7956 JNI_TRACE("NativeCrypto_d2i_SSL_SESSION cipher_id=%lx hton=%x 0=%x 1=%x cipher=%s", 7957 ssl_session->cipher_id, cipher_id_network_order, 7958 cipher_id_byte_pointer[0], cipher_id_byte_pointer[1], 7959 SSL_CIPHER_get_name(ssl_session->cipher)); 7960 } else { 7961 freeOpenSslErrorState(); 7962 } 7963 7964 JNI_TRACE("NativeCrypto_d2i_SSL_SESSION => %p", ssl_session); 7965 return reinterpret_cast<uintptr_t>(ssl_session); 7966 } 7967 7968 static jlong NativeCrypto_ERR_peek_last_error(JNIEnv*, jclass) { 7969 return ERR_peek_last_error(); 7970 } 7971 7972 #define FILE_DESCRIPTOR "Ljava/io/FileDescriptor;" 7973 #define SSL_CALLBACKS "L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto$SSLHandshakeCallbacks;" 7974 static JNINativeMethod sNativeCryptoMethods[] = { 7975 NATIVE_METHOD(NativeCrypto, clinit, "()V"), 7976 NATIVE_METHOD(NativeCrypto, ENGINE_load_dynamic, "()V"), 7977 NATIVE_METHOD(NativeCrypto, ENGINE_by_id, "(Ljava/lang/String;)J"), 7978 NATIVE_METHOD(NativeCrypto, ENGINE_add, "(J)I"), 7979 NATIVE_METHOD(NativeCrypto, ENGINE_init, "(J)I"), 7980 NATIVE_METHOD(NativeCrypto, ENGINE_finish, "(J)I"), 7981 NATIVE_METHOD(NativeCrypto, ENGINE_free, "(J)I"), 7982 NATIVE_METHOD(NativeCrypto, ENGINE_load_private_key, "(JLjava/lang/String;)J"), 7983 NATIVE_METHOD(NativeCrypto, ENGINE_get_id, "(J)Ljava/lang/String;"), 7984 NATIVE_METHOD(NativeCrypto, ENGINE_ctrl_cmd_string, "(JLjava/lang/String;Ljava/lang/String;I)I"), 7985 NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_DSA, "([B[B[B[B[B)J"), 7986 NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_RSA, "([B[B[B[B[B[B[B[B)J"), 7987 NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_EC_KEY, "(JJ[B)J"), 7988 NATIVE_METHOD(NativeCrypto, EVP_PKEY_new_mac_key, "(I[B)J"), 7989 NATIVE_METHOD(NativeCrypto, EVP_PKEY_type, "(J)I"), 7990 NATIVE_METHOD(NativeCrypto, EVP_PKEY_size, "(J)I"), 7991 NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_public, "(J)Ljava/lang/String;"), 7992 NATIVE_METHOD(NativeCrypto, EVP_PKEY_print_private, "(J)Ljava/lang/String;"), 7993 NATIVE_METHOD(NativeCrypto, EVP_PKEY_free, "(J)V"), 7994 NATIVE_METHOD(NativeCrypto, EVP_PKEY_cmp, "(JJ)I"), 7995 NATIVE_METHOD(NativeCrypto, i2d_PKCS8_PRIV_KEY_INFO, "(J)[B"), 7996 NATIVE_METHOD(NativeCrypto, d2i_PKCS8_PRIV_KEY_INFO, "([B)J"), 7997 NATIVE_METHOD(NativeCrypto, i2d_PUBKEY, "(J)[B"), 7998 NATIVE_METHOD(NativeCrypto, d2i_PUBKEY, "([B)J"), 7999 NATIVE_METHOD(NativeCrypto, RSA_generate_key_ex, "(I[B)J"), 8000 NATIVE_METHOD(NativeCrypto, RSA_size, "(J)I"), 8001 NATIVE_METHOD(NativeCrypto, RSA_private_encrypt, "(I[B[BJI)I"), 8002 NATIVE_METHOD(NativeCrypto, RSA_public_decrypt, "(I[B[BJI)I"), 8003 NATIVE_METHOD(NativeCrypto, RSA_public_encrypt, "(I[B[BJI)I"), 8004 NATIVE_METHOD(NativeCrypto, RSA_private_decrypt, "(I[B[BJI)I"), 8005 NATIVE_METHOD(NativeCrypto, get_RSA_private_params, "(J)[[B"), 8006 NATIVE_METHOD(NativeCrypto, get_RSA_public_params, "(J)[[B"), 8007 NATIVE_METHOD(NativeCrypto, DSA_generate_key, "(I[B[B[B[B)J"), 8008 NATIVE_METHOD(NativeCrypto, get_DSA_params, "(J)[[B"), 8009 NATIVE_METHOD(NativeCrypto, EC_GROUP_new_by_curve_name, "(Ljava/lang/String;)J"), 8010 NATIVE_METHOD(NativeCrypto, EC_GROUP_new_curve, "(I[B[B[B)J"), 8011 NATIVE_METHOD(NativeCrypto, EC_GROUP_dup, "(J)J"), 8012 NATIVE_METHOD(NativeCrypto, EC_GROUP_set_asn1_flag, "(JI)V"), 8013 NATIVE_METHOD(NativeCrypto, EC_GROUP_set_point_conversion_form, "(JI)V"), 8014 NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve_name, "(J)Ljava/lang/String;"), 8015 NATIVE_METHOD(NativeCrypto, EC_GROUP_get_curve, "(J)[[B"), 8016 NATIVE_METHOD(NativeCrypto, EC_GROUP_get_order, "(J)[B"), 8017 NATIVE_METHOD(NativeCrypto, EC_GROUP_get_degree, "(J)I"), 8018 NATIVE_METHOD(NativeCrypto, EC_GROUP_get_cofactor, "(J)[B"), 8019 NATIVE_METHOD(NativeCrypto, EC_GROUP_clear_free, "(J)V"), 8020 NATIVE_METHOD(NativeCrypto, EC_GROUP_cmp, "(JJ)Z"), 8021 NATIVE_METHOD(NativeCrypto, EC_GROUP_get_generator, "(J)J"), 8022 NATIVE_METHOD(NativeCrypto, EC_GROUP_set_generator, "(JJ[B[B)V"), 8023 NATIVE_METHOD(NativeCrypto, get_EC_GROUP_type, "(J)I"), 8024 NATIVE_METHOD(NativeCrypto, EC_POINT_new, "(J)J"), 8025 NATIVE_METHOD(NativeCrypto, EC_POINT_clear_free, "(J)V"), 8026 NATIVE_METHOD(NativeCrypto, EC_POINT_cmp, "(JJJ)Z"), 8027 NATIVE_METHOD(NativeCrypto, EC_POINT_set_affine_coordinates, "(JJ[B[B)V"), 8028 NATIVE_METHOD(NativeCrypto, EC_POINT_get_affine_coordinates, "(JJ)[[B"), 8029 NATIVE_METHOD(NativeCrypto, EC_KEY_generate_key, "(J)J"), 8030 NATIVE_METHOD(NativeCrypto, EC_KEY_get0_group, "(J)J"), 8031 NATIVE_METHOD(NativeCrypto, EC_KEY_get_private_key, "(J)[B"), 8032 NATIVE_METHOD(NativeCrypto, EC_KEY_get_public_key, "(J)J"), 8033 NATIVE_METHOD(NativeCrypto, ECDH_compute_key, "([BIJJ)I"), 8034 NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_create, "()J"), 8035 NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_init, "(J)V"), 8036 NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_destroy, "(J)V"), 8037 NATIVE_METHOD(NativeCrypto, EVP_MD_CTX_copy, "(J)J"), 8038 NATIVE_METHOD(NativeCrypto, EVP_DigestFinal, "(J[BI)I"), 8039 NATIVE_METHOD(NativeCrypto, EVP_DigestInit, "(J)J"), 8040 NATIVE_METHOD(NativeCrypto, EVP_get_digestbyname, "(Ljava/lang/String;)J"), 8041 NATIVE_METHOD(NativeCrypto, EVP_MD_block_size, "(J)I"), 8042 NATIVE_METHOD(NativeCrypto, EVP_MD_size, "(J)I"), 8043 NATIVE_METHOD(NativeCrypto, EVP_DigestUpdate, "(J[BII)V"), 8044 NATIVE_METHOD(NativeCrypto, EVP_SignInit, "(Ljava/lang/String;)J"), 8045 NATIVE_METHOD(NativeCrypto, EVP_SignUpdate, "(J[BII)V"), 8046 NATIVE_METHOD(NativeCrypto, EVP_SignFinal, "(J[BIJ)I"), 8047 NATIVE_METHOD(NativeCrypto, EVP_VerifyInit, "(Ljava/lang/String;)J"), 8048 NATIVE_METHOD(NativeCrypto, EVP_VerifyUpdate, "(J[BII)V"), 8049 NATIVE_METHOD(NativeCrypto, EVP_VerifyFinal, "(J[BIIJ)I"), 8050 NATIVE_METHOD(NativeCrypto, EVP_DigestSignInit, "(JJJ)V"), 8051 NATIVE_METHOD(NativeCrypto, EVP_DigestSignUpdate, "(J[B)V"), 8052 NATIVE_METHOD(NativeCrypto, EVP_DigestSignFinal, "(J)[B"), 8053 NATIVE_METHOD(NativeCrypto, EVP_get_cipherbyname, "(Ljava/lang/String;)J"), 8054 NATIVE_METHOD(NativeCrypto, EVP_CipherInit_ex, "(JJ[B[BZ)V"), 8055 NATIVE_METHOD(NativeCrypto, EVP_CipherUpdate, "(J[BI[BII)I"), 8056 NATIVE_METHOD(NativeCrypto, EVP_CipherFinal_ex, "(J[BI)I"), 8057 NATIVE_METHOD(NativeCrypto, EVP_CIPHER_iv_length, "(J)I"), 8058 NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_new, "()J"), 8059 NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_block_size, "(J)I"), 8060 NATIVE_METHOD(NativeCrypto, get_EVP_CIPHER_CTX_buf_len, "(J)I"), 8061 NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_padding, "(JZ)V"), 8062 NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_set_key_length, "(JI)V"), 8063 NATIVE_METHOD(NativeCrypto, EVP_CIPHER_CTX_cleanup, "(J)V"), 8064 NATIVE_METHOD(NativeCrypto, RAND_seed, "([B)V"), 8065 NATIVE_METHOD(NativeCrypto, RAND_load_file, "(Ljava/lang/String;J)I"), 8066 NATIVE_METHOD(NativeCrypto, RAND_bytes, "([B)V"), 8067 NATIVE_METHOD(NativeCrypto, OBJ_txt2nid, "(Ljava/lang/String;)I"), 8068 NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_longName, "(Ljava/lang/String;)Ljava/lang/String;"), 8069 NATIVE_METHOD(NativeCrypto, OBJ_txt2nid_oid, "(Ljava/lang/String;)Ljava/lang/String;"), 8070 NATIVE_METHOD(NativeCrypto, create_BIO_InputStream, ("(L" TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream;)J")), 8071 NATIVE_METHOD(NativeCrypto, create_BIO_OutputStream, "(Ljava/io/OutputStream;)J"), 8072 NATIVE_METHOD(NativeCrypto, BIO_read, "(J[B)I"), 8073 NATIVE_METHOD(NativeCrypto, BIO_write, "(J[BII)V"), 8074 NATIVE_METHOD(NativeCrypto, BIO_free, "(J)V"), 8075 NATIVE_METHOD(NativeCrypto, X509_NAME_print_ex, "(JJ)Ljava/lang/String;"), 8076 NATIVE_METHOD(NativeCrypto, d2i_X509_bio, "(J)J"), 8077 NATIVE_METHOD(NativeCrypto, d2i_X509, "([B)J"), 8078 NATIVE_METHOD(NativeCrypto, i2d_X509, "(J)[B"), 8079 NATIVE_METHOD(NativeCrypto, i2d_X509_PUBKEY, "(J)[B"), 8080 NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509, "(J)J"), 8081 NATIVE_METHOD(NativeCrypto, PEM_read_bio_PKCS7, "(JI)[J"), 8082 NATIVE_METHOD(NativeCrypto, d2i_PKCS7_bio, "(JI)[J"), 8083 NATIVE_METHOD(NativeCrypto, i2d_PKCS7, "([J)[B"), 8084 NATIVE_METHOD(NativeCrypto, ASN1_seq_unpack_X509_bio, "(J)[J"), 8085 NATIVE_METHOD(NativeCrypto, ASN1_seq_pack_X509, "([J)[B"), 8086 NATIVE_METHOD(NativeCrypto, X509_free, "(J)V"), 8087 NATIVE_METHOD(NativeCrypto, X509_cmp, "(JJ)I"), 8088 NATIVE_METHOD(NativeCrypto, get_X509_hashCode, "(J)I"), 8089 NATIVE_METHOD(NativeCrypto, X509_print_ex, "(JJJJ)V"), 8090 NATIVE_METHOD(NativeCrypto, X509_get_pubkey, "(J)J"), 8091 NATIVE_METHOD(NativeCrypto, X509_get_issuer_name, "(J)[B"), 8092 NATIVE_METHOD(NativeCrypto, X509_get_subject_name, "(J)[B"), 8093 NATIVE_METHOD(NativeCrypto, get_X509_pubkey_oid, "(J)Ljava/lang/String;"), 8094 NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_oid, "(J)Ljava/lang/String;"), 8095 NATIVE_METHOD(NativeCrypto, get_X509_sig_alg_parameter, "(J)[B"), 8096 NATIVE_METHOD(NativeCrypto, get_X509_issuerUID, "(J)[Z"), 8097 NATIVE_METHOD(NativeCrypto, get_X509_subjectUID, "(J)[Z"), 8098 NATIVE_METHOD(NativeCrypto, get_X509_ex_kusage, "(J)[Z"), 8099 NATIVE_METHOD(NativeCrypto, get_X509_ex_xkusage, "(J)[Ljava/lang/String;"), 8100 NATIVE_METHOD(NativeCrypto, get_X509_ex_pathlen, "(J)I"), 8101 NATIVE_METHOD(NativeCrypto, X509_get_ext_oid, "(JLjava/lang/String;)[B"), 8102 NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext_oid, "(JLjava/lang/String;)[B"), 8103 NATIVE_METHOD(NativeCrypto, get_X509_CRL_crl_enc, "(J)[B"), 8104 NATIVE_METHOD(NativeCrypto, X509_CRL_verify, "(JJ)V"), 8105 NATIVE_METHOD(NativeCrypto, X509_CRL_get_lastUpdate, "(J)J"), 8106 NATIVE_METHOD(NativeCrypto, X509_CRL_get_nextUpdate, "(J)J"), 8107 NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext_oid, "(JLjava/lang/String;)[B"), 8108 NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_serialNumber, "(J)[B"), 8109 NATIVE_METHOD(NativeCrypto, X509_REVOKED_print, "(JJ)V"), 8110 NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_revocationDate, "(J)J"), 8111 NATIVE_METHOD(NativeCrypto, get_X509_ext_oids, "(JI)[Ljava/lang/String;"), 8112 NATIVE_METHOD(NativeCrypto, get_X509_CRL_ext_oids, "(JI)[Ljava/lang/String;"), 8113 NATIVE_METHOD(NativeCrypto, get_X509_REVOKED_ext_oids, "(JI)[Ljava/lang/String;"), 8114 NATIVE_METHOD(NativeCrypto, get_X509_GENERAL_NAME_stack, "(JI)[[Ljava/lang/Object;"), 8115 NATIVE_METHOD(NativeCrypto, X509_get_notBefore, "(J)J"), 8116 NATIVE_METHOD(NativeCrypto, X509_get_notAfter, "(J)J"), 8117 NATIVE_METHOD(NativeCrypto, X509_get_version, "(J)J"), 8118 NATIVE_METHOD(NativeCrypto, X509_get_serialNumber, "(J)[B"), 8119 NATIVE_METHOD(NativeCrypto, X509_verify, "(JJ)V"), 8120 NATIVE_METHOD(NativeCrypto, get_X509_cert_info_enc, "(J)[B"), 8121 NATIVE_METHOD(NativeCrypto, get_X509_signature, "(J)[B"), 8122 NATIVE_METHOD(NativeCrypto, get_X509_CRL_signature, "(J)[B"), 8123 NATIVE_METHOD(NativeCrypto, get_X509_ex_flags, "(J)I"), 8124 NATIVE_METHOD(NativeCrypto, X509_check_issued, "(JJ)I"), 8125 NATIVE_METHOD(NativeCrypto, d2i_X509_CRL_bio, "(J)J"), 8126 NATIVE_METHOD(NativeCrypto, PEM_read_bio_X509_CRL, "(J)J"), 8127 NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_cert, "(JJ)J"), 8128 NATIVE_METHOD(NativeCrypto, X509_CRL_get0_by_serial, "(J[B)J"), 8129 NATIVE_METHOD(NativeCrypto, X509_CRL_get_REVOKED, "(J)[J"), 8130 NATIVE_METHOD(NativeCrypto, i2d_X509_CRL, "(J)[B"), 8131 NATIVE_METHOD(NativeCrypto, X509_CRL_free, "(J)V"), 8132 NATIVE_METHOD(NativeCrypto, X509_CRL_print, "(JJ)V"), 8133 NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_oid, "(J)Ljava/lang/String;"), 8134 NATIVE_METHOD(NativeCrypto, get_X509_CRL_sig_alg_parameter, "(J)[B"), 8135 NATIVE_METHOD(NativeCrypto, X509_CRL_get_issuer_name, "(J)[B"), 8136 NATIVE_METHOD(NativeCrypto, X509_CRL_get_version, "(J)J"), 8137 NATIVE_METHOD(NativeCrypto, X509_CRL_get_ext, "(JLjava/lang/String;)J"), 8138 NATIVE_METHOD(NativeCrypto, X509_REVOKED_get_ext, "(JLjava/lang/String;)J"), 8139 NATIVE_METHOD(NativeCrypto, X509_REVOKED_dup, "(J)J"), 8140 NATIVE_METHOD(NativeCrypto, i2d_X509_REVOKED, "(J)[B"), 8141 NATIVE_METHOD(NativeCrypto, X509_supported_extension, "(J)I"), 8142 NATIVE_METHOD(NativeCrypto, ASN1_TIME_to_Calendar, "(JLjava/util/Calendar;)V"), 8143 NATIVE_METHOD(NativeCrypto, SSL_CTX_new, "()J"), 8144 NATIVE_METHOD(NativeCrypto, SSL_CTX_free, "(J)V"), 8145 NATIVE_METHOD(NativeCrypto, SSL_CTX_set_session_id_context, "(J[B)V"), 8146 NATIVE_METHOD(NativeCrypto, SSL_new, "(J)J"), 8147 NATIVE_METHOD(NativeCrypto, SSL_enable_tls_channel_id, "(J)V"), 8148 NATIVE_METHOD(NativeCrypto, SSL_get_tls_channel_id, "(J)[B"), 8149 NATIVE_METHOD(NativeCrypto, SSL_set1_tls_channel_id, "(JJ)V"), 8150 NATIVE_METHOD(NativeCrypto, SSL_use_PrivateKey, "(JJ)V"), 8151 NATIVE_METHOD(NativeCrypto, SSL_use_certificate, "(J[[B)V"), 8152 NATIVE_METHOD(NativeCrypto, SSL_check_private_key, "(J)V"), 8153 NATIVE_METHOD(NativeCrypto, SSL_set_client_CA_list, "(J[[B)V"), 8154 NATIVE_METHOD(NativeCrypto, SSL_get_mode, "(J)J"), 8155 NATIVE_METHOD(NativeCrypto, SSL_set_mode, "(JJ)J"), 8156 NATIVE_METHOD(NativeCrypto, SSL_clear_mode, "(JJ)J"), 8157 NATIVE_METHOD(NativeCrypto, SSL_get_options, "(J)J"), 8158 NATIVE_METHOD(NativeCrypto, SSL_set_options, "(JJ)J"), 8159 NATIVE_METHOD(NativeCrypto, SSL_clear_options, "(JJ)J"), 8160 NATIVE_METHOD(NativeCrypto, SSL_set_cipher_lists, "(J[Ljava/lang/String;)V"), 8161 NATIVE_METHOD(NativeCrypto, SSL_set_verify, "(JI)V"), 8162 NATIVE_METHOD(NativeCrypto, SSL_set_session, "(JJ)V"), 8163 NATIVE_METHOD(NativeCrypto, SSL_set_session_creation_enabled, "(JZ)V"), 8164 NATIVE_METHOD(NativeCrypto, SSL_set_tlsext_host_name, "(JLjava/lang/String;)V"), 8165 NATIVE_METHOD(NativeCrypto, SSL_get_servername, "(J)Ljava/lang/String;"), 8166 NATIVE_METHOD(NativeCrypto, SSL_do_handshake, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "IZ[B[B)I"), 8167 NATIVE_METHOD(NativeCrypto, SSL_renegotiate, "(J)V"), 8168 NATIVE_METHOD(NativeCrypto, SSL_get_certificate, "(J)[[B"), 8169 NATIVE_METHOD(NativeCrypto, SSL_get_peer_cert_chain, "(J)[[B"), 8170 NATIVE_METHOD(NativeCrypto, SSL_read, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)I"), 8171 NATIVE_METHOD(NativeCrypto, SSL_write, "(J" FILE_DESCRIPTOR SSL_CALLBACKS "[BIII)V"), 8172 NATIVE_METHOD(NativeCrypto, SSL_interrupt, "(J)V"), 8173 NATIVE_METHOD(NativeCrypto, SSL_shutdown, "(J" FILE_DESCRIPTOR SSL_CALLBACKS ")V"), 8174 NATIVE_METHOD(NativeCrypto, SSL_free, "(J)V"), 8175 NATIVE_METHOD(NativeCrypto, SSL_SESSION_session_id, "(J)[B"), 8176 NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_time, "(J)J"), 8177 NATIVE_METHOD(NativeCrypto, SSL_SESSION_get_version, "(J)Ljava/lang/String;"), 8178 NATIVE_METHOD(NativeCrypto, SSL_SESSION_cipher, "(J)Ljava/lang/String;"), 8179 NATIVE_METHOD(NativeCrypto, SSL_SESSION_free, "(J)V"), 8180 NATIVE_METHOD(NativeCrypto, i2d_SSL_SESSION, "(J)[B"), 8181 NATIVE_METHOD(NativeCrypto, d2i_SSL_SESSION, "([B)J"), 8182 NATIVE_METHOD(NativeCrypto, SSL_CTX_enable_npn, "(J)V"), 8183 NATIVE_METHOD(NativeCrypto, SSL_CTX_disable_npn, "(J)V"), 8184 NATIVE_METHOD(NativeCrypto, SSL_get_npn_negotiated_protocol, "(J)[B"), 8185 NATIVE_METHOD(NativeCrypto, SSL_CTX_set_alpn_protos, "(J[B)I"), 8186 NATIVE_METHOD(NativeCrypto, SSL_get0_alpn_selected, "(J)[B"), 8187 NATIVE_METHOD(NativeCrypto, ERR_peek_last_error, "()J"), 8188 }; 8189 8190 static void initialize_conscrypt(JNIEnv* env) { 8191 jniRegisterNativeMethods(env, TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/NativeCrypto", 8192 sNativeCryptoMethods, NELEM(sNativeCryptoMethods)); 8193 8194 ScopedLocalRef<jclass> localClass(env, 8195 env->FindClass(TO_STRING(JNI_JARJAR_PREFIX) "org/conscrypt/OpenSSLBIOInputStream")); 8196 openSslOutputStreamClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get())); 8197 if (openSslOutputStreamClass == NULL) { 8198 ALOGE("failed to find class OpenSSLBIOInputStream"); 8199 abort(); 8200 } 8201 8202 calendar_setMethod = env->GetMethodID(calendarClass, "set", "(IIIIII)V"); 8203 inputStream_readMethod = env->GetMethodID(inputStreamClass, "read", "([B)I"); 8204 integer_valueOfMethod = env->GetStaticMethodID(integerClass, "valueOf", 8205 "(I)Ljava/lang/Integer;"); 8206 openSslInputStream_readLineMethod = env->GetMethodID(openSslOutputStreamClass, "gets", 8207 "([B)I"); 8208 outputStream_writeMethod = env->GetMethodID(outputStreamClass, "write", "([B)V"); 8209 outputStream_flushMethod = env->GetMethodID(outputStreamClass, "flush", "()V"); 8210 } 8211 8212 static jclass findClass(JNIEnv* env, const char* name) { 8213 ScopedLocalRef<jclass> localClass(env, env->FindClass(name)); 8214 jclass result = reinterpret_cast<jclass>(env->NewGlobalRef(localClass.get())); 8215 if (result == NULL) { 8216 ALOGE("failed to find class '%s'", name); 8217 abort(); 8218 } 8219 return result; 8220 } 8221 8222 // Use JNI_OnLoad for when we're standalone 8223 int JNI_OnLoad(JavaVM *vm, void*) { 8224 JNI_TRACE("JNI_OnLoad NativeCrypto"); 8225 gJavaVM = vm; 8226 8227 JNIEnv *env; 8228 if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) { 8229 ALOGE("Could not get JNIEnv"); 8230 return JNI_ERR; 8231 } 8232 8233 byteArrayClass = findClass(env, "[B"); 8234 calendarClass = findClass(env, "java/util/Calendar"); 8235 inputStreamClass = findClass(env, "java/io/InputStream"); 8236 integerClass = findClass(env, "java/lang/Integer"); 8237 objectClass = findClass(env, "java/lang/Object"); 8238 objectArrayClass = findClass(env, "[Ljava/lang/Object;"); 8239 outputStreamClass = findClass(env, "java/io/OutputStream"); 8240 stringClass = findClass(env, "java/lang/String"); 8241 8242 initialize_conscrypt(env); 8243 return JNI_VERSION_1_6; 8244 } 8245