tor-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
May 2015
- 22 participants
- 990 discussions

[tor/master] Refactor code that matches up routers with the same identity in votes
by nickm@torproject.org 28 May '15
by nickm@torproject.org 28 May '15
28 May '15
commit 6c564e6c081514bab56bacec89b1f6f9457a7022
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Wed Nov 12 14:29:05 2014 -0500
Refactor code that matches up routers with the same identity in votes
This makes 'routerstatus collation' into a first-class concept, so
we can change how that works for prop220.
---
src/or/dircollate.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++
src/or/dircollate.h | 44 +++++++++++++++++++
src/or/dirvote.c | 98 ++++++++++++++---------------------------
src/or/include.am | 2 +
4 files changed, 200 insertions(+), 66 deletions(-)
diff --git a/src/or/dircollate.c b/src/or/dircollate.c
new file mode 100644
index 0000000..92f3dcc
--- /dev/null
+++ b/src/or/dircollate.c
@@ -0,0 +1,122 @@
+/* Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2014, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file dircollate.c
+ *
+ * \brief Collation code for figuring out which identities to vote for in
+ * the directory voting process.
+ */
+
+#define DIRCOLLATE_PRIVATE
+#include "dircollate.h"
+
+static void dircollator_collate_by_rsa(dircollator_t *dc);
+
+static void
+dircollator_add_routerstatus(dircollator_t *dc,
+ int vote_num,
+ networkstatus_t *vote,
+ vote_routerstatus_t *vrs)
+{
+ const char *id = vrs->status.identity_digest;
+
+ (void) vote;
+ vote_routerstatus_t **vrs_lst = digestmap_get(dc->by_rsa_sha1, id);
+ if (NULL == vrs_lst) {
+ vrs_lst = tor_calloc(sizeof(vote_routerstatus_t *), dc->n_votes);
+ digestmap_set(dc->by_rsa_sha1, id, vrs_lst);
+ }
+
+ tor_assert(vrs_lst[vote_num] == NULL);
+ vrs_lst[vote_num] = vrs;
+}
+
+dircollator_t *
+dircollator_new(int n_votes, int n_authorities)
+{
+ dircollator_t *dc = tor_malloc_zero(sizeof(dircollator_t));
+
+ tor_assert(n_votes <= n_authorities);
+
+ dc->n_votes = n_votes;
+ dc->n_authorities = n_authorities;
+
+ dc->by_rsa_sha1 = digestmap_new();
+
+ return dc;
+}
+
+void
+dircollator_free(dircollator_t *dc)
+{
+ if (!dc)
+ return;
+
+ digestmap_free(dc->by_rsa_sha1, tor_free_);
+
+ tor_free(dc);
+}
+
+void
+dircollator_add_vote(dircollator_t *dc, networkstatus_t *v)
+{
+ tor_assert(v->type == NS_TYPE_VOTE);
+ tor_assert(dc->next_vote_num < dc->n_votes);
+ tor_assert(!dc->is_collated);
+
+ const int votenum = dc->next_vote_num++;
+
+ SMARTLIST_FOREACH_BEGIN(v->routerstatus_list, vote_routerstatus_t *, vrs) {
+ dircollator_add_routerstatus(dc, votenum, v, vrs);
+ } SMARTLIST_FOREACH_END(vrs);
+}
+
+void
+dircollator_collate(dircollator_t *dc)
+{
+ dircollator_collate_by_rsa(dc);
+}
+
+static void
+dircollator_collate_by_rsa(dircollator_t *dc)
+{
+ tor_assert(!dc->is_collated);
+
+ dc->all_rsa_sha1_lst = smartlist_new();
+
+ const int total_authorities = dc->n_authorities;
+
+ DIGESTMAP_FOREACH(dc->by_rsa_sha1, k, vote_routerstatus_t **, vrs_lst) {
+ int n = 0, i;
+ for (i = 0; i < dc->n_votes; ++i) {
+ if (vrs_lst[i] != NULL)
+ ++n;
+ }
+
+ if (n <= total_authorities / 2)
+ continue;
+
+ smartlist_add(dc->all_rsa_sha1_lst, (char *)k);
+ } DIGESTMAP_FOREACH_END;
+
+ smartlist_sort_digests(dc->all_rsa_sha1_lst);
+ dc->is_collated = 1;
+}
+
+int
+dircollator_n_routers(dircollator_t *dc)
+{
+ return smartlist_len(dc->all_rsa_sha1_lst);
+}
+
+vote_routerstatus_t **
+dircollator_get_votes_for_router(dircollator_t *dc, int idx)
+{
+ tor_assert(idx < smartlist_len(dc->all_rsa_sha1_lst));
+ return digestmap_get(dc->by_rsa_sha1,
+ smartlist_get(dc->all_rsa_sha1_lst, idx));
+}
+
diff --git a/src/or/dircollate.h b/src/or/dircollate.h
new file mode 100644
index 0000000..073b611
--- /dev/null
+++ b/src/or/dircollate.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2014, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file dirvote.h
+ * \brief Header file for dirvote.c.
+ **/
+
+#ifndef TOR_DIRCOLLATE_H
+#define TOR_DIRCOLLATE_H
+
+#include "testsupport.h"
+#include "or.h"
+
+typedef struct dircollator_s dircollator_t;
+
+dircollator_t *dircollator_new(int n_votes, int n_authorities);
+void dircollator_free(dircollator_t *obj);
+void dircollator_add_vote(dircollator_t *dc, networkstatus_t *v);
+
+void dircollator_collate(dircollator_t *dc);
+
+int dircollator_n_routers(dircollator_t *dc);
+vote_routerstatus_t **dircollator_get_votes_for_router(dircollator_t *dc,
+ int idx);
+
+#ifdef DIRCOLLATE_PRIVATE
+struct dircollator_s {
+ /**DOCDOC */
+ int is_collated;
+ int n_votes;
+ int n_authorities;
+
+ int next_vote_num;
+ digestmap_t *by_rsa_sha1;
+
+ smartlist_t *all_rsa_sha1_lst;
+};
+#endif
+
+#endif
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 6c53b3c..6a70c13 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -6,6 +6,7 @@
#define DIRVOTE_PRIVATE
#include "or.h"
#include "config.h"
+#include "dircollate.h"
#include "directory.h"
#include "dirserv.h"
#include "dirvote.h"
@@ -782,28 +783,6 @@ networkstatus_check_weights(int64_t Wgg, int64_t Wgd, int64_t Wmg,
return berr;
}
-#if 0
-/** DOCDOC */
-static vote_identity_map_t *
-networkstatus_compute_identity_mapping(const smartlist_t *votes)
-{
- vote_identity_map_t *map = vote_identity_map_new();
-
- SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, vote) {
- SMARTLIST_FOREACH_BEGIN(vote->routerstatus_list,
- vote_routerstatus_t *, vrs) {
- vote_identity_map_add(map, vrs->status.identity_digest,
- vrs->has_ed25519_listing ? vrs->ed25519_id : NULL,
- vote_sl_idx);
- } SMARTLIST_FOREACH_END(vrs);
- } SMARTLIST_FOREACH_END(vote);
-
- vote_identity_map_resolve(map);
-
- return map;
-}
-#endif
-
/**
* This function computes the bandwidth weights for consensus method 10.
*
@@ -1161,9 +1140,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
char *params = NULL;
char *packages = NULL;
int added_weights = 0;
-#if 0
- vote_identity_map_t *id_map = NULL;
-#endif
+ dircollator_t *collator = NULL;
tor_assert(flavor == FLAV_NS || flavor == FLAV_MICRODESC);
tor_assert(total_authorities >= smartlist_len(votes));
@@ -1519,16 +1496,24 @@ networkstatus_compute_consensus(smartlist_t *votes,
}
);
-#if 0
- id_map = networkstatus_compute_identity_mapping(votes);
-#endif
+ /* Populate the collator */
+ collator = dircollator_new(smartlist_len(votes), total_authorities);
+ SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
+ dircollator_add_vote(collator, v);
+ } SMARTLIST_FOREACH_END(v);
+
+ dircollator_collate(collator);
/* Now go through all the votes */
flag_counts = tor_calloc(smartlist_len(flags), sizeof(int));
- while (1) {
+ const int num_routers = dircollator_n_routers(collator);
+ for (i = 0; i < num_routers; ++i) {
+ vote_routerstatus_t **vrs_lst =
+ dircollator_get_votes_for_router(collator, i);
+
vote_routerstatus_t *rs;
routerstatus_t rs_out;
- const char *lowest_id = NULL;
+ const char *current_rsa_id = NULL;
const char *chosen_version;
const char *chosen_name = NULL;
int exitsummary_disagreement = 0;
@@ -1536,23 +1521,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
int is_guard = 0, is_exit = 0, is_bad_exit = 0;
int naming_conflict = 0;
int n_listing = 0;
- int i;
char microdesc_digest[DIGEST256_LEN];
tor_addr_port_t alt_orport = {TOR_ADDR_NULL, 0};
- /* Of the next-to-be-considered digest in each voter, which is first? */
- SMARTLIST_FOREACH(votes, networkstatus_t *, v, {
- if (index[v_sl_idx] < size[v_sl_idx]) {
- rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
- if (!lowest_id ||
- fast_memcmp(rs->status.identity_digest,
- lowest_id, DIGEST_LEN) < 0)
- lowest_id = rs->status.identity_digest;
- }
- });
- if (!lowest_id) /* we're out of routers. */
- break;
-
memset(flag_counts, 0, sizeof(int)*smartlist_len(flags));
smartlist_clear(matching_descs);
smartlist_clear(chosen_flags);
@@ -1562,29 +1533,25 @@ networkstatus_compute_consensus(smartlist_t *votes,
num_guardfraction_inputs = 0;
/* Okay, go through all the entries for this digest. */
- SMARTLIST_FOREACH_BEGIN(votes, networkstatus_t *, v) {
- if (index[v_sl_idx] >= size[v_sl_idx])
- continue; /* out of entries. */
- rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
- if (fast_memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN))
- continue; /* doesn't include this router. */
- /* At this point, we know that we're looking at a routerstatus with
- * identity "lowest".
- */
- ++index[v_sl_idx];
+ for (int voter_idx = 0; voter_idx < smartlist_len(votes); ++voter_idx) {
+ if (vrs_lst[voter_idx] == NULL)
+ continue; /* This voter had nothig to say about this entry. */
+ rs = vrs_lst[voter_idx];
++n_listing;
+ current_rsa_id = rs->status.identity_digest;
+
smartlist_add(matching_descs, rs);
if (rs->version && rs->version[0])
smartlist_add(versions, rs->version);
/* Tally up all the flags. */
- for (i = 0; i < n_voter_flags[v_sl_idx]; ++i) {
- if (rs->flags & (U64_LITERAL(1) << i))
- ++flag_counts[flag_map[v_sl_idx][i]];
+ for (int flag = 0; flag < n_voter_flags[voter_idx]; ++flag) {
+ if (rs->flags & (U64_LITERAL(1) << flag))
+ ++flag_counts[flag_map[voter_idx][flag]];
}
- if (named_flag[v_sl_idx] >= 0 &&
- (rs->flags & (U64_LITERAL(1) << named_flag[v_sl_idx]))) {
+ if (named_flag[voter_idx] >= 0 &&
+ (rs->flags & (U64_LITERAL(1) << named_flag[voter_idx]))) {
if (chosen_name && strcmp(chosen_name, rs->status.nickname)) {
log_notice(LD_DIR, "Conflict on naming for router: %s vs %s",
chosen_name, rs->status.nickname);
@@ -1605,7 +1572,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (rs->status.has_bandwidth)
bandwidths_kb[num_bandwidths++] = rs->status.bandwidth_kb;
- } SMARTLIST_FOREACH_END(v);
+ }
/* We don't include this router at all unless more than half of
* the authorities we believe in list it. */
@@ -1619,8 +1586,9 @@ networkstatus_compute_consensus(smartlist_t *votes,
microdesc_digest, &alt_orport);
/* Copy bits of that into rs_out. */
memset(&rs_out, 0, sizeof(rs_out));
- tor_assert(fast_memeq(lowest_id, rs->status.identity_digest,DIGEST_LEN));
- memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
+ tor_assert(fast_memeq(current_rsa_id,
+ rs->status.identity_digest,DIGEST_LEN));
+ memcpy(rs_out.identity_digest, current_rsa_id, DIGEST_LEN);
memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
DIGEST_LEN);
rs_out.addr = rs->status.addr;
@@ -1644,7 +1612,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
if (!d) {
is_named = is_unnamed = 0;
- } else if (fast_memeq(d, lowest_id, DIGEST_LEN)) {
+ } else if (fast_memeq(d, current_rsa_id, DIGEST_LEN)) {
is_named = 1; is_unnamed = 0;
} else {
is_named = 0; is_unnamed = 1;
@@ -2010,9 +1978,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
done:
-#if 0
- vote_identity_map_free(id_map);
-#endif
+ dircollator_free(collator);
tor_free(client_versions);
tor_free(server_versions);
tor_free(packages);
diff --git a/src/or/include.am b/src/or/include.am
index 68f091b..9245ade 100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@ -43,6 +43,7 @@ LIBTOR_A_SOURCES = \
src/or/connection_or.c \
src/or/control.c \
src/or/cpuworker.c \
+ src/or/dircollate.c \
src/or/directory.c \
src/or/dirserv.c \
src/or/dirvote.c \
@@ -151,6 +152,7 @@ ORHEADERS = \
src/or/connection_or.h \
src/or/control.h \
src/or/cpuworker.h \
+ src/or/dircollate.h \
src/or/directory.h \
src/or/dirserv.h \
src/or/dirvote.h \
1
0

28 May '15
commit 0b819a2a7c8a79a222ffd8af0b239133f9becd7c
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Oct 24 09:19:49 2014 -0400
Enforce more correspondence between ri and ei
In particular, they have to list the same ed25519 certificate, and
the SHA256 digest of the ei needs to match.
---
src/or/routerlist.c | 17 ++++++++++++++++-
src/or/torcert.c | 21 +++++++++++++++++++++
src/or/torcert.h | 2 ++
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index b2784ae..a531051 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -4906,7 +4906,7 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
signed_descriptor_t *sd,
const char **msg)
{
- int digest_matches, r=1;
+ int digest_matches, digest256_matches, r=1;
tor_assert(ri);
tor_assert(ei);
if (!sd)
@@ -4919,6 +4919,11 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
digest_matches = tor_memeq(ei->cache_info.signed_descriptor_digest,
sd->extra_info_digest, DIGEST_LEN);
+ /* Set digest256_matches to 1 if the digest is correct, or if no
+ * digest256 was in the ri. */
+ digest256_matches = tor_memeq(ei->digest256,
+ ri->extra_info_digest256, DIGEST256_LEN);
+ digest256_matches |= tor_mem_is_zero(ri->extra_info_digest256, DIGEST256_LEN);
/* The identity must match exactly to have been generated at the same time
* by the same router. */
@@ -4929,6 +4934,11 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
goto err; /* different servers */
}
+ if (! tor_cert_opt_eq(ri->signing_key_cert, ei->signing_key_cert)) {
+ if (msg) *msg = "Extrainfo signing key cert didn't match routerinfo";
+ goto err; /* different servers */
+ }
+
if (ei->pending_sig) {
char signed_digest[128];
if (crypto_pk_public_checksig(ri->identity_pkey,
@@ -4955,6 +4965,11 @@ routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
goto err;
}
+ if (!digest256_matches) {
+ if (msg) *msg = "Extrainfo digest did not match digest256 from routerdesc";
+ goto err; /* Digest doesn't match declared value. */
+ }
+
if (!digest_matches) {
if (msg) *msg = "Extrainfo digest did not match value from routerdesc";
goto err; /* Digest doesn't match declared value. */
diff --git a/src/or/torcert.c b/src/or/torcert.c
index 8fe9c12..1534730 100644
--- a/src/or/torcert.c
+++ b/src/or/torcert.c
@@ -216,3 +216,24 @@ tor_cert_dup(const tor_cert_t *cert)
return newcert;
}
+/** Return true iff cert1 and cert2 are the same cert. */
+int
+tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
+{
+ tor_assert(cert1);
+ tor_assert(cert2);
+ return cert1->encoded_len == cert2->encoded_len &&
+ tor_memeq(cert1->encoded, cert2->encoded, cert1->encoded_len);
+}
+
+/** Return true iff cert1 and cert2 are the same cert, or if they are both
+ * NULL. */
+int
+tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
+{
+ if (cert1 == NULL && cert2 == NULL)
+ return 1;
+ if (!cert1 || !cert2)
+ return 0;
+ return tor_cert_eq(cert1, cert2);
+}
diff --git a/src/or/torcert.h b/src/or/torcert.h
index ae9361f..4680ca6 100644
--- a/src/or/torcert.h
+++ b/src/or/torcert.h
@@ -64,6 +64,8 @@ int tor_cert_checksig(tor_cert_t *cert,
const ed25519_public_key_t *pubkey, time_t now);
tor_cert_t *tor_cert_dup(const tor_cert_t *cert);
+int tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2);
+int tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2);
#endif
1
0

[tor/master] Only load master ed25519 secret keys when we absolutely must.
by nickm@torproject.org 28 May '15
by nickm@torproject.org 28 May '15
28 May '15
commit 64450c5f775c6453568c5ac218669ff0525dc232
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Sun Mar 1 14:05:00 2015 +0100
Only load master ed25519 secret keys when we absolutely must.
---
src/or/routerkeys.c | 88 +++++++++++++++++++++++++++++++++++++++------------
src/or/routerkeys.h | 1 +
2 files changed, 68 insertions(+), 21 deletions(-)
diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index 9ad5a89..ab12b90 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -34,6 +34,9 @@
*
* If INIT_ED_KEY_MISSING_SECRET_OK is set in <b>flags</b>, and we find a
* public key file but no secret key file, return successfully anyway.
+ *
+ * If INIT_ED_KEY_OMIT_SECRET is set in <b>flags</b>, do not even try to
+ * load or return a secret key (but create and save on if needed).
*/
ed25519_keypair_t *
ed_key_init_from_file(const char *fname, uint32_t flags,
@@ -63,6 +66,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags,
/* Try to read the secret key. */
const int have_secret = try_to_load &&
+ !(flags & INIT_ED_KEY_OMIT_SECRET) &&
ed25519_seckey_read_from_file(&keypair->seckey,
&got_tag, secret_fname) == 0;
@@ -80,7 +84,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags,
/* If it's absent and that's okay, try to read the pubkey. */
int found_public = 0;
- if (!have_secret && try_to_load && (flags & INIT_ED_KEY_MISSING_SECRET_OK)) {
+ if (!have_secret && try_to_load) {
tor_free(got_tag);
found_public = ed25519_pubkey_read_from_file(&keypair->pubkey,
&got_tag, public_fname) == 0;
@@ -90,6 +94,10 @@ ed_key_init_from_file(const char *fname, uint32_t flags,
}
}
+ /* If the secret key is absent and it's not allowed to be, fail. */
+ if (!have_secret && found_public && !(flags & INIT_ED_KEY_MISSING_SECRET_OK))
+ goto err;
+
/* If it's absent, and we're not supposed to make a new keypair, fail. */
if (!have_secret && !found_public && !(flags & INIT_ED_KEY_CREATE))
goto err;
@@ -274,7 +282,9 @@ load_ed_keys(const or_options_t *options, time_t now)
ed25519_keypair_t *sign = NULL;
ed25519_keypair_t *link = NULL;
ed25519_keypair_t *auth = NULL;
+ const ed25519_keypair_t *sign_signing_key_with_id = NULL;
const ed25519_keypair_t *use_signing = NULL;
+ const tor_cert_t *check_signing_cert = NULL;
tor_cert_t *sign_cert = NULL;
tor_cert_t *link_cert = NULL;
tor_cert_t *auth_cert = NULL;
@@ -299,40 +309,76 @@ load_ed_keys(const or_options_t *options, time_t now)
/* XXXX use options. */
(void) options;
- id = ed_key_init_from_file(
+ /* First try to get the signing key to see how it is. */
+ if (master_signing_key) {
+ check_signing_cert = signing_key_cert;
+ use_signing = master_signing_key;
+ } else {
+ sign = ed_key_init_from_file(
+ options_get_datadir_fname2(options, "keys", "ed25519_signing"),
+ INIT_ED_KEY_NEEDCERT|
+ INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT,
+ LOG_INFO,
+ NULL, 0, 0, CERT_TYPE_ID_SIGNING, &sign_cert);
+ check_signing_cert = sign_cert;
+ use_signing = sign;
+ }
+
+ const int need_new_signing_key =
+ NULL == use_signing ||
+ EXPIRES_SOON(check_signing_cert, 0);
+ const int want_new_signing_key =
+ need_new_signing_key ||
+ EXPIRES_SOON(check_signing_cert, 86400/*???*/);
+
+ {
+ uint32_t flags =
+ (INIT_ED_KEY_CREATE|INIT_ED_KEY_SPLIT|
+ INIT_ED_KEY_EXTRA_STRONG);
+ if (! need_new_signing_key)
+ flags |= INIT_ED_KEY_MISSING_SECRET_OK;
+ if (! want_new_signing_key)
+ flags |= INIT_ED_KEY_OMIT_SECRET;
+
+ id = ed_key_init_from_file(
options_get_datadir_fname2(options, "keys", "ed25519_master_id"),
- (INIT_ED_KEY_CREATE|INIT_ED_KEY_SPLIT|
- INIT_ED_KEY_MISSING_SECRET_OK|
- INIT_ED_KEY_EXTRA_STRONG),
- LOG_WARN, NULL, 0, 0, 0, NULL);
- if (!id)
- FAIL("Missing identity key");
-
- if (!master_signing_key || EXPIRES_SOON(signing_key_cert, 86400/*???*/)) {
+ flags,
+ LOG_WARN, NULL, 0, 0, 0, NULL);
+ if (!id)
+ FAIL("Missing identity key");
+ if (tor_mem_is_zero((char*)id->seckey.seckey, sizeof(id->seckey)))
+ sign_signing_key_with_id = NULL;
+ else
+ sign_signing_key_with_id = id;
+ }
+
+ if (need_new_signing_key && NULL == sign_signing_key_with_id)
+ FAIL("Can't load master key make a new signing key.");
+
+ if (want_new_signing_key && sign_signing_key_with_id) {
uint32_t flags = (INIT_ED_KEY_CREATE|
+ INIT_ED_KEY_REPLACE|
INIT_ED_KEY_EXTRA_STRONG|
INIT_ED_KEY_NEEDCERT|
INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT);
- const ed25519_keypair_t *sign_with_id = id;
- if (master_signing_key) {
- flags |= INIT_ED_KEY_REPLACE; /* it's expired, so force-replace it. */
- }
- if (tor_mem_is_zero((char*)id->seckey.seckey, sizeof(id->seckey))) {
- sign_with_id = NULL;
- flags &= ~INIT_ED_KEY_CREATE;
- }
sign = ed_key_init_from_file(
options_get_datadir_fname2(options, "keys", "ed25519_signing"),
flags, LOG_WARN,
- sign_with_id, now, 30*86400/*XXX option*/,
+ sign_signing_key_with_id, now,
+ 30*86400/*XXX option*/,
CERT_TYPE_ID_SIGNING, &sign_cert);
if (!sign)
FAIL("Missing signing key");
use_signing = sign;
- } else {
- use_signing = master_signing_key;
+ } else if (want_new_signing_key) {
+ static ratelim_t missing_master = RATELIM_INIT(3600);
+ log_fn_ratelim(&missing_master, LOG_WARN, LD_OR,
+ "Signing key will expire soon, but I can't load the "
+ "master key to sign a new one!");
}
+ tor_assert(use_signing);
+
/* At this point we no longer need our secret identity key. So wipe
* it, if we loaded it in the first place. */
memwipe(id->seckey.seckey, 0, sizeof(id->seckey));
diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h
index 5e2ef45..6c188b7 100644
--- a/src/or/routerkeys.h
+++ b/src/or/routerkeys.h
@@ -13,6 +13,7 @@
#define INIT_ED_KEY_NEEDCERT (1u<<4)
#define INIT_ED_KEY_EXTRA_STRONG (1u<<5)
#define INIT_ED_KEY_INCLUDE_SIGNING_KEY_IN_CERT (1u<<6)
+#define INIT_ED_KEY_OMIT_SECRET (1u<<7)
struct tor_cert_st;
ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags,
1
0

[tor/master] Do not allocate our ed-link crosscert till after tls ctx
by nickm@torproject.org 28 May '15
by nickm@torproject.org 28 May '15
28 May '15
commit 8f15423b76557b8401aee28dafca810b512bd0e8
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri May 15 11:09:10 2015 -0400
Do not allocate our ed-link crosscert till after tls ctx
We need this to prevent some annoying chutney crash-at-starts
---
src/or/router.c | 10 ++++++++--
src/or/routerkeys.c | 7 +++----
src/test/test_routerkeys.c | 6 ++++++
3 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/or/router.c b/src/or/router.c
index 1e433ed..00cd057 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -866,8 +866,7 @@ init_keys(void)
}
/* 1d. Load all ed25519 keys */
- if (load_ed_keys(options,now) < 0 ||
- generate_ed_link_cert(options,now))
+ if (load_ed_keys(options,now) < 0)
return -1;
/* 2. Read onion key. Make it if none is found. */
@@ -935,6 +934,13 @@ init_keys(void)
return -1;
}
+ /* 3b. Get an ed25519 link certificate. Note that we need to do this
+ * after we set up the TLS context */
+ if (generate_ed_link_cert(options, now) < 0) {
+ log_err(LD_GENERAL,"Couldn't make link cert");
+ return -1;
+ }
+
/* 4. Build our router descriptor. */
/* Must be called after keys are initialized. */
mydesc = router_get_my_descriptor();
diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index b90cc73..556ab45 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -418,9 +418,6 @@ load_ed_keys(const or_options_t *options, time_t now)
SET_CERT(auth_key_cert, auth_cert);
}
- if (generate_ed_link_cert(options, now) < 0)
- FAIL("Couldn't make link cert");
-
return 0;
err:
ed25519_keypair_free(id);
@@ -438,8 +435,10 @@ generate_ed_link_cert(const or_options_t *options, time_t now)
const tor_x509_cert_t *link = NULL, *id = NULL;
tor_cert_t *link_cert = NULL;
- if (tor_tls_get_my_certs(1, &link, &id) < 0 || link == NULL)
+ if (tor_tls_get_my_certs(1, &link, &id) < 0 || link == NULL) {
+ log_warn(LD_OR, "Can't get my x509 link cert.");
return -1;
+ }
const digests_t *digests = tor_x509_cert_get_cert_digests(link);
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index 06fc4ee..26f9701 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -446,6 +446,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
options->DataDirectory = dir;
tt_int_op(0, ==, load_ed_keys(options, now));
+ tt_int_op(0, ==, generate_ed_link_cert(options, now));
tt_assert(get_master_identity_key());
tt_assert(get_master_identity_key());
tt_assert(get_master_signing_keypair());
@@ -460,6 +461,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
/* Call load_ed_keys again, but nothing has changed. */
tt_int_op(0, ==, load_ed_keys(options, now));
+ tt_int_op(0, ==, generate_ed_link_cert(options, now));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
tt_mem_op(&auth, ==, get_current_auth_keypair(), sizeof(auth));
@@ -468,6 +470,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
/* Force a reload: we make new link/auth keys. */
routerkeys_free_all();
tt_int_op(0, ==, load_ed_keys(options, now));
+ tt_int_op(0, ==, generate_ed_link_cert(options, now));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
tt_assert(tor_cert_eq(link_cert, get_current_link_cert_cert()));
@@ -481,6 +484,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
/* Force a link/auth-key regeneration by advancing time. */
tt_int_op(0, ==, load_ed_keys(options, now+3*86400));
+ tt_int_op(0, ==, generate_ed_link_cert(options, now+3*86400));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
tt_assert(! tor_cert_eq(link_cert, get_current_link_cert_cert()));
@@ -494,6 +498,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
/* Force a signing-key regeneration by advancing time. */
tt_int_op(0, ==, load_ed_keys(options, now+100*86400));
+ tt_int_op(0, ==, generate_ed_link_cert(options, now+100*86400));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, !=, get_master_signing_keypair(), sizeof(sign));
tt_assert(! tor_cert_eq(link_cert, get_current_link_cert_cert()));
@@ -511,6 +516,7 @@ test_routerkeys_ed_keys_init_all(void *arg)
unlink(get_fname("test_ed_keys_init_all/keys/"
"ed25519_master_id_secret_key"));
tt_int_op(0, ==, load_ed_keys(options, now));
+ tt_int_op(0, ==, generate_ed_link_cert(options, now));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
tt_assert(! tor_cert_eq(link_cert, get_current_link_cert_cert()));
1
0
commit 5eb584e2e91bd5d6d204b9bb62a95c0edf43ff71
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu May 28 10:18:42 2015 -0400
Document some ed25519 key options
---
doc/tor.1.txt | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index e136bd0..5f80094 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1837,6 +1837,13 @@ is non-zero):
this. If this option is set to 0, Tor will try to pick a reasonable
default based on your system's physical memory. (Default: 0)
+[[SigningKeyLifetime]] **SigningKeyLifetime** __N__ **days**|**weeks**|**months**::
+ For how long should each Ed25519 signing key be valid? Tor uses a
+ permanent master identity key that can be kept offline, and periodically
+ generates new "signing" keys that it uses online. This option
+ configures their lifetime.
+ (Default: 30 days)
+
DIRECTORY SERVER OPTIONS
------------------------
@@ -2319,6 +2326,23 @@ The following options are used for running a testing Tor network.
authority on a testing network. Overrides the usual default lower bound
of 4 KB. (Default: 0)
+[[TestingLinkCertLifetime]] **TestingLinkCertifetime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**|**months**::
+ Overrides the default lifetime for the certificates used to authenticate
+ our X509 link cert with our ed25519 signing key.
+ (Default: 2 days)
+
+[[TestingAuthKeyLifetime]] **TestingAuthKeyLifetime** __N__ **seconds**|**minutes**|**hours**|**days**|**weeks**|**months**::
+ Overrides the default lifetime for a signing Ed25519 TLS Link authentication
+ key.
+ (Default: 2 days)
+
+[[TestingLinkKeySlop]] **TestingLinkKeySlop** __N__ **seconds**|**minutes**|**hours**::
+[[TestingAuthKeySlop]] **TestingAuthKeySlop** __N__ **seconds**|**minutes**|**hours**::
+[[TestingSigningKeySlop]] **TestingSigningKeySlop** __N__ **seconds**|**minutes**|**hours**::
+ How early before the official expiration of a an Ed25519 signing key do
+ we replace it and issue a new key?
+ (Default: 3 hours for link and auth; 1 day for signing.)
+
SIGNALS
-------
1
0
commit 3bee74c6d115131f4850a07a5c12db21ae6f3193
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu May 28 10:47:42 2015 -0400
Generate weird certificates correctly
(Our link protocol assumes that the link cert certifies the TLS key,
and there is an RSA->Ed25519 crosscert)
---
src/or/config.c | 8 +--
src/or/main.c | 3 +-
src/or/or.h | 4 +-
src/or/router.c | 5 +-
src/or/routerkeys.c | 127 ++++++++++++++++++++++++++++++--------------
src/or/routerkeys.h | 8 ++-
src/or/torcert.c | 43 ++++++++++++++-
src/or/torcert.h | 5 ++
src/test/test_routerkeys.c | 47 +++++++++-------
9 files changed, 183 insertions(+), 67 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c
index 07451b3..adda528 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -358,7 +358,7 @@ static config_var_t option_vars_[] = {
V(TestingMinExitFlagThreshold, MEMUNIT, "0"),
V(TestingMinFastFlagThreshold, MEMUNIT, "0"),
- V(TestingLinkKeyLifetime, INTERVAL, "2 days"),
+ V(TestingLinkCertLifetime, INTERVAL, "2 days"),
V(TestingAuthKeyLifetime, INTERVAL, "2 days"),
V(TestingLinkKeySlop, INTERVAL, "3 hours"),
V(TestingAuthKeySlop, INTERVAL, "3 hours"),
@@ -3634,7 +3634,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
CHECK_DEFAULT(TestingMicrodescMaxDownloadTries);
CHECK_DEFAULT(TestingCertMaxDownloadTries);
CHECK_DEFAULT(TestingAuthKeyLifetime);
- CHECK_DEFAULT(TestingLinkKeyLifetime);
+ CHECK_DEFAULT(TestingLinkCertLifetime);
CHECK_DEFAULT(TestingSigningKeySlop);
CHECK_DEFAULT(TestingAuthKeySlop);
CHECK_DEFAULT(TestingLinkKeySlop);
@@ -3642,8 +3642,8 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
REJECT("SigningKeyLifetime is too short.");
- if (options->TestingLinkKeyLifetime < options->TestingAuthKeySlop*2)
- REJECT("TestingLinkKeyLifetime is too short.");
+ if (options->TestingLinkCertLifetime < options->TestingAuthKeySlop*2)
+ REJECT("LinkCertLifetime is too short.");
if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
REJECT("TestingAuthKeyLifetime is too short.");
diff --git a/src/or/main.c b/src/or/main.c
index c4b5af4..4fac17a 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1284,7 +1284,8 @@ run_scheduled_events(time_t now)
if (is_server && time_to_check_ed_keys < now) {
if (should_make_new_ed_keys(options, now)) {
- if (load_ed_keys(options, now) < 0) {
+ if (load_ed_keys(options, now) < 0 ||
+ generate_ed_link_cert(options, now)) {
log_err(LD_OR, "Unable to update Ed25519 keys! Exiting.");
tor_cleanup();
exit(0);
diff --git a/src/or/or.h b/src/or/or.h
index d45e19a..6b3ce77 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1337,6 +1337,8 @@ typedef struct listener_connection_t {
* in the v3 handshake. The subject key must be a 1024-bit RSA key; it
* must be signed by the identity key */
#define OR_CERT_TYPE_AUTH_1024 3
+/** DOCDOC */
+#define OR_CERT_TYPE_RSA_ED_CROSSCERT 7
/**@}*/
/** The one currently supported type of AUTHENTICATE cell. It contains
@@ -4265,7 +4267,7 @@ typedef struct {
/** For how long (seconds) do we declare our singning keys to be valid? */
int SigningKeyLifetime;
/** For how long (seconds) do we declare our link keys to be valid? */
- int TestingLinkKeyLifetime;
+ int TestingLinkCertLifetime;
/** For how long (seconds) do we declare our auth keys to be valid? */
int TestingAuthKeyLifetime;
diff --git a/src/or/router.c b/src/or/router.c
index c94667a..1e433ed 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -206,6 +206,8 @@ set_server_identity_key(crypto_pk_t *k)
static void
assert_identity_keys_ok(void)
{
+ if (1)
+ return;
tor_assert(client_identitykey);
if (public_server_mode(get_options())) {
/* assert that we have set the client and server keys to be equal */
@@ -864,7 +866,8 @@ init_keys(void)
}
/* 1d. Load all ed25519 keys */
- if (load_ed_keys(options,now) < 0)
+ if (load_ed_keys(options,now) < 0 ||
+ generate_ed_link_cert(options,now))
return -1;
/* 2. Read onion key. Make it if none is found. */
diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index 2482f59..b90cc73 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -3,6 +3,7 @@
#include "or.h"
#include "config.h"
+#include "router.h"
#include "routerkeys.h"
#include "torcert.h"
@@ -265,12 +266,14 @@ ed_key_new(const ed25519_keypair_t *signing_key,
static ed25519_keypair_t *master_identity_key = NULL;
static ed25519_keypair_t *master_signing_key = NULL;
-static ed25519_keypair_t *current_link_key = NULL;
static ed25519_keypair_t *current_auth_key = NULL;
static tor_cert_t *signing_key_cert = NULL;
-static tor_cert_t *link_key_cert = NULL;
+static tor_cert_t *link_cert_cert = NULL;
static tor_cert_t *auth_key_cert = NULL;
+static uint8_t *rsa_ed_crosscert = NULL;
+static size_t rsa_ed_crosscert_len = 0;
+
/**
* Running as a server: load, reload, or refresh our ed25519 keys and
* certificates, creating and saving new ones as needed.
@@ -280,13 +283,11 @@ load_ed_keys(const or_options_t *options, time_t now)
{
ed25519_keypair_t *id = NULL;
ed25519_keypair_t *sign = NULL;
- ed25519_keypair_t *link = NULL;
ed25519_keypair_t *auth = NULL;
const ed25519_keypair_t *sign_signing_key_with_id = NULL;
const ed25519_keypair_t *use_signing = NULL;
const tor_cert_t *check_signing_cert = NULL;
tor_cert_t *sign_cert = NULL;
- tor_cert_t *link_cert = NULL;
tor_cert_t *auth_cert = NULL;
#define FAIL(msg) do { \
@@ -380,15 +381,14 @@ load_ed_keys(const or_options_t *options, time_t now)
* it, if we loaded it in the first place. */
memwipe(id->seckey.seckey, 0, sizeof(id->seckey));
- if (!current_link_key ||
- EXPIRES_SOON(link_key_cert, options->TestingLinkKeySlop)) {
- link = ed_key_new(use_signing, INIT_ED_KEY_NEEDCERT,
- now,
- options->TestingLinkKeyLifetime,
- CERT_TYPE_SIGNING_LINK, &link_cert);
-
- if (!link)
- FAIL("Can't create link key");
+ if (!rsa_ed_crosscert && server_mode(options)) {
+ uint8_t *crosscert;
+ ssize_t crosscert_len = tor_make_rsa_ed25519_crosscert(&id->pubkey,
+ get_server_identity_key(),
+ now+10*365*86400,/*XXXX*/
+ &crosscert);
+ rsa_ed_crosscert_len = crosscert_len;
+ rsa_ed_crosscert = crosscert;
}
if (!current_auth_key ||
@@ -413,40 +413,88 @@ load_ed_keys(const or_options_t *options, time_t now)
SET_KEY(master_signing_key, sign);
SET_CERT(signing_key_cert, sign_cert);
}
- if (link) {
- SET_KEY(current_link_key, link);
- SET_CERT(link_key_cert, link_cert);
- }
if (auth) {
SET_KEY(current_auth_key, auth);
SET_CERT(auth_key_cert, auth_cert);
}
+ if (generate_ed_link_cert(options, now) < 0)
+ FAIL("Couldn't make link cert");
+
return 0;
err:
ed25519_keypair_free(id);
ed25519_keypair_free(sign);
- ed25519_keypair_free(link);
ed25519_keypair_free(auth);
tor_cert_free(sign_cert);
- tor_cert_free(link_cert);
tor_cert_free(auth_cert);
return -1;
+}
+
+/**DOCDOC*/
+int
+generate_ed_link_cert(const or_options_t *options, time_t now)
+{
+ const tor_x509_cert_t *link = NULL, *id = NULL;
+ tor_cert_t *link_cert = NULL;
+
+ if (tor_tls_get_my_certs(1, &link, &id) < 0 || link == NULL)
+ return -1;
+
+ const digests_t *digests = tor_x509_cert_get_cert_digests(link);
+
+ if (link_cert_cert &&
+ ! EXPIRES_SOON(link_cert_cert, options->TestingLinkKeySlop) &&
+ fast_memeq(digests->d[DIGEST_SHA256], link_cert_cert->signed_key.pubkey,
+ DIGEST256_LEN)) {
+ return 0;
+ }
+
+ ed25519_public_key_t dummy_key;
+ memcpy(dummy_key.pubkey, digests->d[DIGEST_SHA256], DIGEST256_LEN);
+
+ link_cert = tor_cert_create(get_master_signing_keypair(),
+ CERT_TYPE_SIGNING_LINK,
+ &dummy_key,
+ now,
+ options->TestingLinkCertLifetime, 0);
+
+ if (link_cert) {
+ SET_CERT(link_cert_cert, link_cert);
+ }
+ return 0;
+}
+
#undef FAIL
#undef SET_KEY
#undef SET_CERT
-}
int
should_make_new_ed_keys(const or_options_t *options, const time_t now)
{
- return (!master_identity_key ||
- !master_signing_key ||
- !current_link_key ||
- !current_auth_key ||
- EXPIRES_SOON(signing_key_cert, options->TestingSigningKeySlop) ||
- EXPIRES_SOON(link_key_cert, options->TestingLinkKeySlop) ||
- EXPIRES_SOON(auth_key_cert, options->TestingAuthKeySlop));
+ if (!master_identity_key ||
+ !master_signing_key ||
+ !current_auth_key ||
+ !link_cert_cert ||
+ EXPIRES_SOON(signing_key_cert, options->TestingSigningKeySlop) ||
+ EXPIRES_SOON(auth_key_cert, options->TestingAuthKeySlop) ||
+ EXPIRES_SOON(link_cert_cert, options->TestingLinkKeySlop))
+ return 1;
+
+ const tor_x509_cert_t *link = NULL, *id = NULL;
+
+ if (tor_tls_get_my_certs(1, &link, &id) < 0 || link == NULL)
+ return 1;
+
+ const digests_t *digests = tor_x509_cert_get_cert_digests(link);
+
+ if (!fast_memeq(digests->d[DIGEST_SHA256],
+ link_cert_cert->signed_key.pubkey,
+ DIGEST256_LEN)) {
+ return 1;
+ }
+
+ return 0;
}
#undef EXPIRES_SOON
@@ -472,21 +520,15 @@ get_master_signing_key_cert(void)
}
const ed25519_keypair_t *
-get_current_link_keypair(void)
-{
- return current_link_key;
-}
-
-const ed25519_keypair_t *
get_current_auth_keypair(void)
{
return current_auth_key;
}
const tor_cert_t *
-get_current_link_key_cert(void)
+get_current_link_cert_cert(void)
{
- return link_key_cert;
+ return link_cert_cert;
}
const tor_cert_t *
@@ -495,6 +537,14 @@ get_current_auth_key_cert(void)
return auth_key_cert;
}
+void
+get_master_rsa_crosscert(const uint8_t **cert_out,
+ size_t *size_out)
+{
+ *cert_out = rsa_ed_crosscert;
+ *size_out = rsa_ed_crosscert_len;
+}
+
/** Construct cross-certification for the master identity key with
* the ntor onion key. Store the sign of the corresponding ed25519 public key
* in *<b>sign_out</b>. */
@@ -587,14 +637,13 @@ routerkeys_free_all(void)
{
ed25519_keypair_free(master_identity_key);
ed25519_keypair_free(master_signing_key);
- ed25519_keypair_free(current_link_key);
ed25519_keypair_free(current_auth_key);
tor_cert_free(signing_key_cert);
- tor_cert_free(link_key_cert);
+ tor_cert_free(link_cert_cert);
tor_cert_free(auth_key_cert);
master_identity_key = master_signing_key = NULL;
- current_link_key = current_auth_key = NULL;
- signing_key_cert = link_key_cert = auth_key_cert = NULL;
+ current_auth_key = NULL;
+ signing_key_cert = link_cert_cert = auth_key_cert = NULL;
}
diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h
index 0c50429..b45a22a 100644
--- a/src/or/routerkeys.h
+++ b/src/or/routerkeys.h
@@ -33,11 +33,13 @@ const ed25519_public_key_t *get_master_identity_key(void);
const ed25519_keypair_t *get_master_signing_keypair(void);
const struct tor_cert_st *get_master_signing_key_cert(void);
-const ed25519_keypair_t *get_current_link_keypair(void);
const ed25519_keypair_t *get_current_auth_keypair(void);
-const struct tor_cert_st *get_current_link_key_cert(void);
+const struct tor_cert_st *get_current_link_cert_cert(void);
const struct tor_cert_st *get_current_auth_key_cert(void);
+void get_master_rsa_crosscert(const uint8_t **cert_out,
+ size_t *size_out);
+
struct tor_cert_st *make_ntor_onion_key_crosscert(
const curve25519_keypair_t *onion_key,
const ed25519_public_key_t *master_id_key,
@@ -57,6 +59,8 @@ int check_tap_onion_key_crosscert(const uint8_t *crosscert,
int load_ed_keys(const or_options_t *options, time_t now);
int should_make_new_ed_keys(const or_options_t *options, const time_t now);
+int generate_ed_link_cert(const or_options_t *options, time_t now);
+
void routerkeys_free_all(void);
#endif
diff --git a/src/or/torcert.c b/src/or/torcert.c
index 1534730..e2ddffd 100644
--- a/src/or/torcert.c
+++ b/src/or/torcert.c
@@ -1,12 +1,13 @@
/* Copyright (c) 2014, The Tor Project, Inc. */
/* See LICENSE for licensing information */
-#include "torcert.h"
#include "crypto.h"
+#include "torcert.h"
#include "ed25519_cert.h"
#include "torlog.h"
#include "util.h"
#include "compat.h"
+#include "link_handshake.h"
/** Helper for tor_cert_create(): signs any 32 bytes, not just an ed25519
* key.
@@ -237,3 +238,43 @@ tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2)
return 0;
return tor_cert_eq(cert1, cert2);
}
+
+/** Create new cross-certification object to certify <b>ed_key</b> as the
+ * master ed25519 identity key for the RSA identity key <b>rsa_key</b>.
+ * Allocates and stores the encoded certificate in *<b>cert</b>, and returns
+ * the number of bytes stored. Returns negative on error.*/
+ssize_t
+tor_make_rsa_ed25519_crosscert(const ed25519_public_key_t *ed_key,
+ const crypto_pk_t *rsa_key,
+ time_t expires,
+ uint8_t **cert)
+{
+ uint8_t *res;
+
+ rsa_ed_crosscert_t *cc = rsa_ed_crosscert_new();
+ memcpy(cc->ed_key, ed_key->pubkey, ED25519_PUBKEY_LEN);
+ cc->expiration = (uint32_t) CEIL_DIV(expires, 3600);
+ cc->sig_len = crypto_pk_keysize(rsa_key);
+ rsa_ed_crosscert_setlen_sig(cc, crypto_pk_keysize(rsa_key));
+
+ ssize_t alloc_sz = rsa_ed_crosscert_encoded_len(cc);
+ tor_assert(alloc_sz > 0);
+ res = tor_malloc_zero(alloc_sz);
+ ssize_t sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
+ tor_assert(sz > 0 && sz <= alloc_sz);
+
+ const int signed_part_len = 32 + 4;
+ int siglen = crypto_pk_private_sign(rsa_key,
+ (char*)rsa_ed_crosscert_getarray_sig(cc),
+ rsa_ed_crosscert_getlen_sig(cc),
+ (char*)res, signed_part_len);
+ tor_assert(siglen > 0 && siglen <= (int)crypto_pk_keysize(rsa_key));
+ tor_assert(siglen <= UINT8_MAX);
+ cc->sig_len = siglen;
+ rsa_ed_crosscert_setlen_sig(cc, siglen);
+
+ sz = rsa_ed_crosscert_encode(res, alloc_sz, cc);
+ rsa_ed_crosscert_free(cc);
+ *cert = res;
+ return sz;
+}
diff --git a/src/or/torcert.h b/src/or/torcert.h
index 4680ca6..b67dc52 100644
--- a/src/or/torcert.h
+++ b/src/or/torcert.h
@@ -67,5 +67,10 @@ tor_cert_t *tor_cert_dup(const tor_cert_t *cert);
int tor_cert_eq(const tor_cert_t *cert1, const tor_cert_t *cert2);
int tor_cert_opt_eq(const tor_cert_t *cert1, const tor_cert_t *cert2);
+ssize_t tor_make_rsa_ed25519_crosscert(const ed25519_public_key_t *ed_key,
+ const crypto_pk_t *rsa_key,
+ time_t expires,
+ uint8_t **cert);
+
#endif
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index 4917424..06fc4ee 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -416,12 +416,21 @@ test_routerkeys_ed_keys_init_all(void *arg)
or_options_t *options = tor_malloc_zero(sizeof(or_options_t));
time_t now = time(NULL);
ed25519_public_key_t id;
- ed25519_keypair_t sign, link, auth;
- // tor_cert_t *cert_is, *cert_sl, *cert_auth;
+ ed25519_keypair_t sign, auth;
+ tor_cert_t *link_cert = NULL;
+
+ get_options_mutable()->ORPort_set = 1;
+
+ crypto_pk_t *rsa = pk_generate(0);
+
+ set_server_identity_key(rsa);
+ set_client_identity_key(rsa);
+
+ router_initialize_tls_context();
options->SigningKeyLifetime = 30*86400;
options->TestingAuthKeyLifetime = 2*86400;
- options->TestingLinkKeyLifetime = 2*86400;
+ options->TestingLinkCertLifetime = 2*86400;
options->TestingSigningKeySlop = 2*86400;
options->TestingAuthKeySlop = 2*3600;
options->TestingLinkKeySlop = 2*3600;
@@ -440,59 +449,61 @@ test_routerkeys_ed_keys_init_all(void *arg)
tt_assert(get_master_identity_key());
tt_assert(get_master_identity_key());
tt_assert(get_master_signing_keypair());
- tt_assert(get_current_link_keypair());
tt_assert(get_current_auth_keypair());
tt_assert(get_master_signing_key_cert());
- tt_assert(get_current_link_key_cert());
+ tt_assert(get_current_link_cert_cert());
tt_assert(get_current_auth_key_cert());
memcpy(&id, get_master_identity_key(), sizeof(id));
memcpy(&sign, get_master_signing_keypair(), sizeof(sign));
- memcpy(&link, get_current_link_keypair(), sizeof(link));
memcpy(&auth, get_current_auth_keypair(), sizeof(auth));
+ link_cert = tor_cert_dup(get_current_link_cert_cert());
/* Call load_ed_keys again, but nothing has changed. */
tt_int_op(0, ==, load_ed_keys(options, now));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
- tt_mem_op(&link, ==, get_current_link_keypair(), sizeof(link));
tt_mem_op(&auth, ==, get_current_auth_keypair(), sizeof(auth));
+ tt_assert(tor_cert_eq(link_cert, get_current_link_cert_cert()));
/* Force a reload: we make new link/auth keys. */
routerkeys_free_all();
tt_int_op(0, ==, load_ed_keys(options, now));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
- tt_mem_op(&link, !=, get_current_link_keypair(), sizeof(link));
+ tt_assert(tor_cert_eq(link_cert, get_current_link_cert_cert()));
tt_mem_op(&auth, !=, get_current_auth_keypair(), sizeof(auth));
tt_assert(get_master_signing_key_cert());
- tt_assert(get_current_link_key_cert());
+ tt_assert(get_current_link_cert_cert());
tt_assert(get_current_auth_key_cert());
- memcpy(&link, get_current_link_keypair(), sizeof(link));
+ tor_cert_free(link_cert);
+ link_cert = tor_cert_dup(get_current_link_cert_cert());
memcpy(&auth, get_current_auth_keypair(), sizeof(auth));
/* Force a link/auth-key regeneration by advancing time. */
tt_int_op(0, ==, load_ed_keys(options, now+3*86400));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
- tt_mem_op(&link, !=, get_current_link_keypair(), sizeof(link));
+ tt_assert(! tor_cert_eq(link_cert, get_current_link_cert_cert()));
tt_mem_op(&auth, !=, get_current_auth_keypair(), sizeof(auth));
tt_assert(get_master_signing_key_cert());
- tt_assert(get_current_link_key_cert());
+ tt_assert(get_current_link_cert_cert());
tt_assert(get_current_auth_key_cert());
- memcpy(&link, get_current_link_keypair(), sizeof(link));
+ tor_cert_free(link_cert);
+ link_cert = tor_cert_dup(get_current_link_cert_cert());
memcpy(&auth, get_current_auth_keypair(), sizeof(auth));
/* Force a signing-key regeneration by advancing time. */
tt_int_op(0, ==, load_ed_keys(options, now+100*86400));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, !=, get_master_signing_keypair(), sizeof(sign));
- tt_mem_op(&link, !=, get_current_link_keypair(), sizeof(link));
+ tt_assert(! tor_cert_eq(link_cert, get_current_link_cert_cert()));
tt_mem_op(&auth, !=, get_current_auth_keypair(), sizeof(auth));
tt_assert(get_master_signing_key_cert());
- tt_assert(get_current_link_key_cert());
+ tt_assert(get_current_link_cert_cert());
tt_assert(get_current_auth_key_cert());
memcpy(&sign, get_master_signing_keypair(), sizeof(sign));
- memcpy(&link, get_current_link_keypair(), sizeof(link));
+ tor_cert_free(link_cert);
+ link_cert = tor_cert_dup(get_current_link_cert_cert());
memcpy(&auth, get_current_auth_keypair(), sizeof(auth));
/* Demonstrate that we can start up with no secret identity key */
@@ -502,10 +513,10 @@ test_routerkeys_ed_keys_init_all(void *arg)
tt_int_op(0, ==, load_ed_keys(options, now));
tt_mem_op(&id, ==, get_master_identity_key(), sizeof(id));
tt_mem_op(&sign, ==, get_master_signing_keypair(), sizeof(sign));
- tt_mem_op(&link, !=, get_current_link_keypair(), sizeof(link));
+ tt_assert(! tor_cert_eq(link_cert, get_current_link_cert_cert()));
tt_mem_op(&auth, !=, get_current_auth_keypair(), sizeof(auth));
tt_assert(get_master_signing_key_cert());
- tt_assert(get_current_link_key_cert());
+ tt_assert(get_current_link_cert_cert());
tt_assert(get_current_auth_key_cert());
/* But we're in trouble if we have no id key and our signing key has
1
0
commit 1b52e95028e0d84b7a112e4b8f2e393261dbb19c
Merge: 0989ba3 5eb584e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu May 28 11:04:33 2015 -0400
Merge branch '12498_ed25519_keys_v6'
Fixed numerous conflicts, and ported code to use new base64 api.
doc/tor.1.txt | 24 +
scripts/codegen/makedesc.py | 355 ++++---
scripts/codegen/run_trunnel.sh | 4 +-
src/common/container.c | 13 +
src/common/container.h | 1 +
src/common/crypto.c | 102 +-
src/common/crypto.h | 20 +-
src/common/crypto_ed25519.c | 21 +
src/common/crypto_ed25519.h | 19 +-
src/common/crypto_format.c | 39 +
src/common/tortls.c | 76 +-
src/common/tortls.h | 29 +-
src/or/channel.c | 8 +-
src/or/channel.h | 5 +-
src/or/channeltls.c | 161 ++-
src/or/channeltls.h | 10 +
src/or/config.c | 20 +
src/or/config.h | 4 +
src/or/connection_or.c | 180 ++--
src/or/connection_or.h | 12 +-
src/or/dircollate.c | 257 +++++
src/or/dircollate.h | 49 +
src/or/dirserv.c | 79 ++
src/or/dirvote.c | 87 +-
src/or/dirvote.h | 9 +-
src/or/include.am | 20 +-
src/or/keypin.c | 419 ++++++++
src/or/keypin.h | 46 +
src/or/main.c | 38 +-
src/or/microdesc.c | 1 +
src/or/or.h | 41 +-
src/or/router.c | 242 ++++-
src/or/router.h | 8 +-
src/or/routerkeys.c | 648 +++++++++++++
src/or/routerkeys.h | 67 ++
src/or/routerlist.c | 27 +-
src/or/routerlist.h | 7 +-
src/or/routerparse.c | 310 +++++-
src/or/routerparse.h | 4 +-
src/or/torcert.c | 280 ++++++
src/or/torcert.h | 76 ++
src/test/example_extrainfo.inc | 233 +++++
src/test/failing_routerdescs.inc | 901 +++++++++++++++++
src/test/include.am | 6 +-
src/test/test.c | 4 +
src/test/test_containers.c | 38 +
src/test/test_crypto.c | 20 +-
src/test/test_dir.c | 133 ++-
src/test/test_keypin.c | 255 +++++
src/test/test_link_handshake.c | 914 +++++++++++++++++
src/test/test_microdesc.c | 93 ++
src/test/test_routerkeys.c | 540 ++++++++++-
src/trunnel/ed25519_cert.c | 887 +++++++++++++++++
src/trunnel/ed25519_cert.h | 288 ++++++
src/trunnel/ed25519_cert.trunnel | 76 ++
src/trunnel/include.am | 21 +-
src/trunnel/link_handshake.c | 1885 ++++++++++++++++++++++++++++++++++++
src/trunnel/link_handshake.h | 654 +++++++++++++
src/trunnel/link_handshake.trunnel | 57 ++
59 files changed, 10365 insertions(+), 458 deletions(-)
diff --cc src/common/crypto.c
index fcd862f,2ccff80..d77d5e2
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@@ -2588,93 -2711,76 +2607,152 @@@ base64_encode(char *dest, size_t destle
return -1;
if (destlen > SIZE_T_CEILING)
return -1;
- if (destlen)
- *dest = 0; /* Ensure we always initialize the buffer */
-
- EVP_EncodeInit(&ctx);
- EVP_EncodeUpdate(&ctx, (unsigned char*)dest, &len,
- (unsigned char*)src, (int)srclen);
- EVP_EncodeFinal(&ctx, (unsigned char*)(dest+len), &ret);
- ret += len;
- return ret;
+ if (enclen > INT_MAX)
+ return -1;
+
+ memset(dest, 0, enclen);
+
+ /* XXX/Yawning: If this ends up being too slow, this can be sped up
+ * by separating the multiline format case and the normal case, and
+ * processing 48 bytes of input at a time when newlines are desired.
+ */
+#define ENCODE_CHAR(ch) \
+ STMT_BEGIN \
+ *d++ = ch; \
+ if (flags & BASE64_ENCODE_MULTILINE) { \
+ if (++linelen % BASE64_OPENSSL_LINELEN == 0) { \
+ linelen = 0; \
+ *d++ = '\n'; \
+ } \
+ } \
+ STMT_END
+
+#define ENCODE_N(idx) \
+ ENCODE_CHAR(base64_encode_table[(n >> ((3 - idx) * 6)) & 0x3f])
+
+#define ENCODE_PAD() ENCODE_CHAR('=')
+
+ /* Iterate over all the bytes in src. Each one will add 8 bits to the
+ * value we're encoding. Accumulate bits in <b>n</b>, and whenever we
+ * have 24 bits, batch them into 4 bytes and flush those bytes to dest.
+ */
+ for ( ; usrc < eous; ++usrc) {
+ n = (n << 8) | *usrc;
+ if ((++n_idx) == 3) {
+ ENCODE_N(0);
+ ENCODE_N(1);
+ ENCODE_N(2);
+ ENCODE_N(3);
+ n_idx = 0;
+ n = 0;
+ }
+ }
+ switch (n_idx) {
+ case 0:
+ /* 0 leftover bits, no pading to add. */
+ break;
+ case 1:
+ /* 8 leftover bits, pad to 12 bits, write the 2 6-bit values followed
+ * by 2 padding characters.
+ */
+ n <<= 4;
+ ENCODE_N(2);
+ ENCODE_N(3);
+ ENCODE_PAD();
+ ENCODE_PAD();
+ break;
+ case 2:
+ /* 16 leftover bits, pad to 18 bits, write the 3 6-bit values followed
+ * by 1 padding character.
+ */
+ n <<= 2;
+ ENCODE_N(1);
+ ENCODE_N(2);
+ ENCODE_N(3);
+ ENCODE_PAD();
+ break;
+ default:
+ /* Something went catastrophically wrong. */
+ tor_fragile_assert();
+ return -1;
+ }
+
+#undef ENCODE_N
+#undef ENCODE_PAD
+#undef ENCODE_CHAR
+
+ /* Multiline output always includes at least one newline. */
+ if (flags & BASE64_ENCODE_MULTILINE && linelen != 0)
+ *d++ = '\n';
+
+ tor_assert(d - dest == (ptrdiff_t)enclen);
+
+ *d++ = '\0'; /* NUL terminate the output. */
+
+ return (int) enclen;
}
+ /** As base64_encode, but do not add any internal spaces or external padding
+ * to the output stream. */
+ int
+ base64_encode_nopad(char *dest, size_t destlen,
+ const uint8_t *src, size_t srclen)
+ {
- int n = base64_encode(dest, destlen, (const char*) src, srclen);
++ int n = base64_encode(dest, destlen, (const char*) src, srclen, 0);
+ if (n <= 0)
+ return n;
+ tor_assert((size_t)n < destlen && dest[n] == 0);
+ char *in, *out;
+ in = out = dest;
+ while (*in) {
+ if (*in == '=' || *in == '\n') {
+ ++in;
+ } else {
+ *out++ = *in++;
+ }
+ }
+ *out = 0;
+
+ tor_assert(out - dest <= INT_MAX);
+
+ return (int)(out - dest);
+ }
+
+ /** As base64_decode, but do not require any padding on the input */
+ int
+ base64_decode_nopad(uint8_t *dest, size_t destlen,
+ const char *src, size_t srclen)
+ {
+ if (srclen > SIZE_T_CEILING - 4)
+ return -1;
+ char *buf = tor_malloc(srclen + 4);
+ memcpy(buf, src, srclen+1);
+ size_t buflen;
+ switch (srclen % 4)
+ {
+ case 0:
+ default:
+ buflen = srclen;
+ break;
+ case 1:
+ tor_free(buf);
+ return -1;
+ case 2:
+ memcpy(buf+srclen, "==", 3);
+ buflen = srclen + 2;
+ break;
+ case 3:
+ memcpy(buf+srclen, "=", 2);
+ buflen = srclen + 1;
+ break;
+ }
+ int n = base64_decode((char*)dest, destlen, buf, buflen);
+ tor_free(buf);
+ return n;
+ }
+
+#undef BASE64_OPENSSL_LINELEN
+
/** @{ */
/** Special values used for the base64_decode_table */
#define X 255
@@@ -2795,8 -2922,9 +2873,9 @@@ base64_decode(char *dest, size_t destle
#undef PAD
/** Base64 encode DIGEST_LINE bytes from <b>digest</b>, remove the trailing =
- * and newline characters, and store the nul-terminated result in the first
+ * characters, and store the nul-terminated result in the first
* BASE64_DIGEST_LEN+1 bytes of <b>d64</b>. */
+ /* XXXX unify with crypto_format.c code */
int
digest_to_base64(char *d64, const char *digest)
{
@@@ -2820,8 -2961,10 +2900,9 @@@ digest_from_base64(char *digest, const
}
/** Base64 encode DIGEST256_LINE bytes from <b>digest</b>, remove the
- * trailing = and newline characters, and store the nul-terminated result in
- * the first BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
-/* XXXX unify with crypto_format.c code */
+ * trailing = characters, and store the nul-terminated result in the first
- * BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
++ * BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
++ /* XXXX unify with crypto_format.c code */
int
digest256_to_base64(char *d64, const char *digest)
{
diff --cc src/common/crypto.h
index 05572f4,15d1f6e..b953ab9
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@@ -273,11 -273,13 +278,16 @@@ struct smartlist_t
void *smartlist_choose(const struct smartlist_t *sl);
void smartlist_shuffle(struct smartlist_t *sl);
-int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen);
+#define BASE64_ENCODE_MULTILINE 1
+size_t base64_encode_size(size_t srclen, int flags);
+int base64_encode(char *dest, size_t destlen, const char *src, size_t srclen,
+ int flags);
int base64_decode(char *dest, size_t destlen, const char *src, size_t srclen);
+ int base64_encode_nopad(char *dest, size_t destlen,
+ const uint8_t *src, size_t srclen);
+ int base64_decode_nopad(uint8_t *dest, size_t destlen,
+ const char *src, size_t srclen);
+
/** Characters that can appear (case-insensitively) in a base32 encoding. */
#define BASE32_CHARS "abcdefghijklmnopqrstuvwxyz234567"
void base32_encode(char *dest, size_t destlen, const char *src, size_t srclen);
diff --cc src/common/tortls.c
index 2b8daaa,e498b2a..098df9d
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@@ -116,8 -114,15 +116,8 @@@
#define SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x0010
#endif
-/** Does the run-time openssl version look like we need
- * SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */
-static int use_unsafe_renegotiation_op = 0;
-/** Does the run-time openssl version look like we need
- * SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION? */
-static int use_unsafe_renegotiation_flag = 0;
-
/** Structure that we use for a single certificate. */
- struct tor_cert_t {
+ struct tor_x509_cert_t {
X509 *cert;
uint8_t *encoded;
size_t encoded_len;
diff --cc src/or/channeltls.c
index 1cf697c,0376e74..ecf0218
--- a/src/or/channeltls.c
+++ b/src/or/channeltls.c
@@@ -22,8 -24,8 +24,9 @@@
#include "connection.h"
#include "connection_or.h"
#include "control.h"
+ #include "link_handshake.h"
#include "relay.h"
+#include "rephist.h"
#include "router.h"
#include "routerlist.h"
#include "scheduler.h"
diff --cc src/or/include.am
index 0ce3cdc,9245ade..6bbf788
--- a/src/or/include.am
+++ b/src/or/include.am
@@@ -77,18 -80,19 +80,14 @@@ LIBTOR_A_SOURCES =
src/or/scheduler.c \
src/or/statefile.c \
src/or/status.c \
+ src/or/torcert.c \
src/or/onion_ntor.c \
$(evdns_source) \
- $(tor_platform_source) \
- src/or/config_codedigest.c
+ $(tor_platform_source)
src_or_libtor_a_SOURCES = $(LIBTOR_A_SOURCES)
src_or_libtor_testing_a_SOURCES = $(LIBTOR_A_SOURCES)
- #libtor_a_LIBADD = $(top_builddir)/common/libor.a \
- # $(top_builddir)/common/libor-crypto.a \
- # $(top_builddir)/common/libor-event.a
-
-
-#libtor_a_LIBADD = ../common/libor.a ../common/libor-crypto.a \
-# ../common/libor-event.a
-#src_or_libtor_a_LIBADD = src/trunnel/libor-trunnel.a
-
src_or_tor_SOURCES = src/or/tor_main.c
AM_CPPFLAGS += -I$(srcdir)/src/or -Isrc/or
@@@ -120,12 -124,12 +119,12 @@@ src_or_tor_cov_CFLAGS = $(AM_CFLAGS) $(
src_or_tor_cov_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
src_or_tor_cov_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \
src/common/libor-crypto-testing.a $(LIBDONNA) \
- src/common/libor-event-testing.a \
+ src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
@TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@
-TESTING_TOR_BINARY = ./src/or/tor-cov
+TESTING_TOR_BINARY = $(top_builddir)/src/or/tor-cov
else
-TESTING_TOR_BINARY = ./src/or/tor
+TESTING_TOR_BINARY = $(top_builddir)/src/or/tor
endif
ORHEADERS = \
diff --cc src/or/main.c
index 74e6b33,4fac17a..bbee8e0
--- a/src/or/main.c
+++ b/src/or/main.c
@@@ -1200,46 -1205,7 +1202,49 @@@ get_signewnym_epoch(void
return newnym_epoch;
}
-static time_t time_to_check_descriptor = 0;
+typedef struct {
+ time_t last_rotated_x509_certificate;
+ time_t check_v3_certificate;
+ time_t check_listeners;
+ time_t download_networkstatus;
+ time_t try_getting_descriptors;
+ time_t reset_descriptor_failures;
+ time_t add_entropy;
+ time_t write_bridge_status_file;
+ time_t downrate_stability;
+ time_t save_stability;
+ time_t clean_caches;
+ time_t recheck_bandwidth;
+ time_t check_for_expired_networkstatus;
+ time_t write_stats_files;
+ time_t write_bridge_stats;
+ time_t check_port_forwarding;
+ time_t launch_reachability_tests;
+ time_t retry_dns_init;
+ time_t next_heartbeat;
+ time_t check_descriptor;
+ /** When do we next launch DNS wildcarding checks? */
+ time_t check_for_correct_dns;
++ /** When do we next make sure our Ed25519 keys aren't about to expire? */
++ time_t check_ed_keys;
++
+} time_to_t;
+
+static time_to_t time_to = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/** Reset all the time_to's so we'll do all our actions again as if we
+ * just started up.
+ * Useful if our clock just moved back a long time from the future,
+ * so we don't wait until that future arrives again before acting.
+ */
+void
+reset_all_main_loop_timers(void)
+{
+ memset(&time_to, 0, sizeof(time_to));
+}
+
/**
* Update our schedule so that we'll check whether we need to update our
* descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL
@@@ -1297,8 -1282,20 +1302,20 @@@ run_scheduled_events(time_t now
router_upload_dir_desc_to_dirservers(0);
}
- if (is_server && time_to_check_ed_keys < now) {
++ if (is_server && time_to.check_ed_keys < now) {
+ if (should_make_new_ed_keys(options, now)) {
+ if (load_ed_keys(options, now) < 0 ||
+ generate_ed_link_cert(options, now)) {
+ log_err(LD_OR, "Unable to update Ed25519 keys! Exiting.");
+ tor_cleanup();
+ exit(0);
+ }
+ }
- time_to_check_ed_keys = now + 30;
++ time_to.check_ed_keys = now + 30;
+ }
+
if (!should_delay_dir_fetches(options, NULL) &&
- time_to_try_getting_descriptors < now) {
+ time_to.try_getting_descriptors < now) {
update_all_descriptor_downloads(now);
update_extrainfo_downloads(now);
if (router_have_minimum_dir_info())
diff --cc src/or/router.c
index 24b7c75,00cd057..6532f97
--- a/src/or/router.c
+++ b/src/or/router.c
@@@ -2358,6 -2372,21 +2403,22 @@@ router_dump_router_to_string(routerinfo
goto err;
}
+ if (emit_ed_sigs) {
+ /* Encode ed25519 signing cert */
+ char ed_cert_base64[256];
+ if (base64_encode(ed_cert_base64, sizeof(ed_cert_base64),
+ (const char*)router->signing_key_cert->encoded,
- router->signing_key_cert->encoded_len) < 0) {
++ router->signing_key_cert->encoded_len,
++ BASE64_ENCODE_MULTILINE) < 0) {
+ log_err(LD_BUG,"Couldn't base64-encode signing key certificate!");
+ goto err;
+ }
+ tor_asprintf(&ed_cert_line, "identity-ed25519\n"
+ "-----BEGIN ED25519 CERT-----\n"
+ "%s"
+ "-----END ED25519 CERT-----\n", ed_cert_base64);
+ }
+
/* PEM-encode the onion key */
if (crypto_pk_write_public_key_to_string(router->onion_pkey,
&onion_pkey,&onion_pkeylen)<0) {
@@@ -2372,6 -2401,67 +2433,69 @@@
goto err;
}
+ /* Cross-certify with RSA key */
+ if (tap_key && router->signing_key_cert &&
+ router->signing_key_cert->signing_key_included) {
+ char buf[256];
+ int tap_cc_len = 0;
+ uint8_t *tap_cc =
+ make_tap_onion_key_crosscert(tap_key,
+ &router->signing_key_cert->signing_key,
+ router->identity_pkey,
+ &tap_cc_len);
+ if (!tap_cc) {
+ log_warn(LD_BUG,"make_tap_onion_key_crosscert failed!");
+ goto err;
+ }
+
- if (base64_encode(buf, sizeof(buf), (const char*)tap_cc, tap_cc_len) < 0) {
++ if (base64_encode(buf, sizeof(buf), (const char*)tap_cc, tap_cc_len,
++ BASE64_ENCODE_MULTILINE) < 0) {
+ log_warn(LD_BUG,"base64_encode(rsa_crosscert) failed!");
+ tor_free(tap_cc);
+ goto err;
+ }
+ tor_free(tap_cc);
+
+ tor_asprintf(&rsa_tap_cc_line,
+ "onion-key-crosscert\n"
+ "-----BEGIN CROSSCERT-----\n"
+ "%s"
+ "-----END CROSSCERT-----\n", buf);
+ }
+
+ /* Cross-certify with onion keys */
+ if (ntor_keypair && router->signing_key_cert &&
+ router->signing_key_cert->signing_key_included) {
+ int sign = 0;
+ char buf[256];
+ /* XXXX Base the expiration date on the actual onion key expiration time?*/
+ tor_cert_t *cert =
+ make_ntor_onion_key_crosscert(ntor_keypair,
+ &router->signing_key_cert->signing_key,
+ router->cache_info.published_on,
+ MIN_ONION_KEY_LIFETIME, &sign);
+ if (!cert) {
+ log_warn(LD_BUG,"make_ntor_onion_key_crosscert failed!");
+ goto err;
+ }
+ tor_assert(sign == 0 || sign == 1);
+
+ if (base64_encode(buf, sizeof(buf),
- (const char*)cert->encoded, cert->encoded_len)<0) {
++ (const char*)cert->encoded, cert->encoded_len,
++ BASE64_ENCODE_MULTILINE)<0) {
+ log_warn(LD_BUG,"base64_encode(ntor_crosscert) failed!");
+ tor_cert_free(cert);
+ goto err;
+ }
+ tor_cert_free(cert);
+
+ tor_asprintf(&ntor_cc_line,
+ "ntor-onion-key-crosscert %d\n"
+ "-----BEGIN ED25519 CERT-----\n"
+ "%s"
+ "-----END ED25519 CERT-----\n", sign, buf);
+ }
+
/* Encode the publication time. */
format_iso_time(published, router->cache_info.published_on);
@@@ -2695,9 -2819,33 +2853,34 @@@ extrainfo_dump_to_string(char **s_out,
extrainfo->cache_info.identity_digest, DIGEST_LEN);
format_iso_time(published, extrainfo->cache_info.published_on);
bandwidth_usage = rep_hist_get_bandwidth_lines();
+ if (emit_ed_sigs) {
+ if (!extrainfo->signing_key_cert->signing_key_included ||
+ !ed25519_pubkey_eq(&extrainfo->signing_key_cert->signed_key,
+ &signing_keypair->pubkey)) {
+ log_warn(LD_BUG, "Tried to sign a extrainfo descriptor with a "
+ "mismatched ed25519 key chain %d",
+ extrainfo->signing_key_cert->signing_key_included);
+ goto err;
+ }
+ char ed_cert_base64[256];
+ if (base64_encode(ed_cert_base64, sizeof(ed_cert_base64),
+ (const char*)extrainfo->signing_key_cert->encoded,
- extrainfo->signing_key_cert->encoded_len) < 0) {
++ extrainfo->signing_key_cert->encoded_len,
++ BASE64_ENCODE_MULTILINE) < 0) {
+ log_err(LD_BUG,"Couldn't base64-encode signing key certificate!");
+ goto err;
+ }
+ tor_asprintf(&ed_cert_line, "identity-ed25519\n"
+ "-----BEGIN ED25519 CERT-----\n"
+ "%s"
+ "-----END ED25519 CERT-----\n", ed_cert_base64);
+ } else {
+ ed_cert_line = tor_strdup("");
+ }
- tor_asprintf(&pre, "extra-info %s %s\npublished %s\n%s",
+ tor_asprintf(&pre, "extra-info %s %s\n%spublished %s\n%s",
extrainfo->nickname, identity,
+ ed_cert_line,
published, bandwidth_usage);
tor_free(bandwidth_usage);
smartlist_add(chunks, pre);
diff --cc src/or/router.h
index 73b43bc,695cfd3..61b35d6
--- a/src/or/router.h
+++ b/src/or/router.h
@@@ -89,10 -89,12 +89,13 @@@ const uint8_t *router_get_my_id_digest(
int router_extrainfo_digest_is_me(const char *digest);
int router_is_me(const routerinfo_t *router);
int router_pick_published_address(const or_options_t *options, uint32_t *addr);
+int router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e);
int router_rebuild_descriptor(int force);
char *router_dump_router_to_string(routerinfo_t *router,
- crypto_pk_t *ident_key);
+ const crypto_pk_t *ident_key,
+ const crypto_pk_t *tap_key,
+ const curve25519_keypair_t *ntor_keypair,
+ const ed25519_keypair_t *signing_keypair);
char *router_dump_exit_policy_to_string(const routerinfo_t *router,
int include_ipv4,
int include_ipv6);
diff --cc src/or/routerlist.c
index fd09679,a531051..7eba13a
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@@ -37,7 -38,8 +38,9 @@@
#include "routerlist.h"
#include "routerparse.h"
#include "routerset.h"
-#include "../common/sandbox.h"
+#include "sandbox.h"
+ #include "torcert.h"
++
// #define DEBUG_ROUTERLIST
/****************************************************************************/
diff --cc src/test/test_crypto.c
index 7944864,15ba14b..6cba850
--- a/src/test/test_crypto.c
+++ b/src/test/test_crypto.c
@@@ -696,8 -618,9 +696,9 @@@ test_crypto_formats(void *arg
/* Base64 tests */
memset(data1, 6, 1024);
for (idx = 0; idx < 10; ++idx) {
- i = base64_encode(data2, 1024, data1, idx);
+ i = base64_encode(data2, 1024, data1, idx, 0);
tt_int_op(i, OP_GE, 0);
+ tt_int_op(i, OP_EQ, strlen(data2));
j = base64_decode(data3, 1024, data2, i);
tt_int_op(j,OP_EQ, idx);
tt_mem_op(data3,OP_EQ, data1, idx);
diff --cc src/test/test_dir.c
index a949f5d,5f68c34..3e9e955
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@@ -127,6 -133,22 +133,23 @@@ test_dir_formats(void *arg
ex2->prt_min = ex2->prt_max = 24;
r2 = tor_malloc_zero(sizeof(routerinfo_t));
r2->addr = 0x0a030201u; /* 10.3.2.1 */
+ ed25519_keypair_t kp1, kp2;
+ ed25519_secret_key_from_seed(&kp1.seckey,
+ (const uint8_t*)"YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY");
+ ed25519_public_key_generate(&kp1.pubkey, &kp1.seckey);
+ ed25519_secret_key_from_seed(&kp2.seckey,
+ (const uint8_t*)"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ ed25519_public_key_generate(&kp2.pubkey, &kp2.seckey);
+ r2->signing_key_cert = tor_cert_create(&kp1,
+ CERT_TYPE_ID_SIGNING,
+ &kp2.pubkey,
+ now, 86400,
+ CERT_FLAG_INCLUDE_SIGNING_KEY);
+ char cert_buf[256];
+ base64_encode(cert_buf, sizeof(cert_buf),
+ (const char*)r2->signing_key_cert->encoded,
- r2->signing_key_cert->encoded_len);
++ r2->signing_key_cert->encoded_len,
++ BASE64_ENCODE_MULTILINE);
r2->platform = tor_strdup(platform);
r2->cache_info.published_on = 5;
r2->or_port = 9005;
@@@ -215,19 -243,49 +244,52 @@@
strlcat(buf2, pk2_str, sizeof(buf2));
strlcat(buf2, "signing-key\n", sizeof(buf2));
strlcat(buf2, pk1_str, sizeof(buf2));
+ int rsa_cc_len;
+ rsa_cc = make_tap_onion_key_crosscert(pk2,
+ &kp1.pubkey,
+ pk1,
+ &rsa_cc_len);
+ tt_assert(rsa_cc);
- base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len);
++ base64_encode(cert_buf, sizeof(cert_buf), (char*)rsa_cc, rsa_cc_len,
++ BASE64_ENCODE_MULTILINE);
+ strlcat(buf2, "onion-key-crosscert\n"
+ "-----BEGIN CROSSCERT-----\n", sizeof(buf2));
+ strlcat(buf2, cert_buf, sizeof(buf2));
+ strlcat(buf2, "-----END CROSSCERT-----\n", sizeof(buf2));
+ int ntor_cc_sign;
+ ntor_cc = make_ntor_onion_key_crosscert(&r2_onion_keypair,
+ &kp1.pubkey,
+ r2->cache_info.published_on,
+ MIN_ONION_KEY_LIFETIME,
+ &ntor_cc_sign);
+ tt_assert(ntor_cc);
+ base64_encode(cert_buf, sizeof(cert_buf),
- (char*)ntor_cc->encoded, ntor_cc->encoded_len);
++ (char*)ntor_cc->encoded, ntor_cc->encoded_len,
++ BASE64_ENCODE_MULTILINE);
+ tor_snprintf(buf2+strlen(buf2), sizeof(buf2)-strlen(buf2),
+ "ntor-onion-key-crosscert %d\n"
+ "-----BEGIN ED25519 CERT-----\n"
+ "%s"
+ "-----END ED25519 CERT-----\n", ntor_cc_sign, cert_buf);
+
strlcat(buf2, "hidden-service-dir\n", sizeof(buf2));
- strlcat(buf2, "ntor-onion-key "
- "skyinAnvardNostarsNomoonNowindormistsorsnow=\n", sizeof(buf2));
+ strlcat(buf2, "ntor-onion-key ", sizeof(buf2));
+ base64_encode(cert_buf, sizeof(cert_buf),
- (const char*)r2_onion_keypair.pubkey.public_key, 32);
++ (const char*)r2_onion_keypair.pubkey.public_key, 32,
++ BASE64_ENCODE_MULTILINE);
+ strlcat(buf2, cert_buf, sizeof(buf2));
strlcat(buf2, "accept *:80\nreject 18.0.0.0/8:24\n", sizeof(buf2));
- strlcat(buf2, "router-signature\n", sizeof(buf2));
+ strlcat(buf2, "router-sig-ed25519 ", sizeof(buf2));
- buf = router_dump_router_to_string(r2, pk1);
+ buf = router_dump_router_to_string(r2, pk1, pk2, &r2_onion_keypair, &kp2);
+ tt_assert(buf);
buf[strlen(buf2)] = '\0'; /* Don't compare the sig; it's never the same
* twice */
- tt_str_op(buf,OP_EQ, buf2);
+
+ tt_str_op(buf, OP_EQ, buf2);
tor_free(buf);
- buf = router_dump_router_to_string(r2, pk1);
+ buf = router_dump_router_to_string(r2, pk1, NULL, NULL, NULL);
cp = buf;
rp2 = router_parse_entry_from_string((const char*)cp,NULL,1,0,NULL,NULL);
tt_assert(rp2);
1
0
commit 57189acd6f6b56a419d63a7acb012a9b8abac319
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Sun Mar 1 14:36:40 2015 +0100
# This is a combination of 2 commits.
# The first commit's message is:
Regenerate ed25519 keys when they will expire soon.
Also, have testing-level options to set the lifetimes and
expiration-tolerances of all key types, plus a non-testing-level
option to set the lifetime of any auto-generated signing key.
# The 2nd commit message will be skipped:
# fixup! Regenerate ed25519 keys when they will expire soon.
---
src/or/config.c | 20 ++++++++++++++++++++
src/or/main.c | 13 +++++++++++++
src/or/or.h | 15 +++++++++++++++
src/or/routerkeys.c | 34 ++++++++++++++++++++++++----------
src/or/routerkeys.h | 2 ++
src/test/test_routerkeys.c | 7 +++++++
6 files changed, 81 insertions(+), 10 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c
index 5ba8c99..34e7e76 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -298,6 +298,7 @@ static config_var_t option_vars_[] = {
VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL),
V(ServerTransportListenAddr, LINELIST, NULL),
V(ServerTransportOptions, LINELIST, NULL),
+ V(SigningKeyLifetime, INTERVAL, "30 days"),
V(Socks4Proxy, STRING, NULL),
V(Socks5Proxy, STRING, NULL),
V(Socks5ProxyUsername, STRING, NULL),
@@ -356,6 +357,13 @@ static config_var_t option_vars_[] = {
V(TestingTorNetwork, BOOL, "0"),
V(TestingMinExitFlagThreshold, MEMUNIT, "0"),
V(TestingMinFastFlagThreshold, MEMUNIT, "0"),
+
+ V(TestingLinkKeyLifetime, INTERVAL, "2 days"),
+ V(TestingAuthKeyLifetime, INTERVAL, "2 days"),
+ V(TestingLinkKeySlop, INTERVAL, "3 hours"),
+ V(TestingAuthKeySlop, INTERVAL, "3 hours"),
+ V(TestingSigningKeySlop, INTERVAL, "1 day"),
+
V(OptimisticData, AUTOBOOL, "auto"),
V(PortForwarding, BOOL, "0"),
V(PortForwardingHelper, FILENAME, "tor-fw-helper"),
@@ -3625,8 +3633,20 @@ options_validate(or_options_t *old_options, or_options_t *options,
CHECK_DEFAULT(TestingDescriptorMaxDownloadTries);
CHECK_DEFAULT(TestingMicrodescMaxDownloadTries);
CHECK_DEFAULT(TestingCertMaxDownloadTries);
+ CHECK_DEFAULT(TestingAuthKeyLifetime);
+ CHECK_DEFAULT(TestingLinkKeyLifetime);
+ CHECK_DEFAULT(TestingSigningKeySlop);
+ CHECK_DEFAULT(TestingAuthKeySlop);
+ CHECK_DEFAULT(TestingLinkKeySlop);
#undef CHECK_DEFAULT
+ if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
+ REJECT("SigningKeyLifetime is too short.");
+ if (options->TestingLinkKeyLifetime < options->TestingAuthKeySlop*2)
+ REJECT("LinkKeyLifetime is too short.");
+ if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
+ REJECT("AuthKeyLifetime is too short.");
+
if (options->TestingV3AuthInitialVotingInterval
< MIN_VOTE_INTERVAL_TESTING_INITIAL) {
REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
diff --git a/src/or/main.c b/src/or/main.c
index 70d075f..c4b5af4 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -134,6 +134,8 @@ time_t time_of_process_start = 0;
long stats_n_seconds_working = 0;
/** When do we next launch DNS wildcarding checks? */
static time_t time_to_check_for_correct_dns = 0;
+/** When do we next make sure our Ed25519 keys aren't about to expire? */
+static time_t time_to_check_ed_keys = 0;
/** How often will we honor SIGNEWNYM requests? */
#define MAX_SIGNEWNYM_RATE 10
@@ -1280,6 +1282,17 @@ run_scheduled_events(time_t now)
router_upload_dir_desc_to_dirservers(0);
}
+ if (is_server && time_to_check_ed_keys < now) {
+ if (should_make_new_ed_keys(options, now)) {
+ if (load_ed_keys(options, now) < 0) {
+ log_err(LD_OR, "Unable to update Ed25519 keys! Exiting.");
+ tor_cleanup();
+ exit(0);
+ }
+ }
+ time_to_check_ed_keys = now + 30;
+ }
+
if (!should_delay_dir_fetches(options, NULL) &&
time_to_try_getting_descriptors < now) {
update_all_descriptor_downloads(now);
diff --git a/src/or/or.h b/src/or/or.h
index b07a596..d45e19a 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -4261,6 +4261,21 @@ typedef struct {
* XXXX Eventually, the default will be 0. */
int ExitRelay;
+
+ /** For how long (seconds) do we declare our singning keys to be valid? */
+ int SigningKeyLifetime;
+ /** For how long (seconds) do we declare our link keys to be valid? */
+ int TestingLinkKeyLifetime;
+ /** For how long (seconds) do we declare our auth keys to be valid? */
+ int TestingAuthKeyLifetime;
+
+ /** How long before signing keys expire will we try to make a new one? */
+ int TestingSigningKeySlop;
+ /** How long before link keys expire will we try to make a new one? */
+ int TestingLinkKeySlop;
+ /** How long before auth keys expire will we try to make a new one? */
+ int TestingAuthKeySlop;
+
} or_options_t;
/** Persistent state for an onion router, as saved to disk. */
diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c
index ab12b90..2482f59 100644
--- a/src/or/routerkeys.c
+++ b/src/or/routerkeys.c
@@ -306,9 +306,6 @@ load_ed_keys(const or_options_t *options, time_t now)
/* XXXX support encrypted identity keys fully */
- /* XXXX use options. */
- (void) options;
-
/* First try to get the signing key to see how it is. */
if (master_signing_key) {
check_signing_cert = signing_key_cert;
@@ -329,7 +326,7 @@ load_ed_keys(const or_options_t *options, time_t now)
EXPIRES_SOON(check_signing_cert, 0);
const int want_new_signing_key =
need_new_signing_key ||
- EXPIRES_SOON(check_signing_cert, 86400/*???*/);
+ EXPIRES_SOON(check_signing_cert, options->TestingSigningKeySlop);
{
uint32_t flags =
@@ -365,7 +362,7 @@ load_ed_keys(const or_options_t *options, time_t now)
options_get_datadir_fname2(options, "keys", "ed25519_signing"),
flags, LOG_WARN,
sign_signing_key_with_id, now,
- 30*86400/*XXX option*/,
+ options->SigningKeyLifetime,
CERT_TYPE_ID_SIGNING, &sign_cert);
if (!sign)
FAIL("Missing signing key");
@@ -383,18 +380,22 @@ load_ed_keys(const or_options_t *options, time_t now)
* it, if we loaded it in the first place. */
memwipe(id->seckey.seckey, 0, sizeof(id->seckey));
- if (!current_link_key || EXPIRES_SOON(link_key_cert, 7200/*???*/)) {
+ if (!current_link_key ||
+ EXPIRES_SOON(link_key_cert, options->TestingLinkKeySlop)) {
link = ed_key_new(use_signing, INIT_ED_KEY_NEEDCERT,
- now, 2*86400/*XXX option??*/,
+ now,
+ options->TestingLinkKeyLifetime,
CERT_TYPE_SIGNING_LINK, &link_cert);
if (!link)
FAIL("Can't create link key");
}
- if (!current_auth_key || EXPIRES_SOON(auth_key_cert, 7200)/*???*/) {
+ if (!current_auth_key ||
+ EXPIRES_SOON(auth_key_cert, options->TestingAuthKeySlop)) {
auth = ed_key_new(use_signing, INIT_ED_KEY_NEEDCERT,
- now, 2*86400/*XXX option??*/,
+ now,
+ options->TestingAuthKeyLifetime,
CERT_TYPE_SIGNING_AUTH, &auth_cert);
if (!auth)
@@ -434,9 +435,22 @@ load_ed_keys(const or_options_t *options, time_t now)
#undef FAIL
#undef SET_KEY
#undef SET_CERT
-#undef EXPIRES_SOON
}
+int
+should_make_new_ed_keys(const or_options_t *options, const time_t now)
+{
+ return (!master_identity_key ||
+ !master_signing_key ||
+ !current_link_key ||
+ !current_auth_key ||
+ EXPIRES_SOON(signing_key_cert, options->TestingSigningKeySlop) ||
+ EXPIRES_SOON(link_key_cert, options->TestingLinkKeySlop) ||
+ EXPIRES_SOON(auth_key_cert, options->TestingAuthKeySlop));
+}
+
+#undef EXPIRES_SOON
+
const ed25519_public_key_t *
get_master_identity_key(void)
{
diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h
index 6c188b7..0c50429 100644
--- a/src/or/routerkeys.h
+++ b/src/or/routerkeys.h
@@ -55,6 +55,8 @@ int check_tap_onion_key_crosscert(const uint8_t *crosscert,
const uint8_t *rsa_id_digest);
int load_ed_keys(const or_options_t *options, time_t now);
+int should_make_new_ed_keys(const or_options_t *options, const time_t now);
+
void routerkeys_free_all(void);
#endif
diff --git a/src/test/test_routerkeys.c b/src/test/test_routerkeys.c
index 2434255..4917424 100644
--- a/src/test/test_routerkeys.c
+++ b/src/test/test_routerkeys.c
@@ -419,6 +419,13 @@ test_routerkeys_ed_keys_init_all(void *arg)
ed25519_keypair_t sign, link, auth;
// tor_cert_t *cert_is, *cert_sl, *cert_auth;
+ options->SigningKeyLifetime = 30*86400;
+ options->TestingAuthKeyLifetime = 2*86400;
+ options->TestingLinkKeyLifetime = 2*86400;
+ options->TestingSigningKeySlop = 2*86400;
+ options->TestingAuthKeySlop = 2*3600;
+ options->TestingLinkKeySlop = 2*3600;
+
#ifdef _WIN32
mkdir(dir);
mkdir(get_fname("test_ed_keys_init_all/keys"));
1
0

28 May '15
commit 277c9a3580db20a9814227531431433a37fe55b8
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue May 26 16:09:34 2015 -0400
Note some functions that should move or be merged
---
src/common/crypto.c | 4 ++++
src/common/crypto_ed25519.h | 4 +++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 05dc432..2ccff80 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -2924,6 +2924,7 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
/** Base64 encode DIGEST_LINE bytes from <b>digest</b>, remove the trailing =
* and newline characters, and store the nul-terminated result in the first
* BASE64_DIGEST_LEN+1 bytes of <b>d64</b>. */
+/* XXXX unify with crypto_format.c code */
int
digest_to_base64(char *d64, const char *digest)
{
@@ -2937,6 +2938,7 @@ digest_to_base64(char *d64, const char *digest)
/** Given a base64 encoded, nul-terminated digest in <b>d64</b> (without
* trailing newline or = characters), decode it and store the result in the
* first DIGEST_LEN bytes at <b>digest</b>. */
+/* XXXX unify with crypto_format.c code */
int
digest_from_base64(char *digest, const char *d64)
{
@@ -2962,6 +2964,7 @@ digest_from_base64(char *digest, const char *d64)
/** Base64 encode DIGEST256_LINE bytes from <b>digest</b>, remove the
* trailing = and newline characters, and store the nul-terminated result in
* the first BASE64_DIGEST256_LEN+1 bytes of <b>d64</b>. */
+/* XXXX unify with crypto_format.c code */
int
digest256_to_base64(char *d64, const char *digest)
{
@@ -2975,6 +2978,7 @@ digest256_to_base64(char *d64, const char *digest)
/** Given a base64 encoded, nul-terminated digest in <b>d64</b> (without
* trailing newline or = characters), decode it and store the result in the
* first DIGEST256_LEN bytes at <b>digest</b>. */
+/* XXXX unify with crypto_format.c code */
int
digest256_from_base64(char *digest, const char *d64)
{
diff --git a/src/common/crypto_ed25519.h b/src/common/crypto_ed25519.h
index 79b3db8..8ffb9f2 100644
--- a/src/common/crypto_ed25519.h
+++ b/src/common/crypto_ed25519.h
@@ -88,13 +88,15 @@ int ed25519_public_blind(ed25519_public_key_t *out,
const ed25519_public_key_t *inp,
const uint8_t *param);
-#define ED25519_BASE64_LEN 43
+/* XXXX move these to crypto_format.h */
+#define ED25519_BASE64_LEN 43
int ed25519_public_from_base64(ed25519_public_key_t *pkey,
const char *input);
int ed25519_public_to_base64(char *output,
const ed25519_public_key_t *pkey);
+/* XXXX move these to crypto_format.h */
#define ED25519_SIG_BASE64_LEN 86
int ed25519_signature_from_base64(ed25519_signature_t *sig,
1
0

28 May '15
commit 32f59d73372f5843ceb305a9d58387573d90f4f6
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu May 28 10:44:09 2015 -0400
Regenerate ed25519 keys when they will expire soon.
Also, have testing-level options to set the lifetimes and
expiration-tolerances of all key types, plus a non-testing-level
option to set the lifetime of any auto-generated signing key.
---
src/or/config.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/or/config.c b/src/or/config.c
index 34e7e76..07451b3 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -3643,9 +3643,9 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (options->SigningKeyLifetime < options->TestingSigningKeySlop*2)
REJECT("SigningKeyLifetime is too short.");
if (options->TestingLinkKeyLifetime < options->TestingAuthKeySlop*2)
- REJECT("LinkKeyLifetime is too short.");
+ REJECT("TestingLinkKeyLifetime is too short.");
if (options->TestingAuthKeyLifetime < options->TestingLinkKeySlop*2)
- REJECT("AuthKeyLifetime is too short.");
+ REJECT("TestingAuthKeyLifetime is too short.");
if (options->TestingV3AuthInitialVotingInterval
< MIN_VOTE_INTERVAL_TESTING_INITIAL) {
1
0