Commit 3f22ec17 authored by Nick Mathewson's avatar Nick Mathewson 🦀
Browse files

New functions to record digests of cells during v3 handshake

Also, free all of the new fields in or_handshake_state_t
parent 6c7f2845
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -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.
 */
+7 −0
Original line number Diff line number Diff line
@@ -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);