[tor-commits] [tor/master] Implement dynamic prime reading and storing to disk.

nickm at torproject.org nickm at torproject.org
Tue Nov 29 23:33:59 UTC 2011


commit 8a726dd0dd28c4550a7f6f7d9aa5f72507d4716b
Author: George Kadianakis <desnacked at gmail.com>
Date:   Thu Nov 24 00:22:31 2011 +0100

    Implement dynamic prime reading and storing to disk.
---
 src/common/crypto.c     |    9 ++++-
 src/common/crypto.h     |    6 +++
 src/or/config.c         |    5 +-
 src/or/main.c           |    2 +-
 src/or/router.c         |   94 ++++++++++++++++++++++++++++++++++++++++++++++-
 src/or/router.h         |    4 ++
 src/tools/tor-gencert.c |    2 +-
 7 files changed, 115 insertions(+), 7 deletions(-)

diff --git a/src/common/crypto.c b/src/common/crypto.c
index bef6265..4843662 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1849,6 +1849,12 @@ crypto_generate_dynamic_prime(void)
   return dynamic_prime;
 }
 
+BIGNUM *
+crypto_get_tls_dh_prime(void)
+{
+  return dh_param_p_tls;
+}
+
 /** Set the global TLS Diffie-Hellman modulus.
  * If <b>use_dynamic_primes</b> is <em>not</em> set, use the prime
  * modulus of mod_ssl.
@@ -1858,6 +1864,7 @@ void
 crypto_set_tls_dh_prime(int use_dynamic_primes, BIGNUM *stored_dynamic_prime)
 {
   BIGNUM *tls_prime = NULL;
+  int r;
 
   /* If the space is occupied, free the previous TLS DH prime */
   if (dh_param_p_tls) {
@@ -1867,7 +1874,7 @@ crypto_set_tls_dh_prime(int use_dynamic_primes, BIGNUM *stored_dynamic_prime)
 
   if (use_dynamic_primes) { /* use dynamic primes: */
     if (stored_dynamic_prime) {
-      log_notice(LD_OR, "Using stored dynamic prime.");
+      log_warn(LD_OR, "Using stored dynamic prime.");
       tls_prime = stored_dynamic_prime;
     } else {
       log_notice(LD_OR, "Generating fresh dynamic prime.");
diff --git a/src/common/crypto.h b/src/common/crypto.h
index b759459..5b753b8 100644
--- a/src/common/crypto.h
+++ b/src/common/crypto.h
@@ -16,6 +16,8 @@
 #include <stdio.h>
 #include "torint.h"
 
+#include <openssl/bn.h>
+
 /** Length of the output of our message digest. */
 #define DIGEST_LEN 20
 /** Length of the output of our second (improved) message digests.  (For now
@@ -93,6 +95,10 @@ int crypto_global_cleanup(void);
 crypto_pk_env_t *crypto_new_pk_env(void);
 void crypto_free_pk_env(crypto_pk_env_t *env);
 
+void crypto_set_tls_dh_prime(int use_dynamic_primes,
+                             BIGNUM *stored_dynamic_prime);
+BIGNUM * crypto_get_tls_dh_prime(void);
+
 /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */
 crypto_cipher_env_t *crypto_create_init_cipher(const char *key,
                                                int encrypt_mode);
diff --git a/src/or/config.c b/src/or/config.c
index a113f7b..78e91bb 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1373,9 +1373,9 @@ options_act(const or_options_t *old_options)
     if (options->DynamicPrimes && !old_options->DynamicPrimes) {
       crypto_set_tls_dh_prime(1, router_get_stored_dynamic_prime());
     } else if (!options->DynamicPrimes && old_options->DynamicPrimes) {
-      crypto_set_tlS_dh_prime(0, NULL);
+      crypto_set_tls_dh_prime(0, NULL);
     } else {
-      tor_assert(crypto_get_tls_dh_prime);
+      tor_assert(crypto_get_tls_dh_prime());
     }
   }
 
@@ -4069,6 +4069,7 @@ options_transition_affects_workers(const or_options_t *old_options,
 {
   if (!opt_streq(old_options->DataDirectory, new_options->DataDirectory) ||
       old_options->NumCPUs != new_options->NumCPUs ||
+      old_options->DynamicPrimes != new_options->DynamicPrimes ||
       old_options->ORPort != new_options->ORPort ||
       old_options->ServerDNSSearchDomains !=
                                        new_options->ServerDNSSearchDomains ||
diff --git a/src/or/main.c b/src/or/main.c
index 0d2127d..7008d38 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -2275,7 +2275,7 @@ tor_init(int argc, char *argv[])
 
   if (crypto_global_init(get_options()->HardwareAccel,
                          get_options()->AccelName,
-                         get_options()->AccelDir) {
+                         get_options()->AccelDir)) {
     log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting.");
     return -1;
   }
diff --git a/src/or/router.c b/src/or/router.c
index 414d346..368ea1b 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -484,6 +484,86 @@ v3_authority_check_key_expiry(void)
   last_warned = now;
 }
 
+
+/** Store <b>dynamic_prime</b> to disk for future use. */
+int
+router_store_dynamic_prime(const BIGNUM *dynamic_prime)
+{
+  FILE *fp = NULL;
+  char *fname = get_datadir_fname2("keys", "dynamic_prime");
+  int retval = -1;
+
+  if (file_status(fname) != FN_NOENT) {
+    log_warn(LD_GENERAL, "Dynamic prime already occupied.");
+    goto done;
+  }
+
+  if (!(fp = fopen(fname, "w"))) {
+    log_warn(LD_GENERAL, "Error writing to certificate file");
+    goto done;
+  }
+
+  if (BN_print_fp(fp, dynamic_prime) == 0) {
+    log_warn(LD_GENERAL, "Error on bn_print_fp()");
+    goto done;
+  }
+
+  retval = 0;
+
+ done:
+  if (fp)
+    fclose(fp);
+  tor_free(fname);
+
+  return retval;
+}
+
+/** Return the dynamic prime stored in the disk. If there is no
+    dynamic prime stored in the disk, return NULL. */
+BIGNUM *
+router_get_stored_dynamic_prime(void)
+{
+  int retval;
+  char *contents = NULL;
+  char *fname = get_datadir_fname2("keys", "dynamic_prime");
+  BIGNUM *dynamic_prime = BN_new();
+  if (!dynamic_prime)
+    goto err;
+
+  contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL);
+  if (!contents) {
+    log_warn(LD_GENERAL, "Error reading dynamic prime from \"%s\"", fname);
+    goto err;
+  }
+
+  retval = BN_hex2bn(&dynamic_prime, contents);
+  if (!retval) {
+    log_warn(LD_GENERAL, "C0rrupted dynamic prime?!?!");
+    goto err;
+  }
+
+  { /* log the dynamic prime: */
+    char *s = BN_bn2hex(dynamic_prime);
+    tor_assert(s);
+    log_notice(LD_OR, "Found stored dynamic prime: [%s]", s);
+    OPENSSL_free(s);
+  }
+
+  goto done;
+
+ err:
+  if (dynamic_prime) {
+    BN_free(dynamic_prime);
+    dynamic_prime = NULL;
+  }
+
+ done:
+  tor_free(fname);
+  tor_free(contents);
+
+  return dynamic_prime;
+}
+
 /** Initialize all OR private keys, and the TLS context, as necessary.
  * On OPs, this only initializes the tls context. Return 0 on success,
  * or -1 if Tor should die.
@@ -514,8 +594,7 @@ init_keys(void)
    * openssl to initialize itself. */
   if (crypto_global_init(get_options()->HardwareAccel,
                          get_options()->AccelName,
-                         get_options()->AccelDir,
-                         get_options()->DynamicPrimes)) {
+                         get_options()->AccelDir)) {
     log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting.");
     return -1;
   }
@@ -634,6 +713,17 @@ init_keys(void)
     log_err(LD_GENERAL,"Error initializing TLS context");
     return -1;
   }
+
+  /** 3b. If we use a dynamic prime, store it to disk. */
+  if (get_options()->DynamicPrimes) {
+    BIGNUM *dynamic_prime = crypto_get_tls_dh_prime();
+    if (dynamic_prime) {
+      if (router_store_dynamic_prime(dynamic_prime) < 0)
+        log_warn(LD_GENERAL, "Failed while storing dynamic prime. "
+                 "Make sure your data directory is sane.");
+    }
+  }
+
   /* 4. Build our router descriptor. */
   /* Must be called after keys are initialized. */
   mydesc = router_get_my_descriptor();
diff --git a/src/or/router.h b/src/or/router.h
index f9d156c..41ff139 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -28,6 +28,10 @@ void dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last);
 void rotate_onion_key(void);
 crypto_pk_env_t *init_key_from_file(const char *fname, int generate,
                                     int severity);
+
+BIGNUM *router_get_stored_dynamic_prime(void);
+int router_store_dynamic_prime(const BIGNUM *dynamic_prime);
+
 void v3_authority_check_key_expiry(void);
 
 int init_keys(void);
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index b9f16d9..974a58b 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -508,7 +508,7 @@ main(int argc, char **argv)
   init_logging();
 
   /* Don't bother using acceleration. */
-  if (crypto_global_init(0, NULL, NULL, 0)) {
+  if (crypto_global_init(0, NULL, NULL)) {
     fprintf(stderr, "Couldn't initialize crypto library.\n");
     return 1;
   }





More information about the tor-commits mailing list