2008-02-01 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / keyedit.c
blobc81594be24144957f4dd050f664bf32c0d4e8c71
1 /* keyedit.c - keyedit stuff
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 * 2006, 2007 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 tty_printf(_("Key is protected.\n"));
1155 rc = check_secret_key( sk, 0 );
1156 if( !rc )
1157 passphrase = get_last_passphrase();
1159 break;
1162 /* Unprotect all subkeys (use the supplied passphrase or ask)*/
1163 for(node=keyblock; !rc && node; node = node->next ) {
1164 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1165 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1166 if ( !(subsk->is_protected
1167 && (subsk->protect.s2k.mode == 1001
1168 || subsk->protect.s2k.mode == 1002))) {
1169 set_next_passphrase( passphrase );
1170 rc = check_secret_key( subsk, 0 );
1171 if( !rc && !passphrase )
1172 passphrase = get_last_passphrase();
1177 if( rc )
1178 tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
1179 else {
1180 DEK *dek = NULL;
1181 STRING2KEY *s2k = xmalloc_secure( sizeof *s2k );
1182 const char *errtext = NULL;
1184 tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
1186 set_next_passphrase( NULL );
1187 for(;;) {
1188 int canceled;
1190 s2k->mode = opt.s2k_mode;
1191 s2k->hash_algo = S2K_DIGEST_ALGO;
1192 dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
1193 s2k, 2, errtext, &canceled);
1194 if (!dek && canceled) {
1195 rc = GPG_ERR_CANCELED;
1196 break;
1198 else if( !dek ) {
1199 errtext = N_("passphrase not correctly repeated; try again");
1200 tty_printf ("%s.\n", _(errtext));
1202 else if( !dek->keylen ) {
1203 rc = 0;
1204 tty_printf(_( "You don't want a passphrase -"
1205 " this is probably a *bad* idea!\n\n"));
1206 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
1207 _("Do you really want to do this? (y/N) ")))
1209 changed++;
1210 break;
1213 else { /* okay */
1214 rc = 0;
1215 if( !no_primary_secrets ) {
1216 sk->protect.algo = dek->algo;
1217 sk->protect.s2k = *s2k;
1218 rc = protect_secret_key( sk, dek );
1220 for(node=keyblock; !rc && node; node = node->next ) {
1221 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1222 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1223 if ( !(subsk->is_protected
1224 && (subsk->protect.s2k.mode == 1001
1225 || subsk->protect.s2k.mode == 1002))) {
1226 subsk->protect.algo = dek->algo;
1227 subsk->protect.s2k = *s2k;
1228 rc = protect_secret_key( subsk, dek );
1232 if( rc )
1233 log_error("protect_secret_key failed: %s\n",
1234 g10_errstr(rc) );
1235 else
1236 changed++;
1237 break;
1240 xfree(s2k);
1241 xfree(dek);
1244 leave:
1245 xfree( passphrase );
1246 set_next_passphrase( NULL );
1247 return changed && !rc;
1251 /****************
1252 * There are some keys out (due to a bug in gnupg), where the sequence
1253 * of the packets is wrong. This function fixes that.
1254 * Returns: true if the keyblock has been fixed.
1256 * Note: This function does not work if there is more than one user ID.
1258 static int
1259 fix_keyblock( KBNODE keyblock )
1261 KBNODE node, last, subkey;
1262 int fixed=0;
1264 /* locate key signatures of class 0x10..0x13 behind sub key packets */
1265 for( subkey=last=NULL, node = keyblock; node;
1266 last=node, node = node->next ) {
1267 switch( node->pkt->pkttype ) {
1268 case PKT_PUBLIC_SUBKEY:
1269 case PKT_SECRET_SUBKEY:
1270 if( !subkey )
1271 subkey = last; /* actually it is the one before the subkey */
1272 break;
1273 case PKT_SIGNATURE:
1274 if( subkey ) {
1275 PKT_signature *sig = node->pkt->pkt.signature;
1276 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1277 log_info(_(
1278 "moving a key signature to the correct place\n"));
1279 last->next = node->next;
1280 node->next = subkey->next;
1281 subkey->next = node;
1282 node = last;
1283 fixed=1;
1286 break;
1287 default: break;
1291 return fixed;
1294 static int
1295 parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
1297 const char *p=str;
1299 while(*p)
1301 if(ascii_strncasecmp(p,"l",1)==0)
1303 *localsig=1;
1304 p++;
1306 else if(ascii_strncasecmp(p,"nr",2)==0)
1308 *nonrevokesig=1;
1309 p+=2;
1311 else if(ascii_strncasecmp(p,"t",1)==0)
1313 *trustsig=1;
1314 p++;
1316 else
1317 return 0;
1320 return 1;
1324 /****************
1325 * Menu driven key editor. If seckey_check is true, then a secret key
1326 * that matches username will be looked for. If it is false, not all
1327 * commands will be available.
1329 * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1332 /* Need an SK for this command */
1333 #define KEYEDIT_NEED_SK 1
1334 /* Cannot be viewing the SK for this command */
1335 #define KEYEDIT_NOT_SK 2
1336 /* Must be viewing the SK for this command */
1337 #define KEYEDIT_ONLY_SK 4
1338 /* Match the tail of the string */
1339 #define KEYEDIT_TAIL_MATCH 8
1341 enum cmdids
1343 cmdNONE = 0,
1344 cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1345 cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
1346 cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
1347 cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
1348 cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
1349 cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
1350 cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN,
1351 cmdMINIMIZE, cmdNOP
1354 static struct
1356 const char *name;
1357 enum cmdids id;
1358 int flags;
1359 const char *desc;
1360 } cmds[] =
1362 { "quit" , cmdQUIT , 0, N_("quit this menu") },
1363 { "q" , cmdQUIT , 0, NULL },
1364 { "save" , cmdSAVE , 0, N_("save and quit") },
1365 { "help" , cmdHELP , 0, N_("show this help") },
1366 { "?" , cmdHELP , 0, NULL },
1367 { "fpr" , cmdFPR , 0, N_("show key fingerprint") },
1368 { "list" , cmdLIST , 0, N_("list key and user IDs") },
1369 { "l" , cmdLIST , 0, NULL },
1370 { "uid" , cmdSELUID , 0, N_("select user ID N") },
1371 { "key" , cmdSELKEY , 0, N_("select subkey N") },
1372 { "check" , cmdCHECK , 0, N_("check signatures") },
1373 { "c" , cmdCHECK , 0, NULL },
1374 { "cross-certify", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1375 { "backsign", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1376 { "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
1377 N_("sign selected user IDs [* see below for related commands]") },
1378 { "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
1379 /* "lsign" and friends will never match since "sign" comes first
1380 and it is a tail match. They are just here so they show up in
1381 the help menu. */
1382 { "lsign" , cmdNOP , 0, N_("sign selected user IDs locally") },
1383 { "tsign" , cmdNOP , 0,
1384 N_("sign selected user IDs with a trust signature") },
1385 { "nrsign" , cmdNOP , 0,
1386 N_("sign selected user IDs with a non-revocable signature") },
1388 { "debug" , cmdDEBUG , 0, NULL },
1389 { "adduid" , cmdADDUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1390 N_("add a user ID") },
1391 { "addphoto", cmdADDPHOTO , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1392 N_("add a photo ID") },
1393 { "deluid" , cmdDELUID , KEYEDIT_NOT_SK,
1394 N_("delete selected user IDs") },
1395 /* delphoto is really deluid in disguise */
1396 { "delphoto", cmdDELUID , KEYEDIT_NOT_SK, NULL },
1398 { "addkey" , cmdADDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1399 N_("add a subkey") },
1401 #ifdef ENABLE_CARD_SUPPORT
1402 { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1403 N_("add a key to a smartcard") },
1404 { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1405 N_("move a key to a smartcard")},
1406 { "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1407 N_("move a backup key to a smartcard")},
1408 #endif /*ENABLE_CARD_SUPPORT*/
1410 { "delkey" , cmdDELKEY , KEYEDIT_NOT_SK,
1411 N_("delete selected subkeys") },
1412 { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1413 N_("add a revocation key") },
1414 { "delsig" , cmdDELSIG , KEYEDIT_NOT_SK,
1415 N_("delete signatures from the selected user IDs") },
1416 { "expire" , cmdEXPIRE , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1417 N_("change the expiration date for the key or selected subkeys") },
1418 { "primary" , cmdPRIMARY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1419 N_("flag the selected user ID as primary")},
1420 { "toggle" , cmdTOGGLE , KEYEDIT_NEED_SK,
1421 N_("toggle between the secret and public key listings") },
1422 { "t" , cmdTOGGLE , KEYEDIT_NEED_SK, NULL },
1423 { "pref" , cmdPREF , KEYEDIT_NOT_SK,
1424 N_("list preferences (expert)")},
1425 { "showpref", cmdSHOWPREF , KEYEDIT_NOT_SK,
1426 N_("list preferences (verbose)") },
1427 { "setpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1428 N_("set preference list for the selected user IDs") },
1429 /* Alias */
1430 { "updpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1432 { "keyserver",cmdPREFKS , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1433 N_("set the preferred keyserver URL for the selected user IDs")},
1434 { "notation", cmdNOTATION , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1435 N_("set a notation for the selected user IDs")},
1436 { "passwd" , cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1437 N_("change the passphrase") },
1438 /* Alias */
1439 { "password", cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1441 { "trust" , cmdTRUST , KEYEDIT_NOT_SK, N_("change the ownertrust") },
1442 { "revsig" , cmdREVSIG , KEYEDIT_NOT_SK,
1443 N_("revoke signatures on the selected user IDs") },
1444 { "revuid" , cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1445 N_("revoke selected user IDs") },
1446 /* Alias */
1447 { "revphoto", cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1449 { "revkey" , cmdREVKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1450 N_("revoke key or selected subkeys") },
1451 { "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
1452 { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
1453 { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
1454 { "clean", cmdCLEAN , KEYEDIT_NOT_SK,
1455 N_("compact unusable user IDs and remove unusable signatures from key")},
1456 { "minimize", cmdMINIMIZE , KEYEDIT_NOT_SK,
1457 N_("compact unusable user IDs and remove all signatures from key") },
1458 { NULL, cmdNONE, 0, NULL }
1461 #ifdef HAVE_LIBREADLINE
1463 /* These two functions are used by readline for command completion. */
1465 static char *
1466 command_generator(const char *text,int state)
1468 static int list_index,len;
1469 const char *name;
1471 /* If this is a new word to complete, initialize now. This includes
1472 saving the length of TEXT for efficiency, and initializing the
1473 index variable to 0. */
1474 if(!state)
1476 list_index=0;
1477 len=strlen(text);
1480 /* Return the next partial match */
1481 while((name=cmds[list_index].name))
1483 /* Only complete commands that have help text */
1484 if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1485 return strdup(name);
1488 return NULL;
1491 static char **
1492 keyedit_completion(const char *text, int start, int end)
1494 /* If we are at the start of a line, we try and command-complete.
1495 If not, just do nothing for now. */
1497 if(start==0)
1498 return rl_completion_matches(text,command_generator);
1500 rl_attempted_completion_over=1;
1502 return NULL;
1504 #endif /* HAVE_LIBREADLINE */
1507 void
1508 keyedit_menu( const char *username, strlist_t locusr,
1509 strlist_t commands, int quiet, int seckey_check )
1511 enum cmdids cmd = 0;
1512 int rc = 0;
1513 KBNODE keyblock = NULL;
1514 KEYDB_HANDLE kdbhd = NULL;
1515 KBNODE sec_keyblock = NULL;
1516 KEYDB_HANDLE sec_kdbhd = NULL;
1517 KBNODE cur_keyblock;
1518 char *answer = NULL;
1519 int redisplay = 1;
1520 int modified = 0;
1521 int sec_modified = 0;
1522 int toggle;
1523 int have_commands = !!commands;
1525 if ( opt.command_fd != -1 )
1527 else if( opt.batch && !have_commands )
1529 log_error(_("can't do this in batch mode\n"));
1530 goto leave;
1533 #ifdef HAVE_W32_SYSTEM
1534 /* Due to Windows peculiarities we need to make sure that the
1535 trustdb stale check is done before we open another file
1536 (i.e. by searching for a key). In theory we could make sure
1537 that the files are closed after use but the open/close caches
1538 inhibits that and flushing the cache right before the stale
1539 check is not easy to implement. Thus we take the easy way out
1540 and run the stale check as early as possible. Note, that for
1541 non- W32 platforms it is run indirectly trough a call to
1542 get_validity (). */
1543 check_trustdb_stale ();
1544 #endif
1546 /* Get the public key */
1547 rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1548 if( rc )
1549 goto leave;
1550 if( fix_keyblock( keyblock ) )
1551 modified++;
1552 if( collapse_uids( &keyblock ) )
1553 modified++;
1554 reorder_keyblock(keyblock);
1555 /* We modified the keyblock, so let's make sure the flags are
1556 right. */
1557 if (modified)
1558 merge_keys_and_selfsig (keyblock);
1560 if(seckey_check)
1561 {/* see whether we have a matching secret key */
1562 PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1564 sec_kdbhd = keydb_new (1);
1566 byte afp[MAX_FINGERPRINT_LEN];
1567 size_t an;
1569 fingerprint_from_pk (pk, afp, &an);
1570 while (an < MAX_FINGERPRINT_LEN)
1571 afp[an++] = 0;
1572 rc = keydb_search_fpr (sec_kdbhd, afp);
1574 if (!rc)
1576 rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1577 if (rc)
1579 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1580 username, g10_errstr(rc));
1582 else
1584 merge_keys_and_selfsig( sec_keyblock );
1585 if( fix_keyblock( sec_keyblock ) )
1586 sec_modified++;
1590 if (rc) {
1591 sec_keyblock = NULL;
1592 keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1593 rc = 0;
1596 if( sec_keyblock && !quiet )
1597 tty_printf(_("Secret key is available.\n"));
1600 toggle = 0;
1601 cur_keyblock = keyblock;
1602 for(;;) { /* main loop */
1603 int i, arg_number, photo;
1604 const char *arg_string = "";
1605 char *p;
1606 PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1608 tty_printf("\n");
1610 if( redisplay && !quiet )
1612 show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1613 tty_printf("\n");
1614 redisplay = 0;
1616 do {
1617 xfree(answer);
1618 if( have_commands ) {
1619 if( commands ) {
1620 answer = xstrdup( commands->d );
1621 commands = commands->next;
1623 else if( opt.batch ) {
1624 answer = xstrdup("quit");
1626 else
1627 have_commands = 0;
1629 if( !have_commands )
1631 #ifdef HAVE_LIBREADLINE
1632 tty_enable_completion(keyedit_completion);
1633 #endif
1634 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1635 cpr_kill_prompt();
1636 tty_disable_completion();
1638 trim_spaces(answer);
1639 } while( *answer == '#' );
1641 arg_number = 0; /* Yes, here is the init which egcc complains about */
1642 photo = 0; /* This too */
1643 if( !*answer )
1644 cmd = cmdLIST;
1645 else if( *answer == CONTROL_D )
1646 cmd = cmdQUIT;
1647 else if( digitp(answer ) ) {
1648 cmd = cmdSELUID;
1649 arg_number = atoi(answer);
1651 else {
1652 if( (p=strchr(answer,' ')) ) {
1653 *p++ = 0;
1654 trim_spaces(answer);
1655 trim_spaces(p);
1656 arg_number = atoi(p);
1657 arg_string = p;
1660 for(i=0; cmds[i].name; i++ )
1662 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1664 size_t l=strlen(cmds[i].name);
1665 size_t a=strlen(answer);
1666 if(a>=l)
1668 if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1670 answer[a-l]='\0';
1671 break;
1675 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1676 break;
1678 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1680 tty_printf(_("Need the secret key to do this.\n"));
1681 cmd = cmdNOP;
1683 else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1684 && toggle)
1685 ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1686 && !toggle))
1688 tty_printf(_("Please use the command \"toggle\" first.\n"));
1689 cmd = cmdNOP;
1691 else
1692 cmd = cmds[i].id;
1694 switch( cmd )
1696 case cmdHELP:
1697 for(i=0; cmds[i].name; i++ )
1699 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1700 ; /* skip if we do not have the secret key */
1701 else if( cmds[i].desc )
1702 tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
1705 tty_printf("\n");
1706 tty_printf(_(
1707 "* The `sign' command may be prefixed with an `l' for local "
1708 "signatures (lsign),\n"
1709 " a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
1710 " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
1712 break;
1714 case cmdLIST:
1715 redisplay = 1;
1716 break;
1718 case cmdFPR:
1719 show_key_and_fingerprint( keyblock );
1720 break;
1722 case cmdSELUID:
1723 if(strlen(arg_string)==NAMEHASH_LEN*2)
1724 redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
1725 else
1726 redisplay=menu_select_uid(cur_keyblock,arg_number);
1727 break;
1729 case cmdSELKEY:
1730 if( menu_select_key( cur_keyblock, arg_number ) )
1731 redisplay = 1;
1732 break;
1734 case cmdCHECK:
1735 /* we can only do this with the public key becuase the
1736 * check functions can't cope with secret keys and it
1737 * is questionable whether this would make sense at all */
1738 check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1739 break;
1741 case cmdSIGN: /* sign (only the public key) */
1743 int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
1745 if( pk->is_revoked )
1747 tty_printf(_("Key is revoked."));
1749 if(opt.expert)
1751 tty_printf(" ");
1752 if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1753 _("Are you sure you still want"
1754 " to sign it? (y/N) ")))
1755 break;
1757 else
1759 tty_printf(_(" Unable to sign.\n"));
1760 break;
1764 if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
1765 && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1766 _("Really sign all user IDs?"
1767 " (y/N) ")))
1769 if(opt.interactive)
1770 interactive=1;
1771 else
1773 tty_printf(_("Hint: Select the user IDs to sign\n"));
1774 have_commands = 0;
1775 break;
1779 /* What sort of signing are we doing? */
1780 if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1782 tty_printf(_("Unknown signature type `%s'\n"),answer);
1783 break;
1786 sign_uids(keyblock, locusr, &modified,
1787 localsig, nonrevokesig, trustsig, interactive);
1789 break;
1791 case cmdDEBUG:
1792 dump_kbnode( cur_keyblock );
1793 break;
1795 case cmdTOGGLE:
1796 toggle = !toggle;
1797 cur_keyblock = toggle? sec_keyblock : keyblock;
1798 redisplay = 1;
1799 break;
1801 case cmdADDPHOTO:
1802 if (RFC2440 || RFC1991 || PGP2)
1804 tty_printf(
1805 _("This command is not allowed while in %s mode.\n"),
1806 compliance_option_string());
1807 break;
1809 photo=1;
1810 /* fall through */
1812 case cmdADDUID:
1813 if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
1815 update_trust = 1;
1816 redisplay = 1;
1817 sec_modified = modified = 1;
1818 merge_keys_and_selfsig( sec_keyblock );
1819 merge_keys_and_selfsig( keyblock );
1821 break;
1823 case cmdDELUID: {
1824 int n1;
1826 if( !(n1=count_selected_uids(keyblock)) )
1827 tty_printf(_("You must select at least one user ID.\n"));
1828 else if( real_uids_left(keyblock) < 1 )
1829 tty_printf(_("You can't delete the last user ID!\n"));
1830 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1831 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1832 : _("Really remove this user ID? (y/N) ")
1833 ) ) {
1834 menu_deluid( keyblock, sec_keyblock );
1835 redisplay = 1;
1836 modified = 1;
1837 if( sec_keyblock )
1838 sec_modified = 1;
1841 break;
1843 case cmdDELSIG: {
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( menu_delsig( keyblock ) ) {
1849 /* no redisplay here, because it may scroll away some
1850 * status output of delsig */
1851 modified = 1;
1854 break;
1856 case cmdADDKEY:
1857 if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1858 redisplay = 1;
1859 sec_modified = modified = 1;
1860 merge_keys_and_selfsig( sec_keyblock );
1861 merge_keys_and_selfsig( keyblock );
1863 break;
1865 #ifdef ENABLE_CARD_SUPPORT
1866 case cmdADDCARDKEY:
1867 if (card_generate_subkey (keyblock, sec_keyblock)) {
1868 redisplay = 1;
1869 sec_modified = modified = 1;
1870 merge_keys_and_selfsig( sec_keyblock );
1871 merge_keys_and_selfsig( keyblock );
1873 break;
1875 case cmdKEYTOCARD:
1877 KBNODE node=NULL;
1878 switch ( count_selected_keys (sec_keyblock) )
1880 case 0:
1881 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1882 _("Really move the primary key? (y/N) ")))
1883 node = sec_keyblock;
1884 break;
1885 case 1:
1886 for (node = sec_keyblock; node; node = node->next )
1888 if (node->pkt->pkttype == PKT_SECRET_SUBKEY
1889 && node->flag & NODFLG_SELKEY)
1890 break;
1892 break;
1893 default:
1894 tty_printf(_("You must select exactly one key.\n"));
1895 break;
1897 if (node)
1899 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1900 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1902 redisplay = 1;
1903 sec_modified = 1;
1907 break;
1909 case cmdBKUPTOCARD:
1911 /* Ask for a filename, check whether this is really a
1912 backup key as generated by the card generation, parse
1913 that key and store it on card. */
1914 KBNODE node;
1915 const char *fname;
1916 PACKET *pkt;
1917 IOBUF a;
1919 fname = arg_string;
1920 if (!*fname)
1922 tty_printf (_("Command expects a filename argument\n"));
1923 break;
1926 /* Open that file. */
1927 a = iobuf_open (fname);
1928 if (a && is_secured_file (iobuf_get_fd (a)))
1930 iobuf_close (a);
1931 a = NULL;
1932 errno = EPERM;
1934 if (!a)
1936 tty_printf (_("Can't open `%s': %s\n"),
1937 fname, strerror(errno));
1938 break;
1941 /* Parse and check that file. */
1942 pkt = xmalloc (sizeof *pkt);
1943 init_packet (pkt);
1944 rc = parse_packet (a, pkt);
1945 iobuf_close (a);
1946 iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache). */
1947 if (!rc
1948 && pkt->pkttype != PKT_SECRET_KEY
1949 && pkt->pkttype != PKT_SECRET_SUBKEY)
1950 rc = G10ERR_NO_SECKEY;
1951 if (rc)
1953 tty_printf(_("Error reading backup key from `%s': %s\n"),
1954 fname, g10_errstr (rc));
1955 free_packet (pkt);
1956 xfree (pkt);
1957 break;
1959 node = new_kbnode (pkt);
1961 /* Store it. */
1962 if (card_store_subkey (node, 0))
1964 redisplay = 1;
1965 sec_modified = 1;
1967 release_kbnode (node);
1969 break;
1971 #endif /* ENABLE_CARD_SUPPORT */
1973 case cmdDELKEY: {
1974 int n1;
1976 if( !(n1=count_selected_keys( keyblock )) )
1977 tty_printf(_("You must select at least one key.\n"));
1978 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1979 n1 > 1?
1980 _("Do you really want to delete the selected keys? (y/N) "):
1981 _("Do you really want to delete this key? (y/N) ")
1984 else {
1985 menu_delkey( keyblock, sec_keyblock );
1986 redisplay = 1;
1987 modified = 1;
1988 if( sec_keyblock )
1989 sec_modified = 1;
1992 break;
1994 case cmdADDREVOKER:
1996 int sensitive=0;
1998 if(ascii_strcasecmp(arg_string,"sensitive")==0)
1999 sensitive=1;
2000 if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
2001 redisplay = 1;
2002 sec_modified = modified = 1;
2003 merge_keys_and_selfsig( sec_keyblock );
2004 merge_keys_and_selfsig( keyblock );
2007 break;
2009 case cmdREVUID: {
2010 int n1;
2012 if( !(n1=count_selected_uids(keyblock)) )
2013 tty_printf(_("You must select at least one user ID.\n"));
2014 else if( cpr_get_answer_is_yes(
2015 "keyedit.revoke.uid.okay",
2016 n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
2017 : _("Really revoke this user ID? (y/N) ")
2018 ) ) {
2019 if(menu_revuid(keyblock,sec_keyblock))
2021 modified=1;
2022 redisplay=1;
2026 break;
2028 case cmdREVKEY:
2030 int n1;
2032 if( !(n1=count_selected_keys( keyblock )) )
2034 if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2035 _("Do you really want to revoke"
2036 " the entire key? (y/N) ")))
2038 if(menu_revkey(keyblock,sec_keyblock))
2039 modified=1;
2041 redisplay=1;
2044 else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2045 n1 > 1?
2046 _("Do you really want to revoke"
2047 " the selected subkeys? (y/N) "):
2048 _("Do you really want to revoke"
2049 " this subkey? (y/N) ")))
2051 if( menu_revsubkey( keyblock, sec_keyblock ) )
2052 modified = 1;
2054 redisplay = 1;
2057 if(modified)
2058 merge_keys_and_selfsig( keyblock );
2060 break;
2062 case cmdEXPIRE:
2063 if( menu_expire( keyblock, sec_keyblock ) )
2065 merge_keys_and_selfsig( sec_keyblock );
2066 merge_keys_and_selfsig( keyblock );
2067 sec_modified = 1;
2068 modified = 1;
2069 redisplay = 1;
2071 break;
2073 case cmdBACKSIGN:
2074 if(menu_backsign(keyblock,sec_keyblock))
2076 sec_modified = 1;
2077 modified = 1;
2078 redisplay = 1;
2080 break;
2082 case cmdPRIMARY:
2083 if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
2084 merge_keys_and_selfsig( keyblock );
2085 modified = 1;
2086 redisplay = 1;
2088 break;
2090 case cmdPASSWD:
2091 if( change_passphrase( sec_keyblock ) )
2092 sec_modified = 1;
2093 break;
2095 case cmdTRUST:
2096 if(opt.trust_model==TM_EXTERNAL)
2098 tty_printf (_("Owner trust may not be set while "
2099 "using a user provided trust database\n"));
2100 break;
2103 show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
2104 tty_printf("\n");
2105 if( edit_ownertrust( find_kbnode( keyblock,
2106 PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
2107 redisplay = 1;
2108 /* No real need to set update_trust here as
2109 edit_ownertrust() calls revalidation_mark()
2110 anyway. */
2111 update_trust=1;
2113 break;
2115 case cmdPREF:
2117 int count=count_selected_uids(keyblock);
2118 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2119 show_names(keyblock,keyblock->pkt->pkt.public_key,
2120 count?NODFLG_SELUID:0,1);
2122 break;
2124 case cmdSHOWPREF:
2126 int count=count_selected_uids(keyblock);
2127 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2128 show_names(keyblock,keyblock->pkt->pkt.public_key,
2129 count?NODFLG_SELUID:0,2);
2131 break;
2133 case cmdSETPREF:
2135 PKT_user_id *tempuid;
2137 keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
2139 tempuid=keygen_get_std_prefs();
2140 tty_printf(_("Set preference list to:\n"));
2141 show_prefs(tempuid,NULL,1);
2142 free_user_id(tempuid);
2144 if(cpr_get_answer_is_yes("keyedit.setpref.okay",
2145 count_selected_uids (keyblock)?
2146 _("Really update the preferences"
2147 " for the selected user IDs? (y/N) "):
2148 _("Really update the preferences? (y/N) ")))
2150 if ( menu_set_preferences (keyblock, sec_keyblock) )
2152 merge_keys_and_selfsig (keyblock);
2153 modified = 1;
2154 redisplay = 1;
2158 break;
2160 case cmdPREFKS:
2161 if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
2162 keyblock, sec_keyblock ) )
2164 merge_keys_and_selfsig( keyblock );
2165 modified = 1;
2166 redisplay = 1;
2168 break;
2170 case cmdNOTATION:
2171 if( menu_set_notation ( *arg_string?arg_string:NULL,
2172 keyblock, sec_keyblock ) )
2174 merge_keys_and_selfsig( keyblock );
2175 modified = 1;
2176 redisplay = 1;
2178 break;
2180 case cmdNOP:
2181 break;
2183 case cmdREVSIG:
2184 if( menu_revsig( keyblock ) ) {
2185 redisplay = 1;
2186 modified = 1;
2188 break;
2190 case cmdENABLEKEY:
2191 case cmdDISABLEKEY:
2192 if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
2193 redisplay = 1;
2194 modified = 1;
2196 break;
2198 case cmdSHOWPHOTO:
2199 menu_showphoto(keyblock);
2200 break;
2202 case cmdCLEAN:
2203 redisplay=modified=menu_clean(keyblock,0);
2204 break;
2206 case cmdMINIMIZE:
2207 redisplay=modified=menu_clean(keyblock,1);
2208 break;
2210 case cmdQUIT:
2211 if( have_commands )
2212 goto leave;
2213 if( !modified && !sec_modified )
2214 goto leave;
2215 if( !cpr_get_answer_is_yes("keyedit.save.okay",
2216 _("Save changes? (y/N) ")) ) {
2217 if( cpr_enabled()
2218 || cpr_get_answer_is_yes("keyedit.cancel.okay",
2219 _("Quit without saving? (y/N) ")))
2220 goto leave;
2221 break;
2223 /* fall thru */
2224 case cmdSAVE:
2225 if( modified || sec_modified ) {
2226 if( modified ) {
2227 rc = keydb_update_keyblock (kdbhd, keyblock);
2228 if( rc ) {
2229 log_error(_("update failed: %s\n"), g10_errstr(rc) );
2230 break;
2233 if( sec_modified ) {
2234 rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
2235 if( rc ) {
2236 log_error( _("update secret failed: %s\n"),
2237 g10_errstr(rc) );
2238 break;
2242 else
2243 tty_printf(_("Key not changed so no update needed.\n"));
2245 if( update_trust )
2247 revalidation_mark ();
2248 update_trust=0;
2250 goto leave;
2252 case cmdINVCMD:
2253 default:
2254 tty_printf("\n");
2255 tty_printf(_("Invalid command (try \"help\")\n"));
2256 break;
2258 } /* end main loop */
2260 leave:
2261 release_kbnode( keyblock );
2262 release_kbnode( sec_keyblock );
2263 keydb_release (kdbhd);
2264 xfree(answer);
2267 static void
2268 tty_print_notations(int indent,PKT_signature *sig)
2270 int first=1;
2271 struct notation *notation,*nd;
2273 if(indent<0)
2275 first=0;
2276 indent=-indent;
2279 notation=sig_to_notation(sig);
2281 for(nd=notation;nd;nd=nd->next)
2283 if(!first)
2284 tty_printf("%*s",indent,"");
2285 else
2286 first=0;
2288 tty_print_utf8_string(nd->name,strlen(nd->name));
2289 tty_printf("=");
2290 tty_print_utf8_string(nd->value,strlen(nd->value));
2291 tty_printf("\n");
2294 free_notation(notation);
2297 /****************
2298 * show preferences of a public keyblock.
2300 static void
2301 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
2303 const prefitem_t fake={0,0};
2304 const prefitem_t *prefs;
2305 int i;
2307 if( !uid )
2308 return;
2310 if( uid->prefs )
2311 prefs=uid->prefs;
2312 else if(verbose)
2313 prefs=&fake;
2314 else
2315 return;
2317 if (verbose) {
2318 int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
2320 tty_printf (" ");
2321 tty_printf (_("Cipher: "));
2322 for(i=any=0; prefs[i].type; i++ ) {
2323 if( prefs[i].type == PREFTYPE_SYM ) {
2324 if (any)
2325 tty_printf (", ");
2326 any = 1;
2327 /* We don't want to display strings for experimental algos */
2328 if (!openpgp_cipher_test_algo (prefs[i].value)
2329 && prefs[i].value < 100 )
2330 tty_printf ("%s",
2331 openpgp_cipher_algo_name (prefs[i].value));
2332 else
2333 tty_printf ("[%d]", prefs[i].value);
2334 if (prefs[i].value == CIPHER_ALGO_3DES )
2335 des_seen = 1;
2338 if (!des_seen) {
2339 if (any)
2340 tty_printf (", ");
2341 tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
2343 tty_printf ("\n ");
2344 tty_printf (_("Digest: "));
2345 for(i=any=0; prefs[i].type; i++ ) {
2346 if( prefs[i].type == PREFTYPE_HASH ) {
2347 if (any)
2348 tty_printf (", ");
2349 any = 1;
2350 /* We don't want to display strings for experimental algos */
2351 if (!gcry_md_test_algo (prefs[i].value)
2352 && prefs[i].value < 100 )
2353 tty_printf ("%s", gcry_md_algo_name (prefs[i].value) );
2354 else
2355 tty_printf ("[%d]", prefs[i].value);
2356 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2357 sha1_seen = 1;
2360 if (!sha1_seen) {
2361 if (any)
2362 tty_printf (", ");
2363 tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
2365 tty_printf ("\n ");
2366 tty_printf (_("Compression: "));
2367 for(i=any=0; prefs[i].type; i++ ) {
2368 if( prefs[i].type == PREFTYPE_ZIP ) {
2369 const char *s=compress_algo_to_string(prefs[i].value);
2371 if (any)
2372 tty_printf (", ");
2373 any = 1;
2374 /* We don't want to display strings for experimental algos */
2375 if (s && prefs[i].value < 100 )
2376 tty_printf ("%s", s );
2377 else
2378 tty_printf ("[%d]", prefs[i].value);
2379 if (prefs[i].value == COMPRESS_ALGO_NONE )
2380 uncomp_seen = 1;
2383 if (!uncomp_seen) {
2384 if (any)
2385 tty_printf (", ");
2386 else {
2387 tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2388 tty_printf (", ");
2390 tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2392 if(uid->flags.mdc || !uid->flags.ks_modify)
2394 tty_printf ("\n ");
2395 tty_printf (_("Features: "));
2396 any=0;
2397 if(uid->flags.mdc)
2399 tty_printf ("MDC");
2400 any=1;
2402 if(!uid->flags.ks_modify)
2404 if(any)
2405 tty_printf (", ");
2406 tty_printf (_("Keyserver no-modify"));
2409 tty_printf("\n");
2411 if(selfsig)
2413 const byte *pref_ks;
2414 size_t pref_ks_len;
2416 pref_ks=parse_sig_subpkt(selfsig->hashed,
2417 SIGSUBPKT_PREF_KS,&pref_ks_len);
2418 if(pref_ks && pref_ks_len)
2420 tty_printf (" ");
2421 tty_printf(_("Preferred keyserver: "));
2422 tty_print_utf8_string(pref_ks,pref_ks_len);
2423 tty_printf("\n");
2426 if(selfsig->flags.notation)
2428 tty_printf (" ");
2429 tty_printf(_("Notations: "));
2430 tty_print_notations(5+strlen(_("Notations: ")),selfsig);
2434 else {
2435 tty_printf(" ");
2436 for(i=0; prefs[i].type; i++ ) {
2437 tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
2438 prefs[i].type == PREFTYPE_HASH ? 'H' :
2439 prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2440 prefs[i].value);
2442 if (uid->flags.mdc)
2443 tty_printf (" [mdc]");
2444 if (!uid->flags.ks_modify)
2445 tty_printf (" [no-ks-modify]");
2446 tty_printf("\n");
2450 /* This is the version of show_key_with_all_names used when
2451 opt.with_colons is used. It prints all available data in a easy to
2452 parse format and does not translate utf8 */
2453 static void
2454 show_key_with_all_names_colon (KBNODE keyblock)
2456 KBNODE node;
2457 int i, j, ulti_hack=0;
2458 byte pk_version=0;
2459 PKT_public_key *primary=NULL;
2461 /* the keys */
2462 for ( node = keyblock; node; node = node->next )
2464 if (node->pkt->pkttype == PKT_PUBLIC_KEY
2465 || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2467 PKT_public_key *pk = node->pkt->pkt.public_key;
2468 u32 keyid[2];
2470 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2472 pk_version = pk->version;
2473 primary=pk;
2476 keyid_from_pk (pk, keyid);
2478 fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2479 if (!pk->is_valid)
2480 putchar ('i');
2481 else if (pk->is_revoked)
2482 putchar ('r');
2483 else if (pk->has_expired)
2484 putchar ('e');
2485 else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2487 int trust = get_validity_info (pk, NULL);
2488 if(trust=='u')
2489 ulti_hack=1;
2490 putchar (trust);
2493 printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2494 nbits_from_pk (pk),
2495 pk->pubkey_algo,
2496 (ulong)keyid[0], (ulong)keyid[1],
2497 (ulong)pk->timestamp,
2498 (ulong)pk->expiredate );
2499 if (node->pkt->pkttype==PKT_PUBLIC_KEY
2500 && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2501 putchar(get_ownertrust_info (pk));
2502 putchar(':');
2503 putchar('\n');
2505 print_fingerprint (pk, NULL, 0);
2506 print_revokers(pk);
2510 /* the user ids */
2511 i = 0;
2512 for (node = keyblock; node; node = node->next)
2514 if ( node->pkt->pkttype == PKT_USER_ID )
2516 PKT_user_id *uid = node->pkt->pkt.user_id;
2518 ++i;
2520 if(uid->attrib_data)
2521 printf("uat:");
2522 else
2523 printf("uid:");
2525 if ( uid->is_revoked )
2526 printf("r::::::::");
2527 else if ( uid->is_expired )
2528 printf("e::::::::");
2529 else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2530 printf("::::::::");
2531 else
2533 int uid_validity;
2535 if( primary && !ulti_hack )
2536 uid_validity = get_validity_info( primary, uid );
2537 else
2538 uid_validity = 'u';
2539 printf("%c::::::::",uid_validity);
2542 if(uid->attrib_data)
2543 printf ("%u %lu",uid->numattribs,uid->attrib_len);
2544 else
2545 print_string (stdout, uid->name, uid->len, ':');
2547 putchar (':');
2548 /* signature class */
2549 putchar (':');
2550 /* capabilities */
2551 putchar (':');
2552 /* preferences */
2553 if (pk_version>3 || uid->selfsigversion>3)
2555 const prefitem_t *prefs = uid->prefs;
2557 for (j=0; prefs && prefs[j].type; j++)
2559 if (j)
2560 putchar (' ');
2561 printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
2562 prefs[j].type == PREFTYPE_HASH ? 'H' :
2563 prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2564 prefs[j].value);
2566 if (uid->flags.mdc)
2567 printf (",mdc");
2568 if (!uid->flags.ks_modify)
2569 printf (",no-ks-modify");
2571 putchar (':');
2572 /* flags */
2573 printf ("%d,", i);
2574 if (uid->is_primary)
2575 putchar ('p');
2576 if (uid->is_revoked)
2577 putchar ('r');
2578 if (uid->is_expired)
2579 putchar ('e');
2580 if ((node->flag & NODFLG_SELUID))
2581 putchar ('s');
2582 if ((node->flag & NODFLG_MARK_A))
2583 putchar ('m');
2584 putchar (':');
2585 putchar('\n');
2590 static void
2591 show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
2593 KBNODE node;
2594 int i=0;
2596 for( node = keyblock; node; node = node->next )
2598 if( node->pkt->pkttype == PKT_USER_ID
2599 && !is_deleted_kbnode(node))
2601 PKT_user_id *uid = node->pkt->pkt.user_id;
2602 ++i;
2603 if(!flag || (flag && (node->flag & flag)))
2605 if(!(flag&NODFLG_MARK_A) && pk)
2606 tty_printf("%s ",uid_trust_string_fixed(pk,uid));
2608 if( flag & NODFLG_MARK_A )
2609 tty_printf(" ");
2610 else if( node->flag & NODFLG_SELUID )
2611 tty_printf("(%d)* ", i);
2612 else if( uid->is_primary )
2613 tty_printf("(%d). ", i);
2614 else
2615 tty_printf("(%d) ", i);
2616 tty_print_utf8_string( uid->name, uid->len );
2617 tty_printf("\n");
2618 if(with_prefs && pk)
2620 if(pk->version>3 || uid->selfsigversion>3)
2622 PKT_signature *selfsig=NULL;
2623 KBNODE signode;
2625 for(signode=node->next;
2626 signode && signode->pkt->pkttype==PKT_SIGNATURE;
2627 signode=signode->next)
2629 if(signode->pkt->pkt.signature->
2630 flags.chosen_selfsig)
2632 selfsig=signode->pkt->pkt.signature;
2633 break;
2637 show_prefs (uid, selfsig, with_prefs == 2);
2639 else
2640 tty_printf(_("There are no preferences on a"
2641 " PGP 2.x-style user ID.\n"));
2648 /****************
2649 * Display the key a the user ids, if only_marked is true, do only
2650 * so for user ids with mark A flag set and dont display the index number
2652 static void
2653 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2654 int with_fpr, int with_subkeys, int with_prefs )
2656 KBNODE node;
2657 int i;
2658 int do_warn = 0;
2659 byte pk_version=0;
2660 PKT_public_key *primary=NULL;
2662 if (opt.with_colons)
2664 show_key_with_all_names_colon (keyblock);
2665 return;
2668 /* the keys */
2669 for( node = keyblock; node; node = node->next ) {
2670 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2671 || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2672 && !is_deleted_kbnode(node)) ) {
2673 PKT_public_key *pk = node->pkt->pkt.public_key;
2674 const char *otrust="err",*trust="err";
2676 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2677 /* do it here, so that debug messages don't clutter the
2678 * output */
2679 static int did_warn = 0;
2681 trust = get_validity_string (pk, NULL);
2682 otrust = get_ownertrust_string (pk);
2684 /* Show a warning once */
2685 if (!did_warn
2686 && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2687 did_warn = 1;
2688 do_warn = 1;
2691 pk_version=pk->version;
2692 primary=pk;
2695 if(pk->is_revoked)
2697 char *user=get_user_id_string_native(pk->revoked.keyid);
2698 const char *algo = gcry_pk_algo_name (pk->revoked.algo);
2699 tty_printf(_("This key was revoked on %s by %s key %s\n"),
2700 revokestr_from_pk(pk),algo?algo:"?",user);
2701 xfree(user);
2704 if(with_revoker)
2706 if( !pk->revkey && pk->numrevkeys )
2707 BUG();
2708 else
2709 for(i=0;i<pk->numrevkeys;i++)
2711 u32 r_keyid[2];
2712 char *user;
2713 const char *algo;
2715 algo = gcry_pk_algo_name (pk->revkey[i].algid);
2716 keyid_from_fingerprint(pk->revkey[i].fpr,
2717 MAX_FINGERPRINT_LEN,r_keyid);
2719 user=get_user_id_string_native(r_keyid);
2720 tty_printf(_("This key may be revoked by %s key %s"),
2721 algo?algo:"?",user);
2723 if(pk->revkey[i].class&0x40)
2725 tty_printf(" ");
2726 tty_printf(_("(sensitive)"));
2729 tty_printf ("\n");
2730 xfree(user);
2734 keyid_from_pk(pk,NULL);
2735 tty_printf("%s%c %4u%c/%s ",
2736 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2737 (node->flag & NODFLG_SELKEY)? '*':' ',
2738 nbits_from_pk( pk ),
2739 pubkey_letter( pk->pubkey_algo ),
2740 keystr(pk->keyid));
2742 tty_printf(_("created: %s"),datestr_from_pk(pk));
2743 tty_printf(" ");
2744 if(pk->is_revoked)
2745 tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2746 else if(pk->has_expired)
2747 tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2748 else
2749 tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2750 tty_printf(" ");
2751 tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2752 tty_printf("\n");
2754 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2756 if(opt.trust_model!=TM_ALWAYS)
2758 tty_printf("%*s", (int)keystrlen()+13,"");
2759 /* Ownertrust is only meaningful for the PGP or
2760 classic trust models */
2761 if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2763 int width=14-strlen(otrust);
2764 if(width<=0)
2765 width=1;
2766 tty_printf(_("trust: %s"), otrust);
2767 tty_printf("%*s",width,"");
2770 tty_printf(_("validity: %s"), trust );
2771 tty_printf("\n");
2773 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2774 && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2776 tty_printf("*** ");
2777 tty_printf(_("This key has been disabled"));
2778 tty_printf("\n");
2782 if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2784 print_fingerprint ( pk, NULL, 2 );
2785 tty_printf("\n");
2788 else if( node->pkt->pkttype == PKT_SECRET_KEY
2789 || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2791 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2792 tty_printf("%s%c %4u%c/%s ",
2793 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2794 (node->flag & NODFLG_SELKEY)? '*':' ',
2795 nbits_from_sk( sk ),
2796 pubkey_letter( sk->pubkey_algo ),
2797 keystr_from_sk(sk));
2798 tty_printf(_("created: %s"),datestr_from_sk(sk));
2799 tty_printf(" ");
2800 tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2801 tty_printf("\n");
2802 if (sk->is_protected && sk->protect.s2k.mode == 1002)
2804 tty_printf(" ");
2805 tty_printf(_("card-no: "));
2806 if (sk->protect.ivlen == 16
2807 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2808 { /* This is an OpenPGP card. */
2809 for (i=8; i < 14; i++)
2811 if (i == 10)
2812 tty_printf (" ");
2813 tty_printf ("%02X", sk->protect.iv[i]);
2816 else
2817 { /* Something is wrong: Print all. */
2818 for (i=0; i < sk->protect.ivlen; i++)
2819 tty_printf ("%02X", sk->protect.iv[i]);
2821 tty_printf ("\n");
2826 show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
2828 if (do_warn)
2829 tty_printf (_("Please note that the shown key validity"
2830 " is not necessarily correct\n"
2831 "unless you restart the program.\n"));
2835 /* Display basic key information. This function is suitable to show
2836 information on the key without any dependencies on the trustdb or
2837 any other internal GnuPG stuff. KEYBLOCK may either be a public or
2838 a secret key.*/
2839 void
2840 show_basic_key_info ( KBNODE keyblock )
2842 KBNODE node;
2843 int i;
2845 /* The primary key */
2846 for (node = keyblock; node; node = node->next)
2848 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2850 PKT_public_key *pk = node->pkt->pkt.public_key;
2852 /* Note, we use the same format string as in other show
2853 functions to make the translation job easier. */
2854 tty_printf ("%s %4u%c/%s ",
2855 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2856 nbits_from_pk( pk ),
2857 pubkey_letter( pk->pubkey_algo ),
2858 keystr_from_pk(pk));
2859 tty_printf(_("created: %s"),datestr_from_pk(pk));
2860 tty_printf(" ");
2861 tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2862 tty_printf("\n");
2863 print_fingerprint ( pk, NULL, 3 );
2864 tty_printf("\n");
2866 else if (node->pkt->pkttype == PKT_SECRET_KEY)
2868 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2869 tty_printf("%s %4u%c/%s",
2870 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2871 nbits_from_sk( sk ),
2872 pubkey_letter( sk->pubkey_algo ),
2873 keystr_from_sk(sk));
2874 tty_printf(_("created: %s"),datestr_from_sk(sk));
2875 tty_printf(" ");
2876 tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2877 tty_printf("\n");
2878 print_fingerprint (NULL, sk, 3 );
2879 tty_printf("\n");
2883 /* The user IDs. */
2884 for (i=0, node = keyblock; node; node = node->next)
2886 if (node->pkt->pkttype == PKT_USER_ID)
2888 PKT_user_id *uid = node->pkt->pkt.user_id;
2889 ++i;
2891 tty_printf (" ");
2892 if (uid->is_revoked)
2893 tty_printf("[%s] ",_("revoked"));
2894 else if ( uid->is_expired )
2895 tty_printf("[%s] ",_("expired"));
2896 tty_print_utf8_string (uid->name, uid->len);
2897 tty_printf ("\n");
2902 static void
2903 show_key_and_fingerprint( KBNODE keyblock )
2905 KBNODE node;
2906 PKT_public_key *pk = NULL;
2908 for( node = keyblock; node; node = node->next )
2910 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2912 pk = node->pkt->pkt.public_key;
2913 tty_printf("pub %4u%c/%s %s ",
2914 nbits_from_pk( pk ),
2915 pubkey_letter( pk->pubkey_algo ),
2916 keystr_from_pk(pk),
2917 datestr_from_pk(pk) );
2919 else if( node->pkt->pkttype == PKT_USER_ID )
2921 PKT_user_id *uid = node->pkt->pkt.user_id;
2922 tty_print_utf8_string( uid->name, uid->len );
2923 break;
2926 tty_printf("\n");
2927 if( pk )
2928 print_fingerprint( pk, NULL, 2 );
2932 /* Show a warning if no uids on the key have the primary uid flag
2933 set. */
2934 static void
2935 no_primary_warning(KBNODE keyblock)
2937 KBNODE node;
2938 int have_primary=0,uid_count=0;
2940 /* TODO: if we ever start behaving differently with a primary or
2941 non-primary attribute ID, we will need to check for attributes
2942 here as well. */
2944 for(node=keyblock; node; node = node->next)
2946 if(node->pkt->pkttype==PKT_USER_ID
2947 && node->pkt->pkt.user_id->attrib_data==NULL)
2949 uid_count++;
2951 if(node->pkt->pkt.user_id->is_primary==2)
2953 have_primary=1;
2954 break;
2959 if(uid_count>1 && !have_primary)
2960 log_info(_("WARNING: no user ID has been marked as primary. This command"
2961 " may\n cause a different user ID to become"
2962 " the assumed primary.\n"));
2965 /****************
2966 * Ask for a new user id, do the selfsignature and put it into
2967 * both keyblocks.
2968 * Return true if there is a new user id
2970 static int
2971 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
2972 int photo, const char *photo_name)
2974 PKT_user_id *uid;
2975 PKT_public_key *pk=NULL;
2976 PKT_secret_key *sk=NULL;
2977 PKT_signature *sig=NULL;
2978 PACKET *pkt;
2979 KBNODE node;
2980 KBNODE pub_where=NULL, sec_where=NULL;
2981 int rc;
2983 for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2984 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2985 pk = node->pkt->pkt.public_key;
2986 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2987 break;
2989 if( !node ) /* no subkey */
2990 pub_where = NULL;
2991 for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2992 if( node->pkt->pkttype == PKT_SECRET_KEY )
2993 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2994 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2995 break;
2997 if( !node ) /* no subkey */
2998 sec_where = NULL;
2999 assert(pk && sk);
3001 if(photo) {
3002 int hasattrib=0;
3004 for( node = pub_keyblock; node; node = node->next )
3005 if( node->pkt->pkttype == PKT_USER_ID &&
3006 node->pkt->pkt.user_id->attrib_data!=NULL)
3008 hasattrib=1;
3009 break;
3012 /* It is legal but bad for compatibility to add a photo ID to a
3013 v3 key as it means that PGP2 will not be able to use that key
3014 anymore. Also, PGP may not expect a photo on a v3 key.
3015 Don't bother to ask this if the key already has a photo - any
3016 damage has already been done at that point. -dms */
3017 if(pk->version==3 && !hasattrib)
3019 if(opt.expert)
3021 tty_printf(_("WARNING: This is a PGP2-style key. "
3022 "Adding a photo ID may cause some versions\n"
3023 " of PGP to reject this key.\n"));
3025 if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
3026 _("Are you sure you still want "
3027 "to add it? (y/N) ")))
3028 return 0;
3030 else
3032 tty_printf(_("You may not add a photo ID to "
3033 "a PGP2-style key.\n"));
3034 return 0;
3038 uid = generate_photo_id(pk,photo_name);
3039 } else
3040 uid = generate_user_id();
3041 if( !uid )
3042 return 0;
3044 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
3045 keygen_add_std_prefs, pk );
3046 free_secret_key( sk );
3047 if( rc ) {
3048 log_error("signing failed: %s\n", g10_errstr(rc) );
3049 free_user_id(uid);
3050 return 0;
3053 /* insert/append to secret keyblock */
3054 pkt = xmalloc_clear( sizeof *pkt );
3055 pkt->pkttype = PKT_USER_ID;
3056 pkt->pkt.user_id = scopy_user_id(uid);
3057 node = new_kbnode(pkt);
3058 if( sec_where )
3059 insert_kbnode( sec_where, node, 0 );
3060 else
3061 add_kbnode( sec_keyblock, node );
3062 pkt = xmalloc_clear( sizeof *pkt );
3063 pkt->pkttype = PKT_SIGNATURE;
3064 pkt->pkt.signature = copy_signature(NULL, sig);
3065 if( sec_where )
3066 insert_kbnode( node, new_kbnode(pkt), 0 );
3067 else
3068 add_kbnode( sec_keyblock, new_kbnode(pkt) );
3069 /* insert/append to public keyblock */
3070 pkt = xmalloc_clear( sizeof *pkt );
3071 pkt->pkttype = PKT_USER_ID;
3072 pkt->pkt.user_id = uid;
3073 node = new_kbnode(pkt);
3074 if( pub_where )
3075 insert_kbnode( pub_where, node, 0 );
3076 else
3077 add_kbnode( pub_keyblock, node );
3078 pkt = xmalloc_clear( sizeof *pkt );
3079 pkt->pkttype = PKT_SIGNATURE;
3080 pkt->pkt.signature = copy_signature(NULL, sig);
3081 if( pub_where )
3082 insert_kbnode( node, new_kbnode(pkt), 0 );
3083 else
3084 add_kbnode( pub_keyblock, new_kbnode(pkt) );
3085 return 1;
3089 /****************
3090 * Remove all selected userids from the keyrings
3092 static void
3093 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3095 KBNODE node;
3096 int selected=0;
3098 for( node = pub_keyblock; node; node = node->next ) {
3099 if( node->pkt->pkttype == PKT_USER_ID ) {
3100 selected = node->flag & NODFLG_SELUID;
3101 if( selected ) {
3102 /* Only cause a trust update if we delete a
3103 non-revoked user id */
3104 if(!node->pkt->pkt.user_id->is_revoked)
3105 update_trust=1;
3106 delete_kbnode( node );
3107 if( sec_keyblock ) {
3108 KBNODE snode;
3109 int s_selected = 0;
3110 PKT_user_id *uid = node->pkt->pkt.user_id;
3111 for( snode = sec_keyblock; snode; snode = snode->next ) {
3112 if( snode->pkt->pkttype == PKT_USER_ID ) {
3113 PKT_user_id *suid = snode->pkt->pkt.user_id;
3115 s_selected =
3116 (uid->len == suid->len
3117 && !memcmp( uid->name, suid->name, uid->len));
3118 if( s_selected )
3119 delete_kbnode( snode );
3121 else if( s_selected
3122 && snode->pkt->pkttype == PKT_SIGNATURE )
3123 delete_kbnode( snode );
3124 else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
3125 s_selected = 0;
3130 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3131 delete_kbnode( node );
3132 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3133 selected = 0;
3135 commit_kbnode( &pub_keyblock );
3136 if( sec_keyblock )
3137 commit_kbnode( &sec_keyblock );
3141 static int
3142 menu_delsig( KBNODE pub_keyblock )
3144 KBNODE node;
3145 PKT_user_id *uid = NULL;
3146 int changed=0;
3148 for( node = pub_keyblock; node; node = node->next ) {
3149 if( node->pkt->pkttype == PKT_USER_ID ) {
3150 uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
3152 else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3153 int okay, valid, selfsig, inv_sig, no_key, other_err;
3155 tty_printf("uid ");
3156 tty_print_utf8_string( uid->name, uid->len );
3157 tty_printf("\n");
3159 okay = inv_sig = no_key = other_err = 0;
3160 if(opt.with_colons)
3161 valid = print_and_check_one_sig_colon( pub_keyblock, node,
3162 &inv_sig, &no_key, &other_err,
3163 &selfsig, 1 );
3164 else
3165 valid = print_and_check_one_sig( pub_keyblock, node,
3166 &inv_sig, &no_key, &other_err,
3167 &selfsig, 1 );
3169 if( valid ) {
3170 okay = cpr_get_answer_yes_no_quit(
3171 "keyedit.delsig.valid",
3172 _("Delete this good signature? (y/N/q)"));
3174 /* Only update trust if we delete a good signature.
3175 The other two cases do not affect trust. */
3176 if(okay)
3177 update_trust=1;
3179 else if( inv_sig || other_err )
3180 okay = cpr_get_answer_yes_no_quit(
3181 "keyedit.delsig.invalid",
3182 _("Delete this invalid signature? (y/N/q)"));
3183 else if( no_key )
3184 okay = cpr_get_answer_yes_no_quit(
3185 "keyedit.delsig.unknown",
3186 _("Delete this unknown signature? (y/N/q)"));
3188 if( okay == -1 )
3189 break;
3190 if( okay && selfsig && !cpr_get_answer_is_yes(
3191 "keyedit.delsig.selfsig",
3192 _("Really delete this self-signature? (y/N)") ))
3193 okay = 0;
3194 if( okay ) {
3195 delete_kbnode( node );
3196 changed++;
3200 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3201 uid = NULL;
3204 if( changed ) {
3205 commit_kbnode( &pub_keyblock );
3206 tty_printf( changed == 1? _("Deleted %d signature.\n")
3207 : _("Deleted %d signatures.\n"), changed );
3209 else
3210 tty_printf( _("Nothing deleted.\n") );
3212 return changed;
3215 static int
3216 menu_clean(KBNODE keyblock,int self_only)
3218 KBNODE uidnode;
3219 int modified=0,select_all=!count_selected_uids(keyblock);
3221 for(uidnode=keyblock->next;
3222 uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
3223 uidnode=uidnode->next)
3225 if(uidnode->pkt->pkttype==PKT_USER_ID
3226 && (uidnode->flag&NODFLG_SELUID || select_all))
3228 int uids=0,sigs=0;
3229 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3230 uidnode->pkt->pkt.user_id->len,
3233 clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
3234 if(uids)
3236 const char *reason;
3238 if(uidnode->pkt->pkt.user_id->is_revoked)
3239 reason=_("revoked");
3240 else if(uidnode->pkt->pkt.user_id->is_expired)
3241 reason=_("expired");
3242 else
3243 reason=_("invalid");
3245 tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
3247 modified=1;
3249 else if(sigs)
3251 tty_printf(sigs==1?
3252 _("User ID \"%s\": %d signature removed\n") :
3253 _("User ID \"%s\": %d signatures removed\n"),
3254 user,sigs);
3256 modified=1;
3258 else
3260 tty_printf (self_only==1?
3261 _("User ID \"%s\": already minimized\n") :
3262 _("User ID \"%s\": already clean\n"),
3263 user);
3266 xfree(user);
3270 return modified;
3273 /****************
3274 * Remove some of the secondary keys
3276 static void
3277 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3279 KBNODE node;
3280 int selected=0;
3282 for( node = pub_keyblock; node; node = node->next ) {
3283 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3284 selected = node->flag & NODFLG_SELKEY;
3285 if( selected ) {
3286 delete_kbnode( node );
3287 if( sec_keyblock ) {
3288 KBNODE snode;
3289 int s_selected = 0;
3290 u32 ki[2];
3292 keyid_from_pk( node->pkt->pkt.public_key, ki );
3293 for( snode = sec_keyblock; snode; snode = snode->next ) {
3294 if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3295 u32 ki2[2];
3297 keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
3298 s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
3299 if( s_selected )
3300 delete_kbnode( snode );
3302 else if( s_selected
3303 && snode->pkt->pkttype == PKT_SIGNATURE )
3304 delete_kbnode( snode );
3305 else
3306 s_selected = 0;
3311 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3312 delete_kbnode( node );
3313 else
3314 selected = 0;
3316 commit_kbnode( &pub_keyblock );
3317 if( sec_keyblock )
3318 commit_kbnode( &sec_keyblock );
3320 /* No need to set update_trust here since signing keys are no
3321 longer used to certify other keys, so there is no change in
3322 trust when revoking/removing them */
3326 /****************
3327 * Ask for a new revoker, do the selfsignature and put it into
3328 * both keyblocks.
3329 * Return true if there is a new revoker
3331 static int
3332 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
3334 PKT_public_key *pk=NULL,*revoker_pk=NULL;
3335 PKT_secret_key *sk=NULL;
3336 PKT_signature *sig=NULL;
3337 PACKET *pkt;
3338 struct revocation_key revkey;
3339 size_t fprlen;
3340 int rc;
3342 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3343 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3345 pk=pub_keyblock->pkt->pkt.public_key;
3347 if(pk->numrevkeys==0 && pk->version==3)
3349 /* It is legal but bad for compatibility to add a revoker to a
3350 v3 key as it means that PGP2 will not be able to use that key
3351 anymore. Also, PGP may not expect a revoker on a v3 key.
3352 Don't bother to ask this if the key already has a revoker -
3353 any damage has already been done at that point. -dms */
3354 if(opt.expert)
3356 tty_printf(_("WARNING: This is a PGP 2.x-style key. "
3357 "Adding a designated revoker may cause\n"
3358 " some versions of PGP to reject this key.\n"));
3360 if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
3361 _("Are you sure you still want "
3362 "to add it? (y/N) ")))
3363 return 0;
3365 else
3367 tty_printf(_("You may not add a designated revoker to "
3368 "a PGP 2.x-style key.\n"));
3369 return 0;
3373 sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3375 for(;;)
3377 char *answer;
3379 if(revoker_pk)
3380 free_public_key(revoker_pk);
3382 revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
3384 tty_printf("\n");
3386 answer=cpr_get_utf8("keyedit.add_revoker",
3387 _("Enter the user ID of the designated revoker: "));
3388 if(answer[0]=='\0' || answer[0]=='\004')
3390 xfree(answer);
3391 goto fail;
3394 /* Note that I'm requesting CERT here, which usually implies
3395 primary keys only, but some casual testing shows that PGP and
3396 GnuPG both can handle a designated revokation from a
3397 subkey. */
3398 revoker_pk->req_usage=PUBKEY_USAGE_CERT;
3399 rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
3400 if(rc)
3402 log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
3403 xfree(answer);
3404 continue;
3407 xfree(answer);
3409 fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
3410 if(fprlen!=20)
3412 log_error(_("cannot appoint a PGP 2.x style key as a "
3413 "designated revoker\n"));
3414 continue;
3417 revkey.class=0x80;
3418 if(sensitive)
3419 revkey.class|=0x40;
3420 revkey.algid=revoker_pk->pubkey_algo;
3422 if(cmp_public_keys(revoker_pk,pk)==0)
3424 /* This actually causes no harm (after all, a key that
3425 designates itself as a revoker is the same as a
3426 regular key), but it's easy enough to check. */
3427 log_error(_("you cannot appoint a key as its own "
3428 "designated revoker\n"));
3430 continue;
3433 keyid_from_pk(pk,NULL);
3435 /* Does this revkey already exist? */
3436 if(!pk->revkey && pk->numrevkeys)
3437 BUG();
3438 else
3440 int i;
3442 for(i=0;i<pk->numrevkeys;i++)
3444 if(memcmp(&pk->revkey[i],&revkey,
3445 sizeof(struct revocation_key))==0)
3447 char buf[50];
3449 log_error(_("this key has already been designated "
3450 "as a revoker\n"));
3452 sprintf(buf,"%08lX%08lX",
3453 (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
3454 write_status_text(STATUS_ALREADY_SIGNED,buf);
3456 break;
3460 if(i<pk->numrevkeys)
3461 continue;
3464 print_pubkey_info(NULL,revoker_pk);
3465 print_fingerprint(revoker_pk,NULL,2);
3466 tty_printf("\n");
3468 tty_printf(_("WARNING: appointing a key as a designated revoker "
3469 "cannot be undone!\n"));
3471 tty_printf("\n");
3473 if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
3474 _("Are you sure you want to appoint this "
3475 "key as a designated revoker? (y/N) ")))
3476 continue;
3478 free_public_key(revoker_pk);
3479 revoker_pk=NULL;
3480 break;
3483 /* The 1F signature must be at least v4 to carry the revocation key
3484 subpacket. */
3485 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3486 keygen_add_revkey,&revkey );
3487 if( rc )
3489 log_error("signing failed: %s\n", g10_errstr(rc) );
3490 goto fail;
3493 free_secret_key(sk);
3494 sk=NULL;
3496 /* insert into secret keyblock */
3497 pkt = xmalloc_clear( sizeof *pkt );
3498 pkt->pkttype = PKT_SIGNATURE;
3499 pkt->pkt.signature = copy_signature(NULL, sig);
3500 insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3502 /* insert into public keyblock */
3503 pkt = xmalloc_clear( sizeof *pkt );
3504 pkt->pkttype = PKT_SIGNATURE;
3505 pkt->pkt.signature = sig;
3506 insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3508 return 1;
3510 fail:
3511 if(sk)
3512 free_secret_key(sk);
3513 if(sig)
3514 free_seckey_enc(sig);
3515 if(revoker_pk)
3516 free_public_key(revoker_pk);
3518 return 0;
3522 static int
3523 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3525 int n1, signumber, rc;
3526 u32 expiredate;
3527 int mainkey=0;
3528 PKT_secret_key *sk; /* copy of the main sk */
3529 PKT_public_key *main_pk, *sub_pk;
3530 PKT_user_id *uid;
3531 KBNODE node;
3532 u32 keyid[2];
3534 if( count_selected_keys( sec_keyblock ) ) {
3535 tty_printf(_("Please remove selections from the secret keys.\n"));
3536 return 0;
3539 n1 = count_selected_keys( pub_keyblock );
3540 if( n1 > 1 ) {
3541 tty_printf(_("Please select at most one subkey.\n"));
3542 return 0;
3544 else if( n1 )
3545 tty_printf(_("Changing expiration time for a subkey.\n"));
3546 else
3548 tty_printf(_("Changing expiration time for the primary key.\n"));
3549 mainkey=1;
3550 no_primary_warning(pub_keyblock);
3553 expiredate = ask_expiredate();
3554 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3555 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3557 /* Now we can actually change the self signature(s) */
3558 main_pk = sub_pk = NULL;
3559 uid = NULL;
3560 signumber = 0;
3561 for( node=pub_keyblock; node; node = node->next ) {
3562 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3563 main_pk = node->pkt->pkt.public_key;
3564 keyid_from_pk( main_pk, keyid );
3565 main_pk->expiredate = expiredate;
3567 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3568 && (node->flag & NODFLG_SELKEY ) ) {
3569 sub_pk = node->pkt->pkt.public_key;
3570 sub_pk->expiredate = expiredate;
3572 else if( node->pkt->pkttype == PKT_USER_ID )
3573 uid = node->pkt->pkt.user_id;
3574 else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3575 && ( mainkey || sub_pk ) ) {
3576 PKT_signature *sig = node->pkt->pkt.signature;
3577 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3578 && ( (mainkey && uid
3579 && uid->created && (sig->sig_class&~3) == 0x10)
3580 || (!mainkey && sig->sig_class == 0x18) )
3581 && sig->flags.chosen_selfsig )
3583 /* this is a selfsignature which is to be replaced */
3584 PKT_signature *newsig;
3585 PACKET *newpkt;
3586 KBNODE sn;
3587 int signumber2 = 0;
3589 signumber++;
3591 if( (mainkey && main_pk->version < 4)
3592 || (!mainkey && sub_pk->version < 4 ) ) {
3593 log_info(_(
3594 "You can't change the expiration date of a v3 key\n"));
3595 free_secret_key( sk );
3596 return 0;
3599 /* find the corresponding secret self-signature */
3600 for( sn=sec_keyblock; sn; sn = sn->next ) {
3601 if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3602 PKT_signature *b = sn->pkt->pkt.signature;
3603 if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3604 && sig->sig_class == b->sig_class
3605 && ++signumber2 == signumber )
3606 break;
3609 if( !sn )
3610 log_info(_("No corresponding signature in secret ring\n"));
3612 if( mainkey )
3613 rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3614 sk, keygen_add_key_expire, main_pk);
3615 else
3616 rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3617 sk, keygen_add_key_expire, sub_pk );
3618 if( rc ) {
3619 log_error("make_keysig_packet failed: %s\n",
3620 g10_errstr(rc));
3621 free_secret_key( sk );
3622 return 0;
3624 /* replace the packet */
3625 newpkt = xmalloc_clear( sizeof *newpkt );
3626 newpkt->pkttype = PKT_SIGNATURE;
3627 newpkt->pkt.signature = newsig;
3628 free_packet( node->pkt );
3629 xfree( node->pkt );
3630 node->pkt = newpkt;
3631 if( sn ) {
3632 newpkt = xmalloc_clear( sizeof *newpkt );
3633 newpkt->pkttype = PKT_SIGNATURE;
3634 newpkt->pkt.signature = copy_signature( NULL, newsig );
3635 free_packet( sn->pkt );
3636 xfree( sn->pkt );
3637 sn->pkt = newpkt;
3639 sub_pk = NULL;
3644 free_secret_key( sk );
3645 update_trust=1;
3646 return 1;
3649 static int
3650 menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
3652 int rc,modified=0;
3653 PKT_public_key *main_pk;
3654 PKT_secret_key *main_sk,*sub_sk=NULL;
3655 KBNODE node;
3656 u32 timestamp;
3658 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3659 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3661 merge_keys_and_selfsig(pub_keyblock);
3662 main_pk=pub_keyblock->pkt->pkt.public_key;
3663 main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3664 keyid_from_pk(main_pk,NULL);
3666 /* We use the same timestamp for all backsigs so that we don't
3667 reveal information about the used machine. */
3668 timestamp = make_timestamp ();
3670 for(node=pub_keyblock;node;node=node->next)
3672 PKT_public_key *sub_pk=NULL;
3673 KBNODE node2,sig_pk=NULL,sig_sk=NULL;
3674 char *passphrase;
3676 if(sub_sk)
3678 free_secret_key(sub_sk);
3679 sub_sk=NULL;
3682 /* Find a signing subkey with no backsig */
3683 if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
3685 if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
3687 if(node->pkt->pkt.public_key->backsig)
3688 tty_printf(_("signing subkey %s is already cross-certified\n"),
3689 keystr_from_pk(node->pkt->pkt.public_key));
3690 else
3691 sub_pk=node->pkt->pkt.public_key;
3693 else
3694 tty_printf(_("subkey %s does not sign and so does"
3695 " not need to be cross-certified\n"),
3696 keystr_from_pk(node->pkt->pkt.public_key));
3699 if(!sub_pk)
3700 continue;
3702 /* Find the selected selfsig on this subkey */
3703 for(node2=node->next;
3704 node2 && node2->pkt->pkttype==PKT_SIGNATURE;
3705 node2=node2->next)
3706 if(node2->pkt->pkt.signature->version>=4
3707 && node2->pkt->pkt.signature->flags.chosen_selfsig)
3709 sig_pk=node2;
3710 break;
3713 if(!sig_pk)
3714 continue;
3716 /* Find the secret subkey that matches the public subkey */
3717 for(node2=sec_keyblock;node2;node2=node2->next)
3718 if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
3719 && !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
3721 sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
3722 break;
3725 if(!sub_sk)
3727 tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
3728 keystr_from_pk(sub_pk));
3729 continue;
3732 /* Now finally find the matching selfsig on the secret subkey.
3733 We can't use chosen_selfsig here (it's not set for secret
3734 keys), so we just pick the selfsig with the right class.
3735 This is what menu_expire does as well. */
3736 for(node2=node2->next;
3737 node2 && node2->pkt->pkttype!=PKT_SECRET_SUBKEY;
3738 node2=node2->next)
3739 if(node2->pkt->pkttype==PKT_SIGNATURE
3740 && node2->pkt->pkt.signature->version>=4
3741 && node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
3742 && node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
3743 && node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
3745 sig_sk=node2;
3746 break;
3749 /* Now we can get to work. We have a main key and secret part,
3750 a signing subkey with signature and secret part possibly with
3751 signature. */
3753 passphrase=get_last_passphrase();
3754 set_next_passphrase(passphrase);
3755 xfree(passphrase);
3757 rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk,
3758 timestamp);
3759 if(rc==0)
3761 PKT_signature *newsig;
3762 PACKET *newpkt;
3764 passphrase=get_last_passphrase();
3765 set_next_passphrase(passphrase);
3766 xfree(passphrase);
3768 rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
3769 NULL,sub_pk,main_sk,NULL,NULL);
3770 if(rc==0)
3772 /* Put the new sig into place on the pubkey */
3773 newpkt=xmalloc_clear(sizeof(*newpkt));
3774 newpkt->pkttype=PKT_SIGNATURE;
3775 newpkt->pkt.signature=newsig;
3776 free_packet(sig_pk->pkt);
3777 xfree(sig_pk->pkt);
3778 sig_pk->pkt=newpkt;
3780 if(sig_sk)
3782 /* Put the new sig into place on the seckey */
3783 newpkt=xmalloc_clear(sizeof(*newpkt));
3784 newpkt->pkttype=PKT_SIGNATURE;
3785 newpkt->pkt.signature=copy_signature(NULL,newsig);
3786 free_packet(sig_sk->pkt);
3787 xfree(sig_sk->pkt);
3788 sig_sk->pkt=newpkt;
3791 modified=1;
3793 else
3795 log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
3796 break;
3799 else
3801 log_error("make_backsig failed: %s\n",g10_errstr(rc));
3802 break;
3806 set_next_passphrase(NULL);
3808 free_secret_key(main_sk);
3809 if(sub_sk)
3810 free_secret_key(sub_sk);
3812 return modified;
3816 static int
3817 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3819 byte buf[1];
3821 /* first clear all primary uid flags so that we are sure none are
3822 * lingering around */
3823 delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
3824 delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3826 /* if opaque is set,we want to set the primary id */
3827 if (opaque) {
3828 buf[0] = 1;
3829 build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3832 return 0;
3837 * Set the primary uid flag for the selected UID. We will also reset
3838 * all other primary uid flags. For this to work with have to update
3839 * all the signature timestamps. If we would do this with the current
3840 * time, we lose quite a lot of information, so we use a a kludge to
3841 * do this: Just increment the timestamp by one second which is
3842 * sufficient to updated a signature during import.
3844 static int
3845 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3847 PKT_secret_key *sk; /* copy of the main sk */
3848 PKT_public_key *main_pk;
3849 PKT_user_id *uid;
3850 KBNODE node;
3851 u32 keyid[2];
3852 int selected;
3853 int attribute = 0;
3854 int modified = 0;
3856 if ( count_selected_uids (pub_keyblock) != 1 ) {
3857 tty_printf(_("Please select exactly one user ID.\n"));
3858 return 0;
3861 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3862 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3864 /* Now we can actually change the self signature(s) */
3865 main_pk = NULL;
3866 uid = NULL;
3867 selected = 0;
3869 /* Is our selected uid an attribute packet? */
3870 for ( node=pub_keyblock; node; node = node->next )
3871 if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3872 attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3874 for ( node=pub_keyblock; node; node = node->next ) {
3875 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3876 break; /* ready */
3878 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3879 main_pk = node->pkt->pkt.public_key;
3880 keyid_from_pk( main_pk, keyid );
3882 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3883 uid = node->pkt->pkt.user_id;
3884 selected = node->flag & NODFLG_SELUID;
3886 else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3887 PKT_signature *sig = node->pkt->pkt.signature;
3888 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3889 && (uid && (sig->sig_class&~3) == 0x10)
3890 && attribute == (uid->attrib_data!=NULL)
3891 && sig->flags.chosen_selfsig )
3893 if(sig->version < 4) {
3894 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3896 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3897 user);
3898 xfree(user);
3900 else {
3901 /* This is a selfsignature which is to be replaced.
3902 We can just ignore v3 signatures because they are
3903 not able to carry the primary ID flag. We also
3904 ignore self-sigs on user IDs that are not of the
3905 same type that we are making primary. That is, if
3906 we are making a user ID primary, we alter user IDs.
3907 If we are making an attribute packet primary, we
3908 alter attribute packets. */
3910 /* FIXME: We must make sure that we only have one
3911 self-signature per user ID here (not counting
3912 revocations) */
3913 PKT_signature *newsig;
3914 PACKET *newpkt;
3915 const byte *p;
3916 int action;
3918 /* see whether this signature has the primary UID flag */
3919 p = parse_sig_subpkt (sig->hashed,
3920 SIGSUBPKT_PRIMARY_UID, NULL );
3921 if ( !p )
3922 p = parse_sig_subpkt (sig->unhashed,
3923 SIGSUBPKT_PRIMARY_UID, NULL );
3924 if ( p && *p ) /* yes */
3925 action = selected? 0 : -1;
3926 else /* no */
3927 action = selected? 1 : 0;
3929 if (action) {
3930 int rc = update_keysig_packet (&newsig, sig,
3931 main_pk, uid, NULL,
3933 change_primary_uid_cb,
3934 action > 0? "x":NULL );
3935 if( rc ) {
3936 log_error ("update_keysig_packet failed: %s\n",
3937 g10_errstr(rc));
3938 free_secret_key( sk );
3939 return 0;
3941 /* replace the packet */
3942 newpkt = xmalloc_clear( sizeof *newpkt );
3943 newpkt->pkttype = PKT_SIGNATURE;
3944 newpkt->pkt.signature = newsig;
3945 free_packet( node->pkt );
3946 xfree( node->pkt );
3947 node->pkt = newpkt;
3948 modified = 1;
3955 free_secret_key( sk );
3956 return modified;
3961 * Set preferences to new values for the selected user IDs
3963 static int
3964 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3966 PKT_secret_key *sk; /* copy of the main sk */
3967 PKT_public_key *main_pk;
3968 PKT_user_id *uid;
3969 KBNODE node;
3970 u32 keyid[2];
3971 int selected, select_all;
3972 int modified = 0;
3974 no_primary_warning(pub_keyblock);
3976 select_all = !count_selected_uids (pub_keyblock);
3978 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3979 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3981 /* Now we can actually change the self signature(s) */
3982 main_pk = NULL;
3983 uid = NULL;
3984 selected = 0;
3985 for ( node=pub_keyblock; node; node = node->next ) {
3986 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3987 break; /* ready */
3989 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3990 main_pk = node->pkt->pkt.public_key;
3991 keyid_from_pk( main_pk, keyid );
3993 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3994 uid = node->pkt->pkt.user_id;
3995 selected = select_all || (node->flag & NODFLG_SELUID);
3997 else if ( main_pk && uid && selected
3998 && node->pkt->pkttype == PKT_SIGNATURE ) {
3999 PKT_signature *sig = node->pkt->pkt.signature;
4000 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4001 && (uid && (sig->sig_class&~3) == 0x10)
4002 && sig->flags.chosen_selfsig ) {
4003 if( sig->version < 4 ) {
4004 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4006 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4007 user);
4008 xfree(user);
4010 else {
4011 /* This is a selfsignature which is to be replaced
4012 * We have to ignore v3 signatures because they are
4013 * not able to carry the preferences */
4014 PKT_signature *newsig;
4015 PACKET *newpkt;
4016 int rc;
4018 rc = update_keysig_packet (&newsig, sig,
4019 main_pk, uid, NULL,
4021 keygen_upd_std_prefs,
4022 NULL );
4023 if( rc ) {
4024 log_error ("update_keysig_packet failed: %s\n",
4025 g10_errstr(rc));
4026 free_secret_key( sk );
4027 return 0;
4029 /* replace the packet */
4030 newpkt = xmalloc_clear( sizeof *newpkt );
4031 newpkt->pkttype = PKT_SIGNATURE;
4032 newpkt->pkt.signature = newsig;
4033 free_packet( node->pkt );
4034 xfree( node->pkt );
4035 node->pkt = newpkt;
4036 modified = 1;
4042 free_secret_key( sk );
4043 return modified;
4047 static int
4048 menu_set_keyserver_url (const char *url,
4049 KBNODE pub_keyblock, KBNODE sec_keyblock )
4051 PKT_secret_key *sk; /* copy of the main sk */
4052 PKT_public_key *main_pk;
4053 PKT_user_id *uid;
4054 KBNODE node;
4055 u32 keyid[2];
4056 int selected, select_all;
4057 int modified = 0;
4058 char *answer,*uri;
4060 no_primary_warning(pub_keyblock);
4062 if(url)
4063 answer=xstrdup(url);
4064 else
4066 answer=cpr_get_utf8("keyedit.add_keyserver",
4067 _("Enter your preferred keyserver URL: "));
4068 if(answer[0]=='\0' || answer[0]=='\004')
4070 xfree(answer);
4071 return 0;
4075 if(ascii_strcasecmp(answer,"none")==0)
4076 uri=NULL;
4077 else
4079 struct keyserver_spec *keyserver=NULL;
4080 /* Sanity check the format */
4081 keyserver=parse_keyserver_uri(answer,1,NULL,0);
4082 xfree(answer);
4083 if(!keyserver)
4085 log_info(_("could not parse keyserver URL\n"));
4086 return 0;
4088 uri=xstrdup(keyserver->uri);
4089 free_keyserver_spec(keyserver);
4092 select_all = !count_selected_uids (pub_keyblock);
4094 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4095 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4097 /* Now we can actually change the self signature(s) */
4098 main_pk = NULL;
4099 uid = NULL;
4100 selected = 0;
4101 for ( node=pub_keyblock; node; node = node->next )
4103 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4104 break; /* ready */
4106 if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4108 main_pk = node->pkt->pkt.public_key;
4109 keyid_from_pk( main_pk, keyid );
4111 else if ( node->pkt->pkttype == PKT_USER_ID )
4113 uid = node->pkt->pkt.user_id;
4114 selected = select_all || (node->flag & NODFLG_SELUID);
4116 else if ( main_pk && uid && selected
4117 && node->pkt->pkttype == PKT_SIGNATURE )
4119 PKT_signature *sig = node->pkt->pkt.signature;
4120 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4121 && (uid && (sig->sig_class&~3) == 0x10)
4122 && sig->flags.chosen_selfsig)
4124 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4125 if( sig->version < 4 )
4126 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4127 user);
4128 else
4130 /* This is a selfsignature which is to be replaced
4131 * We have to ignore v3 signatures because they are
4132 * not able to carry the subpacket. */
4133 PKT_signature *newsig;
4134 PACKET *newpkt;
4135 int rc;
4136 const byte *p;
4137 size_t plen;
4139 p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
4140 if(p && plen)
4142 tty_printf("Current preferred keyserver for user"
4143 " ID \"%s\": ",user);
4144 tty_print_utf8_string(p,plen);
4145 tty_printf("\n");
4146 if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
4147 uri?_("Are you sure you want to replace it? (y/N) "):
4148 _("Are you sure you want to delete it? (y/N) ")))
4149 continue;
4151 else if(uri==NULL)
4153 /* There is no current keyserver URL, so there
4154 is no point in trying to un-set it. */
4155 continue;
4158 rc = update_keysig_packet (&newsig, sig,
4159 main_pk, uid, NULL,
4161 keygen_add_keyserver_url, uri );
4162 if( rc )
4164 log_error ("update_keysig_packet failed: %s\n",
4165 g10_errstr(rc));
4166 free_secret_key( sk );
4167 xfree(uri);
4168 return 0;
4170 /* replace the packet */
4171 newpkt = xmalloc_clear( sizeof *newpkt );
4172 newpkt->pkttype = PKT_SIGNATURE;
4173 newpkt->pkt.signature = newsig;
4174 free_packet( node->pkt );
4175 xfree( node->pkt );
4176 node->pkt = newpkt;
4177 modified = 1;
4180 xfree(user);
4185 xfree(uri);
4186 free_secret_key( sk );
4187 return modified;
4190 static int
4191 menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
4193 PKT_secret_key *sk; /* copy of the main sk */
4194 PKT_public_key *main_pk;
4195 PKT_user_id *uid;
4196 KBNODE node;
4197 u32 keyid[2];
4198 int selected, select_all;
4199 int modified = 0;
4200 char *answer;
4201 struct notation *notation;
4203 no_primary_warning(pub_keyblock);
4205 if(string)
4206 answer=xstrdup(string);
4207 else
4209 answer=cpr_get_utf8("keyedit.add_notation",
4210 _("Enter the notation: "));
4211 if(answer[0]=='\0' || answer[0]=='\004')
4213 xfree(answer);
4214 return 0;
4218 if(ascii_strcasecmp(answer,"none")==0
4219 || ascii_strcasecmp(answer,"-")==0)
4220 notation=NULL; /* delete them all */
4221 else
4223 notation=string_to_notation(answer,0);
4224 if(!notation)
4226 xfree(answer);
4227 return 0;
4231 xfree(answer);
4233 select_all = !count_selected_uids (pub_keyblock);
4235 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4236 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4238 /* Now we can actually change the self signature(s) */
4239 main_pk = NULL;
4240 uid = NULL;
4241 selected = 0;
4242 for ( node=pub_keyblock; node; node = node->next )
4244 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4245 break; /* ready */
4247 if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4249 main_pk = node->pkt->pkt.public_key;
4250 keyid_from_pk( main_pk, keyid );
4252 else if ( node->pkt->pkttype == PKT_USER_ID )
4254 uid = node->pkt->pkt.user_id;
4255 selected = select_all || (node->flag & NODFLG_SELUID);
4257 else if ( main_pk && uid && selected
4258 && node->pkt->pkttype == PKT_SIGNATURE )
4260 PKT_signature *sig = node->pkt->pkt.signature;
4261 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4262 && (uid && (sig->sig_class&~3) == 0x10)
4263 && sig->flags.chosen_selfsig)
4265 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4266 if( sig->version < 4 )
4267 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4268 user);
4269 else
4271 PKT_signature *newsig;
4272 PACKET *newpkt;
4273 int rc,skip=0,addonly=1;
4275 if(sig->flags.notation)
4277 tty_printf("Current notations for user ID \"%s\":\n",
4278 user);
4279 tty_print_notations(-9,sig);
4281 else
4283 tty_printf("No notations on user ID \"%s\"\n",user);
4284 if(notation==NULL)
4286 /* There are no current notations, so there
4287 is no point in trying to un-set them. */
4288 continue;
4292 if(notation)
4294 struct notation *n;
4295 int deleting=0;
4297 notation->next=sig_to_notation(sig);
4299 for(n=notation->next;n;n=n->next)
4300 if(strcmp(n->name,notation->name)==0)
4302 if(notation->value)
4304 if(strcmp(n->value,notation->value)==0)
4306 if(notation->flags.ignore)
4308 /* Value match with a delete
4309 flag. */
4310 n->flags.ignore=1;
4311 deleting=1;
4313 else
4315 /* Adding the same notation
4316 twice, so don't add it at
4317 all. */
4318 skip=1;
4319 tty_printf("Skipping notation:"
4320 " %s=%s\n",
4321 notation->name,
4322 notation->value);
4323 break;
4327 else
4329 /* No value, so it means delete. */
4330 n->flags.ignore=1;
4331 deleting=1;
4334 if(n->flags.ignore)
4336 tty_printf("Removing notation: %s=%s\n",
4337 n->name,n->value);
4338 addonly=0;
4342 if(!notation->flags.ignore && !skip)
4343 tty_printf("Adding notation: %s=%s\n",
4344 notation->name,notation->value);
4346 /* We tried to delete, but had no matches */
4347 if(notation->flags.ignore && !deleting)
4348 continue;
4350 else
4352 tty_printf("Removing all notations\n");
4353 addonly=0;
4356 if(skip
4357 || (!addonly
4358 && !cpr_get_answer_is_yes("keyedit.confirm_notation",
4359 _("Proceed? (y/N) "))))
4360 continue;
4362 rc = update_keysig_packet (&newsig, sig,
4363 main_pk, uid, NULL,
4365 keygen_add_notations, notation );
4366 if( rc )
4368 log_error ("update_keysig_packet failed: %s\n",
4369 g10_errstr(rc));
4370 free_secret_key( sk );
4371 free_notation(notation);
4372 xfree(user);
4373 return 0;
4376 /* replace the packet */
4377 newpkt = xmalloc_clear( sizeof *newpkt );
4378 newpkt->pkttype = PKT_SIGNATURE;
4379 newpkt->pkt.signature = newsig;
4380 free_packet( node->pkt );
4381 xfree( node->pkt );
4382 node->pkt = newpkt;
4383 modified = 1;
4385 if(notation)
4387 /* Snip off the notation list from the sig */
4388 free_notation(notation->next);
4389 notation->next=NULL;
4392 xfree(user);
4398 free_notation(notation);
4399 free_secret_key( sk );
4400 return modified;
4404 /****************
4405 * Select one user id or remove all selection if index is 0.
4406 * Returns: True if the selection changed;
4408 static int
4409 menu_select_uid( KBNODE keyblock, int idx )
4411 KBNODE node;
4412 int i;
4414 /* first check that the index is valid */
4415 if( idx ) {
4416 for( i=0, node = keyblock; node; node = node->next ) {
4417 if( node->pkt->pkttype == PKT_USER_ID ) {
4418 if( ++i == idx )
4419 break;
4422 if( !node ) {
4423 tty_printf(_("No user ID with index %d\n"), idx );
4424 return 0;
4427 else { /* reset all */
4428 for( i=0, node = keyblock; node; node = node->next ) {
4429 if( node->pkt->pkttype == PKT_USER_ID )
4430 node->flag &= ~NODFLG_SELUID;
4432 return 1;
4434 /* and toggle the new index */
4435 for( i=0, node = keyblock; node; node = node->next ) {
4436 if( node->pkt->pkttype == PKT_USER_ID ) {
4437 if( ++i == idx ) {
4438 if( (node->flag & NODFLG_SELUID) )
4439 node->flag &= ~NODFLG_SELUID;
4440 else
4441 node->flag |= NODFLG_SELUID;
4446 return 1;
4449 /* Search in the keyblock for a uid that matches namehash */
4450 static int
4451 menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
4453 byte hash[NAMEHASH_LEN];
4454 KBNODE node;
4455 int i;
4457 assert(strlen(namehash)==NAMEHASH_LEN*2);
4459 for(i=0;i<NAMEHASH_LEN;i++)
4460 hash[i]=hextobyte(&namehash[i*2]);
4462 for(node=keyblock->next;node;node=node->next)
4464 if(node->pkt->pkttype==PKT_USER_ID)
4466 namehash_from_uid(node->pkt->pkt.user_id);
4467 if(memcmp(node->pkt->pkt.user_id->namehash,hash,NAMEHASH_LEN)==0)
4469 if(node->flag&NODFLG_SELUID)
4470 node->flag &= ~NODFLG_SELUID;
4471 else
4472 node->flag |= NODFLG_SELUID;
4474 break;
4479 if(!node)
4481 tty_printf(_("No user ID with hash %s\n"),namehash);
4482 return 0;
4485 return 1;
4488 /****************
4489 * Select secondary keys
4490 * Returns: True if the selection changed;
4492 static int
4493 menu_select_key( KBNODE keyblock, int idx )
4495 KBNODE node;
4496 int i;
4498 /* first check that the index is valid */
4499 if( idx ) {
4500 for( i=0, node = keyblock; node; node = node->next ) {
4501 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4502 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
4503 if( ++i == idx )
4504 break;
4507 if( !node ) {
4508 tty_printf(_("No subkey with index %d\n"), idx );
4509 return 0;
4512 else { /* reset all */
4513 for( i=0, node = keyblock; node; node = node->next ) {
4514 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4515 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
4516 node->flag &= ~NODFLG_SELKEY;
4518 return 1;
4520 /* and set the new index */
4521 for( i=0, node = keyblock; node; node = node->next ) {
4522 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4523 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
4524 if( ++i == idx ) {
4525 if( (node->flag & NODFLG_SELKEY) )
4526 node->flag &= ~NODFLG_SELKEY;
4527 else
4528 node->flag |= NODFLG_SELKEY;
4533 return 1;
4537 static int
4538 count_uids_with_flag( KBNODE keyblock, unsigned flag )
4540 KBNODE node;
4541 int i=0;
4543 for( node = keyblock; node; node = node->next )
4544 if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
4545 i++;
4546 return i;
4549 static int
4550 count_keys_with_flag( KBNODE keyblock, unsigned flag )
4552 KBNODE node;
4553 int i=0;
4555 for( node = keyblock; node; node = node->next )
4556 if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4557 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4558 && (node->flag & flag) )
4559 i++;
4560 return i;
4563 static int
4564 count_uids( KBNODE keyblock )
4566 KBNODE node;
4567 int i=0;
4569 for( node = keyblock; node; node = node->next )
4570 if( node->pkt->pkttype == PKT_USER_ID )
4571 i++;
4572 return i;
4576 /****************
4577 * Returns true if there is at least one selected user id
4579 static int
4580 count_selected_uids( KBNODE keyblock )
4582 return count_uids_with_flag( keyblock, NODFLG_SELUID);
4585 static int
4586 count_selected_keys( KBNODE keyblock )
4588 return count_keys_with_flag( keyblock, NODFLG_SELKEY);
4591 /* returns how many real (i.e. not attribute) uids are unmarked */
4592 static int
4593 real_uids_left( KBNODE keyblock )
4595 KBNODE node;
4596 int real=0;
4598 for(node=keyblock;node;node=node->next)
4599 if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
4600 !node->pkt->pkt.user_id->attrib_data)
4601 real++;
4603 return real;
4607 * Ask whether the signature should be revoked. If the user commits this,
4608 * flag bit MARK_A is set on the signature and the user ID.
4610 static void
4611 ask_revoke_sig( KBNODE keyblock, KBNODE node )
4613 int doit=0;
4614 PKT_user_id *uid;
4615 PKT_signature *sig = node->pkt->pkt.signature;
4616 KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4618 if( !unode ) {
4619 log_error("Oops: no user ID for signature\n");
4620 return;
4623 uid=unode->pkt->pkt.user_id;
4625 if(opt.with_colons)
4627 if(uid->attrib_data)
4628 printf("uat:::::::::%u %lu",uid->numattribs,uid->attrib_len);
4629 else
4631 printf("uid:::::::::");
4632 print_string (stdout, uid->name, uid->len, ':');
4635 printf("\n");
4637 print_and_check_one_sig_colon(keyblock,node,NULL,NULL,NULL,NULL,1);
4639 else
4641 char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
4642 unode->pkt->pkt.user_id->len,0);
4643 tty_printf(_("user ID: \"%s\"\n"),p);
4644 xfree(p);
4646 tty_printf(_("signed by your key %s on %s%s%s\n"),
4647 keystr(sig->keyid),datestr_from_sig(sig),
4648 sig->flags.exportable?"":_(" (non-exportable)"),"");
4650 if(sig->flags.expired)
4652 tty_printf(_("This signature expired on %s.\n"),
4653 expirestr_from_sig(sig));
4654 /* Use a different question so we can have different help text */
4655 doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
4656 _("Are you sure you still want to revoke it? (y/N) "));
4658 else
4659 doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
4660 _("Create a revocation certificate for this signature? (y/N) "));
4662 if(doit) {
4663 node->flag |= NODFLG_MARK_A;
4664 unode->flag |= NODFLG_MARK_A;
4668 /****************
4669 * Display all user ids of the current public key together with signatures
4670 * done by one of our keys. Then walk over all this sigs and ask the user
4671 * whether he wants to revoke this signature.
4672 * Return: True when the keyblock has changed.
4674 static int
4675 menu_revsig( KBNODE keyblock )
4677 PKT_signature *sig;
4678 PKT_public_key *primary_pk;
4679 KBNODE node;
4680 int changed = 0;
4681 int rc, any, skip=1, all=!count_selected_uids(keyblock);
4682 struct revocation_reason_info *reason = NULL;
4684 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
4686 /* FIXME: detect duplicates here */
4687 tty_printf(_("You have signed these user IDs on key %s:\n"),
4688 keystr_from_pk(keyblock->pkt->pkt.public_key));
4689 for( node = keyblock; node; node = node->next ) {
4690 node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
4691 if( node->pkt->pkttype == PKT_USER_ID ) {
4692 if( node->flag&NODFLG_SELUID || all ) {
4693 PKT_user_id *uid = node->pkt->pkt.user_id;
4694 /* Hmmm: Should we show only UIDs with a signature? */
4695 tty_printf(" ");
4696 tty_print_utf8_string( uid->name, uid->len );
4697 tty_printf("\n");
4698 skip=0;
4700 else
4701 skip=1;
4703 else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
4704 && ((sig = node->pkt->pkt.signature),
4705 !seckey_available(sig->keyid) ) )
4707 if( (sig->sig_class&~3) == 0x10 )
4709 tty_printf(" ");
4710 tty_printf(_("signed by your key %s on %s%s%s\n"),
4711 keystr(sig->keyid), datestr_from_sig(sig),
4712 sig->flags.exportable?"":_(" (non-exportable)"),
4713 sig->flags.revocable?"":_(" (non-revocable)"));
4714 if(sig->flags.revocable)
4715 node->flag |= NODFLG_SELSIG;
4717 else if( sig->sig_class == 0x30 )
4719 tty_printf(" ");
4720 tty_printf(_("revoked by your key %s on %s\n"),
4721 keystr(sig->keyid),datestr_from_sig(sig));
4726 tty_printf("\n");
4728 /* ask */
4729 for( node = keyblock; node; node = node->next ) {
4730 if( !(node->flag & NODFLG_SELSIG) )
4731 continue;
4732 ask_revoke_sig( keyblock, node );
4735 /* present selected */
4736 any = 0;
4737 for( node = keyblock; node; node = node->next ) {
4738 if( !(node->flag & NODFLG_MARK_A) )
4739 continue;
4740 if( !any ) {
4741 any = 1;
4742 tty_printf(_("You are about to revoke these signatures:\n"));
4744 if( node->pkt->pkttype == PKT_USER_ID ) {
4745 PKT_user_id *uid = node->pkt->pkt.user_id;
4746 tty_printf(" ");
4747 tty_print_utf8_string( uid->name, uid->len );
4748 tty_printf("\n");
4750 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
4751 sig = node->pkt->pkt.signature;
4752 tty_printf(" ");
4753 tty_printf(_("signed by your key %s on %s%s%s\n"),
4754 keystr(sig->keyid), datestr_from_sig(sig),"",
4755 sig->flags.exportable?"":_(" (non-exportable)") );
4758 if( !any )
4759 return 0; /* none selected */
4761 if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
4762 _("Really create the revocation certificates? (y/N) ")) )
4763 return 0; /* forget it */
4765 reason = ask_revocation_reason( 0, 1, 0 );
4766 if( !reason ) { /* user decided to cancel */
4767 return 0;
4770 /* now we can sign the user ids */
4771 reloop: /* (must use this, because we are modifing the list) */
4772 primary_pk = keyblock->pkt->pkt.public_key;
4773 for( node=keyblock; node; node = node->next ) {
4774 KBNODE unode;
4775 PACKET *pkt;
4776 struct sign_attrib attrib;
4777 PKT_secret_key *sk;
4779 if( !(node->flag & NODFLG_MARK_A)
4780 || node->pkt->pkttype != PKT_SIGNATURE )
4781 continue;
4782 unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4783 assert( unode ); /* we already checked this */
4785 memset( &attrib, 0, sizeof attrib );
4786 attrib.reason = reason;
4787 attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
4789 node->flag &= ~NODFLG_MARK_A;
4790 sk = xmalloc_secure_clear( sizeof *sk );
4791 if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
4792 log_info(_("no secret key\n"));
4793 continue;
4795 rc = make_keysig_packet( &sig, primary_pk,
4796 unode->pkt->pkt.user_id,
4797 NULL,
4799 0x30, 0, 0, 0, 0,
4800 sign_mk_attrib,
4801 &attrib );
4802 free_secret_key(sk);
4803 if( rc ) {
4804 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4805 release_revocation_reason_info( reason );
4806 return changed;
4808 changed = 1; /* we changed the keyblock */
4809 update_trust = 1;
4810 /* Are we revoking our own uid? */
4811 if(primary_pk->keyid[0]==sig->keyid[0] &&
4812 primary_pk->keyid[1]==sig->keyid[1])
4813 unode->pkt->pkt.user_id->is_revoked=1;
4814 pkt = xmalloc_clear( sizeof *pkt );
4815 pkt->pkttype = PKT_SIGNATURE;
4816 pkt->pkt.signature = sig;
4817 insert_kbnode( unode, new_kbnode(pkt), 0 );
4818 goto reloop;
4821 release_revocation_reason_info( reason );
4822 return changed;
4825 /* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
4826 keyblock changed. */
4827 static int
4828 menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
4830 PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
4831 PKT_secret_key *sk = copy_secret_key( NULL,
4832 sec_keyblock->pkt->pkt.secret_key );
4833 KBNODE node;
4834 int changed = 0;
4835 int rc;
4836 struct revocation_reason_info *reason = NULL;
4838 /* Note that this is correct as per the RFCs, but nevertheless
4839 somewhat meaningless in the real world. 1991 did define the 0x30
4840 sig class, but PGP 2.x did not actually implement it, so it would
4841 probably be safe to use v4 revocations everywhere. -ds */
4843 for( node = pub_keyblock; node; node = node->next )
4844 if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
4845 node->pkt->pkt.user_id->selfsigversion>3))
4847 if((reason = ask_revocation_reason( 0, 1, 4 )))
4848 break;
4849 else
4850 goto leave;
4853 reloop: /* (better this way because we are modifing the keyring) */
4854 for( node = pub_keyblock; node; node = node->next )
4855 if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
4857 PKT_user_id *uid=node->pkt->pkt.user_id;
4859 if(uid->is_revoked)
4861 char *user=utf8_to_native(uid->name,uid->len,0);
4862 log_info(_("user ID \"%s\" is already revoked\n"),user);
4863 xfree(user);
4865 else
4867 PACKET *pkt;
4868 PKT_signature *sig;
4869 struct sign_attrib attrib;
4870 u32 timestamp=make_timestamp();
4872 if(uid->created>=timestamp)
4874 /* Okay, this is a problem. The user ID selfsig was
4875 created in the future, so we need to warn the user and
4876 set our revocation timestamp one second after that so
4877 everything comes out clean. */
4879 log_info(_("WARNING: a user ID signature is dated %d"
4880 " seconds in the future\n"),uid->created-timestamp);
4882 timestamp=uid->created+1;
4885 memset( &attrib, 0, sizeof attrib );
4886 attrib.reason = reason;
4888 node->flag &= ~NODFLG_SELUID;
4890 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
4891 (reason==NULL)?3:0, timestamp, 0,
4892 sign_mk_attrib, &attrib );
4893 if( rc )
4895 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4896 goto leave;
4898 else
4900 pkt = xmalloc_clear( sizeof *pkt );
4901 pkt->pkttype = PKT_SIGNATURE;
4902 pkt->pkt.signature = sig;
4903 insert_kbnode( node, new_kbnode(pkt), 0 );
4905 /* If the trustdb has an entry for this key+uid then the
4906 trustdb needs an update. */
4907 if(!update_trust
4908 && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
4909 update_trust=1;
4911 changed = 1;
4912 node->pkt->pkt.user_id->is_revoked=1;
4914 goto reloop;
4919 if(changed)
4920 commit_kbnode( &pub_keyblock );
4922 leave:
4923 free_secret_key(sk);
4924 release_revocation_reason_info( reason );
4925 return changed;
4928 /****************
4929 * Revoke the whole key.
4931 static int
4932 menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
4934 PKT_public_key *pk=pub_keyblock->pkt->pkt.public_key;
4935 PKT_secret_key *sk;
4936 int rc,changed = 0;
4937 struct revocation_reason_info *reason;
4938 PACKET *pkt;
4939 PKT_signature *sig;
4941 if(pk->is_revoked)
4943 tty_printf(_("Key %s is already revoked.\n"),keystr_from_pk(pk));
4944 return 0;
4947 reason = ask_revocation_reason( 1, 0, 0 );
4948 /* user decided to cancel */
4949 if( !reason )
4950 return 0;
4952 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
4953 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk,
4954 0x20, 0, opt.force_v4_certs?4:0, 0, 0,
4955 revocation_reason_build_cb, reason );
4956 free_secret_key(sk);
4957 if( rc )
4959 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4960 goto scram;
4963 changed = 1; /* we changed the keyblock */
4965 pkt = xmalloc_clear( sizeof *pkt );
4966 pkt->pkttype = PKT_SIGNATURE;
4967 pkt->pkt.signature = sig;
4968 insert_kbnode( pub_keyblock, new_kbnode(pkt), 0 );
4969 commit_kbnode( &pub_keyblock );
4971 update_trust=1;
4973 scram:
4974 release_revocation_reason_info( reason );
4975 return changed;
4978 static int
4979 menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
4981 PKT_public_key *mainpk;
4982 KBNODE node;
4983 int changed = 0;
4984 int rc;
4985 struct revocation_reason_info *reason = NULL;
4987 reason = ask_revocation_reason( 1, 0, 0 );
4988 if( !reason ) { /* user decided to cancel */
4989 return 0;
4992 reloop: /* (better this way because we are modifing the keyring) */
4993 mainpk = pub_keyblock->pkt->pkt.public_key;
4994 for( node = pub_keyblock; node; node = node->next ) {
4995 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4996 && (node->flag & NODFLG_SELKEY) ) {
4997 PACKET *pkt;
4998 PKT_signature *sig;
4999 PKT_secret_key *sk;
5000 PKT_public_key *subpk = node->pkt->pkt.public_key;
5001 struct sign_attrib attrib;
5003 if(subpk->is_revoked)
5005 tty_printf(_("Subkey %s is already revoked.\n"),
5006 keystr_from_pk(subpk));
5007 continue;
5010 memset( &attrib, 0, sizeof attrib );
5011 attrib.reason = reason;
5013 node->flag &= ~NODFLG_SELKEY;
5014 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
5015 rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
5016 0x28, 0, 0, 0, 0,
5017 sign_mk_attrib, &attrib );
5018 free_secret_key(sk);
5019 if( rc ) {
5020 log_error(_("signing failed: %s\n"), g10_errstr(rc));
5021 release_revocation_reason_info( reason );
5022 return changed;
5024 changed = 1; /* we changed the keyblock */
5026 pkt = xmalloc_clear( sizeof *pkt );
5027 pkt->pkttype = PKT_SIGNATURE;
5028 pkt->pkt.signature = sig;
5029 insert_kbnode( node, new_kbnode(pkt), 0 );
5030 goto reloop;
5033 commit_kbnode( &pub_keyblock );
5034 /*commit_kbnode( &sec_keyblock );*/
5036 /* No need to set update_trust here since signing keys no longer
5037 are used to certify other keys, so there is no change in trust
5038 when revoking/removing them */
5040 release_revocation_reason_info( reason );
5041 return changed;
5044 /* Note that update_ownertrust is going to mark the trustdb dirty when
5045 enabling or disabling a key. This is arguably sub-optimal as
5046 disabled keys are still counted in the web of trust, but perhaps
5047 not worth adding extra complexity to change. -ds */
5048 static int
5049 enable_disable_key( KBNODE keyblock, int disable )
5051 PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
5052 ->pkt->pkt.public_key;
5053 unsigned int trust, newtrust;
5055 trust = newtrust = get_ownertrust (pk);
5056 newtrust &= ~TRUST_FLAG_DISABLED;
5057 if( disable )
5058 newtrust |= TRUST_FLAG_DISABLED;
5059 if( trust == newtrust )
5060 return 0; /* already in that state */
5061 update_ownertrust(pk, newtrust );
5062 return 0;
5066 static void
5067 menu_showphoto( KBNODE keyblock )
5069 KBNODE node;
5070 int select_all = !count_selected_uids(keyblock);
5071 int count=0;
5072 PKT_public_key *pk=NULL;
5074 /* Look for the public key first. We have to be really, really,
5075 explicit as to which photo this is, and what key it is a UID on
5076 since people may want to sign it. */
5078 for( node = keyblock; node; node = node->next )
5080 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
5081 pk = node->pkt->pkt.public_key;
5082 else if( node->pkt->pkttype == PKT_USER_ID )
5084 PKT_user_id *uid = node->pkt->pkt.user_id;
5085 count++;
5087 if((select_all || (node->flag & NODFLG_SELUID)) &&
5088 uid->attribs!=NULL)
5090 int i;
5092 for(i=0;i<uid->numattribs;i++)
5094 byte type;
5095 u32 size;
5097 if(uid->attribs[i].type==ATTRIB_IMAGE &&
5098 parse_image_header(&uid->attribs[i],&type,&size))
5100 tty_printf(_("Displaying %s photo ID of size %ld for "
5101 "key %s (uid %d)\n"),
5102 image_type_to_string(type,1),
5103 (ulong)size,keystr_from_pk(pk),count);
5104 show_photos(&uid->attribs[i],1,pk,NULL);