commit 3f22ec179c6f90b9c2af9483e2c8000132d2f33e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Sep 16 18:32:11 2011 -0400
New functions to record digests of cells during v3 handshake
Also, free all of the new fields in or_handshake_state_t
---
src/or/connection_or.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++
src/or/connection_or.h | 7 +++++
2 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/src/or/connection_or.c b/src/or/…
[View More]connection_or.c
index 93b0b3a..4caa3d3 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1504,10 +1504,74 @@ or_handshake_state_free(or_handshake_state_t *state)
{
if (!state)
return;
+ crypto_free_digest_env(state->digest_sent);
+ crypto_free_digest_env(state->digest_received);
+ tor_cert_free(state->auth_cert);
+ tor_cert_free(state->id_cert);
memset(state, 0xBE, sizeof(or_handshake_state_t));
tor_free(state);
}
+/**
+ * Remember that <b>cell</b> has been transmitted (if <b>incoming</b> is
+ * false) or received (if <b>incoming is true) during a V3 handshake using
+ * <b>state</b>.
+ *
+ * (We don't record the cell, but we keep a digest of everything sent or
+ * received during the v3 handshake, and the client signs it in an
+ * authenticate cell.)
+ */
+void
+or_handshake_state_record_cell(or_handshake_state_t *state,
+ const cell_t *cell,
+ int incoming)
+{
+ crypto_digest_env_t *d, **dptr;
+ packed_cell_t packed;
+ if (!incoming) {
+ log_warn(LD_BUG, "We shouldn't be sending any non-variable-length cells "
+ "whilemaking a handshake digest. But we think we are.");
+ }
+ dptr = incoming ? &state->digest_received : &state->digest_sent;
+ if (! *dptr)
+ *dptr = crypto_new_digest256_env(DIGEST_SHA256);
+
+ d = *dptr;
+ /* Re-packing like this is a little inefficient, but we don't have to do
+ this very often at all. */
+ cell_pack(&packed, cell);
+ crypto_digest_add_bytes(d, packed.body, sizeof(packed.body));
+ memset(&packed, 0, sizeof(packed));
+}
+
+/** Remember that a variable-length <b>cell</b> has been transmitted (if
+ * <b>incoming</b> is false) or received (if <b>incoming is true) during a V3
+ * handshake using <b>state</b>.
+ *
+ * (We don't record the cell, but we keep a digest of everything sent or
+ * received during the v3 handshake, and the client signs it in an
+ * authenticate cell.)
+ */
+void
+or_handshake_state_record_var_cell(or_handshake_state_t *state,
+ const var_cell_t *cell,
+ int incoming)
+{
+ crypto_digest_env_t *d, **dptr;
+ char buf[VAR_CELL_HEADER_SIZE];
+ dptr = incoming ? &state->digest_received : &state->digest_sent;
+ if (! *dptr)
+ *dptr = crypto_new_digest256_env(DIGEST_SHA256);
+
+ d = *dptr;
+
+ var_cell_pack_header(cell, buf);
+ crypto_digest_add_bytes(d, buf, sizeof(buf));
+ crypto_digest_add_bytes(d, (const char *)cell->payload, cell->payload_len);
+
+ memset(buf, 0, sizeof(buf));
+}
+
/** Set <b>conn</b>'s state to OR_CONN_STATE_OPEN, and tell other subsystems
* as appropriate. Called when we are done with all TLS and OR handshaking.
*/
diff --git a/src/or/connection_or.h b/src/or/connection_or.h
index ba441c4..a4d3be0 100644
--- a/src/or/connection_or.h
+++ b/src/or/connection_or.h
@@ -42,6 +42,13 @@ int connection_tls_start_handshake(or_connection_t *conn, int receiving);
int connection_tls_continue_handshake(or_connection_t *conn);
void or_handshake_state_free(or_handshake_state_t *state);
+void or_handshake_state_record_cell(or_handshake_state_t *state,
+ const cell_t *cell,
+ int incoming);
+void or_handshake_state_record_var_cell(or_handshake_state_t *state,
+ const var_cell_t *cell,
+ int incoming);
+
int connection_or_set_state_open(or_connection_t *conn);
void connection_or_write_cell_to_buf(const cell_t *cell,
or_connection_t *conn);
[View Less]
commit c39688de6c5d4bf19739ecffb2e98aa560a4630a
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Sep 13 13:46:21 2011 -0400
Function to extract the TLSSECRETS field for v3 handshakes
---
src/common/tortls.c | 30 ++++++++++++++++++++++++++++++
src/common/tortls.h | 1 +
2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/src/common/tortls.c b/src/common/tortls.c
index b711967..2b12eea 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -1985,6 +…
[View More]1985,36 @@ tor_tls_server_got_renegotiate(tor_tls_t *tls)
return tls->got_renegotiate;
}
+/** 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
+ * connection <b>tls</b>. Return 0 on success, -1 on failure.
+ */
+int
+tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out)
+{
+#define TLSSECRET_MAGIC "Tor V3 handshake TLS cross-certification"
+ char buf[128];
+ size_t len;
+ tor_assert(tls);
+ tor_assert(tls->ssl);
+ tor_assert(tls->ssl->s3);
+ tor_assert(tls->ssl->session);
+ /*
+ The value is an HMAC, using the TLS master key as the HMAC key, of
+ 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,
+ (char*)tls->ssl->session->master_key,
+ tls->ssl->session->master_key_length,
+ buf, len);
+ memset(buf, 0, sizeof(buf));
+ return 0;
+}
+
/** Examine the amount of memory used and available for buffers in <b>tls</b>.
* Set *<b>rbuf_capacity</b> to the amount of storage allocated for the read
* buffer and *<b>rbuf_bytes</b> to the amount actually used.
diff --git a/src/common/tortls.h b/src/common/tortls.h
index c55da4a..a6aed29 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -90,6 +90,7 @@ void tor_tls_get_buffer_sizes(tor_tls_t *tls,
int tor_tls_used_v1_handshake(tor_tls_t *tls);
int tor_tls_get_num_server_handshakes(tor_tls_t *tls);
int tor_tls_server_got_renegotiate(tor_tls_t *tls);
+int tor_tls_get_tlssecrets(tor_tls_t *tls, uint8_t *secrets_out);
/* Log and abort if there are unhandled TLS errors in OpenSSL's error stack.
*/
[View Less]