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.