1 /* skclist.c - Build a list of secret keys
2 * Copyright (C) 1998, 1999, 2000, 2001, 2006,
3 * 2010 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
36 /* Return true if Libgcrypt's RNG is in faked mode. */
38 random_is_faked (void)
40 return !!gcry_control (GCRYCTL_FAKED_RANDOM_P, 0);
45 release_sk_list (SK_LIST sk_list)
49 for (; sk_list; sk_list = sk_rover)
51 sk_rover = sk_list->next;
52 free_public_key (sk_list->pk);
58 /* Check that we are only using keys which don't have
59 * the string "(insecure!)" or "not secure" or "do not use"
60 * in one of the user ids. */
62 is_insecure (PKT_public_key *pk)
65 KBNODE node = NULL, u;
68 keyid_from_pk (pk, keyid);
69 node = get_pubkeyblock (keyid);
70 for (u = node; u; u = u->next)
72 if (u->pkt->pkttype == PKT_USER_ID)
74 PKT_user_id *id = u->pkt->pkt.user_id;
76 continue; /* skip attribute packets */
77 if (strstr (id->name, "(insecure!)")
78 || strstr (id->name, "not secure")
79 || strstr (id->name, "do not use")
80 || strstr (id->name, "(INSECURE!)"))
87 release_kbnode (node);
93 key_present_in_sk_list (SK_LIST sk_list, PKT_public_key *pk)
95 for (; sk_list; sk_list = sk_list->next)
97 if (!cmp_public_keys (sk_list->pk, pk))
104 is_duplicated_entry (strlist_t list, strlist_t item)
106 for (; list && list != item; list = list->next)
108 if (!strcmp (list->d, item->d))
116 build_sk_list (ctrl_t ctrl,
117 strlist_t locusr, SK_LIST *ret_sk_list, unsigned int use)
120 SK_LIST sk_list = NULL;
122 /* XXX: Change this function to use get_pubkeys instead of
123 getkey_byname to detect ambiguous key specifications and warn
124 about duplicate keyblocks. For ambiguous key specifications on
125 the command line or provided interactively, prompt the user to
126 select the best key. If a key specification is ambiguous and we
127 are in batch mode, die. */
129 if (!locusr) /* No user ids given - use the default key. */
133 pk = xmalloc_clear (sizeof *pk);
135 if ((err = getkey_byname (ctrl, NULL, pk, NULL, 1, NULL)))
137 free_public_key (pk);
139 log_error ("no default secret key: %s\n", gpg_strerror (err));
140 write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (err));
142 else if ((err = openpgp_pk_test_algo2 (pk->pubkey_algo, use)))
144 free_public_key (pk);
146 log_error ("invalid default secret key: %s\n", gpg_strerror (err));
147 write_status_text (STATUS_INV_SGNR, get_inv_recpsgnr_code (err));
153 if (random_is_faked () && !is_insecure (pk))
155 log_info (_("key is not flagged as insecure - "
156 "can't use it with the faked RNG!\n"));
157 free_public_key (pk);
159 write_status_text (STATUS_INV_SGNR,
160 get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED));
164 r = xmalloc (sizeof *r);
173 else /* Check the given user ids. */
175 strlist_t locusr_orig = locusr;
177 for (; locusr; locusr = locusr->next)
182 /* Do an early check against duplicated entries. However
183 * this won't catch all duplicates because the user IDs may
184 * be specified in different ways. */
185 if (is_duplicated_entry (locusr_orig, locusr))
187 log_info (_("skipped \"%s\": duplicated\n"), locusr->d);
190 pk = xmalloc_clear (sizeof *pk);
192 if ((err = getkey_byname (ctrl, NULL, pk, locusr->d, 1, NULL)))
194 free_public_key (pk);
196 log_error (_("skipped \"%s\": %s\n"),
197 locusr->d, gpg_strerror (err));
198 write_status_text_and_buffer
199 (STATUS_INV_SGNR, get_inv_recpsgnr_code (err),
200 locusr->d, strlen (locusr->d), -1);
202 else if (!key_present_in_sk_list (sk_list, pk))
204 free_public_key (pk);
206 log_info (_("skipped: secret key already present\n"));
208 else if ((err = openpgp_pk_test_algo2 (pk->pubkey_algo, use)))
210 free_public_key (pk);
212 log_error ("skipped \"%s\": %s\n", locusr->d, gpg_strerror (err));
213 write_status_text_and_buffer
214 (STATUS_INV_SGNR, get_inv_recpsgnr_code (err),
215 locusr->d, strlen (locusr->d), -1);
221 if (pk->version == 4 && (use & PUBKEY_USAGE_SIG)
222 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E)
224 log_info (_("skipped \"%s\": %s\n"), locusr->d,
225 _("this is a PGP generated Elgamal key which"
226 " is not secure for signatures!"));
227 free_public_key (pk);
229 write_status_text_and_buffer
231 get_inv_recpsgnr_code (GPG_ERR_WRONG_KEY_USAGE),
232 locusr->d, strlen (locusr->d), -1);
234 else if (random_is_faked () && !is_insecure (pk))
236 log_info (_("key is not flagged as insecure - "
237 "can't use it with the faked RNG!\n"));
238 free_public_key (pk);
240 write_status_text_and_buffer
242 get_inv_recpsgnr_code (GPG_ERR_NOT_TRUSTED),
243 locusr->d, strlen (locusr->d), -1);
247 r = xmalloc (sizeof *r);
258 if (!err && !sk_list)
260 log_error ("no valid signators\n");
261 write_status_text (STATUS_NO_SGNR, "0");
262 err = gpg_error (GPG_ERR_NO_USER_ID);
266 release_sk_list (sk_list);
268 *ret_sk_list = sk_list;