From: Nick Mathewson Date: Fri, 16 Sep 2011 22:32:11 +0000 (-0400) Subject: New functions to record digests of cells during v3 handshake X-Git-Tag: tor-0.2.3.6-alpha~30^2~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3f22ec179c6f90b9c2af9483e2c8000132d2f33e;p=thirdparty%2Ftor.git New functions to record digests of cells during v3 handshake Also, free all of the new fields in or_handshake_state_t --- diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 93b0b3a2c9..4caa3d3692 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 cell has been transmitted (if incoming is + * false) or received (if incoming is true) during a V3 handshake using + * state. + * + * (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 cell has been transmitted (if + * incoming is false) or received (if incoming is true) during a V3 + * handshake using state. + * + * (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 conn'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 ba441c45df..a4d3be0922 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);