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