Code to remember client_random and server_random values, and to compute hmac using TLS master secret.
svn:r12381
#include <assert.h>
#include <openssl/ssl.h>
+#include <openssl/ssl3.h>
#include <openssl/err.h>
#include <openssl/tls1.h>
#include <openssl/asn1.h>
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;
+}
+
+
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);
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.
*/
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);
}
} 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)
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);
}
/** 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;
/* 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