Implement SSLKEYLOGFILE support for TLS 1.3.
This adds three more formats to the SSLKEYLOGFILE format to support TLS 1.3: EARLY_TRAFFIC_SECRET <client_random> <early_traffic_secret> HANDSHAKE_TRAFFIC_SECRET <client_random> <handshake_traffic_secret> TRAFFIC_SECRET_0 <client_random> <traffic_secret_0> (We don't implement 0-RTT yet, so only the second two are implemented.) Motivations: 1. If emitted the non-traffic secrets (early, handshake, and master) or the IKMs, Wireshark needs to maintain a handshake hash. I don't believe they need to do this today. 2. We don't store more than one non-traffic secret at a time and don't keep traffic secrets for longer than needed. That suggests three separate lines logged at different times rather than one line. 3. If 0-RTT isn't used, we probably won't even compute the early traffic secret, so that further suggests three different lines. 4. If the handshake didn't get far enough to complete, we won't have an TRAFFIC_SECRET_0 to log at all. That seems like exactly when Wireshark would be handy, which means we want to log secrets as they are computed. MT from NSS has ACK'd over email that this format would be acceptable for them, so let's go with it. Change-Id: I4d685a1355dff4d4bd200310029d502bb6c511f9 Reviewed-on: https://boringssl-review.googlesource.com/8841 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:
parent
f2401eb42b
commit
e776cc2956
@ -911,6 +911,23 @@ int ext_key_share_parse_clienthello(SSL *ssl, uint8_t **out_secret,
|
||||
int ext_key_share_add_serverhello(SSL *ssl, CBB *out);
|
||||
|
||||
|
||||
/* SSLKEYLOGFILE functions. */
|
||||
|
||||
/* ssl_log_rsa_client_key_exchange logs |premaster|, if logging is enabled for
|
||||
* |ssl|. It returns one on success and zero on failure. The entry is identified
|
||||
* by the first 8 bytes of |encrypted_premaster|. */
|
||||
int ssl_log_rsa_client_key_exchange(const SSL *ssl,
|
||||
const uint8_t *encrypted_premaster,
|
||||
size_t encrypted_premaster_len,
|
||||
const uint8_t *premaster,
|
||||
size_t premaster_len);
|
||||
|
||||
/* ssl_log_secret logs |secret| with label |label|, if logging is enabled for
|
||||
* |ssl|. It returns one on success and zero on failure. */
|
||||
int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret,
|
||||
size_t secret_len);
|
||||
|
||||
|
||||
/* Underdocumented functions.
|
||||
*
|
||||
* Functions below here haven't been touched up and may be underdocumented. */
|
||||
@ -1360,22 +1377,6 @@ int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len);
|
||||
|
||||
int tls1_record_handshake_hashes_for_channel_id(SSL *ssl);
|
||||
|
||||
/* ssl_log_rsa_client_key_exchange logs |premaster|, if logging is enabled for
|
||||
* |ssl|. It returns one on success and zero on failure. The entry is identified
|
||||
* by the first 8 bytes of |encrypted_premaster|. */
|
||||
int ssl_log_rsa_client_key_exchange(const SSL *ssl,
|
||||
const uint8_t *encrypted_premaster,
|
||||
size_t encrypted_premaster_len,
|
||||
const uint8_t *premaster,
|
||||
size_t premaster_len);
|
||||
|
||||
/* ssl_log_master_secret logs |master|, if logging is enabled for |ssl|. It
|
||||
* returns one on success and zero on failure. The entry is identified by
|
||||
* |client_random|. */
|
||||
int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
|
||||
size_t client_random_len, const uint8_t *master,
|
||||
size_t master_len);
|
||||
|
||||
/* ssl3_can_false_start returns one if |ssl| is allowed to False Start and zero
|
||||
* otherwise. */
|
||||
int ssl3_can_false_start(const SSL *ssl);
|
||||
|
@ -216,9 +216,8 @@ int ssl3_send_finished(SSL *ssl, int a, int b) {
|
||||
ssl->s3->tmp.finish_md_len = n;
|
||||
|
||||
/* Log the master secret, if logging is enabled. */
|
||||
if (!ssl_log_master_secret(ssl, ssl->s3->client_random, SSL3_RANDOM_SIZE,
|
||||
ssl->session->master_key,
|
||||
ssl->session->master_key_length)) {
|
||||
if (!ssl_log_secret(ssl, "CLIENT_RANDOM", ssl->session->master_key,
|
||||
ssl->session->master_key_length)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2470,26 +2470,22 @@ int ssl_log_rsa_client_key_exchange(const SSL *ssl,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ssl_log_master_secret(const SSL *ssl, const uint8_t *client_random,
|
||||
size_t client_random_len, const uint8_t *master,
|
||||
size_t master_len) {
|
||||
int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret,
|
||||
size_t secret_len) {
|
||||
if (ssl->ctx->keylog_callback == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (client_random_len != 32) {
|
||||
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CBB cbb;
|
||||
uint8_t *out;
|
||||
size_t out_len;
|
||||
if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) ||
|
||||
!CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
|
||||
!cbb_add_hex(&cbb, client_random, 32) ||
|
||||
if (!CBB_init(&cbb, strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 +
|
||||
secret_len * 2 + 1) ||
|
||||
!CBB_add_bytes(&cbb, (const uint8_t *)label, strlen(label)) ||
|
||||
!CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
|
||||
!cbb_add_hex(&cbb, master, master_len) ||
|
||||
!cbb_add_hex(&cbb, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
|
||||
!CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
|
||||
!cbb_add_hex(&cbb, secret, secret_len) ||
|
||||
!CBB_add_u8(&cbb, 0 /* NUL */) ||
|
||||
!CBB_finish(&cbb, &out, &out_len)) {
|
||||
CBB_cleanup(&cbb);
|
||||
|
@ -248,6 +248,8 @@ int tls13_set_handshake_traffic(SSL *ssl) {
|
||||
if (!derive_secret(ssl, traffic_secret, hs->hash_len,
|
||||
(const uint8_t *)kTLS13LabelHandshakeTraffic,
|
||||
strlen(kTLS13LabelHandshakeTraffic)) ||
|
||||
!ssl_log_secret(ssl, "HANDSHAKE_TRAFFIC_SECRET", traffic_secret,
|
||||
hs->hash_len) ||
|
||||
!tls13_set_traffic_key(ssl, type_handshake, evp_aead_open, traffic_secret,
|
||||
hs->hash_len) ||
|
||||
!tls13_set_traffic_key(ssl, type_handshake, evp_aead_seal, traffic_secret,
|
||||
@ -262,7 +264,9 @@ int tls13_derive_traffic_secret_0(SSL *ssl) {
|
||||
|
||||
return derive_secret(ssl, hs->traffic_secret_0, hs->hash_len,
|
||||
(const uint8_t *)kTLS13LabelApplicationTraffic,
|
||||
strlen(kTLS13LabelApplicationTraffic));
|
||||
strlen(kTLS13LabelApplicationTraffic)) &&
|
||||
ssl_log_secret(ssl, "TRAFFIC_SECRET_0", hs->traffic_secret_0,
|
||||
hs->hash_len);
|
||||
}
|
||||
|
||||
static const char kTLS13LabelExporter[] = "exporter master secret";
|
||||
|
Loading…
Reference in New Issue
Block a user