Convert ClientHello tests to GTest.

I was just passing by.

Change-Id: I0212b4a1a3fd2ad24d7157181cd55a92263a3727
Reviewed-on: https://boringssl-review.googlesource.com/20904
Commit-Queue: David Benjamin <davidben@google.com>
Commit-Queue: Steven Valdez <svaldez@google.com>
Reviewed-by: Steven Valdez <svaldez@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
David Benjamin 2017-09-25 15:05:19 -04:00 committed by CQ bot account: commit-bot@chromium.org
parent e9c7b1c8ae
commit 737d2dffdf

View File

@ -1941,197 +1941,106 @@ TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
EXPECT_EQ(Bytes(cert_sha256), Bytes(session->peer_sha256)); EXPECT_EQ(Bytes(cert_sha256), Bytes(session->peer_sha256));
} }
static bool ClientHelloMatches(uint16_t version, const uint8_t *expected, // Tests that our ClientHellos do not change unexpectedly. These are purely
size_t expected_len) { // change detection tests. If they fail as part of an intentional ClientHello
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method())); // change, update the test vector.
// Our default cipher list varies by CPU capabilities, so manually place the TEST(SSLTest, ClientHello) {
// ChaCha20 ciphers in front. struct {
const char* cipher_list = "CHACHA20:ALL"; uint16_t max_version;
if (!ctx || std::vector<uint8_t> expected;
// SSLv3 is off by default. } kTests[] = {
!SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) || {SSL3_VERSION,
!SSL_CTX_set_max_proto_version(ctx.get(), version) || {0x16, 0x03, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, 0x37, 0x03, 0x00,
!SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
return false; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00,
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get())); 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x00, 0xff, 0x01, 0x00}},
if (!ssl) { {TLS1_VERSION,
return false; {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x01, 0x00,
} 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
std::vector<uint8_t> client_hello; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
if (!GetClientHello(ssl.get(), &client_hello)) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
return false; 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
}
// Zero the client_random.
constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1 + 3 + // handshake message header
2; // client_version
if (client_hello.size() < kRandomOffset + SSL3_RANDOM_SIZE) {
fprintf(stderr, "ClientHello for version %04x too short.\n", version);
return false;
}
OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
if (client_hello.size() != expected_len ||
OPENSSL_memcmp(client_hello.data(), expected, expected_len) != 0) {
fprintf(stderr, "ClientHello for version %04x did not match:\n", version);
fprintf(stderr, "Got:\n\t");
for (size_t i = 0; i < client_hello.size(); i++) {
fprintf(stderr, "0x%02x, ", client_hello[i]);
}
fprintf(stderr, "\nWanted:\n\t");
for (size_t i = 0; i < expected_len; i++) {
fprintf(stderr, "0x%02x, ", expected[i]);
}
fprintf(stderr, "\n");
return false;
}
return true;
}
// Tests that our ClientHellos do not change unexpectedly.
static bool TestClientHello() {
static const uint8_t kSSL3ClientHello[] = {
0x16,
0x03, 0x00,
0x00, 0x3b,
0x01,
0x00, 0x00, 0x37,
0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x00, 0x10,
0xc0, 0x09,
0xc0, 0x13,
0xc0, 0x0a,
0xc0, 0x14,
0x00, 0x2f,
0x00, 0x35,
0x00, 0x0a,
0x00, 0xff, 0x01, 0x00,
};
if (!ClientHelloMatches(SSL3_VERSION, kSSL3ClientHello,
sizeof(kSSL3ClientHello))) {
return false;
}
static const uint8_t kTLS1ClientHello[] = {
0x16,
0x03, 0x01,
0x00, 0x5a,
0x01,
0x00, 0x00, 0x56,
0x03, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x00, 0x0e,
0xc0, 0x09,
0xc0, 0x13,
0xc0, 0x0a,
0xc0, 0x14,
0x00, 0x2f,
0x00, 0x35,
0x00, 0x0a,
0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
}; {TLS1_1_VERSION,
if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello, {0x16, 0x03, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x56, 0x03, 0x02, 0x00,
sizeof(kTLS1ClientHello))) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
return false; 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
} 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xc0, 0x09,
0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a,
static const uint8_t kTLS11ClientHello[] = {
0x16,
0x03, 0x01,
0x00, 0x5a,
0x01,
0x00, 0x00, 0x56,
0x03, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00,
0x00, 0x0e,
0xc0, 0x09,
0xc0, 0x13,
0xc0, 0x0a,
0xc0, 0x14,
0x00, 0x2f,
0x00, 0x35,
0x00, 0x0a,
0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00, 0x00, 0x1f, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
}; // This test assumes RSA-PSS, which is disabled for Android system builds.
if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello, #if !defined(BORINGSSL_ANDROID_SYSTEM)
sizeof(kTLS11ClientHello))) { {TLS1_2_VERSION,
return false; {0x16, 0x03, 0x01, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x8a, 0x03, 0x03, 0x00,
} 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xcc, 0xa9,
// builds. 0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
#if defined(BORINGSSL_ANDROID_SYSTEM) 0xc0, 0x23, 0xc0, 0x13, 0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
return true; 0xc0, 0x28, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x35,
0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01,
0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00,
0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
0x17, 0x00, 0x18}},
#endif #endif
// TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
static const uint8_t kTLS12ClientHello[] = { // implementation has settled enough that it won't change.
0x16,
0x03, 0x01,
0x00, 0x8e,
0x01,
0x00, 0x00, 0x8a,
0x03, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x2a,
0xcc, 0xa9,
0xcc, 0xa8,
0xc0, 0x2b,
0xc0, 0x2f,
0xc0, 0x2c,
0xc0, 0x30,
0xc0, 0x09,
0xc0, 0x23,
0xc0, 0x13,
0xc0, 0x27,
0xc0, 0x0a,
0xc0, 0x24,
0xc0, 0x14,
0xc0, 0x28,
0x00, 0x9c,
0x00, 0x9d,
0x00, 0x2f,
0x00, 0x3c,
0x00, 0x35,
0x00, 0x3d,
0x00, 0x0a,
0x01, 0x00, 0x00, 0x37, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00,
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04,
0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08,
0x06, 0x06, 0x01, 0x02, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
}; };
if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
sizeof(kTLS12ClientHello))) { for (const auto &t : kTests) {
return false; SCOPED_TRACE(t.max_version);
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
ASSERT_TRUE(ctx);
// Our default cipher list varies by CPU capabilities, so manually place the
// ChaCha20 ciphers in front.
const char *cipher_list = "CHACHA20:ALL";
// SSLv3 is off by default.
ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
ASSERT_TRUE(ssl);
std::vector<uint8_t> client_hello;
ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
// Zero the client_random.
constexpr size_t kRandomOffset = 1 + 2 + 2 + // record header
1 + 3 + // handshake message header
2; // client_version
ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
if (client_hello != t.expected) {
ADD_FAILURE() << "ClientHellos did not match.";
// Print the value manually so it is easier to update the test vector.
for (size_t i = 0; i < client_hello.size(); i += 12) {
printf(" %c", i == 0 ? '{' : ' ');
for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
if (j > i) {
printf(" ");
}
printf("0x%02x", client_hello[j]);
if (j < client_hello.size() - 1) {
printf(",");
}
}
if (i + 12 >= client_hello.size()) {
printf("}}");
}
printf("\n");
}
}
} }
// TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
// implementation has settled enough that it won't change.
return true;
} }
static bssl::UniquePtr<SSL_SESSION> g_last_session; static bssl::UniquePtr<SSL_SESSION> g_last_session;
@ -3846,8 +3755,7 @@ TEST(SSLTest, AllTests) {
!TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) || !TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
// Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
// will be a PSK binder after the padding extension. // will be a PSK binder after the padding extension.
!TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) || !TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION)) {
!TestClientHello()) {
ADD_FAILURE() << "Tests failed"; ADD_FAILURE() << "Tests failed";
} }
} }