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