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