From d8f031aec2ee84c753ef282577c7f4fcf0123d2f Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 1 Sep 2015 10:41:02 -0400 Subject: [PATCH 1/4] Add a new --newpass option to add or remove secret key passphrases. --- changes/feature16769 | 3 +++ src/or/config.c | 10 ++++++++++ src/or/or.h | 1 + src/or/routerkeys.c | 23 ++++++++++++++++++----- 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 changes/feature16769 diff --git a/changes/feature16769 b/changes/feature16769 new file mode 100644 index 0000000000..62d373e5cc --- /dev/null +++ b/changes/feature16769 @@ -0,0 +1,3 @@ + o Minor features (ed25519): + - Add a --newpass option to allow changing or removing the + passphrase of an encrypted key. \ No newline at end of file diff --git a/src/or/config.c b/src/or/config.c index 6e782de0e0..b4a490c70f 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1918,6 +1918,7 @@ static const struct { { "--dump-config", ARGUMENT_OPTIONAL }, { "--list-fingerprint", TAKES_NO_ARGUMENT }, { "--keygen", TAKES_NO_ARGUMENT }, + { "--newpass", TAKES_NO_ARGUMENT }, { "--no-passphrase", TAKES_NO_ARGUMENT }, { "--passphrase-fd", ARGUMENT_NECESSARY }, { "--verify-config", TAKES_NO_ARGUMENT }, @@ -4512,6 +4513,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"); diff --git a/src/or/or.h b/src/or/or.h index 8c40f1ab67..0637325b24 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4302,6 +4302,7 @@ typedef struct { } keygen_force_passphrase; int use_keygen_passphrase_fd; int keygen_passphrase_fd; + int change_key_passphrase; } 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 50659fcb69..be5c2c33a1 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"); } @@ -432,7 +441,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, @@ -441,8 +450,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 @@ -671,7 +684,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); From bca4211de5464cd159592b359b2f16eb64d3c07f Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 1 Sep 2015 10:58:53 -0400 Subject: [PATCH 2/4] Add a --master-key option This lets the user override the default location for the master key when used with --keygen Part of 16769. --- changes/feature16769 | 6 +++++- src/or/config.c | 15 +++++++++++++++ src/or/or.h | 1 + src/or/routerkeys.c | 20 +++++++++++++++++--- src/or/routerkeys.h | 1 + 5 files changed, 39 insertions(+), 4 deletions(-) diff --git a/changes/feature16769 b/changes/feature16769 index 62d373e5cc..49e9f3591a 100644 --- a/changes/feature16769 +++ b/changes/feature16769 @@ -1,3 +1,7 @@ o Minor features (ed25519): - Add a --newpass option to allow changing or removing the - passphrase of an encrypted key. \ No newline at end of file + passphrase of an encrypted key with tor --keygen. Implements + part of ticket 16769. + - Add a --master-key option to allow overriding the location of + the master key when running tor --keygen. Implements part of + ticket 16769. diff --git a/src/or/config.c b/src/or/config.c index b4a490c70f..d954316b3b 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -762,6 +762,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,7 @@ static const struct { { "--list-fingerprint", TAKES_NO_ARGUMENT }, { "--keygen", TAKES_NO_ARGUMENT }, { "--newpass", TAKES_NO_ARGUMENT }, + { "--master-key", ARGUMENT_NECESSARY }, { "--no-passphrase", TAKES_NO_ARGUMENT }, { "--passphrase-fd", ARGUMENT_NECESSARY }, { "--verify-config", TAKES_NO_ARGUMENT }, @@ -4547,6 +4549,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 0637325b24..22c1eb29f8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -4303,6 +4303,7 @@ typedef struct { 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 be5c2c33a1..197dbf87a1 100644 --- a/src/or/routerkeys.c +++ b/src/or/routerkeys.c @@ -258,6 +258,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, @@ -279,6 +282,7 @@ ed_key_init_from_file(const char *fname, uint32_t flags, const int norepair = !! (flags & INIT_ED_KEY_NO_REPAIR); const int split = !! (flags & INIT_ED_KEY_SPLIT); const int omit_secret = !! (flags & INIT_ED_KEY_OMIT_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)) != @@ -291,8 +295,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); @@ -729,7 +738,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 b4e73aa33f..f9eb777e90 100644 --- a/src/or/routerkeys.h +++ b/src/or/routerkeys.h @@ -17,6 +17,7 @@ #define INIT_ED_KEY_TRY_ENCRYPTED (1u<<8) #define INIT_ED_KEY_NO_REPAIR (1u<<9) #define INIT_ED_KEY_SUGGEST_KEYGEN (1u<<10) +#define INIT_ED_KEY_EXPLICIT_FNAME (1u<<11) struct tor_cert_st; ed25519_keypair_t *ed_key_init_from_file(const char *fname, uint32_t flags, From 1911f80fb5630b78bfca9c2dc994addf8e401c77 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 21 Sep 2015 13:07:38 -0400 Subject: [PATCH 3/4] Disable --master-key as not-yet-working for 0.2.7 --- src/or/config.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/or/config.c b/src/or/config.c index d954316b3b..1962e24efd 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1920,7 +1920,11 @@ static const struct { { "--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 }, From 8234fa00539cd6aa560c4fa1502a04e0f9e35a18 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 22 Sep 2015 09:22:09 -0400 Subject: [PATCH 4/4] Remove --master-key form the changes file --- changes/feature16769 | 3 --- 1 file changed, 3 deletions(-) diff --git a/changes/feature16769 b/changes/feature16769 index 49e9f3591a..acb2b9c0da 100644 --- a/changes/feature16769 +++ b/changes/feature16769 @@ -2,6 +2,3 @@ - Add a --newpass option to allow changing or removing the passphrase of an encrypted key with tor --keygen. Implements part of ticket 16769. - - Add a --master-key option to allow overriding the location of - the master key when running tor --keygen. Implements part of - ticket 16769.