summaryrefslogtreecommitdiff
path: root/src/or/routerparse.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-06-01 11:24:55 -0400
committerNick Mathewson <nickm@torproject.org>2015-06-01 11:24:55 -0400
commit3d653dff5e891c1e547ef7eacbc991410a98c1cb (patch)
treeb8169c115b1092c92ae871b1d6d08d9060a13454 /src/or/routerparse.c
parent3028507e96a51f2058e7ce6678ac8f2d8ab1b502 (diff)
downloadtor-3d653dff5e891c1e547ef7eacbc991410a98c1cb.tar.gz
tor-3d653dff5e891c1e547ef7eacbc991410a98c1cb.zip
Add a master-key-ed25519 line for convenience
Diffstat (limited to 'src/or/routerparse.c')
-rw-r--r--src/or/routerparse.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 1413d40703..ae50cda248 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -89,6 +89,7 @@ typedef enum {
K_IPV6_POLICY,
K_ROUTER_SIG_ED25519,
K_IDENTITY_ED25519,
+ K_MASTER_KEY_ED25519,
K_ONION_KEY_CROSSCERT,
K_NTOR_ONION_KEY_CROSSCERT,
@@ -302,6 +303,7 @@ static token_rule_t routerdesc_token_table[] = {
T01("extra-info-digest", K_EXTRA_INFO_DIGEST, GE(1), NO_OBJ ),
T01("hidden-service-dir", K_HIDDEN_SERVICE_DIR, NO_ARGS, NO_OBJ ),
T01("identity-ed25519", K_IDENTITY_ED25519, NO_ARGS, NEED_OBJ ),
+ T01("master-key-ed25519", K_MASTER_KEY_ED25519, GE(1), NO_OBJ ),
T01("router-sig-ed25519", K_ROUTER_SIG_ED25519, GE(1), NO_OBJ ),
T01("onion-key-crosscert", K_ONION_KEY_CROSSCERT, NO_ARGS, NEED_OBJ ),
T01("ntor-onion-key-crosscert", K_NTOR_ONION_KEY_CROSSCERT,
@@ -1337,9 +1339,11 @@ router_parse_entry_from_string(const char *s, const char *end,
}
{
- directory_token_t *ed_sig_tok, *ed_cert_tok, *cc_tap_tok, *cc_ntor_tok;
+ directory_token_t *ed_sig_tok, *ed_cert_tok, *cc_tap_tok, *cc_ntor_tok,
+ *master_key_tok;
ed_sig_tok = find_opt_by_keyword(tokens, K_ROUTER_SIG_ED25519);
ed_cert_tok = find_opt_by_keyword(tokens, K_IDENTITY_ED25519);
+ master_key_tok = find_opt_by_keyword(tokens, K_MASTER_KEY_ED25519);
cc_tap_tok = find_opt_by_keyword(tokens, K_ONION_KEY_CROSSCERT);
cc_ntor_tok = find_opt_by_keyword(tokens, K_NTOR_ONION_KEY_CROSSCERT);
int n_ed_toks = !!ed_sig_tok + !!ed_cert_tok +
@@ -1350,6 +1354,11 @@ router_parse_entry_from_string(const char *s, const char *end,
"cross-certification support");
goto err;
}
+ if (master_key_tok && !ed_sig_tok) {
+ log_warn(LD_DIR, "Router descriptor has ed25519 master key but no "
+ "certificate");
+ goto err;
+ }
if (ed_sig_tok) {
tor_assert(ed_cert_tok && cc_tap_tok && cc_ntor_tok);
const int ed_cert_token_pos = smartlist_pos(tokens, ed_cert_tok);
@@ -1394,12 +1403,30 @@ router_parse_entry_from_string(const char *s, const char *end,
goto err;
}
router->signing_key_cert = cert; /* makes sure it gets freed. */
+
if (cert->cert_type != CERT_TYPE_ID_SIGNING ||
! cert->signing_key_included) {
log_warn(LD_DIR, "Invalid form for ed25519 cert");
goto err;
}
+ if (master_key_tok) {
+ /* This token is optional, but if it's present, it must match
+ * the signature in the signing cert, or supplant it. */
+ tor_assert(master_key_tok->n_args >= 1);
+ ed25519_public_key_t pkey;
+ if (ed25519_public_from_base64(&pkey, master_key_tok->args[0])<0) {
+ log_warn(LD_DIR, "Can't parse ed25519 master key");
+ goto err;
+ }
+
+ if (fast_memneq(&cert->signing_key.pubkey,
+ pkey.pubkey, ED25519_PUBKEY_LEN)) {
+ log_warn(LD_DIR, "Ed25519 master key does not match "
+ "key in certificate");
+ goto err;
+ }
+ }
ntor_cc_cert = tor_cert_parse((const uint8_t*)cc_ntor_tok->object_body,
cc_ntor_tok->object_size);
if (!ntor_cc_cert) {