Add support for key logging callbacks.
Reviewed-by: Rich Salz <rsalz@openssl.org> Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/1646)
This commit is contained in:
parent
ea24bb0ac5
commit
2faa1b48fd
7 changed files with 177 additions and 2 deletions
|
@ -775,6 +775,25 @@ __owur int SSL_extension_supported(unsigned int ext_type);
|
|||
# define SSL_MAC_FLAG_READ_MAC_STREAM 1
|
||||
# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
|
||||
|
||||
/*
|
||||
* A callback for logging out TLS key material. This callback should log out
|
||||
* |line| followed by a newline.
|
||||
*/
|
||||
typedef void (*SSL_CTX_keylog_cb_func)(const SSL *ssl, const char *line);
|
||||
|
||||
/*
|
||||
* SSL_CTX_set_keylog_callback configures a callback to log key material. This
|
||||
* is intended for debugging use with tools like Wireshark. The cb function
|
||||
* should log line followed by a newline.
|
||||
*/
|
||||
void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb);
|
||||
|
||||
/*
|
||||
* SSL_CTX_get_keylog_callback returns the callback configured by
|
||||
* SSL_CTX_set_keylog_callback.
|
||||
*/
|
||||
SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -2079,6 +2098,7 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_F_FINAL_EMS 486
|
||||
# define SSL_F_FINAL_RENEGOTIATE 483
|
||||
# define SSL_F_FINAL_SIG_ALGS 497
|
||||
# define SSL_F_NSS_KEYLOG_INT 500
|
||||
# define SSL_F_OPENSSL_INIT_SSL 342
|
||||
# define SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION 436
|
||||
# define SSL_F_OSSL_STATEM_CLIENT_CONSTRUCT_MESSAGE 430
|
||||
|
@ -2170,6 +2190,8 @@ int ERR_load_SSL_strings(void);
|
|||
# define SSL_F_SSL_GET_SIGN_PKEY 183
|
||||
# define SSL_F_SSL_INIT_WBIO_BUFFER 184
|
||||
# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185
|
||||
# define SSL_F_SSL_LOG_MASTER_SECRET 498
|
||||
# define SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE 499
|
||||
# define SSL_F_SSL_MODULE_INIT 392
|
||||
# define SSL_F_SSL_NEW 186
|
||||
# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
|
@ -53,6 +53,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||
{ERR_FUNC(SSL_F_FINAL_EMS), "final_ems"},
|
||||
{ERR_FUNC(SSL_F_FINAL_RENEGOTIATE), "final_renegotiate"},
|
||||
{ERR_FUNC(SSL_F_FINAL_SIG_ALGS), "final_sig_algs"},
|
||||
{ERR_FUNC(SSL_F_NSS_KEYLOG_INT), "nss_keylog_int"},
|
||||
{ERR_FUNC(SSL_F_OPENSSL_INIT_SSL), "OPENSSL_init_ssl"},
|
||||
{ERR_FUNC(SSL_F_OSSL_STATEM_CLIENT13_READ_TRANSITION),
|
||||
"ossl_statem_client13_read_transition"},
|
||||
|
@ -177,6 +178,9 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
|||
{ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "ssl_get_sign_pkey"},
|
||||
{ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "ssl_init_wbio_buffer"},
|
||||
{ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"},
|
||||
{ERR_FUNC(SSL_F_SSL_LOG_MASTER_SECRET), "ssl_log_master_secret"},
|
||||
{ERR_FUNC(SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE),
|
||||
"ssl_log_rsa_client_key_exchange"},
|
||||
{ERR_FUNC(SSL_F_SSL_MODULE_INIT), "ssl_module_init"},
|
||||
{ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"},
|
||||
{ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),
|
||||
|
|
111
ssl/ssl_lib.c
111
ssl/ssl_lib.c
|
@ -4344,3 +4344,114 @@ const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb)
|
||||
{
|
||||
ctx->keylog_callback = cb;
|
||||
}
|
||||
|
||||
SSL_CTX_keylog_cb_func SSL_CTX_get_keylog_callback(const SSL_CTX *ctx)
|
||||
{
|
||||
return ctx->keylog_callback;
|
||||
}
|
||||
|
||||
static int nss_keylog_int(const char *prefix,
|
||||
SSL *ssl,
|
||||
const uint8_t *parameter_1,
|
||||
size_t parameter_1_len,
|
||||
const uint8_t *parameter_2,
|
||||
size_t parameter_2_len)
|
||||
{
|
||||
char *out = NULL;
|
||||
char *cursor = NULL;
|
||||
size_t out_len = 0;
|
||||
size_t i;
|
||||
size_t prefix_len;
|
||||
|
||||
if (ssl->ctx->keylog_callback == NULL) return 1;
|
||||
|
||||
/*
|
||||
* Our output buffer will contain the following strings, rendered with
|
||||
* space characters in between, terminated by a NULL character: first the
|
||||
* prefix, then the first parameter, then the second parameter. The
|
||||
* meaning of each parameter depends on the specific key material being
|
||||
* logged. Note that the first and second parameters are encoded in
|
||||
* hexadecimal, so we need a buffer that is twice their lengths.
|
||||
*/
|
||||
prefix_len = strlen(prefix);
|
||||
out_len = prefix_len + (2*parameter_1_len) + (2*parameter_2_len) + 3;
|
||||
if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) {
|
||||
SSLerr(SSL_F_NSS_KEYLOG_INT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(cursor, prefix);
|
||||
cursor += prefix_len;
|
||||
*cursor++ = ' ';
|
||||
|
||||
for (i = 0; i < parameter_1_len; i++) {
|
||||
sprintf(cursor, "%02x", parameter_1[i]);
|
||||
cursor += 2;
|
||||
}
|
||||
*cursor++ = ' ';
|
||||
|
||||
for (i = 0; i < parameter_2_len; i++) {
|
||||
sprintf(cursor, "%02x", parameter_2[i]);
|
||||
cursor += 2;
|
||||
}
|
||||
*cursor = '\0';
|
||||
|
||||
ssl->ctx->keylog_callback(ssl, (const char *)out);
|
||||
OPENSSL_free(out);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int ssl_log_rsa_client_key_exchange(SSL *ssl,
|
||||
const uint8_t *encrypted_premaster,
|
||||
size_t encrypted_premaster_len,
|
||||
const uint8_t *premaster,
|
||||
size_t premaster_len)
|
||||
{
|
||||
if (encrypted_premaster_len < 8) {
|
||||
SSLerr(SSL_F_SSL_LOG_RSA_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nss_keylog_int("RSA",
|
||||
ssl,
|
||||
encrypted_premaster,
|
||||
encrypted_premaster_len,
|
||||
premaster,
|
||||
premaster_len);
|
||||
}
|
||||
|
||||
int ssl_log_master_secret(SSL *ssl,
|
||||
const uint8_t *client_random,
|
||||
size_t client_random_len,
|
||||
const uint8_t *master,
|
||||
size_t master_len)
|
||||
{
|
||||
/*
|
||||
* TLSv1.3 changes the derivation of the master secret compared to earlier
|
||||
* TLS versions, meaning that logging it out is less useful. Instead we
|
||||
* want to log out other secrets: specifically, the handshake and
|
||||
* application traffic secrets. For this reason, if this function is called
|
||||
* for TLSv1.3 we don't bother logging, and just return success
|
||||
* immediately.
|
||||
*/
|
||||
if (SSL_IS_TLS13(ssl)) return 1;
|
||||
|
||||
if (client_random_len != 32) {
|
||||
SSLerr(SSL_F_SSL_LOG_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nss_keylog_int("CLIENT_RANDOM",
|
||||
ssl,
|
||||
client_random,
|
||||
client_random_len,
|
||||
master,
|
||||
master_len);
|
||||
}
|
||||
|
||||
|
|
|
@ -875,6 +875,12 @@ struct ssl_ctx_st {
|
|||
int (*not_resumable_session_cb) (SSL *ssl, int is_forward_secure);
|
||||
|
||||
CRYPTO_RWLOCK *lock;
|
||||
|
||||
/*
|
||||
* Callback for logging key material for use with debugging tools like
|
||||
* Wireshark. The callback should log `line` followed by a newline.
|
||||
*/
|
||||
SSL_CTX_keylog_cb_func keylog_callback;
|
||||
};
|
||||
|
||||
struct ssl_st {
|
||||
|
@ -2194,6 +2200,26 @@ __owur const EVP_MD *ssl_md(int idx);
|
|||
__owur const EVP_MD *ssl_handshake_md(SSL *s);
|
||||
__owur const EVP_MD *ssl_prf_md(SSL *s);
|
||||
|
||||
/*
|
||||
* ssl_log_rsa_client_key_exchange logs |premaster| to the SSL_CTX associated
|
||||
* with |ssl|, if logging is enabled. It returns one on success and zero on
|
||||
* failure. The entry is identified by the first 8 bytes of
|
||||
* |encrypted_premaster|.
|
||||
*/
|
||||
__owur int ssl_log_rsa_client_key_exchange(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| to the SSL_CTX associated with |ssl|, if
|
||||
* logging is enabled. It returns one on success and zero on failure. The entry
|
||||
* is identified by |client_random|.
|
||||
*/
|
||||
__owur int ssl_log_master_secret(SSL *ssl, const uint8_t *client_random,
|
||||
size_t client_random_len,
|
||||
const uint8_t *master, size_t master_len);
|
||||
|
||||
/* s3_cbc.c */
|
||||
__owur char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
|
||||
__owur int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
|
||||
|
|
|
@ -2258,7 +2258,7 @@ int tls_process_cert_status_body(SSL *s, PACKET *pkt, int *al)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
MSG_PROCESS_RETURN tls_process_cert_status(SSL *s, PACKET *pkt)
|
||||
{
|
||||
|
@ -2522,6 +2522,10 @@ static int tls_construct_cke_rsa(SSL *s, WPACKET *pkt, int *al)
|
|||
s->s3->tmp.pms = pms;
|
||||
s->s3->tmp.pmslen = pmslen;
|
||||
|
||||
/* Log the premaster secret, if logging is enabled. */
|
||||
if (!ssl_log_rsa_client_key_exchange(s, encdata, enclen, pms, pmslen))
|
||||
goto err;
|
||||
|
||||
return 1;
|
||||
err:
|
||||
OPENSSL_clear_free(pms, pmslen);
|
||||
|
|
|
@ -427,6 +427,12 @@ int tls_construct_finished(SSL *s, WPACKET *pkt)
|
|||
goto err;
|
||||
}
|
||||
|
||||
/* Log the master secret, if logging is enabled. */
|
||||
if (!ssl_log_master_secret(s, s->s3->client_random, SSL3_RANDOM_SIZE,
|
||||
s->session->master_key,
|
||||
s->session->master_key_length))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Copy the finished so we can use it for renegotiation checks
|
||||
*/
|
||||
|
|
|
@ -410,3 +410,5 @@ SSL_peek_ex 410 1_1_1 EXIST::FUNCTION:
|
|||
SSL_write_ex 411 1_1_1 EXIST::FUNCTION:
|
||||
SSL_COMP_get_id 412 1_1_0d EXIST::FUNCTION:
|
||||
SSL_COMP_get0_name 413 1_1_0d EXIST::FUNCTION:
|
||||
SSL_CTX_set_keylog_callback 414 1_1_1 EXIST::FUNCTION:
|
||||
SSL_CTX_get_keylog_callback 415 1_1_1 EXIST::FUNCTION:
|
||||
|
|
Loading…
Reference in a new issue