Index: b/g10/getkey.c =================================================================== --- b/g10/getkey.c +++ b/g10/getkey.c @@ -1121,17 +1121,91 @@ return 0; } +static const char * +parse_def_secret_key (ctrl_t ctrl) +{ + KEYDB_HANDLE hd = NULL; + strlist_t t; + + 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)) + { + log_error (_("Invalid value ('%s') for --default-key:" + " value must be a long keyid or a fingerprint.\n"), + t->d); + continue; + } + + 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) + { + log_debug (_("Using %s as default secret key.\n"), t->d); + break; + } + } + + 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 +1228,19 @@ /* 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 +2815,7 @@ /* 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 +2861,7 @@ 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 +2887,7 @@ } 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 Index: b/g10/gpg.c =================================================================== --- b/g10/gpg.c +++ b/g10/gpg.c @@ -2577,7 +2577,9 @@ case oTrustDBName: trustdb_name = pargs.r.ret_str; break; #endif /*!NO_TRUST_MODELS*/ - case oDefaultKey: opt.def_secret_key = pargs.r.ret_str; break; + case oDefaultKey: + add_to_strlist (&opt.def_secret_key, pargs.r.ret_str); + break; case oDefRecipient: if( *pargs.r.ret_str ) { @@ -3865,7 +3867,7 @@ case aSignSym: /* sign and conventionally encrypt the given file */ if (argc > 1) wrong_args(_("--sign --symmetric [filename]")); - rc = sign_symencrypt_file (fname, locusr); + rc = sign_symencrypt_file (ctrl, fname, locusr); if (rc) { write_status_failure ("sign-symencrypt", rc); @@ -3877,7 +3879,7 @@ case aClearsign: /* make a clearsig */ if( argc > 1 ) wrong_args(_("--clearsign [filename]")); - if( (rc = clearsign_file(fname, locusr, NULL)) ) + if( (rc = clearsign_file (ctrl, fname, locusr, NULL)) ) { write_status_failure ("sign", rc); log_error("%s: clearsign failed: %s\n", Index: b/g10/gpgv.c =================================================================== --- b/g10/gpgv.c +++ b/g10/gpgv.c @@ -386,8 +386,9 @@ * No encryption here but mainproc links to these functions. */ gpg_error_t -get_session_key (PKT_pubkey_enc *k, DEK *dek) +get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek) { + (void)ctrl; (void)k; (void)dek; return GPG_ERR_GENERAL; Index: b/g10/keydb.h =================================================================== --- b/g10/keydb.h +++ b/g10/keydb.h @@ -364,8 +364,8 @@ /*-- skclist.c --*/ int random_is_faked (void); void release_sk_list( SK_LIST sk_list ); -gpg_error_t build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list, - unsigned use); +gpg_error_t build_sk_list (ctrl_t ctrl, strlist_t locusr, + SK_LIST *ret_sk_list, unsigned use); /*-- passphrase.h --*/ unsigned char encode_s2k_iterations (int iterations); @@ -605,7 +605,7 @@ This function returns the first match. Additional results can be returned using getkey_next. */ -gpg_error_t get_seckey_default (PKT_public_key *pk); +gpg_error_t get_seckey_default (ctrl_t ctrl, PKT_public_key *pk); /* Search for keys matching some criteria. @@ -686,7 +686,8 @@ FIXME: We also have the get_pubkey_byname function which has a different semantic. Should be merged with this one. */ -gpg_error_t getkey_byname (getkey_ctx_t *retctx, PKT_public_key *pk, +gpg_error_t getkey_byname (ctrl_t ctrl, + getkey_ctx_t *retctx, PKT_public_key *pk, const char *name, int want_secret, kbnode_t *ret_keyblock); @@ -748,7 +749,7 @@ if (gpg_err_code (err) != GPG_ERR_EOF) ; // An error occured. */ -gpg_error_t enum_secret_keys (void **context, PKT_public_key *pk); +gpg_error_t enum_secret_keys (ctrl_t ctrl, void **context, PKT_public_key *pk); /* Set the mainkey_id fields for all keys in KEYBLOCK. This is usually done by merge_selfsigs but at some places we only need the Index: b/g10/keyedit.c =================================================================== --- b/g10/keyedit.c +++ b/g10/keyedit.c @@ -565,7 +565,7 @@ * why to sign keys using a subkey. Implementation of USAGE_CERT * is just a hack in getkey.c and does not mean that a subkey * marked as certification capable will be used. */ - rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_CERT); + rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_CERT); if (rc) goto leave; @@ -2319,7 +2319,7 @@ err = gpg_error_from_syserror (); goto leave; } - err = getkey_byname (NULL, pk, username, 1, &keyblock); + err = getkey_byname (ctrl, NULL, pk, username, 1, &keyblock); if (err) goto leave; Index: b/g10/main.h =================================================================== --- b/g10/main.h +++ b/g10/main.h @@ -236,8 +236,9 @@ const char *cache_nonce); int sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, int do_encrypt, strlist_t remusr, const char *outfile ); -int clearsign_file( const char *fname, strlist_t locusr, const char *outfile ); -int sign_symencrypt_file (const char *fname, strlist_t locusr); +int clearsign_file (ctrl_t ctrl, + const char *fname, strlist_t locusr, const char *outfile); +int sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr); /*-- sig-check.c --*/ Index: b/g10/mainproc.c =================================================================== --- b/g10/mainproc.c +++ b/g10/mainproc.c @@ -106,7 +106,7 @@ /*** Local prototypes. ***/ -static int do_proc_packets (CTX c, iobuf_t a); +static int do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a); static void list_node (CTX c, kbnode_t node); static void proc_tree (CTX c, kbnode_t node); static int literals_seen; @@ -366,7 +366,7 @@ static void -proc_pubkey_enc (CTX c, PACKET *pkt) +proc_pubkey_enc (ctrl_t ctrl, CTX c, PACKET *pkt) { PKT_pubkey_enc *enc; int result = 0; @@ -428,7 +428,7 @@ else { c->dek = xmalloc_secure_clear (sizeof *c->dek); - if ((result = get_session_key (enc, c->dek))) + if ((result = get_session_key (ctrl, enc, c->dek))) { /* Error: Delete the DEK. */ xfree (c->dek); @@ -1195,7 +1195,7 @@ c->ctrl = ctrl; c->anchor = anchor; - rc = do_proc_packets (c, a); + rc = do_proc_packets (ctrl, c, a); xfree (c); return rc; @@ -1218,7 +1218,7 @@ c->signed_data.used = !!signedfiles; c->sigfilename = sigfilename; - rc = do_proc_packets ( c, a ); + rc = do_proc_packets (ctrl, c, a); /* If we have not encountered any signature we print an error messages, send a NODATA status back and return an error code. @@ -1261,7 +1261,7 @@ c->signed_data.data_names = NULL; c->signed_data.used = (signed_data_fd != -1); - rc = do_proc_packets ( c, a ); + rc = do_proc_packets (ctrl, c, a); /* If we have not encountered any signature we print an error messages, send a NODATA status back and return an error code. @@ -1294,7 +1294,7 @@ c->ctrl = ctrl; c->anchor = anchor; c->encrypt_only = 1; - rc = do_proc_packets (c, a); + rc = do_proc_packets (ctrl, c, a); xfree (c); return rc; } @@ -1320,7 +1320,7 @@ static int -do_proc_packets (CTX c, iobuf_t a) +do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) { PACKET *pkt; int rc = 0; @@ -1352,7 +1352,7 @@ { switch (pkt->pkttype) { - case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break; + case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break; case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break; case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break; @@ -1396,7 +1396,7 @@ case PKT_SIGNATURE: newpkt = add_signature (c, pkt); break; case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break; - case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break; + case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break; case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break; case PKT_PLAINTEXT: proc_plaintext (c, pkt); break; @@ -1422,7 +1422,7 @@ break; case PKT_USER_ID: newpkt = add_user_id (c, pkt); break; case PKT_SIGNATURE: newpkt = add_signature (c, pkt); break; - case PKT_PUBKEY_ENC: proc_pubkey_enc (c, pkt); break; + case PKT_PUBKEY_ENC: proc_pubkey_enc (ctrl, c, pkt); break; case PKT_SYMKEY_ENC: proc_symkey_enc (c, pkt); break; case PKT_ENCRYPTED: case PKT_ENCRYPTED_MDC: proc_encrypted (c, pkt); break; Index: b/g10/options.h =================================================================== --- b/g10/options.h +++ b/g10/options.h @@ -87,7 +87,7 @@ int compress_level; int bz2_compress_level; int bz2_decompress_lowmem; - const char *def_secret_key; + strlist_t def_secret_key; char *def_recipient; int def_recipient_self; strlist_t secret_keys_to_try; Index: b/g10/packet.h =================================================================== --- b/g10/packet.h +++ b/g10/packet.h @@ -652,7 +652,7 @@ /*-- pubkey-enc.c --*/ -gpg_error_t get_session_key (PKT_pubkey_enc *k, DEK *dek); +gpg_error_t get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek); gpg_error_t get_override_session_key (DEK *dek, const char *string); /*-- compress.c --*/ Index: b/g10/pkclist.c =================================================================== --- b/g10/pkclist.c +++ b/g10/pkclist.c @@ -702,7 +702,7 @@ * Return a malloced string with a default recipient if there is any */ static char * -default_recipient(void) +default_recipient(ctrl_t ctrl) { PKT_public_key *pk; byte fpr[MAX_FINGERPRINT_LEN+1]; @@ -715,7 +715,7 @@ if( !opt.def_recipient_self ) return NULL; pk = xmalloc_clear( sizeof *pk ); - i = get_seckey_default (pk); + i = get_seckey_default (ctrl, pk); if( i ) { free_public_key( pk ); return NULL; @@ -1010,7 +1010,7 @@ if (pk_list) any_recipients = 1; - def_rec = default_recipient(); + def_rec = default_recipient(ctrl); have_def_rec = !!def_rec; if ( !have_def_rec ) tty_printf(_("You did not specify a user ID. (you may use \"-r\")\n")); @@ -1153,7 +1153,7 @@ pk = NULL; } } - else if ( !any_recipients && (def_rec = default_recipient()) ) + else if ( !any_recipients && (def_rec = default_recipient(ctrl)) ) { /* We are in batch mode and have only a default recipient. */ pk = xmalloc_clear( sizeof *pk ); Index: b/g10/pubkey-enc.c =================================================================== --- b/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -72,7 +72,7 @@ * which should have been allocated in secure memory by the caller. */ gpg_error_t -get_session_key (PKT_pubkey_enc * k, DEK * dek) +get_session_key (ctrl_t ctrl, PKT_pubkey_enc * k, DEK * dek) { PKT_public_key *sk = NULL; int rc; @@ -102,7 +102,7 @@ { free_public_key (sk); sk = xmalloc_clear (sizeof *sk); - rc = enum_secret_keys (&enum_context, sk); + rc = enum_secret_keys (ctrl, &enum_context, sk); if (rc) { rc = GPG_ERR_NO_SECKEY; @@ -127,7 +127,7 @@ else if (gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) break; /* Don't try any more secret keys. */ } - enum_secret_keys (&enum_context, NULL); /* free context */ + enum_secret_keys (ctrl, &enum_context, NULL); /* free context */ } leave: Index: b/g10/revoke.c =================================================================== --- b/g10/revoke.c +++ b/g10/revoke.c @@ -248,7 +248,7 @@ if(locusr) { - rc=build_sk_list(locusr, &sk_list, PUBKEY_USAGE_CERT); + rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_CERT); if(rc) goto leave; } Index: b/g10/sign.c =================================================================== --- b/g10/sign.c +++ b/g10/sign.c @@ -769,7 +769,7 @@ /* Note: In the old non-agent version the following call used to unprotect the secret key. This is now done on demand by the agent. */ - if( (rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG )) ) + if( (rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_SIG )) ) goto leave; if (encryptflag @@ -1057,7 +1057,8 @@ * make a clear signature. note that opt.armor is not needed */ int -clearsign_file( const char *fname, strlist_t locusr, const char *outfile ) +clearsign_file (ctrl_t ctrl, + const char *fname, strlist_t locusr, const char *outfile ) { armor_filter_context_t *afx; progress_filter_context_t *pfx; @@ -1080,7 +1081,7 @@ /* Note: In the old non-agent version the following call used to unprotect the secret key. This is now done on demand by the agent. */ - if( (rc=build_sk_list( locusr, &sk_list, PUBKEY_USAGE_SIG )) ) + if( (rc=build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_SIG )) ) goto leave; /* prepare iobufs */ @@ -1191,7 +1192,7 @@ * FIXME: Far too much code is duplicated - revamp the whole file. */ int -sign_symencrypt_file (const char *fname, strlist_t locusr) +sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr) { armor_filter_context_t *afx; progress_filter_context_t *pfx; @@ -1224,7 +1225,7 @@ /* Note: In the old non-agent version the following call used to unprotect the secret key. This is now done on demand by the agent. */ - rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_SIG); + rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_SIG); if (rc) goto leave; Index: b/g10/skclist.c =================================================================== --- b/g10/skclist.c +++ b/g10/skclist.c @@ -114,7 +114,8 @@ gpg_error_t -build_sk_list (strlist_t locusr, SK_LIST *ret_sk_list, unsigned int use) +build_sk_list (ctrl_t ctrl, + strlist_t locusr, SK_LIST *ret_sk_list, unsigned int use) { gpg_error_t err; SK_LIST sk_list = NULL; @@ -125,7 +126,7 @@ pk = xmalloc_clear (sizeof *pk); pk->req_usage = use; - if ((err = getkey_byname (NULL, pk, NULL, 1, NULL))) + if ((err = getkey_byname (ctrl, NULL, pk, NULL, 1, NULL))) { free_public_key (pk); pk = NULL; @@ -182,7 +183,7 @@ } pk = xmalloc_clear (sizeof *pk); pk->req_usage = use; - if ((err = getkey_byname (NULL, pk, locusr->d, 1, NULL))) + if ((err = getkey_byname (ctrl, NULL, pk, locusr->d, 1, NULL))) { free_public_key (pk); pk = NULL; Index: b/g10/test-stubs.c =================================================================== --- b/g10/test-stubs.c +++ b/g10/test-stubs.c @@ -198,8 +198,9 @@ * No encryption here but mainproc links to these functions. */ gpg_error_t -get_session_key (PKT_pubkey_enc *k, DEK *dek) +get_session_key (ctrl_t ctrl, PKT_pubkey_enc *k, DEK *dek) { + (void)ctrl; (void)k; (void)dek; return GPG_ERR_GENERAL;