commit 42bda231ee10db0136cf2ffb56a38ce290891794 Author: George Kadianakis desnacked@gmail.com Date: Wed Nov 23 23:39:46 2011 +0100
Make DynamicPrimes SIGHUP-able.
Instead of passing the DynamicPrimes configuration option to crypto_global_init(), generate and set a new TLS DH prime when we read the torrc. --- src/common/crypto.c | 82 +++++++++++++++++++++++++++++----------------- src/common/crypto.h | 3 +- src/or/config.c | 17 +++++++++ src/or/main.c | 3 +- src/test/test.c | 2 +- src/tools/tor-checkkey.c | 2 +- 6 files changed, 73 insertions(+), 36 deletions(-)
diff --git a/src/common/crypto.c b/src/common/crypto.c index 88cba03..bef6265 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -105,9 +105,6 @@ static tor_mutex_t **_openssl_mutexes = NULL; static int _n_openssl_mutexes = 0; #endif
-/** True if we use dynamic primes. */ -static int use_dynamic_primes = 0; - /** A public key, or a public/private key-pair. */ struct crypto_pk_env_t { @@ -227,15 +224,13 @@ try_load_engine(const char *path, const char *engine) /** Initialize the crypto library. Return 0 on success, -1 on failure. */ int -crypto_global_init(int useAccel, const char *accelName, const char *accelDir, - int DynamicPrimes) +crypto_global_init(int useAccel, const char *accelName, const char *accelDir) { if (!_crypto_global_initialized) { ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); _crypto_global_initialized = 1; setup_openssl_threading(); - use_dynamic_primes = DynamicPrimes; if (useAccel > 0) { #ifdef DISABLE_ENGINES (void)accelName; @@ -1854,14 +1849,60 @@ crypto_generate_dynamic_prime(void) return dynamic_prime; }
+/** 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. + * If <b>use_dynamic_primes</b> is set, use <b>stored_dynamic_prime</b> + * if it exists, otherwise generate and use a new prime modulus. */ +void +crypto_set_tls_dh_prime(int use_dynamic_primes, BIGNUM *stored_dynamic_prime) +{ + BIGNUM *tls_prime = NULL; + + /* If the space is occupied, free the previous TLS DH prime */ + if (dh_param_p_tls) { + BN_free(dh_param_p_tls); + dh_param_p_tls = NULL; + } + + if (use_dynamic_primes) { /* use dynamic primes: */ + if (stored_dynamic_prime) { + log_notice(LD_OR, "Using stored dynamic prime."); + tls_prime = stored_dynamic_prime; + } else { + log_notice(LD_OR, "Generating fresh dynamic prime."); + tls_prime = crypto_generate_dynamic_prime(); + } + } else { /* use the static DH prime modulus used by Apache in mod_ssl: */ + tls_prime = BN_new(); + tor_assert(tls_prime); + + /* This is the 1024-bit safe prime that Apache uses for its DH stuff; see + * modules/ssl/ssl_engine_dh.c; Apache also uses a generator of 2 with this + * prime. + */ + r = BN_hex2bn(&tls_prime, + "D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98" + "BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A" + "467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7" + "DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68" + "B0E7393E0F24218EB3"); + tor_assert(r); + } + + tor_assert(tls_prime); + + dh_param_p_tls = tls_prime; +} + /** Initialize dh_param_p and dh_param_g if they are not already * set. */ static void init_dh_param(void) { - BIGNUM *circuit_dh_prime, *tls_prime, *generator; + BIGNUM *circuit_dh_prime, *generator; int r; - if (dh_param_p && dh_param_g && dh_param_p_tls) + if (dh_param_p && dh_param_g) return;
circuit_dh_prime = BN_new(); @@ -1884,31 +1925,12 @@ init_dh_param(void) "49286651ECE65381FFFFFFFFFFFFFFFF"); tor_assert(r);
- if (use_dynamic_primes) { /* use dynamic primes: */ - log_notice(LD_OR, "Generating fresh dynamic prime."); - tls_prime = crypto_generate_dynamic_prime(); - tor_assert(tls_prime); - } else { /* use the static DH prime modulus used by Apache in mod_ssl: */ - tls_prime = BN_new(); - tor_assert(tls_prime); - - /* This is the 1024-bit safe prime that Apache uses for its DH stuff; see - * modules/ssl/ssl_engine_dh.c; Apache also uses a generator of 2 with this - * prime. - */ - r = BN_hex2bn(&tls_prime, - "D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98" - "BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A" - "467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7" - "DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68" - "B0E7393E0F24218EB3"); - tor_assert(r); - } - /* Set the new values as the global DH parameters. */ dh_param_p = circuit_dh_prime; - dh_param_p_tls = tls_prime; dh_param_g = generator; + + /* Should be already set by config.c. */ + tor_assert(dh_param_p_tls); }
/** Number of bits to use when choosing the x or y value in a Diffie-Hellman diff --git a/src/common/crypto.h b/src/common/crypto.h index 9e52bc4..b759459 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -85,8 +85,7 @@ typedef struct crypto_dh_env_t crypto_dh_env_t; /* global state */ int crypto_global_init(int hardwareAccel, const char *accelName, - const char *accelPath, - int DynamicPrimes); + const char *accelPath); void crypto_thread_cleanup(void); int crypto_global_cleanup(void);
diff --git a/src/or/config.c b/src/or/config.c index 4766b24..a113f7b 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1362,6 +1362,23 @@ options_act(const or_options_t *old_options) finish_daemon(options->DataDirectory); }
+ /* If needed, generate a new TLS DH prime according to the current torrc. */ + if (!old_options) { + if (options->DynamicPrimes) { + crypto_set_tls_dh_prime(1, router_get_stored_dynamic_prime()); + } else { + crypto_set_tls_dh_prime(0, NULL); + } + } else { + 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); + } else { + tor_assert(crypto_get_tls_dh_prime); + } + } + /* We want to reinit keys as needed before we do much of anything else: keys are important, and other things can depend on them. */ if (transition_affects_workers || diff --git a/src/or/main.c b/src/or/main.c index 3c75e1c..0d2127d 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -2275,8 +2275,7 @@ tor_init(int argc, char *argv[])
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; } diff --git a/src/test/test.c b/src/test/test.c index 26a55d1..d4edf14 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1903,7 +1903,7 @@ main(int c, const char **v) }
options->command = CMD_RUN_UNITTESTS; - if (crypto_global_init(0, NULL, NULL, 1)) { + if (crypto_global_init(0, NULL, NULL)) { printf("Can't initialize crypto subsystem; exiting.\n"); return 1; } diff --git a/src/tools/tor-checkkey.c b/src/tools/tor-checkkey.c index 55480b4..94c8cbd 100644 --- a/src/tools/tor-checkkey.c +++ b/src/tools/tor-checkkey.c @@ -31,7 +31,7 @@ main(int c, char **v) return 1; }
- 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; }