Add "Ed ID" arguments to a bunch of connection-ID-related fns.

In particular, these functions are the ones that set the identity of
a given connection or channel, and/or confirm that we have learned
said IDs.

There's a lot of stub code here: we don't actually need to use the
new keys till we start looking up connections/channels by Ed25519
IDs.  Still, we want to start passing the Ed25519 IDs in now, so it
makes sense to add these stubs as part of 15055.
This commit is contained in:
Nick Mathewson 2016-08-30 09:44:42 -04:00
parent 0704fa8a63
commit 99b3e54691
11 changed files with 93 additions and 45 deletions

View File

@ -3223,9 +3223,10 @@ channel_free_all(void)
channel_t *
channel_connect(const tor_addr_t *addr, uint16_t port,
const char *id_digest)
const char *id_digest,
const ed25519_public_key_t *ed_id)
{
return channel_tls_connect(addr, port, id_digest);
return channel_tls_connect(addr, port, id_digest, ed_id);
}
/**

View File

@ -486,7 +486,8 @@ int channel_send_destroy(circid_t circ_id, channel_t *chan,
*/
channel_t * channel_connect(const tor_addr_t *addr, uint16_t port,
const char *id_digest);
const char *id_digest,
const ed25519_public_key_t *ed_id);
channel_t * channel_get_for_extend(const char *digest,
const tor_addr_t *target_addr,

View File

@ -149,8 +149,10 @@ channel_tls_common_init(channel_tls_t *tlschan)
channel_t *
channel_tls_connect(const tor_addr_t *addr, uint16_t port,
const char *id_digest)
const char *id_digest,
const ed25519_public_key_t *ed_id)
{
(void) ed_id; // XXXX not fully used yet
channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan));
channel_t *chan = &(tlschan->base_);
@ -177,7 +179,7 @@ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
channel_mark_outgoing(chan);
/* Set up or_connection stuff */
tlschan->conn = connection_or_connect(addr, port, id_digest, tlschan);
tlschan->conn = connection_or_connect(addr, port, id_digest, ed_id, tlschan);
/* connection_or_connect() will fill in tlschan->conn */
if (!(tlschan->conn)) {
chan->reason_for_closing = CHANNEL_CLOSE_FOR_ERROR;
@ -1618,7 +1620,10 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
if (!(chan->conn->handshake_state->authenticated)) {
tor_assert(tor_digest_is_zero(
(const char*)(chan->conn->handshake_state->
authenticated_peer_id)));
authenticated_rsa_peer_id)));
tor_assert(tor_mem_is_zero(
(const char*)(chan->conn->handshake_state->
authenticated_ed25519_peer_id.pubkey), 32));
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL,
chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
@ -1626,7 +1631,8 @@ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
&(chan->conn->base_.addr),
chan->conn->base_.port,
(const char*)(chan->conn->handshake_state->
authenticated_peer_id),
authenticated_rsa_peer_id),
NULL, // XXXX Ed key
0);
}
}
@ -1926,6 +1932,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
/* No more information is needed. */
chan->conn->handshake_state->authenticated = 1;
chan->conn->handshake_state->authenticated_rsa = 1;
{
const common_digests_t *id_digests =
tor_x509_cert_get_id_digests(id_cert);
@ -1936,7 +1943,7 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
identity_rcvd = tor_tls_cert_get_key(id_cert);
if (!identity_rcvd)
ERR("Internal error: Couldn't get RSA key from ID cert.");
memcpy(chan->conn->handshake_state->authenticated_peer_id,
memcpy(chan->conn->handshake_state->authenticated_rsa_peer_id,
id_digests->d[DIGEST_SHA1], DIGEST_LEN);
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd,
chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
@ -1944,7 +1951,8 @@ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
}
if (connection_or_client_learned_peer_id(chan->conn,
chan->conn->handshake_state->authenticated_peer_id) < 0)
chan->conn->handshake_state->authenticated_rsa_peer_id,
NULL) < 0)
ERR("Problem setting or checking peer id");
log_info(LD_OR,
@ -2219,6 +2227,7 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
/* Okay, we are authenticated. */
chan->conn->handshake_state->received_authenticate = 1;
chan->conn->handshake_state->authenticated = 1;
chan->conn->handshake_state->authenticated_rsa = 1;
chan->conn->handshake_state->digest_received_data = 0;
{
crypto_pk_t *identity_rcvd =
@ -2229,7 +2238,7 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
/* This must exist; we checked key type when reading the cert. */
tor_assert(id_digests);
memcpy(chan->conn->handshake_state->authenticated_peer_id,
memcpy(chan->conn->handshake_state->authenticated_rsa_peer_id,
id_digests->d[DIGEST_SHA1], DIGEST_LEN);
channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd,
@ -2240,7 +2249,8 @@ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
&(chan->conn->base_.addr),
chan->conn->base_.port,
(const char*)(chan->conn->handshake_state->
authenticated_peer_id),
authenticated_rsa_peer_id),
NULL, // XXXX Ed key
0);
log_info(LD_OR,

View File

@ -29,7 +29,8 @@ struct channel_tls_s {
#endif /* TOR_CHANNEL_INTERNAL_ */
channel_t * channel_tls_connect(const tor_addr_t *addr, uint16_t port,
const char *id_digest);
const char *id_digest,
const ed25519_public_key_t *ed_id);
channel_listener_t * channel_tls_get_listener(void);
channel_listener_t * channel_tls_start_listener(void);
channel_t * channel_tls_handle_incoming(or_connection_t *orconn);

View File

@ -69,7 +69,10 @@ channel_connect_for_circuit(const tor_addr_t *addr, uint16_t port,
{
channel_t *chan;
chan = channel_connect(addr, port, id_digest);
chan = channel_connect(addr, port, id_digest,
NULL // XXXX Ed25519 id.
);
if (chan) command_setup_channel(chan);
return chan;

View File

@ -134,15 +134,18 @@ connection_or_clear_identity_map(void)
/** Change conn->identity_digest to digest, and add conn into
* orconn_digest_map. */
static void
connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
connection_or_set_identity_digest(or_connection_t *conn,
const char *rsa_digest,
const ed25519_public_key_t *ed_id)
{
(void) ed_id; // DOCDOC // XXXX not implemented yet.
or_connection_t *tmp;
tor_assert(conn);
tor_assert(digest);
tor_assert(rsa_digest);
if (!orconn_identity_map)
orconn_identity_map = digestmap_new();
if (tor_memeq(conn->identity_digest, digest, DIGEST_LEN))
if (tor_memeq(conn->identity_digest, rsa_digest, DIGEST_LEN))
return;
/* If the identity was set previously, remove the old mapping. */
@ -152,23 +155,23 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
channel_clear_identity_digest(TLS_CHAN_TO_BASE(conn->chan));
}
memcpy(conn->identity_digest, digest, DIGEST_LEN);
memcpy(conn->identity_digest, rsa_digest, DIGEST_LEN);
/* If we're setting the ID to zero, don't add a mapping. */
if (tor_digest_is_zero(digest))
if (tor_digest_is_zero(rsa_digest))
return;
tmp = digestmap_set(orconn_identity_map, digest, conn);
tmp = digestmap_set(orconn_identity_map, rsa_digest, conn);
conn->next_with_same_id = tmp;
/* Deal with channels */
if (conn->chan)
channel_set_identity_digest(TLS_CHAN_TO_BASE(conn->chan), digest);
channel_set_identity_digest(TLS_CHAN_TO_BASE(conn->chan), rsa_digest);
#if 1
/* Testing code to check for bugs in representation. */
for (; tmp; tmp = tmp->next_with_same_id) {
tor_assert(tor_memeq(tmp->identity_digest, digest, DIGEST_LEN));
tor_assert(tor_memeq(tmp->identity_digest, rsa_digest, DIGEST_LEN));
tor_assert(tmp != conn);
}
#endif
@ -866,10 +869,12 @@ void
connection_or_init_conn_from_address(or_connection_t *conn,
const tor_addr_t *addr, uint16_t port,
const char *id_digest,
const ed25519_public_key_t *ed_id,
int started_here)
{
(void) ed_id; // not fully used yet.
const node_t *r = node_get_by_id(id_digest);
connection_or_set_identity_digest(conn, id_digest);
connection_or_set_identity_digest(conn, id_digest, ed_id);
connection_or_update_token_buckets_helper(conn, 1, get_options());
conn->base_.port = port;
@ -1162,8 +1167,11 @@ connection_or_notify_error(or_connection_t *conn,
MOCK_IMPL(or_connection_t *,
connection_or_connect, (const tor_addr_t *_addr, uint16_t port,
const char *id_digest, channel_tls_t *chan))
const char *id_digest,
const ed25519_public_key_t *ed_id,
channel_tls_t *chan))
{
(void) ed_id; // XXXX not fully used yet.
or_connection_t *conn;
const or_options_t *options = get_options();
int socket_error = 0;
@ -1194,7 +1202,7 @@ connection_or_connect, (const tor_addr_t *_addr, uint16_t port,
*/
conn->chan = chan;
chan->conn = conn;
connection_or_init_conn_from_address(conn, &addr, port, id_digest, 1);
connection_or_init_conn_from_address(conn, &addr, port, id_digest, ed_id, 1);
connection_or_change_state(conn, OR_CONN_STATE_CONNECTING);
control_event_or_conn_status(conn, OR_CONN_EVENT_LAUNCHED, 0);
@ -1553,7 +1561,9 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
if (started_here)
return connection_or_client_learned_peer_id(conn,
(const uint8_t*)digest_rcvd_out);
(const uint8_t*)digest_rcvd_out,
NULL // Ed25519 ID
);
return 0;
}
@ -1583,12 +1593,16 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
*/
int
connection_or_client_learned_peer_id(or_connection_t *conn,
const uint8_t *peer_id)
const uint8_t *rsa_peer_id,
const ed25519_public_key_t *ed_peer_id)
{
(void) ed_peer_id; // not used yet.
const or_options_t *options = get_options();
if (tor_digest_is_zero(conn->identity_digest)) {
connection_or_set_identity_digest(conn, (const char*)peer_id);
connection_or_set_identity_digest(conn,
(const char*)rsa_peer_id, ed_peer_id);
tor_free(conn->nickname);
conn->nickname = tor_malloc(HEX_DIGEST_LEN+2);
conn->nickname[0] = '$';
@ -1600,14 +1614,14 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
/* if it's a bridge and we didn't know its identity fingerprint, now
* we do -- remember it for future attempts. */
learned_router_identity(&conn->base_.addr, conn->base_.port,
(const char*)peer_id);
(const char*)rsa_peer_id /*, ed_peer_id XXXX */);
}
if (tor_memneq(peer_id, conn->identity_digest, DIGEST_LEN)) {
if (tor_memneq(rsa_peer_id, 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), (const char*)peer_id, DIGEST_LEN);
base16_encode(seen, sizeof(seen), (const char*)rsa_peer_id, DIGEST_LEN);
base16_encode(expected, sizeof(expected), conn->identity_digest,
DIGEST_LEN);
const int using_hardcoded_fingerprints =
@ -1660,7 +1674,7 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
}
if (authdir_mode_tests_reachability(options)) {
dirserv_orconn_tls_done(&conn->base_.addr, conn->base_.port,
(const char*)peer_id);
(const char*)rsa_peer_id /*, ed_id XXXX */);
}
return 0;
@ -1716,7 +1730,8 @@ connection_tls_finish_handshake(or_connection_t *conn)
if (tor_tls_used_v1_handshake(conn->tls)) {
conn->link_proto = 1;
connection_or_init_conn_from_address(conn, &conn->base_.addr,
conn->base_.port, digest_rcvd, 0);
conn->base_.port, digest_rcvd,
NULL, 0);
tor_tls_block_renegotiation(conn->tls);
rep_hist_note_negotiated_link_proto(1, started_here);
return connection_or_set_state_open(conn);
@ -1725,7 +1740,8 @@ connection_tls_finish_handshake(or_connection_t *conn)
if (connection_init_or_handshake_state(conn, started_here) < 0)
return -1;
connection_or_init_conn_from_address(conn, &conn->base_.addr,
conn->base_.port, digest_rcvd, 0);
conn->base_.port, digest_rcvd,
NULL, 0);
return connection_or_send_versions(conn, 0);
}
}

View File

@ -40,7 +40,9 @@ void connection_or_notify_error(or_connection_t *conn,
MOCK_DECL(or_connection_t *,
connection_or_connect,
(const tor_addr_t *addr, uint16_t port,
const char *id_digest, channel_tls_t *chan));
const char *id_digest,
const ed25519_public_key_t *ed_id,
channel_tls_t *chan));
void connection_or_close_normally(or_connection_t *orconn, int flush);
MOCK_DECL(void,connection_or_close_for_error,
@ -59,10 +61,12 @@ int connection_init_or_handshake_state(or_connection_t *conn,
void connection_or_init_conn_from_address(or_connection_t *conn,
const tor_addr_t *addr,
uint16_t port,
const char *id_digest,
const char *rsa_id_digest,
const ed25519_public_key_t *ed_id,
int started_here);
int connection_or_client_learned_peer_id(or_connection_t *conn,
const uint8_t *peer_id);
const uint8_t *rsa_peer_id,
const ed25519_public_key_t *ed_peer_id);
time_t connection_or_client_used(or_connection_t *conn);
MOCK_DECL(int, connection_or_get_num_circuits, (or_connection_t *conn));
void or_handshake_state_free(or_handshake_state_t *state);

View File

@ -3199,7 +3199,9 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router)
router->nickname, fmt_addr32(router->addr), router->or_port);
tor_addr_from_ipv4h(&router_addr, router->addr);
chan = channel_tls_connect(&router_addr, router->or_port,
router->cache_info.identity_digest);
router->cache_info.identity_digest,
NULL // XXXX Ed25519 ID.
);
if (chan) command_setup_channel(chan);
/* Possible IPv6. */
@ -3211,7 +3213,9 @@ dirserv_single_reachability_test(time_t now, routerinfo_t *router)
tor_addr_to_str(addrstr, &router->ipv6_addr, sizeof(addrstr), 1),
router->ipv6_orport);
chan = channel_tls_connect(&router->ipv6_addr, router->ipv6_orport,
router->cache_info.identity_digest);
router->cache_info.identity_digest,
NULL // XXXX Ed25519 ID.
);
if (chan) command_setup_channel(chan);
}
}

View File

@ -1419,6 +1419,8 @@ typedef struct or_handshake_state_t {
/* True iff we've received valid authentication to some identity. */
unsigned int authenticated : 1;
unsigned int authenticated_rsa : 1;
unsigned int authenticated_ed25519 : 1;
/* True iff we have sent a netinfo cell */
unsigned int sent_netinfo : 1;
@ -1436,9 +1438,12 @@ typedef struct or_handshake_state_t {
unsigned int digest_received_data : 1;
/**@}*/
/** Identity digest that we have received and authenticated for our peer
/** Identity RSA digest that we have received and authenticated for our peer
* on this connection. */
uint8_t authenticated_peer_id[DIGEST_LEN];
uint8_t authenticated_rsa_peer_id[DIGEST_LEN];
/** Identity Ed25519 public key that we have received and authenticated for
* our peer on this connection. */
ed25519_public_key_t authenticated_ed25519_peer_id;
/** Digests of the cells that we have sent or received as part of a V3
* handshake. Used for making and checking AUTHENTICATE cells.

View File

@ -30,6 +30,7 @@ static or_connection_t * tlschan_connection_or_connect_mock(
const tor_addr_t *addr,
uint16_t port,
const char *digest,
const ed25519_public_key_t *ed_id,
channel_tls_t *tlschan);
static int tlschan_is_local_addr_mock(const tor_addr_t *addr);
@ -68,7 +69,7 @@ test_channeltls_create(void *arg)
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
/* Try connecting */
ch = channel_tls_connect(&test_addr, 567, test_digest);
ch = channel_tls_connect(&test_addr, 567, test_digest, NULL);
tt_assert(ch != NULL);
done:
@ -117,7 +118,7 @@ test_channeltls_num_bytes_queued(void *arg)
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
/* Try connecting */
ch = channel_tls_connect(&test_addr, 567, test_digest);
ch = channel_tls_connect(&test_addr, 567, test_digest, NULL);
tt_assert(ch != NULL);
/*
@ -202,7 +203,7 @@ test_channeltls_overhead_estimate(void *arg)
MOCK(connection_or_connect, tlschan_connection_or_connect_mock);
/* Try connecting */
ch = channel_tls_connect(&test_addr, 567, test_digest);
ch = channel_tls_connect(&test_addr, 567, test_digest, NULL);
tt_assert(ch != NULL);
/* First case: silly low ratios should get clamped to 1.0 */
@ -264,9 +265,11 @@ static or_connection_t *
tlschan_connection_or_connect_mock(const tor_addr_t *addr,
uint16_t port,
const char *digest,
const ed25519_public_key_t *ed_id,
channel_tls_t *tlschan)
{
or_connection_t *result = NULL;
(void) ed_id; // XXXX Not yet used.
tt_assert(addr != NULL);
tt_assert(port != 0);

View File

@ -150,7 +150,7 @@ test_link_handshake_certs_ok(void *arg)
tt_assert(c1->handshake_state->certs->auth_cert == NULL);
tt_assert(c1->handshake_state->certs->id_cert);
tt_assert(! tor_mem_is_zero(
(char*)c1->handshake_state->authenticated_peer_id, 20));
(char*)c1->handshake_state->authenticated_rsa_peer_id, 20));
chan2 = tor_malloc_zero(sizeof(*chan2));
channel_tls_common_init(chan2);
@ -168,7 +168,7 @@ test_link_handshake_certs_ok(void *arg)
tt_assert(c2->handshake_state->certs->auth_cert);
tt_assert(c2->handshake_state->certs->id_cert);
tt_assert(tor_mem_is_zero(
(char*)c2->handshake_state->authenticated_peer_id, 20));
(char*)c2->handshake_state->authenticated_rsa_peer_id, 20));
done:
UNMOCK(tor_tls_cert_matches_key);