|
44 | 44 | #include <openssl/err.h> |
45 | 45 | #include <openssl/evp.h> |
46 | 46 | #include <openssl/hmac.h> |
| 47 | +#include <openssl/hpke.h> |
47 | 48 | #include <openssl/pkcs7.h> |
48 | 49 | #include <openssl/pkcs8.h> |
49 | 50 | #include <openssl/rand.h> |
@@ -123,6 +124,15 @@ static SSL_CIPHER* to_SSL_CIPHER(JNIEnv* env, jlong ssl_cipher_address, bool thr |
123 | 124 | return ssl_cipher; |
124 | 125 | } |
125 | 126 |
|
| 127 | +static SSL_ECH_KEYS* to_SSL_ECH_KEYS(JNIEnv* env, jlong ssl_ech_keys_address, bool throwIfNull) { |
| 128 | + SSL_ECH_KEYS* ssl_ech_keys = reinterpret_cast<SSL_ECH_KEYS*>(static_cast<uintptr_t>(ssl_ech_keys_address)); |
| 129 | + if ((ssl_ech_keys == nullptr) && throwIfNull) { |
| 130 | + JNI_TRACE("ssl_ech_keys == null"); |
| 131 | + conscrypt::jniutil::throwNullPointerException(env, "ssl_ech_keys == null"); |
| 132 | + } |
| 133 | + return ssl_ech_keys; |
| 134 | +} |
| 135 | + |
126 | 136 | template <typename T> |
127 | 137 | static T* fromContextObject(JNIEnv* env, jobject contextObject) { |
128 | 138 | if (contextObject == nullptr) { |
@@ -10429,6 +10439,96 @@ static jlong NativeCrypto_SSL_get1_session(JNIEnv* env, jclass, jlong ssl_addres |
10429 | 10439 | return reinterpret_cast<uintptr_t>(SSL_get1_session(ssl)); |
10430 | 10440 | } |
10431 | 10441 |
|
| 10442 | +static void NativeCrypto_SSL_set_enable_ech_grease(JNIEnv* env, jclass, jlong ssl_address, |
| 10443 | + CONSCRYPT_UNUSED jobject ssl_holder, |
| 10444 | + jboolean enable) { |
| 10445 | + CHECK_ERROR_QUEUE_ON_RETURN; |
| 10446 | + SSL* ssl = to_SSL(env, ssl_address, true); |
| 10447 | + JNI_TRACE("ssl=%p NativeCrypto_SSL_set_enable_ech_grease(%d)", ssl, enable); |
| 10448 | + if (ssl == nullptr) { |
| 10449 | + return; |
| 10450 | + } |
| 10451 | + SSL_set_enable_ech_grease(ssl, enable ? 1 : 0); |
| 10452 | + JNI_TRACE("ssl=%p NativeCrypto_SSL_set_enable_ech_grease(%d) => success", ssl, enable); |
| 10453 | +} |
| 10454 | + |
| 10455 | +static jboolean NativeCrypto_SSL_set1_ech_config_list(JNIEnv* env, jclass, jlong ssl_address, |
| 10456 | + CONSCRYPT_UNUSED jobject ssl_holder, |
| 10457 | + jbyteArray configJavaBytes) { |
| 10458 | + CHECK_ERROR_QUEUE_ON_RETURN; |
| 10459 | + SSL* ssl = to_SSL(env, ssl_address, true); |
| 10460 | + JNI_TRACE("ssl=%p NativeCrypto_SSL_set1_ech_config_list(%p)", ssl, configJavaBytes); |
| 10461 | + if (ssl == nullptr) { |
| 10462 | + return JNI_FALSE; |
| 10463 | + } |
| 10464 | + ScopedByteArrayRO configBytes(env, configJavaBytes); |
| 10465 | + if (configBytes.get() == nullptr) { |
| 10466 | + JNI_TRACE("NativeCrypto_SSL_set1_ech_config_list => threw exception:" |
| 10467 | + " could not read config bytes"); |
| 10468 | + return JNI_FALSE; |
| 10469 | + } |
| 10470 | + const uint8_t* bs = reinterpret_cast<const uint8_t*>(configBytes.get()); |
| 10471 | + int ret = SSL_set1_ech_config_list(ssl, reinterpret_cast<const uint8_t*>(configBytes.get()), |
| 10472 | + configBytes.size()); |
| 10473 | + JNI_TRACE("ssl=%p NativeCrypto_SSL_set1_ech_config_list(%p) => %d", ssl, configJavaBytes, ret); |
| 10474 | + return !!ret; |
| 10475 | +} |
| 10476 | + |
| 10477 | +/** |
| 10478 | + * public static native long SSL_ech_accepted(long ssl); |
| 10479 | + */ |
| 10480 | +static jboolean NativeCrypto_SSL_ech_accepted(JNIEnv* env, jclass, jlong ssl_address, |
| 10481 | + CONSCRYPT_UNUSED jobject ssl_holder) { |
| 10482 | + JNI_TRACE("NativeCrypto_SSL_ech_accepted"); |
| 10483 | + CHECK_ERROR_QUEUE_ON_RETURN; |
| 10484 | + SSL* ssl = to_SSL(env, ssl_address, true); |
| 10485 | + JNI_TRACE("ssl=%p NativeCrypto_SSL_ech_accepted", ssl); |
| 10486 | + if (ssl == nullptr) { |
| 10487 | + return 0; |
| 10488 | + } |
| 10489 | + jboolean accepted = SSL_ech_accepted(ssl); |
| 10490 | + JNI_TRACE("ssl=%p NativeCrypto_SSL_ech_accepted => %d", ssl, accepted); |
| 10491 | + return accepted; |
| 10492 | +} |
| 10493 | + |
| 10494 | +static jboolean NativeCrypto_SSL_CTX_ech_enable_server(JNIEnv* env, jclass, jlong ssl_ctx_address, |
| 10495 | + CONSCRYPT_UNUSED jobject holder, |
| 10496 | + jbyteArray keyJavaBytes, |
| 10497 | + jbyteArray configJavaBytes) { |
| 10498 | + CHECK_ERROR_QUEUE_ON_RETURN; |
| 10499 | + SSL_CTX* ssl_ctx = to_SSL_CTX(env, ssl_ctx_address, true); |
| 10500 | + JNI_TRACE("NativeCrypto_SSL_CTX_ech_enable_server(keyJavaBytes=%p, configJavaBytes=%p)", |
| 10501 | + keyJavaBytes, configJavaBytes); |
| 10502 | + ScopedByteArrayRO keyBytes(env, keyJavaBytes); |
| 10503 | + if (keyBytes.get() == nullptr) { |
| 10504 | + JNI_TRACE("NativeCrypto_SSL_CTX_ech_enable_server => threw exception: " |
| 10505 | + "could not read key bytes"); |
| 10506 | + return JNI_FALSE; |
| 10507 | + } |
| 10508 | + ScopedByteArrayRO configBytes(env, configJavaBytes); |
| 10509 | + if (configBytes.get() == nullptr) { |
| 10510 | + JNI_TRACE("NativeCrypto_SSL_CTX_ech_enable_server => threw exception: " |
| 10511 | + "could not read config bytes"); |
| 10512 | + return JNI_FALSE; |
| 10513 | + } |
| 10514 | + const uint8_t* ech_key = reinterpret_cast<const uint8_t*>(keyBytes.get()); |
| 10515 | + size_t ech_key_size = keyBytes.size(); |
| 10516 | + const uint8_t* ech_config = reinterpret_cast<const uint8_t*>(configBytes.get()); |
| 10517 | + size_t ech_config_size = configBytes.size(); |
| 10518 | + bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new()); |
| 10519 | + bssl::ScopedEVP_HPKE_KEY key; |
| 10520 | + if (!keys || |
| 10521 | + !EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(), ech_key, ech_key_size) || |
| 10522 | + !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, |
| 10523 | + ech_config, ech_config_size, key.get()) || |
| 10524 | + !SSL_CTX_set1_ech_keys(ssl_ctx, keys.get())) { |
| 10525 | + JNI_TRACE("NativeCrypto_SSL_CTX_ech_enable_server: " |
| 10526 | + "Error setting server's ECHConfig and private key\n"); |
| 10527 | + return JNI_FALSE; |
| 10528 | + } |
| 10529 | + return JNI_TRUE; |
| 10530 | +} |
| 10531 | + |
10432 | 10532 | // TESTING METHODS END |
10433 | 10533 |
|
10434 | 10534 | #define CONSCRYPT_NATIVE_METHOD(functionName, signature) \ |
@@ -10749,6 +10849,10 @@ static JNINativeMethod sNativeCryptoMethods[] = { |
10749 | 10849 | CONSCRYPT_NATIVE_METHOD(ENGINE_SSL_force_read, "(J" REF_SSL SSL_CALLBACKS ")V"), |
10750 | 10850 | CONSCRYPT_NATIVE_METHOD(ENGINE_SSL_shutdown, "(J" REF_SSL SSL_CALLBACKS ")V"), |
10751 | 10851 | CONSCRYPT_NATIVE_METHOD(usesBoringSsl_FIPS_mode, "()Z"), |
| 10852 | + CONSCRYPT_NATIVE_METHOD(SSL_set_enable_ech_grease, "(J" REF_SSL "Z)V"), |
| 10853 | + CONSCRYPT_NATIVE_METHOD(SSL_set1_ech_config_list, "(J" REF_SSL "[B)Z"), |
| 10854 | + CONSCRYPT_NATIVE_METHOD(SSL_ech_accepted, "(J" REF_SSL ")Z"), |
| 10855 | + CONSCRYPT_NATIVE_METHOD(SSL_CTX_ech_enable_server, "(J" REF_SSL_CTX "[B[B)Z"), |
10752 | 10856 |
|
10753 | 10857 | // Used for testing only. |
10754 | 10858 | CONSCRYPT_NATIVE_METHOD(BIO_read, "(J[B)I"), |
|
0 commit comments