aboutsummaryrefslogtreecommitdiff
path: root/ssl
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2024-04-13 17:36:22 -0400
committerBoringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-04-17 21:00:59 +0000
commitf374e1af18c25700923985f6613417847e8f6ab1 (patch)
tree3860777423356f8e125fccbb49ad54a41ce0782f /ssl
parent5f924229aa9b85ae74c613081fe27de22384e7ee (diff)
downloadboringssl-f374e1af18c25700923985f6613417847e8f6ab1.zip
boringssl-f374e1af18c25700923985f6613417847e8f6ab1.tar.gz
boringssl-f374e1af18c25700923985f6613417847e8f6ab1.tar.bz2
Add some tests for SSL_CTX_set_keylog_callback
We actually don't test this at all right now. Change-Id: Iaac8850da3c012cbd21d0f38b026e7ff14db3650 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/67828 Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: David Benjamin <davidben@google.com>
Diffstat (limited to 'ssl')
-rw-r--r--ssl/ssl_test.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc
index 503ad5f..f39d042 100644
--- a/ssl/ssl_test.cc
+++ b/ssl/ssl_test.cc
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <openssl/aead.h>
@@ -60,6 +61,9 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
+using testing::ElementsAre;
+using testing::Key;
+
BSSL_NAMESPACE_BEGIN
namespace {
@@ -910,6 +914,35 @@ static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
return true;
}
+static bool DecodeLowerHex(std::vector<uint8_t> *out,
+ bssl::Span<const char> in) {
+ if (in.size() % 2 != 0) {
+ return false;
+ }
+ out->resize(in.size() / 2);
+ for (size_t i = 0; i < out->size(); i++) {
+ char hi = in[2 * i], lo = in[2 * i + 1];
+ uint8_t b = 0;
+ if ('0' <= hi && hi <= '9') {
+ b |= hi - '0';
+ } else if ('a' <= hi && hi <= 'f') {
+ b |= hi - 'a' + 10;
+ } else {
+ return false;
+ }
+ b <<= 4;
+ if ('0' <= lo && lo <= '9') {
+ b |= lo - '0';
+ } else if ('a' <= lo && lo <= 'f') {
+ b |= lo - 'a' + 10;
+ } else {
+ return false;
+ }
+ (*out)[i] = b;
+ }
+ return true;
+}
+
TEST(SSLTest, SessionEncoding) {
for (const char *input_b64 : {
kOpenSSLSession,
@@ -9332,5 +9365,80 @@ TEST_P(SSLVersionTest, NoCertOrKey) {
}
}
+TEST_P(SSLVersionTest, KeyLog) {
+ using KeyLog = std::map<std::string, std::vector<uint8_t>>;
+ KeyLog client_log, server_log;
+
+ SSL_CTX_set_app_data(client_ctx_.get(), &client_log);
+ SSL_CTX_set_app_data(server_ctx_.get(), &server_log);
+
+ auto keylog_callback = [](const SSL *ssl, const char *line) {
+ SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
+ KeyLog *log = static_cast<KeyLog *>(SSL_CTX_get_app_data(ctx));
+ ASSERT_TRUE(log);
+
+ const char *space1 = strchr(line, ' ');
+ ASSERT_TRUE(space1);
+ std::string name(line, space1 - line);
+ space1++;
+ const char *space2 = strchr(space1, ' ');
+ ASSERT_TRUE(space2);
+ bssl::Span<const char> client_random_hex(space1, space2 - space1);
+ space2++;
+ bssl::Span<const char> secret_hex(space2, strlen(space2));
+
+ std::vector<uint8_t> client_random, secret;
+ ASSERT_TRUE(DecodeLowerHex(&client_random, client_random_hex));
+ ASSERT_TRUE(DecodeLowerHex(&secret, secret_hex));
+
+ // The client_random field identifies the connection. Check it matches
+ // the connection.
+ uint8_t expected_random[SSL3_RANDOM_SIZE];
+ ASSERT_EQ(
+ sizeof(expected_random),
+ SSL_get_client_random(ssl, expected_random, sizeof(expected_random)));
+ ASSERT_EQ(Bytes(expected_random), Bytes(client_random));
+
+ ASSERT_EQ(log->count(name), 0u) << "duplicate name " << name;
+ log->emplace(std::move(name), std::move(secret));
+ };
+ SSL_CTX_set_keylog_callback(client_ctx_.get(), keylog_callback);
+ SSL_CTX_set_keylog_callback(server_ctx_.get(), keylog_callback);
+
+ // Connect and capture the various secrets.
+ ASSERT_TRUE(Connect());
+
+ // Check that we logged the secrets we expected to log.
+ if (version() == TLS1_3_VERSION) {
+ EXPECT_THAT(client_log, ElementsAre(Key("CLIENT_HANDSHAKE_TRAFFIC_SECRET"),
+ Key("CLIENT_TRAFFIC_SECRET_0"),
+ Key("EXPORTER_SECRET"),
+ Key("SERVER_HANDSHAKE_TRAFFIC_SECRET"),
+ Key("SERVER_TRAFFIC_SECRET_0")));
+
+ // Ideally we'd check the other values, but those are harder to check
+ // without actually decrypting the records.
+ Span<const uint8_t> read_secret, write_secret;
+ ASSERT_TRUE(bssl::SSL_get_traffic_secrets(client_.get(), &read_secret,
+ &write_secret));
+ EXPECT_EQ(Bytes(read_secret), Bytes(client_log["SERVER_TRAFFIC_SECRET_0"]));
+ EXPECT_EQ(Bytes(write_secret),
+ Bytes(client_log["CLIENT_TRAFFIC_SECRET_0"]));
+ } else {
+ EXPECT_THAT(client_log, ElementsAre(Key("CLIENT_RANDOM")));
+
+ size_t len =
+ SSL_SESSION_get_master_key(SSL_get0_session(client_.get()), nullptr, 0);
+ std::vector<uint8_t> expected(len);
+ ASSERT_EQ(SSL_SESSION_get_master_key(SSL_get0_session(client_.get()),
+ expected.data(), expected.size()),
+ expected.size());
+ EXPECT_EQ(Bytes(expected), Bytes(client_log["CLIENT_RANDOM"]));
+ }
+
+ // The server should have logged the same secrets as the client.
+ EXPECT_EQ(client_log, server_log);
+}
+
} // namespace
BSSL_NAMESPACE_END