Skip to content

Commit 18baf53

Browse files
committed
implement ECH Retry Config handling
This introduces a new Exception so that clients can respond only to the ECH retry request without having to parse SSLHandshakeExceptions in general. This exception should probably be implemented in boringssl or native_crypto.cc.
1 parent 2645b84 commit 18baf53

13 files changed

+264
-1
lines changed

common/src/jni/main/cpp/conscrypt/native_crypto.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10474,6 +10474,50 @@ static jboolean NativeCrypto_SSL_set1_ech_config_list(JNIEnv* env, jclass, jlong
1047410474
return !!ret;
1047510475
}
1047610476

10477+
static jstring NativeCrypto_SSL_get0_ech_name_override(JNIEnv* env, jclass, jlong ssl_address,
10478+
CONSCRYPT_UNUSED jobject ssl_holder) {
10479+
CHECK_ERROR_QUEUE_ON_RETURN;
10480+
SSL* ssl = to_SSL(env, ssl_address, true);
10481+
JNI_TRACE("ssl=%p NativeCrypto_SSL_get0_ech_name_override()", ssl);
10482+
if (ssl == nullptr) {
10483+
JNI_TRACE("ssl=%p NativeCrypto_SSL_get0_ech_name_override() => nullptr", ssl);
10484+
return nullptr;
10485+
}
10486+
const char* ech_name_override;
10487+
size_t ech_name_override_len;
10488+
SSL_get0_ech_name_override(ssl, &ech_name_override, &ech_name_override_len);
10489+
if (ech_name_override_len > 0) {
10490+
jstring name = env->NewStringUTF(ech_name_override);
10491+
return name;
10492+
}
10493+
return nullptr;
10494+
}
10495+
10496+
static jbyteArray NativeCrypto_SSL_get0_ech_retry_configs(JNIEnv* env, jclass, jlong ssl_address,
10497+
CONSCRYPT_UNUSED jobject ssl_holder) {
10498+
CHECK_ERROR_QUEUE_ON_RETURN;
10499+
SSL* ssl = to_SSL(env, ssl_address, true);
10500+
JNI_TRACE("ssl=%p NativeCrypto_SSL_get0_ech_retry_configs()", ssl);
10501+
if (ssl == nullptr) {
10502+
return nullptr;
10503+
}
10504+
10505+
const uint8_t *retry_configs;
10506+
size_t retry_configs_len;
10507+
SSL_get0_ech_retry_configs(ssl, &retry_configs, &retry_configs_len);
10508+
10509+
jbyteArray result = env->NewByteArray(static_cast<jsize>(retry_configs_len));
10510+
if (result == nullptr) {
10511+
JNI_TRACE("ssl=%p NativeCrypto_SSL_get0_ech_retry_configs() => creating byte array failed",
10512+
ssl);
10513+
return nullptr;
10514+
}
10515+
env->SetByteArrayRegion(result, 0, static_cast<jsize>(retry_configs_len),
10516+
(const jbyte*) retry_configs);
10517+
JNI_TRACE("ssl=%p NativeCrypto_SSL_get0_ech_retry_configs(%p) => %p", ssl, ssl, result);
10518+
return result;
10519+
}
10520+
1047710521
/**
1047810522
* public static native long SSL_ech_accepted(long ssl);
1047910523
*/
@@ -10851,6 +10895,8 @@ static JNINativeMethod sNativeCryptoMethods[] = {
1085110895
CONSCRYPT_NATIVE_METHOD(usesBoringSsl_FIPS_mode, "()Z"),
1085210896
CONSCRYPT_NATIVE_METHOD(SSL_set_enable_ech_grease, "(J" REF_SSL "Z)V"),
1085310897
CONSCRYPT_NATIVE_METHOD(SSL_set1_ech_config_list, "(J" REF_SSL "[B)Z"),
10898+
CONSCRYPT_NATIVE_METHOD(SSL_get0_ech_name_override, "(J" REF_SSL ")Ljava/lang/String;"),
10899+
CONSCRYPT_NATIVE_METHOD(SSL_get0_ech_retry_configs, "(J" REF_SSL ")[B"),
1085410900
CONSCRYPT_NATIVE_METHOD(SSL_ech_accepted, "(J" REF_SSL ")Z"),
1085510901
CONSCRYPT_NATIVE_METHOD(SSL_CTX_ech_enable_server, "(J" REF_SSL_CTX "[B[B)Z"),
1085610902

common/src/main/java/org/conscrypt/AbstractConscryptEngine.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ abstract class AbstractConscryptEngine extends SSLEngine {
100100

101101
public abstract byte[] getEchConfigList();
102102

103+
public abstract String getEchNameOverride();
104+
105+
public abstract byte[] getEchRetryConfig();
106+
103107
public abstract boolean echAccepted();
104108

105109
/* @Override */

common/src/main/java/org/conscrypt/AbstractConscryptSocket.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,5 +761,9 @@ abstract byte[] exportKeyingMaterial(String label, byte[] context, int length)
761761

762762
public abstract byte[] getEchConfigList();
763763

764+
public abstract String getEchNameOverride();
765+
766+
public abstract byte[] getEchRetryConfig();
767+
764768
public abstract boolean echAccepted();
765769
}

common/src/main/java/org/conscrypt/Conscrypt.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,14 @@ public static byte[] getEchConfigList(SSLSocket socket) {
510510
return toConscrypt(socket).getEchConfigList();
511511
}
512512

513+
public static String getEchNameOverride(SSLSocket socket) {
514+
return toConscrypt(socket).getEchNameOverride();
515+
}
516+
517+
public static byte[] getEchRetryConfig(SSLSocket socket) {
518+
return toConscrypt(socket).getEchConfigList();
519+
}
520+
513521
public static boolean echAccepted(SSLSocket socket) {
514522
return toConscrypt(socket).echAccepted();
515523
}

common/src/main/java/org/conscrypt/ConscryptEngine.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,16 @@ public byte[] getEchConfigList() {
415415
return sslParameters.getEchConfigList();
416416
}
417417

418+
@Override
419+
public String getEchNameOverride() {
420+
return ssl.getEchNameOverride();
421+
}
422+
423+
@Override
424+
public byte[] getEchRetryConfig() {
425+
return ssl.getEchRetryConfig();
426+
}
427+
418428
@Override
419429
public boolean echAccepted() {
420430
return ssl.echAccepted();

common/src/main/java/org/conscrypt/ConscryptEngineSocket.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,16 @@ public byte[] getEchConfigList() {
420420
return engine.getEchConfigList();
421421
}
422422

423+
@Override
424+
public String getEchNameOverride() {
425+
return engine.getEchNameOverride();
426+
}
427+
428+
@Override
429+
public byte[] getEchRetryConfig() {
430+
return engine.getEchRetryConfig();
431+
}
432+
423433
@Override
424434
public boolean echAccepted() {
425435
return engine.echAccepted();

common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,16 @@ public byte[] getEchConfigList() {
931931
return sslParameters.getEchConfigList();
932932
}
933933

934+
@Override
935+
public String getEchNameOverride() {
936+
return ssl.getEchNameOverride();
937+
}
938+
939+
@Override
940+
public byte[] getEchRetryConfig() {
941+
return ssl.getEchRetryConfig();
942+
}
943+
934944
@Override
935945
public boolean echAccepted() {
936946
return ssl.echAccepted();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.conscrypt;
2+
3+
import javax.net.ssl.SSLHandshakeException;
4+
5+
/**
6+
* The server rejected the ECH Config List, and might have supplied an ECH
7+
* Retry Config.
8+
*
9+
* @see NativeCrypto#SSL_get0_ech_retry_configs(long, NativeSsl)
10+
*/
11+
public class EchRejectedException extends SSLHandshakeException {
12+
private static final long serialVersionUID = 98723498273473923L;
13+
14+
EchRejectedException(String message) {
15+
super(message);
16+
}
17+
}
18+

common/src/main/java/org/conscrypt/Java8EngineWrapper.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ public byte[] getEchConfigList() {
136136
return delegate.getEchConfigList();
137137
}
138138

139+
@Override
140+
public String getEchNameOverride() {
141+
return delegate.getEchNameOverride();
142+
}
143+
144+
@Override
145+
public byte[] getEchRetryConfig() {
146+
return delegate.getEchRetryConfig();
147+
}
148+
139149
@Override
140150
public boolean echAccepted() {
141151
return delegate.echAccepted();

common/src/main/java/org/conscrypt/NativeCrypto.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,10 @@ static native void ENGINE_SSL_shutdown(long ssl, NativeSsl ssl_holder, SSLHandsh
14541454

14551455
static native boolean SSL_set1_ech_config_list(long ssl, NativeSsl ssl_holder, byte[] echConfig);
14561456

1457+
static native String SSL_get0_ech_name_override(long ssl, NativeSsl ssl_holder);
1458+
1459+
static native byte[] SSL_get0_ech_retry_configs(long ssl, NativeSsl ssl_holder);
1460+
14571461
static native boolean SSL_ech_accepted(long ssl, NativeSsl ssl_holder);
14581462

14591463
static native boolean SSL_CTX_ech_enable_server(long sslCtx, AbstractSessionContext holder,

0 commit comments

Comments
 (0)