Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/boringssl.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@chromium.org>2014-09-03 00:29:36 +0400
committerAdam Langley <agl@google.com>2014-09-04 00:15:55 +0400
commit859ec3cc09f244348f3c919693817acb01064535 (patch)
tree4a962515b803f19caacf66f8303c15db1476ea47 /ssl/ssl_lib.c
parent60d612fdcf7052008fcc17a503854eac1653c739 (diff)
Add SSL_CTX_set_keylog_bio.
Configures the SSL stack to log session information to a BIO. The intent is to support NSS's SSLKEYLOGFILE environment variable. Add support for the same environment variable to tool/client.cc. Tested against Wireshark 1.12.0. BUG=393477 Change-Id: I4c231f9abebf194eb2df4aaeeafa337516774c95 Reviewed-on: https://boringssl-review.googlesource.com/1699 Reviewed-by: Adam Langley <agl@google.com>
Diffstat (limited to 'ssl/ssl_lib.c')
-rw-r--r--ssl/ssl_lib.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index b8df1bf0..1ad825ac 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -2130,6 +2130,9 @@ void SSL_CTX_free(SSL_CTX *a)
if (a->tlsext_channel_id_private)
EVP_PKEY_free(a->tlsext_channel_id_private);
+ if (a->keylog_bio)
+ BIO_free(a->keylog_bio);
+
OPENSSL_free(a);
}
@@ -3088,6 +3091,122 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}
+void SSL_CTX_set_keylog_bio(SSL_CTX *ctx, BIO *keylog_bio)
+ {
+ if (ctx->keylog_bio != NULL)
+ BIO_free(ctx->keylog_bio);
+ ctx->keylog_bio = keylog_bio;
+ }
+
+static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len)
+ {
+ static const char hextable[] = "0123456789abcdef";
+ uint8_t *out;
+ size_t i;
+
+ if (!CBB_add_space(cbb, &out, in_len * 2))
+ {
+ return 0;
+ }
+
+ for (i = 0; i < in_len; i++)
+ {
+ *(out++) = (uint8_t)hextable[in[i] >> 4];
+ *(out++) = (uint8_t)hextable[in[i] & 0xf];
+ }
+ return 1;
+ }
+
+int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
+ const uint8_t *encrypted_premaster, size_t encrypted_premaster_len,
+ const uint8_t *premaster, size_t premaster_len)
+ {
+ BIO *bio = ctx->keylog_bio;
+ CBB cbb;
+ uint8_t *out;
+ size_t out_len;
+ int ret;
+
+ if (bio == NULL)
+ {
+ return 1;
+ }
+
+ if (encrypted_premaster_len < 8)
+ {
+ OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len*2 + 1))
+ {
+ return 0;
+ }
+ if (!CBB_add_bytes(&cbb, (const uint8_t*)"RSA ", 4) ||
+ /* Only the first 8 bytes of the encrypted premaster secret are
+ * logged. */
+ !cbb_add_hex(&cbb, encrypted_premaster, 8) ||
+ !CBB_add_bytes(&cbb, (const uint8_t*)" ", 1) ||
+ !cbb_add_hex(&cbb, premaster, premaster_len) ||
+ !CBB_add_bytes(&cbb, (const uint8_t*)"\n", 1) ||
+ !CBB_finish(&cbb, &out, &out_len))
+ {
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+
+ CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+ ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
+ CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+
+ OPENSSL_free(out);
+ return ret;
+ }
+
+int ssl_ctx_log_master_secret(SSL_CTX *ctx,
+ const uint8_t *client_random, size_t client_random_len,
+ const uint8_t *master, size_t master_len)
+ {
+ BIO *bio = ctx->keylog_bio;
+ CBB cbb;
+ uint8_t *out;
+ size_t out_len;
+ int ret;
+
+ if (bio == NULL)
+ {
+ return 1;
+ }
+
+ if (client_random_len != 32)
+ {
+ OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (!CBB_init(&cbb, 14 + 64 + 1 + master_len*2 + 1))
+ {
+ return 0;
+ }
+ if (!CBB_add_bytes(&cbb, (const uint8_t*)"CLIENT_RANDOM ", 14) ||
+ !cbb_add_hex(&cbb, client_random, 32) ||
+ !CBB_add_bytes(&cbb, (const uint8_t*)" ", 1) ||
+ !cbb_add_hex(&cbb, master, master_len) ||
+ !CBB_add_bytes(&cbb, (const uint8_t*)"\n", 1) ||
+ !CBB_finish(&cbb, &out, &out_len))
+ {
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+
+ CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+ ret = BIO_write(bio, out, out_len) >= 0 && BIO_flush(bio);
+ CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+
+ OPENSSL_free(out);
+ return ret;
+ }
+
int SSL_cutthrough_complete(const SSL *s)
{
return (!s->server && /* cutthrough only applies to clients */