aboutsummaryrefslogtreecommitdiff
path: root/src/or/dirserv.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-05-28 11:04:33 -0400
committerNick Mathewson <nickm@torproject.org>2015-05-28 11:04:33 -0400
commit1b52e95028e0d84b7a112e4b8f2e393261dbb19c (patch)
tree3dba31b96e31d4c9816a2f124afc5ff2152af2c8 /src/or/dirserv.c
parent0989ba33834c17b2eac3bb87596fca115965ce3c (diff)
parent5eb584e2e91bd5d6d204b9bb62a95c0edf43ff71 (diff)
downloadtor-1b52e95028e0d84b7a112e4b8f2e393261dbb19c.tar.gz
tor-1b52e95028e0d84b7a112e4b8f2e393261dbb19c.zip
Merge branch '12498_ed25519_keys_v6'
Fixed numerous conflicts, and ported code to use new base64 api.
Diffstat (limited to 'src/or/dirserv.c')
-rw-r--r--src/or/dirserv.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index a024be8342..bee67cf749 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -18,6 +18,7 @@
#include "dirserv.h"
#include "dirvote.h"
#include "hibernate.h"
+#include "keypin.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
@@ -27,6 +28,7 @@
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
+#include "torcert.h"
/**
* \file dirserv.c
@@ -225,6 +227,16 @@ dirserv_load_fingerprint_file(void)
return 0;
}
+/* If this is set, then we don't allow routers that have advertised an Ed25519
+ * identity to stop doing so. This is going to be essential for good identity
+ * security: otherwise anybody who can attack RSA-1024 but not Ed25519 could
+ * just sign fake descriptors missing the Ed25519 key. But we won't actually
+ * be able to prevent that kind of thing until we're confident that there
+ * isn't actually a legit reason to downgrade to 0.2.5. So for now, we have
+ * to leave this #undef.
+ */
+#undef DISABLE_DISABLING_ED25519
+
/** Check whether <b>router</b> has a nickname/identity key combination that
* we recognize from the fingerprint list, or an IP we automatically act on
* according to our configuration. Return the appropriate router status.
@@ -243,6 +255,36 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg)
return FP_REJECT;
}
+ if (router->signing_key_cert) {
+ /* This has an ed25519 identity key. */
+ if (KEYPIN_MISMATCH ==
+ keypin_check((const uint8_t*)router->cache_info.identity_digest,
+ router->signing_key_cert->signing_key.pubkey)) {
+ if (msg) {
+ *msg = "Ed25519 identity key or RSA identity key has changed.";
+ }
+ log_warn(LD_DIR, "Router %s uploaded a descriptor with a Ed25519 key "
+ "but the <rsa,ed25519> keys don't match what they were before.",
+ router_describe(router));
+ return FP_REJECT;
+ }
+ } else {
+ /* No ed25519 key */
+ if (KEYPIN_MISMATCH == keypin_check_lone_rsa(
+ (const uint8_t*)router->cache_info.identity_digest)) {
+ log_warn(LD_DIR, "Router %s uploaded a descriptor with no Ed25519 key, "
+ "when we previously knew an Ed25519 for it. Ignoring for now, "
+ "since Tor 0.2.6 is under development.",
+ router_describe(router));
+#ifdef DISABLE_DISABLING_ED25519
+ if (msg) {
+ *msg = "Ed25519 identity key has disappeared.";
+ }
+ return FP_REJECT;
+#endif
+ }
+ }
+
return dirserv_get_status_impl(d, router->nickname,
router->addr, router->or_port,
router->platform, msg, 1);
@@ -578,6 +620,28 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
return ROUTER_IS_ALREADY_KNOWN;
}
+ /* Do keypinning again ... this time, to add the pin if appropriate */
+ int keypin_status;
+ if (ri->signing_key_cert) {
+ keypin_status = keypin_check_and_add(
+ (const uint8_t*)ri->cache_info.identity_digest,
+ ri->signing_key_cert->signing_key.pubkey);
+ } else {
+ keypin_status = keypin_check_lone_rsa(
+ (const uint8_t*)ri->cache_info.identity_digest);
+#ifndef DISABLE_DISABLING_ED25519
+ if (keypin_status == KEYPIN_MISMATCH)
+ keypin_status = KEYPIN_NOT_FOUND;
+#endif
+ }
+ if (keypin_status == KEYPIN_MISMATCH) {
+ log_info(LD_DIRSERV, "Dropping descriptor from %s (source: %s) because "
+ "its key did not match an older RSA/Ed25519 keypair",
+ router_describe(ri), source);
+ *msg = "Looks like your keypair does not match its older value.";
+ return ROUTER_AUTHDIR_REJECTS;
+ }
+
/* Make a copy of desc, since router_add_to_routerlist might free
* ri and its associated signed_descriptor_t. */
desc = tor_strndup(ri->cache_info.signed_descriptor_body, desclen);
@@ -1929,6 +1993,16 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
smartlist_add_asprintf(chunks, "p %s\n", summary);
tor_free(summary);
}
+
+ if (format == NS_V3_VOTE && vrs) {
+ if (tor_mem_is_zero((char*)vrs->ed25519_id, ED25519_PUBKEY_LEN)) {
+ smartlist_add(chunks, tor_strdup("id ed25519 none\n"));
+ } else {
+ char ed_b64[BASE64_DIGEST256_LEN+1];
+ digest256_to_base64(ed_b64, (const char*)vrs->ed25519_id);
+ smartlist_add_asprintf(chunks, "id ed25519 %s\n", ed_b64);
+ }
+ }
}
done:
@@ -2751,6 +2825,11 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_t *private_key,
listbadexits,
vote_on_hsdirs);
+ if (ri->signing_key_cert) {
+ memcpy(vrs->ed25519_id, ri->signing_key_cert->signing_key.pubkey,
+ ED25519_PUBKEY_LEN);
+ }
+
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
clear_status_flags_on_sybil(rs);