Index: b/g10/gpg.c =================================================================== --- b/g10/gpg.c +++ b/g10/gpg.c @@ -2081,6 +2081,128 @@ return configname; } +strlist_t +check_user_ids (strlist_t s, const char *option, + int warn_possibly_ambiguous, int die_if_not_found) +{ + strlist_t t; + KEYDB_HANDLE hd = NULL; + int die = 0; + PKT_public_key *pk; + char fingerprint_bin[MAX_FINGERPRINT_LEN]; + size_t fingerprint_bin_len = sizeof (fingerprint_bin); + char fingerprint[2 * MAX_FINGERPRINT_LEN + 1]; + strlist_t s2 = NULL; + + if (! s) + return NULL; + + for (t = s; 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') passed to %s.\n"), + t->d, option); + die = 1; + continue; + } + + if (warn_possibly_ambiguous + && ! (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_info (_("Warning: value '%s' for %s" + " should be a long keyid or a fingerprint.\n"), + t->d, option); + + 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) + { + if (die_if_not_found) + { + log_error (_("no such key corresponding to %s (passed to %s)\n"), + t->d, option); + die = 1; + } + continue; + } + if (err) + { + log_error (_("error looking up %s in keyring: %s.\n"), + t->d, gpg_strerror (err)); + die = 1; + break; + } + + err = keydb_get_keyblock (hd, &kb); + if (err) + { + log_error (_("error reading key block for %s: %s\n"), + t->d, gpg_strerror (err)); + die = 1; + continue; + } + + pk = kb->pkt->pkt.public_key; + fingerprint_from_pk (pk, fingerprint_bin, &fingerprint_bin_len); + assert (fingerprint_bin_len == sizeof (fingerprint_bin)); + bin2hex (fingerprint_bin, MAX_FINGERPRINT_LEN, fingerprint); + append_to_strlist (&s2, fingerprint); + + release_kbnode (kb); + + /* Continue the search. */ + err = keydb_search (hd, &desc, 1, NULL); + if (! (gpg_err_code (err) == GPG_ERR_NOT_FOUND + || gpg_err_code (err) == GPG_ERR_EOF)) + { + char fingerprint_bin2[MAX_FINGERPRINT_LEN]; + size_t fingerprint_bin2_len = sizeof (fingerprint_bin2); + char fingerprint2[2 * MAX_FINGERPRINT_LEN + 1]; + + log_error ("Error: the key specification '%s' is ambiguous (passed to %s).\n", + t->d, option); + die = 1; + + err = keydb_get_keyblock (hd, &kb); + if (err) + log_error (_("error reading key block for %s: %s.\n"), + t->d, gpg_strerror (err)); + else + { + pk = kb->pkt->pkt.public_key; + fingerprint_from_pk (pk, fingerprint_bin2, &fingerprint_bin2_len); + assert (fingerprint_bin2_len == sizeof (fingerprint_bin2)); + bin2hex (fingerprint_bin2, MAX_FINGERPRINT_LEN, fingerprint2); + + log_error ("'%s' matches at least: %s and %s.\n", + t->d, fingerprint, fingerprint2); + + release_kbnode (kb); + } + } + } + + if (hd) + keydb_release (hd); + + if (die) + g10_exit(2); + + free_strlist (s); + return s2; +} int main (int argc, char **argv) @@ -3754,6 +3876,11 @@ log_info (_("--encrypt-to-default-key specified, but --default-key not specified.\n")); } + locusr = check_user_ids (locusr, "--local-user", 1, 1); + remusr = check_user_ids (remusr, "--encrypt-to", 0, 1); + opt.def_secret_key = check_user_ids (opt.def_secret_key, + "--default-key", 1, 0); + /* The command dispatcher. */ switch( cmd ) {