diff options
author | Nick Mathewson <nickm@torproject.org> | 2015-09-22 09:26:30 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2015-09-22 09:26:30 -0400 |
commit | df0b4f0342fc95f213cb5bb19a1f5260d546c1b6 (patch) | |
tree | 550eb99f0f3bba666ac9e60c4de157b69ee265cd | |
parent | e94ef30a2fa6ef0197fe9fafbb2469475d868627 (diff) | |
parent | 8234fa00539cd6aa560c4fa1502a04e0f9e35a18 (diff) | |
download | tor-df0b4f0342fc95f213cb5bb19a1f5260d546c1b6.tar.gz tor-df0b4f0342fc95f213cb5bb19a1f5260d546c1b6.zip |
Merge branch 'feature16769_squashed'
-rw-r--r-- | changes/feature16769 | 4 | ||||
-rw-r--r-- | src/or/config.c | 29 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routerkeys.c | 43 | ||||
-rw-r--r-- | src/or/routerkeys.h | 1 |
5 files changed, 71 insertions, 9 deletions
diff --git a/changes/feature16769 b/changes/feature16769 new file mode 100644 index 0000000000..acb2b9c0da --- /dev/null +++ b/changes/feature16769 @@ -0,0 +1,4 @@ + o Minor features (ed25519): + - Add a --newpass option to allow changing or removing the + passphrase of an encrypted key with tor --keygen. Implements + part of ticket 16769. diff --git a/src/or/config.c b/src/or/config.c index 47a1ee1fa5..44fb4ecec6 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -763,6 +763,7 @@ or_options_free(or_options_t *options) } tor_free(options->BridgePassword_AuthDigest_); tor_free(options->command_arg); + tor_free(options->master_key_fname); config_free(&options_format, options); } @@ -1919,6 +1920,12 @@ static const struct { { "--dump-config", ARGUMENT_OPTIONAL }, { "--list-fingerprint", TAKES_NO_ARGUMENT }, { "--keygen", TAKES_NO_ARGUMENT }, + { "--newpass", TAKES_NO_ARGUMENT }, +#if 0 +/* XXXX028: This is not working yet in 0.2.7, so disabling with the + * minimal code modification. */ + { "--master-key", ARGUMENT_NECESSARY }, +#endif { "--no-passphrase", TAKES_NO_ARGUMENT }, { "--passphrase-fd", ARGUMENT_NECESSARY }, { "--verify-config", TAKES_NO_ARGUMENT }, @@ -4528,6 +4535,15 @@ options_init_from_torrc(int argc, char **argv) } } + if (config_line_find(cmdline_only_options, "--newpass")) { + if (command == CMD_KEYGEN) { + get_options_mutable()->change_key_passphrase = 1; + } else { + log_err(LD_CONFIG, "--newpass specified without --keygen!"); + exit(1); + } + } + { const config_line_t *fd_line = config_line_find(cmdline_only_options, "--passphrase-fd"); @@ -4553,6 +4569,19 @@ options_init_from_torrc(int argc, char **argv) } } + { + const config_line_t *key_line = config_line_find(cmdline_only_options, + "--master-key"); + if (key_line) { + if (command != CMD_KEYGEN) { + log_err(LD_CONFIG, "--master-key without --keygen!"); + exit(1); + } else { + get_options_mutable()->master_key_fname = tor_strdup(key_line->value); + } + } + } + err: tor_free(cf); diff --git a/src/or/or.h b/src/or/or.h index 503eb56b65..bec39b2b37 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4313,7 +4313,8 @@ typedef struct { } keygen_force_passphrase; int use_keygen_passphrase_fd; int keygen_passphrase_fd; - + int change_key_passphrase; + char *master_key_fname; } or_options_t; /** Persistent state for an onion router, as saved to disk. */ diff --git a/src/or/routerkeys.c b/src/or/routerkeys.c index b1e9ed36f0..765dac883a 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -200,8 +200,17 @@ write_secret_key(const ed25519_secret_key_t *key, int encrypted, { if (encrypted) { int r = write_encrypted_secret_key(key, encrypted_fname); - if (r != 0) - return r; /* Either succeeded or failed unrecoverably */ + if (r == 1) { + /* Success! */ + + /* Try to unlink the unencrypted key, if any existed before */ + if (strcmp(fname, encrypted_fname)) + unlink(fname); + return r; + } else if (r != 0) { + /* Unrecoverable failure! */ + return r; + } fprintf(stderr, "Not encrypting the secret key.\n"); } @@ -253,6 +262,9 @@ write_secret_key(const ed25519_secret_key_t *key, int encrypted, * * If INIT_ED_KEY_SUGGEST_KEYGEN is set, have log messages about failures * refer to the --keygen option. + * + * If INIT_ED_KEY_EXPLICIT_FNAME is set, use the provided file name for the + * secret key file, encrypted or not. */ ed25519_keypair_t * ed_key_init_from_file(const char *fname, uint32_t flags, @@ -275,6 +287,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags, const int split = !! (flags & INIT_ED_KEY_SPLIT); const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_SECRET); const int offline_secret = !! (flags & INIT_ED_KEY_OFFLINE_SECRET); + const int explicit_fname = !! (flags & INIT_ED_KEY_EXPLICIT_FNAME); /* we don't support setting both of these flags at once. */ tor_assert((flags & (INIT_ED_KEY_NO_REPAIR|INIT_ED_KEY_NEEDCERT)) != @@ -287,8 +300,13 @@ ed_key_init_from_file(const char *fname, uint32_t flags, char *got_tag = NULL; ed25519_keypair_t *keypair = tor_malloc_zero(sizeof(ed25519_keypair_t)); - tor_asprintf(&secret_fname, "%s_secret_key", fname); - tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname); + if (explicit_fname) { + secret_fname = tor_strdup(fname); + encrypted_secret_fname = tor_strdup(fname); + } else { + tor_asprintf(&secret_fname, "%s_secret_key", fname); + tor_asprintf(&encrypted_secret_fname, "%s_secret_key_encrypted", fname); + } tor_asprintf(&public_fname, "%s_public_key", fname); tor_asprintf(&cert_fname, "%s_cert", fname); @@ -441,7 +459,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags, goto err; } - /* if it's absent, make a new keypair and save it. */ + /* if it's absent, make a new keypair... */ if (!have_secret && !found_public) { tor_free(keypair); keypair = ed_key_new(signing_key, flags, now, lifetime, @@ -450,8 +468,12 @@ ed_key_init_from_file(const char *fname, uint32_t flags, tor_log(severity, LD_OR, "Couldn't create keypair"); goto err; } - created_pk = created_sk = created_cert = 1; + } + + /* Write it to disk if we're supposed to do with a new passphrase, or if + * we just created it. */ + if (created_sk || (have_secret && get_options()->change_key_passphrase)) { if (write_secret_key(&keypair->seckey, encrypt_key, secret_fname, tag, encrypted_secret_fname) < 0 @@ -686,7 +708,7 @@ load_ed_keys(const or_options_t *options, time_t now) const int need_new_signing_key = NULL == use_signing || EXPIRES_SOON(check_signing_cert, 0) || - options->command == CMD_KEYGEN; + (options->command == CMD_KEYGEN && ! options->change_key_passphrase); const int want_new_signing_key = need_new_signing_key || EXPIRES_SOON(check_signing_cert, options->TestingSigningKeySlop); @@ -747,7 +769,12 @@ load_ed_keys(const or_options_t *options, time_t now) goto err; } tor_free(fname); - fname = options_get_datadir_fname2(options, "keys", "ed25519_master_id"); + if (options->master_key_fname) { + fname = tor_strdup(options->master_key_fname); + flags |= INIT_ED_KEY_EXPLICIT_FNAME; + } else { + fname = options_get_datadir_fname2(options, "keys", "ed25519_master_id"); + } id = ed_key_init_from_file( fname, flags, diff --git a/src/or/routerkeys.h b/src/or/routerkeys.h index b396779bd2..0e1c62571f 100644 --- a/src/or/routerkeys.h +++ b/src/or/routerkeys.h @@ -18,6 +18,7 @@ #define INIT_ED_KEY_NO_REPAIR (1u<<9) #define INIT_ED_KEY_SUGGEST_KEYGEN (1u<<10) #define INIT_ED_KEY_OFFLINE_SECRET (1u<<11) +#define INIT_ED_KEY_EXPLICIT_FNAME (1u<<12) struct tor_cert_st; ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags, |