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