runner: Test different V2ClientHello challenge lengths.
The challenge field, at least per our implementation and OpenSSL, may be
either left-padded or truncated to form the ClientHello random. Test
both cases, as well as an exact match.
Change-Id: Icdedf899ef483225d8ed20580ad15818b5e52e91
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46631
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 3f0d245..83439a0 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -760,6 +760,10 @@
// instead of a normal ClientHello.
SendV2ClientHello bool
+ // V2ClientHelloChallengeLength is the length of the challenge field to send
+ // in V2ClientHello.
+ V2ClientHelloChallengeLength int
+
// SendFallbackSCSV causes the client to include
// TLS_FALLBACK_SCSV in the ClientHello.
SendFallbackSCSV bool
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go
index 6ba4e4b..d368701 100644
--- a/ssl/test/runner/handshake_client.go
+++ b/ssl/test/runner/handshake_client.go
@@ -471,11 +471,28 @@
var helloBytes []byte
if c.config.Bugs.SendV2ClientHello {
hello.isV2ClientHello = true
+
// The V2ClientHello "challenge" field is variable-length and is
- // left-padded to become the SSL3/TLS random. Test this behavior by
- // forcing the left padding.
- hello.random[0] = 0
- hello.v2Challenge = hello.random[1:]
+ // left-padded or truncated to become the SSL3/TLS random.
+ challengeLength := c.config.Bugs.V2ClientHelloChallengeLength
+ if challengeLength == 0 {
+ challengeLength = len(hello.random)
+ }
+ if challengeLength <= len(hello.random) {
+ skip := len(hello.random) - challengeLength
+ for i := 0; i < skip; i++ {
+ hello.random[i] = 0
+ }
+ hello.v2Challenge = hello.random[skip:]
+ } else {
+ hello.v2Challenge = make([]byte, challengeLength)
+ copy(hello.v2Challenge, hello.random)
+ if _, err := io.ReadFull(c.config.rand(), hello.v2Challenge[len(hello.random):]); err != nil {
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: short read from Rand: %s", err)
+ }
+ }
+
helloBytes = hello.marshal()
c.writeV2Record(helloBytes)
} else {
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index e648b68..0e250c2 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -5628,23 +5628,26 @@
shimWritesFirst: true,
})
- // Server parses a V2ClientHello.
- tests = append(tests, testCase{
- testType: serverTest,
- name: "SendV2ClientHello",
- config: Config{
- // Choose a cipher suite that does not involve
- // elliptic curves, so no extensions are
- // involved.
- MaxVersion: VersionTLS12,
- CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
- Bugs: ProtocolBugs{
- SendV2ClientHello: true,
+ // Server parses a V2ClientHello. Test different lengths for the
+ // challenge field.
+ for _, challengeLength := range []int{16, 31, 32, 33, 48} {
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: fmt.Sprintf("SendV2ClientHello-%d", challengeLength),
+ config: Config{
+ // Choose a cipher suite that does not involve
+ // elliptic curves, so no extensions are
+ // involved.
+ MaxVersion: VersionTLS12,
+ CipherSuites: []uint16{TLS_RSA_WITH_3DES_EDE_CBC_SHA},
+ Bugs: ProtocolBugs{
+ SendV2ClientHello: true,
+ V2ClientHelloChallengeLength: challengeLength,
+ },
},
- },
- flags: []string{
- "-expect-msg-callback",
- `read v2clienthello
+ flags: []string{
+ "-expect-msg-callback",
+ `read v2clienthello
write hs 2
write hs 11
write hs 14
@@ -5655,8 +5658,9 @@
write hs 20
read alert 1 0
`,
- },
- })
+ },
+ })
+ }
// Channel ID and NPN at the same time, to ensure their relative
// ordering is correct.