Use accessor functions for client_random/server_random/master_key

If OpenSSL accepts my patch to introduce these functions, they'll
be a way to help Tor work with OpenSSL 1.1.
This commit is contained in:
Nick Mathewson 2015-05-26 12:09:53 -04:00
parent 9537596398
commit f90a704f12

View File

@ -2707,6 +2707,46 @@ tor_tls_server_got_renegotiate(tor_tls_t *tls)
return tls->got_renegotiate; return tls->got_renegotiate;
} }
#ifndef HAVE_SSL_GET_CLIENT_RANDOM
static size_t
SSL_get_client_random(SSL *s, uint8_t *out, size_t len)
{
if (len == 0)
return SSL3_RANDOM_SIZE;
tor_assert(len == SSL3_RANDOM_SIZE);
tor_assert(s->s3);
memcpy(out, s->s3->client_random, len);
return len;
}
#endif
#ifndef HAVE_SSL_GET_SERVER_RANDOM
static size_t
SSL_get_server_random(SSL *s, uint8_t *out, size_t len)
{
if (len == 0)
return SSL3_RANDOM_SIZE;
tor_assert(len == SSL3_RANDOM_SIZE);
tor_assert(s->s3);
memcpy(out, s->s3->server_random, len);
return len;
}
#endif
#ifndef HAVE_SSL_SESSION_GET_MASTER_KEY
static size_t
SSL_SESSION_get_master_key(SSL_SESSION *s, uint8_t *out, size_t len)
{
if (len == 0)
return s->master_key_length;
tor_assert(len == (size_t)s->master_key_length);
tor_assert(s->master_key);
memcpy(out, s->master_key, len);
return len;
}
#endif
/** Set the DIGEST256_LEN buffer at <b>secrets_out</b> to the value used in /** Set the DIGEST256_LEN buffer at <b>secrets_out</b> to the value used in
* the v3 handshake to prove that the client knows the TLS secrets for the * the v3 handshake to prove that the client knows the TLS secrets for the
* connection <b>tls</b>. Return 0 on success, -1 on failure. * connection <b>tls</b>. Return 0 on success, -1 on failure.
@ -2715,25 +2755,57 @@ int
tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out) tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
{ {
#define TLSSECRET_MAGIC "Tor V3 handshake TLS cross-certification" #define TLSSECRET_MAGIC "Tor V3 handshake TLS cross-certification"
char buf[128]; uint8_t buf[128];
size_t len; size_t len;
tor_assert(tls); tor_assert(tls);
tor_assert(tls->ssl);
tor_assert(tls->ssl->s3); SSL *const ssl = tls->ssl;
tor_assert(tls->ssl->session); SSL_SESSION *const session = SSL_get_session(ssl);
tor_assert(ssl);
tor_assert(session);
const size_t server_random_len = SSL_get_server_random(ssl, NULL, 0);
const size_t client_random_len = SSL_get_client_random(ssl, NULL, 0);
const size_t master_key_len = SSL_SESSION_get_master_key(session, NULL, 0);
tor_assert(server_random_len);
tor_assert(client_random_len);
tor_assert(master_key_len);
len = client_random_len + server_random_len + strlen(TLSSECRET_MAGIC) + 1;
tor_assert(len <= sizeof(buf));
{
size_t r = SSL_get_client_random(ssl, buf, client_random_len);
tor_assert(r == client_random_len);
}
{
size_t r = SSL_get_server_random(ssl, buf+client_random_len, server_random_len);
tor_assert(r == server_random_len);
}
uint8_t *master_key = tor_malloc_zero(master_key_len);
{
size_t r = SSL_SESSION_get_master_key(session, master_key, master_key_len);
tor_assert(r == master_key_len);
}
uint8_t *nextbuf = buf + client_random_len + server_random_len;
memcpy(nextbuf, TLSSECRET_MAGIC, strlen(TLSSECRET_MAGIC) + 1);
/* /*
The value is an HMAC, using the TLS master key as the HMAC key, of The value is an HMAC, using the TLS master key as the HMAC key, of
client_random | server_random | TLSSECRET_MAGIC client_random | server_random | TLSSECRET_MAGIC
*/ */
memcpy(buf + 0, tls->ssl->s3->client_random, 32);
memcpy(buf + 32, tls->ssl->s3->server_random, 32);
memcpy(buf + 64, TLSSECRET_MAGIC, strlen(TLSSECRET_MAGIC) + 1);
len = 64 + strlen(TLSSECRET_MAGIC) + 1;
crypto_hmac_sha256((char*)secrets_out, crypto_hmac_sha256((char*)secrets_out,
(char*)tls->ssl->session->master_key, (char*)master_key,
tls->ssl->session->master_key_length, master_key_len,
buf, len); (char*)buf, len);
memwipe(buf, 0, sizeof(buf)); memwipe(buf, 0, sizeof(buf));
memwipe(master_key, 0, master_key_len);
tor_free(master_key);
return 0; return 0;
} }