Test ECH server with unique and repeated config IDs.
Also shortens ECH variable names in runner.go.
Bug: 275
Change-Id: Iaef520ae09eb94f714fbdaa4383d1456add6f113
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47744
Commit-Queue: Dan McArdle <dmcardle@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 0f7c628..4629a69 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -16167,10 +16167,10 @@
},
}
-// generateECHConfigWithSecretKey constructs a valid ECHConfig and corresponding
+// generateECHConfigWithKey constructs a valid ECHConfig and corresponding
// private key for the server. If the cipher list is empty, all ciphers are
// included.
-func generateECHConfigWithSecretKey(publicName string, ciphers []HPKECipherSuite) (*ECHConfig, []byte, error) {
+func generateECHConfigWithKey(publicName string, ciphers []HPKECipherSuite, configID uint8) (*ECHConfig, []byte, error) {
publicKeyR, secretKeyR, err := hpke.GenerateKeyPair()
if err != nil {
return nil, nil, err
@@ -16182,7 +16182,7 @@
}
}
result := ECHConfig{
- ConfigID: 42,
+ ConfigID: configID,
PublicName: publicName,
PublicKey: publicKeyR,
KEM: hpke.X25519WithHKDFSHA256,
@@ -16196,19 +16196,23 @@
}
func addEncryptedClientHelloTests() {
- publicECHConfig, secretKey, err := generateECHConfigWithSecretKey("public.example", nil)
+ echConfig, key, err := generateECHConfigWithKey("public.example", nil, 42)
if err != nil {
panic(err)
}
- publicECHConfig1, secretKey1, err := generateECHConfigWithSecretKey("public.example", nil)
+ echConfig1, key1, err := generateECHConfigWithKey("public.example", nil, 43)
if err != nil {
panic(err)
}
- publicECHConfig2, secretKey2, err := generateECHConfigWithSecretKey("public.example", nil)
+ echConfig2, key2, err := generateECHConfigWithKey("public.example", nil, 44)
if err != nil {
panic(err)
}
- publicECHConfig3, secretKey3, err := generateECHConfigWithSecretKey("public.example", nil)
+ echConfig3, key3, err := generateECHConfigWithKey("public.example", nil, 45)
+ if err != nil {
+ panic(err)
+ }
+ echConfigRepeatID, keyRepeatID, err := generateECHConfigWithKey("public.example", nil, 42)
if err != nil {
panic(err)
}
@@ -16234,13 +16238,13 @@
name: prefix + "ECH-Server" + suffix,
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
DefaultCurves: defaultCurves,
},
resumeSession: true,
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16258,7 +16262,7 @@
name: prefix + "ECH-Server-MinimalClientHelloOuter" + suffix,
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
DefaultCurves: defaultCurves,
Bugs: ProtocolBugs{
MinimalClientHelloOuter: true,
@@ -16266,8 +16270,8 @@
},
resumeSession: true,
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16287,24 +16291,24 @@
DefaultCurves: defaultCurves,
// The client uses an ECHConfig that the server does not understand
// so we can observe which retry configs the server sends back.
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
OfferSessionInClientHelloOuter: true,
- ExpectECHRetryConfigs: MarshalECHConfigList(publicECHConfig2, publicECHConfig3),
+ ExpectECHRetryConfigs: MarshalECHConfigList(echConfig2, echConfig3),
},
},
resumeSession: true,
flags: []string{
// Configure three ECHConfigs on the shim, only two of which
// should be sent in retry configs.
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig1)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey1),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig1)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key1),
"-ech-is-retry-config", "0",
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig2)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey2),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig2)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key2),
"-ech-is-retry-config", "1",
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig3)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey3),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig3)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key3),
"-ech-is-retry-config", "1",
"-expect-server-name", "public.example",
},
@@ -16319,14 +16323,14 @@
config: Config{
ServerName: "secret.example",
DefaultCurves: defaultCurves,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
AllowTLS12InClientHelloInner: true,
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1"},
shouldFail: true,
expectedLocalError: "remote error: illegal parameter",
@@ -16342,15 +16346,15 @@
config: Config{
ServerName: "secret.example",
DefaultCurves: defaultCurves,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
OmitECHIsInner: !hrr,
OmitSecondECHIsInner: hrr,
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
shouldFail: true,
@@ -16366,7 +16370,7 @@
config: Config{
ServerName: "secret.example",
DefaultCurves: defaultCurves,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
ECHOuterExtensions: []uint16{
extensionKeyShare,
extensionSupportedCurves,
@@ -16384,8 +16388,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16405,7 +16409,7 @@
config: Config{
ServerName: "secret.example",
DefaultCurves: defaultCurves,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
ECHOuterExtensions: []uint16{
extensionSupportedCurves,
extensionSupportedCurves,
@@ -16415,8 +16419,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16434,7 +16438,7 @@
config: Config{
ServerName: "secret.example",
DefaultCurves: defaultCurves,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
ECHOuterExtensions: []uint16{
extensionCustom,
},
@@ -16443,8 +16447,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16463,7 +16467,7 @@
config: Config{
ServerName: "secret.example",
DefaultCurves: defaultCurves,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
ECHOuterExtensions: []uint16{
extensionEncryptedClientHello,
},
@@ -16472,8 +16476,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16491,13 +16495,13 @@
name: prefix + "ECH-Server-AsyncEarlyCallback",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
},
flags: []string{
"-async",
"-use-early-callback",
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16514,14 +16518,38 @@
name: prefix + "ECH-Server-SecondECHConfig",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig1,
+ ClientECHConfig: echConfig1,
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig1)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey1),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig1)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key1),
+ "-ech-is-retry-config", "1",
+ "-expect-server-name", "secret.example",
+ },
+ expectations: connectionExpectations{
+ echAccepted: true,
+ },
+ })
+
+ // Test ECH-enabled server with two ECHConfigs that have the same config
+ // ID can decrypt client's ECH when it uses the second ECHConfig.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ protocol: protocol,
+ name: prefix + "ECH-Server-RepeatedConfigID",
+ config: Config{
+ ServerName: "secret.example",
+ ClientECHConfig: echConfigRepeatID,
+ },
+ flags: []string{
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig3)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key3),
+ "-ech-is-retry-config", "1",
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfigRepeatID)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(keyRepeatID),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16544,12 +16572,12 @@
name: prefix + "ECH-Server-Cipher-" + cipher.name,
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
ECHCipherSuites: []HPKECipherSuite{cipher.cipher},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "secret.example",
},
@@ -16560,7 +16588,7 @@
// Test that the ECH server rejects the specified cipher if not
// listed in its ECHConfig.
- config, key, err := generateECHConfigWithSecretKey("public.example", []HPKECipherSuite{otherCipher.cipher})
+ config, key, err := generateECHConfigWithKey("public.example", []HPKECipherSuite{otherCipher.cipher}, 42)
if err != nil {
panic(err)
}
@@ -16570,7 +16598,7 @@
name: prefix + "ECH-Server-DisabledCipher-" + cipher.name,
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
ECHCipherSuites: []HPKECipherSuite{cipher.cipher},
Bugs: ProtocolBugs{
ExpectECHRetryConfigs: MarshalECHConfigList(config),
@@ -16593,15 +16621,15 @@
name: prefix + "ECH-Server-ShortClientECHEnc",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
- ExpectECHRetryConfigs: MarshalECHConfigList(publicECHConfig),
+ ExpectECHRetryConfigs: MarshalECHConfigList(echConfig),
TruncateClientECHEnc: true,
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
"-expect-server-name", "public.example",
},
@@ -16615,15 +16643,15 @@
name: prefix + "ECH-Server-CorruptEncryptedClientHello",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
- ExpectECHRetryConfigs: MarshalECHConfigList(publicECHConfig),
+ ExpectECHRetryConfigs: MarshalECHConfigList(echConfig),
CorruptEncryptedClientHello: true,
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
})
@@ -16636,7 +16664,7 @@
name: prefix + "ECH-Server-CorruptSecondEncryptedClientHello",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
// Force a HelloRetryRequest.
DefaultCurves: []CurveID{},
Bugs: ProtocolBugs{
@@ -16644,8 +16672,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
shouldFail: true,
@@ -16660,7 +16688,7 @@
name: prefix + "ECH-Server-OmitSecondEncryptedClientHello",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
// Force a HelloRetryRequest.
DefaultCurves: []CurveID{},
Bugs: ProtocolBugs{
@@ -16668,8 +16696,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
shouldFail: true,
@@ -16684,7 +16712,7 @@
name: prefix + "ECH-Server-DifferentConfigIDSecondClientHello",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
// Force a HelloRetryRequest.
DefaultCurves: []CurveID{},
Bugs: ProtocolBugs{
@@ -16692,8 +16720,8 @@
},
},
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
shouldFail: true,
@@ -16708,13 +16736,13 @@
name: prefix + "ECH-Server-EarlyData",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
},
resumeSession: true,
earlyData: true,
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
expectations: connectionExpectations{
@@ -16727,7 +16755,7 @@
name: prefix + "ECH-Server-EarlyDataRejected",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
// Cause the server to reject 0-RTT with a bad ticket age.
SendTicketAge: 1 * time.Hour,
@@ -16737,8 +16765,8 @@
earlyData: true,
expectEarlyDataRejected: true,
flags: []string{
- "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(publicECHConfig)),
- "-ech-server-key", base64.StdEncoding.EncodeToString(secretKey),
+ "-ech-server-config", base64.StdEncoding.EncodeToString(MarshalECHConfig(echConfig)),
+ "-ech-server-key", base64.StdEncoding.EncodeToString(key),
"-ech-is-retry-config", "1",
},
expectations: connectionExpectations{
@@ -16754,7 +16782,7 @@
name: prefix + "ECH-Server-Disabled",
config: Config{
ServerName: "secret.example",
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
},
flags: []string{
"-expect-server-name", "public.example",
@@ -16953,7 +16981,7 @@
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
- ClientECHConfig: publicECHConfig,
+ ClientECHConfig: echConfig,
Bugs: ProtocolBugs{
AlwaysSendECHIsInner: true,
},