Test the behavior of running SSL_do_handshake twice in a row.

BUG=185

Change-Id: I4ce6735ca78cd687538a8c0fdbd78ee97b93585c
Reviewed-on: https://boringssl-review.googlesource.com/14382
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2017-03-26 15:13:51 -05:00 committed by CQ bot account: commit-bot@chromium.org
parent 7a60ca095d
commit 8c26d750e1
4 changed files with 124 additions and 0 deletions

View File

@ -1883,6 +1883,22 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
return false; return false;
} }
if (config->handshake_twice) {
do {
ret = SSL_do_handshake(ssl.get());
} while (config->async && RetryAsync(ssl.get(), ret));
if (ret != 1) {
return false;
}
}
// Skip the |config->async| logic as this should be a no-op.
if (config->no_op_extra_handshake &&
SSL_do_handshake(ssl.get()) != 1) {
fprintf(stderr, "Extra SSL_do_handshake was not a no-op.\n");
return false;
}
// Reset the state to assert later that the callback isn't called in // Reset the state to assert later that the callback isn't called in
// renegotations. // renegotations.
GetTestState(ssl.get())->got_new_session = false; GetTestState(ssl.get())->got_new_session = false;

View File

@ -10740,6 +10740,109 @@ func addECDSAKeyUsageTests() {
} }
} }
func addExtraHandshakeTests() {
// An extra SSL_do_handshake is normally a no-op. These tests use -async
// to ensure there is no transport I/O.
testCases = append(testCases, testCase{
testType: clientTest,
name: "ExtraHandshake-Client-TLS12",
config: Config{
MinVersion: VersionTLS12,
MaxVersion: VersionTLS12,
},
flags: []string{
"-async",
"-no-op-extra-handshake",
},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ExtraHandshake-Server-TLS12",
config: Config{
MinVersion: VersionTLS12,
MaxVersion: VersionTLS12,
},
flags: []string{
"-async",
"-no-op-extra-handshake",
},
})
testCases = append(testCases, testCase{
testType: clientTest,
name: "ExtraHandshake-Client-TLS13",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
},
flags: []string{
"-async",
"-no-op-extra-handshake",
},
})
testCases = append(testCases, testCase{
testType: serverTest,
name: "ExtraHandshake-Server-TLS13",
config: Config{
MinVersion: VersionTLS13,
MaxVersion: VersionTLS13,
},
flags: []string{
"-async",
"-no-op-extra-handshake",
},
})
// An extra SSL_do_handshake is a no-op in server 0-RTT.
testCases = append(testCases, testCase{
testType: serverTest,
name: "ExtraHandshake-Server-EarlyData-TLS13",
config: Config{
MaxVersion: VersionTLS13,
MinVersion: VersionTLS13,
Bugs: ProtocolBugs{
SendEarlyData: [][]byte{{1, 2, 3, 4}},
ExpectEarlyDataAccepted: true,
ExpectHalfRTTData: [][]byte{{254, 253, 252, 251}},
},
},
messageCount: 2,
resumeSession: true,
flags: []string{
"-async",
"-enable-early-data",
"-expect-accept-early-data",
"-no-op-extra-handshake",
},
})
// An extra SSL_do_handshake drives the handshake to completion in False
// Start. We test this by handshaking twice and asserting the False
// Start does not appear to happen. See AlertBeforeFalseStartTest for
// how the test works.
testCases = append(testCases, testCase{
testType: clientTest,
name: "ExtraHandshake-FalseStart",
config: Config{
MaxVersion: VersionTLS12,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
NextProtos: []string{"foo"},
Bugs: ProtocolBugs{
ExpectFalseStart: true,
AlertBeforeFalseStartTest: alertAccessDenied,
},
},
flags: []string{
"-handshake-twice",
"-false-start",
"-advertise-alpn", "\x03foo",
},
shimWritesFirst: true,
shouldFail: true,
expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
expectedLocalError: "tls: peer did not false start: EOF",
})
}
func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
defer wg.Done() defer wg.Done()
@ -10866,6 +10969,7 @@ func main() {
addCertificateTests() addCertificateTests()
addRetainOnlySHA256ClientCertTests() addRetainOnlySHA256ClientCertTests()
addECDSAKeyUsageTests() addECDSAKeyUsageTests()
addExtraHandshakeTests()
var wg sync.WaitGroup var wg sync.WaitGroup

View File

@ -128,6 +128,8 @@ const Flag<bool> kBoolFlags[] = {
{ "-expect-reject-early-data", &TestConfig::expect_reject_early_data }, { "-expect-reject-early-data", &TestConfig::expect_reject_early_data },
{ "-expect-no-alpn", &TestConfig::expect_no_alpn }, { "-expect-no-alpn", &TestConfig::expect_no_alpn },
{ "-expect-no-resume-alpn", &TestConfig::expect_no_resume_alpn }, { "-expect-no-resume-alpn", &TestConfig::expect_no_resume_alpn },
{ "-no-op-extra-handshake", &TestConfig::no_op_extra_handshake },
{ "-handshake-twice", &TestConfig::handshake_twice },
}; };
const Flag<std::string> kStringFlags[] = { const Flag<std::string> kStringFlags[] = {

View File

@ -141,6 +141,8 @@ struct TestConfig {
bool expect_session_id = false; bool expect_session_id = false;
bool expect_no_session_id = false; bool expect_no_session_id = false;
int expect_ticket_age_skew = 0; int expect_ticket_age_skew = 0;
bool no_op_extra_handshake = false;
bool handshake_twice = false;
}; };
bool ParseConfig(int argc, char **argv, TestConfig *out_config); bool ParseConfig(int argc, char **argv, TestConfig *out_config);