diff --git a/NEWS b/NEWS index 164b1db09..0cb21fa9c 100644 --- a/NEWS +++ b/NEWS @@ -19,8 +19,8 @@ Noteworthy changes in version 2.1.10 (unreleased) * gpg: New option --only-sign-text-ids to exclude photo IDs from key signing. - * gpg: Check for ambigious or non-matching key specification of - command line options. + * gpg: Check for ambigious or non-matching key specification in the + config file or given to --encrypt-to. * gpg: Show the used card reader with --card-status. diff --git a/g10/gpg.c b/g10/gpg.c index c8db8f08f..2b4842139 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -2116,7 +2116,12 @@ check_user_ids (strlist_t *sp, KEYDB_HANDLE hd = NULL; - if (! s) + /* A quick check to avoid allocating a new strlist if we can skip + all keys. Handles also the case of !SP. See below for details. */ + for (t = s; t && (!(t->flags & PK_LIST_CONFIG) + && !(t->flags & PK_LIST_ENCRYPT_TO)); t = t->next) + ; + if (!t) return 0; for (t = s; t; t = t->next) @@ -2131,8 +2136,19 @@ check_user_ids (strlist_t *sp, /* We also potentially need a ! at the end. */ char fingerprint[2 * MAX_FINGERPRINT_LEN + 1 + 1]; + /* If the key has been given on the command line and it has not + been given by one of the encrypt-to options, we skip the + checks. The reason is that the actual key selection code + does its own checks and provides proper status message to the + caller to detect the wrong keys. */ + if (!(t->flags & PK_LIST_CONFIG) && !(t->flags & PK_LIST_ENCRYPT_TO)) + { + add_to_strlist (&s2, t->d); + s2->flags = t->flags; + continue; + } - switch (t->flags >> 2) + switch (t->flags >> PK_LIST_SHIFT) { case oDefaultKey: option = "--default-key"; break; case oEncryptTo: option = "--encrypt-to"; break; @@ -2141,7 +2157,8 @@ check_user_ids (strlist_t *sp, case oRecipient: option = "--recipient"; break; case oHiddenRecipient: option = "--hidden-recipient"; break; case oLocalUser: option = "--local-user"; break; - default: log_bug ("Unsupport option: %d\n", t->flags >> 2); + default: + log_bug ("Unsupport option: %d\n", (t->flags >> PK_LIST_SHIFT)); } if (DBG_LOOKUP) @@ -2338,7 +2355,9 @@ main (int argc, char **argv) const char *fname; char *username; int may_coredump; - strlist_t sl, remusr= NULL, locusr=NULL; + strlist_t sl; + strlist_t remusr = NULL; + strlist_t locusr = NULL; strlist_t nrings = NULL; armor_filter_context_t *afx = NULL; int detached_sig = 0; @@ -2828,7 +2847,7 @@ main (int argc, char **argv) #endif /*!NO_TRUST_MODELS*/ case oDefaultKey: sl = add_to_strlist (&opt.def_secret_key, pargs.r.ret_str); - sl->flags = (pargs.r_opt << 2); + sl->flags = (pargs.r_opt << PK_LIST_SHIFT); break; case oDefRecipient: if( *pargs.r.ret_str ) @@ -3020,23 +3039,32 @@ main (int argc, char **argv) case oNoEncryptTo: opt.no_encrypt_to = 1; break; case oEncryptTo: /* store the recipient in the second list */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = (pargs.r_opt << 2) | 1; + sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_ENCRYPT_TO); + if (configfp) + sl->flags |= PK_LIST_CONFIG; break; case oHiddenEncryptTo: /* store the recipient in the second list */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = (pargs.r_opt << 2) | 1|2; + sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) + | PK_LIST_ENCRYPT_TO|PK_LIST_HIDDEN); + if (configfp) + sl->flags |= PK_LIST_CONFIG; break; case oEncryptToDefaultKey: opt.encrypt_to_default_key = 1; break; case oRecipient: /* store the recipient */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = (pargs.r_opt << 2); + sl->flags = (pargs.r_opt << PK_LIST_SHIFT); + if (configfp) + sl->flags |= PK_LIST_CONFIG; any_explicit_recipient = 1; break; case oHiddenRecipient: /* store the recipient with a flag */ sl = add_to_strlist2( &remusr, pargs.r.ret_str, utf8_strings ); - sl->flags = (pargs.r_opt << 2) | 2; + sl->flags = ((pargs.r_opt << PK_LIST_SHIFT) | PK_LIST_HIDDEN); + if (configfp) + sl->flags |= PK_LIST_CONFIG; any_explicit_recipient = 1; break; @@ -3080,7 +3108,9 @@ main (int argc, char **argv) case oNoAskCertLevel: opt.ask_cert_level = 0; break; case oLocalUser: /* store the local users */ sl = add_to_strlist2( &locusr, pargs.r.ret_str, utf8_strings ); - sl->flags = (pargs.r_opt << 2); + sl->flags = (pargs.r_opt << PK_LIST_SHIFT); + if (configfp) + sl->flags |= PK_LIST_CONFIG; break; case oCompress: /* this is the -z command line option */ @@ -4010,7 +4040,8 @@ main (int argc, char **argv) if (default_key) { sl = add_to_strlist2 (&remusr, default_key, utf8_strings); - sl->flags = (oEncryptToDefaultKey << 2) | 1; + sl->flags = ((oEncryptToDefaultKey << PK_LIST_SHIFT) + | PK_LIST_ENCRYPT_TO); } else if (have_def_secret_key) log_info (_("option '%s' given, but no valid default keys given\n"), diff --git a/g10/keydb.h b/g10/keydb.h index 919f3fd77..d7aa43271 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -69,6 +69,14 @@ enum resource_type { }; +/* Bit flags used with build_pk_list. */ +#define PK_LIST_ENCRYPT_TO 1 /* This is an encrypt-to recipient. */ +#define PK_LIST_HIDDEN 2 /* This is a hidden recipient. */ +#define PK_LIST_CONFIG 4 /* Specified via config file. */ +/* To store private data in the flags they must be left shifted by + this value. */ +#define PK_LIST_SHIFT 3 + /**************** * A data structure to hold information about the external position * of a keyblock. diff --git a/g10/pkclist.c b/g10/pkclist.c index 480578254..c86566008 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -890,8 +890,8 @@ find_and_check_key (ctrl_t ctrl, const char *name, unsigned int use, value but not very useful. Group expansion is done on these names; they may be in any of the user Id formats we can handle. The flags bits for each string in the string list are used for: - Bit 0: This is an encrypt-to recipient. - Bit 1: This is a hidden recipient. + Bit 0 (PK_LIST_ENCRYPT_TO): This is an encrypt-to recipient. + Bit 1 (PK_LIST_HIDDEN) : This is a hidden recipient. USE is the desired use for the key - usually PUBKEY_USAGE_ENC. @@ -921,7 +921,7 @@ build_pk_list (ctrl_t ctrl, * list of the encrypt-to ones (we always trust them). */ for ( rov = remusr; rov; rov = rov->next ) { - if ( !(rov->flags & 1) ) + if ( !(rov->flags & PK_LIST_ENCRYPT_TO) ) { /* This is a regular recipient; i.e. not an encrypt-to one. */ @@ -929,7 +929,7 @@ build_pk_list (ctrl_t ctrl, /* Hidden recipients are not allowed while in PGP mode, issue a warning and switch into GnuPG mode. */ - if ((rov->flags&2) && (PGP6 || PGP7 || PGP8)) + if ((rov->flags & PK_LIST_HIDDEN) && (PGP6 || PGP7 || PGP8)) { log_info(_("you may not use %s while in %s mode\n"), "--hidden-recipient", @@ -973,13 +973,13 @@ build_pk_list (ctrl_t ctrl, r = xmalloc( sizeof *r ); r->pk = pk; pk = NULL; r->next = pk_list; - r->flags = (rov->flags&2)?1:0; + r->flags = (rov->flags&PK_LIST_HIDDEN)?1:0; pk_list = r; /* Hidden encrypt-to recipients are not allowed while in PGP mode, issue a warning and switch into GnuPG mode. */ - if ((r->flags&1) && (PGP6 || PGP7 || PGP8)) + if ((r->flags&PK_LIST_ENCRYPT_TO) && (PGP6 || PGP7 || PGP8)) { log_info(_("you may not use %s while in %s mode\n"), "--hidden-encrypt-to", @@ -1196,10 +1196,11 @@ build_pk_list (ctrl_t ctrl, any_recipients = 0; for (; remusr; remusr = remusr->next ) { - if ( (remusr->flags & 1) ) + if ( (remusr->flags & PK_LIST_ENCRYPT_TO) ) continue; /* encrypt-to keys are already handled. */ - rc = find_and_check_key (ctrl, remusr->d, use, !!(remusr->flags&2), + rc = find_and_check_key (ctrl, remusr->d, use, + !!(remusr->flags&PK_LIST_HIDDEN), &pk_list); if (rc) goto fail;