diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-11-05 18:15:56 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-11-05 18:15:56 +0000 |
commit | 44eab517fce92b05614efc7f849ed54cee94463a (patch) | |
tree | 039455e82fc27952bd4797b7be7392658f0cc66e /src | |
parent | 12afd4777c5ef3003b08acb34e9090a09703cf60 (diff) | |
download | tor-44eab517fce92b05614efc7f849ed54cee94463a.tar.gz tor-44eab517fce92b05614efc7f849ed54cee94463a.zip |
r16414@catbus: nickm | 2007-11-05 13:14:46 -0500
Function to process link auth cells; stub function for cert cell processing
svn:r12385
Diffstat (limited to 'src')
-rw-r--r-- | src/or/command.c | 104 | ||||
-rw-r--r-- | src/or/connection_or.c | 34 | ||||
-rw-r--r-- | src/or/or.h | 6 |
3 files changed, 144 insertions, 0 deletions
diff --git a/src/or/command.c b/src/or/command.c index e667d5e0a6..dcb713f73c 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -27,6 +27,8 @@ uint64_t stats_n_relay_cells_processed = 0; uint64_t stats_n_destroy_cells_processed = 0; uint64_t stats_n_versions_cells_processed = 0; uint64_t stats_n_netinfo_cells_processed = 0; +uint64_t stats_n_cert_cells_processed = 0; +uint64_t stats_n_link_auth_cells_processed = 0; /* These are the main functions for processing cells */ static void command_process_create_cell(cell_t *cell, or_connection_t *conn); @@ -35,6 +37,8 @@ static void command_process_relay_cell(cell_t *cell, or_connection_t *conn); static void command_process_destroy_cell(cell_t *cell, or_connection_t *conn); static void command_process_versions_cell(cell_t *cell, or_connection_t *conn); static void command_process_netinfo_cell(cell_t *cell, or_connection_t *conn); +static void command_process_cert_cell(cell_t *cell, or_connection_t *conn); +static void command_process_link_auth_cell(cell_t *cell,or_connection_t *conn); #ifdef KEEP_TIMING_STATS /** This is a wrapper function around the actual function that processes the @@ -113,6 +117,8 @@ command_process_cell(cell_t *cell, or_connection_t *conn) #define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn) #endif + /*XXXX020 reject all but VERSIONS, NETINFO, CERT, LINK_AUTH when + * handshaking. */ switch (cell->command) { case CELL_PADDING: ++stats_n_padding_cells_processed; @@ -144,6 +150,14 @@ command_process_cell(cell_t *cell, or_connection_t *conn) ++stats_n_netinfo_cells_processed; PROCESS_CELL(netinfo, cell, conn); break; + case CELL_CERT: + ++stats_n_cert_cells_processed; + PROCESS_CELL(cert, cell, conn); + break; + case CELL_LINK_AUTH: + ++stats_n_link_auth_cells_processed; + PROCESS_CELL(link_auth, cell, conn); + break; default: log_fn(LOG_INFO, LD_PROTOCOL, "Cell of unknown type (%d) received. Dropping.", cell->command); @@ -500,6 +514,7 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn) conn->handshake_state->received_netinfo = 1; } +/*XXXX020 move to connection_or.c */ /** DOCDOC Called when we're done authenticating; act on stuff we * learned in netinfo. */ void @@ -536,3 +551,92 @@ connection_or_act_on_netinfo(or_connection_t *conn) conn->is_canonical = 1; } } + +static void +command_process_cert_cell(cell_t *cell, or_connection_t *conn) +{ + (void) cell; + (void) conn; + + /* Parse certs. */ + /* Verify that identity cert has signed peer cert in SSL, or + * peer cert in the cell. */ + /* Verify that identity cert is self-signed. */ + /* Learn ID digest. */ + /* Learn cert digests. */ + /* Remember peer cert public key. */ + /* set received_certs. */ +} + +#define LINK_AUTH_STRING "Tor initiator certificate verification" + +/** DOCDOC */ +static void +command_process_link_auth_cell(cell_t *cell, or_connection_t *conn) +{ + or_handshake_state_t *s; + char hmac[DIGEST_LEN]; + size_t sig_len; + const char *sig; + char *checked = NULL; + int checked_len; + tor_assert(conn); + if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Received a LINK_AUTH cell on connection in the wrong state; " + "dropping."); + return; + } + s = conn->handshake_state; + tor_assert(s); + if (s->started_here) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, + "Got a LINK_AUTH cell from a server; closing the connection."); + goto err; + } + if (!s->received_netinfo || !s->received_versions || !s->received_certs) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Got a LINK_AUTH cell too early; " + "closing the connection"); + goto err; + } + if (cell->payload[0] != 0x00) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Unrecognized LINK_AUTH signature " + "version; closing the connection"); + goto err; + } + connection_or_compute_link_auth_hmac(conn, hmac); + + tor_assert(s->signing_key); + + /*XXXX020 these two are wrong; fix when protocol is revised. */ + sig = cell->payload+1; + sig_len = 128; + checked = tor_malloc(crypto_pk_keysize(s->signing_key)); + checked_len = crypto_pk_public_checksig(s->signing_key,checked,sig,sig_len); + if (checked_len < 0) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad signature on LINK_AUTH cell; " + "closing the connection"); + goto err; + } + if (checked_len != DIGEST_LEN) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad length (%d) of signed material in " + "LINK_AUTH cell; closing the connection", checked_len); + goto err; + } + if (memcmp(checked, hmac, DIGEST_LEN) != 0) { + log_fn(LOG_PROTOCOL_WARN, LD_OR, "Bad signed data in LINK_AUTH cell; " + "closing the connection."); + goto err; + } + + /* Okay, we're authenticated. */ + s->authenticated = 1; + + /* XXXX020 act on being authenticated: */ + + return; + err: + tor_free(checked); + connection_mark_for_close(TO_CONN(conn)); +} + diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 11e45fb2a8..a75d6df7d8 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -947,3 +947,37 @@ connection_or_send_netinfo(or_connection_t *conn) return 0; } +#define LINK_AUTH_STRING "Tor initiator certificate verification" +/** DOCDOC */ +int +connection_or_compute_link_auth_hmac(or_connection_t *conn, + char *hmac_out) +{ + char buf[64 + 2*TOR_TLS_RANDOM_LEN + 2*DIGEST_LEN]; + char *cp; + or_handshake_state_t *s; + tor_assert(conn); + tor_assert(conn->handshake_state); + tor_assert(conn->tls); + s = conn->handshake_state; + + /* Fill the buffer. */ + strlcpy(buf, LINK_AUTH_STRING, sizeof(buf)); + cp = buf+strlen(buf); + ++cp; /* Skip the NUL */ + memcpy(cp, s->client_random, TOR_TLS_RANDOM_LEN); + cp += TOR_TLS_RANDOM_LEN; + memcpy(cp, s->server_random, TOR_TLS_RANDOM_LEN); + cp += TOR_TLS_RANDOM_LEN; + memcpy(cp, s->client_cert_digest, DIGEST_LEN); + cp += DIGEST_LEN; + memcpy(cp, s->server_cert_digest, DIGEST_LEN); + cp += DIGEST_LEN; + tor_assert(cp < buf+sizeof(buf)); + + if (tor_tls_hmac_with_master_secret(conn->tls, hmac_out, buf, cp-buf) < 0) + return -1; + return 0; +} + + diff --git a/src/or/or.h b/src/or/or.h index dd4d2c54de..87914e3c3c 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -657,6 +657,8 @@ typedef enum { #define CELL_CREATED_FAST 6 #define CELL_VERSIONS 7 #define CELL_NETINFO 8 +#define CELL_CERT 9 +#define CELL_LINK_AUTH 10 /** How long to test reachability before complaining to the user. */ #define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60) @@ -2778,6 +2780,10 @@ void connection_or_write_cell_to_buf(const cell_t *cell, int connection_or_send_destroy(uint16_t circ_id, or_connection_t *conn, int reason); int connection_or_send_netinfo(or_connection_t *conn); +int connection_or_send_certs(or_connection_t *conn); +int connection_or_send_link_auth(or_connection_t *conn); +int connection_or_compute_link_auth_hmac(or_connection_t *conn, + char *hmac_out); void cell_pack(packed_cell_t *dest, const cell_t *src); |