summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2015-09-22 09:26:30 -0400
committerNick Mathewson <nickm@torproject.org>2015-09-22 09:26:30 -0400
commitdf0b4f0342fc95f213cb5bb19a1f5260d546c1b6 (patch)
tree550eb99f0f3bba666ac9e60c4de157b69ee265cd
parente94ef30a2fa6ef0197fe9fafbb2469475d868627 (diff)
parent8234fa00539cd6aa560c4fa1502a04e0f9e35a18 (diff)
downloadtor-df0b4f0342fc95f213cb5bb19a1f5260d546c1b6.tar.gz
tor-df0b4f0342fc95f213cb5bb19a1f5260d546c1b6.zip
Merge branch 'feature16769_squashed'
-rw-r--r--changes/feature167694
-rw-r--r--src/or/config.c29
-rw-r--r--src/or/or.h3
-rw-r--r--src/or/routerkeys.c43
-rw-r--r--src/or/routerkeys.h1
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,