Fix bug#1003.
[gnupg.git] / g10 / keyedit.c
blobb0d59f66a19a7b1d273277cc23376c9c9e5fbe8b
1 /* keyedit.c - keyedit stuff
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 * 2008 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <ctype.h>
28 #ifdef HAVE_LIBREADLINE
29 #define GNUPG_LIBREADLINE_H_INCLUDED
30 #include <readline/readline.h>
31 #endif
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"
49 static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
50 static void show_names(KBNODE keyblock,PKT_public_key *pk,
51 unsigned int flag,int with_prefs);
52 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
53 int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
54 static void show_key_and_fingerprint( KBNODE keyblock );
55 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock,
56 int photo, const char *photo_name );
57 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
58 static int menu_delsig( KBNODE pub_keyblock );
59 static int menu_clean(KBNODE keyblock,int self_only);
60 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
61 static int menu_addrevoker( KBNODE pub_keyblock,
62 KBNODE sec_keyblock, int sensitive );
63 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
64 static int menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock);
65 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
66 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
67 static int menu_set_keyserver_url (const char *url,
68 KBNODE pub_keyblock, KBNODE sec_keyblock );
69 static int menu_set_notation(const char *string,
70 KBNODE pub_keyblock,KBNODE sec_keyblock);
71 static int menu_select_uid( KBNODE keyblock, int idx );
72 static int menu_select_uid_namehash( KBNODE keyblock, const char *namehash );
73 static int menu_select_key( KBNODE keyblock, int idx );
74 static int count_uids( KBNODE keyblock );
75 static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
76 static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
77 static int count_selected_uids( KBNODE keyblock );
78 static int real_uids_left( KBNODE keyblock );
79 static int count_selected_keys( KBNODE keyblock );
80 static int menu_revsig( KBNODE keyblock );
81 static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
82 static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
83 static int menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
84 static int enable_disable_key( KBNODE keyblock, int disable );
85 static void menu_showphoto( KBNODE keyblock );
87 static int update_trust=0;
89 #define CONTROL_D ('D' - 'A' + 1)
91 #define NODFLG_BADSIG (1<<0) /* bad signature */
92 #define NODFLG_NOKEY (1<<1) /* no public key */
93 #define NODFLG_SIGERR (1<<2) /* other sig error */
95 #define NODFLG_MARK_A (1<<4) /* temporary mark */
96 #define NODFLG_DELSIG (1<<5) /* to be deleted */
98 #define NODFLG_SELUID (1<<8) /* indicate the selected userid */
99 #define NODFLG_SELKEY (1<<9) /* indicate the selected key */
100 #define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
102 struct sign_attrib {
103 int non_exportable,non_revocable;
104 struct revocation_reason_info *reason;
105 byte trust_depth,trust_value;
106 char *trust_regexp;
110 #ifdef ENABLE_CARD_SUPPORT
111 /* Given a node SEC_NODE with a secret key or subkey, locate the
112 corresponding public key from pub_keyblock. */
113 static PKT_public_key *
114 find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
116 KBNODE node = pub_keyblock;
117 PKT_secret_key *sk;
118 PKT_public_key *pk;
120 if (sec_node->pkt->pkttype == PKT_SECRET_KEY
121 && node->pkt->pkttype == PKT_PUBLIC_KEY)
122 return node->pkt->pkt.public_key;
123 if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
124 return NULL;
125 sk = sec_node->pkt->pkt.secret_key;
126 for (; node; node = node->next)
127 if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
129 pk = node->pkt->pkt.public_key;
130 if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
131 return pk;
134 return NULL;
136 #endif /* ENABLE_CARD_SUPPORT */
139 /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
140 code in keylist.c. */
141 static int
142 print_and_check_one_sig_colon( KBNODE keyblock, KBNODE node,
143 int *inv_sigs, int *no_key, int *oth_err,
144 int *is_selfsig, int print_without_key )
146 PKT_signature *sig = node->pkt->pkt.signature;
147 int rc, sigrc;
149 /* TODO: Make sure a cached sig record here still has the pk that
150 issued it. See also keylist.c:list_keyblock_print */
152 switch((rc=check_key_signature(keyblock,node,is_selfsig)))
154 case 0:
155 node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
156 sigrc = '!';
157 break;
158 case G10ERR_BAD_SIGN:
159 node->flag = NODFLG_BADSIG;
160 sigrc = '-';
161 if( inv_sigs )
162 ++*inv_sigs;
163 break;
164 case G10ERR_NO_PUBKEY:
165 case G10ERR_UNU_PUBKEY:
166 node->flag = NODFLG_NOKEY;
167 sigrc = '?';
168 if( no_key )
169 ++*no_key;
170 break;
171 default:
172 node->flag = NODFLG_SIGERR;
173 sigrc = '%';
174 if( oth_err )
175 ++*oth_err;
176 break;
179 if( sigrc != '?' || print_without_key )
181 printf("sig:%c::%d:%08lX%08lX:%lu:%lu:",
182 sigrc,sig->pubkey_algo,(ulong)sig->keyid[0],(ulong)sig->keyid[1],
183 (ulong)sig->timestamp,(ulong)sig->expiredate);
185 if(sig->trust_depth || sig->trust_value)
186 printf("%d %d",sig->trust_depth,sig->trust_value);
188 printf(":");
190 if(sig->trust_regexp)
191 print_string(stdout,sig->trust_regexp,strlen(sig->trust_regexp),':');
193 printf("::%02x%c\n",sig->sig_class,sig->flags.exportable?'x':'l');
195 if(opt.show_subpackets)
196 print_subpackets_colon(sig);
199 return (sigrc == '!');
203 /****************
204 * Print information about a signature, check it and return true
205 * if the signature is okay. NODE must be a signature packet.
207 static int
208 print_and_check_one_sig( KBNODE keyblock, KBNODE node,
209 int *inv_sigs, int *no_key, int *oth_err,
210 int *is_selfsig, int print_without_key )
212 PKT_signature *sig = node->pkt->pkt.signature;
213 int rc, sigrc;
214 int is_rev = sig->sig_class == 0x30;
216 /* TODO: Make sure a cached sig record here still has the pk that
217 issued it. See also keylist.c:list_keyblock_print */
219 switch( (rc = check_key_signature( keyblock, node, is_selfsig)) ) {
220 case 0:
221 node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
222 sigrc = '!';
223 break;
224 case G10ERR_BAD_SIGN:
225 node->flag = NODFLG_BADSIG;
226 sigrc = '-';
227 if( inv_sigs )
228 ++*inv_sigs;
229 break;
230 case G10ERR_NO_PUBKEY:
231 case G10ERR_UNU_PUBKEY:
232 node->flag = NODFLG_NOKEY;
233 sigrc = '?';
234 if( no_key )
235 ++*no_key;
236 break;
237 default:
238 node->flag = NODFLG_SIGERR;
239 sigrc = '%';
240 if( oth_err )
241 ++*oth_err;
242 break;
244 if( sigrc != '?' || print_without_key ) {
245 tty_printf("%s%c%c %c%c%c%c%c%c %s %s",
246 is_rev? "rev":"sig",sigrc,
247 (sig->sig_class-0x10>0 &&
248 sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
249 sig->flags.exportable?' ':'L',
250 sig->flags.revocable?' ':'R',
251 sig->flags.policy_url?'P':' ',
252 sig->flags.notation?'N':' ',
253 sig->flags.expired?'X':' ',
254 (sig->trust_depth>9)?'T':
255 (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
256 keystr(sig->keyid),datestr_from_sig(sig));
257 if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
258 tty_printf(" %s",expirestr_from_sig(sig));
259 tty_printf(" ");
260 if( sigrc == '%' )
261 tty_printf("[%s] ", g10_errstr(rc) );
262 else if( sigrc == '?' )
264 else if( *is_selfsig ) {
265 tty_printf( is_rev? _("[revocation]")
266 : _("[self-signature]") );
268 else
270 size_t n;
271 char *p = get_user_id( sig->keyid, &n );
272 tty_print_utf8_string2(p, n, opt.screen_columns-keystrlen()-26-
273 ((opt.list_options&LIST_SHOW_SIG_EXPIRE)?11:0));
274 xfree(p);
276 tty_printf("\n");
278 if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY_URLS))
279 show_policy_url(sig,3,0);
281 if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATIONS))
282 show_notation(sig,3,0,
283 ((opt.list_options&LIST_SHOW_STD_NOTATIONS)?1:0)+
284 ((opt.list_options&LIST_SHOW_USER_NOTATIONS)?2:0));
286 if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER_URLS))
287 show_keyserver_url(sig,3,0);
290 return (sigrc == '!');
295 /****************
296 * Check the keysigs and set the flags to indicate errors.
297 * Returns true if error found.
299 static int
300 check_all_keysigs( KBNODE keyblock, int only_selected )
302 KBNODE kbctx;
303 KBNODE node;
304 int inv_sigs = 0;
305 int no_key = 0;
306 int oth_err = 0;
307 int has_selfsig = 0;
308 int mis_selfsig = 0;
309 int selected = !only_selected;
310 int anyuid = 0;
312 for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
313 if( node->pkt->pkttype == PKT_USER_ID ) {
314 PKT_user_id *uid = node->pkt->pkt.user_id;
316 if( only_selected )
317 selected = (node->flag & NODFLG_SELUID);
318 if( selected ) {
319 tty_printf("uid ");
320 tty_print_utf8_string( uid->name, uid->len );
321 tty_printf("\n");
322 if( anyuid && !has_selfsig )
323 mis_selfsig++;
324 has_selfsig = 0;
325 anyuid = 1;
328 else if( selected && node->pkt->pkttype == PKT_SIGNATURE
329 && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
330 || node->pkt->pkt.signature->sig_class == 0x30 ) ) {
331 int selfsig;
333 if( print_and_check_one_sig( keyblock, node, &inv_sigs,
334 &no_key, &oth_err, &selfsig, 0 ) ) {
335 if( selfsig )
336 has_selfsig = 1;
338 /* Hmmm: should we update the trustdb here? */
341 if( !has_selfsig )
342 mis_selfsig++;
343 if( inv_sigs == 1 )
344 tty_printf(_("1 bad signature\n") );
345 else if( inv_sigs )
346 tty_printf(_("%d bad signatures\n"), inv_sigs );
347 if( no_key == 1 )
348 tty_printf(_("1 signature not checked due to a missing key\n") );
349 else if( no_key )
350 tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
351 if( oth_err == 1 )
352 tty_printf(_("1 signature not checked due to an error\n") );
353 else if( oth_err )
354 tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
355 if( mis_selfsig == 1 )
356 tty_printf(_("1 user ID without valid self-signature detected\n"));
357 else if( mis_selfsig )
358 tty_printf(_("%d user IDs without valid self-signatures detected\n"),
359 mis_selfsig);
361 return inv_sigs || no_key || oth_err || mis_selfsig;
365 static int
366 sign_mk_attrib( PKT_signature *sig, void *opaque )
368 struct sign_attrib *attrib = opaque;
369 byte buf[8];
371 if( attrib->non_exportable ) {
372 buf[0] = 0; /* not exportable */
373 build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
376 if( attrib->non_revocable ) {
377 buf[0] = 0; /* not revocable */
378 build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
381 if( attrib->reason )
382 revocation_reason_build_cb( sig, attrib->reason );
384 if(attrib->trust_depth)
386 /* Not critical. If someone doesn't understand trust sigs,
387 this can still be a valid regular signature. */
388 buf[0] = attrib->trust_depth;
389 buf[1] = attrib->trust_value;
390 build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
392 /* Critical. If someone doesn't understands regexps, this
393 whole sig should be invalid. Note the +1 for the length -
394 regexps are null terminated. */
395 if(attrib->trust_regexp)
396 build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
397 attrib->trust_regexp,
398 strlen(attrib->trust_regexp)+1);
401 return 0;
404 static void
405 trustsig_prompt(byte *trust_value,byte *trust_depth,char **regexp)
407 char *p;
409 *trust_value=0;
410 *trust_depth=0;
411 *regexp=NULL;
413 /* Same string as pkclist.c:do_edit_ownertrust */
414 tty_printf(_("Please decide how far you trust this user to correctly verify"
415 " other users' keys\n(by looking at passports, checking"
416 " fingerprints from different sources, etc.)\n"));
417 tty_printf("\n");
418 tty_printf (_(" %d = I trust marginally\n"), 1);
419 tty_printf (_(" %d = I trust fully\n"), 2);
420 tty_printf("\n");
422 while(*trust_value==0)
424 p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
425 trim_spaces(p);
426 cpr_kill_prompt();
427 /* 60 and 120 are as per RFC2440 */
428 if(p[0]=='1' && !p[1])
429 *trust_value=60;
430 else if(p[0]=='2' && !p[1])
431 *trust_value=120;
432 xfree(p);
435 tty_printf("\n");
437 tty_printf(_(
438 "Please enter the depth of this trust signature.\n"
439 "A depth greater than 1 allows the key you are signing to make\n"
440 "trust signatures on your behalf.\n"));
441 tty_printf("\n");
443 while(*trust_depth==0)
445 p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
446 trim_spaces(p);
447 cpr_kill_prompt();
448 *trust_depth=atoi(p);
449 xfree(p);
452 tty_printf("\n");
454 tty_printf(_("Please enter a domain to restrict this signature, "
455 "or enter for none.\n"));
457 tty_printf("\n");
459 p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
460 trim_spaces(p);
461 cpr_kill_prompt();
463 if(strlen(p)>0)
465 char *q=p;
466 int regexplen=100,ind;
468 *regexp=xmalloc(regexplen);
470 /* Now mangle the domain the user entered into a regexp. To do
471 this, \-escape everything that isn't alphanumeric, and attach
472 "<[^>]+[@.]" to the front, and ">$" to the end. */
474 strcpy(*regexp,"<[^>]+[@.]");
475 ind=strlen(*regexp);
477 while(*q)
479 if(!((*q>='A' && *q<='Z')
480 || (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
481 (*regexp)[ind++]='\\';
483 (*regexp)[ind++]=*q;
485 if((regexplen-ind)<3)
487 regexplen+=100;
488 *regexp=xrealloc(*regexp,regexplen);
491 q++;
494 (*regexp)[ind]='\0';
495 strcat(*regexp,">$");
498 xfree(p);
499 tty_printf("\n");
502 /****************
503 * Loop over all locusr and and sign the uids after asking.
504 * If no user id is marked, all user ids will be signed;
505 * if some user_ids are marked those will be signed.
507 static int
508 sign_uids( KBNODE keyblock, strlist_t locusr, int *ret_modified,
509 int local, int nonrevocable, int trust, int interactive )
511 int rc = 0;
512 SK_LIST sk_list = NULL;
513 SK_LIST sk_rover = NULL;
514 PKT_secret_key *sk = NULL;
515 KBNODE node, uidnode;
516 PKT_public_key *primary_pk=NULL;
517 int select_all = !count_selected_uids(keyblock) || interactive;
518 int all_v3=1;
520 /* Are there any non-v3 sigs on this key already? */
521 if(PGP2)
522 for(node=keyblock;node;node=node->next)
523 if(node->pkt->pkttype==PKT_SIGNATURE &&
524 node->pkt->pkt.signature->version>3)
526 all_v3=0;
527 break;
530 /* build a list of all signators.
532 * We use the CERT flag to request the primary which must always
533 * be one which is capable of signing keys. I can't see a reason
534 * why to sign keys using a subkey. Implementation of USAGE_CERT
535 * is just a hack in getkey.c and does not mean that a subkey
536 * marked as certification capable will be used. */
537 rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_CERT);
538 if( rc )
539 goto leave;
541 /* loop over all signators */
542 for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
543 u32 sk_keyid[2],pk_keyid[2];
544 char *p,*trust_regexp=NULL;
545 int force_v4=0,class=0,selfsig=0;
546 u32 duration=0,timestamp=0;
547 byte trust_depth=0,trust_value=0;
549 if(local || nonrevocable || trust ||
550 opt.cert_policy_url || opt.cert_notations)
551 force_v4=1;
553 /* we have to use a copy of the sk, because make_keysig_packet
554 * may remove the protection from sk and if we did other
555 * changes to the secret key, we would save the unprotected
556 * version */
557 if( sk )
558 free_secret_key(sk);
559 sk = copy_secret_key( NULL, sk_rover->sk );
560 keyid_from_sk( sk, sk_keyid );
561 /* set mark A for all selected user ids */
562 for( node=keyblock; node; node = node->next ) {
563 if( select_all || (node->flag & NODFLG_SELUID) )
564 node->flag |= NODFLG_MARK_A;
565 else
566 node->flag &= ~NODFLG_MARK_A;
568 /* reset mark for uids which are already signed */
569 uidnode = NULL;
570 for( node=keyblock; node; node = node->next ) {
571 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
572 primary_pk=node->pkt->pkt.public_key;
573 keyid_from_pk( primary_pk, pk_keyid );
575 /* Is this a self-sig? */
576 if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
578 selfsig=1;
579 /* Do not force a v4 sig here, otherwise it would
580 be difficult to remake a v3 selfsig. If this
581 is a v3->v4 promotion case, then we set
582 force_v4 later anyway. */
583 force_v4=0;
586 else if( node->pkt->pkttype == PKT_USER_ID )
588 uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
589 if(uidnode)
591 int yesreally=0;
592 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
593 uidnode->pkt->pkt.user_id->len,
596 if(uidnode->pkt->pkt.user_id->is_revoked)
598 tty_printf(_("User ID \"%s\" is revoked."),user);
600 if(selfsig)
601 tty_printf("\n");
602 else if(opt.expert)
604 tty_printf("\n");
605 /* No, so remove the mark and continue */
606 if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
607 _("Are you sure you "
608 "still want to sign "
609 "it? (y/N) ")))
611 uidnode->flag &= ~NODFLG_MARK_A;
612 uidnode=NULL;
614 else if(interactive)
615 yesreally=1;
617 else
619 uidnode->flag &= ~NODFLG_MARK_A;
620 uidnode=NULL;
621 tty_printf(_(" Unable to sign.\n"));
624 else if(uidnode->pkt->pkt.user_id->is_expired)
626 tty_printf(_("User ID \"%s\" is expired."),user);
628 if(selfsig)
629 tty_printf("\n");
630 else if(opt.expert)
632 tty_printf("\n");
633 /* No, so remove the mark and continue */
634 if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
635 _("Are you sure you "
636 "still want to sign "
637 "it? (y/N) ")))
639 uidnode->flag &= ~NODFLG_MARK_A;
640 uidnode=NULL;
642 else if(interactive)
643 yesreally=1;
645 else
647 uidnode->flag &= ~NODFLG_MARK_A;
648 uidnode=NULL;
649 tty_printf(_(" Unable to sign.\n"));
652 else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
654 tty_printf(_("User ID \"%s\" is not self-signed."),
655 user);
657 if(opt.expert)
659 tty_printf("\n");
660 /* No, so remove the mark and continue */
661 if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
662 _("Are you sure you "
663 "still want to sign "
664 "it? (y/N) ")))
666 uidnode->flag &= ~NODFLG_MARK_A;
667 uidnode=NULL;
669 else if(interactive)
670 yesreally=1;
672 else
674 uidnode->flag &= ~NODFLG_MARK_A;
675 uidnode=NULL;
676 tty_printf(_(" Unable to sign.\n"));
680 if(uidnode && interactive && !yesreally)
682 tty_printf(_("User ID \"%s\" is signable. "),user);
683 if(!cpr_get_answer_is_yes("sign_uid.sign_okay",
684 _("Sign it? (y/N) ")))
686 uidnode->flag &= ~NODFLG_MARK_A;
687 uidnode=NULL;
691 xfree(user);
694 else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
695 && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
696 if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
697 && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
698 char buf[50];
699 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
700 uidnode->pkt->pkt.user_id->len,
703 /* It's a v3 self-sig. Make it into a v4 self-sig? */
704 if(node->pkt->pkt.signature->version<4 && selfsig)
706 tty_printf(_("The self-signature on \"%s\"\n"
707 "is a PGP 2.x-style signature.\n"),user);
709 /* Note that the regular PGP2 warning below
710 still applies if there are no v4 sigs on
711 this key at all. */
713 if(opt.expert)
714 if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
715 _("Do you want to promote "
716 "it to an OpenPGP self-"
717 "signature? (y/N) ")))
719 force_v4=1;
720 node->flag|=NODFLG_DELSIG;
721 xfree(user);
722 continue;
726 /* Is the current signature expired? */
727 if(node->pkt->pkt.signature->flags.expired)
729 tty_printf(_("Your current signature on \"%s\"\n"
730 "has expired.\n"),user);
732 if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
733 _("Do you want to issue a "
734 "new signature to replace "
735 "the expired one? (y/N) ")))
737 /* Mark these for later deletion. We
738 don't want to delete them here, just in
739 case the replacement signature doesn't
740 happen for some reason. We only delete
741 these after the replacement is already
742 in place. */
744 node->flag|=NODFLG_DELSIG;
745 xfree(user);
746 continue;
750 if(!node->pkt->pkt.signature->flags.exportable && !local)
752 /* It's a local sig, and we want to make a
753 exportable sig. */
754 tty_printf(_("Your current signature on \"%s\"\n"
755 "is a local signature.\n"),user);
757 if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
758 _("Do you want to promote "
759 "it to a full exportable "
760 "signature? (y/N) ")))
762 /* Mark these for later deletion. We
763 don't want to delete them here, just in
764 case the replacement signature doesn't
765 happen for some reason. We only delete
766 these after the replacement is already
767 in place. */
769 node->flag|=NODFLG_DELSIG;
770 xfree(user);
771 continue;
775 /* Fixme: see whether there is a revocation in which
776 * case we should allow to sign it again. */
777 if (!node->pkt->pkt.signature->flags.exportable && local)
778 tty_printf(_(
779 "\"%s\" was already locally signed by key %s\n"),
780 user,keystr_from_sk(sk));
781 else
782 tty_printf(_("\"%s\" was already signed by key %s\n"),
783 user,keystr_from_sk(sk));
785 if(opt.expert
786 && cpr_get_answer_is_yes("sign_uid.dupe_okay",
787 _("Do you want to sign it "
788 "again anyway? (y/N) ")))
790 /* Don't delete the old sig here since this is
791 an --expert thing. */
792 xfree(user);
793 continue;
796 sprintf (buf, "%08lX%08lX",
797 (ulong)sk->keyid[0], (ulong)sk->keyid[1] );
798 write_status_text (STATUS_ALREADY_SIGNED, buf);
799 uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
801 xfree(user);
806 /* check whether any uids are left for signing */
807 if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) )
809 tty_printf(_("Nothing to sign with key %s\n"),keystr_from_sk(sk));
810 continue;
813 /* Ask whether we really should sign these user id(s) */
814 tty_printf("\n");
815 show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
816 tty_printf("\n");
818 if(primary_pk->expiredate && !selfsig)
820 u32 now=make_timestamp();
822 if(primary_pk->expiredate<=now)
824 tty_printf(_("This key has expired!"));
826 if(opt.expert)
828 tty_printf(" ");
829 if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
830 _("Are you sure you still "
831 "want to sign it? (y/N) ")))
832 continue;
834 else
836 tty_printf(_(" Unable to sign.\n"));
837 continue;
840 else
842 tty_printf(_("This key is due to expire on %s.\n"),
843 expirestr_from_pk(primary_pk));
845 if(opt.ask_cert_expire)
847 char *answer=cpr_get("sign_uid.expire",
848 _("Do you want your signature to "
849 "expire at the same time? (Y/n) "));
850 if(answer_is_yes_no_default(answer,1))
852 /* This fixes the signature timestamp we're
853 going to make as now. This is so the
854 expiration date is exactly correct, and not
855 a few seconds off (due to the time it takes
856 to answer the questions, enter the
857 passphrase, etc). */
858 timestamp=now;
859 duration=primary_pk->expiredate-now;
860 force_v4=1;
863 cpr_kill_prompt();
864 xfree(answer);
869 /* Only ask for duration if we haven't already set it to match
870 the expiration of the pk */
871 if(!duration && !selfsig)
873 if(opt.ask_cert_expire)
874 duration=ask_expire_interval(1,opt.def_cert_expire);
875 else
876 duration=parse_expire_string(opt.def_cert_expire);
879 if(duration)
880 force_v4=1;
882 /* Is --pgp2 on, it's a v3 key, all the sigs on the key are
883 currently v3 and we're about to sign it with a v4 sig? If
884 so, danger! */
885 if(PGP2 && all_v3 &&
886 (sk->version>3 || force_v4) && primary_pk->version<=3)
888 tty_printf(_("You may not make an OpenPGP signature on a "
889 "PGP 2.x key while in --pgp2 mode.\n"));
890 tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
892 if(opt.expert)
894 if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
895 _("Are you sure you still "
896 "want to sign it? (y/N) ")))
897 continue;
899 all_v3=0;
901 else
902 continue;
905 if(selfsig)
907 else
909 if(opt.batch || !opt.ask_cert_level)
910 class=0x10+opt.def_cert_level;
911 else
913 char *answer;
915 tty_printf(_("How carefully have you verified the key you are "
916 "about to sign actually belongs\nto the person "
917 "named above? If you don't know what to "
918 "answer, enter \"0\".\n"));
919 tty_printf("\n");
920 tty_printf(_(" (0) I will not answer.%s\n"),
921 opt.def_cert_level==0?" (default)":"");
922 tty_printf(_(" (1) I have not checked at all.%s\n"),
923 opt.def_cert_level==1?" (default)":"");
924 tty_printf(_(" (2) I have done casual checking.%s\n"),
925 opt.def_cert_level==2?" (default)":"");
926 tty_printf(_(" (3) I have done very careful checking.%s\n"),
927 opt.def_cert_level==3?" (default)":"");
928 tty_printf("\n");
930 while(class==0)
932 answer = cpr_get("sign_uid.class",_("Your selection? "
933 "(enter `?' for more information): "));
934 if(answer[0]=='\0')
935 class=0x10+opt.def_cert_level; /* Default */
936 else if(ascii_strcasecmp(answer,"0")==0)
937 class=0x10; /* Generic */
938 else if(ascii_strcasecmp(answer,"1")==0)
939 class=0x11; /* Persona */
940 else if(ascii_strcasecmp(answer,"2")==0)
941 class=0x12; /* Casual */
942 else if(ascii_strcasecmp(answer,"3")==0)
943 class=0x13; /* Positive */
944 else
945 tty_printf(_("Invalid selection.\n"));
947 xfree(answer);
951 if(trust)
952 trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
955 p=get_user_id_native(sk_keyid);
956 tty_printf(_("Are you sure that you want to sign this key with your\n"
957 "key \"%s\" (%s)\n"),p,keystr_from_sk(sk));
958 xfree(p);
960 if(selfsig)
962 tty_printf("\n");
963 tty_printf(_("This will be a self-signature.\n"));
965 if( local )
967 tty_printf("\n");
968 tty_printf(
969 _("WARNING: the signature will not be marked "
970 "as non-exportable.\n"));
973 if( nonrevocable )
975 tty_printf("\n");
976 tty_printf(
977 _("WARNING: the signature will not be marked "
978 "as non-revocable.\n"));
981 else
983 if( local )
985 tty_printf("\n");
986 tty_printf(
987 _("The signature will be marked as non-exportable.\n"));
990 if( nonrevocable )
992 tty_printf("\n");
993 tty_printf(
994 _("The signature will be marked as non-revocable.\n"));
997 switch(class)
999 case 0x11:
1000 tty_printf("\n");
1001 tty_printf(_("I have not checked this key at all.\n"));
1002 break;
1004 case 0x12:
1005 tty_printf("\n");
1006 tty_printf(_("I have checked this key casually.\n"));
1007 break;
1009 case 0x13:
1010 tty_printf("\n");
1011 tty_printf(_("I have checked this key very carefully.\n"));
1012 break;
1016 tty_printf("\n");
1018 if( opt.batch && opt.answer_yes )
1020 else if( !cpr_get_answer_is_yes("sign_uid.okay",
1021 _("Really sign? (y/N) ")) )
1022 continue;
1024 /* now we can sign the user ids */
1025 reloop: /* (must use this, because we are modifing the list) */
1026 primary_pk = NULL;
1027 for( node=keyblock; node; node = node->next ) {
1028 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
1029 primary_pk = node->pkt->pkt.public_key;
1030 else if( node->pkt->pkttype == PKT_USER_ID
1031 && (node->flag & NODFLG_MARK_A) ) {
1032 PACKET *pkt;
1033 PKT_signature *sig;
1034 struct sign_attrib attrib;
1036 assert( primary_pk );
1037 memset( &attrib, 0, sizeof attrib );
1038 attrib.non_exportable = local;
1039 attrib.non_revocable = nonrevocable;
1040 attrib.trust_depth = trust_depth;
1041 attrib.trust_value = trust_value;
1042 attrib.trust_regexp = trust_regexp;
1043 node->flag &= ~NODFLG_MARK_A;
1045 /* we force creation of a v4 signature for local
1046 * signatures, otherwise we would not generate the
1047 * subpacket with v3 keys and the signature becomes
1048 * exportable */
1050 if(selfsig)
1051 rc = make_keysig_packet( &sig, primary_pk,
1052 node->pkt->pkt.user_id,
1053 NULL,
1055 0x13, 0, force_v4?4:0, 0, 0,
1056 keygen_add_std_prefs, primary_pk);
1057 else
1058 rc = make_keysig_packet( &sig, primary_pk,
1059 node->pkt->pkt.user_id,
1060 NULL,
1062 class, 0, force_v4?4:0,
1063 timestamp, duration,
1064 sign_mk_attrib, &attrib );
1065 if( rc ) {
1066 log_error(_("signing failed: %s\n"), g10_errstr(rc));
1067 goto leave;
1070 *ret_modified = 1; /* we changed the keyblock */
1071 update_trust = 1;
1073 pkt = xmalloc_clear( sizeof *pkt );
1074 pkt->pkttype = PKT_SIGNATURE;
1075 pkt->pkt.signature = sig;
1076 insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
1077 goto reloop;
1081 /* Delete any sigs that got promoted */
1082 for( node=keyblock; node; node = node->next )
1083 if( node->flag & NODFLG_DELSIG)
1084 delete_kbnode(node);
1085 } /* end loop over signators */
1087 leave:
1088 release_sk_list( sk_list );
1089 if( sk )
1090 free_secret_key(sk);
1091 return rc;
1096 /****************
1097 * Change the passphrase of the primary and all secondary keys.
1098 * We use only one passphrase for all keys.
1100 static int
1101 change_passphrase( KBNODE keyblock )
1103 int rc = 0;
1104 int changed=0;
1105 KBNODE node;
1106 PKT_secret_key *sk;
1107 char *passphrase = NULL;
1108 int no_primary_secrets = 0;
1109 int any;
1111 node = find_kbnode( keyblock, PKT_SECRET_KEY );
1112 if( !node ) {
1113 log_error("Oops; secret key not found anymore!\n");
1114 goto leave;
1116 sk = node->pkt->pkt.secret_key;
1118 for (any = 0, node=keyblock; node; node = node->next) {
1119 if (node->pkt->pkttype == PKT_SECRET_KEY
1120 || node->pkt->pkttype == PKT_SECRET_SUBKEY) {
1121 PKT_secret_key *tmpsk = node->pkt->pkt.secret_key;
1122 if (!(tmpsk->is_protected
1123 && (tmpsk->protect.s2k.mode == 1001
1124 || tmpsk->protect.s2k.mode == 1002))) {
1125 any = 1;
1126 break;
1130 if (!any) {
1131 tty_printf (_("Key has only stub or on-card key items - "
1132 "no passphrase to change.\n"));
1133 goto leave;
1136 /* See how to handle this key. */
1137 switch( is_secret_key_protected( sk ) ) {
1138 case -1:
1139 rc = G10ERR_PUBKEY_ALGO;
1140 break;
1141 case 0:
1142 tty_printf(_("This key is not protected.\n"));
1143 break;
1144 default:
1145 if( sk->protect.s2k.mode == 1001 ) {
1146 tty_printf(_("Secret parts of primary key are not available.\n"));
1147 no_primary_secrets = 1;
1149 else if( sk->protect.s2k.mode == 1002 ) {
1150 tty_printf(_("Secret parts of primary key are stored on-card.\n"));
1151 no_primary_secrets = 1;
1153 else {
1154 u32 keyid[2];
1156 tty_printf(_("Key is protected.\n"));
1158 /* Clear the passphrase cache so that the user is required
1159 to enter the old passphrase. */
1160 keyid_from_sk (sk, keyid);
1161 passphrase_clear_cache (keyid, NULL, 0);
1163 rc = check_secret_key( sk, 0 );
1164 if( !rc )
1165 passphrase = get_last_passphrase();
1167 break;
1170 /* Unprotect all subkeys (use the supplied passphrase or ask)*/
1171 for(node=keyblock; !rc && node; node = node->next ) {
1172 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1173 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1174 if ( !(subsk->is_protected
1175 && (subsk->protect.s2k.mode == 1001
1176 || subsk->protect.s2k.mode == 1002))) {
1177 set_next_passphrase( passphrase );
1178 rc = check_secret_key( subsk, 0 );
1179 if( !rc && !passphrase )
1180 passphrase = get_last_passphrase();
1185 if( rc )
1186 tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
1187 else {
1188 DEK *dek = NULL;
1189 STRING2KEY *s2k = xmalloc_secure( sizeof *s2k );
1190 const char *errtext = NULL;
1192 tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
1194 set_next_passphrase( NULL );
1195 for(;;) {
1196 int canceled;
1198 s2k->mode = opt.s2k_mode;
1199 s2k->hash_algo = S2K_DIGEST_ALGO;
1200 dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
1201 s2k, 2, errtext, &canceled);
1202 if (!dek && canceled) {
1203 rc = GPG_ERR_CANCELED;
1204 break;
1206 else if( !dek ) {
1207 errtext = N_("passphrase not correctly repeated; try again");
1208 tty_printf ("%s.\n", _(errtext));
1210 else if( !dek->keylen ) {
1211 rc = 0;
1212 tty_printf(_( "You don't want a passphrase -"
1213 " this is probably a *bad* idea!\n\n"));
1214 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
1215 _("Do you really want to do this? (y/N) ")))
1217 changed++;
1218 break;
1221 else { /* okay */
1222 rc = 0;
1223 if( !no_primary_secrets ) {
1224 sk->protect.algo = dek->algo;
1225 sk->protect.s2k = *s2k;
1226 rc = protect_secret_key( sk, dek );
1228 for(node=keyblock; !rc && node; node = node->next ) {
1229 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1230 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1231 if ( !(subsk->is_protected
1232 && (subsk->protect.s2k.mode == 1001
1233 || subsk->protect.s2k.mode == 1002))) {
1234 subsk->protect.algo = dek->algo;
1235 subsk->protect.s2k = *s2k;
1236 rc = protect_secret_key( subsk, dek );
1240 if( rc )
1241 log_error("protect_secret_key failed: %s\n",
1242 g10_errstr(rc) );
1243 else
1245 u32 keyid[2];
1247 /* Clear the cahce again so that the user is
1248 required to enter the new passphrase at the
1249 next operation. */
1250 keyid_from_sk (sk, keyid);
1251 passphrase_clear_cache (keyid, NULL, 0);
1253 changed++;
1255 break;
1258 xfree(s2k);
1259 xfree(dek);
1262 leave:
1263 xfree( passphrase );
1264 set_next_passphrase( NULL );
1265 return changed && !rc;
1269 /****************
1270 * There are some keys out (due to a bug in gnupg), where the sequence
1271 * of the packets is wrong. This function fixes that.
1272 * Returns: true if the keyblock has been fixed.
1274 * Note: This function does not work if there is more than one user ID.
1276 static int
1277 fix_keyblock( KBNODE keyblock )
1279 KBNODE node, last, subkey;
1280 int fixed=0;
1282 /* locate key signatures of class 0x10..0x13 behind sub key packets */
1283 for( subkey=last=NULL, node = keyblock; node;
1284 last=node, node = node->next ) {
1285 switch( node->pkt->pkttype ) {
1286 case PKT_PUBLIC_SUBKEY:
1287 case PKT_SECRET_SUBKEY:
1288 if( !subkey )
1289 subkey = last; /* actually it is the one before the subkey */
1290 break;
1291 case PKT_SIGNATURE:
1292 if( subkey ) {
1293 PKT_signature *sig = node->pkt->pkt.signature;
1294 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1295 log_info(_(
1296 "moving a key signature to the correct place\n"));
1297 last->next = node->next;
1298 node->next = subkey->next;
1299 subkey->next = node;
1300 node = last;
1301 fixed=1;
1304 break;
1305 default: break;
1309 return fixed;
1312 static int
1313 parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
1315 const char *p=str;
1317 while(*p)
1319 if(ascii_strncasecmp(p,"l",1)==0)
1321 *localsig=1;
1322 p++;
1324 else if(ascii_strncasecmp(p,"nr",2)==0)
1326 *nonrevokesig=1;
1327 p+=2;
1329 else if(ascii_strncasecmp(p,"t",1)==0)
1331 *trustsig=1;
1332 p++;
1334 else
1335 return 0;
1338 return 1;
1342 /****************
1343 * Menu driven key editor. If seckey_check is true, then a secret key
1344 * that matches username will be looked for. If it is false, not all
1345 * commands will be available.
1347 * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1350 /* Need an SK for this command */
1351 #define KEYEDIT_NEED_SK 1
1352 /* Cannot be viewing the SK for this command */
1353 #define KEYEDIT_NOT_SK 2
1354 /* Must be viewing the SK for this command */
1355 #define KEYEDIT_ONLY_SK 4
1356 /* Match the tail of the string */
1357 #define KEYEDIT_TAIL_MATCH 8
1359 enum cmdids
1361 cmdNONE = 0,
1362 cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1363 cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
1364 cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
1365 cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
1366 cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
1367 cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
1368 cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN,
1369 cmdMINIMIZE, cmdNOP
1372 static struct
1374 const char *name;
1375 enum cmdids id;
1376 int flags;
1377 const char *desc;
1378 } cmds[] =
1380 { "quit" , cmdQUIT , 0, N_("quit this menu") },
1381 { "q" , cmdQUIT , 0, NULL },
1382 { "save" , cmdSAVE , 0, N_("save and quit") },
1383 { "help" , cmdHELP , 0, N_("show this help") },
1384 { "?" , cmdHELP , 0, NULL },
1385 { "fpr" , cmdFPR , 0, N_("show key fingerprint") },
1386 { "list" , cmdLIST , 0, N_("list key and user IDs") },
1387 { "l" , cmdLIST , 0, NULL },
1388 { "uid" , cmdSELUID , 0, N_("select user ID N") },
1389 { "key" , cmdSELKEY , 0, N_("select subkey N") },
1390 { "check" , cmdCHECK , 0, N_("check signatures") },
1391 { "c" , cmdCHECK , 0, NULL },
1392 { "cross-certify", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1393 { "backsign", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1394 { "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
1395 N_("sign selected user IDs [* see below for related commands]") },
1396 { "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
1397 /* "lsign" and friends will never match since "sign" comes first
1398 and it is a tail match. They are just here so they show up in
1399 the help menu. */
1400 { "lsign" , cmdNOP , 0, N_("sign selected user IDs locally") },
1401 { "tsign" , cmdNOP , 0,
1402 N_("sign selected user IDs with a trust signature") },
1403 { "nrsign" , cmdNOP , 0,
1404 N_("sign selected user IDs with a non-revocable signature") },
1406 { "debug" , cmdDEBUG , 0, NULL },
1407 { "adduid" , cmdADDUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1408 N_("add a user ID") },
1409 { "addphoto", cmdADDPHOTO , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1410 N_("add a photo ID") },
1411 { "deluid" , cmdDELUID , KEYEDIT_NOT_SK,
1412 N_("delete selected user IDs") },
1413 /* delphoto is really deluid in disguise */
1414 { "delphoto", cmdDELUID , KEYEDIT_NOT_SK, NULL },
1416 { "addkey" , cmdADDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1417 N_("add a subkey") },
1419 #ifdef ENABLE_CARD_SUPPORT
1420 { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1421 N_("add a key to a smartcard") },
1422 { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1423 N_("move a key to a smartcard")},
1424 { "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1425 N_("move a backup key to a smartcard")},
1426 #endif /*ENABLE_CARD_SUPPORT*/
1428 { "delkey" , cmdDELKEY , KEYEDIT_NOT_SK,
1429 N_("delete selected subkeys") },
1430 { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1431 N_("add a revocation key") },
1432 { "delsig" , cmdDELSIG , KEYEDIT_NOT_SK,
1433 N_("delete signatures from the selected user IDs") },
1434 { "expire" , cmdEXPIRE , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1435 N_("change the expiration date for the key or selected subkeys") },
1436 { "primary" , cmdPRIMARY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1437 N_("flag the selected user ID as primary")},
1438 { "toggle" , cmdTOGGLE , KEYEDIT_NEED_SK,
1439 N_("toggle between the secret and public key listings") },
1440 { "t" , cmdTOGGLE , KEYEDIT_NEED_SK, NULL },
1441 { "pref" , cmdPREF , KEYEDIT_NOT_SK,
1442 N_("list preferences (expert)")},
1443 { "showpref", cmdSHOWPREF , KEYEDIT_NOT_SK,
1444 N_("list preferences (verbose)") },
1445 { "setpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1446 N_("set preference list for the selected user IDs") },
1447 /* Alias */
1448 { "updpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1450 { "keyserver",cmdPREFKS , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1451 N_("set the preferred keyserver URL for the selected user IDs")},
1452 { "notation", cmdNOTATION , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1453 N_("set a notation for the selected user IDs")},
1454 { "passwd" , cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1455 N_("change the passphrase") },
1456 /* Alias */
1457 { "password", cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1459 { "trust" , cmdTRUST , KEYEDIT_NOT_SK, N_("change the ownertrust") },
1460 { "revsig" , cmdREVSIG , KEYEDIT_NOT_SK,
1461 N_("revoke signatures on the selected user IDs") },
1462 { "revuid" , cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1463 N_("revoke selected user IDs") },
1464 /* Alias */
1465 { "revphoto", cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1467 { "revkey" , cmdREVKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1468 N_("revoke key or selected subkeys") },
1469 { "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
1470 { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
1471 { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
1472 { "clean", cmdCLEAN , KEYEDIT_NOT_SK,
1473 N_("compact unusable user IDs and remove unusable signatures from key")},
1474 { "minimize", cmdMINIMIZE , KEYEDIT_NOT_SK,
1475 N_("compact unusable user IDs and remove all signatures from key") },
1476 { NULL, cmdNONE, 0, NULL }
1479 #ifdef HAVE_LIBREADLINE
1481 /* These two functions are used by readline for command completion. */
1483 static char *
1484 command_generator(const char *text,int state)
1486 static int list_index,len;
1487 const char *name;
1489 /* If this is a new word to complete, initialize now. This includes
1490 saving the length of TEXT for efficiency, and initializing the
1491 index variable to 0. */
1492 if(!state)
1494 list_index=0;
1495 len=strlen(text);
1498 /* Return the next partial match */
1499 while((name=cmds[list_index].name))
1501 /* Only complete commands that have help text */
1502 if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1503 return strdup(name);
1506 return NULL;
1509 static char **
1510 keyedit_completion(const char *text, int start, int end)
1512 /* If we are at the start of a line, we try and command-complete.
1513 If not, just do nothing for now. */
1515 (void)end;
1517 if(start==0)
1518 return rl_completion_matches(text,command_generator);
1520 rl_attempted_completion_over=1;
1522 return NULL;
1524 #endif /* HAVE_LIBREADLINE */
1527 void
1528 keyedit_menu( const char *username, strlist_t locusr,
1529 strlist_t commands, int quiet, int seckey_check )
1531 enum cmdids cmd = 0;
1532 int rc = 0;
1533 KBNODE keyblock = NULL;
1534 KEYDB_HANDLE kdbhd = NULL;
1535 KBNODE sec_keyblock = NULL;
1536 KEYDB_HANDLE sec_kdbhd = NULL;
1537 KBNODE cur_keyblock;
1538 char *answer = NULL;
1539 int redisplay = 1;
1540 int modified = 0;
1541 int sec_modified = 0;
1542 int toggle;
1543 int have_commands = !!commands;
1545 if ( opt.command_fd != -1 )
1547 else if( opt.batch && !have_commands )
1549 log_error(_("can't do this in batch mode\n"));
1550 goto leave;
1553 #ifdef HAVE_W32_SYSTEM
1554 /* Due to Windows peculiarities we need to make sure that the
1555 trustdb stale check is done before we open another file
1556 (i.e. by searching for a key). In theory we could make sure
1557 that the files are closed after use but the open/close caches
1558 inhibits that and flushing the cache right before the stale
1559 check is not easy to implement. Thus we take the easy way out
1560 and run the stale check as early as possible. Note, that for
1561 non- W32 platforms it is run indirectly trough a call to
1562 get_validity (). */
1563 check_trustdb_stale ();
1564 #endif
1566 /* Get the public key */
1567 rc = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
1568 if( rc )
1569 goto leave;
1570 if( fix_keyblock( keyblock ) )
1571 modified++;
1572 if( collapse_uids( &keyblock ) )
1573 modified++;
1574 reorder_keyblock(keyblock);
1575 /* We modified the keyblock, so let's make sure the flags are
1576 right. */
1577 if (modified)
1578 merge_keys_and_selfsig (keyblock);
1580 if(seckey_check)
1581 {/* see whether we have a matching secret key */
1582 PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1584 sec_kdbhd = keydb_new (1);
1586 byte afp[MAX_FINGERPRINT_LEN];
1587 size_t an;
1589 fingerprint_from_pk (pk, afp, &an);
1590 while (an < MAX_FINGERPRINT_LEN)
1591 afp[an++] = 0;
1592 rc = keydb_search_fpr (sec_kdbhd, afp);
1594 if (!rc)
1596 rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1597 if (rc)
1599 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1600 username, g10_errstr(rc));
1602 else
1604 merge_keys_and_selfsig( sec_keyblock );
1605 if( fix_keyblock( sec_keyblock ) )
1606 sec_modified++;
1610 if (rc) {
1611 sec_keyblock = NULL;
1612 keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1613 rc = 0;
1616 if( sec_keyblock && !quiet )
1617 tty_printf(_("Secret key is available.\n"));
1620 toggle = 0;
1621 cur_keyblock = keyblock;
1622 for(;;) { /* main loop */
1623 int i, arg_number, photo;
1624 const char *arg_string = "";
1625 char *p;
1626 PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1628 tty_printf("\n");
1630 if( redisplay && !quiet )
1632 show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1633 tty_printf("\n");
1634 redisplay = 0;
1636 do {
1637 xfree(answer);
1638 if( have_commands ) {
1639 if( commands ) {
1640 answer = xstrdup( commands->d );
1641 commands = commands->next;
1643 else if( opt.batch ) {
1644 answer = xstrdup("quit");
1646 else
1647 have_commands = 0;
1649 if( !have_commands )
1651 #ifdef HAVE_LIBREADLINE
1652 tty_enable_completion(keyedit_completion);
1653 #endif
1654 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1655 cpr_kill_prompt();
1656 tty_disable_completion();
1658 trim_spaces(answer);
1659 } while( *answer == '#' );
1661 arg_number = 0; /* Yes, here is the init which egcc complains about */
1662 photo = 0; /* This too */
1663 if( !*answer )
1664 cmd = cmdLIST;
1665 else if( *answer == CONTROL_D )
1666 cmd = cmdQUIT;
1667 else if( digitp(answer ) ) {
1668 cmd = cmdSELUID;
1669 arg_number = atoi(answer);
1671 else {
1672 if( (p=strchr(answer,' ')) ) {
1673 *p++ = 0;
1674 trim_spaces(answer);
1675 trim_spaces(p);
1676 arg_number = atoi(p);
1677 arg_string = p;
1680 for(i=0; cmds[i].name; i++ )
1682 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1684 size_t l=strlen(cmds[i].name);
1685 size_t a=strlen(answer);
1686 if(a>=l)
1688 if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1690 answer[a-l]='\0';
1691 break;
1695 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1696 break;
1698 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1700 tty_printf(_("Need the secret key to do this.\n"));
1701 cmd = cmdNOP;
1703 else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1704 && toggle)
1705 ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1706 && !toggle))
1708 tty_printf(_("Please use the command \"toggle\" first.\n"));
1709 cmd = cmdNOP;
1711 else
1712 cmd = cmds[i].id;
1714 switch( cmd )
1716 case cmdHELP:
1717 for(i=0; cmds[i].name; i++ )
1719 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1720 ; /* skip if we do not have the secret key */
1721 else if( cmds[i].desc )
1722 tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
1725 tty_printf("\n");
1726 tty_printf(_(
1727 "* The `sign' command may be prefixed with an `l' for local "
1728 "signatures (lsign),\n"
1729 " a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
1730 " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
1732 break;
1734 case cmdLIST:
1735 redisplay = 1;
1736 break;
1738 case cmdFPR:
1739 show_key_and_fingerprint( keyblock );
1740 break;
1742 case cmdSELUID:
1743 if(strlen(arg_string)==NAMEHASH_LEN*2)
1744 redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
1745 else
1746 redisplay=menu_select_uid(cur_keyblock,arg_number);
1747 break;
1749 case cmdSELKEY:
1750 if( menu_select_key( cur_keyblock, arg_number ) )
1751 redisplay = 1;
1752 break;
1754 case cmdCHECK:
1755 /* we can only do this with the public key becuase the
1756 * check functions can't cope with secret keys and it
1757 * is questionable whether this would make sense at all */
1758 check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1759 break;
1761 case cmdSIGN: /* sign (only the public key) */
1763 int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
1765 if( pk->is_revoked )
1767 tty_printf(_("Key is revoked."));
1769 if(opt.expert)
1771 tty_printf(" ");
1772 if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1773 _("Are you sure you still want"
1774 " to sign it? (y/N) ")))
1775 break;
1777 else
1779 tty_printf(_(" Unable to sign.\n"));
1780 break;
1784 if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
1785 && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1786 _("Really sign all user IDs?"
1787 " (y/N) ")))
1789 if(opt.interactive)
1790 interactive=1;
1791 else
1793 tty_printf(_("Hint: Select the user IDs to sign\n"));
1794 have_commands = 0;
1795 break;
1799 /* What sort of signing are we doing? */
1800 if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1802 tty_printf(_("Unknown signature type `%s'\n"),answer);
1803 break;
1806 sign_uids(keyblock, locusr, &modified,
1807 localsig, nonrevokesig, trustsig, interactive);
1809 break;
1811 case cmdDEBUG:
1812 dump_kbnode( cur_keyblock );
1813 break;
1815 case cmdTOGGLE:
1816 toggle = !toggle;
1817 cur_keyblock = toggle? sec_keyblock : keyblock;
1818 redisplay = 1;
1819 break;
1821 case cmdADDPHOTO:
1822 if (RFC2440 || RFC1991 || PGP2)
1824 tty_printf(
1825 _("This command is not allowed while in %s mode.\n"),
1826 compliance_option_string());
1827 break;
1829 photo=1;
1830 /* fall through */
1832 case cmdADDUID:
1833 if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
1835 update_trust = 1;
1836 redisplay = 1;
1837 sec_modified = modified = 1;
1838 merge_keys_and_selfsig( sec_keyblock );
1839 merge_keys_and_selfsig( keyblock );
1841 break;
1843 case cmdDELUID: {
1844 int n1;
1846 if( !(n1=count_selected_uids(keyblock)) )
1847 tty_printf(_("You must select at least one user ID.\n"));
1848 else if( real_uids_left(keyblock) < 1 )
1849 tty_printf(_("You can't delete the last user ID!\n"));
1850 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1851 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1852 : _("Really remove this user ID? (y/N) ")
1853 ) ) {
1854 menu_deluid( keyblock, sec_keyblock );
1855 redisplay = 1;
1856 modified = 1;
1857 if( sec_keyblock )
1858 sec_modified = 1;
1861 break;
1863 case cmdDELSIG: {
1864 int n1;
1866 if( !(n1=count_selected_uids(keyblock)) )
1867 tty_printf(_("You must select at least one user ID.\n"));
1868 else if( menu_delsig( keyblock ) ) {
1869 /* no redisplay here, because it may scroll away some
1870 * status output of delsig */
1871 modified = 1;
1874 break;
1876 case cmdADDKEY:
1877 if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1878 redisplay = 1;
1879 sec_modified = modified = 1;
1880 merge_keys_and_selfsig( sec_keyblock );
1881 merge_keys_and_selfsig( keyblock );
1883 break;
1885 #ifdef ENABLE_CARD_SUPPORT
1886 case cmdADDCARDKEY:
1887 if (card_generate_subkey (keyblock, sec_keyblock)) {
1888 redisplay = 1;
1889 sec_modified = modified = 1;
1890 merge_keys_and_selfsig( sec_keyblock );
1891 merge_keys_and_selfsig( keyblock );
1893 break;
1895 case cmdKEYTOCARD:
1897 KBNODE node=NULL;
1898 switch ( count_selected_keys (sec_keyblock) )
1900 case 0:
1901 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1902 _("Really move the primary key? (y/N) ")))
1903 node = sec_keyblock;
1904 break;
1905 case 1:
1906 for (node = sec_keyblock; node; node = node->next )
1908 if (node->pkt->pkttype == PKT_SECRET_SUBKEY
1909 && node->flag & NODFLG_SELKEY)
1910 break;
1912 break;
1913 default:
1914 tty_printf(_("You must select exactly one key.\n"));
1915 break;
1917 if (node)
1919 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1920 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1922 redisplay = 1;
1923 sec_modified = 1;
1927 break;
1929 case cmdBKUPTOCARD:
1931 /* Ask for a filename, check whether this is really a
1932 backup key as generated by the card generation, parse
1933 that key and store it on card. */
1934 KBNODE node;
1935 const char *fname;
1936 PACKET *pkt;
1937 IOBUF a;
1939 fname = arg_string;
1940 if (!*fname)
1942 tty_printf (_("Command expects a filename argument\n"));
1943 break;
1946 /* Open that file. */
1947 a = iobuf_open (fname);
1948 if (a && is_secured_file (iobuf_get_fd (a)))
1950 iobuf_close (a);
1951 a = NULL;
1952 errno = EPERM;
1954 if (!a)
1956 tty_printf (_("Can't open `%s': %s\n"),
1957 fname, strerror(errno));
1958 break;
1961 /* Parse and check that file. */
1962 pkt = xmalloc (sizeof *pkt);
1963 init_packet (pkt);
1964 rc = parse_packet (a, pkt);
1965 iobuf_close (a);
1966 iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache). */
1967 if (!rc
1968 && pkt->pkttype != PKT_SECRET_KEY
1969 && pkt->pkttype != PKT_SECRET_SUBKEY)
1970 rc = G10ERR_NO_SECKEY;
1971 if (rc)
1973 tty_printf(_("Error reading backup key from `%s': %s\n"),
1974 fname, g10_errstr (rc));
1975 free_packet (pkt);
1976 xfree (pkt);
1977 break;
1979 node = new_kbnode (pkt);
1981 /* Store it. */
1982 if (card_store_subkey (node, 0))
1984 redisplay = 1;
1985 sec_modified = 1;
1987 release_kbnode (node);
1989 break;
1991 #endif /* ENABLE_CARD_SUPPORT */
1993 case cmdDELKEY: {
1994 int n1;
1996 if( !(n1=count_selected_keys( keyblock )) )
1997 tty_printf(_("You must select at least one key.\n"));
1998 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1999 n1 > 1?
2000 _("Do you really want to delete the selected keys? (y/N) "):
2001 _("Do you really want to delete this key? (y/N) ")
2004 else {
2005 menu_delkey( keyblock, sec_keyblock );
2006 redisplay = 1;
2007 modified = 1;
2008 if( sec_keyblock )
2009 sec_modified = 1;
2012 break;
2014 case cmdADDREVOKER:
2016 int sensitive=0;
2018 if(ascii_strcasecmp(arg_string,"sensitive")==0)
2019 sensitive=1;
2020 if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
2021 redisplay = 1;
2022 sec_modified = modified = 1;
2023 merge_keys_and_selfsig( sec_keyblock );
2024 merge_keys_and_selfsig( keyblock );
2027 break;
2029 case cmdREVUID: {
2030 int n1;
2032 if( !(n1=count_selected_uids(keyblock)) )
2033 tty_printf(_("You must select at least one user ID.\n"));
2034 else if( cpr_get_answer_is_yes(
2035 "keyedit.revoke.uid.okay",
2036 n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
2037 : _("Really revoke this user ID? (y/N) ")
2038 ) ) {
2039 if(menu_revuid(keyblock,sec_keyblock))
2041 modified=1;
2042 redisplay=1;
2046 break;
2048 case cmdREVKEY:
2050 int n1;
2052 if( !(n1=count_selected_keys( keyblock )) )
2054 if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2055 _("Do you really want to revoke"
2056 " the entire key? (y/N) ")))
2058 if(menu_revkey(keyblock,sec_keyblock))
2059 modified=1;
2061 redisplay=1;
2064 else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2065 n1 > 1?
2066 _("Do you really want to revoke"
2067 " the selected subkeys? (y/N) "):
2068 _("Do you really want to revoke"
2069 " this subkey? (y/N) ")))
2071 if( menu_revsubkey( keyblock, sec_keyblock ) )
2072 modified = 1;
2074 redisplay = 1;
2077 if(modified)
2078 merge_keys_and_selfsig( keyblock );
2080 break;
2082 case cmdEXPIRE:
2083 if( menu_expire( keyblock, sec_keyblock ) )
2085 merge_keys_and_selfsig( sec_keyblock );
2086 merge_keys_and_selfsig( keyblock );
2087 sec_modified = 1;
2088 modified = 1;
2089 redisplay = 1;
2091 break;
2093 case cmdBACKSIGN:
2094 if(menu_backsign(keyblock,sec_keyblock))
2096 sec_modified = 1;
2097 modified = 1;
2098 redisplay = 1;
2100 break;
2102 case cmdPRIMARY:
2103 if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
2104 merge_keys_and_selfsig( keyblock );
2105 modified = 1;
2106 redisplay = 1;
2108 break;
2110 case cmdPASSWD:
2111 if( change_passphrase( sec_keyblock ) )
2112 sec_modified = 1;
2113 break;
2115 case cmdTRUST:
2116 if(opt.trust_model==TM_EXTERNAL)
2118 tty_printf (_("Owner trust may not be set while "
2119 "using a user provided trust database\n"));
2120 break;
2123 show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
2124 tty_printf("\n");
2125 if( edit_ownertrust( find_kbnode( keyblock,
2126 PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
2127 redisplay = 1;
2128 /* No real need to set update_trust here as
2129 edit_ownertrust() calls revalidation_mark()
2130 anyway. */
2131 update_trust=1;
2133 break;
2135 case cmdPREF:
2137 int count=count_selected_uids(keyblock);
2138 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2139 show_names(keyblock,keyblock->pkt->pkt.public_key,
2140 count?NODFLG_SELUID:0,1);
2142 break;
2144 case cmdSHOWPREF:
2146 int count=count_selected_uids(keyblock);
2147 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2148 show_names(keyblock,keyblock->pkt->pkt.public_key,
2149 count?NODFLG_SELUID:0,2);
2151 break;
2153 case cmdSETPREF:
2155 PKT_user_id *tempuid;
2157 keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
2159 tempuid=keygen_get_std_prefs();
2160 tty_printf(_("Set preference list to:\n"));
2161 show_prefs(tempuid,NULL,1);
2162 free_user_id(tempuid);
2164 if(cpr_get_answer_is_yes("keyedit.setpref.okay",
2165 count_selected_uids (keyblock)?
2166 _("Really update the preferences"
2167 " for the selected user IDs? (y/N) "):
2168 _("Really update the preferences? (y/N) ")))
2170 if ( menu_set_preferences (keyblock, sec_keyblock) )
2172 merge_keys_and_selfsig (keyblock);
2173 modified = 1;
2174 redisplay = 1;
2178 break;
2180 case cmdPREFKS:
2181 if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
2182 keyblock, sec_keyblock ) )
2184 merge_keys_and_selfsig( keyblock );
2185 modified = 1;
2186 redisplay = 1;
2188 break;
2190 case cmdNOTATION:
2191 if( menu_set_notation ( *arg_string?arg_string:NULL,
2192 keyblock, sec_keyblock ) )
2194 merge_keys_and_selfsig( keyblock );
2195 modified = 1;
2196 redisplay = 1;
2198 break;
2200 case cmdNOP:
2201 break;
2203 case cmdREVSIG:
2204 if( menu_revsig( keyblock ) ) {
2205 redisplay = 1;
2206 modified = 1;
2208 break;
2210 case cmdENABLEKEY:
2211 case cmdDISABLEKEY:
2212 if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
2213 redisplay = 1;
2214 modified = 1;
2216 break;
2218 case cmdSHOWPHOTO:
2219 menu_showphoto(keyblock);
2220 break;
2222 case cmdCLEAN:
2223 if(menu_clean(keyblock,0))
2224 redisplay=modified=1;
2225 break;
2227 case cmdMINIMIZE:
2228 if(menu_clean(keyblock,1))
2229 redisplay=modified=1;
2230 break;
2232 case cmdQUIT:
2233 if( have_commands )
2234 goto leave;
2235 if( !modified && !sec_modified )
2236 goto leave;
2237 if( !cpr_get_answer_is_yes("keyedit.save.okay",
2238 _("Save changes? (y/N) ")) ) {
2239 if( cpr_enabled()
2240 || cpr_get_answer_is_yes("keyedit.cancel.okay",
2241 _("Quit without saving? (y/N) ")))
2242 goto leave;
2243 break;
2245 /* fall thru */
2246 case cmdSAVE:
2247 if( modified || sec_modified ) {
2248 if( modified ) {
2249 rc = keydb_update_keyblock (kdbhd, keyblock);
2250 if( rc ) {
2251 log_error(_("update failed: %s\n"), g10_errstr(rc) );
2252 break;
2255 if( sec_modified ) {
2256 rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
2257 if( rc ) {
2258 log_error( _("update secret failed: %s\n"),
2259 g10_errstr(rc) );
2260 break;
2264 else
2265 tty_printf(_("Key not changed so no update needed.\n"));
2267 if( update_trust )
2269 revalidation_mark ();
2270 update_trust=0;
2272 goto leave;
2274 case cmdINVCMD:
2275 default:
2276 tty_printf("\n");
2277 tty_printf(_("Invalid command (try \"help\")\n"));
2278 break;
2280 } /* end main loop */
2282 leave:
2283 release_kbnode( keyblock );
2284 release_kbnode( sec_keyblock );
2285 keydb_release (kdbhd);
2286 xfree(answer);
2289 static void
2290 tty_print_notations(int indent,PKT_signature *sig)
2292 int first=1;
2293 struct notation *notation,*nd;
2295 if(indent<0)
2297 first=0;
2298 indent=-indent;
2301 notation=sig_to_notation(sig);
2303 for(nd=notation;nd;nd=nd->next)
2305 if(!first)
2306 tty_printf("%*s",indent,"");
2307 else
2308 first=0;
2310 tty_print_utf8_string(nd->name,strlen(nd->name));
2311 tty_printf("=");
2312 tty_print_utf8_string(nd->value,strlen(nd->value));
2313 tty_printf("\n");
2316 free_notation(notation);
2319 /****************
2320 * show preferences of a public keyblock.
2322 static void
2323 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
2325 const prefitem_t fake={0,0};
2326 const prefitem_t *prefs;
2327 int i;
2329 if( !uid )
2330 return;
2332 if( uid->prefs )
2333 prefs=uid->prefs;
2334 else if(verbose)
2335 prefs=&fake;
2336 else
2337 return;
2339 if (verbose) {
2340 int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
2342 tty_printf (" ");
2343 tty_printf (_("Cipher: "));
2344 for(i=any=0; prefs[i].type; i++ ) {
2345 if( prefs[i].type == PREFTYPE_SYM ) {
2346 if (any)
2347 tty_printf (", ");
2348 any = 1;
2349 /* We don't want to display strings for experimental algos */
2350 if (!openpgp_cipher_test_algo (prefs[i].value)
2351 && prefs[i].value < 100 )
2352 tty_printf ("%s",
2353 openpgp_cipher_algo_name (prefs[i].value));
2354 else
2355 tty_printf ("[%d]", prefs[i].value);
2356 if (prefs[i].value == CIPHER_ALGO_3DES )
2357 des_seen = 1;
2360 if (!des_seen) {
2361 if (any)
2362 tty_printf (", ");
2363 tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
2365 tty_printf ("\n ");
2366 tty_printf (_("Digest: "));
2367 for(i=any=0; prefs[i].type; i++ ) {
2368 if( prefs[i].type == PREFTYPE_HASH ) {
2369 if (any)
2370 tty_printf (", ");
2371 any = 1;
2372 /* We don't want to display strings for experimental algos */
2373 if (!gcry_md_test_algo (prefs[i].value)
2374 && prefs[i].value < 100 )
2375 tty_printf ("%s", gcry_md_algo_name (prefs[i].value) );
2376 else
2377 tty_printf ("[%d]", prefs[i].value);
2378 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2379 sha1_seen = 1;
2382 if (!sha1_seen) {
2383 if (any)
2384 tty_printf (", ");
2385 tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
2387 tty_printf ("\n ");
2388 tty_printf (_("Compression: "));
2389 for(i=any=0; prefs[i].type; i++ ) {
2390 if( prefs[i].type == PREFTYPE_ZIP ) {
2391 const char *s=compress_algo_to_string(prefs[i].value);
2393 if (any)
2394 tty_printf (", ");
2395 any = 1;
2396 /* We don't want to display strings for experimental algos */
2397 if (s && prefs[i].value < 100 )
2398 tty_printf ("%s", s );
2399 else
2400 tty_printf ("[%d]", prefs[i].value);
2401 if (prefs[i].value == COMPRESS_ALGO_NONE )
2402 uncomp_seen = 1;
2405 if (!uncomp_seen) {
2406 if (any)
2407 tty_printf (", ");
2408 else {
2409 tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2410 tty_printf (", ");
2412 tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2414 if(uid->flags.mdc || !uid->flags.ks_modify)
2416 tty_printf ("\n ");
2417 tty_printf (_("Features: "));
2418 any=0;
2419 if(uid->flags.mdc)
2421 tty_printf ("MDC");
2422 any=1;
2424 if(!uid->flags.ks_modify)
2426 if(any)
2427 tty_printf (", ");
2428 tty_printf (_("Keyserver no-modify"));
2431 tty_printf("\n");
2433 if(selfsig)
2435 const byte *pref_ks;
2436 size_t pref_ks_len;
2438 pref_ks=parse_sig_subpkt(selfsig->hashed,
2439 SIGSUBPKT_PREF_KS,&pref_ks_len);
2440 if(pref_ks && pref_ks_len)
2442 tty_printf (" ");
2443 tty_printf(_("Preferred keyserver: "));
2444 tty_print_utf8_string(pref_ks,pref_ks_len);
2445 tty_printf("\n");
2448 if(selfsig->flags.notation)
2450 tty_printf (" ");
2451 tty_printf(_("Notations: "));
2452 tty_print_notations(5+strlen(_("Notations: ")),selfsig);
2456 else {
2457 tty_printf(" ");
2458 for(i=0; prefs[i].type; i++ ) {
2459 tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
2460 prefs[i].type == PREFTYPE_HASH ? 'H' :
2461 prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2462 prefs[i].value);
2464 if (uid->flags.mdc)
2465 tty_printf (" [mdc]");
2466 if (!uid->flags.ks_modify)
2467 tty_printf (" [no-ks-modify]");
2468 tty_printf("\n");
2472 /* This is the version of show_key_with_all_names used when
2473 opt.with_colons is used. It prints all available data in a easy to
2474 parse format and does not translate utf8 */
2475 static void
2476 show_key_with_all_names_colon (KBNODE keyblock)
2478 KBNODE node;
2479 int i, j, ulti_hack=0;
2480 byte pk_version=0;
2481 PKT_public_key *primary=NULL;
2483 /* the keys */
2484 for ( node = keyblock; node; node = node->next )
2486 if (node->pkt->pkttype == PKT_PUBLIC_KEY
2487 || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2489 PKT_public_key *pk = node->pkt->pkt.public_key;
2490 u32 keyid[2];
2492 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2494 pk_version = pk->version;
2495 primary=pk;
2498 keyid_from_pk (pk, keyid);
2500 fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2501 if (!pk->is_valid)
2502 putchar ('i');
2503 else if (pk->is_revoked)
2504 putchar ('r');
2505 else if (pk->has_expired)
2506 putchar ('e');
2507 else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2509 int trust = get_validity_info (pk, NULL);
2510 if(trust=='u')
2511 ulti_hack=1;
2512 putchar (trust);
2515 printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2516 nbits_from_pk (pk),
2517 pk->pubkey_algo,
2518 (ulong)keyid[0], (ulong)keyid[1],
2519 (ulong)pk->timestamp,
2520 (ulong)pk->expiredate );
2521 if (node->pkt->pkttype==PKT_PUBLIC_KEY
2522 && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2523 putchar(get_ownertrust_info (pk));
2524 putchar(':');
2525 putchar (':');
2526 putchar (':');
2527 /* Print capabilities. */
2528 if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) )
2529 putchar ('e');
2530 if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) )
2531 putchar ('s');
2532 if ( (pk->pubkey_usage & PUBKEY_USAGE_CERT) )
2533 putchar ('c');
2534 if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
2535 putchar ('a');
2536 putchar('\n');
2538 print_fingerprint (pk, NULL, 0);
2539 print_revokers(pk);
2543 /* the user ids */
2544 i = 0;
2545 for (node = keyblock; node; node = node->next)
2547 if ( node->pkt->pkttype == PKT_USER_ID )
2549 PKT_user_id *uid = node->pkt->pkt.user_id;
2551 ++i;
2553 if(uid->attrib_data)
2554 printf("uat:");
2555 else
2556 printf("uid:");
2558 if ( uid->is_revoked )
2559 printf("r::::::::");
2560 else if ( uid->is_expired )
2561 printf("e::::::::");
2562 else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2563 printf("::::::::");
2564 else
2566 int uid_validity;
2568 if( primary && !ulti_hack )
2569 uid_validity = get_validity_info( primary, uid );
2570 else
2571 uid_validity = 'u';
2572 printf("%c::::::::",uid_validity);
2575 if(uid->attrib_data)
2576 printf ("%u %lu",uid->numattribs,uid->attrib_len);
2577 else
2578 print_string (stdout, uid->name, uid->len, ':');
2580 putchar (':');
2581 /* signature class */
2582 putchar (':');
2583 /* capabilities */
2584 putchar (':');
2585 /* preferences */
2586 if (pk_version>3 || uid->selfsigversion>3)
2588 const prefitem_t *prefs = uid->prefs;
2590 for (j=0; prefs && prefs[j].type; j++)
2592 if (j)
2593 putchar (' ');
2594 printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
2595 prefs[j].type == PREFTYPE_HASH ? 'H' :
2596 prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2597 prefs[j].value);
2599 if (uid->flags.mdc)
2600 printf (",mdc");
2601 if (!uid->flags.ks_modify)
2602 printf (",no-ks-modify");
2604 putchar (':');
2605 /* flags */
2606 printf ("%d,", i);
2607 if (uid->is_primary)
2608 putchar ('p');
2609 if (uid->is_revoked)
2610 putchar ('r');
2611 if (uid->is_expired)
2612 putchar ('e');
2613 if ((node->flag & NODFLG_SELUID))
2614 putchar ('s');
2615 if ((node->flag & NODFLG_MARK_A))
2616 putchar ('m');
2617 putchar (':');
2618 putchar('\n');
2623 static void
2624 show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
2626 KBNODE node;
2627 int i=0;
2629 for( node = keyblock; node; node = node->next )
2631 if( node->pkt->pkttype == PKT_USER_ID
2632 && !is_deleted_kbnode(node))
2634 PKT_user_id *uid = node->pkt->pkt.user_id;
2635 ++i;
2636 if(!flag || (flag && (node->flag & flag)))
2638 if(!(flag&NODFLG_MARK_A) && pk)
2639 tty_printf("%s ",uid_trust_string_fixed(pk,uid));
2641 if( flag & NODFLG_MARK_A )
2642 tty_printf(" ");
2643 else if( node->flag & NODFLG_SELUID )
2644 tty_printf("(%d)* ", i);
2645 else if( uid->is_primary )
2646 tty_printf("(%d). ", i);
2647 else
2648 tty_printf("(%d) ", i);
2649 tty_print_utf8_string( uid->name, uid->len );
2650 tty_printf("\n");
2651 if(with_prefs && pk)
2653 if(pk->version>3 || uid->selfsigversion>3)
2655 PKT_signature *selfsig=NULL;
2656 KBNODE signode;
2658 for(signode=node->next;
2659 signode && signode->pkt->pkttype==PKT_SIGNATURE;
2660 signode=signode->next)
2662 if(signode->pkt->pkt.signature->
2663 flags.chosen_selfsig)
2665 selfsig=signode->pkt->pkt.signature;
2666 break;
2670 show_prefs (uid, selfsig, with_prefs == 2);
2672 else
2673 tty_printf(_("There are no preferences on a"
2674 " PGP 2.x-style user ID.\n"));
2681 /****************
2682 * Display the key a the user ids, if only_marked is true, do only
2683 * so for user ids with mark A flag set and dont display the index number
2685 static void
2686 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2687 int with_fpr, int with_subkeys, int with_prefs )
2689 KBNODE node;
2690 int i;
2691 int do_warn = 0;
2692 byte pk_version=0;
2693 PKT_public_key *primary=NULL;
2695 if (opt.with_colons)
2697 show_key_with_all_names_colon (keyblock);
2698 return;
2701 /* the keys */
2702 for( node = keyblock; node; node = node->next ) {
2703 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2704 || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2705 && !is_deleted_kbnode(node)) ) {
2706 PKT_public_key *pk = node->pkt->pkt.public_key;
2707 const char *otrust="err",*trust="err";
2709 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2710 /* do it here, so that debug messages don't clutter the
2711 * output */
2712 static int did_warn = 0;
2714 trust = get_validity_string (pk, NULL);
2715 otrust = get_ownertrust_string (pk);
2717 /* Show a warning once */
2718 if (!did_warn
2719 && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2720 did_warn = 1;
2721 do_warn = 1;
2724 pk_version=pk->version;
2725 primary=pk;
2728 if(pk->is_revoked)
2730 char *user=get_user_id_string_native(pk->revoked.keyid);
2731 const char *algo = gcry_pk_algo_name (pk->revoked.algo);
2732 tty_printf(_("This key was revoked on %s by %s key %s\n"),
2733 revokestr_from_pk(pk),algo?algo:"?",user);
2734 xfree(user);
2737 if(with_revoker)
2739 if( !pk->revkey && pk->numrevkeys )
2740 BUG();
2741 else
2742 for(i=0;i<pk->numrevkeys;i++)
2744 u32 r_keyid[2];
2745 char *user;
2746 const char *algo;
2748 algo = gcry_pk_algo_name (pk->revkey[i].algid);
2749 keyid_from_fingerprint(pk->revkey[i].fpr,
2750 MAX_FINGERPRINT_LEN,r_keyid);
2752 user=get_user_id_string_native(r_keyid);
2753 tty_printf(_("This key may be revoked by %s key %s"),
2754 algo?algo:"?",user);
2756 if(pk->revkey[i].class&0x40)
2758 tty_printf(" ");
2759 tty_printf(_("(sensitive)"));
2762 tty_printf ("\n");
2763 xfree(user);
2767 keyid_from_pk(pk,NULL);
2768 tty_printf("%s%c %4u%c/%s ",
2769 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2770 (node->flag & NODFLG_SELKEY)? '*':' ',
2771 nbits_from_pk( pk ),
2772 pubkey_letter( pk->pubkey_algo ),
2773 keystr(pk->keyid));
2775 tty_printf(_("created: %s"),datestr_from_pk(pk));
2776 tty_printf(" ");
2777 if(pk->is_revoked)
2778 tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2779 else if(pk->has_expired)
2780 tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2781 else
2782 tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2783 tty_printf(" ");
2784 tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2785 tty_printf("\n");
2787 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2789 if(opt.trust_model!=TM_ALWAYS)
2791 tty_printf("%*s", (int)keystrlen()+13,"");
2792 /* Ownertrust is only meaningful for the PGP or
2793 classic trust models */
2794 if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2796 int width=14-strlen(otrust);
2797 if(width<=0)
2798 width=1;
2799 tty_printf(_("trust: %s"), otrust);
2800 tty_printf("%*s",width,"");
2803 tty_printf(_("validity: %s"), trust );
2804 tty_printf("\n");
2806 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2807 && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2809 tty_printf("*** ");
2810 tty_printf(_("This key has been disabled"));
2811 tty_printf("\n");
2815 if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2817 print_fingerprint ( pk, NULL, 2 );
2818 tty_printf("\n");
2821 else if( node->pkt->pkttype == PKT_SECRET_KEY
2822 || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2824 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2825 tty_printf("%s%c %4u%c/%s ",
2826 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2827 (node->flag & NODFLG_SELKEY)? '*':' ',
2828 nbits_from_sk( sk ),
2829 pubkey_letter( sk->pubkey_algo ),
2830 keystr_from_sk(sk));
2831 tty_printf(_("created: %s"),datestr_from_sk(sk));
2832 tty_printf(" ");
2833 tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2834 tty_printf("\n");
2835 if (sk->is_protected && sk->protect.s2k.mode == 1002)
2837 tty_printf(" ");
2838 tty_printf(_("card-no: "));
2839 if (sk->protect.ivlen == 16
2840 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2841 { /* This is an OpenPGP card. */
2842 for (i=8; i < 14; i++)
2844 if (i == 10)
2845 tty_printf (" ");
2846 tty_printf ("%02X", sk->protect.iv[i]);
2849 else
2850 { /* Something is wrong: Print all. */
2851 for (i=0; i < sk->protect.ivlen; i++)
2852 tty_printf ("%02X", sk->protect.iv[i]);
2854 tty_printf ("\n");
2859 show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
2861 if (do_warn)
2862 tty_printf (_("Please note that the shown key validity"
2863 " is not necessarily correct\n"
2864 "unless you restart the program.\n"));
2868 /* Display basic key information. This function is suitable to show
2869 information on the key without any dependencies on the trustdb or
2870 any other internal GnuPG stuff. KEYBLOCK may either be a public or
2871 a secret key.*/
2872 void
2873 show_basic_key_info ( KBNODE keyblock )
2875 KBNODE node;
2876 int i;
2878 /* The primary key */
2879 for (node = keyblock; node; node = node->next)
2881 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2883 PKT_public_key *pk = node->pkt->pkt.public_key;
2885 /* Note, we use the same format string as in other show
2886 functions to make the translation job easier. */
2887 tty_printf ("%s %4u%c/%s ",
2888 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2889 nbits_from_pk( pk ),
2890 pubkey_letter( pk->pubkey_algo ),
2891 keystr_from_pk(pk));
2892 tty_printf(_("created: %s"),datestr_from_pk(pk));
2893 tty_printf(" ");
2894 tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2895 tty_printf("\n");
2896 print_fingerprint ( pk, NULL, 3 );
2897 tty_printf("\n");
2899 else if (node->pkt->pkttype == PKT_SECRET_KEY)
2901 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2902 tty_printf("%s %4u%c/%s",
2903 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2904 nbits_from_sk( sk ),
2905 pubkey_letter( sk->pubkey_algo ),
2906 keystr_from_sk(sk));
2907 tty_printf(_("created: %s"),datestr_from_sk(sk));
2908 tty_printf(" ");
2909 tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2910 tty_printf("\n");
2911 print_fingerprint (NULL, sk, 3 );
2912 tty_printf("\n");
2916 /* The user IDs. */
2917 for (i=0, node = keyblock; node; node = node->next)
2919 if (node->pkt->pkttype == PKT_USER_ID)
2921 PKT_user_id *uid = node->pkt->pkt.user_id;
2922 ++i;
2924 tty_printf (" ");
2925 if (uid->is_revoked)
2926 tty_printf("[%s] ",_("revoked"));
2927 else if ( uid->is_expired )
2928 tty_printf("[%s] ",_("expired"));
2929 tty_print_utf8_string (uid->name, uid->len);
2930 tty_printf ("\n");
2935 static void
2936 show_key_and_fingerprint( KBNODE keyblock )
2938 KBNODE node;
2939 PKT_public_key *pk = NULL;
2941 for( node = keyblock; node; node = node->next )
2943 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2945 pk = node->pkt->pkt.public_key;
2946 tty_printf("pub %4u%c/%s %s ",
2947 nbits_from_pk( pk ),
2948 pubkey_letter( pk->pubkey_algo ),
2949 keystr_from_pk(pk),
2950 datestr_from_pk(pk) );
2952 else if( node->pkt->pkttype == PKT_USER_ID )
2954 PKT_user_id *uid = node->pkt->pkt.user_id;
2955 tty_print_utf8_string( uid->name, uid->len );
2956 break;
2959 tty_printf("\n");
2960 if( pk )
2961 print_fingerprint( pk, NULL, 2 );
2965 /* Show a warning if no uids on the key have the primary uid flag
2966 set. */
2967 static void
2968 no_primary_warning(KBNODE keyblock)
2970 KBNODE node;
2971 int have_primary=0,uid_count=0;
2973 /* TODO: if we ever start behaving differently with a primary or
2974 non-primary attribute ID, we will need to check for attributes
2975 here as well. */
2977 for(node=keyblock; node; node = node->next)
2979 if(node->pkt->pkttype==PKT_USER_ID
2980 && node->pkt->pkt.user_id->attrib_data==NULL)
2982 uid_count++;
2984 if(node->pkt->pkt.user_id->is_primary==2)
2986 have_primary=1;
2987 break;
2992 if(uid_count>1 && !have_primary)
2993 log_info(_("WARNING: no user ID has been marked as primary. This command"
2994 " may\n cause a different user ID to become"
2995 " the assumed primary.\n"));
2998 /****************
2999 * Ask for a new user id, do the selfsignature and put it into
3000 * both keyblocks.
3001 * Return true if there is a new user id
3003 static int
3004 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
3005 int photo, const char *photo_name)
3007 PKT_user_id *uid;
3008 PKT_public_key *pk=NULL;
3009 PKT_secret_key *sk=NULL;
3010 PKT_signature *sig=NULL;
3011 PACKET *pkt;
3012 KBNODE node;
3013 KBNODE pub_where=NULL, sec_where=NULL;
3014 int rc;
3016 for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
3017 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
3018 pk = node->pkt->pkt.public_key;
3019 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3020 break;
3022 if( !node ) /* no subkey */
3023 pub_where = NULL;
3024 for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
3025 if( node->pkt->pkttype == PKT_SECRET_KEY )
3026 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3027 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
3028 break;
3030 if( !node ) /* no subkey */
3031 sec_where = NULL;
3032 assert(pk && sk);
3034 if(photo) {
3035 int hasattrib=0;
3037 for( node = pub_keyblock; node; node = node->next )
3038 if( node->pkt->pkttype == PKT_USER_ID &&
3039 node->pkt->pkt.user_id->attrib_data!=NULL)
3041 hasattrib=1;
3042 break;
3045 /* It is legal but bad for compatibility to add a photo ID to a
3046 v3 key as it means that PGP2 will not be able to use that key
3047 anymore. Also, PGP may not expect a photo on a v3 key.
3048 Don't bother to ask this if the key already has a photo - any
3049 damage has already been done at that point. -dms */
3050 if(pk->version==3 && !hasattrib)
3052 if(opt.expert)
3054 tty_printf(_("WARNING: This is a PGP2-style key. "
3055 "Adding a photo ID may cause some versions\n"
3056 " of PGP to reject this key.\n"));
3058 if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
3059 _("Are you sure you still want "
3060 "to add it? (y/N) ")))
3061 return 0;
3063 else
3065 tty_printf(_("You may not add a photo ID to "
3066 "a PGP2-style key.\n"));
3067 return 0;
3071 uid = generate_photo_id(pk,photo_name);
3072 } else
3073 uid = generate_user_id();
3074 if( !uid )
3075 return 0;
3077 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
3078 keygen_add_std_prefs, pk );
3079 free_secret_key( sk );
3080 if( rc ) {
3081 log_error("signing failed: %s\n", g10_errstr(rc) );
3082 free_user_id(uid);
3083 return 0;
3086 /* insert/append to secret keyblock */
3087 pkt = xmalloc_clear( sizeof *pkt );
3088 pkt->pkttype = PKT_USER_ID;
3089 pkt->pkt.user_id = scopy_user_id(uid);
3090 node = new_kbnode(pkt);
3091 if( sec_where )
3092 insert_kbnode( sec_where, node, 0 );
3093 else
3094 add_kbnode( sec_keyblock, node );
3095 pkt = xmalloc_clear( sizeof *pkt );
3096 pkt->pkttype = PKT_SIGNATURE;
3097 pkt->pkt.signature = copy_signature(NULL, sig);
3098 if( sec_where )
3099 insert_kbnode( node, new_kbnode(pkt), 0 );
3100 else
3101 add_kbnode( sec_keyblock, new_kbnode(pkt) );
3102 /* insert/append to public keyblock */
3103 pkt = xmalloc_clear( sizeof *pkt );
3104 pkt->pkttype = PKT_USER_ID;
3105 pkt->pkt.user_id = uid;
3106 node = new_kbnode(pkt);
3107 if( pub_where )
3108 insert_kbnode( pub_where, node, 0 );
3109 else
3110 add_kbnode( pub_keyblock, node );
3111 pkt = xmalloc_clear( sizeof *pkt );
3112 pkt->pkttype = PKT_SIGNATURE;
3113 pkt->pkt.signature = copy_signature(NULL, sig);
3114 if( pub_where )
3115 insert_kbnode( node, new_kbnode(pkt), 0 );
3116 else
3117 add_kbnode( pub_keyblock, new_kbnode(pkt) );
3118 return 1;
3122 /****************
3123 * Remove all selected userids from the keyrings
3125 static void
3126 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3128 KBNODE node;
3129 int selected=0;
3131 for( node = pub_keyblock; node; node = node->next ) {
3132 if( node->pkt->pkttype == PKT_USER_ID ) {
3133 selected = node->flag & NODFLG_SELUID;
3134 if( selected ) {
3135 /* Only cause a trust update if we delete a
3136 non-revoked user id */
3137 if(!node->pkt->pkt.user_id->is_revoked)
3138 update_trust=1;
3139 delete_kbnode( node );
3140 if( sec_keyblock ) {
3141 KBNODE snode;
3142 int s_selected = 0;
3143 PKT_user_id *uid = node->pkt->pkt.user_id;
3144 for( snode = sec_keyblock; snode; snode = snode->next ) {
3145 if( snode->pkt->pkttype == PKT_USER_ID ) {
3146 PKT_user_id *suid = snode->pkt->pkt.user_id;
3148 s_selected =
3149 (uid->len == suid->len
3150 && !memcmp( uid->name, suid->name, uid->len));
3151 if( s_selected )
3152 delete_kbnode( snode );
3154 else if( s_selected
3155 && snode->pkt->pkttype == PKT_SIGNATURE )
3156 delete_kbnode( snode );
3157 else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
3158 s_selected = 0;
3163 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3164 delete_kbnode( node );
3165 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3166 selected = 0;
3168 commit_kbnode( &pub_keyblock );
3169 if( sec_keyblock )
3170 commit_kbnode( &sec_keyblock );
3174 static int
3175 menu_delsig( KBNODE pub_keyblock )
3177 KBNODE node;
3178 PKT_user_id *uid = NULL;
3179 int changed=0;
3181 for( node = pub_keyblock; node; node = node->next ) {
3182 if( node->pkt->pkttype == PKT_USER_ID ) {
3183 uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
3185 else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3186 int okay, valid, selfsig, inv_sig, no_key, other_err;
3188 tty_printf("uid ");
3189 tty_print_utf8_string( uid->name, uid->len );
3190 tty_printf("\n");
3192 okay = inv_sig = no_key = other_err = 0;
3193 if(opt.with_colons)
3194 valid = print_and_check_one_sig_colon( pub_keyblock, node,
3195 &inv_sig, &no_key, &other_err,
3196 &selfsig, 1 );
3197 else
3198 valid = print_and_check_one_sig( pub_keyblock, node,
3199 &inv_sig, &no_key, &other_err,
3200 &selfsig, 1 );
3202 if( valid ) {
3203 okay = cpr_get_answer_yes_no_quit(
3204 "keyedit.delsig.valid",
3205 _("Delete this good signature? (y/N/q)"));
3207 /* Only update trust if we delete a good signature.
3208 The other two cases do not affect trust. */
3209 if(okay)
3210 update_trust=1;
3212 else if( inv_sig || other_err )
3213 okay = cpr_get_answer_yes_no_quit(
3214 "keyedit.delsig.invalid",
3215 _("Delete this invalid signature? (y/N/q)"));
3216 else if( no_key )
3217 okay = cpr_get_answer_yes_no_quit(
3218 "keyedit.delsig.unknown",
3219 _("Delete this unknown signature? (y/N/q)"));
3221 if( okay == -1 )
3222 break;
3223 if( okay && selfsig && !cpr_get_answer_is_yes(
3224 "keyedit.delsig.selfsig",
3225 _("Really delete this self-signature? (y/N)") ))
3226 okay = 0;
3227 if( okay ) {
3228 delete_kbnode( node );
3229 changed++;
3233 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3234 uid = NULL;
3237 if( changed ) {
3238 commit_kbnode( &pub_keyblock );
3239 tty_printf( changed == 1? _("Deleted %d signature.\n")
3240 : _("Deleted %d signatures.\n"), changed );
3242 else
3243 tty_printf( _("Nothing deleted.\n") );
3245 return changed;
3248 static int
3249 menu_clean(KBNODE keyblock,int self_only)
3251 KBNODE uidnode;
3252 int modified=0,select_all=!count_selected_uids(keyblock);
3254 for(uidnode=keyblock->next;
3255 uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
3256 uidnode=uidnode->next)
3258 if(uidnode->pkt->pkttype==PKT_USER_ID
3259 && (uidnode->flag&NODFLG_SELUID || select_all))
3261 int uids=0,sigs=0;
3262 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3263 uidnode->pkt->pkt.user_id->len,
3266 clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
3267 if(uids)
3269 const char *reason;
3271 if(uidnode->pkt->pkt.user_id->is_revoked)
3272 reason=_("revoked");
3273 else if(uidnode->pkt->pkt.user_id->is_expired)
3274 reason=_("expired");
3275 else
3276 reason=_("invalid");
3278 tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
3280 modified=1;
3282 else if(sigs)
3284 tty_printf(sigs==1?
3285 _("User ID \"%s\": %d signature removed\n") :
3286 _("User ID \"%s\": %d signatures removed\n"),
3287 user,sigs);
3289 modified=1;
3291 else
3293 tty_printf (self_only==1?
3294 _("User ID \"%s\": already minimized\n") :
3295 _("User ID \"%s\": already clean\n"),
3296 user);
3299 xfree(user);
3303 return modified;
3306 /****************
3307 * Remove some of the secondary keys
3309 static void
3310 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3312 KBNODE node;
3313 int selected=0;
3315 for( node = pub_keyblock; node; node = node->next ) {
3316 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3317 selected = node->flag & NODFLG_SELKEY;
3318 if( selected ) {
3319 delete_kbnode( node );
3320 if( sec_keyblock ) {
3321 KBNODE snode;
3322 int s_selected = 0;
3323 u32 ki[2];
3325 keyid_from_pk( node->pkt->pkt.public_key, ki );
3326 for( snode = sec_keyblock; snode; snode = snode->next ) {
3327 if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3328 u32 ki2[2];
3330 keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
3331 s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
3332 if( s_selected )
3333 delete_kbnode( snode );
3335 else if( s_selected
3336 && snode->pkt->pkttype == PKT_SIGNATURE )
3337 delete_kbnode( snode );
3338 else
3339 s_selected = 0;
3344 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3345 delete_kbnode( node );
3346 else
3347 selected = 0;
3349 commit_kbnode( &pub_keyblock );
3350 if( sec_keyblock )
3351 commit_kbnode( &sec_keyblock );
3353 /* No need to set update_trust here since signing keys are no
3354 longer used to certify other keys, so there is no change in
3355 trust when revoking/removing them */
3359 /****************
3360 * Ask for a new revoker, do the selfsignature and put it into
3361 * both keyblocks.
3362 * Return true if there is a new revoker
3364 static int
3365 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
3367 PKT_public_key *pk=NULL,*revoker_pk=NULL;
3368 PKT_secret_key *sk=NULL;
3369 PKT_signature *sig=NULL;
3370 PACKET *pkt;
3371 struct revocation_key revkey;
3372 size_t fprlen;
3373 int rc;
3375 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3376 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3378 pk=pub_keyblock->pkt->pkt.public_key;
3380 if(pk->numrevkeys==0 && pk->version==3)
3382 /* It is legal but bad for compatibility to add a revoker to a
3383 v3 key as it means that PGP2 will not be able to use that key
3384 anymore. Also, PGP may not expect a revoker on a v3 key.
3385 Don't bother to ask this if the key already has a revoker -
3386 any damage has already been done at that point. -dms */
3387 if(opt.expert)
3389 tty_printf(_("WARNING: This is a PGP 2.x-style key. "
3390 "Adding a designated revoker may cause\n"
3391 " some versions of PGP to reject this key.\n"));
3393 if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
3394 _("Are you sure you still want "
3395 "to add it? (y/N) ")))
3396 return 0;
3398 else
3400 tty_printf(_("You may not add a designated revoker to "
3401 "a PGP 2.x-style key.\n"));
3402 return 0;
3406 sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3408 for(;;)
3410 char *answer;
3412 if(revoker_pk)
3413 free_public_key(revoker_pk);
3415 revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
3417 tty_printf("\n");
3419 answer=cpr_get_utf8("keyedit.add_revoker",
3420 _("Enter the user ID of the designated revoker: "));
3421 if(answer[0]=='\0' || answer[0]=='\004')
3423 xfree(answer);
3424 goto fail;
3427 /* Note that I'm requesting CERT here, which usually implies
3428 primary keys only, but some casual testing shows that PGP and
3429 GnuPG both can handle a designated revokation from a
3430 subkey. */
3431 revoker_pk->req_usage=PUBKEY_USAGE_CERT;
3432 rc=get_pubkey_byname (NULL, revoker_pk,answer,NULL,NULL,1, 1);
3433 if(rc)
3435 log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
3436 xfree(answer);
3437 continue;
3440 xfree(answer);
3442 fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
3443 if(fprlen!=20)
3445 log_error(_("cannot appoint a PGP 2.x style key as a "
3446 "designated revoker\n"));
3447 continue;
3450 revkey.class=0x80;
3451 if(sensitive)
3452 revkey.class|=0x40;
3453 revkey.algid=revoker_pk->pubkey_algo;
3455 if(cmp_public_keys(revoker_pk,pk)==0)
3457 /* This actually causes no harm (after all, a key that
3458 designates itself as a revoker is the same as a
3459 regular key), but it's easy enough to check. */
3460 log_error(_("you cannot appoint a key as its own "
3461 "designated revoker\n"));
3463 continue;
3466 keyid_from_pk(pk,NULL);
3468 /* Does this revkey already exist? */
3469 if(!pk->revkey && pk->numrevkeys)
3470 BUG();
3471 else
3473 int i;
3475 for(i=0;i<pk->numrevkeys;i++)
3477 if(memcmp(&pk->revkey[i],&revkey,
3478 sizeof(struct revocation_key))==0)
3480 char buf[50];
3482 log_error(_("this key has already been designated "
3483 "as a revoker\n"));
3485 sprintf(buf,"%08lX%08lX",
3486 (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
3487 write_status_text(STATUS_ALREADY_SIGNED,buf);
3489 break;
3493 if(i<pk->numrevkeys)
3494 continue;
3497 print_pubkey_info(NULL,revoker_pk);
3498 print_fingerprint(revoker_pk,NULL,2);
3499 tty_printf("\n");
3501 tty_printf(_("WARNING: appointing a key as a designated revoker "
3502 "cannot be undone!\n"));
3504 tty_printf("\n");
3506 if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
3507 _("Are you sure you want to appoint this "
3508 "key as a designated revoker? (y/N) ")))
3509 continue;
3511 free_public_key(revoker_pk);
3512 revoker_pk=NULL;
3513 break;
3516 /* The 1F signature must be at least v4 to carry the revocation key
3517 subpacket. */
3518 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3519 keygen_add_revkey,&revkey );
3520 if( rc )
3522 log_error("signing failed: %s\n", g10_errstr(rc) );
3523 goto fail;
3526 free_secret_key(sk);
3527 sk=NULL;
3529 /* insert into secret keyblock */
3530 pkt = xmalloc_clear( sizeof *pkt );
3531 pkt->pkttype = PKT_SIGNATURE;
3532 pkt->pkt.signature = copy_signature(NULL, sig);
3533 insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3535 /* insert into public keyblock */
3536 pkt = xmalloc_clear( sizeof *pkt );
3537 pkt->pkttype = PKT_SIGNATURE;
3538 pkt->pkt.signature = sig;
3539 insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3541 return 1;
3543 fail:
3544 if(sk)
3545 free_secret_key(sk);
3546 if(sig)
3547 free_seckey_enc(sig);
3548 if(revoker_pk)
3549 free_public_key(revoker_pk);
3551 return 0;
3555 static int
3556 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3558 int n1, signumber, rc;
3559 u32 expiredate;
3560 int mainkey=0;
3561 PKT_secret_key *sk; /* copy of the main sk */
3562 PKT_public_key *main_pk, *sub_pk;
3563 PKT_user_id *uid;
3564 KBNODE node;
3565 u32 keyid[2];
3567 if( count_selected_keys( sec_keyblock ) ) {
3568 tty_printf(_("Please remove selections from the secret keys.\n"));
3569 return 0;
3572 n1 = count_selected_keys( pub_keyblock );
3573 if( n1 > 1 ) {
3574 tty_printf(_("Please select at most one subkey.\n"));
3575 return 0;
3577 else if( n1 )
3578 tty_printf(_("Changing expiration time for a subkey.\n"));
3579 else
3581 tty_printf(_("Changing expiration time for the primary key.\n"));
3582 mainkey=1;
3583 no_primary_warning(pub_keyblock);
3586 expiredate = ask_expiredate();
3587 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3588 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3590 /* Now we can actually change the self signature(s) */
3591 main_pk = sub_pk = NULL;
3592 uid = NULL;
3593 signumber = 0;
3594 for( node=pub_keyblock; node; node = node->next ) {
3595 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3596 main_pk = node->pkt->pkt.public_key;
3597 keyid_from_pk( main_pk, keyid );
3598 main_pk->expiredate = expiredate;
3600 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3601 && (node->flag & NODFLG_SELKEY ) ) {
3602 sub_pk = node->pkt->pkt.public_key;
3603 sub_pk->expiredate = expiredate;
3605 else if( node->pkt->pkttype == PKT_USER_ID )
3606 uid = node->pkt->pkt.user_id;
3607 else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3608 && ( mainkey || sub_pk ) ) {
3609 PKT_signature *sig = node->pkt->pkt.signature;
3610 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3611 && ( (mainkey && uid
3612 && uid->created && (sig->sig_class&~3) == 0x10)
3613 || (!mainkey && sig->sig_class == 0x18) )
3614 && sig->flags.chosen_selfsig )
3616 /* this is a selfsignature which is to be replaced */
3617 PKT_signature *newsig;
3618 PACKET *newpkt;
3619 KBNODE sn;
3620 int signumber2 = 0;
3622 signumber++;
3624 if( (mainkey && main_pk->version < 4)
3625 || (!mainkey && sub_pk->version < 4 ) ) {
3626 log_info(_(
3627 "You can't change the expiration date of a v3 key\n"));
3628 free_secret_key( sk );
3629 return 0;
3632 /* find the corresponding secret self-signature */
3633 for( sn=sec_keyblock; sn; sn = sn->next ) {
3634 if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3635 PKT_signature *b = sn->pkt->pkt.signature;
3636 if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3637 && sig->sig_class == b->sig_class
3638 && ++signumber2 == signumber )
3639 break;
3642 if( !sn )
3643 log_info(_("No corresponding signature in secret ring\n"));
3645 if( mainkey )
3646 rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3647 sk, keygen_add_key_expire, main_pk);
3648 else
3649 rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3650 sk, keygen_add_key_expire, sub_pk );
3651 if( rc ) {
3652 log_error("make_keysig_packet failed: %s\n",
3653 g10_errstr(rc));
3654 free_secret_key( sk );
3655 return 0;
3657 /* replace the packet */
3658 newpkt = xmalloc_clear( sizeof *newpkt );
3659 newpkt->pkttype = PKT_SIGNATURE;
3660 newpkt->pkt.signature = newsig;
3661 free_packet( node->pkt );
3662 xfree( node->pkt );
3663 node->pkt = newpkt;
3664 if( sn ) {
3665 newpkt = xmalloc_clear( sizeof *newpkt );
3666 newpkt->pkttype = PKT_SIGNATURE;
3667 newpkt->pkt.signature = copy_signature( NULL, newsig );
3668 free_packet( sn->pkt );
3669 xfree( sn->pkt );
3670 sn->pkt = newpkt;
3672 sub_pk = NULL;
3677 free_secret_key( sk );
3678 update_trust=1;
3679 return 1;
3682 static int
3683 menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
3685 int rc,modified=0;
3686 PKT_public_key *main_pk;
3687 PKT_secret_key *main_sk,*sub_sk=NULL;
3688 KBNODE node;
3689 u32 timestamp;
3691 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3692 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3694 merge_keys_and_selfsig(pub_keyblock);
3695 main_pk=pub_keyblock->pkt->pkt.public_key;
3696 main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3697 keyid_from_pk(main_pk,NULL);
3699 /* We use the same timestamp for all backsigs so that we don't
3700 reveal information about the used machine. */
3701 timestamp = make_timestamp ();
3703 for(node=pub_keyblock;node;node=node->next)
3705 PKT_public_key *sub_pk=NULL;
3706 KBNODE node2,sig_pk=NULL,sig_sk=NULL;
3707 char *passphrase;
3709 if(sub_sk)
3711 free_secret_key(sub_sk);
3712 sub_sk=NULL;
3715 /* Find a signing subkey with no backsig */
3716 if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
3718 if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
3720 if(node->pkt->pkt.public_key->backsig)
3721 tty_printf(_("signing subkey %s is already cross-certified\n"),
3722 keystr_from_pk(node->pkt->pkt.public_key));
3723 else
3724 sub_pk=node->pkt->pkt.public_key;
3726 else
3727 tty_printf(_("subkey %s does not sign and so does"
3728 " not need to be cross-certified\n"),
3729 keystr_from_pk(node->pkt->pkt.public_key));
3732 if(!sub_pk)
3733 continue;
3735 /* Find the selected selfsig on this subkey */
3736 for(node2=node->next;
3737 node2 && node2->pkt->pkttype==PKT_SIGNATURE;
3738 node2=node2->next)
3739 if(node2->pkt->pkt.signature->version>=4
3740 && node2->pkt->pkt.signature->flags.chosen_selfsig)
3742 sig_pk=node2;
3743 break;
3746 if(!sig_pk)
3747 continue;
3749 /* Find the secret subkey that matches the public subkey */
3750 for(node2=sec_keyblock;node2;node2=node2->next)
3751 if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
3752 && !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
3754 sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
3755 break;
3758 if(!sub_sk)
3760 tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
3761 keystr_from_pk(sub_pk));
3762 continue;
3765 /* Now finally find the matching selfsig on the secret subkey.
3766 We can't use chosen_selfsig here (it's not set for secret
3767 keys), so we just pick the selfsig with the right class.
3768 This is what menu_expire does as well. */
3769 for(node2=node2->next;
3770 node2 && node2->pkt->pkttype!=PKT_SECRET_SUBKEY;
3771 node2=node2->next)
3772 if(node2->pkt->pkttype==PKT_SIGNATURE
3773 && node2->pkt->pkt.signature->version>=4
3774 && node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
3775 && node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
3776 && node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
3778 sig_sk=node2;
3779 break;
3782 /* Now we can get to work. We have a main key and secret part,
3783 a signing subkey with signature and secret part possibly with
3784 signature. */
3786 passphrase=get_last_passphrase();
3787 set_next_passphrase(passphrase);
3788 xfree(passphrase);
3790 rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk,
3791 timestamp);
3792 if(rc==0)
3794 PKT_signature *newsig;
3795 PACKET *newpkt;
3797 passphrase=get_last_passphrase();
3798 set_next_passphrase(passphrase);
3799 xfree(passphrase);
3801 rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
3802 NULL,sub_pk,main_sk,NULL,NULL);
3803 if(rc==0)
3805 /* Put the new sig into place on the pubkey */
3806 newpkt=xmalloc_clear(sizeof(*newpkt));
3807 newpkt->pkttype=PKT_SIGNATURE;
3808 newpkt->pkt.signature=newsig;
3809 free_packet(sig_pk->pkt);
3810 xfree(sig_pk->pkt);
3811 sig_pk->pkt=newpkt;
3813 if(sig_sk)
3815 /* Put the new sig into place on the seckey */
3816 newpkt=xmalloc_clear(sizeof(*newpkt));
3817 newpkt->pkttype=PKT_SIGNATURE;
3818 newpkt->pkt.signature=copy_signature(NULL,newsig);
3819 free_packet(sig_sk->pkt);
3820 xfree(sig_sk->pkt);
3821 sig_sk->pkt=newpkt;
3824 modified=1;
3826 else
3828 log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
3829 break;
3832 else
3834 log_error("make_backsig failed: %s\n",g10_errstr(rc));
3835 break;
3839 set_next_passphrase(NULL);
3841 free_secret_key(main_sk);
3842 if(sub_sk)
3843 free_secret_key(sub_sk);
3845 return modified;
3849 static int
3850 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3852 byte buf[1];
3854 /* first clear all primary uid flags so that we are sure none are
3855 * lingering around */
3856 delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
3857 delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3859 /* if opaque is set,we want to set the primary id */
3860 if (opaque) {
3861 buf[0] = 1;
3862 build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3865 return 0;
3870 * Set the primary uid flag for the selected UID. We will also reset
3871 * all other primary uid flags. For this to work with have to update
3872 * all the signature timestamps. If we would do this with the current
3873 * time, we lose quite a lot of information, so we use a a kludge to
3874 * do this: Just increment the timestamp by one second which is
3875 * sufficient to updated a signature during import.
3877 static int
3878 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3880 PKT_secret_key *sk; /* copy of the main sk */
3881 PKT_public_key *main_pk;
3882 PKT_user_id *uid;
3883 KBNODE node;
3884 u32 keyid[2];
3885 int selected;
3886 int attribute = 0;
3887 int modified = 0;
3889 if ( count_selected_uids (pub_keyblock) != 1 ) {
3890 tty_printf(_("Please select exactly one user ID.\n"));
3891 return 0;
3894 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3895 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3897 /* Now we can actually change the self signature(s) */
3898 main_pk = NULL;
3899 uid = NULL;
3900 selected = 0;
3902 /* Is our selected uid an attribute packet? */
3903 for ( node=pub_keyblock; node; node = node->next )
3904 if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3905 attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3907 for ( node=pub_keyblock; node; node = node->next ) {
3908 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3909 break; /* ready */
3911 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3912 main_pk = node->pkt->pkt.public_key;
3913 keyid_from_pk( main_pk, keyid );
3915 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3916 uid = node->pkt->pkt.user_id;
3917 selected = node->flag & NODFLG_SELUID;
3919 else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3920 PKT_signature *sig = node->pkt->pkt.signature;
3921 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3922 && (uid && (sig->sig_class&~3) == 0x10)
3923 && attribute == (uid->attrib_data!=NULL)
3924 && sig->flags.chosen_selfsig )
3926 if(sig->version < 4) {
3927 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3929 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3930 user);
3931 xfree(user);
3933 else {
3934 /* This is a selfsignature which is to be replaced.
3935 We can just ignore v3 signatures because they are
3936 not able to carry the primary ID flag. We also
3937 ignore self-sigs on user IDs that are not of the
3938 same type that we are making primary. That is, if
3939 we are making a user ID primary, we alter user IDs.
3940 If we are making an attribute packet primary, we
3941 alter attribute packets. */
3943 /* FIXME: We must make sure that we only have one
3944 self-signature per user ID here (not counting
3945 revocations) */
3946 PKT_signature *newsig;
3947 PACKET *newpkt;
3948 const byte *p;
3949 int action;
3951 /* see whether this signature has the primary UID flag */
3952 p = parse_sig_subpkt (sig->hashed,
3953 SIGSUBPKT_PRIMARY_UID, NULL );
3954 if ( !p )
3955 p = parse_sig_subpkt (sig->unhashed,
3956 SIGSUBPKT_PRIMARY_UID, NULL );
3957 if ( p && *p ) /* yes */
3958 action = selected? 0 : -1;
3959 else /* no */
3960 action = selected? 1 : 0;
3962 if (action) {
3963 int rc = update_keysig_packet (&newsig, sig,
3964 main_pk, uid, NULL,
3966 change_primary_uid_cb,
3967 action > 0? "x":NULL );
3968 if( rc ) {
3969 log_error ("update_keysig_packet failed: %s\n",
3970 g10_errstr(rc));
3971 free_secret_key( sk );
3972 return 0;
3974 /* replace the packet */
3975 newpkt = xmalloc_clear( sizeof *newpkt );
3976 newpkt->pkttype = PKT_SIGNATURE;
3977 newpkt->pkt.signature = newsig;
3978 free_packet( node->pkt );
3979 xfree( node->pkt );
3980 node->pkt = newpkt;
3981 modified = 1;
3988 free_secret_key( sk );
3989 return modified;
3994 * Set preferences to new values for the selected user IDs
3996 static int
3997 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3999 PKT_secret_key *sk; /* copy of the main sk */
4000 PKT_public_key *main_pk;
4001 PKT_user_id *uid;
4002 KBNODE node;
4003 u32 keyid[2];
4004 int selected, select_all;
4005 int modified = 0;
4007 no_primary_warning(pub_keyblock);
4009 select_all = !count_selected_uids (pub_keyblock);
4011 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4012 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4014 /* Now we can actually change the self signature(s) */
4015 main_pk = NULL;
4016 uid = NULL;
4017 selected = 0;
4018 for ( node=pub_keyblock; node; node = node->next ) {
4019 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4020 break; /* ready */
4022 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
4023 main_pk = node->pkt->pkt.public_key;
4024 keyid_from_pk( main_pk, keyid );
4026 else if ( node->pkt->pkttype == PKT_USER_ID ) {
4027 uid = node->pkt->pkt.user_id;
4028 selected = select_all || (node->flag & NODFLG_SELUID);
4030 else if ( main_pk && uid && selected
4031 && node->pkt->pkttype == PKT_SIGNATURE ) {
4032 PKT_signature *sig = node->pkt->pkt.signature;
4033 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4034 && (uid && (sig->sig_class&~3) == 0x10)
4035 && sig->flags.chosen_selfsig ) {
4036 if( sig->version < 4 ) {
4037 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4039 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4040 user);
4041 xfree(user);
4043 else {
4044 /* This is a selfsignature which is to be replaced
4045 * We have to ignore v3 signatures because they are
4046 * not able to carry the preferences */
4047 PKT_signature *newsig;
4048 PACKET *newpkt;
4049 int rc;
4051 rc = update_keysig_packet (&newsig, sig,
4052 main_pk, uid, NULL,
4054 keygen_upd_std_prefs,
4055 NULL );
4056 if( rc ) {
4057 log_error ("update_keysig_packet failed: %s\n",
4058 g10_errstr(rc));
4059 free_secret_key( sk );
4060 return 0;
4062 /* replace the packet */
4063 newpkt = xmalloc_clear( sizeof *newpkt );
4064 newpkt->pkttype = PKT_SIGNATURE;
4065 newpkt->pkt.signature = newsig;
4066 free_packet( node->pkt );
4067 xfree( node->pkt );
4068 node->pkt = newpkt;
4069 modified = 1;
4075 free_secret_key( sk );
4076 return modified;
4080 static int
4081 menu_set_keyserver_url (const char *url,
4082 KBNODE pub_keyblock, KBNODE sec_keyblock )
4084 PKT_secret_key *sk; /* copy of the main sk */
4085 PKT_public_key *main_pk;
4086 PKT_user_id *uid;
4087 KBNODE node;
4088 u32 keyid[2];
4089 int selected, select_all;
4090 int modified = 0;
4091 char *answer,*uri;
4093 no_primary_warning(pub_keyblock);
4095 if(url)
4096 answer=xstrdup(url);
4097 else
4099 answer=cpr_get_utf8("keyedit.add_keyserver",
4100 _("Enter your preferred keyserver URL: "));
4101 if(answer[0]=='\0' || answer[0]=='\004')
4103 xfree(answer);
4104 return 0;
4108 if(ascii_strcasecmp(answer,"none")==0)
4109 uri=NULL;
4110 else
4112 struct keyserver_spec *keyserver=NULL;
4113 /* Sanity check the format */
4114 keyserver=parse_keyserver_uri(answer,1,NULL,0);
4115 xfree(answer);
4116 if(!keyserver)
4118 log_info(_("could not parse keyserver URL\n"));
4119 return 0;
4121 uri=xstrdup(keyserver->uri);
4122 free_keyserver_spec(keyserver);
4125 select_all = !count_selected_uids (pub_keyblock);
4127 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4128 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4130 /* Now we can actually change the self signature(s) */
4131 main_pk = NULL;
4132 uid = NULL;
4133 selected = 0;
4134 for ( node=pub_keyblock; node; node = node->next )
4136 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4137 break; /* ready */
4139 if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4141 main_pk = node->pkt->pkt.public_key;
4142 keyid_from_pk( main_pk, keyid );
4144 else if ( node->pkt->pkttype == PKT_USER_ID )
4146 uid = node->pkt->pkt.user_id;
4147 selected = select_all || (node->flag & NODFLG_SELUID);
4149 else if ( main_pk && uid && selected
4150 && node->pkt->pkttype == PKT_SIGNATURE )
4152 PKT_signature *sig = node->pkt->pkt.signature;
4153 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4154 && (uid && (sig->sig_class&~3) == 0x10)
4155 && sig->flags.chosen_selfsig)
4157 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4158 if( sig->version < 4 )
4159 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4160 user);
4161 else
4163 /* This is a selfsignature which is to be replaced
4164 * We have to ignore v3 signatures because they are
4165 * not able to carry the subpacket. */
4166 PKT_signature *newsig;
4167 PACKET *newpkt;
4168 int rc;
4169 const byte *p;
4170 size_t plen;
4172 p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
4173 if(p && plen)
4175 tty_printf("Current preferred keyserver for user"
4176 " ID \"%s\": ",user);
4177 tty_print_utf8_string(p,plen);
4178 tty_printf("\n");
4179 if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
4180 uri?_("Are you sure you want to replace it? (y/N) "):
4181 _("Are you sure you want to delete it? (y/N) ")))
4182 continue;
4184 else if(uri==NULL)
4186 /* There is no current keyserver URL, so there
4187 is no point in trying to un-set it. */
4188 continue;
4191 rc = update_keysig_packet (&newsig, sig,
4192 main_pk, uid, NULL,
4194 keygen_add_keyserver_url, uri );
4195 if( rc )
4197 log_error ("update_keysig_packet failed: %s\n",
4198 g10_errstr(rc));
4199 free_secret_key( sk );
4200 xfree(uri);
4201 return 0;
4203 /* replace the packet */
4204 newpkt = xmalloc_clear( sizeof *newpkt );
4205 newpkt->pkttype = PKT_SIGNATURE;
4206 newpkt->pkt.signature = newsig;
4207 free_packet( node->pkt );
4208 xfree( node->pkt );
4209 node->pkt = newpkt;
4210 modified = 1;
4213 xfree(user);
4218 xfree(uri);
4219 free_secret_key( sk );
4220 return modified;
4223 static int
4224 menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
4226 PKT_secret_key *sk; /* copy of the main sk */
4227 PKT_public_key *main_pk;
4228 PKT_user_id *uid;
4229 KBNODE node;
4230 u32 keyid[2];
4231 int selected, select_all;
4232 int modified = 0;
4233 char *answer;
4234 struct notation *notation;
4236 no_primary_warning(pub_keyblock);
4238 if(string)
4239 answer=xstrdup(string);
4240 else
4242 answer=cpr_get_utf8("keyedit.add_notation",
4243 _("Enter the notation: "));
4244 if(answer[0]=='\0' || answer[0]=='\004')
4246 xfree(answer);
4247 return 0;
4251 if(ascii_strcasecmp(answer,"none")==0
4252 || ascii_strcasecmp(answer,"-")==0)
4253 notation=NULL; /* delete them all */
4254 else
4256 notation=string_to_notation(answer,0);
4257 if(!notation)
4259 xfree(answer);
4260 return 0;
4264 xfree(answer);
4266 select_all = !count_selected_uids (pub_keyblock);
4268 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4269 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4271 /* Now we can actually change the self signature(s) */
4272 main_pk = NULL;
4273 uid = NULL;
4274 selected = 0;
4275 for ( node=pub_keyblock; node; node = node->next )
4277 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4278 break; /* ready */
4280 if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4282 main_pk = node->pkt->pkt.public_key;
4283 keyid_from_pk( main_pk, keyid );
4285 else if ( node->pkt->pkttype == PKT_USER_ID )
4287 uid = node->pkt->pkt.user_id;
4288 selected = select_all || (node->flag & NODFLG_SELUID);
4290 else if ( main_pk && uid && selected
4291 && node->pkt->pkttype == PKT_SIGNATURE )
4293 PKT_signature *sig = node->pkt->pkt.signature;
4294 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4295 && (uid && (sig->sig_class&~3) == 0x10)
4296 && sig->flags.chosen_selfsig)
4298 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4299 if( sig->version < 4 )
4300 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4301 user);
4302 else
4304 PKT_signature *newsig;
4305 PACKET *newpkt;
4306 int rc,skip=0,addonly=1;
4308 if(sig->flags.notation)
4310 tty_printf("Current notations for user ID \"%s\":\n",
4311 user);
4312 tty_print_notations(-9,sig);
4314 else
4316 tty_printf("No notations on user ID \"%s\"\n",user);
4317 if(notation==NULL)
4319 /* There are no current notations, so there
4320 is no point in trying to un-set them. */
4321 continue;
4325 if(notation)
4327 struct notation *n;
4328 int deleting=0;
4330 notation->next=sig_to_notation(sig);
4332 for(n=notation->next;n;n=n->next)
4333 if(strcmp(n->name,notation->name)==0)
4335 if(notation->value)
4337 if(strcmp(n->value,notation->value)==0)
4339 if(notation->flags.ignore)
4341 /* Value match with a delete
4342 flag. */
4343 n->flags.ignore=1;
4344 deleting=1;
4346 else
4348 /* Adding the same notation
4349 twice, so don't add it at
4350 all. */
4351 skip=1;
4352 tty_printf("Skipping notation:"
4353 " %s=%s\n",
4354 notation->name,
4355 notation->value);
4356 break;
4360 else
4362 /* No value, so it means delete. */
4363 n->flags.ignore=1;
4364 deleting=1;
4367 if(n->flags.ignore)
4369 tty_printf("Removing notation: %s=%s\n",
4370 n->name,n->value);
4371 addonly=0;
4375 if(!notation->flags.ignore && !skip)
4376 tty_printf("Adding notation: %s=%s\n",
4377 notation->name,notation->value);
4379 /* We tried to delete, but had no matches */
4380 if(notation->flags.ignore && !deleting)
4381 continue;
4383 else
4385 tty_printf("Removing all notations\n");
4386 addonly=0;
4389 if(skip
4390 || (!addonly
4391 && !cpr_get_answer_is_yes("keyedit.confirm_notation",
4392 _("Proceed? (y/N) "))))
4393 continue;
4395 rc = update_keysig_packet (&newsig, sig,
4396 main_pk, uid, NULL,
4398 keygen_add_notations, notation );
4399 if( rc )
4401 log_error ("update_keysig_packet failed: %s\n",
4402 g10_errstr(rc));
4403 free_secret_key( sk );
4404 free_notation(notation);
4405 xfree(user);
4406 return 0;
4409 /* replace the packet */
4410 newpkt = xmalloc_clear( sizeof *newpkt );
4411 newpkt->pkttype = PKT_SIGNATURE;
4412 newpkt->pkt.signature = newsig;
4413 free_packet( node->pkt );
4414 xfree( node->pkt );
4415 node->pkt = newpkt;
4416 modified = 1;
4418 if(notation)
4420 /* Snip off the notation list from the sig */
4421 free_notation(notation->next);
4422 notation->next=NULL;
4425 xfree(user);
4431 free_notation(notation);
4432 free_secret_key( sk );
4433 return modified;
4437 /****************
4438 * Select one user id or remove all selection if index is 0.
4439 * Returns: True if the selection changed;
4441 static int
4442 menu_select_uid( KBNODE keyblock, int idx )
4444 KBNODE node;
4445 int i;
4447 /* first check that the index is valid */
4448 if( idx ) {
4449 for( i=0, node = keyblock; node; node = node->next ) {
4450 if( node->pkt->pkttype == PKT_USER_ID ) {
4451 if( ++i == idx )
4452 break;
4455 if( !node ) {
4456 tty_printf(_("No user ID with index %d\n"), idx );
4457 return 0;
4460 else { /* reset all */
4461 for( i=0, node = keyblock; node; node = node->next ) {
4462 if( node->pkt->pkttype == PKT_USER_ID )
4463 node->flag &= ~NODFLG_SELUID;
4465 return 1;
4467 /* and toggle the new index */
4468 for( i=0, node = keyblock; node; node = node->next ) {
4469 if( node->pkt->pkttype == PKT_USER_ID ) {
4470 if( ++i == idx ) {
4471 if( (node->flag & NODFLG_SELUID) )
4472 node->flag &= ~NODFLG_SELUID;
4473 else
4474 node->flag |= NODFLG_SELUID;
4479 return 1;
4482 /* Search in the keyblock for a uid that matches namehash */
4483 static int
4484 menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
4486 byte hash[NAMEHASH_LEN];
4487 KBNODE node;
4488 int i;
4490 assert(strlen(namehash)==NAMEHASH_LEN*2);
4492 for(i=0;i<NAMEHASH_LEN;i++)
4493 hash[i]=hextobyte(&namehash[i*2]);
4495 for(node=keyblock->next;node;node=node->next)
4497 if(node->pkt->pkttype==PKT_USER_ID)
4499 namehash_from_uid(node->pkt->pkt.user_id);
4500 if(memcmp(node->pkt->pkt.user_id->namehash,hash,NAMEHASH_LEN)==0)
4502 if(node->flag&NODFLG_SELUID)
4503 node->flag &= ~NODFLG_SELUID;
4504 else
4505 node->flag |= NODFLG_SELUID;
4507 break;
4512 if(!node)
4514 tty_printf(_("No user ID with hash %s\n"),namehash);
4515 return 0;
4518 return 1;
4521 /****************
4522 * Select secondary keys
4523 * Returns: True if the selection changed;
4525 static int
4526 menu_select_key( KBNODE keyblock, int idx )
4528 KBNODE node;
4529 int i;
4531 /* first check that the index is valid */
4532 if( idx ) {
4533 for( i=0, node = keyblock; node; node = node->next ) {
4534 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4535 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
4536 if( ++i == idx )
4537 break;
4540 if( !node ) {
4541 tty_printf(_("No subkey with index %d\n"), idx );
4542 return 0;
4545 else { /* reset all */
4546 for( i=0, node = keyblock; node; node = node->next ) {
4547 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4548 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
4549 node->flag &= ~NODFLG_SELKEY;
4551 return 1;
4553 /* and set the new index */
4554 for( i=0, node = keyblock; node; node = node->next ) {
4555 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4556 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
4557 if( ++i == idx ) {
4558 if( (node->flag & NODFLG_SELKEY) )
4559 node->flag &= ~NODFLG_SELKEY;
4560 else
4561 node->flag |= NODFLG_SELKEY;
4566 return 1;
4570 static int
4571 count_uids_with_flag( KBNODE keyblock, unsigned flag )
4573 KBNODE node;
4574 int i=0;
4576 for( node = keyblock; node; node = node->next )
4577 if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
4578 i++;
4579 return i;
4582 static int
4583 count_keys_with_flag( KBNODE keyblock, unsigned flag )
4585 KBNODE node;
4586 int i=0;
4588 for( node = keyblock; node; node = node->next )
4589 if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4590 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4591 && (node->flag & flag) )
4592 i++;
4593 return i;
4596 static int
4597 count_uids( KBNODE keyblock )
4599 KBNODE node;
4600 int i=0;
4602 for( node = keyblock; node; node = node->next )
4603 if( node->pkt->pkttype == PKT_USER_ID )
4604 i++;
4605 return i;
4609 /****************
4610 * Returns true if there is at least one selected user id
4612 static int
4613 count_selected_uids( KBNODE keyblock )
4615 return count_uids_with_flag( keyblock, NODFLG_SELUID);
4618 static int
4619 count_selected_keys( KBNODE keyblock )
4621 return count_keys_with_flag( keyblock, NODFLG_SELKEY);
4624 /* returns how many real (i.e. not attribute) uids are unmarked */
4625 static int
4626 real_uids_left( KBNODE keyblock )
4628 KBNODE node;
4629 int real=0;
4631 for(node=keyblock;node;node=node->next)
4632 if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
4633 !node->pkt->pkt.user_id->attrib_data)
4634 real++;
4636 return real;
4640 * Ask whether the signature should be revoked. If the user commits this,
4641 * flag bit MARK_A is set on the signature and the user ID.
4643 static void
4644 ask_revoke_sig( KBNODE keyblock, KBNODE node )
4646 int doit=0;
4647 PKT_user_id *uid;
4648 PKT_signature *sig = node->pkt->pkt.signature;
4649 KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4651 if( !unode ) {
4652 log_error("Oops: no user ID for signature\n");
4653 return;
4656 uid=unode->pkt->pkt.user_id;
4658 if(opt.with_colons)
4660 if(uid->attrib_data)
4661 printf("uat:::::::::%u %lu",uid->numattribs,uid->attrib_len);
4662 else
4664 printf("uid:::::::::");
4665 print_string (stdout, uid->name, uid->len, ':');
4668 printf("\n");
4670 print_and_check_one_sig_colon(keyblock,node,NULL,NULL,NULL,NULL,1);
4672 else
4674 char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
4675 unode->pkt->pkt.user_id->len,0);
4676 tty_printf(_("user ID: \"%s\"\n"),p);
4677 xfree(p);
4679 tty_printf(_("signed by your key %s on %s%s%s\n"),
4680 keystr(sig->keyid),datestr_from_sig(sig),
4681 sig->flags.exportable?"":_(" (non-exportable)"),"");
4683 if(sig->flags.expired)
4685 tty_printf(_("This signature expired on %s.\n"),
4686 expirestr_from_sig(sig));
4687 /* Use a different question so we can have different help text */
4688 doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
4689 _("Are you sure you still want to revoke it? (y/N) "));
4691 else
4692 doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
4693 _("Create a revocation certificate for this signature? (y/N) "));
4695 if(doit) {
4696 node->flag |= NODFLG_MARK_A;
4697 unode->flag |= NODFLG_MARK_A;
4701 /****************
4702 * Display all user ids of the current public key together with signatures
4703 * done by one of our keys. Then walk over all this sigs and ask the user
4704 * whether he wants to revoke this signature.
4705 * Return: True when the keyblock has changed.
4707 static int
4708 menu_revsig( KBNODE keyblock )
4710 PKT_signature *sig;
4711 PKT_public_key *primary_pk;
4712 KBNODE node;
4713 int changed = 0;
4714 int rc, any, skip=1, all=!count_selected_uids(keyblock);
4715 struct revocation_reason_info *reason = NULL;
4717 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
4719 /* FIXME: detect duplicates here */
4720 tty_printf(_("You have signed these user IDs on key %s:\n"),
4721 keystr_from_pk(keyblock->pkt->pkt.public_key));
4722 for( node = keyblock; node; node = node->next ) {
4723 node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
4724 if( node->pkt->pkttype == PKT_USER_ID ) {
4725 if( node->flag&NODFLG_SELUID || all ) {
4726 PKT_user_id *uid = node->pkt->pkt.user_id;
4727 /* Hmmm: Should we show only UIDs with a signature? */
4728 tty_printf(" ");
4729 tty_print_utf8_string( uid->name, uid->len );
4730 tty_printf("\n");
4731 skip=0;
4733 else
4734 skip=1;
4736 else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
4737 && ((sig = node->pkt->pkt.signature),
4738 !seckey_available(sig->keyid) ) )
4740 if( (sig->sig_class&~3) == 0x10 )
4742 tty_printf(" ");
4743 tty_printf(_("signed by your key %s on %s%s%s\n"),
4744 keystr(sig->keyid), datestr_from_sig(sig),
4745 sig->flags.exportable?"":_(" (non-exportable)"),
4746 sig->flags.revocable?"":_(" (non-revocable)"));
4747 if(sig->flags.revocable)
4748 node->flag |= NODFLG_SELSIG;
4750 else if( sig->sig_class == 0x30 )
4752 tty_printf(" ");
4753 tty_printf(_("revoked by your key %s on %s\n"),
4754 keystr(sig->keyid),datestr_from_sig(sig));
4759 tty_printf("\n");
4761 /* ask */
4762 for( node = keyblock; node; node = node->next ) {
4763 if( !(node->flag & NODFLG_SELSIG) )
4764 continue;
4765 ask_revoke_sig( keyblock, node );
4768 /* present selected */
4769 any = 0;
4770 for( node = keyblock; node; node = node->next ) {
4771 if( !(node->flag & NODFLG_MARK_A) )
4772 continue;
4773 if( !any ) {
4774 any = 1;
4775 tty_printf(_("You are about to revoke these signatures:\n"));
4777 if( node->pkt->pkttype == PKT_USER_ID ) {
4778 PKT_user_id *uid = node->pkt->pkt.user_id;
4779 tty_printf(" ");
4780 tty_print_utf8_string( uid->name, uid->len );
4781 tty_printf("\n");
4783 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
4784 sig = node->pkt->pkt.signature;
4785 tty_printf(" ");
4786 tty_printf(_("signed by your key %s on %s%s%s\n"),
4787 keystr(sig->keyid), datestr_from_sig(sig),"",
4788 sig->flags.exportable?"":_(" (non-exportable)") );
4791 if( !any )
4792 return 0; /* none selected */
4794 if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
4795 _("Really create the revocation certificates? (y/N) ")) )
4796 return 0; /* forget it */
4798 reason = ask_revocation_reason( 0, 1, 0 );
4799 if( !reason ) { /* user decided to cancel */
4800 return 0;
4803 /* now we can sign the user ids */
4804 reloop: /* (must use this, because we are modifing the list) */
4805 primary_pk = keyblock->pkt->pkt.public_key;
4806 for( node=keyblock; node; node = node->next ) {
4807 KBNODE unode;
4808 PACKET *pkt;
4809 struct sign_attrib attrib;
4810 PKT_secret_key *sk;
4812 if( !(node->flag & NODFLG_MARK_A)
4813 || node->pkt->pkttype != PKT_SIGNATURE )
4814 continue;
4815 unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4816 assert( unode ); /* we already checked this */
4818 memset( &attrib, 0, sizeof attrib );
4819 attrib.reason = reason;
4820 attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
4822 node->flag &= ~NODFLG_MARK_A;
4823 sk = xmalloc_secure_clear( sizeof *sk );
4824 if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
4825 log_info(_("no secret key\n"));
4826 continue;
4828 rc = make_keysig_packet( &sig, primary_pk,
4829 unode->pkt->pkt.user_id,
4830 NULL,
4832 0x30, 0, 0, 0, 0,
4833 sign_mk_attrib,
4834 &attrib );
4835 free_secret_key(sk);
4836 if( rc ) {
4837 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4838 release_revocation_reason_info( reason );
4839 return changed;
4841 changed = 1; /* we changed the keyblock */
4842 update_trust = 1;
4843 /* Are we revoking our own uid? */
4844 if(primary_pk->keyid[0]==sig->keyid[0] &&
4845 primary_pk->keyid[1]==sig->keyid[1])
4846 unode->pkt->pkt.user_id->is_revoked=1;
4847 pkt = xmalloc_clear( sizeof *pkt );
4848 pkt->pkttype = PKT_SIGNATURE;
4849 pkt->pkt.signature = sig;
4850 insert_kbnode( unode, new_kbnode(pkt), 0 );
4851 goto reloop;
4854 release_revocation_reason_info( reason );
4855 return changed;
4858 /* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
4859 keyblock changed. */
4860 static int
4861 menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
4863 PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
4864 PKT_secret_key *sk = copy_secret_key( NULL,
4865 sec_keyblock->pkt->pkt.secret_key );
4866 KBNODE node;
4867 int changed = 0;
4868 int rc;
4869 struct revocation_reason_info *reason = NULL;
4871 /* Note that this is correct as per the RFCs, but nevertheless
4872 somewhat meaningless in the real world. 1991 did define the 0x30
4873 sig class, but PGP 2.x did not actually implement it, so it would
4874 probably be safe to use v4 revocations everywhere. -ds */
4876 for( node = pub_keyblock; node; node = node->next )
4877 if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
4878 node->pkt->pkt.user_id->selfsigversion>3))
4880 if((reason = ask_revocation_reason( 0, 1, 4 )))
4881 break;
4882 else
4883 goto leave;
4886 reloop: /* (better this way because we are modifing the keyring) */
4887 for( node = pub_keyblock; node; node = node->next )
4888 if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
4890 PKT_user_id *uid=node->pkt->pkt.user_id;
4892 if(uid->is_revoked)
4894 char *user=utf8_to_native(uid->name,uid->len,0);
4895 log_info(_("user ID \"%s\" is already revoked\n"),user);
4896 xfree(user);
4898 else
4900 PACKET *pkt;
4901 PKT_signature *sig;
4902 struct sign_attrib attrib;
4903 u32 timestamp=make_timestamp();
4905 if(uid->created>=timestamp)
4907 /* Okay, this is a problem. The user ID selfsig was
4908 created in the future, so we need to warn the user and
4909 set our revocation timestamp one second after that so
4910 everything comes out clean. */
4912 log_info(_("WARNING: a user ID signature is dated %d"
4913 " seconds in the future\n"),uid->created-timestamp);
4915 timestamp=uid->created+1;
4918 memset( &attrib, 0, sizeof attrib );
4919 attrib.reason = reason;
4921 node->flag &= ~NODFLG_SELUID;
4923 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
4924 (reason==NULL)?3:0, timestamp, 0,
4925 sign_mk_attrib, &attrib );
4926 if( rc )
4928 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4929 goto leave;
4931 else
4933 pkt = xmalloc_clear( sizeof *pkt );
4934 pkt->pkttype = PKT_SIGNATURE;
4935 pkt->pkt.signature = sig;
4936 insert_kbnode( node, new_kbnode(pkt), 0 );
4938 /* If the trustdb has an entry for this key+uid then the
4939 trustdb needs an update. */
4940 if(!update_trust
4941 && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
4942 update_trust=1;
4944 changed = 1;
4945 node->pkt->pkt.user_id->is_revoked=1;
4947 goto reloop;
4952 if(changed)
4953 commit_kbnode( &pub_keyblock );
4955 leave:
4956 free_secret_key(sk);
4957 release_revocation_reason_info( reason );
4958 return changed;
4961 /****************
4962 * Revoke the whole key.
4964 static int
4965 menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
4967 PKT_public_key *pk=pub_keyblock->pkt->pkt.public_key;
4968 PKT_secret_key *sk;
4969 int rc,changed = 0;
4970 struct revocation_reason_info *reason;
4971 PACKET *pkt;
4972 PKT_signature *sig;
4974 if(pk->is_revoked)
4976 tty_printf(_("Key %s is already revoked.\n"),keystr_from_pk(pk));
4977 return 0;
4980 reason = ask_revocation_reason( 1, 0, 0 );
4981 /* user decided to cancel */
4982 if( !reason )
4983 return 0;
4985 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
4986 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk,
4987 0x20, 0, opt.force_v4_certs?4:0, 0, 0,
4988 revocation_reason_build_cb, reason );
4989 free_secret_key(sk);
4990 if( rc )
4992 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4993 goto scram;
4996 changed = 1; /* we changed the keyblock */
4998 pkt = xmalloc_clear( sizeof *pkt );
4999 pkt->pkttype = PKT_SIGNATURE;
5000 pkt->pkt.signature = sig;
5001 insert_kbnode( pub_keyblock, new_kbnode(pkt), 0 );
5002 commit_kbnode( &pub_keyblock );
5004 update_trust=1;
5006 scram:
5007 release_revocation_reason_info( reason );
5008 return changed;
5011 static int
5012 menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
5014 PKT_public_key *mainpk;
5015 KBNODE node;
5016 int changed = 0;
5017 int rc;
5018 struct revocation_reason_info *reason = NULL;
5020 reason = ask_revocation_reason( 1, 0, 0 );
5021 if( !reason ) { /* user decided to cancel */
5022 return 0;
5025 reloop: /* (better this way because we are modifing the keyring) */
5026 mainpk = pub_keyblock->pkt->pkt.public_key;
5027 for( node = pub_keyblock; node; node = node->next ) {
5028 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
5029 && (node->flag & NODFLG_SELKEY) ) {
5030 PACKET *pkt;
5031 PKT_signature *sig;
5032 PKT_secret_key *sk;
5033 PKT_public_key *subpk = node->pkt->pkt.public_key;
5034 struct sign_attrib attrib;
5036 if(subpk->is_revoked)
5038 tty_printf(_("Subkey %s is already revoked.\n"),
5039 keystr_from_pk(subpk));
5040 continue;
5043 memset( &attrib, 0, sizeof attrib );
5044 attrib.reason = reason;
5046 node->flag &= ~NODFLG_SELKEY;
5047 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
5048 rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
5049 0x28, 0, 0, 0, 0,
5050 sign_mk_attrib, &attrib );
5051 free_secret_key(sk);
5052 if( rc ) {
5053 log_error(_("signing failed: %s\n"), g10_errstr(rc));
5054 release_revocation_reason_info( reason );
5055 return changed;
5057 changed = 1; /* we changed the keyblock */
5059 pkt = xmalloc_clear( sizeof *pkt );
5060 pkt->pkttype = PKT_SIGNATURE;
5061 pkt->pkt.signature = sig;
5062 insert_kbnode( node, new_kbnode(pkt), 0 );
5063 goto reloop;
5066 commit_kbnode( &pub_keyblock );
5067 /*commit_kbnode( &sec_keyblock );*/
5069 /* No need to set update_trust here since signing keys no longer
5070 are used to certify other keys, so there is no change in trust
5071 when revoking/removing them */
5073 release_revocation_reason_info( reason );
5074 return changed;
5077 /* Note that update_ownertrust is going to mark the trustdb dirty when
5078 enabling or disabling a key. This is arguably sub-optimal as
5079 disabled keys are still counted in the web of trust, but perhaps
5080 not worth adding extra complexity to change. -ds */
5081 static int
5082 enable_disable_key( KBNODE keyblock, int disable )
5084 PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
5085 ->pkt->pkt.public_key;
5086 unsigned int trust, newtrust;
5088 trust = newtrust = get_ownertrust (pk);
5089 newtrust &= ~TRUST_FLAG_DISABLED;
5090 if( disable )
5091 newtrust |= TRUST_FLAG_DISABLED;
5092 if( trust == newtrust )
5093 return 0; /* already in that state */
5094 update_ownertrust(pk, newtrust );
5095 return 0;
5099 static void
5100 menu_showphoto( KBNODE keyblock )
5102 KBNODE node;
5103 int select_all = !count_selected_uids(keyblock);
5104 int count=0;
5105 PKT_public_key *pk=NULL;
5107 /* Look for the public key first. We have to be really, really,
5108 explicit as to which photo this is, and what key it is a UID on
5109 since people may want to sign it. */
5111 for( node = keyblock; node; node = node->next )
5113 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
5114 pk = node->pkt->pkt.public_key;
5115 else if( node->pkt->pkttype == PKT_USER_ID )
5117 PKT_user_id *uid = node->pkt->pkt.user_id;
5118 count++;
5120 if((select_all || (node->flag & NODFLG_SELUID)) &&
5121 uid->attribs!=NULL)
5123 int i;
5125 for(i=0;i<uid->numattribs;i++)
5127 byte type;
5128 u32 size;
5130 if(uid->attribs[i].type==ATTRIB_IMAGE &&
5131 parse_image_header(&uid->attribs[i],&type,&size))
5133 tty_printf(_("Displaying %s photo ID of size %ld for "
5134 "key %s (uid %d)\n"),
5135 image_type_to_string(type,1),
5136 (ulong)size,keystr_from_pk(pk),count);
5137 show_photos(&uid->attribs[i],1,pk,NULL,uid);