aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2007-11-06 18:00:07 +0000
committerNick Mathewson <nickm@torproject.org>2007-11-06 18:00:07 +0000
commite047f7f8652d9c67ed96d4ff6f02fa7e23333c54 (patch)
tree1108bb0903409319cd8d49057b6f9c31d7bb7a95 /src/or
parentaf60d79f5deee3e6b264049dfa8512f381a8cbc6 (diff)
downloadtor-e047f7f8652d9c67ed96d4ff6f02fa7e23333c54.tar
tor-e047f7f8652d9c67ed96d4ff6f02fa7e23333c54.tar.gz
r16455@catbus: nickm | 2007-11-06 12:48:00 -0500
Parse CERT cells and act correctly when we get them. svn:r12396
Diffstat (limited to 'src/or')
-rw-r--r--src/or/command.c45
-rw-r--r--src/or/connection_or.c20
2 files changed, 42 insertions, 23 deletions
diff --git a/src/or/command.c b/src/or/command.c
index 834d47e87..8e8aa4abd 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -608,9 +608,10 @@ static void
command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
{
int n_certs = 0;
- uint16_t conn_cert_len, id_cert_len;
+ uint16_t conn_cert_len = 0, id_cert_len = 0;
const char *conn_cert = NULL, *id_cert = NULL;
const char *cp, *end;
+ int authenticated = 0;
/*XXXX020 log messages*/
if (conn->_base.state != OR_CONN_STATE_OR_HANDSHAKING)
@@ -633,9 +634,11 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
if (end-cp < len)
goto err;
if (n_certs == 0) {
- conn_cert = cp;
- conn_cert_len = len;
+ id_cert = cp;
+ id_cert_len = len;
} else if (n_certs == 1) {
+ conn_cert = id_cert;
+ conn_cert_len = id_cert_len;
id_cert = cp;
id_cert_len = len;
} else {
@@ -646,20 +649,34 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
}
/* Now we have 0, 1, or 2 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. */
+ if (n_certs == 0) {
+ /* The other side is unauthenticated. */
+ } else {
+ int r;
+ r = tor_tls_verify_certs_v2(LOG_PROTOCOL_WARN, conn->tls,
+ conn_cert, conn_cert_len,
+ id_cert, id_cert_len,
+ &conn->handshake_state->signing_key,
+ (conn->handshake_state->started_here ?
+ conn->handshake_state->server_cert_digest :
+ conn->handshake_state->client_cert_digest),
+ conn->handshake_state->cert_id_digest);
+ if (r < 0)
+ goto err;
+ if (r == 1)
+ authenticated = 1;
+ }
conn->handshake_state->received_certs = 1;
+ if (authenticated) {
+ /* XXXX020 make the connection open. */
+ }
+ if (! conn->handshake_state->signing_key)
+ goto err;
+
return;
err:
- ;
+ /*XXXX020 close the connection */;
}
#define LINK_AUTH_STRING "Tor initiator certificate verification"
@@ -732,7 +749,7 @@ command_process_link_auth_cell(cell_t *cell, or_connection_t *conn)
/* Okay, we're authenticated. */
s->authenticated = 1;
- /* XXXX020 act on being authenticated: */
+ /* XXXX020 act on being authenticated: Open the connection. */
return;
err:
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index e64844e52..aff224774 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -633,8 +633,9 @@ connection_or_nonopen_was_started_here(or_connection_t *conn)
* this guy; and note that this guy is reachable.
*/
static int
-connection_or_check_valid_handshake(or_connection_t *conn, int started_here,
- char *digest_rcvd)
+connection_or_check_valid_tls_handshake(or_connection_t *conn,
+ int started_here,
+ char *digest_rcvd_out)
{
crypto_pk_env_t *identity_rcvd=NULL;
or_options_t *options = get_options();
@@ -677,7 +678,7 @@ connection_or_check_valid_handshake(or_connection_t *conn, int started_here,
if (identity_rcvd) {
has_identity=1;
- crypto_pk_get_digest(identity_rcvd, digest_rcvd);
+ crypto_pk_get_digest(identity_rcvd, digest_rcvd_out);
if (crypto_pk_cmp_keys(get_identity_key(), identity_rcvd)<0) {
conn->circ_id_type = CIRC_ID_TYPE_LOWER;
@@ -686,12 +687,12 @@ connection_or_check_valid_handshake(or_connection_t *conn, int started_here,
}
crypto_free_pk_env(identity_rcvd);
} else {
- memset(digest_rcvd, 0, DIGEST_LEN);
+ memset(digest_rcvd_out, 0, DIGEST_LEN);
conn->circ_id_type = CIRC_ID_TYPE_NEITHER;
}
if (started_here && tor_digest_is_zero(conn->identity_digest)) {
- memcpy(conn->identity_digest, digest_rcvd, DIGEST_LEN);
+ memcpy(conn->identity_digest, digest_rcvd_out, DIGEST_LEN);
tor_free(conn->nickname);
conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
conn->nickname[0] = '$';
@@ -706,11 +707,11 @@ connection_or_check_valid_handshake(or_connection_t *conn, int started_here,
int as_advertised = 1;
tor_assert(has_cert);
tor_assert(has_identity);
- if (memcmp(digest_rcvd, conn->identity_digest, DIGEST_LEN)) {
+ if (memcmp(digest_rcvd_out, conn->identity_digest, DIGEST_LEN)) {
/* I was aiming for a particular digest. I didn't get it! */
char seen[HEX_DIGEST_LEN+1];
char expected[HEX_DIGEST_LEN+1];
- base16_encode(seen, sizeof(seen), digest_rcvd, DIGEST_LEN);
+ base16_encode(seen, sizeof(seen), digest_rcvd_out, DIGEST_LEN);
base16_encode(expected, sizeof(expected), conn->identity_digest,
DIGEST_LEN);
log_fn(severity, LD_OR,
@@ -728,7 +729,7 @@ connection_or_check_valid_handshake(or_connection_t *conn, int started_here,
* with the same address:port and a different key.
*/
dirserv_orconn_tls_done(conn->_base.address, conn->_base.port,
- digest_rcvd, as_advertised);
+ digest_rcvd_out, as_advertised);
}
if (!as_advertised)
return -1;
@@ -755,7 +756,8 @@ connection_tls_finish_handshake(or_connection_t *conn)
log_debug(LD_OR,"tls handshake done. verifying.");
/* V1 only XXXX020 */
- if (connection_or_check_valid_handshake(conn, started_here, digest_rcvd) < 0)
+ if (connection_or_check_valid_tls_handshake(conn, started_here,
+ digest_rcvd) < 0)
return -1;
if (!started_here) { /* V1 only XXXX020 */