]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
New functions to record digests of cells during v3 handshake
authorNick Mathewson <nickm@torproject.org>
Fri, 16 Sep 2011 22:32:11 +0000 (18:32 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 11 Oct 2011 03:14:17 +0000 (23:14 -0400)
Also, free all of the new fields in or_handshake_state_t

src/or/connection_or.c
src/or/connection_or.h

index 93b0b3a2c9159c52849161bf34e45e5474f5ae4c..4caa3d3692bc1d192e5187b5ccf49af129ab5df7 100644 (file)
@@ -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.
  */
index ba441c45df72e59f0b6b721761f8e3e5de3ce226..a4d3be092245182f4ce0217cfd1111cfbcb15378 100644 (file)
@@ -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);