commit 3f22ec179c6f90b9c2af9483e2c8000132d2f33e Author: Nick Mathewson nickm@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/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);
tor-commits@lists.torproject.org