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