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