commit 8a726dd0dd28c4550a7f6f7d9aa5f72507d4716b Author: George Kadianakis desnacked@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; }
tor-commits@lists.torproject.org