mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-24 22:58:50 +01:00
Allow conflicts to occur in keypinning journal
When we find a conflict in the keypinning journal, treat the new entry as superseding all old entries that overlap either of its keys. Also add a (not-yet-used) configuration option to disable keypinning enforcement.
This commit is contained in:
parent
81724d5a00
commit
c5e87e33c7
4 changed files with 40 additions and 16 deletions
|
@ -162,6 +162,7 @@ static config_var_t option_vars_[] = {
|
|||
V(AuthDirInvalidCCs, CSV, ""),
|
||||
V(AuthDirFastGuarantee, MEMUNIT, "100 KB"),
|
||||
V(AuthDirGuardBWGuarantee, MEMUNIT, "2 MB"),
|
||||
V(AuthDirPinKeys, BOOL, "0"),
|
||||
V(AuthDirReject, LINELIST, NULL),
|
||||
V(AuthDirRejectCCs, CSV, ""),
|
||||
OBSOLETE("AuthDirRejectUnlisted"),
|
||||
|
|
|
@ -321,19 +321,41 @@ keypin_load_journal_impl(const char *data, size_t size)
|
|||
continue;
|
||||
}
|
||||
|
||||
const keypin_ent_t *ent2;
|
||||
if ((ent2 = HT_FIND(rsamap, &the_rsa_map, ent))) {
|
||||
if (fast_memeq(ent2->ed25519_key, ent->ed25519_key, DIGEST256_LEN)) {
|
||||
++n_duplicates;
|
||||
} else {
|
||||
++n_conflicts;
|
||||
keypin_ent_t *ent2 = HT_FIND(rsamap, &the_rsa_map, ent);
|
||||
keypin_ent_t *ent3 = HT_FIND(edmap, &the_ed_map, ent);
|
||||
if (ent2 &&
|
||||
fast_memeq(ent2->ed25519_key, ent->ed25519_key, DIGEST256_LEN)) {
|
||||
/* We already have this mapping stored. Ignore it. */
|
||||
tor_free(ent);
|
||||
++n_duplicates;
|
||||
continue;
|
||||
} else if (ent2 || ent3) {
|
||||
/* We have a conflict. (If we had no entry, we would have ent2 == ent3
|
||||
* == NULL. If we had a non-conflicting duplicate, we would have found
|
||||
* it above.)
|
||||
*
|
||||
* We respond by having this entry (ent) supersede all entries that it
|
||||
* contradicts (ent2 and/or ent3). In other words, if we receive
|
||||
* <rsa,ed>, we remove all <rsa,ed'> and all <rsa',ed>, for rsa'!=rsa
|
||||
* and ed'!= ed.
|
||||
*/
|
||||
const keypin_ent_t *t;
|
||||
if (ent2) {
|
||||
t = HT_REMOVE(rsamap, &the_rsa_map, ent2);
|
||||
tor_assert(ent2 == t);
|
||||
t = HT_REMOVE(edmap, &the_ed_map, ent2);
|
||||
tor_assert(ent2 == t);
|
||||
}
|
||||
tor_free(ent);
|
||||
continue;
|
||||
} else if (HT_FIND(edmap, &the_ed_map, ent)) {
|
||||
tor_free(ent);
|
||||
if (ent3 && ent2 != ent3) {
|
||||
t = HT_REMOVE(rsamap, &the_rsa_map, ent3);
|
||||
tor_assert(ent3 == t);
|
||||
t = HT_REMOVE(edmap, &the_ed_map, ent3);
|
||||
tor_assert(ent3 == t);
|
||||
tor_free(ent3);
|
||||
}
|
||||
tor_free(ent2);
|
||||
++n_conflicts;
|
||||
continue;
|
||||
/* Fall through */
|
||||
}
|
||||
|
||||
keypin_add_entry_to_map(ent);
|
||||
|
|
|
@ -3790,6 +3790,7 @@ typedef struct {
|
|||
* number of servers per IP address shared
|
||||
* with an authority. */
|
||||
int AuthDirHasIPv6Connectivity; /**< Boolean: are we on IPv6? */
|
||||
int AuthDirPinKeys; /**< Boolean: Do we enforce key-pinning? */
|
||||
|
||||
/** If non-zero, always vote the Fast flag for any relay advertising
|
||||
* this amount of capacity or more. */
|
||||
|
|
|
@ -108,21 +108,21 @@ test_keypin_parse_file(void *arg)
|
|||
;
|
||||
|
||||
tt_int_op(0, ==, keypin_load_journal_impl(data2, strlen(data2)));
|
||||
tt_int_op(11, ==, smartlist_len(mock_addent_got));
|
||||
tt_int_op(13, ==, smartlist_len(mock_addent_got));
|
||||
ent = smartlist_get(mock_addent_got, 9);
|
||||
tt_mem_op(ent->rsa_id, ==, "\"You have made a goo", 20);
|
||||
tt_mem_op(ent->ed25519_key, ==, "d beginning.\" But no more. Wizar", 32);
|
||||
|
||||
ent = smartlist_get(mock_addent_got, 10);
|
||||
ent = smartlist_get(mock_addent_got, 12);
|
||||
tt_mem_op(ent->rsa_id, ==, "ds speak truth, and ", 20);
|
||||
tt_mem_op(ent->ed25519_key, ==, "it was true that all the master\n", 32);
|
||||
tt_mem_op(ent->ed25519_key, ==, "it was tru\xa5 that all the master\n", 32);
|
||||
|
||||
/* File truncated before NL */
|
||||
const char data3[] =
|
||||
"Tm8gZHJhZ29uIGNhbiByZXNpc3Q IHRoZSBmYXNjaW5hdGlvbiBvZiByaWRkbGluZyB0YWw";
|
||||
tt_int_op(0, ==, keypin_load_journal_impl(data3, strlen(data3)));
|
||||
tt_int_op(12, ==, smartlist_len(mock_addent_got));
|
||||
ent = smartlist_get(mock_addent_got, 11);
|
||||
tt_int_op(14, ==, smartlist_len(mock_addent_got));
|
||||
ent = smartlist_get(mock_addent_got, 13);
|
||||
tt_mem_op(ent->rsa_id, ==, "No dragon can resist", 20);
|
||||
tt_mem_op(ent->ed25519_key, ==, " the fascination of riddling tal", 32);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue