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:
parent
e9c7b1c8ae
commit
737d2dffdf
280
ssl/ssl_test.cc
280
ssl/ssl_test.cc
@ -1941,197 +1941,106 @@ TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
|
||||
EXPECT_EQ(Bytes(cert_sha256), Bytes(session->peer_sha256));
|
||||
}
|
||||
|
||||
static bool ClientHelloMatches(uint16_t version, const uint8_t *expected,
|
||||
size_t expected_len) {
|
||||
bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
|
||||
// Our default cipher list varies by CPU capabilities, so manually place the
|
||||
// ChaCha20 ciphers in front.
|
||||
const char* cipher_list = "CHACHA20:ALL";
|
||||
if (!ctx ||
|
||||
// SSLv3 is off by default.
|
||||
!SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION) ||
|
||||
!SSL_CTX_set_max_proto_version(ctx.get(), version) ||
|
||||
!SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
|
||||
if (!ssl) {
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> client_hello;
|
||||
if (!GetClientHello(ssl.get(), &client_hello)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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,
|
||||
// Tests that our ClientHellos do not change unexpectedly. These are purely
|
||||
// change detection tests. If they fail as part of an intentional ClientHello
|
||||
// change, update the test vector.
|
||||
TEST(SSLTest, ClientHello) {
|
||||
struct {
|
||||
uint16_t max_version;
|
||||
std::vector<uint8_t> expected;
|
||||
} kTests[] = {
|
||||
{SSL3_VERSION,
|
||||
{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}},
|
||||
{TLS1_VERSION,
|
||||
{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,
|
||||
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
|
||||
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
|
||||
};
|
||||
if (!ClientHelloMatches(TLS1_VERSION, kTLS1ClientHello,
|
||||
sizeof(kTLS1ClientHello))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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,
|
||||
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
|
||||
{TLS1_1_VERSION,
|
||||
{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,
|
||||
0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
|
||||
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
|
||||
};
|
||||
if (!ClientHelloMatches(TLS1_1_VERSION, kTLS11ClientHello,
|
||||
sizeof(kTLS11ClientHello))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// kTLS12ClientHello assumes RSA-PSS, which is disabled for Android system
|
||||
// builds.
|
||||
#if defined(BORINGSSL_ANDROID_SYSTEM)
|
||||
return true;
|
||||
0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18}},
|
||||
// This test assumes RSA-PSS, which is disabled for Android system builds.
|
||||
#if !defined(BORINGSSL_ANDROID_SYSTEM)
|
||||
{TLS1_2_VERSION,
|
||||
{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}},
|
||||
#endif
|
||||
|
||||
static const uint8_t kTLS12ClientHello[] = {
|
||||
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,
|
||||
// TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
|
||||
// implementation has settled enough that it won't change.
|
||||
};
|
||||
if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
|
||||
sizeof(kTLS12ClientHello))) {
|
||||
return false;
|
||||
|
||||
for (const auto &t : kTests) {
|
||||
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;
|
||||
@ -3846,8 +3755,7 @@ TEST(SSLTest, AllTests) {
|
||||
!TestPaddingExtension(TLS1_3_VERSION, TLS1_2_VERSION) ||
|
||||
// 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.
|
||||
!TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION) ||
|
||||
!TestClientHello()) {
|
||||
!TestPaddingExtension(TLS1_3_VERSION, TLS1_3_DRAFT_VERSION)) {
|
||||
ADD_FAILURE() << "Tests failed";
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user