From 22c31d91ab5766db23f65a28d01009f594095901 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 5 Nov 2007 18:15:47 +0000 Subject: [PATCH] r16410@catbus: nickm | 2007-11-05 10:54:29 -0500 Code to remember client_random and server_random values, and to compute hmac using TLS master secret. svn:r12381 --- src/common/tortls.c | 37 +++++++++++++++++++++++++++++++++++++ src/common/tortls.h | 7 +++++++ src/or/connection_or.c | 9 ++++++++- src/or/or.h | 2 +- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/common/tortls.c b/src/common/tortls.c index 162c9d740b..ce5b702a2b 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -20,6 +20,7 @@ const char tortls_c_id[] = #include #include +#include #include #include #include @@ -896,3 +897,39 @@ tor_tls_used_v1_handshake(tor_tls_t *tls) return 1; } +#if SSL3_RANDOM_SIZE != TOR_TLS_RANDOM_LEN +#error "The TOR_TLS_RANDOM_LEN macro is defined incorrectly. That's a bug." +#endif + +/** DOCDOC */ +int +tor_tls_get_random_values(tor_tls_t *tls, char *client_random_out, + char *server_random_out) +{ + tor_assert(tls && tls->ssl); + if (!tls->ssl->s3) + return -1; + memcpy(client_random_out, tls->ssl->s3->client_random, SSL3_RANDOM_SIZE); + memcpy(server_random_out, tls->ssl->s3->server_random, SSL3_RANDOM_SIZE); + return 0; +} + +/** DOCDOC */ +int +tor_tls_hmac_with_master_secret(tor_tls_t *tls, char *hmac_out, + const char *data, size_t data_len) +{ + SSL_SESSION *s; + tor_assert(tls && tls->ssl); + if (!(s = SSL_get_session(tls->ssl))) + return -1; + if (s->master_key_length < 0) + return -1; + crypto_hmac_sha1(hmac_out, + (const char*)s->master_key, + (size_t)s->master_key_length, + data, data_len); + return 0; +} + + diff --git a/src/common/tortls.h b/src/common/tortls.h index 89cbe3be58..eac337b921 100644 --- a/src/common/tortls.h +++ b/src/common/tortls.h @@ -41,6 +41,9 @@ typedef struct tor_tls_t tor_tls_t; case TOR_TLS_ERROR_NO_ROUTE: \ case TOR_TLS_ERROR_TIMEOUT +/**DOCDOC*/ +#define TOR_TLS_RANDOM_LEN 32 + #define TOR_TLS_IS_ERROR(rv) ((rv) < TOR_TLS_CLOSE) void tor_tls_free_all(void); @@ -65,6 +68,10 @@ void tor_tls_get_n_raw_bytes(tor_tls_t *tls, size_t *n_read, size_t *n_written); int tor_tls_used_v1_handshake(tor_tls_t *tls); +int tor_tls_get_random_values(tor_tls_t *tls, char *client_random_out, + char *server_random_out); +int tor_tls_hmac_with_master_secret(tor_tls_t *tls, char *hmac_out, + const char *data, size_t data_len); /* Log and abort if there are unhandled TLS errors in OpenSSL's error stack. */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 6fdf4f8151..37fe55f97e 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -728,7 +728,7 @@ connection_tls_finish_handshake(or_connection_t *conn) if (connection_or_check_valid_handshake(conn, started_here, digest_rcvd) < 0) return -1; - if (!started_here) { + if (!started_here) { /* V1 only XXX020 */ connection_or_init_conn_from_address(conn,conn->_base.addr, conn->_base.port, digest_rcvd, 0); } @@ -741,10 +741,16 @@ connection_tls_finish_handshake(or_connection_t *conn) } else { conn->_base.state = OR_CONN_STATE_OR_HANDSHAKING; conn->handshake_state = tor_malloc_zero(sizeof(or_handshake_state_t)); + conn->handshake_state->started_here = started_here ? 1 : 0; + if (tor_tls_get_random_values(conn->tls, + conn->handshake_state->client_random, + conn->handshake_state->server_random) < 0) + return -1; return connection_or_send_versions(conn); } } + /** DOCDOC */ void or_handshake_state_free(or_handshake_state_t *state) @@ -752,6 +758,7 @@ or_handshake_state_free(or_handshake_state_t *state) tor_assert(state); if (state->signing_key) crypto_free_pk_env(state->signing_key); + memset(state, 0xBE, sizeof(or_handshake_state_t)); tor_free(state); } diff --git a/src/or/or.h b/src/or/or.h index f08b70cbe9..0968f6d7d8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -861,6 +861,7 @@ typedef struct connection_t { /** DOCDOC */ typedef struct or_handshake_state_t { time_t sent_versions_at; + unsigned int started_here : 1; unsigned int received_versions : 1; unsigned int received_netinfo : 1; unsigned int received_certs : 1; @@ -878,7 +879,6 @@ typedef struct or_handshake_state_t { /* from certs */ char cert_id_digest[DIGEST_LEN]; crypto_pk_env_t *signing_key; - } or_handshake_state_t; /** Subtype of connection_t for an "OR connection" -- that is, one that speaks