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