Add test coverage for TLS version negotiation.
Test all pairs of client and server version, except for the ones that require SSLv3 client support in runner.go. That is, as yet, still missing. Change-Id: I601ab49c5526cd2eb4f85d5d535570e32f218d5b Reviewed-on: https://boringssl-review.googlesource.com/1450 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
0fecacd46d
commit
7e2e6cf1a0
@ -271,6 +271,14 @@ static int do_exchange(SSL_SESSION **out_session,
|
|||||||
SSL_set_mode(ssl, SSL_MODE_CBC_RECORD_SPLITTING);
|
SSL_set_mode(ssl, SSL_MODE_CBC_RECORD_SPLITTING);
|
||||||
} else if (strcmp(argv[i], "-partial-write") == 0) {
|
} else if (strcmp(argv[i], "-partial-write") == 0) {
|
||||||
SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
|
||||||
|
} else if (strcmp(argv[i], "-no-tls12") == 0) {
|
||||||
|
SSL_set_options(ssl, SSL_OP_NO_TLSv1_2);
|
||||||
|
} else if (strcmp(argv[i], "-no-tls11") == 0) {
|
||||||
|
SSL_set_options(ssl, SSL_OP_NO_TLSv1_1);
|
||||||
|
} else if (strcmp(argv[i], "-no-tls1") == 0) {
|
||||||
|
SSL_set_options(ssl, SSL_OP_NO_TLSv1);
|
||||||
|
} else if (strcmp(argv[i], "-no-ssl3") == 0) {
|
||||||
|
SSL_set_options(ssl, SSL_OP_NO_SSLv3);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
|
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -72,6 +72,9 @@ type testCase struct {
|
|||||||
// expectedLocalError, if not empty, contains a substring that must be
|
// expectedLocalError, if not empty, contains a substring that must be
|
||||||
// found in the local error.
|
// found in the local error.
|
||||||
expectedLocalError string
|
expectedLocalError string
|
||||||
|
// expectedVersion, if non-zero, specifies the TLS version that must be
|
||||||
|
// negotiated.
|
||||||
|
expectedVersion uint16
|
||||||
// messageLen is the length, in bytes, of the test message that will be
|
// messageLen is the length, in bytes, of the test message that will be
|
||||||
// sent.
|
// sent.
|
||||||
messageLen int
|
messageLen int
|
||||||
@ -382,9 +385,9 @@ var testCases = []testCase{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func doExchange(testType testType, config *Config, conn net.Conn, messageLen int) error {
|
func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int) error {
|
||||||
var tlsConn *Conn
|
var tlsConn *Conn
|
||||||
if testType == clientTest {
|
if test.testType == clientTest {
|
||||||
tlsConn = Server(conn, config)
|
tlsConn = Server(conn, config)
|
||||||
} else {
|
} else {
|
||||||
config.InsecureSkipVerify = true
|
config.InsecureSkipVerify = true
|
||||||
@ -395,6 +398,10 @@ func doExchange(testType testType, config *Config, conn net.Conn, messageLen int
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if vers := tlsConn.ConnectionState().Version; test.expectedVersion != 0 && vers != test.expectedVersion {
|
||||||
|
return fmt.Errorf("got version %x, expected %x", vers, test.expectedVersion)
|
||||||
|
}
|
||||||
|
|
||||||
if messageLen < 0 {
|
if messageLen < 0 {
|
||||||
// Read until EOF.
|
// Read until EOF.
|
||||||
_, err := io.Copy(ioutil.Discard, tlsConn)
|
_, err := io.Copy(ioutil.Discard, tlsConn)
|
||||||
@ -527,10 +534,10 @@ func runTest(test *testCase, buildDir string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := doExchange(test.testType, &config, conn, test.messageLen)
|
err := doExchange(test, &config, conn, test.messageLen)
|
||||||
conn.Close()
|
conn.Close()
|
||||||
if err == nil && test.resumeSession {
|
if err == nil && test.resumeSession {
|
||||||
err = doExchange(test.testType, &config, connResume, test.messageLen)
|
err = doExchange(test, &config, connResume, test.messageLen)
|
||||||
connResume.Close()
|
connResume.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,11 +586,12 @@ func runTest(test *testCase, buildDir string) error {
|
|||||||
var tlsVersions = []struct {
|
var tlsVersions = []struct {
|
||||||
name string
|
name string
|
||||||
version uint16
|
version uint16
|
||||||
|
flag string
|
||||||
}{
|
}{
|
||||||
{"SSL3", VersionSSL30},
|
{"SSL3", VersionSSL30, "-no-ssl3"},
|
||||||
{"TLS1", VersionTLS10},
|
{"TLS1", VersionTLS10, "-no-tls1"},
|
||||||
{"TLS11", VersionTLS11},
|
{"TLS11", VersionTLS11, "-no-tls11"},
|
||||||
{"TLS12", VersionTLS12},
|
{"TLS12", VersionTLS12, "-no-tls12"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var testCipherSuites = []struct {
|
var testCipherSuites = []struct {
|
||||||
@ -969,6 +977,47 @@ func addStateMachineCoverageTests(async bool, splitHandshake bool) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func addVersionNegotiationTests() {
|
||||||
|
for i, shimVers := range tlsVersions {
|
||||||
|
// Assemble flags to disable all newer versions on the shim.
|
||||||
|
var flags []string
|
||||||
|
for _, vers := range tlsVersions[i+1:] {
|
||||||
|
flags = append(flags, vers.flag)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, runnerVers := range tlsVersions {
|
||||||
|
expectedVersion := shimVers.version
|
||||||
|
if runnerVers.version < shimVers.version {
|
||||||
|
expectedVersion = runnerVers.version
|
||||||
|
}
|
||||||
|
suffix := shimVers.name + "-" + runnerVers.name
|
||||||
|
|
||||||
|
testCases = append(testCases, testCase{
|
||||||
|
testType: clientTest,
|
||||||
|
name: "VersionNegotiation-Client-" + suffix,
|
||||||
|
config: Config{
|
||||||
|
MaxVersion: runnerVers.version,
|
||||||
|
},
|
||||||
|
flags: flags,
|
||||||
|
expectedVersion: expectedVersion,
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO(davidben): Implement SSLv3 as a client in the runner.
|
||||||
|
if expectedVersion > VersionSSL30 {
|
||||||
|
testCases = append(testCases, testCase{
|
||||||
|
testType: serverTest,
|
||||||
|
name: "VersionNegotiation-Server-" + suffix,
|
||||||
|
config: Config{
|
||||||
|
MaxVersion: runnerVers.version,
|
||||||
|
},
|
||||||
|
flags: flags,
|
||||||
|
expectedVersion: expectedVersion,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {
|
func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
@ -1020,6 +1069,7 @@ func main() {
|
|||||||
addCBCPaddingTests()
|
addCBCPaddingTests()
|
||||||
addCBCSplittingTests()
|
addCBCSplittingTests()
|
||||||
addClientAuthTests()
|
addClientAuthTests()
|
||||||
|
addVersionNegotiationTests()
|
||||||
for _, async := range []bool{false, true} {
|
for _, async := range []bool{false, true} {
|
||||||
for _, splitHandshake := range []bool{false, true} {
|
for _, splitHandshake := range []bool{false, true} {
|
||||||
addStateMachineCoverageTests(async, splitHandshake)
|
addStateMachineCoverageTests(async, splitHandshake)
|
||||||
|
Loading…
Reference in New Issue
Block a user