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