diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-09-23 10:44:38 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-09-23 11:02:21 -0400 |
commit | c5e87e33c7a3bf0f3d6b289814d303bcb4c63fe2 (patch) | |
tree | 697388196be5e2808ccfec0ec6096d99cf049009 /src/or | |
parent | 81724d5a001575e3f25da665b8bdedf287ace765 (diff) | |
download | tor-c5e87e33c7a3bf0f3d6b289814d303bcb4c63fe2.tar.gz tor-c5e87e33c7a3bf0f3d6b289814d303bcb4c63fe2.zip |
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.
Diffstat (limited to 'src/or')
-rw-r--r-- | src/or/config.c | 1 | ||||
-rw-r--r-- | src/or/keypin.c | 42 | ||||
-rw-r--r-- | src/or/or.h | 1 |
3 files changed, 34 insertions, 10 deletions
diff --git a/src/or/config.c b/src/or/config.c index 44fb4ecec6..fa860af337 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -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"), diff --git a/src/or/keypin.c b/src/or/keypin.c index ebe83b35d2..cab6c9dc37 100644 --- a/src/or/keypin.c +++ b/src/or/keypin.c @@ -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 (HT_FIND(edmap, &the_ed_map, ent)) { - tor_free(ent); + } 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); + } + 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); diff --git a/src/or/or.h b/src/or/or.h index bec39b2b37..4496cbcec3 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -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. */ |