commit fae7060aea5c562fc59e7089b6a3459a5718b2d0 Author: Nick Mathewson nickm@torproject.org Date: Tue Aug 30 08:48:50 2016 -0400
Fix a misfeature with the Ed cert expiration API
The batch-verification helper didn't expose the expiration time, which made it pretty error-prone.
This closes ticket 15087. --- src/or/routerparse.c | 12 +++++------- src/or/torcert.c | 23 +++++++++++++++++------ src/or/torcert.h | 5 +++-- 3 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 03f8f4e..686ac48 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -2028,12 +2028,13 @@ router_parse_entry_from_string(const char *s, const char *end,
ed25519_checkable_t check[3]; int check_ok[3]; - if (tor_cert_get_checkable_sig(&check[0], cert, NULL) < 0) { + time_t expires = TIME_MAX; + if (tor_cert_get_checkable_sig(&check[0], cert, NULL, &expires) < 0) { log_err(LD_BUG, "Couldn't create 'checkable' for cert."); goto err; } if (tor_cert_get_checkable_sig(&check[1], - ntor_cc_cert, &ntor_cc_pk) < 0) { + ntor_cc_cert, &ntor_cc_pk, &expires) < 0) { log_err(LD_BUG, "Couldn't create 'checkable' for ntor_cc_cert."); goto err; } @@ -2063,10 +2064,7 @@ router_parse_entry_from_string(const char *s, const char *end, }
/* We check this before adding it to the routerlist. */ - if (cert->valid_until < ntor_cc_cert->valid_until) - router->cert_expiration_time = cert->valid_until; - else - router->cert_expiration_time = ntor_cc_cert->valid_until; + router->cert_expiration_time = expires; } }
@@ -2376,7 +2374,7 @@ extrainfo_parse_entry_from_string(const char *s, const char *end,
ed25519_checkable_t check[2]; int check_ok[2]; - if (tor_cert_get_checkable_sig(&check[0], cert, NULL) < 0) { + if (tor_cert_get_checkable_sig(&check[0], cert, NULL, NULL) < 0) { log_err(LD_BUG, "Couldn't create 'checkable' for cert."); goto err; } diff --git a/src/or/torcert.c b/src/or/torcert.c index b7ed7f8..2629155 100644 --- a/src/or/torcert.c +++ b/src/or/torcert.c @@ -166,11 +166,17 @@ tor_cert_parse(const uint8_t *encoded, const size_t len) }
/** Fill in <b>checkable_out</b> with the information needed to check - * the signature on <b>cert</b> with <b>pubkey</b>. */ + * the signature on <b>cert</b> with <b>pubkey</b>. + * + * On success, if <b>expiration_out</b> is provided, and it is some time + * _after_ the expiration time of this certificate, set it to the + * expiration time of this certificate. + */ int tor_cert_get_checkable_sig(ed25519_checkable_t *checkable_out, const tor_cert_t *cert, - const ed25519_public_key_t *pubkey) + const ed25519_public_key_t *pubkey, + time_t *expiration_out) { if (! pubkey) { if (cert->signing_key_included) @@ -187,6 +193,10 @@ tor_cert_get_checkable_sig(ed25519_checkable_t *checkable_out, memcpy(checkable_out->signature.sig, cert->encoded + signed_len, ED25519_SIG_LEN);
+ if (expiration_out) { + *expiration_out = MIN(*expiration_out, cert->valid_until); + } + return 0; }
@@ -201,14 +211,15 @@ tor_cert_checksig(tor_cert_t *cert, { ed25519_checkable_t checkable; int okay; + time_t expires = TIME_MAX;
- if (now && now > cert->valid_until) { - cert->cert_expired = 1; + if (tor_cert_get_checkable_sig(&checkable, cert, pubkey, &expires) < 0) return -1; - }
- if (tor_cert_get_checkable_sig(&checkable, cert, pubkey) < 0) + if (now && now > expires) { + cert->cert_expired = 1; return -1; + }
if (ed25519_checksig_batch(&okay, &checkable, 1) < 0) { cert->sig_bad = 1; diff --git a/src/or/torcert.h b/src/or/torcert.h index f851b92..143a2aa 100644 --- a/src/or/torcert.h +++ b/src/or/torcert.h @@ -57,8 +57,9 @@ tor_cert_t *tor_cert_parse(const uint8_t *cert, size_t certlen); void tor_cert_free(tor_cert_t *cert);
int tor_cert_get_checkable_sig(ed25519_checkable_t *checkable_out, - const tor_cert_t *out, - const ed25519_public_key_t *pubkey); + const tor_cert_t *out, + const ed25519_public_key_t *pubkey, + time_t *expiration_out);
int tor_cert_checksig(tor_cert_t *cert, const ed25519_public_key_t *pubkey, time_t now);