diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-11-05 23:55:43 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-11-05 23:55:43 +0000 |
commit | 95c7b8cc641ad275ebb5f445760f27a7ea937075 (patch) | |
tree | d8c69f028a97b4aa780a1b6a023e4604d7147269 /src | |
parent | 6fcda5299fe7c0a40d3bff06ac4dcfe13d02d476 (diff) | |
download | tor-95c7b8cc641ad275ebb5f445760f27a7ea937075.tar tor-95c7b8cc641ad275ebb5f445760f27a7ea937075.tar.gz |
r14729@31-33-67: nickm | 2007-11-05 18:54:50 -0500
Send and Parse CERT cells correctly. Still need to understand the certs inside.
svn:r12392
Diffstat (limited to 'src')
-rw-r--r-- | src/or/command.c | 49 | ||||
-rw-r--r-- | src/or/connection_or.c | 39 |
2 files changed, 83 insertions, 5 deletions
diff --git a/src/or/command.c b/src/or/command.c index 100f1c379..36de2d15c 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -603,13 +603,51 @@ connection_or_act_on_netinfo(or_connection_t *conn) } } +/*DOCDOC*/ static void command_process_cert_cell(var_cell_t *cell, or_connection_t *conn) { - (void) cell; - (void) conn; + int n_certs = 0; + uint16_t conn_cert_len, id_cert_len; + const char *conn_cert = NULL, *id_cert = NULL; + const char *cp, *end; + + /*XXXX020 log messages*/ + if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING) + goto err; + tor_assert(conn->handshake_state); + if (!conn->handshake_state->received_versions || + !conn->handshake_state->received_netinfo || + conn->handshake_state->received_certs) + goto err; + + cp = cell->payload; + end = cell->payload + cell->payload_len; + + while (cp < end) { + uint16_t len; + if (end-cp == 1) + goto err; + len = ntohs(get_uint16(cp)); + cp += 2; + if (end-cp < len) + goto err; + if (n_certs == 0) { + conn_cert = cp; + conn_cert_len = len; + } else if (n_certs == 1) { + id_cert = cp; + id_cert_len = len; + } else { + goto err; + } + cp += len; + ++n_certs; + } + + /* Now we have 0, 1, or 2 certs. */ + - /* 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. */ @@ -617,6 +655,11 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn) /* Learn cert digests. */ /* Remember peer cert public key. */ /* set received_certs. */ + + conn->handshake_state->received_certs = 1; + return; + err: + ; } #define LINK_AUTH_STRING "Tor initiator certificate verification" diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 7842d8da9..e64844e52 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -965,6 +965,7 @@ connection_or_send_versions(or_connection_t *conn) connection_or_write_var_cell_to_buf(cell, conn); conn->handshake_state->sent_versions_at = time(NULL); + var_cell_free(cell); return 0; } @@ -1037,8 +1038,42 @@ connection_or_compute_link_auth_hmac(or_connection_t *conn, int connection_or_send_cert(or_connection_t *conn) { - (void)conn; - /*XXX020 implement.*/ + size_t conn_cert_len = 0, id_cert_len = 0, total_len = 0; + char *id_cert = NULL, *conn_cert = NULL; + var_cell_t *cell; + char *cp; + + /* If we're a client, we can send no cert at all. XXXXX020 */ + /* DOCDOC length of cert before cert. */ + tor_assert(conn); + tor_assert(conn->handshake_state); + tor_assert(conn->handshake_state->received_versions == 1); + if (conn->handshake_state->started_here) + conn_cert = tor_tls_encode_my_certificate(conn->tls, &conn_cert_len, 1); + id_cert = tor_tls_encode_my_certificate(conn->tls, &id_cert_len, 0); + tor_assert(id_cert); + total_len = id_cert_len + conn_cert_len + conn_cert ? 4 : 2; + + cell = var_cell_new(total_len); + cell->command = CELL_VERSIONS; + cp = cell->payload; + if (conn_cert) { + set_uint16(cp, htons(conn_cert_len)); + cp += 2; + memcpy(cp, conn_cert, conn_cert_len); + cp += conn_cert_len; + } + set_uint16(cp, htons(id_cert_len)); + cp += 2; + memcpy(cp, id_cert, id_cert_len); + cp += id_cert_len; + tor_assert(cp == cell->payload + total_len); + + connection_or_write_var_cell_to_buf(cell, conn); + + tor_free(conn_cert); + tor_free(id_cert); + var_cell_free(cell); return 0; } |