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:
David Benjamin 2016-07-19 07:26:49 +02:00 committed by CQ bot account: commit-bot@chromium.org
parent f2401eb42b
commit e776cc2956
4 changed files with 32 additions and 32 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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";