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);