diff options
author | David Benjamin <davidben@google.com> | 2016-09-19 20:08:16 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2016-09-22 21:45:20 +0300 |
commit | f3fbadeae053aaa897df8433912bec59eb483521 (patch) | |
tree | 0aa8223a43b9e9bb61de6ec5039f0ff306fa2d85 | |
parent | e34bcc91c07c0bf65ecc53a814d51f5246007150 (diff) |
Add tests for SSL_peek.
SSL_peek works fine for us, but OpenSSL 1.1.0 regressed this
(https://github.com/openssl/openssl/issues/1563), and we don't have
tests either. Fix this.
SSL_peek can handle all weird events that SSL_read can, so use runner
and tell bssl_shim to do a SSL_peek + SSL_peek + SSL_read instead of
SSL_read. Then add tests for all the events we may discover.
Change-Id: I9e8635e3ca19653a02a883f220ab1332d4412f98
Reviewed-on: https://boringssl-review.googlesource.com/11090
Reviewed-by: Adam Langley <agl@google.com>
-rw-r--r-- | ssl/test/bssl_shim.cc | 24 | ||||
-rw-r--r-- | ssl/test/runner/runner.go | 72 | ||||
-rw-r--r-- | ssl/test/test_config.cc | 1 | ||||
-rw-r--r-- | ssl/test/test_config.h | 1 |
4 files changed, 97 insertions, 1 deletions
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index dc6e99d2..533e7b27 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc @@ -1020,11 +1020,33 @@ static int DoRead(SSL *ssl, uint8_t *out, size_t max_out) { // trigger a retransmit, so disconnect the write quota. AsyncBioEnforceWriteQuota(test_state->async_bio, false); } - ret = SSL_read(ssl, out, max_out); + ret = config->peek_then_read ? SSL_peek(ssl, out, max_out) + : SSL_read(ssl, out, max_out); if (config->async) { AsyncBioEnforceWriteQuota(test_state->async_bio, true); } } while (config->async && RetryAsync(ssl, ret)); + + if (config->peek_then_read && ret > 0) { + std::unique_ptr<uint8_t[]> buf(new uint8_t[static_cast<size_t>(ret)]); + + // SSL_peek should synchronously return the same data. + int ret2 = SSL_peek(ssl, buf.get(), ret); + if (ret2 != ret || + memcmp(buf.get(), out, ret) != 0) { + fprintf(stderr, "First and second SSL_peek did not match.\n"); + return -1; + } + + // SSL_read should synchronously return the same data and consume it. + ret2 = SSL_read(ssl, buf.get(), ret); + if (ret2 != ret || + memcmp(buf.get(), out, ret) != 0) { + fprintf(stderr, "SSL_peek and SSL_read did not match.\n"); + return -1; + } + } + return ret; } diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index c350ac5b..01de14fd 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -8192,6 +8192,77 @@ func addTLS13HandshakeTests() { }) } +func addPeekTests() { + // Test SSL_peek works, including on empty records. + testCases = append(testCases, testCase{ + name: "Peek-Basic", + sendEmptyRecords: 1, + flags: []string{"-peek-then-read"}, + }) + + // Test SSL_peek can drive the initial handshake. + testCases = append(testCases, testCase{ + name: "Peek-ImplicitHandshake", + flags: []string{ + "-peek-then-read", + "-implicit-handshake", + }, + }) + + // Test SSL_peek can discover and drive a renegotiation. + testCases = append(testCases, testCase{ + name: "Peek-Renegotiate", + config: Config{ + MaxVersion: VersionTLS12, + }, + renegotiate: 1, + flags: []string{ + "-peek-then-read", + "-renegotiate-freely", + "-expect-total-renegotiations", "1", + }, + }) + + // Test SSL_peek can discover a close_notify. + testCases = append(testCases, testCase{ + name: "Peek-Shutdown", + config: Config{ + Bugs: ProtocolBugs{ + ExpectCloseNotify: true, + }, + }, + flags: []string{ + "-peek-then-read", + "-check-close-notify", + }, + }) + + // Test SSL_peek can discover an alert. + testCases = append(testCases, testCase{ + name: "Peek-Alert", + config: Config{ + Bugs: ProtocolBugs{ + SendSpuriousAlert: alertRecordOverflow, + }, + }, + flags: []string{"-peek-then-read"}, + shouldFail: true, + expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:", + }) + + // Test SSL_peek can handle KeyUpdate. + testCases = append(testCases, testCase{ + name: "Peek-KeyUpdate", + config: Config{ + MaxVersion: VersionTLS13, + Bugs: ProtocolBugs{ + SendKeyUpdateBeforeEveryAppDataRecord: true, + }, + }, + flags: []string{"-peek-then-read"}, + }) +} + func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) { defer wg.Done() @@ -8308,6 +8379,7 @@ func main() { addWrongMessageTypeTests() addTrailingMessageDataTests() addTLS13HandshakeTests() + addPeekTests() var wg sync.WaitGroup diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc index 1f01166e..b7dc511b 100644 --- a/ssl/test/test_config.cc +++ b/ssl/test/test_config.cc @@ -104,6 +104,7 @@ const Flag<bool> kBoolFlags[] = { &TestConfig::use_old_client_cert_callback }, { "-use-null-client-ca-list", &TestConfig::use_null_client_ca_list }, { "-send-alert", &TestConfig::send_alert }, + { "-peek-then-read", &TestConfig::peek_then_read }, }; const Flag<std::string> kStringFlags[] = { diff --git a/ssl/test/test_config.h b/ssl/test/test_config.h index 93c22ce4..e0029a5b 100644 --- a/ssl/test/test_config.h +++ b/ssl/test/test_config.h @@ -112,6 +112,7 @@ struct TestConfig { int initial_timeout_duration_ms = 0; bool use_null_client_ca_list = false; bool send_alert = false; + bool peek_then_read = false; }; bool ParseConfig(int argc, char **argv, TestConfig *out_config); |