aboutsummaryrefslogtreecommitdiffstats
path: root/g10/getkey.c
diff options
context:
space:
mode:
authorNeal H. Walfield <[email protected]>2015-11-03 22:15:27 +0000
committerNeal H. Walfield <[email protected]>2015-11-04 12:19:52 +0000
commite16d7168c54e5f7bc2f0037806ee4f730930eaf0 (patch)
tree8cf75fb29648d091e01533506d6377e645451123 /g10/getkey.c
parentscd: Fix error handling with libusb-compat library. (diff)
downloadgnupg-e16d7168c54e5f7bc2f0037806ee4f730930eaf0.tar.gz
gnupg-e16d7168c54e5f7bc2f0037806ee4f730930eaf0.zip
gpg: Allow multiple --default-key options. Take the last available key.
* g10/getkey.c (parse_def_secret_key): New function. (get_seckey_default): Add parameter ctrl. Update callers. Use parse_def_secret_key to get the default secret key, if any. (getkey_byname): Likewise. (enum_secret_keys): Likewise. * g10/options.h (opt): Change def_secret_key's type from a char * to a strlist_t. * g10/gpg.c (main): When processing --default-key, add the key to OPT.DEF_SECRET_KEY. * g10/gpgv.c (get_session_key): Add parameter ctrl. Update callers. * g10/mainproc.c (proc_pubkey_enc): Likewise. (do_proc_packets): Likewise. * g10/pkclist.c (default_recipient): Likewise. * g10/pubkey-enc.c (get_session_key): Likewise. * g10/sign.c (clearsign_file): Likewise. (sign_symencrypt_file): Likewise. * g10/skclist.c (build_sk_list): Likewise. * g10/test-stubs.c (get_session_key): Likewise. -- Signed-off-by: Neal H. Walield <[email protected]> GnuPG-bug-id: 806
Diffstat (limited to '')
-rw-r--r--g10/getkey.c99
1 files changed, 89 insertions, 10 deletions
diff --git a/g10/getkey.c b/g10/getkey.c
index a5f568956..d3ce7d23f 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -1121,17 +1121,93 @@ get_pubkey_byfprint_fast (PKT_public_key * pk,
return 0;
}
+static const char *
+parse_def_secret_key (ctrl_t ctrl)
+{
+ KEYDB_HANDLE hd = NULL;
+ strlist_t t;
+ static int warned;
+
+ for (t = opt.def_secret_key; t; t = t->next)
+ {
+ gpg_error_t err;
+ KEYDB_SEARCH_DESC desc;
+ KBNODE kb;
+
+ err = classify_user_id (t->d, &desc, 1);
+ if (err)
+ {
+ log_error (_("Invalid value ('%s') for --default-key.\n"),
+ t->d);
+ continue;
+ }
+
+ if (! (desc.mode == KEYDB_SEARCH_MODE_LONG_KID
+ || desc.mode == KEYDB_SEARCH_MODE_FPR16
+ || desc.mode == KEYDB_SEARCH_MODE_FPR20
+ || desc.mode == KEYDB_SEARCH_MODE_FPR)
+ && ! warned)
+ log_info (_("Warning: value '%s' for --default-key"
+ " should be a long keyid or a fingerprint.\n"),
+ t->d);
+
+ if (! hd)
+ hd = keydb_new ();
+ else
+ keydb_search_reset (hd);
+
+ err = keydb_search (hd, &desc, 1, NULL);
+ if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+ continue;
+
+ if (err)
+ {
+ log_error (_("Error reading from keyring: %s.\n"),
+ gpg_strerror (err));
+ t = NULL;
+ break;
+ }
+
+ err = keydb_get_keyblock (hd, &kb);
+ if (err)
+ {
+ log_error (_("error reading keyblock: %s\n"),
+ gpg_strerror (err));
+ continue;
+ }
+
+ err = agent_probe_secret_key (ctrl, kb->pkt->pkt.public_key);
+ release_kbnode (kb);
+ if (! err)
+ {
+ if (! warned)
+ log_debug (_("Using %s as default secret key.\n"), t->d);
+ break;
+ }
+ }
+
+ warned = 1;
+
+ if (hd)
+ keydb_release (hd);
+
+ if (t)
+ return t->d;
+ return NULL;
+}
/* For documentation see keydb.h. */
gpg_error_t
-get_seckey_default (PKT_public_key *pk)
+get_seckey_default (ctrl_t ctrl, PKT_public_key *pk)
{
gpg_error_t err;
strlist_t namelist = NULL;
int include_unusable = 1;
- if (opt.def_secret_key && *opt.def_secret_key)
- add_to_strlist (&namelist, opt.def_secret_key);
+
+ const char *def_secret_key = parse_def_secret_key (ctrl);
+ if (def_secret_key)
+ add_to_strlist (&namelist, def_secret_key);
else
include_unusable = 0;
@@ -1154,15 +1230,19 @@ getkey_bynames (getkey_ctx_t *retctx, PKT_public_key *pk,
/* For documentation see keydb.h. */
gpg_error_t
-getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk,
+getkey_byname (ctrl_t ctrl, getkey_ctx_t *retctx, PKT_public_key *pk,
const char *name, int want_secret, kbnode_t *ret_keyblock)
{
gpg_error_t err;
strlist_t namelist = NULL;
int with_unusable = 1;
+ const char *def_secret_key = NULL;
+
+ if (want_secret && !name)
+ def_secret_key = parse_def_secret_key (ctrl);
- if (want_secret && !name && opt.def_secret_key && *opt.def_secret_key)
- add_to_strlist (&namelist, opt.def_secret_key);
+ if (want_secret && !name && def_secret_key)
+ add_to_strlist (&namelist, def_secret_key);
else if (name)
add_to_strlist (&namelist, name);
else
@@ -2737,7 +2817,7 @@ found:
/* For documentation see keydb.h. */
gpg_error_t
-enum_secret_keys (void **context, PKT_public_key *sk)
+enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *sk)
{
gpg_error_t err = 0;
const char *name;
@@ -2783,8 +2863,7 @@ enum_secret_keys (void **context, PKT_public_key *sk)
switch (c->state)
{
case 0: /* First try to use the --default-key. */
- if (opt.def_secret_key && *opt.def_secret_key)
- name = opt.def_secret_key;
+ name = parse_def_secret_key (ctrl);
c->state = 1;
break;
@@ -2810,7 +2889,7 @@ enum_secret_keys (void **context, PKT_public_key *sk)
}
while (!name || !*name);
- err = getkey_byname (NULL, NULL, name, 1, &c->keyblock);
+ err = getkey_byname (ctrl, NULL, NULL, name, 1, &c->keyblock);
if (err)
{
/* getkey_byname might return a keyblock even in the