diff options
Diffstat (limited to 'src/or/keypin.c')
-rw-r--r-- | src/or/keypin.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/src/or/keypin.c b/src/or/keypin.c index 0c99429962..047d2b069b 100644 --- a/src/or/keypin.c +++ b/src/or/keypin.c @@ -48,7 +48,9 @@ static int keypin_journal_append_entry(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key); static int keypin_check_and_add_impl(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key, - int do_not_add); + const int do_not_add, + const int replace); +static int keypin_add_or_replace_entry_in_map(keypin_ent_t *ent); static HT_HEAD(rsamap, keypin_ent_st) the_rsa_map = HT_INITIALIZER(); static HT_HEAD(edmap, keypin_ent_st) the_ed_map = HT_INITIALIZER(); @@ -100,12 +102,17 @@ HT_GENERATE2(edmap, keypin_ent_st, edmap_node, keypin_ent_hash_ed, * return KEYPIN_FOUND. If we find an entry that matches one key but * not the other, return KEYPIN_MISMATCH. If we have no entry for either * key, add such an entry to the table and return KEYPIN_ADDED. + * + * If <b>replace_existing_entry</b> is true, then any time we would have said + * KEYPIN_FOUND, we instead add this entry anyway and return KEYPIN_ADDED. */ int keypin_check_and_add(const uint8_t *rsa_id_digest, - const uint8_t *ed25519_id_key) + const uint8_t *ed25519_id_key, + const int replace_existing_entry) { - return keypin_check_and_add_impl(rsa_id_digest, ed25519_id_key, 0); + return keypin_check_and_add_impl(rsa_id_digest, ed25519_id_key, 0, + replace_existing_entry); } /** @@ -116,7 +123,7 @@ int keypin_check(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key) { - return keypin_check_and_add_impl(rsa_id_digest, ed25519_id_key, 1); + return keypin_check_and_add_impl(rsa_id_digest, ed25519_id_key, 1, 0); } /** @@ -125,7 +132,8 @@ keypin_check(const uint8_t *rsa_id_digest, static int keypin_check_and_add_impl(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key, - int do_not_add) + const int do_not_add, + const int replace) { keypin_ent_t search, *ent; memset(&search, 0, sizeof(search)); @@ -139,18 +147,21 @@ keypin_check_and_add_impl(const uint8_t *rsa_id_digest, if (tor_memeq(ent->ed25519_key, ed25519_id_key,sizeof(ent->ed25519_key))) { return KEYPIN_FOUND; /* Match on both keys. Great. */ } else { - return KEYPIN_MISMATCH; /* Found RSA with different Ed key */ + if (!replace) + return KEYPIN_MISMATCH; /* Found RSA with different Ed key */ } } /* See if we know a different RSA key for this ed key */ - ent = HT_FIND(edmap, &the_ed_map, &search); - if (ent) { - /* If we got here, then the ed key matches and the RSA doesn't */ - tor_assert(fast_memeq(ent->ed25519_key, ed25519_id_key, - sizeof(ent->ed25519_key))); - tor_assert(fast_memneq(ent->rsa_id, rsa_id_digest, sizeof(ent->rsa_id))); - return KEYPIN_MISMATCH; + if (! replace) { + ent = HT_FIND(edmap, &the_ed_map, &search); + if (ent) { + /* If we got here, then the ed key matches and the RSA doesn't */ + tor_assert(fast_memeq(ent->ed25519_key, ed25519_id_key, + sizeof(ent->ed25519_key))); + tor_assert(fast_memneq(ent->rsa_id, rsa_id_digest, sizeof(ent->rsa_id))); + return KEYPIN_MISMATCH; + } } /* Okay, this one is new to us. */ @@ -158,7 +169,12 @@ keypin_check_and_add_impl(const uint8_t *rsa_id_digest, return KEYPIN_NOT_FOUND; ent = tor_memdup(&search, sizeof(search)); - keypin_add_entry_to_map(ent); + int r = keypin_add_or_replace_entry_in_map(ent); + if (! replace) { + tor_assert(r == 1); + } else { + tor_assert(r != 0); + } keypin_journal_append_entry(rsa_id_digest, ed25519_id_key); return KEYPIN_ADDED; } |