[tor-commits] [tor/master] Make tor_tls_cert_is_valid check key lengths

nickm at torproject.org nickm at torproject.org
Tue Oct 11 03:22:16 UTC 2011


commit 9a77ebc794cff2df50bb2d47788461864f4bc8c9
Author: Nick Mathewson <nickm at torproject.org>
Date:   Thu Sep 22 10:01:41 2011 -0400

    Make tor_tls_cert_is_valid check key lengths
---
 src/common/tortls.c |   34 +++++++++++++++++++++++++++++-----
 src/common/tortls.h |    3 ++-
 src/or/command.c    |    8 ++++----
 3 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/src/common/tortls.c b/src/common/tortls.c
index aa90f18..01a0f8e 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -928,14 +928,18 @@ tor_tls_cert_matches_key(const tor_tls_t *tls, const tor_cert_t *cert)
 }
 
 /** Check wither <b>cert</b> is well-formed, currently live, and correctly
- * signed by the public key in <b>signing_cert</b>.  Return 0 if the cert is
- * good, and -1 if it's bad or we couldn't check it. */
+ * signed by the public key in <b>signing_cert</b>.  If <b>check_rsa_1024</b>,
+ * make sure that it has an RSA key with 1024 bits; otherwise, just check that
+ * the key is long enough. Return 1 if the cert is good, and 0 if it's bad or
+ * we couldn't check it. */
 int
 tor_tls_cert_is_valid(const tor_cert_t *cert,
-                      const tor_cert_t *signing_cert)
+                      const tor_cert_t *signing_cert,
+                      int check_rsa_1024)
 {
+  EVP_PKEY *cert_key;
   EVP_PKEY *signing_key = X509_get_pubkey(signing_cert->cert);
-  int r;
+  int r, key_ok = 0;
   if (!signing_key)
     return 0;
   r = X509_verify(cert->cert, signing_key);
@@ -949,9 +953,29 @@ tor_tls_cert_is_valid(const tor_cert_t *cert,
   if (check_cert_lifetime_internal(cert->cert, 60*60) < 0)
     return 0;
 
+  cert_key = X509_get_pubkey(cert->cert);
+  if (check_rsa_1024 && cert_key) {
+    RSA *rsa = EVP_PKEY_get1_RSA(cert_key);
+    if (rsa && BN_num_bits(rsa->n) == 1024)
+      key_ok = 1;
+    if (rsa)
+      RSA_free(rsa);
+  } else if (cert_key) {
+    int min_bits = 1024;
+#ifdef EVP_PKEY_EC
+    if (EVP_PKEY_type(cert_key->type) == EVP_PKEY_EC)
+      min_bits = 128;
+#endif
+    if (EVP_PKEY_bits(cert_key) >= min_bits)
+      key_ok = 1;
+  }
+  EVP_PKEY_free(cert_key);
+  if (!key_ok)
+    return 0;
+
   /* XXXX compare DNs or anything? */
 
-  return -1;
+  return 1;
 }
 
 /** Increase the reference count of <b>ctx</b>. */
diff --git a/src/common/tortls.h b/src/common/tortls.h
index 00bf406..90e76e4 100644
--- a/src/common/tortls.h
+++ b/src/common/tortls.h
@@ -123,7 +123,8 @@ crypto_pk_env_t *tor_tls_get_my_client_auth_key(void);
 crypto_pk_env_t *tor_tls_cert_get_key(tor_cert_t *cert);
 int tor_tls_cert_matches_key(const tor_tls_t *tls, const tor_cert_t *cert);
 int tor_tls_cert_is_valid(const tor_cert_t *cert,
-                          const tor_cert_t *signing_cert);
+                          const tor_cert_t *signing_cert,
+                          int check_rsa_1024);
 
 #endif
 
diff --git a/src/or/command.c b/src/or/command.c
index aad971f..a32671f 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -745,9 +745,9 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
     if (! tor_tls_cert_matches_key(conn->tls, link_cert)) {
       ERR("The link certificate didn't match the TLS public key");
     }
-    if (! tor_tls_cert_is_valid(link_cert, id_cert))
+    if (! tor_tls_cert_is_valid(link_cert, id_cert, 0))
       ERR("The link certificate was not valid");
-    if (! tor_tls_cert_is_valid(id_cert, id_cert))
+    if (! tor_tls_cert_is_valid(id_cert, id_cert, 1))
       ERR("The ID certificate was not valid");
 
     /* XXXX  okay, we just got authentication.  Do something about that. */
@@ -761,9 +761,9 @@ command_process_cert_cell(var_cell_t *cell, or_connection_t *conn)
     /* Remember these certificates so we can check an AUTHENTICATE cell */
     conn->handshake_state->id_cert = id_cert;
     conn->handshake_state->auth_cert = auth_cert;
-    if (! tor_tls_cert_is_valid(auth_cert, id_cert))
+    if (! tor_tls_cert_is_valid(auth_cert, id_cert, 1))
       ERR("The authentication certificate was not valid");
-    if (! tor_tls_cert_is_valid(id_cert, id_cert))
+    if (! tor_tls_cert_is_valid(id_cert, id_cert, 1))
       ERR("The ID certificate was not valid");
 
     /* XXXX check more stuff? */





More information about the tor-commits mailing list