diff options
Diffstat (limited to 'src/feature/nodelist')
-rw-r--r-- | src/feature/nodelist/microdesc.c | 2 | ||||
-rw-r--r-- | src/feature/nodelist/microdesc_st.h | 6 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.c | 31 | ||||
-rw-r--r-- | src/feature/nodelist/nodelist.h | 1 | ||||
-rw-r--r-- | src/feature/nodelist/routerinfo_st.h | 5 | ||||
-rw-r--r-- | src/feature/nodelist/routerlist.c | 5 | ||||
-rw-r--r-- | src/feature/nodelist/routerparse.c | 16 |
7 files changed, 55 insertions, 11 deletions
diff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c index d9630b4f1d..aa5e6b1dbe 100644 --- a/src/feature/nodelist/microdesc.c +++ b/src/feature/nodelist/microdesc.c @@ -874,7 +874,7 @@ microdesc_free_(microdesc_t *md, const char *fname, int lineno) //tor_assert(md->held_by_nodes == 0); if (md->onion_pkey) - crypto_pk_free(md->onion_pkey); + tor_free(md->onion_pkey); tor_free(md->onion_curve25519_pkey); tor_free(md->ed25519_identity_pkey); if (md->body && md->saved_location != SAVED_IN_CACHE) diff --git a/src/feature/nodelist/microdesc_st.h b/src/feature/nodelist/microdesc_st.h index e9dc3e0174..40b562f265 100644 --- a/src/feature/nodelist/microdesc_st.h +++ b/src/feature/nodelist/microdesc_st.h @@ -53,8 +53,10 @@ struct microdesc_t { /* Fields in the microdescriptor. */ - /** As routerinfo_t.onion_pkey */ - crypto_pk_t *onion_pkey; + /* Public RSA key for onions in ASN.1 encoded. */ + char *onion_pkey; + size_t onion_pkey_len; + /** As routerinfo_t.onion_curve25519_pkey */ struct curve25519_public_key_t *onion_curve25519_pkey; /** Ed25519 identity key, if included. */ diff --git a/src/feature/nodelist/nodelist.c b/src/feature/nodelist/nodelist.c index 75a08fe752..1a123f1ce7 100644 --- a/src/feature/nodelist/nodelist.c +++ b/src/feature/nodelist/nodelist.c @@ -1761,6 +1761,37 @@ node_get_curve25519_onion_key(const node_t *node) return NULL; } +/* Return a newly allocacted RSA onion public key taken from the given node. + * + * Return NULL if node is NULL or no RSA onion public key can be found. It is + * the caller responsability to free the returned object. */ +crypto_pk_t * +node_get_rsa_onion_key(const node_t *node) +{ + crypto_pk_t *pk = NULL; + const char *onion_pkey; + size_t onion_pkey_len; + + if (!node) { + goto end; + } + + if (node->ri) { + onion_pkey = node->ri->onion_pkey; + onion_pkey_len = node->ri->onion_pkey_len; + } else if (node->rs && node->md) { + onion_pkey = node->md->onion_pkey; + onion_pkey_len = node->md->onion_pkey_len; + } else { + /* No descriptor or microdescriptor. */ + goto end; + } + pk = router_get_rsa_onion_pkey(onion_pkey, onion_pkey_len); + + end: + return pk; +} + /** Refresh the country code of <b>ri</b>. This function MUST be called on * each router when the GeoIP database is reloaded, and on all new routers. */ void diff --git a/src/feature/nodelist/nodelist.h b/src/feature/nodelist/nodelist.h index ed3a542971..cf7658cf9d 100644 --- a/src/feature/nodelist/nodelist.h +++ b/src/feature/nodelist/nodelist.h @@ -95,6 +95,7 @@ void node_get_pref_ipv6_dirport(const node_t *node, tor_addr_port_t *ap_out); int node_has_curve25519_onion_key(const node_t *node); const struct curve25519_public_key_t *node_get_curve25519_onion_key( const node_t *node); +crypto_pk_t *node_get_rsa_onion_key(const node_t *node); MOCK_DECL(smartlist_t *, nodelist_get_list, (void)); diff --git a/src/feature/nodelist/routerinfo_st.h b/src/feature/nodelist/routerinfo_st.h index ca8fd40e3b..18ea0fade3 100644 --- a/src/feature/nodelist/routerinfo_st.h +++ b/src/feature/nodelist/routerinfo_st.h @@ -27,7 +27,10 @@ struct routerinfo_t { tor_addr_t ipv6_addr; uint16_t ipv6_orport; - crypto_pk_t *onion_pkey; /**< Public RSA key for onions. */ + /* Public RSA key for onions in ASN.1 encoded. */ + char *onion_pkey; + size_t onion_pkey_len; + crypto_pk_t *identity_pkey; /**< Public RSA key for signing. */ /** Public curve25519 key for onions */ struct curve25519_public_key_t *onion_curve25519_pkey; diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c index 8b54329da9..bcc5c1f074 100644 --- a/src/feature/nodelist/routerlist.c +++ b/src/feature/nodelist/routerlist.c @@ -3217,7 +3217,7 @@ routerinfo_free_(routerinfo_t *router) tor_free(router->protocol_list); tor_free(router->contact_info); if (router->onion_pkey) - crypto_pk_free(router->onion_pkey); + tor_free(router->onion_pkey); tor_free(router->onion_curve25519_pkey); if (router->identity_pkey) crypto_pk_free(router->identity_pkey); @@ -5498,7 +5498,8 @@ router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2) r1->ipv6_orport != r2->ipv6_orport || r1->dir_port != r2->dir_port || r1->purpose != r2->purpose || - !crypto_pk_eq_keys(r1->onion_pkey, r2->onion_pkey) || + r1->onion_pkey_len != r2->onion_pkey_len || + !tor_memeq(r1->onion_pkey, r2->onion_pkey, r1->onion_pkey_len) || !crypto_pk_eq_keys(r1->identity_pkey, r2->identity_pkey) || strcasecmp(r1->platform, r2->platform) || (r1->contact_info && !r2->contact_info) || /* contact_info is optional */ diff --git a/src/feature/nodelist/routerparse.c b/src/feature/nodelist/routerparse.c index 166806e9c1..587966210e 100644 --- a/src/feature/nodelist/routerparse.c +++ b/src/feature/nodelist/routerparse.c @@ -1535,6 +1535,7 @@ router_parse_entry_from_string(const char *s, const char *end, /* Do not set this to '1' until we have parsed everything that we intend to * parse that's covered by the hash. */ int can_dl_again = 0; + crypto_pk_t *rsa_pubkey = NULL; tor_assert(!allow_annotations || !prepend_annotations); @@ -1717,8 +1718,9 @@ router_parse_entry_from_string(const char *s, const char *end, "Relay's onion key had invalid exponent."); goto err; } - router->onion_pkey = tok->key; - tok->key = NULL; /* Prevent free */ + router_set_rsa_onion_pkey(tok->key, &router->onion_pkey, + &router->onion_pkey_len); + crypto_pk_free(tok->key); if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) { curve25519_public_key_t k; @@ -1890,10 +1892,12 @@ router_parse_entry_from_string(const char *s, const char *end, goto err; } + rsa_pubkey = router_get_rsa_onion_pkey(router->onion_pkey, + router->onion_pkey_len); if (check_tap_onion_key_crosscert( (const uint8_t*)cc_tap_tok->object_body, (int)cc_tap_tok->object_size, - router->onion_pkey, + rsa_pubkey, &cert->signing_key, (const uint8_t*)router->cache_info.identity_digest)<0) { log_warn(LD_DIR, "Incorrect TAP cross-verification"); @@ -2058,6 +2062,7 @@ router_parse_entry_from_string(const char *s, const char *end, routerinfo_free(router); router = NULL; done: + crypto_pk_free(rsa_pubkey); tor_cert_free(ntor_cc_cert); if (tokens) { SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); @@ -4752,8 +4757,9 @@ microdescs_parse_from_string(const char *s, const char *eos, "Relay's onion key had invalid exponent."); goto next; } - md->onion_pkey = tok->key; - tok->key = NULL; + router_set_rsa_onion_pkey(tok->key, &md->onion_pkey, + &md->onion_pkey_len); + crypto_pk_free(tok->key); if ((tok = find_opt_by_keyword(tokens, K_ONION_KEY_NTOR))) { curve25519_public_key_t k; |