From 659381e00dc09deb4fb342d9f45cfae0b65aa33f Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Tue, 22 Nov 2011 04:53:43 +0100 Subject: Introduce the DynamicPrimes configuration option. --- src/or/router.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/or/router.c') diff --git a/src/or/router.c b/src/or/router.c index b6b96a5fff..414d346bfa 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -514,7 +514,8 @@ init_keys(void) * openssl to initialize itself. */ if (crypto_global_init(get_options()->HardwareAccel, get_options()->AccelName, - get_options()->AccelDir)) { + get_options()->AccelDir, + get_options()->DynamicPrimes)) { log_err(LD_BUG, "Unable to initialize OpenSSL. Exiting."); return -1; } -- cgit v1.2.3-54-g00ecf From 8a726dd0dd28c4550a7f6f7d9aa5f72507d4716b Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 24 Nov 2011 00:22:31 +0100 Subject: 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(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index bef62651fc..484366297d 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 use_dynamic_primes is not 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 b759459d40..5b753b83d6 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -16,6 +16,8 @@ #include #include "torint.h" +#include + /** 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 a113f7b2da..78e91bbe11 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 0d2127d336..7008d388a1 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 414d346bfa..368ea1b741 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 dynamic_prime 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 f9d156cb09..41ff139936 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 b9f16d9929..974a58becf 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; } -- cgit v1.2.3-54-g00ecf From cabb8e54c7240aeb20ccfa745d75c5ad4063edb3 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 24 Nov 2011 06:12:22 +0100 Subject: Tone down the logging. --- src/common/crypto.c | 6 +++--- src/or/router.c | 28 +++++++++++++++++----------- 2 files changed, 20 insertions(+), 14 deletions(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index 484366297d..72c3dd7c12 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1842,7 +1842,7 @@ crypto_generate_dynamic_prime(void) { /* log the dynamic prime: */ s = BN_bn2hex(dynamic_prime); tor_assert(s); - log_notice(LD_OR, "Dynamic prime generated: [%s]", s); + log_info(LD_OR, "Dynamic prime generated: [%s]", s); OPENSSL_free(s); } @@ -1874,10 +1874,10 @@ 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_warn(LD_OR, "Using stored dynamic prime."); + log_info(LD_OR, "Using stored dynamic prime."); tls_prime = stored_dynamic_prime; } else { - log_notice(LD_OR, "Generating fresh dynamic prime."); + log_info(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: */ diff --git a/src/or/router.c b/src/or/router.c index 368ea1b741..6b38c793ce 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -492,19 +492,26 @@ router_store_dynamic_prime(const BIGNUM *dynamic_prime) FILE *fp = NULL; char *fname = get_datadir_fname2("keys", "dynamic_prime"); int retval = -1; + file_status_t fname_status = file_status(fname); - if (file_status(fname) != FN_NOENT) { - log_warn(LD_GENERAL, "Dynamic prime already occupied."); + if (fname_status == FN_FILE) { + /* If the fname is a file, then the dynamic prime is already stored. */ + retval = 0; + goto done; + } else if (fname_status != FN_NOENT) { + log_info(LD_GENERAL, "Dynamic prime filename is occupied."); goto done; } + tor_assert(fname_status == FN_NOENT); + if (!(fp = fopen(fname, "w"))) { - log_warn(LD_GENERAL, "Error writing to certificate file"); + log_notice(LD_GENERAL, "Error while creating dynamic prime file."); goto done; } if (BN_print_fp(fp, dynamic_prime) == 0) { - log_warn(LD_GENERAL, "Error on bn_print_fp()"); + log_warn(LD_GENERAL, "Error while printing dynamic prime to file."); goto done; } @@ -531,21 +538,20 @@ router_get_stored_dynamic_prime(void) 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); + if (!contents) goto err; - } retval = BN_hex2bn(&dynamic_prime, contents); if (!retval) { - log_warn(LD_GENERAL, "C0rrupted dynamic prime?!?!"); + log_notice(LD_GENERAL, "Could not understand the dynamic prime " + "format in '%s'", fname); 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); + log_info(LD_OR, "Found stored dynamic prime: [%s]", s); OPENSSL_free(s); } @@ -719,8 +725,8 @@ init_keys(void) 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."); + log_notice(LD_GENERAL, "Failed while storing dynamic prime. " + "Make sure your data directory is sane."); } } -- cgit v1.2.3-54-g00ecf From 2ef68980a778666bcc9b3b492c4acbd7af27fc28 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 24 Nov 2011 22:32:10 +0100 Subject: Move store_dynamic_prime() to crypto.c. --- src/common/crypto.c | 40 +++++++++++++++++++++++++++++++++++++--- src/common/crypto.h | 2 +- src/or/router.c | 52 ++++++---------------------------------------------- src/or/router.h | 1 - 4 files changed, 44 insertions(+), 51 deletions(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index 72c3dd7c12..a3c292324b 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1849,10 +1849,44 @@ crypto_generate_dynamic_prime(void) return dynamic_prime; } -BIGNUM * -crypto_get_tls_dh_prime(void) +/** Store our dynamic prime to fname for future use. */ +int +router_store_dynamic_prime(const char *fname) { - return dh_param_p_tls; + FILE *fp = NULL; + int retval = -1; + file_status_t fname_status = file_status(fname); + + tor_assert(fname); + + if (fname_status == FN_FILE) { + /* If the fname is a file, then the dynamic prime is already stored. */ + retval = 0; + goto done; + } else if (fname_status != FN_NOENT) { + log_info(LD_GENERAL, "Dynamic prime filename is occupied."); + goto done; + } + + tor_assert(fname_status == FN_NOENT); + + if (!(fp = fopen(fname, "w"))) { + log_notice(LD_GENERAL, "Error while creating dynamic prime file."); + goto done; + } + + if (BN_print_fp(fp, dh_param_p_tls) == 0) { + log_warn(LD_GENERAL, "Error while printing dynamic prime to file."); + goto done; + } + + retval = 0; + + done: + if (fp) + fclose(fp); + + return retval; } /** Set the global TLS Diffie-Hellman modulus. diff --git a/src/common/crypto.h b/src/common/crypto.h index 5b753b83d6..8c99dd7a37 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -97,7 +97,7 @@ 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); +int router_store_dynamic_prime(const char *fname); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, diff --git a/src/or/router.c b/src/or/router.c index 6b38c793ce..dd5b9fff52 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -485,46 +485,6 @@ v3_authority_check_key_expiry(void) } -/** Store dynamic_prime 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; - file_status_t fname_status = file_status(fname); - - if (fname_status == FN_FILE) { - /* If the fname is a file, then the dynamic prime is already stored. */ - retval = 0; - goto done; - } else if (fname_status != FN_NOENT) { - log_info(LD_GENERAL, "Dynamic prime filename is occupied."); - goto done; - } - - tor_assert(fname_status == FN_NOENT); - - if (!(fp = fopen(fname, "w"))) { - log_notice(LD_GENERAL, "Error while creating dynamic prime file."); - goto done; - } - - if (BN_print_fp(fp, dynamic_prime) == 0) { - log_warn(LD_GENERAL, "Error while printing dynamic prime to file."); - 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 * @@ -722,12 +682,12 @@ init_keys(void) /** 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_notice(LD_GENERAL, "Failed while storing dynamic prime. " - "Make sure your data directory is sane."); - } + const char *fname = get_datadir_fname2("keys", "dynamic_prime"); + if (crypto_store_dynamic_prime(fname)) { + log_notice(LD_GENERAL, "Failed while storing dynamic prime. " + "Make sure your data directory is sane."); + } + tor_free(fname); } /* 4. Build our router descriptor. */ diff --git a/src/or/router.h b/src/or/router.h index 41ff139936..a998335aa3 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -30,7 +30,6 @@ 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); -- cgit v1.2.3-54-g00ecf From 94076d9e3b74ad1f6aee8a96f51eb4af5f5bdb64 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 24 Nov 2011 22:59:01 +0100 Subject: Move crypto_get_stored_dynamic_prime() to crypto.c --- src/common/crypto.c | 70 ++++++++++++++++++++++++++++++++++++++++++++--------- src/common/crypto.h | 5 ++-- src/or/config.c | 14 ++++++----- src/or/router.c | 58 +++++--------------------------------------- src/or/router.h | 2 -- 5 files changed, 75 insertions(+), 74 deletions(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index a3c292324b..c6285e5ce9 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1851,7 +1851,7 @@ crypto_generate_dynamic_prime(void) /** Store our dynamic prime to fname for future use. */ int -router_store_dynamic_prime(const char *fname) +crypto_store_dynamic_prime(const char *fname) { FILE *fp = NULL; int retval = -1; @@ -1889,13 +1889,61 @@ router_store_dynamic_prime(const char *fname) return retval; } +/** Return the dynamic prime stored in fname. If there is no + dynamic prime stored in fname, return NULL. */ +static BIGNUM * +crypto_get_stored_dynamic_prime(const char *fname) +{ + int retval; + char *contents = NULL; + BIGNUM *dynamic_prime = BN_new(); + + tor_assert(fname); + + if (!dynamic_prime) + goto err; + + contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL); + if (!contents) + goto err; + + retval = BN_hex2bn(&dynamic_prime, contents); + if (!retval) { + log_notice(LD_GENERAL, "Could not understand the dynamic prime " + "format in '%s'", fname); + goto err; + } + + { /* log the dynamic prime: */ + char *s = BN_bn2hex(dynamic_prime); + tor_assert(s); + log_info(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(contents); + + return dynamic_prime; +} + + /** Set the global TLS Diffie-Hellman modulus. - * If use_dynamic_primes is not set, use the prime - * modulus of mod_ssl. - * If use_dynamic_primes is set, use stored_dynamic_prime - * if it exists, otherwise generate and use a new prime modulus. */ + * If dynamic_prime_fname is set, try to read a dynamic prime + * off it and use it as the DH modulus. If that's not possible, + * generate a new dynamic prime. + * If dynamic_prime_fname is NULL, use the Apache mod_ssl DH + * modulus. */ void -crypto_set_tls_dh_prime(int use_dynamic_primes, BIGNUM *stored_dynamic_prime) +crypto_set_tls_dh_prime(const char *dynamic_prime_fname) { BIGNUM *tls_prime = NULL; int r; @@ -1906,11 +1954,11 @@ crypto_set_tls_dh_prime(int use_dynamic_primes, BIGNUM *stored_dynamic_prime) dh_param_p_tls = NULL; } - if (use_dynamic_primes) { /* use dynamic primes: */ - if (stored_dynamic_prime) { - log_info(LD_OR, "Using stored dynamic prime."); - tls_prime = stored_dynamic_prime; - } else { + if (dynamic_prime_fname) { /* use dynamic primes: */ + log_info(LD_OR, "Using stored dynamic prime."); + tls_prime = crypto_get_stored_dynamic_prime(dynamic_prime_fname); + + if (!tls_prime) { log_info(LD_OR, "Generating fresh dynamic prime."); tls_prime = crypto_generate_dynamic_prime(); } diff --git a/src/common/crypto.h b/src/common/crypto.h index 8c99dd7a37..20298b3c49 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -95,9 +95,8 @@ 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); -int router_store_dynamic_prime(const char *fname); +void crypto_set_tls_dh_prime(const char *dynamic_prime_fname); +int crypto_store_dynamic_prime(const char *fname); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, diff --git a/src/or/config.c b/src/or/config.c index 78e91bbe11..e1e71b0593 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1365,17 +1365,19 @@ options_act(const or_options_t *old_options) /* 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()); + char *fname = get_datadir_fname2("keys", "dynamic_prime"); + crypto_set_tls_dh_prime(fname); + tor_free(fname); } else { - crypto_set_tls_dh_prime(0, NULL); + crypto_set_tls_dh_prime(NULL); } } else { if (options->DynamicPrimes && !old_options->DynamicPrimes) { - crypto_set_tls_dh_prime(1, router_get_stored_dynamic_prime()); + char *fname = get_datadir_fname2("keys", "dynamic_prime"); + crypto_set_tls_dh_prime(fname); + tor_free(fname); } else if (!options->DynamicPrimes && old_options->DynamicPrimes) { - crypto_set_tls_dh_prime(0, NULL); - } else { - tor_assert(crypto_get_tls_dh_prime()); + crypto_set_tls_dh_prime(NULL); } } diff --git a/src/or/router.c b/src/or/router.c index dd5b9fff52..c554d5b961 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -484,52 +484,6 @@ v3_authority_check_key_expiry(void) last_warned = now; } - -/** 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) - goto err; - - retval = BN_hex2bn(&dynamic_prime, contents); - if (!retval) { - log_notice(LD_GENERAL, "Could not understand the dynamic prime " - "format in '%s'", fname); - goto err; - } - - { /* log the dynamic prime: */ - char *s = BN_bn2hex(dynamic_prime); - tor_assert(s); - log_info(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. @@ -682,12 +636,12 @@ init_keys(void) /** 3b. If we use a dynamic prime, store it to disk. */ if (get_options()->DynamicPrimes) { - const char *fname = get_datadir_fname2("keys", "dynamic_prime"); - if (crypto_store_dynamic_prime(fname)) { - log_notice(LD_GENERAL, "Failed while storing dynamic prime. " - "Make sure your data directory is sane."); - } - tor_free(fname); + char *fname = get_datadir_fname2("keys", "dynamic_prime"); + if (crypto_store_dynamic_prime(fname)) { + log_notice(LD_GENERAL, "Failed while storing dynamic prime. " + "Make sure your data directory is sane."); + } + tor_free(fname); } /* 4. Build our router descriptor. */ diff --git a/src/or/router.h b/src/or/router.h index a998335aa3..b9e9f2a713 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -29,8 +29,6 @@ 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); - void v3_authority_check_key_expiry(void); int init_keys(void); -- cgit v1.2.3-54-g00ecf From 782c907c7cbd3bf2bb75680f5d3deb2d984052de Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Fri, 25 Nov 2011 01:00:14 +0100 Subject: s/DynamicPrimes/DynamicDHGroups/g --- src/or/config.c | 10 +++++----- src/or/or.h | 2 +- src/or/router.c | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/or/router.c') diff --git a/src/or/config.c b/src/or/config.c index e1e71b0593..fc3cc745f9 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -247,7 +247,7 @@ static config_var_t _option_vars[] = { VAR("DirServer", LINELIST, DirServers, NULL), V(DisableAllSwap, BOOL, "0"), V(DisableIOCP, BOOL, "1"), - V(DynamicPrimes, BOOL, "1"), + V(DynamicDHGroups, BOOL, "1"), V(DNSPort, LINELIST, NULL), V(DNSListenAddress, LINELIST, NULL), V(DownloadExtraInfo, BOOL, "0"), @@ -1364,7 +1364,7 @@ options_act(const or_options_t *old_options) /* If needed, generate a new TLS DH prime according to the current torrc. */ if (!old_options) { - if (options->DynamicPrimes) { + if (options->DynamicDHGroups) { char *fname = get_datadir_fname2("keys", "dynamic_prime"); crypto_set_tls_dh_prime(fname); tor_free(fname); @@ -1372,11 +1372,11 @@ options_act(const or_options_t *old_options) crypto_set_tls_dh_prime(NULL); } } else { - if (options->DynamicPrimes && !old_options->DynamicPrimes) { + if (options->DynamicDHGroups && !old_options->DynamicDHGroups) { char *fname = get_datadir_fname2("keys", "dynamic_prime"); crypto_set_tls_dh_prime(fname); tor_free(fname); - } else if (!options->DynamicPrimes && old_options->DynamicPrimes) { + } else if (!options->DynamicDHGroups && old_options->DynamicDHGroups) { crypto_set_tls_dh_prime(NULL); } } @@ -4071,7 +4071,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->DynamicDHGroups != new_options->DynamicDHGroups || old_options->ORPort != new_options->ORPort || old_options->ServerDNSSearchDomains != new_options->ServerDNSSearchDomains || diff --git a/src/or/or.h b/src/or/or.h index b2ea3bc7a7..e3feeedc27 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2873,7 +2873,7 @@ typedef struct { char *Address; /**< OR only: configured address for this onion router. */ char *PidFile; /**< Where to store PID of Tor process. */ - int DynamicPrimes; /**< Enable dynamic generation of primes for use in DH. */ + int DynamicDHGroups; /**< Enable dynamic generation of primes for use in DH. */ routerset_t *ExitNodes; /**< Structure containing nicknames, digests, * country codes and IP address patterns of ORs to diff --git a/src/or/router.c b/src/or/router.c index c554d5b961..fa791fc85e 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -635,7 +635,7 @@ init_keys(void) } /** 3b. If we use a dynamic prime, store it to disk. */ - if (get_options()->DynamicPrimes) { + if (get_options()->DynamicDHGroups) { char *fname = get_datadir_fname2("keys", "dynamic_prime"); if (crypto_store_dynamic_prime(fname)) { log_notice(LD_GENERAL, "Failed while storing dynamic prime. " -- cgit v1.2.3-54-g00ecf From 7c37a664c17f4dd9748f096ea385c3627cc323fa Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Fri, 25 Nov 2011 01:00:58 +0100 Subject: Rename 'dynamic prime' to 'dynamic DH modulus'. --- src/common/crypto.c | 80 ++++++++++++++++++++++++++--------------------------- src/common/crypto.h | 4 +-- src/or/config.c | 4 +-- src/or/router.c | 4 +-- 4 files changed, 46 insertions(+), 46 deletions(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index 4e96fed90a..0f828db81f 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1818,15 +1818,15 @@ static BIGNUM *dh_param_g = NULL; /** Generate and return a reasonable and safe DH parameter p. */ static BIGNUM * -crypto_generate_dynamic_prime(void) +crypto_generate_dynamic_dh_modulus(void) { - BIGNUM *dynamic_prime; + BIGNUM *dynamic_dh_modulus; DH *dh_parameters; int r, dh_codes; char *s; - dynamic_prime = BN_new(); - tor_assert(dynamic_prime); + dynamic_dh_modulus = BN_new(); + tor_assert(dynamic_dh_modulus); dh_parameters = DH_generate_parameters(DH_BYTES*8, DH_GENERATOR, NULL, NULL); tor_assert(dh_parameters); @@ -1834,24 +1834,24 @@ crypto_generate_dynamic_prime(void) r = DH_check(dh_parameters, &dh_codes); tor_assert(r && !dh_codes); - BN_copy(dynamic_prime, dh_parameters->p); - tor_assert(dynamic_prime); + BN_copy(dynamic_dh_modulus, dh_parameters->p); + tor_assert(dynamic_dh_modulus); DH_free(dh_parameters); - { /* log the dynamic prime: */ - s = BN_bn2hex(dynamic_prime); + { /* log the dynamic DH modulus: */ + s = BN_bn2hex(dynamic_dh_modulus); tor_assert(s); - log_info(LD_OR, "Dynamic prime generated: [%s]", s); + log_info(LD_OR, "Dynamic DH modulus generated: [%s]", s); OPENSSL_free(s); } - return dynamic_prime; + return dynamic_dh_modulus; } -/** Store our dynamic prime to fname for future use. */ +/** Store our dynamic DH modulus to fname for future use. */ int -crypto_store_dynamic_prime(const char *fname) +crypto_store_dynamic_dh_modulus(const char *fname) { FILE *fp = NULL; int retval = -1; @@ -1862,23 +1862,23 @@ crypto_store_dynamic_prime(const char *fname) fname_status = file_status(fname); if (fname_status == FN_FILE) { - /* If the fname is a file, then the dynamic prime is already stored. */ + /* If the fname is a file, then the dynamic DH modulus is already stored. */ retval = 0; goto done; } else if (fname_status != FN_NOENT) { - log_info(LD_GENERAL, "Dynamic prime filename is occupied."); + log_info(LD_GENERAL, "Dynamic DH modulus filename is occupied."); goto done; } tor_assert(fname_status == FN_NOENT); if (!(fp = fopen(fname, "w"))) { - log_notice(LD_GENERAL, "Error while creating dynamic prime file."); + log_notice(LD_GENERAL, "Error while creating dynamic DH modulus file."); goto done; } if (BN_print_fp(fp, dh_param_p_tls) == 0) { - log_warn(LD_GENERAL, "Error while printing dynamic prime to file."); + log_warn(LD_GENERAL, "Error while printing dynamic DH modulus to file."); goto done; } @@ -1891,29 +1891,29 @@ crypto_store_dynamic_prime(const char *fname) return retval; } -/** Return the dynamic prime stored in fname. If there is no - dynamic prime stored in fname, return NULL. */ +/** Return the dynamic DH modulus stored in fname. If there is no + dynamic DH modulus stored in fname, return NULL. */ static BIGNUM * -crypto_get_stored_dynamic_prime(const char *fname) +crypto_get_stored_dynamic_dh_modulus(const char *fname) { int retval; char *contents = NULL; DH *dh = NULL; int dh_codes; - BIGNUM *dynamic_prime = BN_new(); + BIGNUM *dynamic_dh_modulus = BN_new(); tor_assert(fname); - if (!dynamic_prime) + if (!dynamic_dh_modulus) goto err; contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL); if (!contents) goto err; - retval = BN_hex2bn(&dynamic_prime, contents); + retval = BN_hex2bn(&dynamic_dh_modulus, contents); if (!retval) { - log_warn(LD_GENERAL, "Could not understand the dynamic prime " + log_warn(LD_GENERAL, "Could not understand the dynamic DH modulus " "format in '%s'", fname); goto err; } @@ -1923,7 +1923,7 @@ crypto_get_stored_dynamic_prime(const char *fname) if (!dh) goto err; - dh->p = BN_dup(dynamic_prime); + dh->p = BN_dup(dynamic_dh_modulus); dh->g = BN_new(); BN_set_word(dh->g, DH_GENERATOR); @@ -1942,19 +1942,19 @@ crypto_get_stored_dynamic_prime(const char *fname) } - { /* log the dynamic prime: */ - char *s = BN_bn2hex(dynamic_prime); + { /* log the dynamic DH modulus: */ + char *s = BN_bn2hex(dynamic_dh_modulus); tor_assert(s); - log_info(LD_OR, "Found stored dynamic prime: [%s]", s); + log_info(LD_OR, "Found stored dynamic DH modulus: [%s]", s); OPENSSL_free(s); } goto done; err: - if (dynamic_prime) { - BN_free(dynamic_prime); - dynamic_prime = NULL; + if (dynamic_dh_modulus) { + BN_free(dynamic_dh_modulus); + dynamic_dh_modulus = NULL; } done: @@ -1962,18 +1962,18 @@ crypto_get_stored_dynamic_prime(const char *fname) if (dh) DH_free(dh); - return dynamic_prime; + return dynamic_dh_modulus; } /** Set the global TLS Diffie-Hellman modulus. - * If dynamic_prime_fname is set, try to read a dynamic prime + * If dynamic_dh_modulus_fname is set, try to read a dynamic DH modulus * off it and use it as the DH modulus. If that's not possible, - * generate a new dynamic prime. - * If dynamic_prime_fname is NULL, use the Apache mod_ssl DH + * generate a new dynamic DH modulus. + * If dynamic_dh_modulus_fname is NULL, use the Apache mod_ssl DH * modulus. */ void -crypto_set_tls_dh_prime(const char *dynamic_prime_fname) +crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname) { BIGNUM *tls_prime = NULL; int r; @@ -1984,14 +1984,14 @@ crypto_set_tls_dh_prime(const char *dynamic_prime_fname) dh_param_p_tls = NULL; } - if (dynamic_prime_fname) { /* use dynamic primes: */ - log_info(LD_OR, "Using stored dynamic prime."); - tls_prime = crypto_get_stored_dynamic_prime(dynamic_prime_fname); + if (dynamic_dh_modulus_fname) { /* use dynamic DH moduluss: */ + log_info(LD_OR, "Using stored dynamic DH modulus."); + tls_prime = crypto_get_stored_dynamic_dh_modulus(dynamic_dh_modulus_fname); if (!tls_prime) { - log_notice(LD_OR, "Generating fresh dynamic prime. " + log_notice(LD_OR, "Generating fresh dynamic DH modulus. " "This might take a while..."); - tls_prime = crypto_generate_dynamic_prime(); + tls_prime = crypto_generate_dynamic_dh_modulus(); } } else { /* use the static DH prime modulus used by Apache in mod_ssl: */ tls_prime = BN_new(); diff --git a/src/common/crypto.h b/src/common/crypto.h index 20298b3c49..504c59b1a7 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -95,8 +95,8 @@ 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(const char *dynamic_prime_fname); -int crypto_store_dynamic_prime(const char *fname); +void crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname); +int crypto_store_dynamic_dh_modulus(const char *fname); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, diff --git a/src/or/config.c b/src/or/config.c index fc3cc745f9..d403decb18 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1365,7 +1365,7 @@ options_act(const or_options_t *old_options) /* If needed, generate a new TLS DH prime according to the current torrc. */ if (!old_options) { if (options->DynamicDHGroups) { - char *fname = get_datadir_fname2("keys", "dynamic_prime"); + char *fname = get_datadir_fname2("keys", "dynamic_dh_modulus"); crypto_set_tls_dh_prime(fname); tor_free(fname); } else { @@ -1373,7 +1373,7 @@ options_act(const or_options_t *old_options) } } else { if (options->DynamicDHGroups && !old_options->DynamicDHGroups) { - char *fname = get_datadir_fname2("keys", "dynamic_prime"); + char *fname = get_datadir_fname2("keys", "dynamic_dh_modulus"); crypto_set_tls_dh_prime(fname); tor_free(fname); } else if (!options->DynamicDHGroups && old_options->DynamicDHGroups) { diff --git a/src/or/router.c b/src/or/router.c index fa791fc85e..963c781733 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -636,8 +636,8 @@ init_keys(void) /** 3b. If we use a dynamic prime, store it to disk. */ if (get_options()->DynamicDHGroups) { - char *fname = get_datadir_fname2("keys", "dynamic_prime"); - if (crypto_store_dynamic_prime(fname)) { + char *fname = get_datadir_fname2("keys", "dynamic_dh_modulus"); + if (crypto_store_dynamic_dh_modulus(fname)) { log_notice(LD_GENERAL, "Failed while storing dynamic prime. " "Make sure your data directory is sane."); } -- cgit v1.2.3-54-g00ecf From 4938bcc06a41b95f47def181ce03a7ade805595b Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Fri, 25 Nov 2011 17:39:28 +0100 Subject: Do dynamic DH modulus storing in crypto.c. --- src/common/crypto.c | 15 +++++++++++++-- src/common/crypto.h | 1 - src/or/router.c | 10 ---------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index 8b0f0ef9da..1974a3931b 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1850,7 +1850,7 @@ crypto_generate_dynamic_dh_modulus(void) } /** Store our dynamic DH modulus to fname for future use. */ -int +static int crypto_store_dynamic_dh_modulus(const char *fname) { FILE *fp = NULL; @@ -1974,6 +1974,7 @@ void crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname) { BIGNUM *tls_prime = NULL; + int store_dh_prime_afterwards = 0; int r; /* If the space is occupied, free the previous TLS DH prime */ @@ -1982,7 +1983,7 @@ crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname) dh_param_p_tls = NULL; } - if (dynamic_dh_modulus_fname) { /* use dynamic DH moduluss: */ + if (dynamic_dh_modulus_fname) { /* use dynamic DH modulus: */ log_info(LD_OR, "Using stored dynamic DH modulus."); tls_prime = crypto_get_stored_dynamic_dh_modulus(dynamic_dh_modulus_fname); @@ -1990,6 +1991,8 @@ crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname) log_notice(LD_OR, "Generating fresh dynamic DH modulus. " "This might take a while..."); tls_prime = crypto_generate_dynamic_dh_modulus(); + + store_dh_prime_afterwards++; } } else { /* use the static DH prime modulus used by Apache in mod_ssl: */ tls_prime = BN_new(); @@ -2011,6 +2014,14 @@ crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname) tor_assert(tls_prime); dh_param_p_tls = tls_prime; + + if (store_dh_prime_afterwards) + /* save the new dynamic DH modulus to disk. */ + if (crypto_store_dynamic_dh_modulus(dynamic_dh_modulus_fname)) { + log_notice(LD_GENERAL, "Failed while storing dynamic DH modulus. " + "Make sure your data directory is sane."); + } + } /** Initialize dh_param_p and dh_param_g if they are not already diff --git a/src/common/crypto.h b/src/common/crypto.h index 683c8ea38f..bac6db920a 100644 --- a/src/common/crypto.h +++ b/src/common/crypto.h @@ -94,7 +94,6 @@ 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(const char *dynamic_dh_modulus_fname); -int crypto_store_dynamic_dh_modulus(const char *fname); /* convenience function: wraps crypto_create_crypto_env, set_key, and init. */ crypto_cipher_env_t *crypto_create_init_cipher(const char *key, diff --git a/src/or/router.c b/src/or/router.c index 963c781733..fdc83f5087 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -634,16 +634,6 @@ init_keys(void) return -1; } - /** 3b. If we use a dynamic prime, store it to disk. */ - if (get_options()->DynamicDHGroups) { - char *fname = get_datadir_fname2("keys", "dynamic_dh_modulus"); - if (crypto_store_dynamic_dh_modulus(fname)) { - log_notice(LD_GENERAL, "Failed while storing dynamic prime. " - "Make sure your data directory is sane."); - } - tor_free(fname); - } - /* 4. Build our router descriptor. */ /* Must be called after keys are initialized. */ mydesc = router_get_my_descriptor(); -- cgit v1.2.3-54-g00ecf From e3cee8bc2e8df6b39a4122829649e3f9ab920aa6 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Thu, 24 Nov 2011 06:40:02 +0100 Subject: Simply initialize TLS context if DynamicDHGroups change. We used to do init_keys() if DynamicDHGroups changed after a HUP, so that the dynamic DH modulus was stored on the disk. Since we are now doing dynamic DH modulus storing in crypto.c, we can simply initialize the TLS context and be good with it. Introduce a new function router_initialize_tls_context() which initializes the TLS context and use it appropriately. --- src/or/config.c | 26 +++++++++++++++++++++++++- src/or/main.c | 5 +---- src/or/router.c | 21 +++++++++++++-------- src/or/router.h | 1 + 4 files changed, 40 insertions(+), 13 deletions(-) (limited to 'src/or/router.c') diff --git a/src/or/config.c b/src/or/config.c index a846ca9079..f8c4ab314d 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1267,6 +1267,24 @@ get_effective_bwburst(const or_options_t *options) return (uint32_t)bw; } +/** Return True if any changes from old_options to + * new_options needs us to refresh our TLS context. */ +static int +options_transition_requires_fresh_tls_context(const or_options_t *old_options, + const or_options_t *new_options) +{ + tor_assert(new_options); + + if (!old_options) + return 0; + + if ((old_options->DynamicDHGroups != new_options->DynamicDHGroups)) { + return 1; + } + + return 0; +} + /** Fetch the active option list, and take actions based on it. All of the * things we do should survive being done repeatedly. If present, * old_options contains the previous value of the options. @@ -1394,6 +1412,13 @@ options_act(const or_options_t *old_options) log_warn(LD_BUG,"Error initializing keys; exiting"); return -1; } + } else if (old_options && + options_transition_requires_fresh_tls_context(old_options, + options)) { + if (router_initialize_tls_context() < 0) { + log_warn(LD_BUG,"Error initializing TLS context."); + return -1; + } } /* Write our PID to the PID file. If we do not have write permissions we @@ -4075,7 +4100,6 @@ 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->DynamicDHGroups != new_options->DynamicDHGroups || 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 7008d388a1..95f9958aa8 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1161,10 +1161,7 @@ run_scheduled_events(time_t now) last_rotated_x509_certificate = now; if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME_INTERNAL < now) { log_info(LD_GENERAL,"Rotating tls context."); - if (tor_tls_context_init(public_server_mode(options), - get_tlsclient_identity_key(), - is_server ? get_server_identity_key() : NULL, - MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { + if (router_initialize_tls_context() < 0) { log_warn(LD_BUG, "Error reinitializing TLS context"); /* XXX is it a bug here, that we just keep going? -RD */ } diff --git a/src/or/router.c b/src/or/router.c index fdc83f5087..67e98da239 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -484,6 +484,17 @@ v3_authority_check_key_expiry(void) last_warned = now; } + +int +router_initialize_tls_context(void) +{ + return tor_tls_context_init(public_server_mode(get_options()), + get_tlsclient_identity_key(), + server_mode(get_options()) ? + get_server_identity_key() : NULL, + MAX_SSL_KEY_LIFETIME_ADVERTISED); +} + /** 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. @@ -530,10 +541,7 @@ init_keys(void) } set_client_identity_key(prkey); /* Create a TLS context. */ - if (tor_tls_context_init(0, - get_tlsclient_identity_key(), - NULL, - MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { + if (router_initialize_tls_context() < 0) { log_err(LD_GENERAL,"Error creating TLS context for Tor client."); return -1; } @@ -626,10 +634,7 @@ init_keys(void) tor_free(keydir); /* 3. Initialize link key and TLS context. */ - if (tor_tls_context_init(public_server_mode(options), - get_tlsclient_identity_key(), - get_server_identity_key(), - MAX_SSL_KEY_LIFETIME_ADVERTISED) < 0) { + if (router_initialize_tls_context() < 0) { log_err(LD_GENERAL,"Error initializing TLS context"); return -1; } diff --git a/src/or/router.h b/src/or/router.h index f9d156cb09..68eadbf4c2 100644 --- a/src/or/router.h +++ b/src/or/router.h @@ -30,6 +30,7 @@ crypto_pk_env_t *init_key_from_file(const char *fname, int generate, int severity); void v3_authority_check_key_expiry(void); +int router_initialize_tls_context(void); int init_keys(void); int check_whether_orport_reachable(void); -- cgit v1.2.3-54-g00ecf From 055d6c01fff3324dbb38c2d81ad49ccfdb5432c2 Mon Sep 17 00:00:00 2001 From: George Kadianakis Date: Sat, 26 Nov 2011 19:29:57 +0100 Subject: Write dynamic DH parameters to a file. Instead of only writing the dynamic DH prime modulus to a file, write the whole DH parameters set for forward compatibility. At the moment we only accept '2' as the group generator. The DH parameters gets stored in base64-ed DER format to the 'dynamic_dh_params' file. --- src/common/crypto.c | 136 ++++++++++++++++++++++++++++++++-------------------- src/or/config.c | 4 +- src/or/router.c | 1 - 3 files changed, 87 insertions(+), 54 deletions(-) (limited to 'src/or/router.c') diff --git a/src/common/crypto.c b/src/common/crypto.c index 8cf6231921..a38956d3e8 100644 --- a/src/common/crypto.c +++ b/src/common/crypto.c @@ -1852,44 +1852,66 @@ crypto_generate_dynamic_dh_modulus(void) return dynamic_dh_modulus; } -/** Store our dynamic DH modulus to fname for future use. */ +/** Store our dynamic DH modulus (and its group parameters) to + fname for future use. */ static int crypto_store_dynamic_dh_modulus(const char *fname) { - FILE *fp = NULL; + int len, new_len; + DH *dh = NULL; + unsigned char *dh_string_repr = NULL, *cp = NULL; + char *base64_encoded_dh = NULL; int retval = -1; - file_status_t fname_status; tor_assert(fname); - fname_status = file_status(fname); + if (!dh_param_p_tls) { + log_info(LD_CRYPTO, "Tried to store a DH modulus that does not exist."); + goto done; + } - if (fname_status == FN_FILE) { - /* If the fname is a file, then the dynamic DH modulus is already stored.*/ - retval = 0; + if (!(dh = DH_new())) + goto done; + if (!(dh->p = BN_dup(dh_param_p_tls))) + goto done; + if (!(dh->g = BN_new())) goto done; - } else if (fname_status != FN_NOENT) { - log_info(LD_GENERAL, "Dynamic DH modulus filename is occupied."); + if (!BN_set_word(dh->g, DH_GENERATOR)) + goto done; + + len = i2d_DHparams(dh, NULL); + if (len < 0) { + log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (1)."); goto done; } - tor_assert(fname_status == FN_NOENT); + cp = dh_string_repr = tor_malloc_zero(len+1); + len = i2d_DHparams(dh, &cp); + if ((len < 0) || ((cp - dh_string_repr) != len)) { + log_warn(LD_CRYPTO, "Error occured while DER encoding DH modulus (2)."); + goto done; + } - if (!(fp = fopen(fname, "w"))) { - log_notice(LD_GENERAL, "Error while creating dynamic DH modulus file."); + base64_encoded_dh = tor_malloc_zero(len * 2); /* should be enough */ + new_len = base64_encode(base64_encoded_dh, len * 2, + (char *)dh_string_repr, len); + if (new_len < 0) { + log_warn(LD_CRYPTO, "Error occured while base64-encoding DH modulus."); goto done; } - if (BN_print_fp(fp, dh_param_p_tls) == 0) { - log_warn(LD_GENERAL, "Error while printing dynamic DH modulus to file."); + if (write_bytes_to_new_file(fname, base64_encoded_dh, new_len, 0) < 0) { + log_info(LD_CRYPTO, "'%s' was already occupied.", fname); goto done; } retval = 0; done: - if (fp) - fclose(fp); + if (dh) + DH_free(dh); + tor_free(dh_string_repr); + tor_free(base64_encoded_dh); return retval; } @@ -1901,52 +1923,62 @@ crypto_get_stored_dynamic_dh_modulus(const char *fname) { int retval; char *contents = NULL; - DH *dh = NULL; int dh_codes; char *fname_new = NULL; - BIGNUM *dynamic_dh_modulus = BN_new(); + DH *stored_dh = NULL; + BIGNUM *dynamic_dh_modulus = NULL; + int length = 0; + unsigned char *base64_decoded_dh = NULL; + const unsigned char *cp = NULL; tor_assert(fname); - if (!dynamic_dh_modulus) - goto err; - contents = read_file_to_str(fname, RFTS_IGNORE_MISSING, NULL); - if (!contents) - goto err; + if (!contents) { + log_info(LD_CRYPTO, "Could not open file '%s'", fname); + goto done; /*usually means that ENOENT. don't try to move file to broken.*/ + } + + /* 'fname' contains the DH parameters stored in base64-ed DER + format. We are only interested in the DH modulus. */ - retval = BN_hex2bn(&dynamic_dh_modulus, contents); - if (!retval) { - log_warn(LD_GENERAL, "Could not understand the dynamic DH modulus " - "format in '%s'", fname); + cp = base64_decoded_dh = tor_malloc_zero(strlen(contents)); + length = base64_decode((char *)base64_decoded_dh, strlen(contents), + contents, strlen(contents)); + if (length < 0) { + log_warn(LD_CRYPTO, "Stored dynamic DH modulus seems corrupted (base64)."); goto err; } - { /* validate the stored prime */ - dh = DH_new(); - if (!dh) - goto err; - - dh->p = BN_dup(dynamic_dh_modulus); - dh->g = BN_new(); - BN_set_word(dh->g, DH_GENERATOR); + stored_dh = d2i_DHparams(NULL, &cp, length); + if ((!stored_dh) || (cp - base64_decoded_dh != length)) { + log_warn(LD_CRYPTO, "Stored dynamic DH modulus seems corrupted (d2i)."); + goto err; + } - retval = DH_check(dh, &dh_codes); + { /* check the cryptographic qualities of the stored dynamic DH modulus: */ + retval = DH_check(stored_dh, &dh_codes); if (!retval || dh_codes) { - log_warn(LD_GENERAL, "Stored dynamic DH prime is not a safe prime."); + log_warn(LD_CRYPTO, "Stored dynamic DH modulus is not a safe prime."); goto err; } - retval = DH_size(dh); + retval = DH_size(stored_dh); if (retval < DH_BYTES) { - log_warn(LD_GENERAL, "Stored dynamic DH prime is smaller " + log_warn(LD_CRYPTO, "Stored dynamic DH modulus is smaller " "than '%d' bits.", DH_BYTES*8); goto err; } + + if (!BN_is_word(stored_dh->g, 2)) { + log_warn(LD_CRYPTO, "Stored dynamic DH parameters do not use '2' " + "as the group generator."); + goto err; + } } { /* log the dynamic DH modulus: */ - char *s = BN_bn2hex(dynamic_dh_modulus); + char *s = BN_bn2hex(stored_dh->p); tor_assert(s); log_info(LD_OR, "Found stored dynamic DH modulus: [%s]", s); OPENSSL_free(s); @@ -1957,31 +1989,34 @@ crypto_get_stored_dynamic_dh_modulus(const char *fname) err: { /* move broken prime to $filename.broken */ - fname_new = tor_malloc(strlen(fname) + 8); /* no can do if these functions return error */ strlcpy(fname_new, fname, strlen(fname) + 8); strlcat(fname_new, ".broken", strlen(fname) + 8); - log_warn(LD_GENERAL, "Moving broken dynamic DH prime to '%s'.", fname_new); + log_warn(LD_CRYPTO, "Moving broken dynamic DH prime to '%s'.", fname_new); if (replace_file(fname, fname_new)) - log_warn(LD_GENERAL, "Error while moving '%s' to '%s'.", fname, fname_new); + log_notice(LD_CRYPTO, "Error while moving '%s' to '%s'.", + fname, fname_new); tor_free(fname_new); - } - if (dynamic_dh_modulus) { - BN_free(dynamic_dh_modulus); - dynamic_dh_modulus = NULL; + if (stored_dh) { + DH_free(stored_dh); + stored_dh = NULL; } done: tor_free(contents); - if (dh) - DH_free(dh); + tor_free(base64_decoded_dh); + + if (stored_dh) { + dynamic_dh_modulus = BN_dup(stored_dh->p); + DH_free(stored_dh); + } return dynamic_dh_modulus; } @@ -2040,10 +2075,9 @@ crypto_set_tls_dh_prime(const char *dynamic_dh_modulus_fname) if (store_dh_prime_afterwards) /* save the new dynamic DH modulus to disk. */ if (crypto_store_dynamic_dh_modulus(dynamic_dh_modulus_fname)) { - log_notice(LD_GENERAL, "Failed while storing dynamic DH modulus. " + log_notice(LD_CRYPTO, "Failed while storing dynamic DH modulus. " "Make sure your data directory is sane."); } - } /** Initialize dh_param_p and dh_param_g if they are not already diff --git a/src/or/config.c b/src/or/config.c index 9c658614ba..06914b62af 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1384,7 +1384,7 @@ options_act(const or_options_t *old_options) if (server_mode(options)) { if (!old_options) { if (options->DynamicDHGroups) { - char *fname = get_datadir_fname2("keys", "dynamic_dh_modulus"); + char *fname = get_datadir_fname2("keys", "dynamic_dh_params"); crypto_set_tls_dh_prime(fname); tor_free(fname); } else { @@ -1392,7 +1392,7 @@ options_act(const or_options_t *old_options) } } else { if (options->DynamicDHGroups && !old_options->DynamicDHGroups) { - char *fname = get_datadir_fname2("keys", "dynamic_dh_modulus"); + char *fname = get_datadir_fname2("keys", "dynamic_dh_params"); crypto_set_tls_dh_prime(fname); tor_free(fname); } else if (!options->DynamicDHGroups && old_options->DynamicDHGroups) { diff --git a/src/or/router.c b/src/or/router.c index 67e98da239..5d36939a8b 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -484,7 +484,6 @@ v3_authority_check_key_expiry(void) last_warned = now; } - int router_initialize_tls_context(void) { -- cgit v1.2.3-54-g00ecf