[tor-commits] [tor/master] Fix a misfeature with the Ed cert expiration API

nickm at torproject.org nickm at torproject.org
Thu Nov 3 13:18:59 UTC 2016


commit fae7060aea5c562fc59e7089b6a3459a5718b2d0
Author: Nick Mathewson <nickm at 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);





More information about the tor-commits mailing list