Tidy up state machine coverage tests.
Rather than duplicate all the various modifiers, which is quite
error-prone, write all the tests to a temporary array and then apply
modifiers afterwards.
Change-Id: I19bfeb83b722ed34e973f17906c5e071471a926a
Reviewed-on: https://boringssl-review.googlesource.com/4782
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go
index 70b6120..bb21847 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -1908,6 +1908,268 @@
// various conditions. Some of these are redundant with other tests, but they
// only cover the synchronous case.
func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) {
+ var tests []testCase
+
+ // Basic handshake, with resumption. Client and server,
+ // session ID and session ticket.
+ tests = append(tests, testCase{
+ name: "Basic-Client",
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ name: "Basic-Client-RenewTicket",
+ config: Config{
+ Bugs: ProtocolBugs{
+ RenewTicketOnResume: true,
+ },
+ },
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ name: "Basic-Client-NoTicket",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ name: "Basic-Client-Implicit",
+ flags: []string{"-implicit-handshake"},
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server",
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-NoTickets",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-Implicit",
+ flags: []string{"-implicit-handshake"},
+ resumeSession: true,
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-EarlyCallback",
+ flags: []string{"-use-early-callback"},
+ resumeSession: true,
+ })
+
+ // TLS client auth.
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-Client",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ flags: []string{
+ "-cert-file", rsaCertificateFile,
+ "-key-file", rsaKeyFile,
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "ClientAuth-Server",
+ config: Config{
+ Certificates: []Certificate{rsaCertificate},
+ },
+ flags: []string{"-require-any-client-certificate"},
+ })
+
+ // No session ticket support; server doesn't send NewSessionTicket.
+ tests = append(tests, testCase{
+ name: "SessionTicketsDisabled-Client",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "SessionTicketsDisabled-Server",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ })
+
+ // Skip ServerKeyExchange in PSK key exchange if there's no
+ // identity hint.
+ tests = append(tests, testCase{
+ name: "EmptyPSKHint-Client",
+ config: Config{
+ CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
+ PreSharedKey: []byte("secret"),
+ },
+ flags: []string{"-psk", "secret"},
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "EmptyPSKHint-Server",
+ config: Config{
+ CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
+ PreSharedKey: []byte("secret"),
+ },
+ flags: []string{"-psk", "secret"},
+ })
+
+ if protocol == tls {
+ tests = append(tests, testCase{
+ name: "Renegotiate-Client",
+ renegotiate: true,
+ })
+ // NPN on client and server; results in post-handshake message.
+ tests = append(tests, testCase{
+ name: "NPN-Client",
+ config: Config{
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{"-select-next-proto", "foo"},
+ expectedNextProto: "foo",
+ expectedNextProtoType: npn,
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "NPN-Server",
+ config: Config{
+ NextProtos: []string{"bar"},
+ },
+ flags: []string{
+ "-advertise-npn", "\x03foo\x03bar\x03baz",
+ "-expect-next-proto", "bar",
+ },
+ expectedNextProto: "bar",
+ expectedNextProtoType: npn,
+ })
+
+ // TODO(davidben): Add tests for when False Start doesn't trigger.
+
+ // Client does False Start and negotiates NPN.
+ tests = append(tests, testCase{
+ name: "FalseStart",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-select-next-proto", "foo",
+ },
+ shimWritesFirst: true,
+ resumeSession: true,
+ })
+
+ // Client does False Start and negotiates ALPN.
+ tests = append(tests, testCase{
+ name: "FalseStart-ALPN",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ resumeSession: true,
+ })
+
+ // Client does False Start but doesn't explicitly call
+ // SSL_connect.
+ tests = append(tests, testCase{
+ name: "FalseStart-Implicit",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-implicit-handshake",
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ })
+
+ // False Start without session tickets.
+ tests = append(tests, testCase{
+ name: "FalseStart-SessionTicketsDisabled",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ SessionTicketsDisabled: true,
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-select-next-proto", "foo",
+ },
+ 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.
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ SendV2ClientHello: true,
+ },
+ },
+ })
+
+ // Client sends a Channel ID.
+ tests = append(tests, testCase{
+ name: "ChannelID-Client",
+ config: Config{
+ RequestChannelID: true,
+ },
+ flags: []string{"-send-channel-id", channelIDKeyFile},
+ resumeSession: true,
+ expectChannelID: true,
+ })
+
+ // Server accepts a Channel ID.
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "ChannelID-Server",
+ config: Config{
+ ChannelID: channelIDKey,
+ },
+ flags: []string{
+ "-expect-channel-id",
+ base64.StdEncoding.EncodeToString(channelIDBytes),
+ },
+ resumeSession: true,
+ expectChannelID: true,
+ })
+ } else {
+ tests = append(tests, testCase{
+ name: "SkipHelloVerifyRequest",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipHelloVerifyRequest: true,
+ },
+ },
+ })
+ }
+
var suffix string
var flags []string
var maxHandshakeRecordLength int
@@ -1924,368 +2186,12 @@
suffix += "-SplitHandshakeRecords"
maxHandshakeRecordLength = 1
}
-
- // Basic handshake, with resumption. Client and server,
- // session ID and session ticket.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "Basic-Client" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "Basic-Client-RenewTicket" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- RenewTicketOnResume: true,
- },
- },
- flags: flags,
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "Basic-Client-NoTicket" + suffix,
- config: Config{
- SessionTicketsDisabled: true,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "Basic-Client-Implicit" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags, "-implicit-handshake"),
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "Basic-Server" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "Basic-Server-NoTickets" + suffix,
- config: Config{
- SessionTicketsDisabled: true,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "Basic-Server-Implicit" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags, "-implicit-handshake"),
- resumeSession: true,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "Basic-Server-EarlyCallback" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags, "-use-early-callback"),
- resumeSession: true,
- })
-
- // TLS client auth.
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: clientTest,
- name: "ClientAuth-Client" + suffix,
- config: Config{
- ClientAuth: RequireAnyClientCert,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile),
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "ClientAuth-Server" + suffix,
- config: Config{
- Certificates: []Certificate{rsaCertificate},
- },
- flags: append(flags, "-require-any-client-certificate"),
- })
-
- // No session ticket support; server doesn't send NewSessionTicket.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "SessionTicketsDisabled-Client" + suffix,
- config: Config{
- SessionTicketsDisabled: true,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "SessionTicketsDisabled-Server" + suffix,
- config: Config{
- SessionTicketsDisabled: true,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- })
-
- // Skip ServerKeyExchange in PSK key exchange if there's no
- // identity hint.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "EmptyPSKHint-Client" + suffix,
- config: Config{
- CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
- PreSharedKey: []byte("secret"),
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags, "-psk", "secret"),
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "EmptyPSKHint-Server" + suffix,
- config: Config{
- CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
- PreSharedKey: []byte("secret"),
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags, "-psk", "secret"),
- })
-
- if protocol == tls {
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "Renegotiate-Client" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: flags,
- renegotiate: true,
- })
- // NPN on client and server; results in post-handshake message.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "NPN-Client" + suffix,
- config: Config{
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags, "-select-next-proto", "foo"),
- expectedNextProto: "foo",
- expectedNextProtoType: npn,
- })
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "NPN-Server" + suffix,
- config: Config{
- NextProtos: []string{"bar"},
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-advertise-npn", "\x03foo\x03bar\x03baz",
- "-expect-next-proto", "bar"),
- expectedNextProto: "bar",
- expectedNextProtoType: npn,
- })
-
- // TODO(davidben): Add tests for when False Start doesn't trigger.
-
- // Client does False Start and negotiates NPN.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "FalseStart" + suffix,
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-false-start",
- "-select-next-proto", "foo"),
- shimWritesFirst: true,
- resumeSession: true,
- })
-
- // Client does False Start and negotiates ALPN.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "FalseStart-ALPN" + suffix,
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-false-start",
- "-advertise-alpn", "\x03foo"),
- shimWritesFirst: true,
- resumeSession: true,
- })
-
- // Client does False Start but doesn't explicitly call
- // SSL_connect.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "FalseStart-Implicit" + suffix,
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-implicit-handshake",
- "-false-start",
- "-advertise-alpn", "\x03foo"),
- })
-
- // False Start without session tickets.
- testCases = append(testCases, testCase{
- name: "FalseStart-SessionTicketsDisabled" + suffix,
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- SessionTicketsDisabled: true,
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-false-start",
- "-select-next-proto", "foo",
- ),
- shimWritesFirst: true,
- })
-
- // Server parses a V2ClientHello.
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "SendV2ClientHello" + suffix,
- config: Config{
- // Choose a cipher suite that does not involve
- // elliptic curves, so no extensions are
- // involved.
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- SendV2ClientHello: true,
- },
- },
- flags: flags,
- })
-
- // Client sends a Channel ID.
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "ChannelID-Client" + suffix,
- config: Config{
- RequestChannelID: true,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-send-channel-id", channelIDKeyFile,
- ),
- resumeSession: true,
- expectChannelID: true,
- })
-
- // Server accepts a Channel ID.
- testCases = append(testCases, testCase{
- protocol: protocol,
- testType: serverTest,
- name: "ChannelID-Server" + suffix,
- config: Config{
- ChannelID: channelIDKey,
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- },
- },
- flags: append(flags,
- "-expect-channel-id",
- base64.StdEncoding.EncodeToString(channelIDBytes),
- ),
- resumeSession: true,
- expectChannelID: true,
- })
- } else {
- testCases = append(testCases, testCase{
- protocol: protocol,
- name: "SkipHelloVerifyRequest" + suffix,
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: maxHandshakeRecordLength,
- SkipHelloVerifyRequest: true,
- },
- },
- flags: flags,
- })
+ for _, test := range tests {
+ test.protocol = protocol
+ test.name += suffix
+ test.config.Bugs.MaxHandshakeRecordLength = maxHandshakeRecordLength
+ test.flags = append(test.flags, flags...)
+ testCases = append(testCases, test)
}
}