Line data Source code
1 : /* keyedit.c - Edit properties of a key
2 : * Copyright (C) 1998-2010 Free Software Foundation, Inc.
3 : * Copyright (C) 1998-2015 Werner Koch
4 : *
5 : * This file is part of GnuPG.
6 : *
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.
11 : *
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.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 : #include <stdio.h>
23 : #include <stdlib.h>
24 : #include <string.h>
25 : #include <errno.h>
26 : #include <assert.h>
27 : #include <ctype.h>
28 : #ifdef HAVE_LIBREADLINE
29 : # define GNUPG_LIBREADLINE_H_INCLUDED
30 : # include <readline/readline.h>
31 : #endif
32 :
33 : #include "gpg.h"
34 : #include "options.h"
35 : #include "packet.h"
36 : #include "status.h"
37 : #include "iobuf.h"
38 : #include "keydb.h"
39 : #include "photoid.h"
40 : #include "util.h"
41 : #include "main.h"
42 : #include "trustdb.h"
43 : #include "filter.h"
44 : #include "ttyio.h"
45 : #include "status.h"
46 : #include "i18n.h"
47 : #include "keyserver-internal.h"
48 : #include "call-agent.h"
49 : #include "host2net.h"
50 : #include "tofu.h"
51 :
52 : static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
53 : int verbose);
54 : static void show_names (estream_t fp, KBNODE keyblock, PKT_public_key * pk,
55 : unsigned int flag, int with_prefs);
56 : static void show_key_with_all_names (ctrl_t ctrl, estream_t fp,
57 : KBNODE keyblock, int only_marked,
58 : int with_revoker, int with_fpr,
59 : int with_subkeys, int with_prefs,
60 : int nowarn);
61 : static void show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys);
62 : static void show_key_and_grip (kbnode_t keyblock);
63 : static void subkey_expire_warning (kbnode_t keyblock);
64 : static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name,
65 : const char *uidstr);
66 : static void menu_deluid (KBNODE pub_keyblock);
67 : static int menu_delsig (KBNODE pub_keyblock);
68 : static int menu_clean (KBNODE keyblock, int self_only);
69 : static void menu_delkey (KBNODE pub_keyblock);
70 : static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
71 : static int menu_expire (KBNODE pub_keyblock);
72 : static int menu_backsign (KBNODE pub_keyblock);
73 : static int menu_set_primary_uid (KBNODE pub_keyblock);
74 : static int menu_set_preferences (KBNODE pub_keyblock);
75 : static int menu_set_keyserver_url (const char *url, KBNODE pub_keyblock);
76 : static int menu_set_notation (const char *string, KBNODE pub_keyblock);
77 : static int menu_select_uid (KBNODE keyblock, int idx);
78 : static int menu_select_uid_namehash (KBNODE keyblock, const char *namehash);
79 : static int menu_select_key (KBNODE keyblock, int idx);
80 : static int count_uids (KBNODE keyblock);
81 : static int count_uids_with_flag (KBNODE keyblock, unsigned flag);
82 : static int count_keys_with_flag (KBNODE keyblock, unsigned flag);
83 : static int count_selected_uids (KBNODE keyblock);
84 : static int real_uids_left (KBNODE keyblock);
85 : static int count_selected_keys (KBNODE keyblock);
86 : static int menu_revsig (KBNODE keyblock);
87 : static int menu_revuid (KBNODE keyblock);
88 : static int menu_revkey (KBNODE pub_keyblock);
89 : static int menu_revsubkey (KBNODE pub_keyblock);
90 : #ifndef NO_TRUST_MODELS
91 : static int enable_disable_key (KBNODE keyblock, int disable);
92 : #endif /*!NO_TRUST_MODELS*/
93 : static void menu_showphoto (KBNODE keyblock);
94 :
95 : static int update_trust = 0;
96 :
97 : #define CONTROL_D ('D' - 'A' + 1)
98 :
99 : #define NODFLG_BADSIG (1<<0) /* Bad signature. */
100 : #define NODFLG_NOKEY (1<<1) /* No public key. */
101 : #define NODFLG_SIGERR (1<<2) /* Other sig error. */
102 :
103 : #define NODFLG_MARK_A (1<<4) /* Temporary mark. */
104 : #define NODFLG_DELSIG (1<<5) /* To be deleted. */
105 :
106 : #define NODFLG_SELUID (1<<8) /* Indicate the selected userid. */
107 : #define NODFLG_SELKEY (1<<9) /* Indicate the selected key. */
108 : #define NODFLG_SELSIG (1<<10) /* Indicate a selected signature. */
109 :
110 : struct sign_attrib
111 : {
112 : int non_exportable, non_revocable;
113 : struct revocation_reason_info *reason;
114 : byte trust_depth, trust_value;
115 : char *trust_regexp;
116 : };
117 :
118 :
119 :
120 : /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
121 : code in keylist.c. */
122 : static int
123 0 : print_and_check_one_sig_colon (KBNODE keyblock, KBNODE node,
124 : int *inv_sigs, int *no_key, int *oth_err,
125 : int *is_selfsig, int print_without_key)
126 : {
127 0 : PKT_signature *sig = node->pkt->pkt.signature;
128 : int rc, sigrc;
129 :
130 : /* TODO: Make sure a cached sig record here still has the pk that
131 : issued it. See also keylist.c:list_keyblock_print */
132 :
133 0 : rc = check_key_signature (keyblock, node, is_selfsig);
134 0 : switch (gpg_err_code (rc))
135 : {
136 : case 0:
137 0 : node->flag &= ~(NODFLG_BADSIG | NODFLG_NOKEY | NODFLG_SIGERR);
138 0 : sigrc = '!';
139 0 : break;
140 : case GPG_ERR_BAD_SIGNATURE:
141 0 : node->flag = NODFLG_BADSIG;
142 0 : sigrc = '-';
143 0 : if (inv_sigs)
144 0 : ++ * inv_sigs;
145 0 : break;
146 : case GPG_ERR_NO_PUBKEY:
147 : case GPG_ERR_UNUSABLE_PUBKEY:
148 0 : node->flag = NODFLG_NOKEY;
149 0 : sigrc = '?';
150 0 : if (no_key)
151 0 : ++ * no_key;
152 0 : break;
153 : default:
154 0 : node->flag = NODFLG_SIGERR;
155 0 : sigrc = '%';
156 0 : if (oth_err)
157 0 : ++ * oth_err;
158 0 : break;
159 : }
160 :
161 0 : if (sigrc != '?' || print_without_key)
162 : {
163 0 : es_printf ("sig:%c::%d:%08lX%08lX:%lu:%lu:",
164 0 : sigrc, sig->pubkey_algo, (ulong) sig->keyid[0],
165 0 : (ulong) sig->keyid[1], (ulong) sig->timestamp,
166 0 : (ulong) sig->expiredate);
167 :
168 0 : if (sig->trust_depth || sig->trust_value)
169 0 : es_printf ("%d %d", sig->trust_depth, sig->trust_value);
170 :
171 0 : es_printf (":");
172 :
173 0 : if (sig->trust_regexp)
174 0 : es_write_sanitized (es_stdout,
175 0 : sig->trust_regexp, strlen (sig->trust_regexp),
176 : ":", NULL);
177 :
178 0 : es_printf ("::%02x%c\n", sig->sig_class,
179 0 : sig->flags.exportable ? 'x' : 'l');
180 :
181 0 : if (opt.show_subpackets)
182 0 : print_subpackets_colon (sig);
183 : }
184 :
185 0 : return (sigrc == '!');
186 : }
187 :
188 :
189 : /*
190 : * Print information about a signature, check it and return true if
191 : * the signature is okay. NODE must be a signature packet. With
192 : * EXTENDED set all possible signature list options will always be
193 : * printed.
194 : */
195 : static int
196 0 : print_and_check_one_sig (KBNODE keyblock, KBNODE node,
197 : int *inv_sigs, int *no_key, int *oth_err,
198 : int *is_selfsig, int print_without_key, int extended)
199 : {
200 0 : PKT_signature *sig = node->pkt->pkt.signature;
201 : int rc, sigrc;
202 0 : int is_rev = sig->sig_class == 0x30;
203 :
204 : /* TODO: Make sure a cached sig record here still has the pk that
205 : issued it. See also keylist.c:list_keyblock_print */
206 :
207 0 : rc = check_key_signature (keyblock, node, is_selfsig);
208 0 : switch (gpg_err_code (rc))
209 : {
210 : case 0:
211 0 : node->flag &= ~(NODFLG_BADSIG | NODFLG_NOKEY | NODFLG_SIGERR);
212 0 : sigrc = '!';
213 0 : break;
214 : case GPG_ERR_BAD_SIGNATURE:
215 0 : node->flag = NODFLG_BADSIG;
216 0 : sigrc = '-';
217 0 : if (inv_sigs)
218 0 : ++ * inv_sigs;
219 0 : break;
220 : case GPG_ERR_NO_PUBKEY:
221 : case GPG_ERR_UNUSABLE_PUBKEY:
222 0 : node->flag = NODFLG_NOKEY;
223 0 : sigrc = '?';
224 0 : if (no_key)
225 0 : ++ * no_key;
226 0 : break;
227 : default:
228 0 : node->flag = NODFLG_SIGERR;
229 0 : sigrc = '%';
230 0 : if (oth_err)
231 0 : ++ * oth_err;
232 0 : break;
233 : }
234 0 : if (sigrc != '?' || print_without_key)
235 : {
236 0 : tty_printf ("%s%c%c %c%c%c%c%c%c %s %s",
237 : is_rev ? "rev" : "sig", sigrc,
238 0 : (sig->sig_class - 0x10 > 0 &&
239 0 : sig->sig_class - 0x10 <
240 0 : 4) ? '0' + sig->sig_class - 0x10 : ' ',
241 0 : sig->flags.exportable ? ' ' : 'L',
242 0 : sig->flags.revocable ? ' ' : 'R',
243 0 : sig->flags.policy_url ? 'P' : ' ',
244 0 : sig->flags.notation ? 'N' : ' ',
245 0 : sig->flags.expired ? 'X' : ' ',
246 0 : (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
247 0 : 0) ? '0' +
248 0 : sig->trust_depth : ' ',
249 0 : keystr (sig->keyid),
250 : datestr_from_sig (sig));
251 0 : if ((opt.list_options & LIST_SHOW_SIG_EXPIRE) || extended )
252 0 : tty_printf (" %s", expirestr_from_sig (sig));
253 0 : tty_printf (" ");
254 0 : if (sigrc == '%')
255 0 : tty_printf ("[%s] ", gpg_strerror (rc));
256 0 : else if (sigrc == '?')
257 : ;
258 0 : else if (*is_selfsig)
259 : {
260 0 : tty_printf (is_rev ? _("[revocation]") : _("[self-signature]"));
261 0 : if (extended && sig->flags.chosen_selfsig)
262 0 : tty_printf ("*");
263 : }
264 : else
265 : {
266 : size_t n;
267 0 : char *p = get_user_id (sig->keyid, &n);
268 0 : tty_print_utf8_string2 (NULL, p, n,
269 0 : opt.screen_columns - keystrlen () - 26 -
270 0 : ((opt.
271 0 : list_options & LIST_SHOW_SIG_EXPIRE) ? 11
272 : : 0));
273 0 : xfree (p);
274 : }
275 0 : tty_printf ("\n");
276 :
277 0 : if (sig->flags.policy_url
278 0 : && ((opt.list_options & LIST_SHOW_POLICY_URLS) || extended))
279 0 : show_policy_url (sig, 3, 0);
280 :
281 0 : if (sig->flags.notation
282 0 : && ((opt.list_options & LIST_SHOW_NOTATIONS) || extended))
283 0 : show_notation (sig, 3, 0,
284 0 : ((opt.
285 0 : list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) +
286 0 : ((opt.
287 0 : list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0));
288 :
289 0 : if (sig->flags.pref_ks
290 0 : && ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended))
291 0 : show_keyserver_url (sig, 3, 0);
292 :
293 0 : if (extended)
294 : {
295 0 : PKT_public_key *pk = keyblock->pkt->pkt.public_key;
296 : const unsigned char *s;
297 :
298 0 : s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL);
299 0 : if (s && *s)
300 0 : tty_printf (" [primary]\n");
301 :
302 0 : s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
303 0 : if (s && buf32_to_u32 (s))
304 0 : tty_printf (" [expires: %s]\n",
305 0 : isotimestamp (pk->timestamp + buf32_to_u32 (s)));
306 : }
307 : }
308 :
309 0 : return (sigrc == '!');
310 : }
311 :
312 :
313 :
314 : /*
315 : * Check the keysigs and set the flags to indicate errors.
316 : * Returns true if error found.
317 : */
318 : static int
319 0 : check_all_keysigs (KBNODE keyblock, int only_selected, int only_selfsigs)
320 : {
321 : KBNODE kbctx;
322 : KBNODE node;
323 0 : int inv_sigs = 0;
324 0 : int no_key = 0;
325 0 : int oth_err = 0;
326 0 : int has_selfsig = 0;
327 0 : int mis_selfsig = 0;
328 0 : int selected = !only_selected;
329 0 : int anyuid = 0;
330 : u32 keyid[2];
331 :
332 0 : for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
333 : {
334 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
335 : {
336 0 : if (only_selfsigs)
337 0 : keyid_from_pk (node->pkt->pkt.public_key, keyid);
338 : }
339 0 : else if (node->pkt->pkttype == PKT_USER_ID)
340 : {
341 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
342 :
343 0 : if (only_selected)
344 0 : selected = (node->flag & NODFLG_SELUID);
345 0 : if (selected)
346 : {
347 0 : tty_printf ("uid ");
348 0 : tty_print_utf8_string (uid->name, uid->len);
349 0 : tty_printf ("\n");
350 0 : if (anyuid && !has_selfsig)
351 0 : mis_selfsig++;
352 0 : has_selfsig = 0;
353 0 : anyuid = 1;
354 : }
355 : }
356 0 : else if (selected && node->pkt->pkttype == PKT_SIGNATURE
357 0 : && ((node->pkt->pkt.signature->sig_class & ~3) == 0x10
358 0 : || node->pkt->pkt.signature->sig_class == 0x30))
359 : {
360 : int selfsig;
361 0 : PKT_signature *sig = node->pkt->pkt.signature;
362 :
363 0 : if (only_selfsigs
364 0 : && !(keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]))
365 : ; /* Not a selfsig but we want only selfsigs - skip. */
366 0 : else if (print_and_check_one_sig (keyblock, node, &inv_sigs,
367 : &no_key, &oth_err, &selfsig,
368 : 0, only_selfsigs))
369 : {
370 0 : if (selfsig)
371 0 : has_selfsig = 1;
372 : }
373 : /* Hmmm: should we update the trustdb here? */
374 : }
375 : }
376 0 : if (!has_selfsig)
377 0 : mis_selfsig++;
378 0 : if (inv_sigs == 1)
379 0 : tty_printf (_("1 bad signature\n"));
380 0 : else if (inv_sigs)
381 0 : tty_printf (_("%d bad signatures\n"), inv_sigs);
382 0 : if (no_key == 1)
383 0 : tty_printf (_("1 signature not checked due to a missing key\n"));
384 0 : else if (no_key)
385 0 : tty_printf (_("%d signatures not checked due to missing keys\n"), no_key);
386 0 : if (oth_err == 1)
387 0 : tty_printf (_("1 signature not checked due to an error\n"));
388 0 : else if (oth_err)
389 0 : tty_printf (_("%d signatures not checked due to errors\n"), oth_err);
390 0 : if (mis_selfsig == 1)
391 0 : tty_printf (_("1 user ID without valid self-signature detected\n"));
392 0 : else if (mis_selfsig)
393 0 : tty_printf (_("%d user IDs without valid self-signatures detected\n"),
394 : mis_selfsig);
395 :
396 0 : return inv_sigs || no_key || oth_err || mis_selfsig;
397 : }
398 :
399 :
400 : static int
401 0 : sign_mk_attrib (PKT_signature * sig, void *opaque)
402 : {
403 0 : struct sign_attrib *attrib = opaque;
404 : byte buf[8];
405 :
406 0 : if (attrib->non_exportable)
407 : {
408 0 : buf[0] = 0; /* not exportable */
409 0 : build_sig_subpkt (sig, SIGSUBPKT_EXPORTABLE, buf, 1);
410 : }
411 :
412 0 : if (attrib->non_revocable)
413 : {
414 0 : buf[0] = 0; /* not revocable */
415 0 : build_sig_subpkt (sig, SIGSUBPKT_REVOCABLE, buf, 1);
416 : }
417 :
418 0 : if (attrib->reason)
419 0 : revocation_reason_build_cb (sig, attrib->reason);
420 :
421 0 : if (attrib->trust_depth)
422 : {
423 : /* Not critical. If someone doesn't understand trust sigs,
424 : this can still be a valid regular signature. */
425 0 : buf[0] = attrib->trust_depth;
426 0 : buf[1] = attrib->trust_value;
427 0 : build_sig_subpkt (sig, SIGSUBPKT_TRUST, buf, 2);
428 :
429 : /* Critical. If someone doesn't understands regexps, this
430 : whole sig should be invalid. Note the +1 for the length -
431 : regexps are null terminated. */
432 0 : if (attrib->trust_regexp)
433 0 : build_sig_subpkt (sig, SIGSUBPKT_FLAG_CRITICAL | SIGSUBPKT_REGEXP,
434 0 : attrib->trust_regexp,
435 0 : strlen (attrib->trust_regexp) + 1);
436 : }
437 :
438 0 : return 0;
439 : }
440 :
441 :
442 : static void
443 0 : trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp)
444 : {
445 : char *p;
446 :
447 0 : *trust_value = 0;
448 0 : *trust_depth = 0;
449 0 : *regexp = NULL;
450 :
451 : /* Same string as pkclist.c:do_edit_ownertrust */
452 0 : tty_printf (_
453 : ("Please decide how far you trust this user to correctly verify"
454 : " other users' keys\n(by looking at passports, checking"
455 : " fingerprints from different sources, etc.)\n"));
456 0 : tty_printf ("\n");
457 0 : tty_printf (_(" %d = I trust marginally\n"), 1);
458 0 : tty_printf (_(" %d = I trust fully\n"), 2);
459 0 : tty_printf ("\n");
460 :
461 0 : while (*trust_value == 0)
462 : {
463 0 : p = cpr_get ("trustsig_prompt.trust_value", _("Your selection? "));
464 0 : trim_spaces (p);
465 0 : cpr_kill_prompt ();
466 : /* 60 and 120 are as per RFC2440 */
467 0 : if (p[0] == '1' && !p[1])
468 0 : *trust_value = 60;
469 0 : else if (p[0] == '2' && !p[1])
470 0 : *trust_value = 120;
471 0 : xfree (p);
472 : }
473 :
474 0 : tty_printf ("\n");
475 :
476 0 : tty_printf (_("Please enter the depth of this trust signature.\n"
477 : "A depth greater than 1 allows the key you are signing to make\n"
478 : "trust signatures on your behalf.\n"));
479 0 : tty_printf ("\n");
480 :
481 0 : while (*trust_depth == 0)
482 : {
483 0 : p = cpr_get ("trustsig_prompt.trust_depth", _("Your selection? "));
484 0 : trim_spaces (p);
485 0 : cpr_kill_prompt ();
486 0 : *trust_depth = atoi (p);
487 0 : xfree (p);
488 : }
489 :
490 0 : tty_printf ("\n");
491 :
492 0 : tty_printf (_("Please enter a domain to restrict this signature, "
493 : "or enter for none.\n"));
494 :
495 0 : tty_printf ("\n");
496 :
497 0 : p = cpr_get ("trustsig_prompt.trust_regexp", _("Your selection? "));
498 0 : trim_spaces (p);
499 0 : cpr_kill_prompt ();
500 :
501 0 : if (strlen (p) > 0)
502 : {
503 0 : char *q = p;
504 0 : int regexplen = 100, ind;
505 :
506 0 : *regexp = xmalloc (regexplen);
507 :
508 : /* Now mangle the domain the user entered into a regexp. To do
509 : this, \-escape everything that isn't alphanumeric, and attach
510 : "<[^>]+[@.]" to the front, and ">$" to the end. */
511 :
512 0 : strcpy (*regexp, "<[^>]+[@.]");
513 0 : ind = strlen (*regexp);
514 :
515 0 : while (*q)
516 : {
517 0 : if (!((*q >= 'A' && *q <= 'Z')
518 0 : || (*q >= 'a' && *q <= 'z') || (*q >= '0' && *q <= '9')))
519 0 : (*regexp)[ind++] = '\\';
520 :
521 0 : (*regexp)[ind++] = *q;
522 :
523 0 : if ((regexplen - ind) < 3)
524 : {
525 0 : regexplen += 100;
526 0 : *regexp = xrealloc (*regexp, regexplen);
527 : }
528 :
529 0 : q++;
530 : }
531 :
532 0 : (*regexp)[ind] = '\0';
533 0 : strcat (*regexp, ">$");
534 : }
535 :
536 0 : xfree (p);
537 0 : tty_printf ("\n");
538 0 : }
539 :
540 :
541 : /*
542 : * Loop over all LOCUSR and and sign the uids after asking. If no
543 : * user id is marked, all user ids will be signed; if some user_ids
544 : * are marked only those will be signed. If QUICK is true the
545 : * function won't ask the user and use sensible defaults.
546 : */
547 : static int
548 0 : sign_uids (ctrl_t ctrl, estream_t fp,
549 : kbnode_t keyblock, strlist_t locusr, int *ret_modified,
550 : int local, int nonrevocable, int trust, int interactive,
551 : int quick)
552 : {
553 0 : int rc = 0;
554 0 : SK_LIST sk_list = NULL;
555 0 : SK_LIST sk_rover = NULL;
556 0 : PKT_public_key *pk = NULL;
557 : KBNODE node, uidnode;
558 0 : PKT_public_key *primary_pk = NULL;
559 0 : int select_all = !count_selected_uids (keyblock) || interactive;
560 :
561 : /* Build a list of all signators.
562 : *
563 : * We use the CERT flag to request the primary which must always
564 : * be one which is capable of signing keys. I can't see a reason
565 : * why to sign keys using a subkey. Implementation of USAGE_CERT
566 : * is just a hack in getkey.c and does not mean that a subkey
567 : * marked as certification capable will be used. */
568 0 : rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_CERT);
569 0 : if (rc)
570 0 : goto leave;
571 :
572 : /* Loop over all signators. */
573 0 : for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
574 : {
575 : u32 sk_keyid[2], pk_keyid[2];
576 0 : char *p, *trust_regexp = NULL;
577 0 : int class = 0, selfsig = 0;
578 0 : u32 duration = 0, timestamp = 0;
579 0 : byte trust_depth = 0, trust_value = 0;
580 :
581 0 : pk = sk_rover->pk;
582 0 : keyid_from_pk (pk, sk_keyid);
583 :
584 : /* Set mark A for all selected user ids. */
585 0 : for (node = keyblock; node; node = node->next)
586 : {
587 0 : if (select_all || (node->flag & NODFLG_SELUID))
588 0 : node->flag |= NODFLG_MARK_A;
589 : else
590 0 : node->flag &= ~NODFLG_MARK_A;
591 : }
592 :
593 : /* Reset mark for uids which are already signed. */
594 0 : uidnode = NULL;
595 0 : for (node = keyblock; node; node = node->next)
596 : {
597 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
598 : {
599 0 : primary_pk = node->pkt->pkt.public_key;
600 0 : keyid_from_pk (primary_pk, pk_keyid);
601 :
602 : /* Is this a self-sig? */
603 0 : if (pk_keyid[0] == sk_keyid[0] && pk_keyid[1] == sk_keyid[1])
604 0 : selfsig = 1;
605 : }
606 0 : else if (node->pkt->pkttype == PKT_USER_ID)
607 : {
608 0 : uidnode = (node->flag & NODFLG_MARK_A) ? node : NULL;
609 0 : if (uidnode)
610 : {
611 0 : int yesreally = 0;
612 : char *user;
613 :
614 0 : user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
615 0 : uidnode->pkt->pkt.user_id->len, 0);
616 :
617 0 : if (uidnode->pkt->pkt.user_id->is_revoked)
618 : {
619 0 : tty_fprintf (fp, _("User ID \"%s\" is revoked."), user);
620 :
621 0 : if (selfsig)
622 0 : tty_fprintf (fp, "\n");
623 0 : else if (opt.expert && !quick)
624 : {
625 0 : tty_fprintf (fp, "\n");
626 : /* No, so remove the mark and continue */
627 0 : if (!cpr_get_answer_is_yes ("sign_uid.revoke_okay",
628 0 : _("Are you sure you "
629 : "still want to sign "
630 : "it? (y/N) ")))
631 : {
632 0 : uidnode->flag &= ~NODFLG_MARK_A;
633 0 : uidnode = NULL;
634 : }
635 0 : else if (interactive)
636 0 : yesreally = 1;
637 : }
638 : else
639 : {
640 0 : uidnode->flag &= ~NODFLG_MARK_A;
641 0 : uidnode = NULL;
642 0 : tty_fprintf (fp, _(" Unable to sign.\n"));
643 : }
644 : }
645 0 : else if (uidnode->pkt->pkt.user_id->is_expired)
646 : {
647 0 : tty_fprintf (fp, _("User ID \"%s\" is expired."), user);
648 :
649 0 : if (selfsig)
650 0 : tty_fprintf (fp, "\n");
651 0 : else if (opt.expert && !quick)
652 : {
653 0 : tty_fprintf (fp, "\n");
654 : /* No, so remove the mark and continue */
655 0 : if (!cpr_get_answer_is_yes ("sign_uid.expire_okay",
656 0 : _("Are you sure you "
657 : "still want to sign "
658 : "it? (y/N) ")))
659 : {
660 0 : uidnode->flag &= ~NODFLG_MARK_A;
661 0 : uidnode = NULL;
662 : }
663 0 : else if (interactive)
664 0 : yesreally = 1;
665 : }
666 : else
667 : {
668 0 : uidnode->flag &= ~NODFLG_MARK_A;
669 0 : uidnode = NULL;
670 0 : tty_fprintf (fp, _(" Unable to sign.\n"));
671 : }
672 : }
673 0 : else if (!uidnode->pkt->pkt.user_id->created && !selfsig)
674 : {
675 0 : tty_fprintf (fp, _("User ID \"%s\" is not self-signed."),
676 : user);
677 :
678 0 : if (opt.expert && !quick)
679 : {
680 0 : tty_fprintf (fp, "\n");
681 : /* No, so remove the mark and continue */
682 0 : if (!cpr_get_answer_is_yes ("sign_uid.nosig_okay",
683 0 : _("Are you sure you "
684 : "still want to sign "
685 : "it? (y/N) ")))
686 : {
687 0 : uidnode->flag &= ~NODFLG_MARK_A;
688 0 : uidnode = NULL;
689 : }
690 0 : else if (interactive)
691 0 : yesreally = 1;
692 : }
693 : else
694 : {
695 0 : uidnode->flag &= ~NODFLG_MARK_A;
696 0 : uidnode = NULL;
697 0 : tty_fprintf (fp, _(" Unable to sign.\n"));
698 : }
699 : }
700 :
701 0 : if (uidnode && interactive && !yesreally && !quick)
702 : {
703 0 : tty_fprintf (fp,
704 0 : _("User ID \"%s\" is signable. "), user);
705 0 : if (!cpr_get_answer_is_yes ("sign_uid.sign_okay",
706 0 : _("Sign it? (y/N) ")))
707 : {
708 0 : uidnode->flag &= ~NODFLG_MARK_A;
709 0 : uidnode = NULL;
710 : }
711 : }
712 :
713 0 : xfree (user);
714 : }
715 : }
716 0 : else if (uidnode && node->pkt->pkttype == PKT_SIGNATURE
717 0 : && (node->pkt->pkt.signature->sig_class & ~3) == 0x10)
718 : {
719 0 : if (sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
720 0 : && sk_keyid[1] == node->pkt->pkt.signature->keyid[1])
721 : {
722 : char buf[50];
723 : char *user;
724 :
725 0 : user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
726 0 : uidnode->pkt->pkt.user_id->len, 0);
727 :
728 : /* It's a v3 self-sig. Make it into a v4 self-sig? */
729 0 : if (node->pkt->pkt.signature->version < 4
730 0 : && selfsig && !quick)
731 : {
732 0 : tty_fprintf (fp,
733 0 : _("The self-signature on \"%s\"\n"
734 : "is a PGP 2.x-style signature.\n"), user);
735 :
736 : /* Note that the regular PGP2 warning below
737 : still applies if there are no v4 sigs on
738 : this key at all. */
739 :
740 0 : if (opt.expert)
741 0 : if (cpr_get_answer_is_yes ("sign_uid.v4_promote_okay",
742 0 : _("Do you want to promote "
743 : "it to an OpenPGP self-"
744 : "signature? (y/N) ")))
745 : {
746 0 : node->flag |= NODFLG_DELSIG;
747 0 : xfree (user);
748 0 : continue;
749 : }
750 : }
751 :
752 : /* Is the current signature expired? */
753 0 : if (node->pkt->pkt.signature->flags.expired)
754 : {
755 0 : tty_fprintf (fp, _("Your current signature on \"%s\"\n"
756 : "has expired.\n"), user);
757 :
758 0 : if (quick || cpr_get_answer_is_yes
759 : ("sign_uid.replace_expired_okay",
760 0 : _("Do you want to issue a "
761 : "new signature to replace "
762 : "the expired one? (y/N) ")))
763 : {
764 : /* Mark these for later deletion. We
765 : don't want to delete them here, just in
766 : case the replacement signature doesn't
767 : happen for some reason. We only delete
768 : these after the replacement is already
769 : in place. */
770 :
771 0 : node->flag |= NODFLG_DELSIG;
772 0 : xfree (user);
773 0 : continue;
774 : }
775 : }
776 :
777 0 : if (!node->pkt->pkt.signature->flags.exportable && !local)
778 : {
779 : /* It's a local sig, and we want to make a
780 : exportable sig. */
781 0 : tty_fprintf (fp, _("Your current signature on \"%s\"\n"
782 : "is a local signature.\n"), user);
783 :
784 0 : if (quick || cpr_get_answer_is_yes
785 : ("sign_uid.local_promote_okay",
786 0 : _("Do you want to promote "
787 : "it to a full exportable " "signature? (y/N) ")))
788 : {
789 : /* Mark these for later deletion. We
790 : don't want to delete them here, just in
791 : case the replacement signature doesn't
792 : happen for some reason. We only delete
793 : these after the replacement is already
794 : in place. */
795 :
796 0 : node->flag |= NODFLG_DELSIG;
797 0 : xfree (user);
798 0 : continue;
799 : }
800 : }
801 :
802 : /* Fixme: see whether there is a revocation in which
803 : * case we should allow to sign it again. */
804 0 : if (!node->pkt->pkt.signature->flags.exportable && local)
805 0 : tty_fprintf ( fp,
806 0 : _("\"%s\" was already locally signed by key %s\n"),
807 : user, keystr_from_pk (pk));
808 : else
809 0 : tty_fprintf (fp,
810 0 : _("\"%s\" was already signed by key %s\n"),
811 : user, keystr_from_pk (pk));
812 :
813 0 : if (opt.expert && !quick
814 0 : && cpr_get_answer_is_yes ("sign_uid.dupe_okay",
815 0 : _("Do you want to sign it "
816 : "again anyway? (y/N) ")))
817 : {
818 : /* Don't delete the old sig here since this is
819 : an --expert thing. */
820 0 : xfree (user);
821 0 : continue;
822 : }
823 :
824 0 : snprintf (buf, sizeof buf, "%08lX%08lX",
825 0 : (ulong) pk->keyid[0], (ulong) pk->keyid[1]);
826 0 : write_status_text (STATUS_ALREADY_SIGNED, buf);
827 0 : uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
828 :
829 0 : xfree (user);
830 : }
831 : }
832 : }
833 :
834 : /* Check whether any uids are left for signing. */
835 0 : if (!count_uids_with_flag (keyblock, NODFLG_MARK_A))
836 : {
837 0 : tty_fprintf (fp, _("Nothing to sign with key %s\n"),
838 : keystr_from_pk (pk));
839 0 : continue;
840 : }
841 :
842 : /* Ask whether we really should sign these user id(s). */
843 0 : tty_fprintf (fp, "\n");
844 0 : show_key_with_all_names (ctrl, fp, keyblock, 1, 0, 1, 0, 0, 0);
845 0 : tty_fprintf (fp, "\n");
846 :
847 0 : if (primary_pk->expiredate && !selfsig)
848 : {
849 0 : u32 now = make_timestamp ();
850 :
851 0 : if (primary_pk->expiredate <= now)
852 : {
853 0 : tty_fprintf (fp, _("This key has expired!"));
854 :
855 0 : if (opt.expert && !quick)
856 : {
857 0 : tty_fprintf (fp, " ");
858 0 : if (!cpr_get_answer_is_yes ("sign_uid.expired_okay",
859 0 : _("Are you sure you still "
860 : "want to sign it? (y/N) ")))
861 0 : continue;
862 : }
863 : else
864 : {
865 0 : tty_fprintf (fp, _(" Unable to sign.\n"));
866 0 : continue;
867 : }
868 : }
869 : else
870 : {
871 0 : tty_fprintf (fp, _("This key is due to expire on %s.\n"),
872 : expirestr_from_pk (primary_pk));
873 :
874 0 : if (opt.ask_cert_expire && !quick)
875 : {
876 0 : char *answer = cpr_get ("sign_uid.expire",
877 0 : _("Do you want your signature to "
878 : "expire at the same time? (Y/n) "));
879 0 : if (answer_is_yes_no_default (answer, 1))
880 : {
881 : /* This fixes the signature timestamp we're
882 : going to make as now. This is so the
883 : expiration date is exactly correct, and not
884 : a few seconds off (due to the time it takes
885 : to answer the questions, enter the
886 : passphrase, etc). */
887 0 : timestamp = now;
888 0 : duration = primary_pk->expiredate - now;
889 : }
890 :
891 0 : cpr_kill_prompt ();
892 0 : xfree (answer);
893 : }
894 : }
895 : }
896 :
897 : /* Only ask for duration if we haven't already set it to match
898 : the expiration of the pk */
899 0 : if (!duration && !selfsig)
900 : {
901 0 : if (opt.ask_cert_expire && !quick)
902 0 : duration = ask_expire_interval (1, opt.def_cert_expire);
903 : else
904 0 : duration = parse_expire_string (opt.def_cert_expire);
905 : }
906 :
907 0 : if (selfsig)
908 : ;
909 : else
910 : {
911 0 : if (opt.batch || !opt.ask_cert_level || quick)
912 0 : class = 0x10 + opt.def_cert_level;
913 : else
914 : {
915 : char *answer;
916 :
917 0 : tty_fprintf (fp,
918 0 : _("How carefully have you verified the key you are "
919 : "about to sign actually belongs\nto the person "
920 : "named above? If you don't know what to "
921 : "answer, enter \"0\".\n"));
922 0 : tty_fprintf (fp, "\n");
923 0 : tty_fprintf (fp, _(" (0) I will not answer.%s\n"),
924 0 : opt.def_cert_level == 0 ? " (default)" : "");
925 0 : tty_fprintf (fp, _(" (1) I have not checked at all.%s\n"),
926 0 : opt.def_cert_level == 1 ? " (default)" : "");
927 0 : tty_fprintf (fp, _(" (2) I have done casual checking.%s\n"),
928 0 : opt.def_cert_level == 2 ? " (default)" : "");
929 0 : tty_fprintf (fp,
930 0 : _(" (3) I have done very careful checking.%s\n"),
931 0 : opt.def_cert_level == 3 ? " (default)" : "");
932 0 : tty_fprintf (fp, "\n");
933 :
934 0 : while (class == 0)
935 : {
936 0 : answer = cpr_get ("sign_uid.class",
937 0 : _("Your selection? "
938 : "(enter '?' for more information): "));
939 0 : if (answer[0] == '\0')
940 0 : class = 0x10 + opt.def_cert_level; /* Default */
941 0 : else if (ascii_strcasecmp (answer, "0") == 0)
942 0 : class = 0x10; /* Generic */
943 0 : else if (ascii_strcasecmp (answer, "1") == 0)
944 0 : class = 0x11; /* Persona */
945 0 : else if (ascii_strcasecmp (answer, "2") == 0)
946 0 : class = 0x12; /* Casual */
947 0 : else if (ascii_strcasecmp (answer, "3") == 0)
948 0 : class = 0x13; /* Positive */
949 : else
950 0 : tty_fprintf (fp, _("Invalid selection.\n"));
951 :
952 0 : xfree (answer);
953 : }
954 : }
955 :
956 0 : if (trust && !quick)
957 0 : trustsig_prompt (&trust_value, &trust_depth, &trust_regexp);
958 : }
959 :
960 0 : if (!quick)
961 : {
962 0 : p = get_user_id_native (sk_keyid);
963 0 : tty_fprintf (fp,
964 0 : _("Are you sure that you want to sign this key with your\n"
965 : "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
966 0 : xfree (p);
967 : }
968 :
969 0 : if (selfsig)
970 : {
971 0 : tty_fprintf (fp, "\n");
972 0 : tty_fprintf (fp, _("This will be a self-signature.\n"));
973 :
974 0 : if (local)
975 : {
976 0 : tty_fprintf (fp, "\n");
977 0 : tty_fprintf (fp, _("WARNING: the signature will not be marked "
978 : "as non-exportable.\n"));
979 : }
980 :
981 0 : if (nonrevocable)
982 : {
983 0 : tty_fprintf (fp, "\n");
984 0 : tty_fprintf (fp, _("WARNING: the signature will not be marked "
985 : "as non-revocable.\n"));
986 : }
987 : }
988 : else
989 : {
990 0 : if (local)
991 : {
992 0 : tty_fprintf (fp, "\n");
993 0 : tty_fprintf (fp,
994 0 : _("The signature will be marked as non-exportable.\n"));
995 : }
996 :
997 0 : if (nonrevocable)
998 : {
999 0 : tty_fprintf (fp, "\n");
1000 0 : tty_fprintf (fp,
1001 0 : _("The signature will be marked as non-revocable.\n"));
1002 : }
1003 :
1004 0 : switch (class)
1005 : {
1006 : case 0x11:
1007 0 : tty_fprintf (fp, "\n");
1008 0 : tty_fprintf (fp, _("I have not checked this key at all.\n"));
1009 0 : break;
1010 :
1011 : case 0x12:
1012 0 : tty_fprintf (fp, "\n");
1013 0 : tty_fprintf (fp, _("I have checked this key casually.\n"));
1014 0 : break;
1015 :
1016 : case 0x13:
1017 0 : tty_fprintf (fp, "\n");
1018 0 : tty_fprintf (fp, _("I have checked this key very carefully.\n"));
1019 0 : break;
1020 : }
1021 : }
1022 :
1023 0 : tty_fprintf (fp, "\n");
1024 :
1025 0 : if (opt.batch && opt.answer_yes)
1026 : ;
1027 0 : else if (quick)
1028 : ;
1029 0 : else if (!cpr_get_answer_is_yes ("sign_uid.okay",
1030 0 : _("Really sign? (y/N) ")))
1031 0 : continue;
1032 :
1033 : /* Now we can sign the user ids. */
1034 : reloop: /* (Must use this, because we are modifing the list.) */
1035 0 : primary_pk = NULL;
1036 0 : for (node = keyblock; node; node = node->next)
1037 : {
1038 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1039 0 : primary_pk = node->pkt->pkt.public_key;
1040 0 : else if (node->pkt->pkttype == PKT_USER_ID
1041 0 : && (node->flag & NODFLG_MARK_A))
1042 : {
1043 : PACKET *pkt;
1044 : PKT_signature *sig;
1045 : struct sign_attrib attrib;
1046 :
1047 0 : assert (primary_pk);
1048 0 : memset (&attrib, 0, sizeof attrib);
1049 0 : attrib.non_exportable = local;
1050 0 : attrib.non_revocable = nonrevocable;
1051 0 : attrib.trust_depth = trust_depth;
1052 0 : attrib.trust_value = trust_value;
1053 0 : attrib.trust_regexp = trust_regexp;
1054 0 : node->flag &= ~NODFLG_MARK_A;
1055 :
1056 : /* We force creation of a v4 signature for local
1057 : * signatures, otherwise we would not generate the
1058 : * subpacket with v3 keys and the signature becomes
1059 : * exportable. */
1060 :
1061 0 : if (selfsig)
1062 0 : rc = make_keysig_packet (&sig, primary_pk,
1063 0 : node->pkt->pkt.user_id,
1064 : NULL,
1065 : pk,
1066 : 0x13, 0, 0, 0,
1067 : keygen_add_std_prefs, primary_pk,
1068 : NULL);
1069 : else
1070 0 : rc = make_keysig_packet (&sig, primary_pk,
1071 0 : node->pkt->pkt.user_id,
1072 : NULL,
1073 : pk,
1074 : class, 0,
1075 : timestamp, duration,
1076 : sign_mk_attrib, &attrib,
1077 : NULL);
1078 0 : if (rc)
1079 : {
1080 0 : write_status_error ("keysig", rc);
1081 0 : log_error (_("signing failed: %s\n"), gpg_strerror (rc));
1082 0 : goto leave;
1083 : }
1084 :
1085 0 : *ret_modified = 1; /* We changed the keyblock. */
1086 0 : update_trust = 1;
1087 :
1088 0 : pkt = xmalloc_clear (sizeof *pkt);
1089 0 : pkt->pkttype = PKT_SIGNATURE;
1090 0 : pkt->pkt.signature = sig;
1091 0 : insert_kbnode (node, new_kbnode (pkt), PKT_SIGNATURE);
1092 0 : goto reloop;
1093 : }
1094 : }
1095 :
1096 : /* Delete any sigs that got promoted */
1097 0 : for (node = keyblock; node; node = node->next)
1098 0 : if (node->flag & NODFLG_DELSIG)
1099 0 : delete_kbnode (node);
1100 : } /* End loop over signators. */
1101 :
1102 : leave:
1103 0 : release_sk_list (sk_list);
1104 0 : return rc;
1105 : }
1106 :
1107 :
1108 : /*
1109 : * Change the passphrase of the primary and all secondary keys. Note
1110 : * that it is common to use only one passphrase for the primary and
1111 : * all subkeys. However, this is now (since GnuPG 2.1) all up to the
1112 : * gpg-agent. Returns 0 on success or an error code.
1113 : */
1114 : static gpg_error_t
1115 0 : change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
1116 : {
1117 : gpg_error_t err;
1118 : kbnode_t node;
1119 : PKT_public_key *pk;
1120 : int any;
1121 : u32 keyid[2], subid[2];
1122 0 : char *hexgrip = NULL;
1123 0 : char *cache_nonce = NULL;
1124 0 : char *passwd_nonce = NULL;
1125 :
1126 0 : node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1127 0 : if (!node)
1128 : {
1129 0 : log_error ("Oops; public key missing!\n");
1130 0 : err = gpg_error (GPG_ERR_INTERNAL);
1131 0 : goto leave;
1132 : }
1133 0 : pk = node->pkt->pkt.public_key;
1134 0 : keyid_from_pk (pk, keyid);
1135 :
1136 : /* Check whether it is likely that we will be able to change the
1137 : passphrase for any subkey. */
1138 0 : for (any = 0, node = keyblock; node; node = node->next)
1139 : {
1140 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
1141 0 : || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1142 : {
1143 : char *serialno;
1144 :
1145 0 : pk = node->pkt->pkt.public_key;
1146 0 : keyid_from_pk (pk, subid);
1147 :
1148 0 : xfree (hexgrip);
1149 0 : err = hexkeygrip_from_pk (pk, &hexgrip);
1150 0 : if (err)
1151 0 : goto leave;
1152 0 : err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
1153 0 : if (!err && serialno)
1154 : ; /* Key on card. */
1155 0 : else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
1156 : ; /* Maybe stub key. */
1157 0 : else if (!err)
1158 0 : any = 1; /* Key is known. */
1159 : else
1160 0 : log_error ("key %s: error getting keyinfo from agent: %s\n",
1161 : keystr_with_sub (keyid, subid), gpg_strerror (err));
1162 0 : xfree (serialno);
1163 : }
1164 : }
1165 0 : err = 0;
1166 0 : if (!any)
1167 : {
1168 0 : tty_printf (_("Key has only stub or on-card key items - "
1169 : "no passphrase to change.\n"));
1170 0 : goto leave;
1171 : }
1172 :
1173 : /* Change the passphrase for all keys. */
1174 0 : for (any = 0, node = keyblock; node; node = node->next)
1175 : {
1176 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
1177 0 : || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1178 : {
1179 : char *desc;
1180 :
1181 0 : pk = node->pkt->pkt.public_key;
1182 0 : keyid_from_pk (pk, subid);
1183 :
1184 0 : xfree (hexgrip);
1185 0 : err = hexkeygrip_from_pk (pk, &hexgrip);
1186 0 : if (err)
1187 0 : goto leave;
1188 :
1189 0 : desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_NORMAL, 1);
1190 0 : err = agent_passwd (ctrl, hexgrip, desc, &cache_nonce, &passwd_nonce);
1191 0 : xfree (desc);
1192 :
1193 0 : if (err)
1194 0 : log_log ((gpg_err_code (err) == GPG_ERR_CANCELED
1195 0 : || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
1196 : ? GPGRT_LOG_INFO : GPGRT_LOG_ERROR,
1197 0 : _("key %s: error changing passphrase: %s\n"),
1198 : keystr_with_sub (keyid, subid),
1199 : gpg_strerror (err));
1200 0 : if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
1201 0 : break;
1202 : }
1203 : }
1204 :
1205 : leave:
1206 0 : xfree (hexgrip);
1207 0 : xfree (cache_nonce);
1208 0 : xfree (passwd_nonce);
1209 0 : return err;
1210 : }
1211 :
1212 :
1213 :
1214 : /*
1215 : * There are some keys out (due to a bug in gnupg), where the sequence
1216 : * of the packets is wrong. This function fixes that.
1217 : * Returns: true if the keyblock has been fixed.
1218 : *
1219 : * Note: This function does not work if there is more than one user ID.
1220 : */
1221 : static int
1222 0 : fix_key_signature_order (KBNODE keyblock)
1223 : {
1224 : KBNODE node, last, subkey;
1225 0 : int fixed = 0;
1226 :
1227 : /* Locate key signatures of class 0x10..0x13 behind sub key packets. */
1228 0 : for (subkey = last = NULL, node = keyblock; node;
1229 0 : last = node, node = node->next)
1230 : {
1231 0 : switch (node->pkt->pkttype)
1232 : {
1233 : case PKT_PUBLIC_SUBKEY:
1234 : case PKT_SECRET_SUBKEY:
1235 0 : if (!subkey)
1236 0 : subkey = last; /* Actually it is the one before the subkey. */
1237 0 : break;
1238 : case PKT_SIGNATURE:
1239 0 : if (subkey)
1240 : {
1241 0 : PKT_signature *sig = node->pkt->pkt.signature;
1242 0 : if (sig->sig_class >= 0x10 && sig->sig_class <= 0x13)
1243 : {
1244 0 : log_info (_("moving a key signature to the correct place\n"));
1245 0 : last->next = node->next;
1246 0 : node->next = subkey->next;
1247 0 : subkey->next = node;
1248 0 : node = last;
1249 0 : fixed = 1;
1250 : }
1251 : }
1252 0 : break;
1253 : default:
1254 0 : break;
1255 : }
1256 : }
1257 :
1258 0 : return fixed;
1259 : }
1260 :
1261 :
1262 : /* Fix various problems in the keyblock. Returns true if the keyblock
1263 : was changed. Note that a pointer to the keyblock must be given and
1264 : the function may change it (i.e. replacing the first node). */
1265 : static int
1266 0 : fix_keyblock (kbnode_t *keyblockp)
1267 : {
1268 0 : int changed = 0;
1269 :
1270 0 : if (fix_key_signature_order (*keyblockp))
1271 0 : changed++;
1272 0 : if (collapse_uids (keyblockp))
1273 0 : changed++;
1274 0 : reorder_keyblock (*keyblockp);
1275 : /* If we modified the keyblock, make sure the flags are right. */
1276 0 : if (changed)
1277 0 : merge_keys_and_selfsig (*keyblockp);
1278 :
1279 0 : return changed;
1280 : }
1281 :
1282 :
1283 : static int
1284 0 : parse_sign_type (const char *str, int *localsig, int *nonrevokesig,
1285 : int *trustsig)
1286 : {
1287 0 : const char *p = str;
1288 :
1289 0 : while (*p)
1290 : {
1291 0 : if (ascii_strncasecmp (p, "l", 1) == 0)
1292 : {
1293 0 : *localsig = 1;
1294 0 : p++;
1295 : }
1296 0 : else if (ascii_strncasecmp (p, "nr", 2) == 0)
1297 : {
1298 0 : *nonrevokesig = 1;
1299 0 : p += 2;
1300 : }
1301 0 : else if (ascii_strncasecmp (p, "t", 1) == 0)
1302 : {
1303 0 : *trustsig = 1;
1304 0 : p++;
1305 : }
1306 : else
1307 0 : return 0;
1308 : }
1309 :
1310 0 : return 1;
1311 : }
1312 :
1313 :
1314 :
1315 : /*
1316 : * Menu driven key editor. If seckey_check is true, then a secret key
1317 : * that matches username will be looked for. If it is false, not all
1318 : * commands will be available.
1319 : *
1320 : * Note: to keep track of certain selections we use node->mark MARKBIT_xxxx.
1321 : */
1322 :
1323 : /* Need an SK for this command */
1324 : #define KEYEDIT_NEED_SK 1
1325 : /* Cannot be viewing the SK for this command */
1326 : #define KEYEDIT_NOT_SK 2
1327 : /* Must be viewing the SK for this command */
1328 : #define KEYEDIT_ONLY_SK 4
1329 : /* Match the tail of the string */
1330 : #define KEYEDIT_TAIL_MATCH 8
1331 :
1332 : enum cmdids
1333 : {
1334 : cmdNONE = 0,
1335 : cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1336 : cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
1337 : cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
1338 : cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
1339 : cmdEXPIRE, cmdBACKSIGN,
1340 : #ifndef NO_TRUST_MODELS
1341 : cmdENABLEKEY, cmdDISABLEKEY,
1342 : #endif /*!NO_TRUST_MODELS*/
1343 : cmdSHOWPREF,
1344 : cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
1345 : cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCHECKBKUPKEY,
1346 : cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP
1347 : };
1348 :
1349 : static struct
1350 : {
1351 : const char *name;
1352 : enum cmdids id;
1353 : int flags;
1354 : const char *desc;
1355 : } cmds[] =
1356 : {
1357 : { "quit", cmdQUIT, 0, N_("quit this menu")},
1358 : { "q", cmdQUIT, 0, NULL},
1359 : { "save", cmdSAVE, 0, N_("save and quit")},
1360 : { "help", cmdHELP, 0, N_("show this help")},
1361 : { "?", cmdHELP, 0, NULL},
1362 : { "fpr", cmdFPR, 0, N_("show key fingerprint")},
1363 : { "grip", cmdGRIP, 0, N_("show the keygrip")},
1364 : { "list", cmdLIST, 0, N_("list key and user IDs")},
1365 : { "l", cmdLIST, 0, NULL},
1366 : { "uid", cmdSELUID, 0, N_("select user ID N")},
1367 : { "key", cmdSELKEY, 0, N_("select subkey N")},
1368 : { "check", cmdCHECK, 0, N_("check signatures")},
1369 : { "c", cmdCHECK, 0, NULL},
1370 : { "cross-certify", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
1371 : { "backsign", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
1372 : { "sign", cmdSIGN, KEYEDIT_NOT_SK | KEYEDIT_TAIL_MATCH,
1373 : N_("sign selected user IDs [* see below for related commands]")},
1374 : { "s", cmdSIGN, KEYEDIT_NOT_SK, NULL},
1375 : /* "lsign" and friends will never match since "sign" comes first
1376 : and it is a tail match. They are just here so they show up in
1377 : the help menu. */
1378 : { "lsign", cmdNOP, 0, N_("sign selected user IDs locally")},
1379 : { "tsign", cmdNOP, 0, N_("sign selected user IDs with a trust signature")},
1380 : { "nrsign", cmdNOP, 0,
1381 : N_("sign selected user IDs with a non-revocable signature")},
1382 : { "debug", cmdDEBUG, 0, NULL},
1383 : { "adduid", cmdADDUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a user ID")},
1384 : { "addphoto", cmdADDPHOTO, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1385 : N_("add a photo ID")},
1386 : { "deluid", cmdDELUID, KEYEDIT_NOT_SK, N_("delete selected user IDs")},
1387 : /* delphoto is really deluid in disguise */
1388 : { "delphoto", cmdDELUID, KEYEDIT_NOT_SK, NULL},
1389 : { "addkey", cmdADDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a subkey")},
1390 : #ifdef ENABLE_CARD_SUPPORT
1391 : { "addcardkey", cmdADDCARDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1392 : N_("add a key to a smartcard")},
1393 : { "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
1394 : N_("move a key to a smartcard")},
1395 : { "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
1396 : N_("move a backup key to a smartcard")},
1397 : { "checkbkupkey", cmdCHECKBKUPKEY, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK, NULL},
1398 : #endif /*ENABLE_CARD_SUPPORT */
1399 : { "delkey", cmdDELKEY, KEYEDIT_NOT_SK, N_("delete selected subkeys")},
1400 : { "addrevoker", cmdADDREVOKER, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1401 : N_("add a revocation key")},
1402 : { "delsig", cmdDELSIG, KEYEDIT_NOT_SK,
1403 : N_("delete signatures from the selected user IDs")},
1404 : { "expire", cmdEXPIRE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1405 : N_("change the expiration date for the key or selected subkeys")},
1406 : { "primary", cmdPRIMARY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1407 : N_("flag the selected user ID as primary")},
1408 : { "toggle", cmdTOGGLE, KEYEDIT_NEED_SK, NULL}, /* Dummy command. */
1409 : { "t", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},
1410 : { "pref", cmdPREF, KEYEDIT_NOT_SK, N_("list preferences (expert)")},
1411 : { "showpref", cmdSHOWPREF, KEYEDIT_NOT_SK, N_("list preferences (verbose)")},
1412 : { "setpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1413 : N_("set preference list for the selected user IDs")},
1414 : { "updpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
1415 : { "keyserver", cmdPREFKS, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1416 : N_("set the preferred keyserver URL for the selected user IDs")},
1417 : { "notation", cmdNOTATION, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1418 : N_("set a notation for the selected user IDs")},
1419 : { "passwd", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1420 : N_("change the passphrase")},
1421 : { "password", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
1422 : #ifndef NO_TRUST_MODELS
1423 : { "trust", cmdTRUST, KEYEDIT_NOT_SK, N_("change the ownertrust")},
1424 : #endif /*!NO_TRUST_MODELS*/
1425 : { "revsig", cmdREVSIG, KEYEDIT_NOT_SK,
1426 : N_("revoke signatures on the selected user IDs")},
1427 : { "revuid", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1428 : N_("revoke selected user IDs")},
1429 : { "revphoto", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
1430 : { "revkey", cmdREVKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
1431 : N_("revoke key or selected subkeys")},
1432 : #ifndef NO_TRUST_MODELS
1433 : { "enable", cmdENABLEKEY, KEYEDIT_NOT_SK, N_("enable key")},
1434 : { "disable", cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key")},
1435 : #endif /*!NO_TRUST_MODELS*/
1436 : { "showphoto", cmdSHOWPHOTO, 0, N_("show selected photo IDs")},
1437 : { "clean", cmdCLEAN, KEYEDIT_NOT_SK,
1438 : N_("compact unusable user IDs and remove unusable signatures from key")},
1439 : { "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
1440 : N_("compact unusable user IDs and remove all signatures from key")},
1441 :
1442 : { NULL, cmdNONE, 0, NULL}
1443 : };
1444 :
1445 :
1446 :
1447 : #ifdef HAVE_LIBREADLINE
1448 :
1449 : /*
1450 : These two functions are used by readline for command completion.
1451 : */
1452 :
1453 : static char *
1454 : command_generator (const char *text, int state)
1455 : {
1456 : static int list_index, len;
1457 : const char *name;
1458 :
1459 : /* If this is a new word to complete, initialize now. This includes
1460 : saving the length of TEXT for efficiency, and initializing the
1461 : index variable to 0. */
1462 : if (!state)
1463 : {
1464 : list_index = 0;
1465 : len = strlen (text);
1466 : }
1467 :
1468 : /* Return the next partial match */
1469 : while ((name = cmds[list_index].name))
1470 : {
1471 : /* Only complete commands that have help text */
1472 : if (cmds[list_index++].desc && strncmp (name, text, len) == 0)
1473 : return strdup (name);
1474 : }
1475 :
1476 : return NULL;
1477 : }
1478 :
1479 : static char **
1480 : keyedit_completion (const char *text, int start, int end)
1481 : {
1482 : /* If we are at the start of a line, we try and command-complete.
1483 : If not, just do nothing for now. */
1484 :
1485 : (void) end;
1486 :
1487 : if (start == 0)
1488 : return rl_completion_matches (text, command_generator);
1489 :
1490 : rl_attempted_completion_over = 1;
1491 :
1492 : return NULL;
1493 : }
1494 : #endif /* HAVE_LIBREADLINE */
1495 :
1496 :
1497 :
1498 : /* Main function of the menu driven key editor. */
1499 : void
1500 0 : keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
1501 : strlist_t commands, int quiet, int seckey_check)
1502 : {
1503 0 : enum cmdids cmd = 0;
1504 0 : gpg_error_t err = 0;
1505 0 : KBNODE keyblock = NULL;
1506 0 : KEYDB_HANDLE kdbhd = NULL;
1507 0 : int have_seckey = 0;
1508 0 : char *answer = NULL;
1509 0 : int redisplay = 1;
1510 0 : int modified = 0;
1511 0 : int sec_shadowing = 0;
1512 0 : int run_subkey_warnings = 0;
1513 0 : int have_commands = !!commands;
1514 :
1515 0 : if (opt.command_fd != -1)
1516 : ;
1517 0 : else if (opt.batch && !have_commands)
1518 : {
1519 0 : log_error (_("can't do this in batch mode\n"));
1520 0 : goto leave;
1521 : }
1522 :
1523 : #ifdef HAVE_W32_SYSTEM
1524 : /* Due to Windows peculiarities we need to make sure that the
1525 : trustdb stale check is done before we open another file
1526 : (i.e. by searching for a key). In theory we could make sure
1527 : that the files are closed after use but the open/close caches
1528 : inhibits that and flushing the cache right before the stale
1529 : check is not easy to implement. Thus we take the easy way out
1530 : and run the stale check as early as possible. Note, that for
1531 : non- W32 platforms it is run indirectly trough a call to
1532 : get_validity (). */
1533 : check_trustdb_stale ();
1534 : #endif
1535 :
1536 : /* Get the public key */
1537 0 : err = get_pubkey_byname (ctrl, NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
1538 0 : if (err)
1539 : {
1540 0 : log_error (_("key \"%s\" not found: %s\n"), username, gpg_strerror (err));
1541 0 : goto leave;
1542 : }
1543 :
1544 0 : if (fix_keyblock (&keyblock))
1545 0 : modified++;
1546 :
1547 : /* See whether we have a matching secret key. */
1548 0 : if (seckey_check)
1549 : {
1550 0 : have_seckey = !agent_probe_any_secret_key (ctrl, keyblock);
1551 0 : if (have_seckey && !quiet)
1552 0 : tty_printf (_("Secret key is available.\n"));
1553 : }
1554 :
1555 : /* Main command loop. */
1556 : for (;;)
1557 : {
1558 : int i, arg_number, photo;
1559 0 : const char *arg_string = "";
1560 : char *p;
1561 0 : PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1562 :
1563 0 : tty_printf ("\n");
1564 :
1565 0 : if (redisplay && !quiet)
1566 : {
1567 : /* Show using flags: with_revoker, with_subkeys. */
1568 0 : show_key_with_all_names (ctrl, NULL, keyblock, 0, 1, 0, 1, 0, 0);
1569 0 : tty_printf ("\n");
1570 0 : redisplay = 0;
1571 : }
1572 :
1573 0 : if (run_subkey_warnings)
1574 : {
1575 0 : run_subkey_warnings = 0;
1576 0 : if (!count_selected_keys (keyblock))
1577 0 : subkey_expire_warning (keyblock);
1578 : }
1579 :
1580 : do
1581 : {
1582 0 : xfree (answer);
1583 0 : if (have_commands)
1584 : {
1585 0 : if (commands)
1586 : {
1587 0 : answer = xstrdup (commands->d);
1588 0 : commands = commands->next;
1589 : }
1590 0 : else if (opt.batch)
1591 : {
1592 0 : answer = xstrdup ("quit");
1593 : }
1594 : else
1595 0 : have_commands = 0;
1596 : }
1597 0 : if (!have_commands)
1598 : {
1599 : #ifdef HAVE_LIBREADLINE
1600 : tty_enable_completion (keyedit_completion);
1601 : #endif
1602 0 : answer = cpr_get_no_help ("keyedit.prompt", GPG_NAME "> ");
1603 0 : cpr_kill_prompt ();
1604 : tty_disable_completion ();
1605 : }
1606 0 : trim_spaces (answer);
1607 : }
1608 0 : while (*answer == '#');
1609 :
1610 0 : arg_number = 0; /* Here is the init which egcc complains about. */
1611 0 : photo = 0; /* Same here. */
1612 0 : if (!*answer)
1613 0 : cmd = cmdLIST;
1614 0 : else if (*answer == CONTROL_D)
1615 0 : cmd = cmdQUIT;
1616 0 : else if (digitp (answer))
1617 : {
1618 0 : cmd = cmdSELUID;
1619 0 : arg_number = atoi (answer);
1620 : }
1621 : else
1622 : {
1623 0 : if ((p = strchr (answer, ' ')))
1624 : {
1625 0 : *p++ = 0;
1626 0 : trim_spaces (answer);
1627 0 : trim_spaces (p);
1628 0 : arg_number = atoi (p);
1629 0 : arg_string = p;
1630 : }
1631 :
1632 0 : for (i = 0; cmds[i].name; i++)
1633 : {
1634 0 : if (cmds[i].flags & KEYEDIT_TAIL_MATCH)
1635 : {
1636 0 : size_t l = strlen (cmds[i].name);
1637 0 : size_t a = strlen (answer);
1638 0 : if (a >= l)
1639 : {
1640 0 : if (!ascii_strcasecmp (&answer[a - l], cmds[i].name))
1641 : {
1642 0 : answer[a - l] = '\0';
1643 0 : break;
1644 : }
1645 : }
1646 : }
1647 0 : else if (!ascii_strcasecmp (answer, cmds[i].name))
1648 0 : break;
1649 : }
1650 0 : if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
1651 : {
1652 0 : tty_printf (_("Need the secret key to do this.\n"));
1653 0 : cmd = cmdNOP;
1654 : }
1655 : else
1656 0 : cmd = cmds[i].id;
1657 : }
1658 :
1659 : /* Dispatch the command. */
1660 0 : switch (cmd)
1661 : {
1662 : case cmdHELP:
1663 0 : for (i = 0; cmds[i].name; i++)
1664 : {
1665 0 : if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
1666 : ; /* Skip those item if we do not have the secret key. */
1667 0 : else if (cmds[i].desc)
1668 0 : tty_printf ("%-11s %s\n", cmds[i].name, _(cmds[i].desc));
1669 : }
1670 :
1671 0 : tty_printf ("\n");
1672 0 : tty_printf
1673 0 : (_("* The 'sign' command may be prefixed with an 'l' for local "
1674 : "signatures (lsign),\n"
1675 : " a 't' for trust signatures (tsign), an 'nr' for "
1676 : "non-revocable signatures\n"
1677 : " (nrsign), or any combination thereof (ltsign, "
1678 : "tnrsign, etc.).\n"));
1679 0 : break;
1680 :
1681 : case cmdLIST:
1682 0 : redisplay = 1;
1683 0 : break;
1684 :
1685 : case cmdFPR:
1686 0 : show_key_and_fingerprint
1687 0 : (keyblock, (*arg_string == '*'
1688 0 : && (!arg_string[1] || spacep (arg_string + 1))));
1689 0 : break;
1690 :
1691 : case cmdGRIP:
1692 0 : show_key_and_grip (keyblock);
1693 0 : break;
1694 :
1695 : case cmdSELUID:
1696 0 : if (strlen (arg_string) == NAMEHASH_LEN * 2)
1697 0 : redisplay = menu_select_uid_namehash (keyblock, arg_string);
1698 : else
1699 : {
1700 0 : if (*arg_string == '*'
1701 0 : && (!arg_string[1] || spacep (arg_string + 1)))
1702 0 : arg_number = -1; /* Select all. */
1703 0 : redisplay = menu_select_uid (keyblock, arg_number);
1704 : }
1705 0 : break;
1706 :
1707 : case cmdSELKEY:
1708 : {
1709 0 : if (*arg_string == '*'
1710 0 : && (!arg_string[1] || spacep (arg_string + 1)))
1711 0 : arg_number = -1; /* Select all. */
1712 0 : if (menu_select_key (keyblock, arg_number))
1713 0 : redisplay = 1;
1714 : }
1715 0 : break;
1716 :
1717 : case cmdCHECK:
1718 0 : check_all_keysigs (keyblock, count_selected_uids (keyblock),
1719 0 : !strcmp (arg_string, "selfsig"));
1720 0 : break;
1721 :
1722 : case cmdSIGN:
1723 : {
1724 0 : int localsig = 0, nonrevokesig = 0, trustsig = 0, interactive = 0;
1725 :
1726 0 : if (pk->flags.revoked)
1727 : {
1728 0 : tty_printf (_("Key is revoked."));
1729 :
1730 0 : if (opt.expert)
1731 : {
1732 0 : tty_printf (" ");
1733 0 : if (!cpr_get_answer_is_yes
1734 : ("keyedit.sign_revoked.okay",
1735 0 : _("Are you sure you still want to sign it? (y/N) ")))
1736 0 : break;
1737 : }
1738 : else
1739 : {
1740 0 : tty_printf (_(" Unable to sign.\n"));
1741 0 : break;
1742 : }
1743 : }
1744 :
1745 0 : if (count_uids (keyblock) > 1 && !count_selected_uids (keyblock)
1746 0 : && !cpr_get_answer_is_yes ("keyedit.sign_all.okay",
1747 0 : _("Really sign all user IDs?"
1748 : " (y/N) ")))
1749 : {
1750 0 : if (opt.interactive)
1751 0 : interactive = 1;
1752 : else
1753 : {
1754 0 : tty_printf (_("Hint: Select the user IDs to sign\n"));
1755 0 : have_commands = 0;
1756 0 : break;
1757 : }
1758 :
1759 : }
1760 : /* What sort of signing are we doing? */
1761 0 : if (!parse_sign_type
1762 : (answer, &localsig, &nonrevokesig, &trustsig))
1763 : {
1764 0 : tty_printf (_("Unknown signature type '%s'\n"), answer);
1765 0 : break;
1766 : }
1767 :
1768 0 : sign_uids (ctrl, NULL, keyblock, locusr, &modified,
1769 : localsig, nonrevokesig, trustsig, interactive, 0);
1770 : }
1771 0 : break;
1772 :
1773 : case cmdDEBUG:
1774 0 : dump_kbnode (keyblock);
1775 0 : break;
1776 :
1777 : case cmdTOGGLE:
1778 : /* The toggle command is a leftover from old gpg versions
1779 : where we worked with a secret and a public keyring. It
1780 : is not necessary anymore but we keep this command for the
1781 : sake of scripts using it. */
1782 0 : redisplay = 1;
1783 0 : break;
1784 :
1785 : case cmdADDPHOTO:
1786 0 : if (RFC2440)
1787 : {
1788 0 : tty_printf (_("This command is not allowed while in %s mode.\n"),
1789 : compliance_option_string ());
1790 0 : break;
1791 : }
1792 0 : photo = 1;
1793 : /* fall through */
1794 : case cmdADDUID:
1795 0 : if (menu_adduid (keyblock, photo, arg_string, NULL))
1796 : {
1797 0 : update_trust = 1;
1798 0 : redisplay = 1;
1799 0 : modified = 1;
1800 0 : merge_keys_and_selfsig (keyblock);
1801 : }
1802 0 : break;
1803 :
1804 : case cmdDELUID:
1805 : {
1806 : int n1;
1807 :
1808 0 : if (!(n1 = count_selected_uids (keyblock)))
1809 : {
1810 0 : tty_printf (_("You must select at least one user ID.\n"));
1811 0 : if (!opt.expert)
1812 0 : tty_printf (_("(Use the '%s' command.)\n"), "uid");
1813 : }
1814 0 : else if (real_uids_left (keyblock) < 1)
1815 0 : tty_printf (_("You can't delete the last user ID!\n"));
1816 0 : else if (cpr_get_answer_is_yes
1817 : ("keyedit.remove.uid.okay",
1818 : n1 > 1 ? _("Really remove all selected user IDs? (y/N) ")
1819 : : _("Really remove this user ID? (y/N) ")))
1820 : {
1821 0 : menu_deluid (keyblock);
1822 0 : redisplay = 1;
1823 0 : modified = 1;
1824 : }
1825 : }
1826 0 : break;
1827 :
1828 : case cmdDELSIG:
1829 : {
1830 : int n1;
1831 :
1832 0 : if (!(n1 = count_selected_uids (keyblock)))
1833 : {
1834 0 : tty_printf (_("You must select at least one user ID.\n"));
1835 0 : if (!opt.expert)
1836 0 : tty_printf (_("(Use the '%s' command.)\n"), "uid");
1837 : }
1838 0 : else if (menu_delsig (keyblock))
1839 : {
1840 : /* No redisplay here, because it may scroll away some
1841 : * of the status output of this command. */
1842 0 : modified = 1;
1843 : }
1844 : }
1845 0 : break;
1846 :
1847 : case cmdADDKEY:
1848 0 : if (!generate_subkeypair (ctrl, keyblock))
1849 : {
1850 0 : redisplay = 1;
1851 0 : modified = 1;
1852 0 : merge_keys_and_selfsig (keyblock);
1853 : }
1854 0 : break;
1855 :
1856 : #ifdef ENABLE_CARD_SUPPORT
1857 : case cmdADDCARDKEY:
1858 0 : if (!card_generate_subkey (keyblock))
1859 : {
1860 0 : redisplay = 1;
1861 0 : modified = 1;
1862 0 : merge_keys_and_selfsig (keyblock);
1863 : }
1864 0 : break;
1865 :
1866 : case cmdKEYTOCARD:
1867 : {
1868 0 : KBNODE node = NULL;
1869 0 : switch (count_selected_keys (keyblock))
1870 : {
1871 : case 0:
1872 0 : if (cpr_get_answer_is_yes
1873 : ("keyedit.keytocard.use_primary",
1874 : /* TRANSLATORS: Please take care: This is about
1875 : moving the key and not about removing it. */
1876 0 : _("Really move the primary key? (y/N) ")))
1877 0 : node = keyblock;
1878 0 : break;
1879 : case 1:
1880 0 : for (node = keyblock; node; node = node->next)
1881 : {
1882 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1883 0 : && node->flag & NODFLG_SELKEY)
1884 0 : break;
1885 : }
1886 0 : break;
1887 : default:
1888 0 : tty_printf (_("You must select exactly one key.\n"));
1889 0 : break;
1890 : }
1891 0 : if (node)
1892 : {
1893 0 : PKT_public_key *xxpk = node->pkt->pkt.public_key;
1894 0 : if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
1895 : {
1896 0 : redisplay = 1;
1897 0 : sec_shadowing = 1;
1898 : }
1899 : }
1900 : }
1901 0 : break;
1902 :
1903 : case cmdBKUPTOCARD:
1904 : case cmdCHECKBKUPKEY:
1905 0 : log_debug ("FIXME: This needs to be changed\n");
1906 : {
1907 : /* Ask for a filename, check whether this is really a
1908 : backup key as generated by the card generation, parse
1909 : that key and store it on card. */
1910 : KBNODE node;
1911 : const char *fname;
1912 : PACKET *pkt;
1913 : IOBUF a;
1914 :
1915 0 : fname = arg_string;
1916 0 : if (!*fname)
1917 : {
1918 0 : tty_printf (_("Command expects a filename argument\n"));
1919 0 : break;
1920 : }
1921 :
1922 : /* Open that file. */
1923 0 : a = iobuf_open (fname);
1924 0 : if (a && is_secured_file (iobuf_get_fd (a)))
1925 : {
1926 0 : iobuf_close (a);
1927 0 : a = NULL;
1928 0 : gpg_err_set_errno (EPERM);
1929 : }
1930 0 : if (!a)
1931 : {
1932 0 : tty_printf (_("Can't open '%s': %s\n"),
1933 0 : fname, strerror (errno));
1934 0 : break;
1935 : }
1936 :
1937 : /* Parse and check that file. */
1938 0 : pkt = xmalloc (sizeof *pkt);
1939 0 : init_packet (pkt);
1940 0 : err = parse_packet (a, pkt);
1941 0 : iobuf_close (a);
1942 0 : iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname);
1943 0 : if (!err && pkt->pkttype != PKT_SECRET_KEY
1944 0 : && pkt->pkttype != PKT_SECRET_SUBKEY)
1945 0 : err = GPG_ERR_NO_SECKEY;
1946 0 : if (err)
1947 : {
1948 0 : tty_printf (_("Error reading backup key from '%s': %s\n"),
1949 : fname, gpg_strerror (err));
1950 0 : free_packet (pkt);
1951 0 : xfree (pkt);
1952 0 : break;
1953 : }
1954 0 : node = new_kbnode (pkt);
1955 :
1956 0 : if (cmd == cmdCHECKBKUPKEY)
1957 : {
1958 : /* PKT_public_key *sk = node->pkt->pkt.secret_key; */
1959 : /* switch (is_secret_key_protected (sk)) */
1960 : /* { */
1961 : /* case 0: /\* Not protected. *\/ */
1962 : /* tty_printf (_("This key is not protected.\n")); */
1963 : /* break; */
1964 : /* case -1: */
1965 : /* log_error (_("unknown key protection algorithm\n")); */
1966 : /* break; */
1967 : /* default: */
1968 : /* if (sk->protect.s2k.mode == 1001) */
1969 : /* tty_printf (_("Secret parts of key" */
1970 : /* " are not available.\n")); */
1971 : /* if (sk->protect.s2k.mode == 1002) */
1972 : /* tty_printf (_("Secret parts of key" */
1973 : /* " are stored on-card.\n")); */
1974 : /* else */
1975 : /* check_secret_key (sk, 0); */
1976 : /* } */
1977 : }
1978 : else /* Store it. */
1979 : {
1980 0 : if (card_store_subkey (node, 0))
1981 : {
1982 0 : redisplay = 1;
1983 0 : sec_shadowing = 1;
1984 : }
1985 : }
1986 0 : release_kbnode (node);
1987 : }
1988 0 : break;
1989 :
1990 : #endif /* ENABLE_CARD_SUPPORT */
1991 :
1992 : case cmdDELKEY:
1993 : {
1994 : int n1;
1995 :
1996 0 : if (!(n1 = count_selected_keys (keyblock)))
1997 : {
1998 0 : tty_printf (_("You must select at least one key.\n"));
1999 0 : if (!opt.expert)
2000 0 : tty_printf (_("(Use the '%s' command.)\n"), "key");
2001 : }
2002 0 : else if (!cpr_get_answer_is_yes
2003 : ("keyedit.remove.subkey.okay",
2004 : n1 > 1 ? _("Do you really want to delete the "
2005 : "selected keys? (y/N) ")
2006 : : _("Do you really want to delete this key? (y/N) ")))
2007 : ;
2008 : else
2009 : {
2010 0 : menu_delkey (keyblock);
2011 0 : redisplay = 1;
2012 0 : modified = 1;
2013 : }
2014 : }
2015 0 : break;
2016 :
2017 : case cmdADDREVOKER:
2018 : {
2019 0 : int sensitive = 0;
2020 :
2021 0 : if (ascii_strcasecmp (arg_string, "sensitive") == 0)
2022 0 : sensitive = 1;
2023 0 : if (menu_addrevoker (ctrl, keyblock, sensitive))
2024 : {
2025 0 : redisplay = 1;
2026 0 : modified = 1;
2027 0 : merge_keys_and_selfsig (keyblock);
2028 : }
2029 : }
2030 0 : break;
2031 :
2032 : case cmdREVUID:
2033 : {
2034 : int n1;
2035 :
2036 0 : if (!(n1 = count_selected_uids (keyblock)))
2037 : {
2038 0 : tty_printf (_("You must select at least one user ID.\n"));
2039 0 : if (!opt.expert)
2040 0 : tty_printf (_("(Use the '%s' command.)\n"), "uid");
2041 : }
2042 0 : else if (cpr_get_answer_is_yes
2043 : ("keyedit.revoke.uid.okay",
2044 : n1 > 1 ? _("Really revoke all selected user IDs? (y/N) ")
2045 : : _("Really revoke this user ID? (y/N) ")))
2046 : {
2047 0 : if (menu_revuid (keyblock))
2048 : {
2049 0 : modified = 1;
2050 0 : redisplay = 1;
2051 : }
2052 : }
2053 : }
2054 0 : break;
2055 :
2056 : case cmdREVKEY:
2057 : {
2058 : int n1;
2059 :
2060 0 : if (!(n1 = count_selected_keys (keyblock)))
2061 : {
2062 0 : if (cpr_get_answer_is_yes ("keyedit.revoke.subkey.okay",
2063 0 : _("Do you really want to revoke"
2064 : " the entire key? (y/N) ")))
2065 : {
2066 0 : if (menu_revkey (keyblock))
2067 0 : modified = 1;
2068 :
2069 0 : redisplay = 1;
2070 : }
2071 : }
2072 0 : else if (cpr_get_answer_is_yes ("keyedit.revoke.subkey.okay",
2073 : n1 > 1 ?
2074 : _("Do you really want to revoke"
2075 : " the selected subkeys? (y/N) ")
2076 : : _("Do you really want to revoke"
2077 : " this subkey? (y/N) ")))
2078 : {
2079 0 : if (menu_revsubkey (keyblock))
2080 0 : modified = 1;
2081 :
2082 0 : redisplay = 1;
2083 : }
2084 :
2085 0 : if (modified)
2086 0 : merge_keys_and_selfsig (keyblock);
2087 : }
2088 0 : break;
2089 :
2090 : case cmdEXPIRE:
2091 0 : if (menu_expire (keyblock))
2092 : {
2093 0 : merge_keys_and_selfsig (keyblock);
2094 0 : run_subkey_warnings = 1;
2095 0 : modified = 1;
2096 0 : redisplay = 1;
2097 : }
2098 0 : break;
2099 :
2100 : case cmdBACKSIGN:
2101 0 : if (menu_backsign (keyblock))
2102 : {
2103 0 : modified = 1;
2104 0 : redisplay = 1;
2105 : }
2106 0 : break;
2107 :
2108 : case cmdPRIMARY:
2109 0 : if (menu_set_primary_uid (keyblock))
2110 : {
2111 0 : merge_keys_and_selfsig (keyblock);
2112 0 : modified = 1;
2113 0 : redisplay = 1;
2114 : }
2115 0 : break;
2116 :
2117 : case cmdPASSWD:
2118 0 : change_passphrase (ctrl, keyblock);
2119 0 : break;
2120 :
2121 : #ifndef NO_TRUST_MODELS
2122 : case cmdTRUST:
2123 0 : if (opt.trust_model == TM_EXTERNAL)
2124 : {
2125 0 : tty_printf (_("Owner trust may not be set while "
2126 : "using a user provided trust database\n"));
2127 0 : break;
2128 : }
2129 :
2130 0 : show_key_with_all_names (ctrl, NULL, keyblock, 0, 0, 0, 1, 0, 0);
2131 0 : tty_printf ("\n");
2132 0 : if (edit_ownertrust (find_kbnode (keyblock,
2133 0 : PKT_PUBLIC_KEY)->pkt->pkt.
2134 : public_key, 1))
2135 : {
2136 0 : redisplay = 1;
2137 : /* No real need to set update_trust here as
2138 : edit_ownertrust() calls revalidation_mark()
2139 : anyway. */
2140 0 : update_trust = 1;
2141 : }
2142 0 : break;
2143 : #endif /*!NO_TRUST_MODELS*/
2144 :
2145 : case cmdPREF:
2146 : {
2147 0 : int count = count_selected_uids (keyblock);
2148 0 : assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
2149 0 : show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
2150 : count ? NODFLG_SELUID : 0, 1);
2151 : }
2152 0 : break;
2153 :
2154 : case cmdSHOWPREF:
2155 : {
2156 0 : int count = count_selected_uids (keyblock);
2157 0 : assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
2158 0 : show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
2159 : count ? NODFLG_SELUID : 0, 2);
2160 : }
2161 0 : break;
2162 :
2163 : case cmdSETPREF:
2164 : {
2165 : PKT_user_id *tempuid;
2166 :
2167 0 : keygen_set_std_prefs (!*arg_string ? "default" : arg_string, 0);
2168 :
2169 0 : tempuid = keygen_get_std_prefs ();
2170 0 : tty_printf (_("Set preference list to:\n"));
2171 0 : show_prefs (tempuid, NULL, 1);
2172 0 : free_user_id (tempuid);
2173 :
2174 0 : if (cpr_get_answer_is_yes
2175 : ("keyedit.setpref.okay",
2176 0 : count_selected_uids (keyblock) ?
2177 : _("Really update the preferences"
2178 : " for the selected user IDs? (y/N) ")
2179 : : _("Really update the preferences? (y/N) ")))
2180 : {
2181 0 : if (menu_set_preferences (keyblock))
2182 : {
2183 0 : merge_keys_and_selfsig (keyblock);
2184 0 : modified = 1;
2185 0 : redisplay = 1;
2186 : }
2187 : }
2188 : }
2189 0 : break;
2190 :
2191 : case cmdPREFKS:
2192 0 : if (menu_set_keyserver_url (*arg_string ? arg_string : NULL,
2193 : keyblock))
2194 : {
2195 0 : merge_keys_and_selfsig (keyblock);
2196 0 : modified = 1;
2197 0 : redisplay = 1;
2198 : }
2199 0 : break;
2200 :
2201 : case cmdNOTATION:
2202 0 : if (menu_set_notation (*arg_string ? arg_string : NULL,
2203 : keyblock))
2204 : {
2205 0 : merge_keys_and_selfsig (keyblock);
2206 0 : modified = 1;
2207 0 : redisplay = 1;
2208 : }
2209 0 : break;
2210 :
2211 : case cmdNOP:
2212 0 : break;
2213 :
2214 : case cmdREVSIG:
2215 0 : if (menu_revsig (keyblock))
2216 : {
2217 0 : redisplay = 1;
2218 0 : modified = 1;
2219 : }
2220 0 : break;
2221 :
2222 : #ifndef NO_TRUST_MODELS
2223 : case cmdENABLEKEY:
2224 : case cmdDISABLEKEY:
2225 0 : if (enable_disable_key (keyblock, cmd == cmdDISABLEKEY))
2226 : {
2227 0 : redisplay = 1;
2228 0 : modified = 1;
2229 : }
2230 0 : break;
2231 : #endif /*!NO_TRUST_MODELS*/
2232 :
2233 : case cmdSHOWPHOTO:
2234 0 : menu_showphoto (keyblock);
2235 0 : break;
2236 :
2237 : case cmdCLEAN:
2238 0 : if (menu_clean (keyblock, 0))
2239 0 : redisplay = modified = 1;
2240 0 : break;
2241 :
2242 : case cmdMINIMIZE:
2243 0 : if (menu_clean (keyblock, 1))
2244 0 : redisplay = modified = 1;
2245 0 : break;
2246 :
2247 : case cmdQUIT:
2248 0 : if (have_commands)
2249 0 : goto leave;
2250 0 : if (!modified && !sec_shadowing)
2251 0 : goto leave;
2252 0 : if (!cpr_get_answer_is_yes ("keyedit.save.okay",
2253 0 : _("Save changes? (y/N) ")))
2254 : {
2255 0 : if (cpr_enabled ()
2256 0 : || cpr_get_answer_is_yes ("keyedit.cancel.okay",
2257 0 : _("Quit without saving? (y/N) ")))
2258 : goto leave;
2259 0 : break;
2260 : }
2261 : /* fall thru */
2262 : case cmdSAVE:
2263 0 : if (modified)
2264 : {
2265 0 : err = keydb_update_keyblock (kdbhd, keyblock);
2266 0 : if (err)
2267 : {
2268 0 : log_error (_("update failed: %s\n"), gpg_strerror (err));
2269 0 : break;
2270 : }
2271 : }
2272 :
2273 0 : if (sec_shadowing)
2274 : {
2275 0 : err = agent_scd_learn (NULL, 1);
2276 0 : if (err)
2277 : {
2278 0 : log_error (_("update failed: %s\n"), gpg_strerror (err));
2279 0 : break;
2280 : }
2281 : }
2282 :
2283 0 : if (!modified && !sec_shadowing)
2284 0 : tty_printf (_("Key not changed so no update needed.\n"));
2285 :
2286 0 : if (update_trust)
2287 : {
2288 0 : revalidation_mark ();
2289 0 : update_trust = 0;
2290 : }
2291 0 : goto leave;
2292 :
2293 : case cmdINVCMD:
2294 : default:
2295 0 : tty_printf ("\n");
2296 0 : tty_printf (_("Invalid command (try \"help\")\n"));
2297 0 : break;
2298 : }
2299 0 : } /* End of the main command loop. */
2300 :
2301 : leave:
2302 0 : release_kbnode (keyblock);
2303 0 : keydb_release (kdbhd);
2304 0 : xfree (answer);
2305 0 : }
2306 :
2307 :
2308 : /* Change the passphrase of the secret key identified by USERNAME. */
2309 : void
2310 0 : keyedit_passwd (ctrl_t ctrl, const char *username)
2311 : {
2312 : gpg_error_t err;
2313 : PKT_public_key *pk;
2314 0 : kbnode_t keyblock = NULL;
2315 :
2316 0 : pk = xtrycalloc (1, sizeof *pk);
2317 0 : if (!pk)
2318 : {
2319 0 : err = gpg_error_from_syserror ();
2320 0 : goto leave;
2321 : }
2322 0 : err = getkey_byname (ctrl, NULL, pk, username, 1, &keyblock);
2323 0 : if (err)
2324 0 : goto leave;
2325 :
2326 0 : err = change_passphrase (ctrl, keyblock);
2327 :
2328 : leave:
2329 0 : release_kbnode (keyblock);
2330 0 : free_public_key (pk);
2331 0 : if (err)
2332 : {
2333 0 : log_info ("error changing the passphrase for '%s': %s\n",
2334 : username, gpg_strerror (err));
2335 0 : write_status_error ("keyedit.passwd", err);
2336 : }
2337 : else
2338 0 : write_status_text (STATUS_SUCCESS, "keyedit.passwd");
2339 0 : }
2340 :
2341 :
2342 : /* Unattended adding of a new keyid. USERNAME specifies the
2343 : key. NEWUID is the new user id to add to the key. */
2344 : void
2345 0 : keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
2346 : {
2347 : gpg_error_t err;
2348 0 : KEYDB_HANDLE kdbhd = NULL;
2349 : KEYDB_SEARCH_DESC desc;
2350 0 : kbnode_t keyblock = NULL;
2351 : kbnode_t node;
2352 0 : char *uidstring = NULL;
2353 :
2354 0 : uidstring = xstrdup (newuid);
2355 0 : trim_spaces (uidstring);
2356 0 : if (!*uidstring)
2357 : {
2358 0 : log_error ("%s\n", gpg_strerror (GPG_ERR_INV_USER_ID));
2359 0 : goto leave;
2360 : }
2361 :
2362 : #ifdef HAVE_W32_SYSTEM
2363 : /* See keyedit_menu for why we need this. */
2364 : check_trustdb_stale ();
2365 : #endif
2366 :
2367 : /* Search the key; we don't want the whole getkey stuff here. */
2368 0 : kdbhd = keydb_new ();
2369 0 : err = classify_user_id (username, &desc, 1);
2370 0 : if (!err)
2371 0 : err = keydb_search (kdbhd, &desc, 1, NULL);
2372 0 : if (!err)
2373 : {
2374 0 : err = keydb_get_keyblock (kdbhd, &keyblock);
2375 0 : if (err)
2376 : {
2377 0 : log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
2378 0 : goto leave;
2379 : }
2380 : /* Now with the keyblock retrieved, search again to detect an
2381 : ambiguous specification. We need to save the found state so
2382 : that we can do an update later. */
2383 0 : keydb_push_found_state (kdbhd);
2384 0 : err = keydb_search (kdbhd, &desc, 1, NULL);
2385 0 : if (!err)
2386 0 : err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
2387 0 : else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
2388 0 : err = 0;
2389 0 : keydb_pop_found_state (kdbhd);
2390 :
2391 0 : if (!err)
2392 : {
2393 : /* We require the secret primary key to add a UID. */
2394 0 : node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
2395 0 : if (!node)
2396 0 : BUG ();
2397 0 : err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
2398 : }
2399 : }
2400 0 : if (err)
2401 : {
2402 0 : log_error (_("secret key \"%s\" not found: %s\n"),
2403 : username, gpg_strerror (err));
2404 0 : goto leave;
2405 : }
2406 :
2407 0 : fix_keyblock (&keyblock);
2408 :
2409 0 : if (menu_adduid (keyblock, 0, NULL, uidstring))
2410 : {
2411 0 : err = keydb_update_keyblock (kdbhd, keyblock);
2412 0 : if (err)
2413 : {
2414 0 : log_error (_("update failed: %s\n"), gpg_strerror (err));
2415 0 : goto leave;
2416 : }
2417 :
2418 0 : if (update_trust)
2419 0 : revalidation_mark ();
2420 : }
2421 :
2422 : leave:
2423 0 : xfree (uidstring);
2424 0 : release_kbnode (keyblock);
2425 0 : keydb_release (kdbhd);
2426 0 : }
2427 :
2428 :
2429 : /* Unattended key signing function. If the key specifified by FPR is
2430 : availabale and FPR is the primary fingerprint all user ids of the
2431 : user ids of the key are signed using the default signing key. If
2432 : UIDS is an empty list all usable UIDs are signed, if it is not
2433 : empty, only those user ids matching one of the entries of the loist
2434 : are signed. With LOCAL being true kthe signatures are marked as
2435 : non-exportable. */
2436 : void
2437 0 : keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
2438 : strlist_t locusr, int local)
2439 : {
2440 : gpg_error_t err;
2441 0 : kbnode_t keyblock = NULL;
2442 0 : KEYDB_HANDLE kdbhd = NULL;
2443 0 : int modified = 0;
2444 : KEYDB_SEARCH_DESC desc;
2445 : PKT_public_key *pk;
2446 : kbnode_t node;
2447 : strlist_t sl;
2448 : int any;
2449 :
2450 : #ifdef HAVE_W32_SYSTEM
2451 : /* See keyedit_menu for why we need this. */
2452 : check_trustdb_stale ();
2453 : #endif
2454 :
2455 : /* We require a fingerprint because only this uniquely identifies a
2456 : key and may thus be used to select a key for unattended key
2457 : signing. */
2458 0 : if (classify_user_id (fpr, &desc, 1)
2459 0 : || !(desc.mode == KEYDB_SEARCH_MODE_FPR
2460 0 : || desc.mode == KEYDB_SEARCH_MODE_FPR16
2461 0 : || desc.mode == KEYDB_SEARCH_MODE_FPR20))
2462 : {
2463 0 : log_error (_("\"%s\" is not a fingerprint\n"), fpr);
2464 0 : goto leave;
2465 : }
2466 0 : err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
2467 0 : if (err)
2468 : {
2469 0 : log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
2470 0 : goto leave;
2471 : }
2472 :
2473 : /* Check that the primary fingerprint has been given. */
2474 : {
2475 : byte fprbin[MAX_FINGERPRINT_LEN];
2476 : size_t fprlen;
2477 :
2478 0 : fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
2479 0 : if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
2480 0 : && !memcmp (fprbin, desc.u.fpr, 16))
2481 : ;
2482 0 : else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
2483 0 : && !memcmp (fprbin, desc.u.fpr, 16)
2484 0 : && !desc.u.fpr[16]
2485 0 : && !desc.u.fpr[17]
2486 0 : && !desc.u.fpr[18]
2487 0 : && !desc.u.fpr[19])
2488 : ;
2489 0 : else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
2490 0 : || desc.mode == KEYDB_SEARCH_MODE_FPR)
2491 0 : && !memcmp (fprbin, desc.u.fpr, 20))
2492 : ;
2493 : else
2494 : {
2495 0 : log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
2496 0 : goto leave;
2497 : }
2498 : }
2499 :
2500 0 : if (fix_keyblock (&keyblock))
2501 0 : modified++;
2502 :
2503 : /* Give some info in verbose. */
2504 0 : if (opt.verbose)
2505 : {
2506 0 : show_key_with_all_names (ctrl, es_stdout, keyblock, 0,
2507 : 1/*with_revoker*/, 1/*with_fingerprint*/,
2508 : 0, 0, 1);
2509 0 : es_fflush (es_stdout);
2510 : }
2511 :
2512 0 : pk = keyblock->pkt->pkt.public_key;
2513 0 : if (pk->flags.revoked)
2514 : {
2515 0 : if (!opt.verbose)
2516 0 : show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
2517 0 : log_error ("%s%s", _("Key is revoked."), _(" Unable to sign.\n"));
2518 0 : goto leave;
2519 : }
2520 :
2521 : /* Set the flags according to the UIDS list. Fixme: We may want to
2522 : use classify_user_id along with dedicated compare functions so
2523 : that we match the same way as in the key lookup. */
2524 0 : any = 0;
2525 0 : menu_select_uid (keyblock, 0); /* Better clear the flags first. */
2526 0 : for (sl=uids; sl; sl = sl->next)
2527 : {
2528 0 : for (node = keyblock; node; node = node->next)
2529 : {
2530 0 : if (node->pkt->pkttype == PKT_USER_ID)
2531 : {
2532 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
2533 :
2534 0 : if (!uid->attrib_data
2535 0 : && ascii_memistr (uid->name, uid->len, sl->d))
2536 : {
2537 0 : node->flag |= NODFLG_SELUID;
2538 0 : any = 1;
2539 : }
2540 : }
2541 : }
2542 : }
2543 :
2544 0 : if (uids && !any)
2545 : {
2546 0 : if (!opt.verbose)
2547 0 : show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
2548 0 : es_fflush (es_stdout);
2549 0 : log_error ("%s %s", _("No matching user IDs."), _("Nothing to sign.\n"));
2550 0 : goto leave;
2551 : }
2552 :
2553 : /* Sign. */
2554 0 : sign_uids (ctrl, es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
2555 0 : es_fflush (es_stdout);
2556 :
2557 0 : if (modified)
2558 : {
2559 0 : err = keydb_update_keyblock (kdbhd, keyblock);
2560 0 : if (err)
2561 : {
2562 0 : log_error (_("update failed: %s\n"), gpg_strerror (err));
2563 0 : goto leave;
2564 : }
2565 : }
2566 : else
2567 0 : log_info (_("Key not changed so no update needed.\n"));
2568 :
2569 0 : if (update_trust)
2570 0 : revalidation_mark ();
2571 :
2572 :
2573 : leave:
2574 0 : release_kbnode (keyblock);
2575 0 : keydb_release (kdbhd);
2576 0 : }
2577 :
2578 :
2579 :
2580 : static void
2581 0 : tty_print_notations (int indent, PKT_signature * sig)
2582 : {
2583 0 : int first = 1;
2584 : struct notation *notation, *nd;
2585 :
2586 0 : if (indent < 0)
2587 : {
2588 0 : first = 0;
2589 0 : indent = -indent;
2590 : }
2591 :
2592 0 : notation = sig_to_notation (sig);
2593 :
2594 0 : for (nd = notation; nd; nd = nd->next)
2595 : {
2596 0 : if (!first)
2597 0 : tty_printf ("%*s", indent, "");
2598 : else
2599 0 : first = 0;
2600 :
2601 0 : tty_print_utf8_string (nd->name, strlen (nd->name));
2602 0 : tty_printf ("=");
2603 0 : tty_print_utf8_string (nd->value, strlen (nd->value));
2604 0 : tty_printf ("\n");
2605 : }
2606 :
2607 0 : free_notation (notation);
2608 0 : }
2609 :
2610 :
2611 : /*
2612 : * Show preferences of a public keyblock.
2613 : */
2614 : static void
2615 0 : show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
2616 : {
2617 0 : const prefitem_t fake = { 0, 0 };
2618 : const prefitem_t *prefs;
2619 : int i;
2620 :
2621 0 : if (!uid)
2622 0 : return;
2623 :
2624 0 : if (uid->prefs)
2625 0 : prefs = uid->prefs;
2626 0 : else if (verbose)
2627 0 : prefs = &fake;
2628 : else
2629 0 : return;
2630 :
2631 0 : if (verbose)
2632 : {
2633 0 : int any, des_seen = 0, sha1_seen = 0, uncomp_seen = 0;
2634 :
2635 0 : tty_printf (" ");
2636 0 : tty_printf (_("Cipher: "));
2637 0 : for (i = any = 0; prefs[i].type; i++)
2638 : {
2639 0 : if (prefs[i].type == PREFTYPE_SYM)
2640 : {
2641 0 : if (any)
2642 0 : tty_printf (", ");
2643 0 : any = 1;
2644 : /* We don't want to display strings for experimental algos */
2645 0 : if (!openpgp_cipher_test_algo (prefs[i].value)
2646 0 : && prefs[i].value < 100)
2647 0 : tty_printf ("%s", openpgp_cipher_algo_name (prefs[i].value));
2648 : else
2649 0 : tty_printf ("[%d]", prefs[i].value);
2650 0 : if (prefs[i].value == CIPHER_ALGO_3DES)
2651 0 : des_seen = 1;
2652 : }
2653 : }
2654 0 : if (!des_seen)
2655 : {
2656 0 : if (any)
2657 0 : tty_printf (", ");
2658 0 : tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
2659 : }
2660 0 : tty_printf ("\n ");
2661 0 : tty_printf (_("Digest: "));
2662 0 : for (i = any = 0; prefs[i].type; i++)
2663 : {
2664 0 : if (prefs[i].type == PREFTYPE_HASH)
2665 : {
2666 0 : if (any)
2667 0 : tty_printf (", ");
2668 0 : any = 1;
2669 : /* We don't want to display strings for experimental algos */
2670 0 : if (!gcry_md_test_algo (prefs[i].value) && prefs[i].value < 100)
2671 0 : tty_printf ("%s", gcry_md_algo_name (prefs[i].value));
2672 : else
2673 0 : tty_printf ("[%d]", prefs[i].value);
2674 0 : if (prefs[i].value == DIGEST_ALGO_SHA1)
2675 0 : sha1_seen = 1;
2676 : }
2677 : }
2678 0 : if (!sha1_seen)
2679 : {
2680 0 : if (any)
2681 0 : tty_printf (", ");
2682 0 : tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
2683 : }
2684 0 : tty_printf ("\n ");
2685 0 : tty_printf (_("Compression: "));
2686 0 : for (i = any = 0; prefs[i].type; i++)
2687 : {
2688 0 : if (prefs[i].type == PREFTYPE_ZIP)
2689 : {
2690 0 : const char *s = compress_algo_to_string (prefs[i].value);
2691 :
2692 0 : if (any)
2693 0 : tty_printf (", ");
2694 0 : any = 1;
2695 : /* We don't want to display strings for experimental algos */
2696 0 : if (s && prefs[i].value < 100)
2697 0 : tty_printf ("%s", s);
2698 : else
2699 0 : tty_printf ("[%d]", prefs[i].value);
2700 0 : if (prefs[i].value == COMPRESS_ALGO_NONE)
2701 0 : uncomp_seen = 1;
2702 : }
2703 : }
2704 0 : if (!uncomp_seen)
2705 : {
2706 0 : if (any)
2707 0 : tty_printf (", ");
2708 : else
2709 : {
2710 0 : tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_ZIP));
2711 0 : tty_printf (", ");
2712 : }
2713 0 : tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_NONE));
2714 : }
2715 0 : if (uid->flags.mdc || !uid->flags.ks_modify)
2716 : {
2717 0 : tty_printf ("\n ");
2718 0 : tty_printf (_("Features: "));
2719 0 : any = 0;
2720 0 : if (uid->flags.mdc)
2721 : {
2722 0 : tty_printf ("MDC");
2723 0 : any = 1;
2724 : }
2725 0 : if (!uid->flags.ks_modify)
2726 : {
2727 0 : if (any)
2728 0 : tty_printf (", ");
2729 0 : tty_printf (_("Keyserver no-modify"));
2730 : }
2731 : }
2732 0 : tty_printf ("\n");
2733 :
2734 0 : if (selfsig)
2735 : {
2736 : const byte *pref_ks;
2737 : size_t pref_ks_len;
2738 :
2739 0 : pref_ks = parse_sig_subpkt (selfsig->hashed,
2740 : SIGSUBPKT_PREF_KS, &pref_ks_len);
2741 0 : if (pref_ks && pref_ks_len)
2742 : {
2743 0 : tty_printf (" ");
2744 0 : tty_printf (_("Preferred keyserver: "));
2745 0 : tty_print_utf8_string (pref_ks, pref_ks_len);
2746 0 : tty_printf ("\n");
2747 : }
2748 :
2749 0 : if (selfsig->flags.notation)
2750 : {
2751 0 : tty_printf (" ");
2752 0 : tty_printf (_("Notations: "));
2753 0 : tty_print_notations (5 + strlen (_("Notations: ")), selfsig);
2754 : }
2755 : }
2756 : }
2757 : else
2758 : {
2759 0 : tty_printf (" ");
2760 0 : for (i = 0; prefs[i].type; i++)
2761 : {
2762 0 : tty_printf (" %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
2763 0 : prefs[i].type == PREFTYPE_HASH ? 'H' :
2764 0 : prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?',
2765 0 : prefs[i].value);
2766 : }
2767 0 : if (uid->flags.mdc)
2768 0 : tty_printf (" [mdc]");
2769 0 : if (!uid->flags.ks_modify)
2770 0 : tty_printf (" [no-ks-modify]");
2771 0 : tty_printf ("\n");
2772 : }
2773 : }
2774 :
2775 :
2776 : /* This is the version of show_key_with_all_names used when
2777 : opt.with_colons is used. It prints all available data in a easy to
2778 : parse format and does not translate utf8 */
2779 : static void
2780 0 : show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
2781 : {
2782 : KBNODE node;
2783 0 : int i, j, ulti_hack = 0;
2784 0 : byte pk_version = 0;
2785 0 : PKT_public_key *primary = NULL;
2786 : int have_seckey;
2787 :
2788 0 : if (!fp)
2789 0 : fp = es_stdout;
2790 :
2791 : /* the keys */
2792 0 : for (node = keyblock; node; node = node->next)
2793 : {
2794 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
2795 0 : || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
2796 : {
2797 0 : PKT_public_key *pk = node->pkt->pkt.public_key;
2798 : u32 keyid[2];
2799 :
2800 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2801 : {
2802 0 : pk_version = pk->version;
2803 0 : primary = pk;
2804 : }
2805 :
2806 0 : keyid_from_pk (pk, keyid);
2807 0 : have_seckey = !agent_probe_secret_key (ctrl, pk);
2808 :
2809 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2810 0 : es_fputs (have_seckey? "sec:" : "pub:", fp);
2811 : else
2812 0 : es_fputs (have_seckey? "ssb:" : "sub:", fp);
2813 :
2814 0 : if (!pk->flags.valid)
2815 0 : es_putc ('i', fp);
2816 0 : else if (pk->flags.revoked)
2817 0 : es_putc ('r', fp);
2818 0 : else if (pk->has_expired)
2819 0 : es_putc ('e', fp);
2820 0 : else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks))
2821 : {
2822 0 : int trust = get_validity_info (pk, NULL);
2823 0 : if (trust == 'u')
2824 0 : ulti_hack = 1;
2825 0 : es_putc (trust, fp);
2826 : }
2827 :
2828 0 : es_fprintf (fp, ":%u:%d:%08lX%08lX:%lu:%lu::",
2829 : nbits_from_pk (pk),
2830 0 : pk->pubkey_algo,
2831 0 : (ulong) keyid[0], (ulong) keyid[1],
2832 0 : (ulong) pk->timestamp, (ulong) pk->expiredate);
2833 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
2834 0 : && !(opt.fast_list_mode || opt.no_expensive_trust_checks))
2835 0 : es_putc (get_ownertrust_info (pk), fp);
2836 0 : es_putc (':', fp);
2837 0 : es_putc (':', fp);
2838 0 : es_putc (':', fp);
2839 : /* Print capabilities. */
2840 0 : if ((pk->pubkey_usage & PUBKEY_USAGE_ENC))
2841 0 : es_putc ('e', fp);
2842 0 : if ((pk->pubkey_usage & PUBKEY_USAGE_SIG))
2843 0 : es_putc ('s', fp);
2844 0 : if ((pk->pubkey_usage & PUBKEY_USAGE_CERT))
2845 0 : es_putc ('c', fp);
2846 0 : if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
2847 0 : es_putc ('a', fp);
2848 0 : es_putc ('\n', fp);
2849 :
2850 0 : print_fingerprint (fp, pk, 0);
2851 0 : print_revokers (fp, pk);
2852 : }
2853 : }
2854 :
2855 : /* the user ids */
2856 0 : i = 0;
2857 0 : for (node = keyblock; node; node = node->next)
2858 : {
2859 0 : if (node->pkt->pkttype == PKT_USER_ID)
2860 : {
2861 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
2862 :
2863 0 : ++i;
2864 :
2865 0 : if (uid->attrib_data)
2866 0 : es_fputs ("uat:", fp);
2867 : else
2868 0 : es_fputs ("uid:", fp);
2869 :
2870 0 : if (uid->is_revoked)
2871 0 : es_fputs ("r::::::::", fp);
2872 0 : else if (uid->is_expired)
2873 0 : es_fputs ("e::::::::", fp);
2874 0 : else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
2875 0 : es_fputs ("::::::::", fp);
2876 : else
2877 : {
2878 : int uid_validity;
2879 :
2880 0 : if (primary && !ulti_hack)
2881 0 : uid_validity = get_validity_info (primary, uid);
2882 : else
2883 0 : uid_validity = 'u';
2884 0 : es_fprintf (fp, "%c::::::::", uid_validity);
2885 : }
2886 :
2887 0 : if (uid->attrib_data)
2888 0 : es_fprintf (fp, "%u %lu", uid->numattribs, uid->attrib_len);
2889 : else
2890 0 : es_write_sanitized (fp, uid->name, uid->len, ":", NULL);
2891 :
2892 0 : es_putc (':', fp);
2893 : /* signature class */
2894 0 : es_putc (':', fp);
2895 : /* capabilities */
2896 0 : es_putc (':', fp);
2897 : /* preferences */
2898 0 : if (pk_version > 3 || uid->selfsigversion > 3)
2899 : {
2900 0 : const prefitem_t *prefs = uid->prefs;
2901 :
2902 0 : for (j = 0; prefs && prefs[j].type; j++)
2903 : {
2904 0 : if (j)
2905 0 : es_putc (' ', fp);
2906 0 : es_fprintf (fp,
2907 0 : "%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
2908 0 : prefs[j].type == PREFTYPE_HASH ? 'H' :
2909 0 : prefs[j].type == PREFTYPE_ZIP ? 'Z' : '?',
2910 0 : prefs[j].value);
2911 : }
2912 0 : if (uid->flags.mdc)
2913 0 : es_fputs (",mdc", fp);
2914 0 : if (!uid->flags.ks_modify)
2915 0 : es_fputs (",no-ks-modify", fp);
2916 : }
2917 0 : es_putc (':', fp);
2918 : /* flags */
2919 0 : es_fprintf (fp, "%d,", i);
2920 0 : if (uid->is_primary)
2921 0 : es_putc ('p', fp);
2922 0 : if (uid->is_revoked)
2923 0 : es_putc ('r', fp);
2924 0 : if (uid->is_expired)
2925 0 : es_putc ('e', fp);
2926 0 : if ((node->flag & NODFLG_SELUID))
2927 0 : es_putc ('s', fp);
2928 0 : if ((node->flag & NODFLG_MARK_A))
2929 0 : es_putc ('m', fp);
2930 0 : es_putc (':', fp);
2931 0 : if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)
2932 : {
2933 : #ifdef USE_TOFU
2934 : enum tofu_policy policy;
2935 0 : if (! tofu_get_policy (primary, uid, &policy)
2936 0 : && policy != TOFU_POLICY_NONE)
2937 0 : es_fprintf (fp, "%s", tofu_policy_str (policy));
2938 : #endif /*USE_TOFU*/
2939 : }
2940 0 : es_putc (':', fp);
2941 0 : es_putc ('\n', fp);
2942 : }
2943 : }
2944 0 : }
2945 :
2946 :
2947 : static void
2948 0 : show_names (estream_t fp,
2949 : KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
2950 : int with_prefs)
2951 : {
2952 : KBNODE node;
2953 0 : int i = 0;
2954 :
2955 0 : for (node = keyblock; node; node = node->next)
2956 : {
2957 0 : if (node->pkt->pkttype == PKT_USER_ID && !is_deleted_kbnode (node))
2958 : {
2959 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
2960 0 : ++i;
2961 0 : if (!flag || (flag && (node->flag & flag)))
2962 : {
2963 0 : if (!(flag & NODFLG_MARK_A) && pk)
2964 0 : tty_fprintf (fp, "%s ", uid_trust_string_fixed (pk, uid));
2965 :
2966 0 : if (flag & NODFLG_MARK_A)
2967 0 : tty_fprintf (fp, " ");
2968 0 : else if (node->flag & NODFLG_SELUID)
2969 0 : tty_fprintf (fp, "(%d)* ", i);
2970 0 : else if (uid->is_primary)
2971 0 : tty_fprintf (fp, "(%d). ", i);
2972 : else
2973 0 : tty_fprintf (fp, "(%d) ", i);
2974 0 : tty_print_utf8_string2 (fp, uid->name, uid->len, 0);
2975 0 : tty_fprintf (fp, "\n");
2976 0 : if (with_prefs && pk)
2977 : {
2978 0 : if (pk->version > 3 || uid->selfsigversion > 3)
2979 0 : {
2980 0 : PKT_signature *selfsig = NULL;
2981 : KBNODE signode;
2982 :
2983 0 : for (signode = node->next;
2984 0 : signode && signode->pkt->pkttype == PKT_SIGNATURE;
2985 0 : signode = signode->next)
2986 : {
2987 0 : if (signode->pkt->pkt.signature->
2988 : flags.chosen_selfsig)
2989 : {
2990 0 : selfsig = signode->pkt->pkt.signature;
2991 0 : break;
2992 : }
2993 : }
2994 :
2995 0 : show_prefs (uid, selfsig, with_prefs == 2);
2996 : }
2997 : else
2998 0 : tty_fprintf (fp, _("There are no preferences on a"
2999 : " PGP 2.x-style user ID.\n"));
3000 : }
3001 : }
3002 : }
3003 : }
3004 0 : }
3005 :
3006 :
3007 : /*
3008 : * Display the key a the user ids, if only_marked is true, do only so
3009 : * for user ids with mark A flag set and do not display the index
3010 : * number. If FP is not NULL print to the given stream and not to the
3011 : * tty (ignored in with-colons mode).
3012 : */
3013 : static void
3014 0 : show_key_with_all_names (ctrl_t ctrl, estream_t fp,
3015 : KBNODE keyblock, int only_marked, int with_revoker,
3016 : int with_fpr, int with_subkeys, int with_prefs,
3017 : int nowarn)
3018 : {
3019 : gpg_error_t err;
3020 : kbnode_t node;
3021 : int i;
3022 0 : int do_warn = 0;
3023 0 : int have_seckey = 0;
3024 0 : char *serialno = NULL;
3025 0 : PKT_public_key *primary = NULL;
3026 : char pkstrbuf[PUBKEY_STRING_SIZE];
3027 :
3028 0 : if (opt.with_colons)
3029 : {
3030 0 : show_key_with_all_names_colon (ctrl, fp, keyblock);
3031 0 : return;
3032 : }
3033 :
3034 : /* the keys */
3035 0 : for (node = keyblock; node; node = node->next)
3036 : {
3037 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
3038 0 : || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3039 0 : && !is_deleted_kbnode (node)))
3040 : {
3041 0 : PKT_public_key *pk = node->pkt->pkt.public_key;
3042 0 : const char *otrust = "err";
3043 0 : const char *trust = "err";
3044 :
3045 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
3046 : {
3047 : /* do it here, so that debug messages don't clutter the
3048 : * output */
3049 : static int did_warn = 0;
3050 :
3051 0 : trust = get_validity_string (pk, NULL);
3052 0 : otrust = get_ownertrust_string (pk);
3053 :
3054 : /* Show a warning once */
3055 0 : if (!did_warn
3056 0 : && (get_validity (pk, NULL, NULL, 0)
3057 0 : & TRUST_FLAG_PENDING_CHECK))
3058 : {
3059 0 : did_warn = 1;
3060 0 : do_warn = 1;
3061 : }
3062 :
3063 0 : primary = pk;
3064 : }
3065 :
3066 0 : if (pk->flags.revoked)
3067 : {
3068 0 : char *user = get_user_id_string_native (pk->revoked.keyid);
3069 0 : tty_fprintf (fp,
3070 0 : _("The following key was revoked on"
3071 : " %s by %s key %s\n"),
3072 : revokestr_from_pk (pk),
3073 0 : gcry_pk_algo_name (pk->revoked.algo), user);
3074 0 : xfree (user);
3075 : }
3076 :
3077 0 : if (with_revoker)
3078 : {
3079 0 : if (!pk->revkey && pk->numrevkeys)
3080 0 : BUG ();
3081 : else
3082 0 : for (i = 0; i < pk->numrevkeys; i++)
3083 : {
3084 : u32 r_keyid[2];
3085 : char *user;
3086 : const char *algo;
3087 :
3088 0 : algo = gcry_pk_algo_name (pk->revkey[i].algid);
3089 0 : keyid_from_fingerprint (pk->revkey[i].fpr,
3090 : MAX_FINGERPRINT_LEN, r_keyid);
3091 :
3092 0 : user = get_user_id_string_native (r_keyid);
3093 0 : tty_fprintf (fp,
3094 0 : _("This key may be revoked by %s key %s"),
3095 : algo ? algo : "?", user);
3096 :
3097 0 : if (pk->revkey[i].class & 0x40)
3098 : {
3099 0 : tty_fprintf (fp, " ");
3100 0 : tty_fprintf (fp, _("(sensitive)"));
3101 : }
3102 :
3103 0 : tty_fprintf (fp, "\n");
3104 0 : xfree (user);
3105 : }
3106 : }
3107 :
3108 0 : keyid_from_pk (pk, NULL);
3109 :
3110 0 : xfree (serialno);
3111 0 : serialno = NULL;
3112 : {
3113 : char *hexgrip;
3114 :
3115 0 : err = hexkeygrip_from_pk (pk, &hexgrip);
3116 0 : if (err)
3117 : {
3118 0 : log_error ("error computing a keygrip: %s\n",
3119 : gpg_strerror (err));
3120 0 : have_seckey = 0;
3121 : }
3122 : else
3123 0 : have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno);
3124 0 : xfree (hexgrip);
3125 : }
3126 :
3127 0 : tty_fprintf
3128 : (fp, "%s%c %s/%s",
3129 0 : node->pkt->pkttype == PKT_PUBLIC_KEY && have_seckey? "sec" :
3130 0 : node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
3131 0 : have_seckey ? "ssb" :
3132 : "sub",
3133 0 : (node->flag & NODFLG_SELKEY) ? '*' : ' ',
3134 : pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
3135 0 : keystr (pk->keyid));
3136 :
3137 0 : if (opt.legacy_list_mode)
3138 0 : tty_fprintf (fp, " ");
3139 : else
3140 0 : tty_fprintf (fp, "\n ");
3141 :
3142 0 : tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
3143 0 : tty_fprintf (fp, " ");
3144 0 : if (pk->flags.revoked)
3145 0 : tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
3146 0 : else if (pk->has_expired)
3147 0 : tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
3148 : else
3149 0 : tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
3150 0 : tty_fprintf (fp, " ");
3151 0 : tty_fprintf (fp, _("usage: %s"), usagestr_from_pk (pk, 1));
3152 0 : tty_fprintf (fp, "\n");
3153 :
3154 0 : if (serialno)
3155 : {
3156 : /* The agent told us that a secret key is available and
3157 : that it has been stored on a card. */
3158 0 : tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
3159 : _("card-no: "));
3160 0 : if (strlen (serialno) == 32
3161 0 : && !strncmp (serialno, "D27600012401", 12))
3162 : {
3163 : /* This is an OpenPGP card. Print the relevant part. */
3164 : /* Example: D2760001240101010001000003470000 */
3165 : /* xxxxyyyyyyyy */
3166 0 : tty_fprintf (fp, "%.*s %.*s\n",
3167 : 4, serialno+16, 8, serialno+20);
3168 : }
3169 : else
3170 0 : tty_fprintf (fp, "%s\n", serialno);
3171 :
3172 : }
3173 0 : else if (pk->seckey_info
3174 0 : && pk->seckey_info->is_protected
3175 0 : && pk->seckey_info->s2k.mode == 1002)
3176 : {
3177 : /* FIXME: Check wether this code path is still used. */
3178 0 : tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
3179 : _("card-no: "));
3180 0 : if (pk->seckey_info->ivlen == 16
3181 0 : && !memcmp (pk->seckey_info->iv,
3182 : "\xD2\x76\x00\x01\x24\x01", 6))
3183 : {
3184 : /* This is an OpenPGP card. */
3185 0 : for (i = 8; i < 14; i++)
3186 : {
3187 0 : if (i == 10)
3188 0 : tty_fprintf (fp, " ");
3189 0 : tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
3190 : }
3191 : }
3192 : else
3193 : {
3194 : /* Unknown card: Print all. */
3195 0 : for (i = 0; i < pk->seckey_info->ivlen; i++)
3196 0 : tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
3197 : }
3198 0 : tty_fprintf (fp, "\n");
3199 : }
3200 :
3201 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
3202 0 : || node->pkt->pkttype == PKT_SECRET_KEY)
3203 : {
3204 0 : if (opt.trust_model != TM_ALWAYS)
3205 : {
3206 0 : tty_fprintf (fp, "%*s",
3207 0 : opt.legacy_list_mode?
3208 0 : ((int) keystrlen () + 13):5, "");
3209 : /* Ownertrust is only meaningful for the PGP or
3210 : classic trust models */
3211 0 : if (opt.trust_model == TM_PGP
3212 0 : || opt.trust_model == TM_CLASSIC)
3213 : {
3214 0 : int width = 14 - strlen (otrust);
3215 0 : if (width <= 0)
3216 0 : width = 1;
3217 0 : tty_fprintf (fp, _("trust: %s"), otrust);
3218 0 : tty_fprintf (fp, "%*s", width, "");
3219 : }
3220 :
3221 0 : tty_fprintf (fp, _("validity: %s"), trust);
3222 0 : tty_fprintf (fp, "\n");
3223 : }
3224 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
3225 0 : && (get_ownertrust (pk) & TRUST_FLAG_DISABLED))
3226 : {
3227 0 : tty_fprintf (fp, "*** ");
3228 0 : tty_fprintf (fp, _("This key has been disabled"));
3229 0 : tty_fprintf (fp, "\n");
3230 : }
3231 : }
3232 :
3233 0 : if ((node->pkt->pkttype == PKT_PUBLIC_KEY
3234 0 : || node->pkt->pkttype == PKT_SECRET_KEY) && with_fpr)
3235 : {
3236 0 : print_fingerprint (fp, pk, 2);
3237 0 : tty_fprintf (fp, "\n");
3238 : }
3239 : }
3240 : }
3241 :
3242 0 : show_names (fp,
3243 : keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
3244 :
3245 0 : if (do_warn && !nowarn)
3246 0 : tty_fprintf (fp, _("Please note that the shown key validity"
3247 : " is not necessarily correct\n"
3248 : "unless you restart the program.\n"));
3249 :
3250 0 : xfree (serialno);
3251 : }
3252 :
3253 :
3254 : /* Display basic key information. This function is suitable to show
3255 : information on the key without any dependencies on the trustdb or
3256 : any other internal GnuPG stuff. KEYBLOCK may either be a public or
3257 : a secret key. This function may be called with KEYBLOCK containing
3258 : secret keys and thus the printing of "pub" vs. "sec" does only
3259 : depend on the packet type and not by checking with gpg-agent. */
3260 : void
3261 0 : show_basic_key_info (KBNODE keyblock)
3262 : {
3263 : KBNODE node;
3264 : int i;
3265 : char pkstrbuf[PUBKEY_STRING_SIZE];
3266 :
3267 : /* The primary key */
3268 0 : for (node = keyblock; node; node = node->next)
3269 : {
3270 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
3271 0 : || node->pkt->pkttype == PKT_SECRET_KEY)
3272 : {
3273 0 : PKT_public_key *pk = node->pkt->pkt.public_key;
3274 :
3275 : /* Note, we use the same format string as in other show
3276 : functions to make the translation job easier. */
3277 0 : tty_printf ("%s %s/%s ",
3278 0 : node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
3279 0 : node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
3280 0 : node->pkt->pkttype == PKT_SECRET_KEY ? "sec" :"ssb",
3281 : pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
3282 : keystr_from_pk (pk));
3283 0 : tty_printf (_("created: %s"), datestr_from_pk (pk));
3284 0 : tty_printf (" ");
3285 0 : tty_printf (_("expires: %s"), expirestr_from_pk (pk));
3286 0 : tty_printf ("\n");
3287 0 : print_fingerprint (NULL, pk, 3);
3288 0 : tty_printf ("\n");
3289 : }
3290 : }
3291 :
3292 : /* The user IDs. */
3293 0 : for (i = 0, node = keyblock; node; node = node->next)
3294 : {
3295 0 : if (node->pkt->pkttype == PKT_USER_ID)
3296 : {
3297 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
3298 0 : ++i;
3299 :
3300 0 : tty_printf (" ");
3301 0 : if (uid->is_revoked)
3302 0 : tty_printf ("[%s] ", _("revoked"));
3303 0 : else if (uid->is_expired)
3304 0 : tty_printf ("[%s] ", _("expired"));
3305 0 : tty_print_utf8_string (uid->name, uid->len);
3306 0 : tty_printf ("\n");
3307 : }
3308 : }
3309 0 : }
3310 :
3311 :
3312 : static void
3313 0 : show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys)
3314 : {
3315 : kbnode_t node;
3316 0 : PKT_public_key *pk = NULL;
3317 : char pkstrbuf[PUBKEY_STRING_SIZE];
3318 :
3319 0 : for (node = keyblock; node; node = node->next)
3320 : {
3321 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
3322 : {
3323 0 : pk = node->pkt->pkt.public_key;
3324 0 : tty_printf ("pub %s/%s %s ",
3325 : pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
3326 : keystr_from_pk(pk),
3327 : datestr_from_pk (pk));
3328 : }
3329 0 : else if (node->pkt->pkttype == PKT_USER_ID)
3330 : {
3331 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
3332 0 : tty_print_utf8_string (uid->name, uid->len);
3333 0 : break;
3334 : }
3335 : }
3336 0 : tty_printf ("\n");
3337 0 : if (pk)
3338 0 : print_fingerprint (NULL, pk, 2);
3339 0 : if (with_subkeys)
3340 : {
3341 0 : for (node = keyblock; node; node = node->next)
3342 : {
3343 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
3344 : {
3345 0 : pk = node->pkt->pkt.public_key;
3346 0 : tty_printf ("sub %s/%s %s [%s]\n",
3347 : pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
3348 : keystr_from_pk(pk),
3349 : datestr_from_pk (pk),
3350 : usagestr_from_pk (pk, 0));
3351 :
3352 0 : print_fingerprint (NULL, pk, 4);
3353 : }
3354 : }
3355 : }
3356 0 : }
3357 :
3358 :
3359 : /* Show a listing of the primary and its subkeys along with their
3360 : keygrips. */
3361 : static void
3362 0 : show_key_and_grip (kbnode_t keyblock)
3363 : {
3364 : kbnode_t node;
3365 0 : PKT_public_key *pk = NULL;
3366 : char pkstrbuf[PUBKEY_STRING_SIZE];
3367 : char *hexgrip;
3368 :
3369 0 : for (node = keyblock; node; node = node->next)
3370 : {
3371 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY
3372 0 : || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
3373 : {
3374 0 : pk = node->pkt->pkt.public_key;
3375 0 : tty_printf ("%s %s/%s %s [%s]\n",
3376 0 : node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
3377 : pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
3378 : keystr_from_pk(pk),
3379 : datestr_from_pk (pk),
3380 : usagestr_from_pk (pk, 0));
3381 :
3382 0 : if (!hexkeygrip_from_pk (pk, &hexgrip))
3383 : {
3384 0 : tty_printf (" Keygrip: %s\n", hexgrip);
3385 0 : xfree (hexgrip);
3386 : }
3387 : }
3388 : }
3389 0 : }
3390 :
3391 :
3392 : /* Show a warning if no uids on the key have the primary uid flag
3393 : set. */
3394 : static void
3395 0 : no_primary_warning (KBNODE keyblock)
3396 : {
3397 : KBNODE node;
3398 0 : int have_primary = 0, uid_count = 0;
3399 :
3400 : /* TODO: if we ever start behaving differently with a primary or
3401 : non-primary attribute ID, we will need to check for attributes
3402 : here as well. */
3403 :
3404 0 : for (node = keyblock; node; node = node->next)
3405 : {
3406 0 : if (node->pkt->pkttype == PKT_USER_ID
3407 0 : && node->pkt->pkt.user_id->attrib_data == NULL)
3408 : {
3409 0 : uid_count++;
3410 :
3411 0 : if (node->pkt->pkt.user_id->is_primary == 2)
3412 : {
3413 0 : have_primary = 1;
3414 0 : break;
3415 : }
3416 : }
3417 : }
3418 :
3419 0 : if (uid_count > 1 && !have_primary)
3420 0 : log_info (_
3421 : ("WARNING: no user ID has been marked as primary. This command"
3422 : " may\n cause a different user ID to become"
3423 : " the assumed primary.\n"));
3424 0 : }
3425 :
3426 :
3427 : /* Print a warning if the latest encryption subkey expires soon. This
3428 : function is called after the expire data of the primary key has
3429 : been changed. */
3430 : static void
3431 0 : subkey_expire_warning (kbnode_t keyblock)
3432 : {
3433 0 : u32 curtime = make_timestamp ();
3434 : kbnode_t node;
3435 : PKT_public_key *pk;
3436 : /* u32 mainexpire = 0; */
3437 0 : u32 subexpire = 0;
3438 0 : u32 latest_date = 0;
3439 :
3440 0 : for (node = keyblock; node; node = node->next)
3441 : {
3442 : /* if (node->pkt->pkttype == PKT_PUBLIC_KEY) */
3443 : /* { */
3444 : /* pk = node->pkt->pkt.public_key; */
3445 : /* mainexpire = pk->expiredate; */
3446 : /* } */
3447 :
3448 0 : if (node->pkt->pkttype != PKT_PUBLIC_SUBKEY)
3449 0 : continue;
3450 0 : pk = node->pkt->pkt.public_key;
3451 :
3452 0 : if (!pk->flags.valid)
3453 0 : continue;
3454 0 : if (pk->flags.revoked)
3455 0 : continue;
3456 0 : if (pk->timestamp > curtime)
3457 0 : continue; /* Ignore future keys. */
3458 0 : if (!(pk->pubkey_usage & PUBKEY_USAGE_ENC))
3459 0 : continue; /* Not an encryption key. */
3460 :
3461 0 : if (pk->timestamp > latest_date || (!pk->timestamp && !latest_date))
3462 : {
3463 0 : latest_date = pk->timestamp;
3464 0 : subexpire = pk->expiredate;
3465 : }
3466 : }
3467 :
3468 0 : if (!subexpire)
3469 0 : return; /* No valid subkey with an expiration time. */
3470 :
3471 0 : if (curtime + (10*86400) > subexpire)
3472 : {
3473 0 : log_info (_("WARNING: Your encryption subkey expires soon.\n"));
3474 0 : log_info (_("You may want to change its expiration date too.\n"));
3475 : }
3476 : }
3477 :
3478 :
3479 : /*
3480 : * Ask for a new user id, add the self-signature, and update the
3481 : * keyblock. If UIDSTRING is not NULL the user ID is generated
3482 : * unattended using that string. UIDSTRING is expected to be utf-8
3483 : * encoded and white space trimmed. Returns true if there is a new
3484 : * user id.
3485 : */
3486 : static int
3487 0 : menu_adduid (kbnode_t pub_keyblock, int photo, const char *photo_name,
3488 : const char *uidstring)
3489 : {
3490 : PKT_user_id *uid;
3491 0 : PKT_public_key *pk = NULL;
3492 0 : PKT_signature *sig = NULL;
3493 : PACKET *pkt;
3494 : KBNODE node;
3495 0 : KBNODE pub_where = NULL;
3496 : gpg_error_t err;
3497 :
3498 0 : if (photo && uidstring)
3499 0 : return 0; /* Not allowed. */
3500 :
3501 0 : for (node = pub_keyblock; node; pub_where = node, node = node->next)
3502 : {
3503 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
3504 0 : pk = node->pkt->pkt.public_key;
3505 0 : else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
3506 0 : break;
3507 : }
3508 0 : if (!node) /* No subkey. */
3509 0 : pub_where = NULL;
3510 0 : assert (pk);
3511 :
3512 0 : if (photo)
3513 : {
3514 0 : int hasattrib = 0;
3515 :
3516 0 : for (node = pub_keyblock; node; node = node->next)
3517 0 : if (node->pkt->pkttype == PKT_USER_ID &&
3518 0 : node->pkt->pkt.user_id->attrib_data != NULL)
3519 : {
3520 0 : hasattrib = 1;
3521 0 : break;
3522 : }
3523 :
3524 : /* It is legal but bad for compatibility to add a photo ID to a
3525 : v3 key as it means that PGP2 will not be able to use that key
3526 : anymore. Also, PGP may not expect a photo on a v3 key.
3527 : Don't bother to ask this if the key already has a photo - any
3528 : damage has already been done at that point. -dms */
3529 0 : if (pk->version == 3 && !hasattrib)
3530 : {
3531 0 : if (opt.expert)
3532 : {
3533 0 : tty_printf (_("WARNING: This is a PGP2-style key. "
3534 : "Adding a photo ID may cause some versions\n"
3535 : " of PGP to reject this key.\n"));
3536 :
3537 0 : if (!cpr_get_answer_is_yes ("keyedit.v3_photo.okay",
3538 0 : _("Are you sure you still want "
3539 : "to add it? (y/N) ")))
3540 0 : return 0;
3541 : }
3542 : else
3543 : {
3544 0 : tty_printf (_("You may not add a photo ID to "
3545 : "a PGP2-style key.\n"));
3546 0 : return 0;
3547 : }
3548 : }
3549 :
3550 0 : uid = generate_photo_id (pk, photo_name);
3551 : }
3552 : else
3553 0 : uid = generate_user_id (pub_keyblock, uidstring);
3554 0 : if (!uid)
3555 : {
3556 0 : if (uidstring)
3557 0 : log_error ("%s", _("Such a user ID already exists on this key!\n"));
3558 0 : return 0;
3559 : }
3560 :
3561 0 : err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0,
3562 : keygen_add_std_prefs, pk, NULL);
3563 0 : if (err)
3564 : {
3565 0 : write_status_error ("keysig", err);
3566 0 : log_error ("signing failed: %s\n", gpg_strerror (err));
3567 0 : free_user_id (uid);
3568 0 : return 0;
3569 : }
3570 :
3571 : /* Insert/append to public keyblock */
3572 0 : pkt = xmalloc_clear (sizeof *pkt);
3573 0 : pkt->pkttype = PKT_USER_ID;
3574 0 : pkt->pkt.user_id = uid;
3575 0 : node = new_kbnode (pkt);
3576 0 : if (pub_where)
3577 0 : insert_kbnode (pub_where, node, 0);
3578 : else
3579 0 : add_kbnode (pub_keyblock, node);
3580 0 : pkt = xmalloc_clear (sizeof *pkt);
3581 0 : pkt->pkttype = PKT_SIGNATURE;
3582 0 : pkt->pkt.signature = copy_signature (NULL, sig);
3583 0 : if (pub_where)
3584 0 : insert_kbnode (node, new_kbnode (pkt), 0);
3585 : else
3586 0 : add_kbnode (pub_keyblock, new_kbnode (pkt));
3587 0 : return 1;
3588 : }
3589 :
3590 :
3591 : /*
3592 : * Remove all selected userids from the keyring
3593 : */
3594 : static void
3595 0 : menu_deluid (KBNODE pub_keyblock)
3596 : {
3597 : KBNODE node;
3598 0 : int selected = 0;
3599 :
3600 0 : for (node = pub_keyblock; node; node = node->next)
3601 : {
3602 0 : if (node->pkt->pkttype == PKT_USER_ID)
3603 : {
3604 0 : selected = node->flag & NODFLG_SELUID;
3605 0 : if (selected)
3606 : {
3607 : /* Only cause a trust update if we delete a
3608 : non-revoked user id */
3609 0 : if (!node->pkt->pkt.user_id->is_revoked)
3610 0 : update_trust = 1;
3611 0 : delete_kbnode (node);
3612 : }
3613 : }
3614 0 : else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
3615 0 : delete_kbnode (node);
3616 0 : else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
3617 0 : selected = 0;
3618 : }
3619 0 : commit_kbnode (&pub_keyblock);
3620 0 : }
3621 :
3622 :
3623 : static int
3624 0 : menu_delsig (KBNODE pub_keyblock)
3625 : {
3626 : KBNODE node;
3627 0 : PKT_user_id *uid = NULL;
3628 0 : int changed = 0;
3629 :
3630 0 : for (node = pub_keyblock; node; node = node->next)
3631 : {
3632 0 : if (node->pkt->pkttype == PKT_USER_ID)
3633 : {
3634 0 : uid = (node->flag & NODFLG_SELUID) ? node->pkt->pkt.user_id : NULL;
3635 : }
3636 0 : else if (uid && node->pkt->pkttype == PKT_SIGNATURE)
3637 0 : {
3638 : int okay, valid, selfsig, inv_sig, no_key, other_err;
3639 :
3640 0 : tty_printf ("uid ");
3641 0 : tty_print_utf8_string (uid->name, uid->len);
3642 0 : tty_printf ("\n");
3643 :
3644 0 : okay = inv_sig = no_key = other_err = 0;
3645 0 : if (opt.with_colons)
3646 0 : valid = print_and_check_one_sig_colon (pub_keyblock, node,
3647 : &inv_sig, &no_key,
3648 : &other_err, &selfsig, 1);
3649 : else
3650 0 : valid = print_and_check_one_sig (pub_keyblock, node,
3651 : &inv_sig, &no_key, &other_err,
3652 : &selfsig, 1, 0);
3653 :
3654 0 : if (valid)
3655 : {
3656 0 : okay = cpr_get_answer_yes_no_quit
3657 : ("keyedit.delsig.valid",
3658 0 : _("Delete this good signature? (y/N/q)"));
3659 :
3660 : /* Only update trust if we delete a good signature.
3661 : The other two cases do not affect trust. */
3662 0 : if (okay)
3663 0 : update_trust = 1;
3664 : }
3665 0 : else if (inv_sig || other_err)
3666 0 : okay = cpr_get_answer_yes_no_quit
3667 : ("keyedit.delsig.invalid",
3668 0 : _("Delete this invalid signature? (y/N/q)"));
3669 0 : else if (no_key)
3670 0 : okay = cpr_get_answer_yes_no_quit
3671 : ("keyedit.delsig.unknown",
3672 0 : _("Delete this unknown signature? (y/N/q)"));
3673 :
3674 0 : if (okay == -1)
3675 0 : break;
3676 0 : if (okay && selfsig
3677 0 : && !cpr_get_answer_is_yes
3678 : ("keyedit.delsig.selfsig",
3679 0 : _("Really delete this self-signature? (y/N)")))
3680 0 : okay = 0;
3681 0 : if (okay)
3682 : {
3683 0 : delete_kbnode (node);
3684 0 : changed++;
3685 : }
3686 :
3687 : }
3688 0 : else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
3689 0 : uid = NULL;
3690 : }
3691 :
3692 0 : if (changed)
3693 : {
3694 0 : commit_kbnode (&pub_keyblock);
3695 0 : tty_printf (changed == 1 ? _("Deleted %d signature.\n")
3696 : : _("Deleted %d signatures.\n"), changed);
3697 : }
3698 : else
3699 0 : tty_printf (_("Nothing deleted.\n"));
3700 :
3701 0 : return changed;
3702 : }
3703 :
3704 :
3705 : static int
3706 0 : menu_clean (KBNODE keyblock, int self_only)
3707 : {
3708 : KBNODE uidnode;
3709 0 : int modified = 0, select_all = !count_selected_uids (keyblock);
3710 :
3711 0 : for (uidnode = keyblock->next;
3712 0 : uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY;
3713 0 : uidnode = uidnode->next)
3714 : {
3715 0 : if (uidnode->pkt->pkttype == PKT_USER_ID
3716 0 : && (uidnode->flag & NODFLG_SELUID || select_all))
3717 : {
3718 0 : int uids = 0, sigs = 0;
3719 0 : char *user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
3720 0 : uidnode->pkt->pkt.user_id->len,
3721 : 0);
3722 :
3723 0 : clean_one_uid (keyblock, uidnode, opt.verbose, self_only, &uids,
3724 : &sigs);
3725 0 : if (uids)
3726 : {
3727 : const char *reason;
3728 :
3729 0 : if (uidnode->pkt->pkt.user_id->is_revoked)
3730 0 : reason = _("revoked");
3731 0 : else if (uidnode->pkt->pkt.user_id->is_expired)
3732 0 : reason = _("expired");
3733 : else
3734 0 : reason = _("invalid");
3735 :
3736 0 : tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
3737 :
3738 0 : modified = 1;
3739 : }
3740 0 : else if (sigs)
3741 : {
3742 0 : tty_printf (sigs == 1 ?
3743 : _("User ID \"%s\": %d signature removed\n") :
3744 : _("User ID \"%s\": %d signatures removed\n"),
3745 : user, sigs);
3746 :
3747 0 : modified = 1;
3748 : }
3749 : else
3750 : {
3751 0 : tty_printf (self_only == 1 ?
3752 : _("User ID \"%s\": already minimized\n") :
3753 : _("User ID \"%s\": already clean\n"), user);
3754 : }
3755 :
3756 0 : xfree (user);
3757 : }
3758 : }
3759 :
3760 0 : return modified;
3761 : }
3762 :
3763 :
3764 : /*
3765 : * Remove some of the secondary keys
3766 : */
3767 : static void
3768 0 : menu_delkey (KBNODE pub_keyblock)
3769 : {
3770 : KBNODE node;
3771 0 : int selected = 0;
3772 :
3773 0 : for (node = pub_keyblock; node; node = node->next)
3774 : {
3775 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
3776 : {
3777 0 : selected = node->flag & NODFLG_SELKEY;
3778 0 : if (selected)
3779 0 : delete_kbnode (node);
3780 : }
3781 0 : else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
3782 0 : delete_kbnode (node);
3783 : else
3784 0 : selected = 0;
3785 : }
3786 0 : commit_kbnode (&pub_keyblock);
3787 :
3788 : /* No need to set update_trust here since signing keys are no
3789 : longer used to certify other keys, so there is no change in
3790 : trust when revoking/removing them. */
3791 0 : }
3792 :
3793 :
3794 : /*
3795 : * Ask for a new revoker, create the self-signature and put it into
3796 : * the keyblock. Returns true if there is a new revoker.
3797 : */
3798 : static int
3799 0 : menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive)
3800 : {
3801 0 : PKT_public_key *pk = NULL;
3802 0 : PKT_public_key *revoker_pk = NULL;
3803 0 : PKT_signature *sig = NULL;
3804 : PACKET *pkt;
3805 : struct revocation_key revkey;
3806 : size_t fprlen;
3807 : int rc;
3808 :
3809 0 : assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
3810 :
3811 0 : pk = pub_keyblock->pkt->pkt.public_key;
3812 :
3813 0 : if (pk->numrevkeys == 0 && pk->version == 3)
3814 : {
3815 : /* It is legal but bad for compatibility to add a revoker to a
3816 : v3 key as it means that PGP2 will not be able to use that key
3817 : anymore. Also, PGP may not expect a revoker on a v3 key.
3818 : Don't bother to ask this if the key already has a revoker -
3819 : any damage has already been done at that point. -dms */
3820 0 : if (opt.expert)
3821 : {
3822 0 : tty_printf (_("WARNING: This is a PGP 2.x-style key. "
3823 : "Adding a designated revoker may cause\n"
3824 : " some versions of PGP to reject this key.\n"));
3825 :
3826 0 : if (!cpr_get_answer_is_yes ("keyedit.v3_revoker.okay",
3827 0 : _("Are you sure you still want "
3828 : "to add it? (y/N) ")))
3829 0 : return 0;
3830 : }
3831 : else
3832 : {
3833 0 : tty_printf (_("You may not add a designated revoker to "
3834 : "a PGP 2.x-style key.\n"));
3835 0 : return 0;
3836 : }
3837 : }
3838 :
3839 : for (;;)
3840 : {
3841 : char *answer;
3842 :
3843 0 : free_public_key (revoker_pk);
3844 0 : revoker_pk = xmalloc_clear (sizeof (*revoker_pk));
3845 :
3846 0 : tty_printf ("\n");
3847 :
3848 0 : answer = cpr_get_utf8
3849 : ("keyedit.add_revoker",
3850 0 : _("Enter the user ID of the designated revoker: "));
3851 0 : if (answer[0] == '\0' || answer[0] == CONTROL_D)
3852 : {
3853 0 : xfree (answer);
3854 0 : goto fail;
3855 : }
3856 :
3857 : /* Note that I'm requesting CERT here, which usually implies
3858 : primary keys only, but some casual testing shows that PGP and
3859 : GnuPG both can handle a designated revocation from a subkey. */
3860 0 : revoker_pk->req_usage = PUBKEY_USAGE_CERT;
3861 0 : rc = get_pubkey_byname (ctrl, NULL, revoker_pk, answer, NULL, NULL, 1, 1);
3862 0 : if (rc)
3863 : {
3864 0 : log_error (_("key \"%s\" not found: %s\n"), answer,
3865 : gpg_strerror (rc));
3866 0 : xfree (answer);
3867 0 : continue;
3868 : }
3869 :
3870 0 : xfree (answer);
3871 :
3872 0 : fingerprint_from_pk (revoker_pk, revkey.fpr, &fprlen);
3873 0 : if (fprlen != 20)
3874 : {
3875 0 : log_error (_("cannot appoint a PGP 2.x style key as a "
3876 : "designated revoker\n"));
3877 0 : continue;
3878 : }
3879 :
3880 0 : revkey.class = 0x80;
3881 0 : if (sensitive)
3882 0 : revkey.class |= 0x40;
3883 0 : revkey.algid = revoker_pk->pubkey_algo;
3884 :
3885 0 : if (cmp_public_keys (revoker_pk, pk) == 0)
3886 : {
3887 : /* This actually causes no harm (after all, a key that
3888 : designates itself as a revoker is the same as a
3889 : regular key), but it's easy enough to check. */
3890 0 : log_error (_("you cannot appoint a key as its own "
3891 : "designated revoker\n"));
3892 :
3893 0 : continue;
3894 : }
3895 :
3896 0 : keyid_from_pk (pk, NULL);
3897 :
3898 : /* Does this revkey already exist? */
3899 0 : if (!pk->revkey && pk->numrevkeys)
3900 0 : BUG ();
3901 : else
3902 : {
3903 : int i;
3904 :
3905 0 : for (i = 0; i < pk->numrevkeys; i++)
3906 : {
3907 0 : if (memcmp (&pk->revkey[i], &revkey,
3908 : sizeof (struct revocation_key)) == 0)
3909 : {
3910 : char buf[50];
3911 :
3912 0 : log_error (_("this key has already been designated "
3913 : "as a revoker\n"));
3914 :
3915 0 : sprintf (buf, "%08lX%08lX",
3916 0 : (ulong) pk->keyid[0], (ulong) pk->keyid[1]);
3917 0 : write_status_text (STATUS_ALREADY_SIGNED, buf);
3918 :
3919 0 : break;
3920 : }
3921 : }
3922 :
3923 0 : if (i < pk->numrevkeys)
3924 0 : continue;
3925 : }
3926 :
3927 0 : print_pubkey_info (NULL, revoker_pk);
3928 0 : print_fingerprint (NULL, revoker_pk, 2);
3929 0 : tty_printf ("\n");
3930 :
3931 0 : tty_printf (_("WARNING: appointing a key as a designated revoker "
3932 : "cannot be undone!\n"));
3933 :
3934 0 : tty_printf ("\n");
3935 :
3936 0 : if (!cpr_get_answer_is_yes ("keyedit.add_revoker.okay",
3937 0 : _("Are you sure you want to appoint this "
3938 : "key as a designated revoker? (y/N) ")))
3939 0 : continue;
3940 :
3941 0 : free_public_key (revoker_pk);
3942 0 : revoker_pk = NULL;
3943 0 : break;
3944 0 : }
3945 :
3946 0 : rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 0, 0,
3947 : keygen_add_revkey, &revkey, NULL);
3948 0 : if (rc)
3949 : {
3950 0 : write_status_error ("keysig", rc);
3951 0 : log_error ("signing failed: %s\n", gpg_strerror (rc));
3952 0 : goto fail;
3953 : }
3954 :
3955 : /* Insert into public keyblock. */
3956 0 : pkt = xmalloc_clear (sizeof *pkt);
3957 0 : pkt->pkttype = PKT_SIGNATURE;
3958 0 : pkt->pkt.signature = sig;
3959 0 : insert_kbnode (pub_keyblock, new_kbnode (pkt), PKT_SIGNATURE);
3960 :
3961 0 : return 1;
3962 :
3963 : fail:
3964 0 : if (sig)
3965 0 : free_seckey_enc (sig);
3966 0 : free_public_key (revoker_pk);
3967 :
3968 0 : return 0;
3969 : }
3970 :
3971 :
3972 : static int
3973 0 : menu_expire (KBNODE pub_keyblock)
3974 : {
3975 : int n1, signumber, rc;
3976 : u32 expiredate;
3977 0 : int mainkey = 0;
3978 : PKT_public_key *main_pk, *sub_pk;
3979 : PKT_user_id *uid;
3980 : KBNODE node;
3981 : u32 keyid[2];
3982 :
3983 0 : n1 = count_selected_keys (pub_keyblock);
3984 0 : if (n1 > 1)
3985 : {
3986 0 : tty_printf (_("Please select at most one subkey.\n"));
3987 0 : return 0;
3988 : }
3989 0 : else if (n1)
3990 0 : tty_printf (_("Changing expiration time for a subkey.\n"));
3991 : else
3992 : {
3993 0 : tty_printf (_("Changing expiration time for the primary key.\n"));
3994 0 : mainkey = 1;
3995 0 : no_primary_warning (pub_keyblock);
3996 : }
3997 :
3998 0 : expiredate = ask_expiredate ();
3999 :
4000 : /* Now we can actually change the self-signature(s) */
4001 0 : main_pk = sub_pk = NULL;
4002 0 : uid = NULL;
4003 0 : signumber = 0;
4004 0 : for (node = pub_keyblock; node; node = node->next)
4005 : {
4006 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
4007 : {
4008 0 : main_pk = node->pkt->pkt.public_key;
4009 0 : keyid_from_pk (main_pk, keyid);
4010 0 : main_pk->expiredate = expiredate;
4011 : }
4012 0 : else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4013 0 : && (node->flag & NODFLG_SELKEY))
4014 : {
4015 0 : sub_pk = node->pkt->pkt.public_key;
4016 0 : sub_pk->expiredate = expiredate;
4017 : }
4018 0 : else if (node->pkt->pkttype == PKT_USER_ID)
4019 0 : uid = node->pkt->pkt.user_id;
4020 0 : else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
4021 0 : && (mainkey || sub_pk))
4022 : {
4023 0 : PKT_signature *sig = node->pkt->pkt.signature;
4024 0 : if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4025 0 : && ((mainkey && uid
4026 0 : && uid->created && (sig->sig_class & ~3) == 0x10)
4027 0 : || (!mainkey && sig->sig_class == 0x18))
4028 0 : && sig->flags.chosen_selfsig)
4029 : {
4030 : /* This is a self-signature which is to be replaced. */
4031 : PKT_signature *newsig;
4032 : PACKET *newpkt;
4033 :
4034 0 : signumber++;
4035 :
4036 0 : if ((mainkey && main_pk->version < 4)
4037 0 : || (!mainkey && sub_pk->version < 4))
4038 : {
4039 0 : log_info
4040 0 : (_("You can't change the expiration date of a v3 key\n"));
4041 0 : return 0;
4042 : }
4043 :
4044 0 : if (mainkey)
4045 0 : rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
4046 : main_pk, keygen_add_key_expire,
4047 : main_pk);
4048 : else
4049 0 : rc =
4050 0 : update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
4051 : main_pk, keygen_add_key_expire, sub_pk);
4052 0 : if (rc)
4053 : {
4054 0 : log_error ("make_keysig_packet failed: %s\n",
4055 : gpg_strerror (rc));
4056 0 : return 0;
4057 : }
4058 :
4059 : /* Replace the packet. */
4060 0 : newpkt = xmalloc_clear (sizeof *newpkt);
4061 0 : newpkt->pkttype = PKT_SIGNATURE;
4062 0 : newpkt->pkt.signature = newsig;
4063 0 : free_packet (node->pkt);
4064 0 : xfree (node->pkt);
4065 0 : node->pkt = newpkt;
4066 0 : sub_pk = NULL;
4067 : }
4068 : }
4069 : }
4070 :
4071 0 : update_trust = 1;
4072 0 : return 1;
4073 : }
4074 :
4075 :
4076 : static int
4077 0 : menu_backsign (KBNODE pub_keyblock)
4078 : {
4079 0 : int rc, modified = 0;
4080 : PKT_public_key *main_pk;
4081 : KBNODE node;
4082 : u32 timestamp;
4083 :
4084 0 : assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
4085 :
4086 0 : merge_keys_and_selfsig (pub_keyblock);
4087 0 : main_pk = pub_keyblock->pkt->pkt.public_key;
4088 0 : keyid_from_pk (main_pk, NULL);
4089 :
4090 : /* We use the same timestamp for all backsigs so that we don't
4091 : reveal information about the used machine. */
4092 0 : timestamp = make_timestamp ();
4093 :
4094 0 : for (node = pub_keyblock; node; node = node->next)
4095 : {
4096 0 : PKT_public_key *sub_pk = NULL;
4097 0 : KBNODE node2, sig_pk = NULL /*,sig_sk = NULL*/;
4098 : /* char *passphrase; */
4099 :
4100 : /* Find a signing subkey with no backsig */
4101 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
4102 : {
4103 0 : if (node->pkt->pkt.public_key->pubkey_usage & PUBKEY_USAGE_SIG)
4104 : {
4105 0 : if (node->pkt->pkt.public_key->flags.backsig)
4106 0 : tty_printf (_
4107 : ("signing subkey %s is already cross-certified\n"),
4108 0 : keystr_from_pk (node->pkt->pkt.public_key));
4109 : else
4110 0 : sub_pk = node->pkt->pkt.public_key;
4111 : }
4112 : else
4113 0 : tty_printf (_("subkey %s does not sign and so does"
4114 : " not need to be cross-certified\n"),
4115 0 : keystr_from_pk (node->pkt->pkt.public_key));
4116 : }
4117 :
4118 0 : if (!sub_pk)
4119 0 : continue;
4120 :
4121 : /* Find the selected selfsig on this subkey */
4122 0 : for (node2 = node->next;
4123 0 : node2 && node2->pkt->pkttype == PKT_SIGNATURE; node2 = node2->next)
4124 0 : if (node2->pkt->pkt.signature->version >= 4
4125 0 : && node2->pkt->pkt.signature->flags.chosen_selfsig)
4126 : {
4127 0 : sig_pk = node2;
4128 0 : break;
4129 : }
4130 :
4131 0 : if (!sig_pk)
4132 0 : continue;
4133 :
4134 : /* Find the secret subkey that matches the public subkey */
4135 0 : log_debug ("FIXME: Check whether a secret subkey is available.\n");
4136 : /* if (!sub_sk) */
4137 : /* { */
4138 : /* tty_printf (_("no secret subkey for public subkey %s - ignoring\n"), */
4139 : /* keystr_from_pk (sub_pk)); */
4140 : /* continue; */
4141 : /* } */
4142 :
4143 :
4144 : /* Now we can get to work. */
4145 :
4146 0 : rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_pk,
4147 : timestamp, NULL);
4148 0 : if (!rc)
4149 : {
4150 : PKT_signature *newsig;
4151 : PACKET *newpkt;
4152 :
4153 0 : rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
4154 : main_pk, NULL, sub_pk, main_pk,
4155 : NULL, NULL);
4156 0 : if (!rc)
4157 : {
4158 : /* Put the new sig into place on the pubkey */
4159 0 : newpkt = xmalloc_clear (sizeof (*newpkt));
4160 0 : newpkt->pkttype = PKT_SIGNATURE;
4161 0 : newpkt->pkt.signature = newsig;
4162 0 : free_packet (sig_pk->pkt);
4163 0 : xfree (sig_pk->pkt);
4164 0 : sig_pk->pkt = newpkt;
4165 :
4166 0 : modified = 1;
4167 : }
4168 : else
4169 : {
4170 0 : log_error ("update_keysig_packet failed: %s\n",
4171 : gpg_strerror (rc));
4172 0 : break;
4173 : }
4174 : }
4175 : else
4176 : {
4177 0 : log_error ("make_backsig failed: %s\n", gpg_strerror (rc));
4178 0 : break;
4179 : }
4180 : }
4181 :
4182 0 : return modified;
4183 : }
4184 :
4185 :
4186 : static int
4187 0 : change_primary_uid_cb (PKT_signature * sig, void *opaque)
4188 : {
4189 : byte buf[1];
4190 :
4191 : /* first clear all primary uid flags so that we are sure none are
4192 : * lingering around */
4193 0 : delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
4194 0 : delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
4195 :
4196 : /* if opaque is set,we want to set the primary id */
4197 0 : if (opaque)
4198 : {
4199 0 : buf[0] = 1;
4200 0 : build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1);
4201 : }
4202 :
4203 0 : return 0;
4204 : }
4205 :
4206 :
4207 : /*
4208 : * Set the primary uid flag for the selected UID. We will also reset
4209 : * all other primary uid flags. For this to work with have to update
4210 : * all the signature timestamps. If we would do this with the current
4211 : * time, we lose quite a lot of information, so we use a a kludge to
4212 : * do this: Just increment the timestamp by one second which is
4213 : * sufficient to updated a signature during import.
4214 : */
4215 : static int
4216 0 : menu_set_primary_uid (KBNODE pub_keyblock)
4217 : {
4218 : PKT_public_key *main_pk;
4219 : PKT_user_id *uid;
4220 : KBNODE node;
4221 : u32 keyid[2];
4222 : int selected;
4223 0 : int attribute = 0;
4224 0 : int modified = 0;
4225 :
4226 0 : if (count_selected_uids (pub_keyblock) != 1)
4227 : {
4228 0 : tty_printf (_("Please select exactly one user ID.\n"));
4229 0 : return 0;
4230 : }
4231 :
4232 0 : main_pk = NULL;
4233 0 : uid = NULL;
4234 0 : selected = 0;
4235 :
4236 : /* Is our selected uid an attribute packet? */
4237 0 : for (node = pub_keyblock; node; node = node->next)
4238 0 : if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
4239 0 : attribute = (node->pkt->pkt.user_id->attrib_data != NULL);
4240 :
4241 0 : for (node = pub_keyblock; node; node = node->next)
4242 : {
4243 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
4244 0 : break; /* No more user ids expected - ready. */
4245 :
4246 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
4247 : {
4248 0 : main_pk = node->pkt->pkt.public_key;
4249 0 : keyid_from_pk (main_pk, keyid);
4250 : }
4251 0 : else if (node->pkt->pkttype == PKT_USER_ID)
4252 : {
4253 0 : uid = node->pkt->pkt.user_id;
4254 0 : selected = node->flag & NODFLG_SELUID;
4255 : }
4256 0 : else if (main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE)
4257 : {
4258 0 : PKT_signature *sig = node->pkt->pkt.signature;
4259 0 : if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4260 0 : && (uid && (sig->sig_class & ~3) == 0x10)
4261 0 : && attribute == (uid->attrib_data != NULL)
4262 0 : && sig->flags.chosen_selfsig)
4263 : {
4264 0 : if (sig->version < 4)
4265 : {
4266 0 : char *user =
4267 0 : utf8_to_native (uid->name, strlen (uid->name), 0);
4268 :
4269 0 : log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
4270 : user);
4271 0 : xfree (user);
4272 : }
4273 : else
4274 : {
4275 : /* This is a selfsignature which is to be replaced.
4276 : We can just ignore v3 signatures because they are
4277 : not able to carry the primary ID flag. We also
4278 : ignore self-sigs on user IDs that are not of the
4279 : same type that we are making primary. That is, if
4280 : we are making a user ID primary, we alter user IDs.
4281 : If we are making an attribute packet primary, we
4282 : alter attribute packets. */
4283 :
4284 : /* FIXME: We must make sure that we only have one
4285 : self-signature per user ID here (not counting
4286 : revocations) */
4287 : PKT_signature *newsig;
4288 : PACKET *newpkt;
4289 : const byte *p;
4290 : int action;
4291 :
4292 : /* See whether this signature has the primary UID flag. */
4293 0 : p = parse_sig_subpkt (sig->hashed,
4294 : SIGSUBPKT_PRIMARY_UID, NULL);
4295 0 : if (!p)
4296 0 : p = parse_sig_subpkt (sig->unhashed,
4297 : SIGSUBPKT_PRIMARY_UID, NULL);
4298 0 : if (p && *p) /* yes */
4299 0 : action = selected ? 0 : -1;
4300 : else /* no */
4301 0 : action = selected ? 1 : 0;
4302 :
4303 0 : if (action)
4304 : {
4305 0 : int rc = update_keysig_packet (&newsig, sig,
4306 : main_pk, uid, NULL,
4307 : main_pk,
4308 : change_primary_uid_cb,
4309 : action > 0 ? "x" : NULL);
4310 0 : if (rc)
4311 : {
4312 0 : log_error ("update_keysig_packet failed: %s\n",
4313 : gpg_strerror (rc));
4314 0 : return 0;
4315 : }
4316 : /* replace the packet */
4317 0 : newpkt = xmalloc_clear (sizeof *newpkt);
4318 0 : newpkt->pkttype = PKT_SIGNATURE;
4319 0 : newpkt->pkt.signature = newsig;
4320 0 : free_packet (node->pkt);
4321 0 : xfree (node->pkt);
4322 0 : node->pkt = newpkt;
4323 0 : modified = 1;
4324 : }
4325 : }
4326 : }
4327 : }
4328 : }
4329 :
4330 0 : return modified;
4331 : }
4332 :
4333 :
4334 : /*
4335 : * Set preferences to new values for the selected user IDs
4336 : */
4337 : static int
4338 0 : menu_set_preferences (KBNODE pub_keyblock)
4339 : {
4340 : PKT_public_key *main_pk;
4341 : PKT_user_id *uid;
4342 : KBNODE node;
4343 : u32 keyid[2];
4344 : int selected, select_all;
4345 0 : int modified = 0;
4346 :
4347 0 : no_primary_warning (pub_keyblock);
4348 :
4349 0 : select_all = !count_selected_uids (pub_keyblock);
4350 :
4351 : /* Now we can actually change the self signature(s) */
4352 0 : main_pk = NULL;
4353 0 : uid = NULL;
4354 0 : selected = 0;
4355 0 : for (node = pub_keyblock; node; node = node->next)
4356 : {
4357 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
4358 0 : break; /* No more user-ids expected - ready. */
4359 :
4360 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
4361 : {
4362 0 : main_pk = node->pkt->pkt.public_key;
4363 0 : keyid_from_pk (main_pk, keyid);
4364 : }
4365 0 : else if (node->pkt->pkttype == PKT_USER_ID)
4366 : {
4367 0 : uid = node->pkt->pkt.user_id;
4368 0 : selected = select_all || (node->flag & NODFLG_SELUID);
4369 : }
4370 0 : else if (main_pk && uid && selected
4371 0 : && node->pkt->pkttype == PKT_SIGNATURE)
4372 : {
4373 0 : PKT_signature *sig = node->pkt->pkt.signature;
4374 0 : if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4375 0 : && (uid && (sig->sig_class & ~3) == 0x10)
4376 0 : && sig->flags.chosen_selfsig)
4377 : {
4378 0 : if (sig->version < 4)
4379 : {
4380 0 : char *user =
4381 0 : utf8_to_native (uid->name, strlen (uid->name), 0);
4382 :
4383 0 : log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
4384 : user);
4385 0 : xfree (user);
4386 : }
4387 : else
4388 : {
4389 : /* This is a selfsignature which is to be replaced
4390 : * We have to ignore v3 signatures because they are
4391 : * not able to carry the preferences. */
4392 : PKT_signature *newsig;
4393 : PACKET *newpkt;
4394 : int rc;
4395 :
4396 0 : rc = update_keysig_packet (&newsig, sig,
4397 : main_pk, uid, NULL, main_pk,
4398 : keygen_upd_std_prefs, NULL);
4399 0 : if (rc)
4400 : {
4401 0 : log_error ("update_keysig_packet failed: %s\n",
4402 : gpg_strerror (rc));
4403 0 : return 0;
4404 : }
4405 : /* replace the packet */
4406 0 : newpkt = xmalloc_clear (sizeof *newpkt);
4407 0 : newpkt->pkttype = PKT_SIGNATURE;
4408 0 : newpkt->pkt.signature = newsig;
4409 0 : free_packet (node->pkt);
4410 0 : xfree (node->pkt);
4411 0 : node->pkt = newpkt;
4412 0 : modified = 1;
4413 : }
4414 : }
4415 : }
4416 : }
4417 :
4418 0 : return modified;
4419 : }
4420 :
4421 :
4422 : static int
4423 0 : menu_set_keyserver_url (const char *url, KBNODE pub_keyblock)
4424 : {
4425 : PKT_public_key *main_pk;
4426 : PKT_user_id *uid;
4427 : KBNODE node;
4428 : u32 keyid[2];
4429 : int selected, select_all;
4430 0 : int modified = 0;
4431 : char *answer, *uri;
4432 :
4433 0 : no_primary_warning (pub_keyblock);
4434 :
4435 0 : if (url)
4436 0 : answer = xstrdup (url);
4437 : else
4438 : {
4439 0 : answer = cpr_get_utf8 ("keyedit.add_keyserver",
4440 0 : _("Enter your preferred keyserver URL: "));
4441 0 : if (answer[0] == '\0' || answer[0] == CONTROL_D)
4442 : {
4443 0 : xfree (answer);
4444 0 : return 0;
4445 : }
4446 : }
4447 :
4448 0 : if (ascii_strcasecmp (answer, "none") == 0)
4449 0 : uri = NULL;
4450 : else
4451 : {
4452 0 : struct keyserver_spec *keyserver = NULL;
4453 : /* Sanity check the format */
4454 0 : keyserver = parse_keyserver_uri (answer, 1);
4455 0 : xfree (answer);
4456 0 : if (!keyserver)
4457 : {
4458 0 : log_info (_("could not parse keyserver URL\n"));
4459 0 : return 0;
4460 : }
4461 0 : uri = xstrdup (keyserver->uri);
4462 0 : free_keyserver_spec (keyserver);
4463 : }
4464 :
4465 0 : select_all = !count_selected_uids (pub_keyblock);
4466 :
4467 : /* Now we can actually change the self signature(s) */
4468 0 : main_pk = NULL;
4469 0 : uid = NULL;
4470 0 : selected = 0;
4471 0 : for (node = pub_keyblock; node; node = node->next)
4472 : {
4473 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
4474 0 : break; /* ready */
4475 :
4476 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
4477 : {
4478 0 : main_pk = node->pkt->pkt.public_key;
4479 0 : keyid_from_pk (main_pk, keyid);
4480 : }
4481 0 : else if (node->pkt->pkttype == PKT_USER_ID)
4482 : {
4483 0 : uid = node->pkt->pkt.user_id;
4484 0 : selected = select_all || (node->flag & NODFLG_SELUID);
4485 : }
4486 0 : else if (main_pk && uid && selected
4487 0 : && node->pkt->pkttype == PKT_SIGNATURE)
4488 : {
4489 0 : PKT_signature *sig = node->pkt->pkt.signature;
4490 0 : if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4491 0 : && (uid && (sig->sig_class & ~3) == 0x10)
4492 0 : && sig->flags.chosen_selfsig)
4493 : {
4494 0 : char *user = utf8_to_native (uid->name, strlen (uid->name), 0);
4495 0 : if (sig->version < 4)
4496 0 : log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
4497 : user);
4498 : else
4499 : {
4500 : /* This is a selfsignature which is to be replaced
4501 : * We have to ignore v3 signatures because they are
4502 : * not able to carry the subpacket. */
4503 : PKT_signature *newsig;
4504 : PACKET *newpkt;
4505 : int rc;
4506 : const byte *p;
4507 : size_t plen;
4508 :
4509 0 : p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen);
4510 0 : if (p && plen)
4511 : {
4512 0 : tty_printf ("Current preferred keyserver for user"
4513 : " ID \"%s\": ", user);
4514 0 : tty_print_utf8_string (p, plen);
4515 0 : tty_printf ("\n");
4516 0 : if (!cpr_get_answer_is_yes
4517 : ("keyedit.confirm_keyserver",
4518 : uri
4519 : ? _("Are you sure you want to replace it? (y/N) ")
4520 : : _("Are you sure you want to delete it? (y/N) ")))
4521 0 : continue;
4522 : }
4523 0 : else if (uri == NULL)
4524 : {
4525 : /* There is no current keyserver URL, so there
4526 : is no point in trying to un-set it. */
4527 0 : continue;
4528 : }
4529 :
4530 0 : rc = update_keysig_packet (&newsig, sig,
4531 : main_pk, uid, NULL,
4532 : main_pk,
4533 : keygen_add_keyserver_url, uri);
4534 0 : if (rc)
4535 : {
4536 0 : log_error ("update_keysig_packet failed: %s\n",
4537 : gpg_strerror (rc));
4538 0 : xfree (uri);
4539 0 : return 0;
4540 : }
4541 : /* replace the packet */
4542 0 : newpkt = xmalloc_clear (sizeof *newpkt);
4543 0 : newpkt->pkttype = PKT_SIGNATURE;
4544 0 : newpkt->pkt.signature = newsig;
4545 0 : free_packet (node->pkt);
4546 0 : xfree (node->pkt);
4547 0 : node->pkt = newpkt;
4548 0 : modified = 1;
4549 : }
4550 :
4551 0 : xfree (user);
4552 : }
4553 : }
4554 : }
4555 :
4556 0 : xfree (uri);
4557 0 : return modified;
4558 : }
4559 :
4560 : static int
4561 0 : menu_set_notation (const char *string, KBNODE pub_keyblock)
4562 : {
4563 : PKT_public_key *main_pk;
4564 : PKT_user_id *uid;
4565 : KBNODE node;
4566 : u32 keyid[2];
4567 : int selected, select_all;
4568 0 : int modified = 0;
4569 : char *answer;
4570 : struct notation *notation;
4571 :
4572 0 : no_primary_warning (pub_keyblock);
4573 :
4574 0 : if (string)
4575 0 : answer = xstrdup (string);
4576 : else
4577 : {
4578 0 : answer = cpr_get_utf8 ("keyedit.add_notation",
4579 0 : _("Enter the notation: "));
4580 0 : if (answer[0] == '\0' || answer[0] == CONTROL_D)
4581 : {
4582 0 : xfree (answer);
4583 0 : return 0;
4584 : }
4585 : }
4586 :
4587 0 : if (!ascii_strcasecmp (answer, "none")
4588 0 : || !ascii_strcasecmp (answer, "-"))
4589 0 : notation = NULL; /* Delete them all. */
4590 : else
4591 : {
4592 0 : notation = string_to_notation (answer, 0);
4593 0 : if (!notation)
4594 : {
4595 0 : xfree (answer);
4596 0 : return 0;
4597 : }
4598 : }
4599 :
4600 0 : xfree (answer);
4601 :
4602 0 : select_all = !count_selected_uids (pub_keyblock);
4603 :
4604 : /* Now we can actually change the self signature(s) */
4605 0 : main_pk = NULL;
4606 0 : uid = NULL;
4607 0 : selected = 0;
4608 0 : for (node = pub_keyblock; node; node = node->next)
4609 : {
4610 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
4611 0 : break; /* ready */
4612 :
4613 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
4614 : {
4615 0 : main_pk = node->pkt->pkt.public_key;
4616 0 : keyid_from_pk (main_pk, keyid);
4617 : }
4618 0 : else if (node->pkt->pkttype == PKT_USER_ID)
4619 : {
4620 0 : uid = node->pkt->pkt.user_id;
4621 0 : selected = select_all || (node->flag & NODFLG_SELUID);
4622 : }
4623 0 : else if (main_pk && uid && selected
4624 0 : && node->pkt->pkttype == PKT_SIGNATURE)
4625 : {
4626 0 : PKT_signature *sig = node->pkt->pkt.signature;
4627 0 : if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4628 0 : && (uid && (sig->sig_class & ~3) == 0x10)
4629 0 : && sig->flags.chosen_selfsig)
4630 : {
4631 0 : char *user = utf8_to_native (uid->name, strlen (uid->name), 0);
4632 0 : if (sig->version < 4)
4633 0 : log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
4634 : user);
4635 : else
4636 : {
4637 : PKT_signature *newsig;
4638 : PACKET *newpkt;
4639 0 : int rc, skip = 0, addonly = 1;
4640 :
4641 0 : if (sig->flags.notation)
4642 : {
4643 0 : tty_printf ("Current notations for user ID \"%s\":\n",
4644 : user);
4645 0 : tty_print_notations (-9, sig);
4646 : }
4647 : else
4648 : {
4649 0 : tty_printf ("No notations on user ID \"%s\"\n", user);
4650 0 : if (notation == NULL)
4651 : {
4652 : /* There are no current notations, so there
4653 : is no point in trying to un-set them. */
4654 0 : continue;
4655 : }
4656 : }
4657 :
4658 0 : if (notation)
4659 : {
4660 : struct notation *n;
4661 0 : int deleting = 0;
4662 :
4663 0 : notation->next = sig_to_notation (sig);
4664 :
4665 0 : for (n = notation->next; n; n = n->next)
4666 0 : if (strcmp (n->name, notation->name) == 0)
4667 : {
4668 0 : if (notation->value)
4669 : {
4670 0 : if (strcmp (n->value, notation->value) == 0)
4671 : {
4672 0 : if (notation->flags.ignore)
4673 : {
4674 : /* Value match with a delete
4675 : flag. */
4676 0 : n->flags.ignore = 1;
4677 0 : deleting = 1;
4678 : }
4679 : else
4680 : {
4681 : /* Adding the same notation
4682 : twice, so don't add it at
4683 : all. */
4684 0 : skip = 1;
4685 0 : tty_printf ("Skipping notation:"
4686 : " %s=%s\n",
4687 : notation->name,
4688 : notation->value);
4689 0 : break;
4690 : }
4691 : }
4692 : }
4693 : else
4694 : {
4695 : /* No value, so it means delete. */
4696 0 : n->flags.ignore = 1;
4697 0 : deleting = 1;
4698 : }
4699 :
4700 0 : if (n->flags.ignore)
4701 : {
4702 0 : tty_printf ("Removing notation: %s=%s\n",
4703 : n->name, n->value);
4704 0 : addonly = 0;
4705 : }
4706 : }
4707 :
4708 0 : if (!notation->flags.ignore && !skip)
4709 0 : tty_printf ("Adding notation: %s=%s\n",
4710 : notation->name, notation->value);
4711 :
4712 : /* We tried to delete, but had no matches. */
4713 0 : if (notation->flags.ignore && !deleting)
4714 0 : continue;
4715 : }
4716 : else
4717 : {
4718 0 : tty_printf ("Removing all notations\n");
4719 0 : addonly = 0;
4720 : }
4721 :
4722 0 : if (skip
4723 0 : || (!addonly
4724 0 : &&
4725 0 : !cpr_get_answer_is_yes ("keyedit.confirm_notation",
4726 0 : _("Proceed? (y/N) "))))
4727 0 : continue;
4728 :
4729 0 : rc = update_keysig_packet (&newsig, sig,
4730 : main_pk, uid, NULL,
4731 : main_pk,
4732 : keygen_add_notations, notation);
4733 0 : if (rc)
4734 : {
4735 0 : log_error ("update_keysig_packet failed: %s\n",
4736 : gpg_strerror (rc));
4737 0 : free_notation (notation);
4738 0 : xfree (user);
4739 0 : return 0;
4740 : }
4741 :
4742 : /* replace the packet */
4743 0 : newpkt = xmalloc_clear (sizeof *newpkt);
4744 0 : newpkt->pkttype = PKT_SIGNATURE;
4745 0 : newpkt->pkt.signature = newsig;
4746 0 : free_packet (node->pkt);
4747 0 : xfree (node->pkt);
4748 0 : node->pkt = newpkt;
4749 0 : modified = 1;
4750 :
4751 0 : if (notation)
4752 : {
4753 : /* Snip off the notation list from the sig */
4754 0 : free_notation (notation->next);
4755 0 : notation->next = NULL;
4756 : }
4757 :
4758 0 : xfree (user);
4759 : }
4760 : }
4761 : }
4762 : }
4763 :
4764 0 : free_notation (notation);
4765 0 : return modified;
4766 : }
4767 :
4768 :
4769 : /*
4770 : * Select one user id or remove all selection if IDX is 0 or select
4771 : * all if IDX is -1. Returns: True if the selection changed.
4772 : */
4773 : static int
4774 0 : menu_select_uid (KBNODE keyblock, int idx)
4775 : {
4776 : KBNODE node;
4777 : int i;
4778 :
4779 0 : if (idx == -1) /* Select all. */
4780 : {
4781 0 : for (node = keyblock; node; node = node->next)
4782 0 : if (node->pkt->pkttype == PKT_USER_ID)
4783 0 : node->flag |= NODFLG_SELUID;
4784 0 : return 1;
4785 : }
4786 0 : else if (idx) /* Toggle. */
4787 : {
4788 0 : for (i = 0, node = keyblock; node; node = node->next)
4789 : {
4790 0 : if (node->pkt->pkttype == PKT_USER_ID)
4791 0 : if (++i == idx)
4792 0 : break;
4793 : }
4794 0 : if (!node)
4795 : {
4796 0 : tty_printf (_("No user ID with index %d\n"), idx);
4797 0 : return 0;
4798 : }
4799 :
4800 0 : for (i = 0, node = keyblock; node; node = node->next)
4801 : {
4802 0 : if (node->pkt->pkttype == PKT_USER_ID)
4803 : {
4804 0 : if (++i == idx)
4805 : {
4806 0 : if ((node->flag & NODFLG_SELUID))
4807 0 : node->flag &= ~NODFLG_SELUID;
4808 : else
4809 0 : node->flag |= NODFLG_SELUID;
4810 : }
4811 : }
4812 : }
4813 : }
4814 : else /* Unselect all */
4815 : {
4816 0 : for (node = keyblock; node; node = node->next)
4817 0 : if (node->pkt->pkttype == PKT_USER_ID)
4818 0 : node->flag &= ~NODFLG_SELUID;
4819 : }
4820 :
4821 0 : return 1;
4822 : }
4823 :
4824 :
4825 : /* Search in the keyblock for a uid that matches namehash */
4826 : static int
4827 0 : menu_select_uid_namehash (KBNODE keyblock, const char *namehash)
4828 : {
4829 : byte hash[NAMEHASH_LEN];
4830 : KBNODE node;
4831 : int i;
4832 :
4833 0 : assert (strlen (namehash) == NAMEHASH_LEN * 2);
4834 :
4835 0 : for (i = 0; i < NAMEHASH_LEN; i++)
4836 0 : hash[i] = hextobyte (&namehash[i * 2]);
4837 :
4838 0 : for (node = keyblock->next; node; node = node->next)
4839 : {
4840 0 : if (node->pkt->pkttype == PKT_USER_ID)
4841 : {
4842 0 : namehash_from_uid (node->pkt->pkt.user_id);
4843 0 : if (memcmp (node->pkt->pkt.user_id->namehash, hash, NAMEHASH_LEN) ==
4844 : 0)
4845 : {
4846 0 : if (node->flag & NODFLG_SELUID)
4847 0 : node->flag &= ~NODFLG_SELUID;
4848 : else
4849 0 : node->flag |= NODFLG_SELUID;
4850 :
4851 0 : break;
4852 : }
4853 : }
4854 : }
4855 :
4856 0 : if (!node)
4857 : {
4858 0 : tty_printf (_("No user ID with hash %s\n"), namehash);
4859 0 : return 0;
4860 : }
4861 :
4862 0 : return 1;
4863 : }
4864 :
4865 :
4866 : /*
4867 : * Select secondary keys
4868 : * Returns: True if the selection changed.
4869 : */
4870 : static int
4871 0 : menu_select_key (KBNODE keyblock, int idx)
4872 : {
4873 : KBNODE node;
4874 : int i;
4875 :
4876 0 : if (idx == -1) /* Select all. */
4877 : {
4878 0 : for (node = keyblock; node; node = node->next)
4879 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4880 0 : || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4881 0 : node->flag |= NODFLG_SELKEY;
4882 : }
4883 0 : else if (idx) /* Toggle selection. */
4884 : {
4885 0 : for (i = 0, node = keyblock; node; node = node->next)
4886 : {
4887 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4888 0 : || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4889 0 : if (++i == idx)
4890 0 : break;
4891 : }
4892 0 : if (!node)
4893 : {
4894 0 : tty_printf (_("No subkey with index %d\n"), idx);
4895 0 : return 0;
4896 : }
4897 :
4898 0 : for (i = 0, node = keyblock; node; node = node->next)
4899 : {
4900 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4901 0 : || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4902 0 : if (++i == idx)
4903 : {
4904 0 : if ((node->flag & NODFLG_SELKEY))
4905 0 : node->flag &= ~NODFLG_SELKEY;
4906 : else
4907 0 : node->flag |= NODFLG_SELKEY;
4908 : }
4909 : }
4910 : }
4911 : else /* Unselect all. */
4912 : {
4913 0 : for (node = keyblock; node; node = node->next)
4914 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4915 0 : || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4916 0 : node->flag &= ~NODFLG_SELKEY;
4917 : }
4918 :
4919 0 : return 1;
4920 : }
4921 :
4922 :
4923 : static int
4924 0 : count_uids_with_flag (KBNODE keyblock, unsigned flag)
4925 : {
4926 : KBNODE node;
4927 0 : int i = 0;
4928 :
4929 0 : for (node = keyblock; node; node = node->next)
4930 0 : if (node->pkt->pkttype == PKT_USER_ID && (node->flag & flag))
4931 0 : i++;
4932 0 : return i;
4933 : }
4934 :
4935 :
4936 : static int
4937 0 : count_keys_with_flag (KBNODE keyblock, unsigned flag)
4938 : {
4939 : KBNODE node;
4940 0 : int i = 0;
4941 :
4942 0 : for (node = keyblock; node; node = node->next)
4943 0 : if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4944 0 : || node->pkt->pkttype == PKT_SECRET_SUBKEY) && (node->flag & flag))
4945 0 : i++;
4946 0 : return i;
4947 : }
4948 :
4949 :
4950 : static int
4951 0 : count_uids (KBNODE keyblock)
4952 : {
4953 : KBNODE node;
4954 0 : int i = 0;
4955 :
4956 0 : for (node = keyblock; node; node = node->next)
4957 0 : if (node->pkt->pkttype == PKT_USER_ID)
4958 0 : i++;
4959 0 : return i;
4960 : }
4961 :
4962 :
4963 : /*
4964 : * Returns true if there is at least one selected user id
4965 : */
4966 : static int
4967 0 : count_selected_uids (KBNODE keyblock)
4968 : {
4969 0 : return count_uids_with_flag (keyblock, NODFLG_SELUID);
4970 : }
4971 :
4972 :
4973 : static int
4974 0 : count_selected_keys (KBNODE keyblock)
4975 : {
4976 0 : return count_keys_with_flag (keyblock, NODFLG_SELKEY);
4977 : }
4978 :
4979 :
4980 : /* Returns how many real (i.e. not attribute) uids are unmarked. */
4981 : static int
4982 0 : real_uids_left (KBNODE keyblock)
4983 : {
4984 : KBNODE node;
4985 0 : int real = 0;
4986 :
4987 0 : for (node = keyblock; node; node = node->next)
4988 0 : if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & NODFLG_SELUID) &&
4989 0 : !node->pkt->pkt.user_id->attrib_data)
4990 0 : real++;
4991 :
4992 0 : return real;
4993 : }
4994 :
4995 :
4996 : /*
4997 : * Ask whether the signature should be revoked. If the user commits this,
4998 : * flag bit MARK_A is set on the signature and the user ID.
4999 : */
5000 : static void
5001 0 : ask_revoke_sig (KBNODE keyblock, KBNODE node)
5002 : {
5003 0 : int doit = 0;
5004 : PKT_user_id *uid;
5005 0 : PKT_signature *sig = node->pkt->pkt.signature;
5006 0 : KBNODE unode = find_prev_kbnode (keyblock, node, PKT_USER_ID);
5007 :
5008 0 : if (!unode)
5009 : {
5010 0 : log_error ("Oops: no user ID for signature\n");
5011 0 : return;
5012 : }
5013 :
5014 0 : uid = unode->pkt->pkt.user_id;
5015 :
5016 0 : if (opt.with_colons)
5017 : {
5018 0 : if (uid->attrib_data)
5019 0 : printf ("uat:::::::::%u %lu", uid->numattribs, uid->attrib_len);
5020 : else
5021 : {
5022 0 : es_printf ("uid:::::::::");
5023 0 : es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
5024 : }
5025 :
5026 0 : es_printf ("\n");
5027 :
5028 0 : print_and_check_one_sig_colon (keyblock, node, NULL, NULL, NULL, NULL,
5029 : 1);
5030 : }
5031 : else
5032 : {
5033 0 : char *p = utf8_to_native (unode->pkt->pkt.user_id->name,
5034 0 : unode->pkt->pkt.user_id->len, 0);
5035 0 : tty_printf (_("user ID: \"%s\"\n"), p);
5036 0 : xfree (p);
5037 :
5038 0 : tty_printf (_("signed by your key %s on %s%s%s\n"),
5039 0 : keystr (sig->keyid), datestr_from_sig (sig),
5040 0 : sig->flags.exportable ? "" : _(" (non-exportable)"), "");
5041 : }
5042 0 : if (sig->flags.expired)
5043 : {
5044 0 : tty_printf (_("This signature expired on %s.\n"),
5045 : expirestr_from_sig (sig));
5046 : /* Use a different question so we can have different help text */
5047 0 : doit = cpr_get_answer_is_yes
5048 : ("ask_revoke_sig.expired",
5049 0 : _("Are you sure you still want to revoke it? (y/N) "));
5050 : }
5051 : else
5052 0 : doit = cpr_get_answer_is_yes
5053 : ("ask_revoke_sig.one",
5054 0 : _("Create a revocation certificate for this signature? (y/N) "));
5055 :
5056 0 : if (doit)
5057 : {
5058 0 : node->flag |= NODFLG_MARK_A;
5059 0 : unode->flag |= NODFLG_MARK_A;
5060 : }
5061 : }
5062 :
5063 :
5064 : /*
5065 : * Display all user ids of the current public key together with signatures
5066 : * done by one of our keys. Then walk over all this sigs and ask the user
5067 : * whether he wants to revoke this signature.
5068 : * Return: True when the keyblock has changed.
5069 : */
5070 : static int
5071 0 : menu_revsig (KBNODE keyblock)
5072 : {
5073 : PKT_signature *sig;
5074 : PKT_public_key *primary_pk;
5075 : KBNODE node;
5076 0 : int changed = 0;
5077 0 : int rc, any, skip = 1, all = !count_selected_uids (keyblock);
5078 0 : struct revocation_reason_info *reason = NULL;
5079 :
5080 0 : assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
5081 :
5082 : /* First check whether we have any signatures at all. */
5083 0 : any = 0;
5084 0 : for (node = keyblock; node; node = node->next)
5085 : {
5086 0 : node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
5087 0 : if (node->pkt->pkttype == PKT_USER_ID)
5088 : {
5089 0 : if (node->flag & NODFLG_SELUID || all)
5090 0 : skip = 0;
5091 : else
5092 0 : skip = 1;
5093 : }
5094 0 : else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
5095 0 : && ((sig = node->pkt->pkt.signature),
5096 0 : have_secret_key_with_kid (sig->keyid)))
5097 : {
5098 0 : if ((sig->sig_class & ~3) == 0x10)
5099 : {
5100 0 : any = 1;
5101 0 : break;
5102 : }
5103 : }
5104 : }
5105 :
5106 0 : if (!any)
5107 : {
5108 0 : tty_printf (_("Not signed by you.\n"));
5109 0 : return 0;
5110 : }
5111 :
5112 :
5113 : /* FIXME: detect duplicates here */
5114 0 : tty_printf (_("You have signed these user IDs on key %s:\n"),
5115 0 : keystr_from_pk (keyblock->pkt->pkt.public_key));
5116 0 : for (node = keyblock; node; node = node->next)
5117 : {
5118 0 : node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
5119 0 : if (node->pkt->pkttype == PKT_USER_ID)
5120 : {
5121 0 : if (node->flag & NODFLG_SELUID || all)
5122 0 : {
5123 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
5124 : /* Hmmm: Should we show only UIDs with a signature? */
5125 0 : tty_printf (" ");
5126 0 : tty_print_utf8_string (uid->name, uid->len);
5127 0 : tty_printf ("\n");
5128 0 : skip = 0;
5129 : }
5130 : else
5131 0 : skip = 1;
5132 : }
5133 0 : else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
5134 0 : && ((sig = node->pkt->pkt.signature),
5135 0 : have_secret_key_with_kid (sig->keyid)))
5136 : {
5137 0 : if ((sig->sig_class & ~3) == 0x10)
5138 : {
5139 0 : tty_printf (" ");
5140 0 : tty_printf (_("signed by your key %s on %s%s%s\n"),
5141 0 : keystr (sig->keyid), datestr_from_sig (sig),
5142 0 : sig->flags.exportable ? "" : _(" (non-exportable)"),
5143 0 : sig->flags.revocable ? "" : _(" (non-revocable)"));
5144 0 : if (sig->flags.revocable)
5145 0 : node->flag |= NODFLG_SELSIG;
5146 : }
5147 0 : else if (sig->sig_class == 0x30)
5148 : {
5149 0 : tty_printf (" ");
5150 0 : tty_printf (_("revoked by your key %s on %s\n"),
5151 0 : keystr (sig->keyid), datestr_from_sig (sig));
5152 : }
5153 : }
5154 : }
5155 :
5156 0 : tty_printf ("\n");
5157 :
5158 : /* ask */
5159 0 : for (node = keyblock; node; node = node->next)
5160 : {
5161 0 : if (!(node->flag & NODFLG_SELSIG))
5162 0 : continue;
5163 0 : ask_revoke_sig (keyblock, node);
5164 : }
5165 :
5166 : /* present selected */
5167 0 : any = 0;
5168 0 : for (node = keyblock; node; node = node->next)
5169 : {
5170 0 : if (!(node->flag & NODFLG_MARK_A))
5171 0 : continue;
5172 0 : if (!any)
5173 : {
5174 0 : any = 1;
5175 0 : tty_printf (_("You are about to revoke these signatures:\n"));
5176 : }
5177 0 : if (node->pkt->pkttype == PKT_USER_ID)
5178 : {
5179 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
5180 0 : tty_printf (" ");
5181 0 : tty_print_utf8_string (uid->name, uid->len);
5182 0 : tty_printf ("\n");
5183 : }
5184 0 : else if (node->pkt->pkttype == PKT_SIGNATURE)
5185 : {
5186 0 : sig = node->pkt->pkt.signature;
5187 0 : tty_printf (" ");
5188 0 : tty_printf (_("signed by your key %s on %s%s%s\n"),
5189 0 : keystr (sig->keyid), datestr_from_sig (sig), "",
5190 0 : sig->flags.exportable ? "" : _(" (non-exportable)"));
5191 : }
5192 : }
5193 0 : if (!any)
5194 0 : return 0; /* none selected */
5195 :
5196 0 : if (!cpr_get_answer_is_yes
5197 : ("ask_revoke_sig.okay",
5198 0 : _("Really create the revocation certificates? (y/N) ")))
5199 0 : return 0; /* forget it */
5200 :
5201 0 : reason = ask_revocation_reason (0, 1, 0);
5202 0 : if (!reason)
5203 : { /* user decided to cancel */
5204 0 : return 0;
5205 : }
5206 :
5207 : /* now we can sign the user ids */
5208 : reloop: /* (must use this, because we are modifing the list) */
5209 0 : primary_pk = keyblock->pkt->pkt.public_key;
5210 0 : for (node = keyblock; node; node = node->next)
5211 : {
5212 : KBNODE unode;
5213 : PACKET *pkt;
5214 : struct sign_attrib attrib;
5215 : PKT_public_key *signerkey;
5216 :
5217 0 : if (!(node->flag & NODFLG_MARK_A)
5218 0 : || node->pkt->pkttype != PKT_SIGNATURE)
5219 0 : continue;
5220 0 : unode = find_prev_kbnode (keyblock, node, PKT_USER_ID);
5221 0 : assert (unode); /* we already checked this */
5222 :
5223 0 : memset (&attrib, 0, sizeof attrib);
5224 0 : attrib.reason = reason;
5225 0 : attrib.non_exportable = !node->pkt->pkt.signature->flags.exportable;
5226 :
5227 0 : node->flag &= ~NODFLG_MARK_A;
5228 0 : signerkey = xmalloc_secure_clear (sizeof *signerkey);
5229 0 : if (get_seckey (signerkey, node->pkt->pkt.signature->keyid))
5230 : {
5231 0 : log_info (_("no secret key\n"));
5232 0 : free_public_key (signerkey);
5233 0 : continue;
5234 : }
5235 0 : rc = make_keysig_packet (&sig, primary_pk,
5236 0 : unode->pkt->pkt.user_id,
5237 : NULL, signerkey, 0x30, 0, 0, 0,
5238 : sign_mk_attrib, &attrib, NULL);
5239 0 : free_public_key (signerkey);
5240 0 : if (rc)
5241 : {
5242 0 : write_status_error ("keysig", rc);
5243 0 : log_error (_("signing failed: %s\n"), gpg_strerror (rc));
5244 0 : release_revocation_reason_info (reason);
5245 0 : return changed;
5246 : }
5247 0 : changed = 1; /* we changed the keyblock */
5248 0 : update_trust = 1;
5249 : /* Are we revoking our own uid? */
5250 0 : if (primary_pk->keyid[0] == sig->keyid[0] &&
5251 0 : primary_pk->keyid[1] == sig->keyid[1])
5252 0 : unode->pkt->pkt.user_id->is_revoked = 1;
5253 0 : pkt = xmalloc_clear (sizeof *pkt);
5254 0 : pkt->pkttype = PKT_SIGNATURE;
5255 0 : pkt->pkt.signature = sig;
5256 0 : insert_kbnode (unode, new_kbnode (pkt), 0);
5257 0 : goto reloop;
5258 : }
5259 :
5260 0 : release_revocation_reason_info (reason);
5261 0 : return changed;
5262 : }
5263 :
5264 :
5265 : /* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
5266 : keyblock changed. */
5267 : static int
5268 0 : menu_revuid (KBNODE pub_keyblock)
5269 : {
5270 0 : PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
5271 : KBNODE node;
5272 0 : int changed = 0;
5273 : int rc;
5274 0 : struct revocation_reason_info *reason = NULL;
5275 :
5276 : /* Note that this is correct as per the RFCs, but nevertheless
5277 : somewhat meaningless in the real world. 1991 did define the 0x30
5278 : sig class, but PGP 2.x did not actually implement it, so it would
5279 : probably be safe to use v4 revocations everywhere. -ds */
5280 :
5281 0 : for (node = pub_keyblock; node; node = node->next)
5282 0 : if (pk->version > 3 || (node->pkt->pkttype == PKT_USER_ID &&
5283 0 : node->pkt->pkt.user_id->selfsigversion > 3))
5284 : {
5285 0 : if ((reason = ask_revocation_reason (0, 1, 4)))
5286 0 : break;
5287 : else
5288 0 : goto leave;
5289 : }
5290 :
5291 : reloop: /* (better this way because we are modifing the keyring) */
5292 0 : for (node = pub_keyblock; node; node = node->next)
5293 0 : if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
5294 : {
5295 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
5296 :
5297 0 : if (uid->is_revoked)
5298 : {
5299 0 : char *user = utf8_to_native (uid->name, uid->len, 0);
5300 0 : log_info (_("user ID \"%s\" is already revoked\n"), user);
5301 0 : xfree (user);
5302 : }
5303 : else
5304 : {
5305 : PACKET *pkt;
5306 : PKT_signature *sig;
5307 : struct sign_attrib attrib;
5308 0 : u32 timestamp = make_timestamp ();
5309 :
5310 0 : if (uid->created >= timestamp)
5311 : {
5312 : /* Okay, this is a problem. The user ID selfsig was
5313 : created in the future, so we need to warn the user and
5314 : set our revocation timestamp one second after that so
5315 : everything comes out clean. */
5316 :
5317 0 : log_info (_("WARNING: a user ID signature is dated %d"
5318 : " seconds in the future\n"),
5319 0 : uid->created - timestamp);
5320 :
5321 0 : timestamp = uid->created + 1;
5322 : }
5323 :
5324 0 : memset (&attrib, 0, sizeof attrib);
5325 0 : attrib.reason = reason;
5326 :
5327 0 : node->flag &= ~NODFLG_SELUID;
5328 :
5329 0 : rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
5330 : timestamp, 0,
5331 : sign_mk_attrib, &attrib, NULL);
5332 0 : if (rc)
5333 : {
5334 0 : write_status_error ("keysig", rc);
5335 0 : log_error (_("signing failed: %s\n"), gpg_strerror (rc));
5336 0 : goto leave;
5337 : }
5338 : else
5339 : {
5340 0 : pkt = xmalloc_clear (sizeof *pkt);
5341 0 : pkt->pkttype = PKT_SIGNATURE;
5342 0 : pkt->pkt.signature = sig;
5343 0 : insert_kbnode (node, new_kbnode (pkt), 0);
5344 :
5345 : #ifndef NO_TRUST_MODELS
5346 : /* If the trustdb has an entry for this key+uid then the
5347 : trustdb needs an update. */
5348 0 : if (!update_trust
5349 0 : && (get_validity (pk, uid, NULL, 0) & TRUST_MASK) >=
5350 : TRUST_UNDEFINED)
5351 0 : update_trust = 1;
5352 : #endif /*!NO_TRUST_MODELS*/
5353 :
5354 0 : changed = 1;
5355 0 : node->pkt->pkt.user_id->is_revoked = 1;
5356 :
5357 0 : goto reloop;
5358 : }
5359 : }
5360 : }
5361 :
5362 0 : if (changed)
5363 0 : commit_kbnode (&pub_keyblock);
5364 :
5365 : leave:
5366 0 : release_revocation_reason_info (reason);
5367 0 : return changed;
5368 : }
5369 :
5370 :
5371 : /*
5372 : * Revoke the whole key.
5373 : */
5374 : static int
5375 0 : menu_revkey (KBNODE pub_keyblock)
5376 : {
5377 0 : PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
5378 0 : int rc, changed = 0;
5379 : struct revocation_reason_info *reason;
5380 : PACKET *pkt;
5381 : PKT_signature *sig;
5382 :
5383 0 : if (pk->flags.revoked)
5384 : {
5385 0 : tty_printf (_("Key %s is already revoked.\n"), keystr_from_pk (pk));
5386 0 : return 0;
5387 : }
5388 :
5389 0 : reason = ask_revocation_reason (1, 0, 0);
5390 : /* user decided to cancel */
5391 0 : if (!reason)
5392 0 : return 0;
5393 :
5394 0 : rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
5395 : 0x20, 0, 0, 0,
5396 : revocation_reason_build_cb, reason, NULL);
5397 0 : if (rc)
5398 : {
5399 0 : write_status_error ("keysig", rc);
5400 0 : log_error (_("signing failed: %s\n"), gpg_strerror (rc));
5401 0 : goto scram;
5402 : }
5403 :
5404 0 : changed = 1; /* we changed the keyblock */
5405 :
5406 0 : pkt = xmalloc_clear (sizeof *pkt);
5407 0 : pkt->pkttype = PKT_SIGNATURE;
5408 0 : pkt->pkt.signature = sig;
5409 0 : insert_kbnode (pub_keyblock, new_kbnode (pkt), 0);
5410 0 : commit_kbnode (&pub_keyblock);
5411 :
5412 0 : update_trust = 1;
5413 :
5414 : scram:
5415 0 : release_revocation_reason_info (reason);
5416 0 : return changed;
5417 : }
5418 :
5419 :
5420 : static int
5421 0 : menu_revsubkey (KBNODE pub_keyblock)
5422 : {
5423 : PKT_public_key *mainpk;
5424 : KBNODE node;
5425 0 : int changed = 0;
5426 : int rc;
5427 0 : struct revocation_reason_info *reason = NULL;
5428 :
5429 0 : reason = ask_revocation_reason (1, 0, 0);
5430 0 : if (!reason)
5431 0 : return 0; /* User decided to cancel. */
5432 :
5433 : reloop: /* (better this way because we are modifing the keyring) */
5434 0 : mainpk = pub_keyblock->pkt->pkt.public_key;
5435 0 : for (node = pub_keyblock; node; node = node->next)
5436 : {
5437 0 : if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
5438 0 : && (node->flag & NODFLG_SELKEY))
5439 : {
5440 : PACKET *pkt;
5441 : PKT_signature *sig;
5442 0 : PKT_public_key *subpk = node->pkt->pkt.public_key;
5443 : struct sign_attrib attrib;
5444 :
5445 0 : if (subpk->flags.revoked)
5446 : {
5447 0 : tty_printf (_("Subkey %s is already revoked.\n"),
5448 : keystr_from_pk (subpk));
5449 0 : continue;
5450 : }
5451 :
5452 0 : memset (&attrib, 0, sizeof attrib);
5453 0 : attrib.reason = reason;
5454 :
5455 0 : node->flag &= ~NODFLG_SELKEY;
5456 0 : rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
5457 : 0x28, 0, 0, 0, sign_mk_attrib, &attrib,
5458 : NULL);
5459 0 : if (rc)
5460 : {
5461 0 : write_status_error ("keysig", rc);
5462 0 : log_error (_("signing failed: %s\n"), gpg_strerror (rc));
5463 0 : release_revocation_reason_info (reason);
5464 0 : return changed;
5465 : }
5466 0 : changed = 1; /* we changed the keyblock */
5467 :
5468 0 : pkt = xmalloc_clear (sizeof *pkt);
5469 0 : pkt->pkttype = PKT_SIGNATURE;
5470 0 : pkt->pkt.signature = sig;
5471 0 : insert_kbnode (node, new_kbnode (pkt), 0);
5472 0 : goto reloop;
5473 : }
5474 : }
5475 0 : commit_kbnode (&pub_keyblock);
5476 :
5477 : /* No need to set update_trust here since signing keys no longer
5478 : are used to certify other keys, so there is no change in trust
5479 : when revoking/removing them */
5480 :
5481 0 : release_revocation_reason_info (reason);
5482 0 : return changed;
5483 : }
5484 :
5485 :
5486 : /* Note that update_ownertrust is going to mark the trustdb dirty when
5487 : enabling or disabling a key. This is arguably sub-optimal as
5488 : disabled keys are still counted in the web of trust, but perhaps
5489 : not worth adding extra complexity to change. -ds */
5490 : #ifndef NO_TRUST_MODELS
5491 : static int
5492 0 : enable_disable_key (KBNODE keyblock, int disable)
5493 : {
5494 0 : PKT_public_key *pk =
5495 0 : find_kbnode (keyblock, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
5496 : unsigned int trust, newtrust;
5497 :
5498 0 : trust = newtrust = get_ownertrust (pk);
5499 0 : newtrust &= ~TRUST_FLAG_DISABLED;
5500 0 : if (disable)
5501 0 : newtrust |= TRUST_FLAG_DISABLED;
5502 0 : if (trust == newtrust)
5503 0 : return 0; /* already in that state */
5504 0 : update_ownertrust (pk, newtrust);
5505 0 : return 0;
5506 : }
5507 : #endif /*!NO_TRUST_MODELS*/
5508 :
5509 :
5510 : static void
5511 0 : menu_showphoto (KBNODE keyblock)
5512 : {
5513 : KBNODE node;
5514 0 : int select_all = !count_selected_uids (keyblock);
5515 0 : int count = 0;
5516 0 : PKT_public_key *pk = NULL;
5517 :
5518 : /* Look for the public key first. We have to be really, really,
5519 : explicit as to which photo this is, and what key it is a UID on
5520 : since people may want to sign it. */
5521 :
5522 0 : for (node = keyblock; node; node = node->next)
5523 : {
5524 0 : if (node->pkt->pkttype == PKT_PUBLIC_KEY)
5525 0 : pk = node->pkt->pkt.public_key;
5526 0 : else if (node->pkt->pkttype == PKT_USER_ID)
5527 : {
5528 0 : PKT_user_id *uid = node->pkt->pkt.user_id;
5529 0 : count++;
5530 :
5531 0 : if ((select_all || (node->flag & NODFLG_SELUID)) &&
5532 0 : uid->attribs != NULL)
5533 : {
5534 : int i;
5535 :
5536 0 : for (i = 0; i < uid->numattribs; i++)
5537 : {
5538 : byte type;
5539 : u32 size;
5540 :
5541 0 : if (uid->attribs[i].type == ATTRIB_IMAGE &&
5542 0 : parse_image_header (&uid->attribs[i], &type, &size))
5543 : {
5544 0 : tty_printf (_("Displaying %s photo ID of size %ld for "
5545 : "key %s (uid %d)\n"),
5546 : image_type_to_string (type, 1),
5547 : (ulong) size, keystr_from_pk (pk), count);
5548 0 : show_photos (&uid->attribs[i], 1, pk, uid);
5549 : }
5550 : }
5551 : }
5552 : }
5553 : }
5554 0 : }
|