2006-09-06 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / keyedit.c
blob80d714adcbfc84fd6aa8560c52ce0d119743a48b
1 /* keyedit.c - keyedit stuff
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 * 2006 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 2 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, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA.
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include <ctype.h>
30 #ifdef HAVE_LIBREADLINE
31 #include <stdio.h>
32 #include <readline/readline.h>
33 #endif
35 #include "gpg.h"
36 #include "options.h"
37 #include "packet.h"
38 #include "errors.h"
39 #include "iobuf.h"
40 #include "keydb.h"
41 #include "photoid.h"
42 #include "util.h"
43 #include "main.h"
44 #include "trustdb.h"
45 #include "filter.h"
46 #include "ttyio.h"
47 #include "status.h"
48 #include "i18n.h"
49 #include "keyserver-internal.h"
51 static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
52 static void show_names(KBNODE keyblock,PKT_public_key *pk,
53 unsigned int flag,int with_prefs);
54 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
55 int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
56 static void show_key_and_fingerprint( KBNODE keyblock );
57 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock,
58 int photo, const char *photo_name );
59 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
60 static int menu_delsig( KBNODE pub_keyblock );
61 static int menu_clean(KBNODE keyblock,int self_only);
62 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
63 static int menu_addrevoker( KBNODE pub_keyblock,
64 KBNODE sec_keyblock, int sensitive );
65 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
66 static int menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock);
67 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
68 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
69 static int menu_set_keyserver_url (const char *url,
70 KBNODE pub_keyblock, KBNODE sec_keyblock );
71 static int menu_set_notation(const char *string,
72 KBNODE pub_keyblock,KBNODE sec_keyblock);
73 static int menu_select_uid( KBNODE keyblock, int idx );
74 static int menu_select_uid_namehash( KBNODE keyblock, const char *namehash );
75 static int menu_select_key( KBNODE keyblock, int idx );
76 static int count_uids( KBNODE keyblock );
77 static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
78 static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
79 static int count_selected_uids( KBNODE keyblock );
80 static int real_uids_left( KBNODE keyblock );
81 static int count_selected_keys( KBNODE keyblock );
82 static int menu_revsig( KBNODE keyblock );
83 static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
84 static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
85 static int menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
86 static int enable_disable_key( KBNODE keyblock, int disable );
87 static void menu_showphoto( KBNODE keyblock );
89 static int update_trust=0;
91 #define CONTROL_D ('D' - 'A' + 1)
93 #define NODFLG_BADSIG (1<<0) /* bad signature */
94 #define NODFLG_NOKEY (1<<1) /* no public key */
95 #define NODFLG_SIGERR (1<<2) /* other sig error */
97 #define NODFLG_MARK_A (1<<4) /* temporary mark */
98 #define NODFLG_DELSIG (1<<5) /* to be deleted */
100 #define NODFLG_SELUID (1<<8) /* indicate the selected userid */
101 #define NODFLG_SELKEY (1<<9) /* indicate the selected key */
102 #define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
104 struct sign_attrib {
105 int non_exportable,non_revocable;
106 struct revocation_reason_info *reason;
107 byte trust_depth,trust_value;
108 char *trust_regexp;
112 #ifdef ENABLE_CARD_SUPPORT
113 /* Given a node SEC_NODE with a secret key or subkey, locate the
114 corresponding public key from pub_keyblock. */
115 static PKT_public_key *
116 find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
118 KBNODE node = pub_keyblock;
119 PKT_secret_key *sk;
120 PKT_public_key *pk;
122 if (sec_node->pkt->pkttype == PKT_SECRET_KEY
123 && node->pkt->pkttype == PKT_PUBLIC_KEY)
124 return node->pkt->pkt.public_key;
125 if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
126 return NULL;
127 sk = sec_node->pkt->pkt.secret_key;
128 for (; node; node = node->next)
129 if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
131 pk = node->pkt->pkt.public_key;
132 if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
133 return pk;
136 return NULL;
138 #endif /* ENABLE_CARD_SUPPORT */
141 /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
142 code in keylist.c. */
143 static int
144 print_and_check_one_sig_colon( KBNODE keyblock, KBNODE node,
145 int *inv_sigs, int *no_key, int *oth_err,
146 int *is_selfsig, int print_without_key )
148 PKT_signature *sig = node->pkt->pkt.signature;
149 int rc, sigrc;
151 /* TODO: Make sure a cached sig record here still has the pk that
152 issued it. See also keylist.c:list_keyblock_print */
154 switch((rc=check_key_signature(keyblock,node,is_selfsig)))
156 case 0:
157 node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
158 sigrc = '!';
159 break;
160 case G10ERR_BAD_SIGN:
161 node->flag = NODFLG_BADSIG;
162 sigrc = '-';
163 if( inv_sigs )
164 ++*inv_sigs;
165 break;
166 case G10ERR_NO_PUBKEY:
167 case G10ERR_UNU_PUBKEY:
168 node->flag = NODFLG_NOKEY;
169 sigrc = '?';
170 if( no_key )
171 ++*no_key;
172 break;
173 default:
174 node->flag = NODFLG_SIGERR;
175 sigrc = '%';
176 if( oth_err )
177 ++*oth_err;
178 break;
181 if( sigrc != '?' || print_without_key )
183 printf("sig:%c::%d:%08lX%08lX:%lu:%lu:",
184 sigrc,sig->pubkey_algo,(ulong)sig->keyid[0],(ulong)sig->keyid[1],
185 (ulong)sig->timestamp,(ulong)sig->expiredate);
187 if(sig->trust_depth || sig->trust_value)
188 printf("%d %d",sig->trust_depth,sig->trust_value);
190 printf(":");
192 if(sig->trust_regexp)
193 print_string(stdout,sig->trust_regexp,strlen(sig->trust_regexp),':');
195 printf("::%02x%c\n",sig->sig_class,sig->flags.exportable?'x':'l');
197 if(opt.show_subpackets)
198 print_subpackets_colon(sig);
201 return (sigrc == '!');
205 /****************
206 * Print information about a signature, check it and return true
207 * if the signature is okay. NODE must be a signature packet.
209 static int
210 print_and_check_one_sig( KBNODE keyblock, KBNODE node,
211 int *inv_sigs, int *no_key, int *oth_err,
212 int *is_selfsig, int print_without_key )
214 PKT_signature *sig = node->pkt->pkt.signature;
215 int rc, sigrc;
216 int is_rev = sig->sig_class == 0x30;
218 /* TODO: Make sure a cached sig record here still has the pk that
219 issued it. See also keylist.c:list_keyblock_print */
221 switch( (rc = check_key_signature( keyblock, node, is_selfsig)) ) {
222 case 0:
223 node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
224 sigrc = '!';
225 break;
226 case G10ERR_BAD_SIGN:
227 node->flag = NODFLG_BADSIG;
228 sigrc = '-';
229 if( inv_sigs )
230 ++*inv_sigs;
231 break;
232 case G10ERR_NO_PUBKEY:
233 case G10ERR_UNU_PUBKEY:
234 node->flag = NODFLG_NOKEY;
235 sigrc = '?';
236 if( no_key )
237 ++*no_key;
238 break;
239 default:
240 node->flag = NODFLG_SIGERR;
241 sigrc = '%';
242 if( oth_err )
243 ++*oth_err;
244 break;
246 if( sigrc != '?' || print_without_key ) {
247 tty_printf("%s%c%c %c%c%c%c%c%c %s %s",
248 is_rev? "rev":"sig",sigrc,
249 (sig->sig_class-0x10>0 &&
250 sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
251 sig->flags.exportable?' ':'L',
252 sig->flags.revocable?' ':'R',
253 sig->flags.policy_url?'P':' ',
254 sig->flags.notation?'N':' ',
255 sig->flags.expired?'X':' ',
256 (sig->trust_depth>9)?'T':
257 (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
258 keystr(sig->keyid),datestr_from_sig(sig));
259 if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
260 tty_printf(" %s",expirestr_from_sig(sig));
261 tty_printf(" ");
262 if( sigrc == '%' )
263 tty_printf("[%s] ", g10_errstr(rc) );
264 else if( sigrc == '?' )
266 else if( *is_selfsig ) {
267 tty_printf( is_rev? _("[revocation]")
268 : _("[self-signature]") );
270 else
272 size_t n;
273 char *p = get_user_id( sig->keyid, &n );
274 tty_print_utf8_string2(p, n, opt.screen_columns-keystrlen()-26-
275 ((opt.list_options&LIST_SHOW_SIG_EXPIRE)?11:0));
276 xfree(p);
278 tty_printf("\n");
280 if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY_URLS))
281 show_policy_url(sig,3,0);
283 if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATIONS))
284 show_notation(sig,3,0,
285 ((opt.list_options&LIST_SHOW_STD_NOTATIONS)?1:0)+
286 ((opt.list_options&LIST_SHOW_USER_NOTATIONS)?2:0));
288 if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER_URLS))
289 show_keyserver_url(sig,3,0);
292 return (sigrc == '!');
297 /****************
298 * Check the keysigs and set the flags to indicate errors.
299 * Returns true if error found.
301 static int
302 check_all_keysigs( KBNODE keyblock, int only_selected )
304 KBNODE kbctx;
305 KBNODE node;
306 int inv_sigs = 0;
307 int no_key = 0;
308 int oth_err = 0;
309 int has_selfsig = 0;
310 int mis_selfsig = 0;
311 int selected = !only_selected;
312 int anyuid = 0;
314 for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
315 if( node->pkt->pkttype == PKT_USER_ID ) {
316 PKT_user_id *uid = node->pkt->pkt.user_id;
318 if( only_selected )
319 selected = (node->flag & NODFLG_SELUID);
320 if( selected ) {
321 tty_printf("uid ");
322 tty_print_utf8_string( uid->name, uid->len );
323 tty_printf("\n");
324 if( anyuid && !has_selfsig )
325 mis_selfsig++;
326 has_selfsig = 0;
327 anyuid = 1;
330 else if( selected && node->pkt->pkttype == PKT_SIGNATURE
331 && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
332 || node->pkt->pkt.signature->sig_class == 0x30 ) ) {
333 int selfsig;
335 if( print_and_check_one_sig( keyblock, node, &inv_sigs,
336 &no_key, &oth_err, &selfsig, 0 ) ) {
337 if( selfsig )
338 has_selfsig = 1;
340 /* Hmmm: should we update the trustdb here? */
343 if( !has_selfsig )
344 mis_selfsig++;
345 if( inv_sigs == 1 )
346 tty_printf(_("1 bad signature\n") );
347 else if( inv_sigs )
348 tty_printf(_("%d bad signatures\n"), inv_sigs );
349 if( no_key == 1 )
350 tty_printf(_("1 signature not checked due to a missing key\n") );
351 else if( no_key )
352 tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
353 if( oth_err == 1 )
354 tty_printf(_("1 signature not checked due to an error\n") );
355 else if( oth_err )
356 tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
357 if( mis_selfsig == 1 )
358 tty_printf(_("1 user ID without valid self-signature detected\n"));
359 else if( mis_selfsig )
360 tty_printf(_("%d user IDs without valid self-signatures detected\n"),
361 mis_selfsig);
363 return inv_sigs || no_key || oth_err || mis_selfsig;
367 static int
368 sign_mk_attrib( PKT_signature *sig, void *opaque )
370 struct sign_attrib *attrib = opaque;
371 byte buf[8];
373 if( attrib->non_exportable ) {
374 buf[0] = 0; /* not exportable */
375 build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
378 if( attrib->non_revocable ) {
379 buf[0] = 0; /* not revocable */
380 build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
383 if( attrib->reason )
384 revocation_reason_build_cb( sig, attrib->reason );
386 if(attrib->trust_depth)
388 /* Not critical. If someone doesn't understand trust sigs,
389 this can still be a valid regular signature. */
390 buf[0] = attrib->trust_depth;
391 buf[1] = attrib->trust_value;
392 build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
394 /* Critical. If someone doesn't understands regexps, this
395 whole sig should be invalid. Note the +1 for the length -
396 regexps are null terminated. */
397 if(attrib->trust_regexp)
398 build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
399 attrib->trust_regexp,
400 strlen(attrib->trust_regexp)+1);
403 return 0;
406 static void
407 trustsig_prompt(byte *trust_value,byte *trust_depth,char **regexp)
409 char *p;
411 *trust_value=0;
412 *trust_depth=0;
413 *regexp=NULL;
415 /* Same string as pkclist.c:do_edit_ownertrust */
416 tty_printf(_("Please decide how far you trust this user to correctly verify"
417 " other users' keys\n(by looking at passports, checking"
418 " fingerprints from different sources, etc.)\n"));
419 tty_printf("\n");
420 tty_printf (_(" %d = I trust marginally\n"), 1);
421 tty_printf (_(" %d = I trust fully\n"), 2);
422 tty_printf("\n");
424 while(*trust_value==0)
426 p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
427 trim_spaces(p);
428 cpr_kill_prompt();
429 /* 60 and 120 are as per RFC2440 */
430 if(p[0]=='1' && !p[1])
431 *trust_value=60;
432 else if(p[0]=='2' && !p[1])
433 *trust_value=120;
434 xfree(p);
437 tty_printf("\n");
439 tty_printf(_(
440 "Please enter the depth of this trust signature.\n"
441 "A depth greater than 1 allows the key you are signing to make\n"
442 "trust signatures on your behalf.\n"));
443 tty_printf("\n");
445 while(*trust_depth==0)
447 p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
448 trim_spaces(p);
449 cpr_kill_prompt();
450 *trust_depth=atoi(p);
451 xfree(p);
454 tty_printf("\n");
456 tty_printf(_("Please enter a domain to restrict this signature, "
457 "or enter for none.\n"));
459 tty_printf("\n");
461 p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
462 trim_spaces(p);
463 cpr_kill_prompt();
465 if(strlen(p)>0)
467 char *q=p;
468 int regexplen=100,ind;
470 *regexp=xmalloc(regexplen);
472 /* Now mangle the domain the user entered into a regexp. To do
473 this, \-escape everything that isn't alphanumeric, and attach
474 "<[^>]+[@.]" to the front, and ">$" to the end. */
476 strcpy(*regexp,"<[^>]+[@.]");
477 ind=strlen(*regexp);
479 while(*q)
481 if(!((*q>='A' && *q<='Z')
482 || (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
483 (*regexp)[ind++]='\\';
485 (*regexp)[ind++]=*q;
487 if((regexplen-ind)<3)
489 regexplen+=100;
490 *regexp=xrealloc(*regexp,regexplen);
493 q++;
496 (*regexp)[ind]='\0';
497 strcat(*regexp,">$");
500 xfree(p);
501 tty_printf("\n");
504 /****************
505 * Loop over all locusr and and sign the uids after asking.
506 * If no user id is marked, all user ids will be signed;
507 * if some user_ids are marked those will be signed.
509 static int
510 sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
511 int local, int nonrevocable, int trust, int interactive )
513 int rc = 0;
514 SK_LIST sk_list = NULL;
515 SK_LIST sk_rover = NULL;
516 PKT_secret_key *sk = NULL;
517 KBNODE node, uidnode;
518 PKT_public_key *primary_pk=NULL;
519 int select_all = !count_selected_uids(keyblock) || interactive;
520 int all_v3=1;
522 /* Are there any non-v3 sigs on this key already? */
523 if(PGP2)
524 for(node=keyblock;node;node=node->next)
525 if(node->pkt->pkttype==PKT_SIGNATURE &&
526 node->pkt->pkt.signature->version>3)
528 all_v3=0;
529 break;
532 /* build a list of all signators.
534 * We use the CERT flag to request the primary which must always
535 * be one which is capable of signing keys. I can't see a reason
536 * why to sign keys using a subkey. Implementation of USAGE_CERT
537 * is just a hack in getkey.c and does not mean that a subkey
538 * marked as certification capable will be used. */
539 rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_CERT);
540 if( rc )
541 goto leave;
543 /* loop over all signators */
544 for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
545 u32 sk_keyid[2],pk_keyid[2];
546 char *p,*trust_regexp=NULL;
547 int force_v4=0,class=0,selfsig=0;
548 u32 duration=0,timestamp=0;
549 byte trust_depth=0,trust_value=0;
551 if(local || nonrevocable || trust ||
552 opt.cert_policy_url || opt.cert_notations)
553 force_v4=1;
555 /* we have to use a copy of the sk, because make_keysig_packet
556 * may remove the protection from sk and if we did other
557 * changes to the secret key, we would save the unprotected
558 * version */
559 if( sk )
560 free_secret_key(sk);
561 sk = copy_secret_key( NULL, sk_rover->sk );
562 keyid_from_sk( sk, sk_keyid );
563 /* set mark A for all selected user ids */
564 for( node=keyblock; node; node = node->next ) {
565 if( select_all || (node->flag & NODFLG_SELUID) )
566 node->flag |= NODFLG_MARK_A;
567 else
568 node->flag &= ~NODFLG_MARK_A;
570 /* reset mark for uids which are already signed */
571 uidnode = NULL;
572 for( node=keyblock; node; node = node->next ) {
573 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
574 primary_pk=node->pkt->pkt.public_key;
575 keyid_from_pk( primary_pk, pk_keyid );
577 /* Is this a self-sig? */
578 if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
580 selfsig=1;
581 /* Do not force a v4 sig here, otherwise it would
582 be difficult to remake a v3 selfsig. If this
583 is a v3->v4 promotion case, then we set
584 force_v4 later anyway. */
585 force_v4=0;
588 else if( node->pkt->pkttype == PKT_USER_ID )
590 uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
591 if(uidnode)
593 int yesreally=0;
594 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
595 uidnode->pkt->pkt.user_id->len,
598 if(uidnode->pkt->pkt.user_id->is_revoked)
600 tty_printf(_("User ID \"%s\" is revoked."),user);
602 if(selfsig)
603 tty_printf("\n");
604 else if(opt.expert)
606 tty_printf("\n");
607 /* No, so remove the mark and continue */
608 if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
609 _("Are you sure you "
610 "still want to sign "
611 "it? (y/N) ")))
613 uidnode->flag &= ~NODFLG_MARK_A;
614 uidnode=NULL;
616 else if(interactive)
617 yesreally=1;
619 else
621 uidnode->flag &= ~NODFLG_MARK_A;
622 uidnode=NULL;
623 tty_printf(_(" Unable to sign.\n"));
626 else if(uidnode->pkt->pkt.user_id->is_expired)
628 tty_printf(_("User ID \"%s\" is expired."),user);
630 if(selfsig)
631 tty_printf("\n");
632 else if(opt.expert)
634 tty_printf("\n");
635 /* No, so remove the mark and continue */
636 if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
637 _("Are you sure you "
638 "still want to sign "
639 "it? (y/N) ")))
641 uidnode->flag &= ~NODFLG_MARK_A;
642 uidnode=NULL;
644 else if(interactive)
645 yesreally=1;
647 else
649 uidnode->flag &= ~NODFLG_MARK_A;
650 uidnode=NULL;
651 tty_printf(_(" Unable to sign.\n"));
654 else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
656 tty_printf(_("User ID \"%s\" is not self-signed."),
657 user);
659 if(opt.expert)
661 tty_printf("\n");
662 /* No, so remove the mark and continue */
663 if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
664 _("Are you sure you "
665 "still want to sign "
666 "it? (y/N) ")))
668 uidnode->flag &= ~NODFLG_MARK_A;
669 uidnode=NULL;
671 else if(interactive)
672 yesreally=1;
674 else
676 uidnode->flag &= ~NODFLG_MARK_A;
677 uidnode=NULL;
678 tty_printf(_(" Unable to sign.\n"));
682 if(uidnode && interactive && !yesreally)
684 tty_printf(_("User ID \"%s\" is signable. "),user);
685 if(!cpr_get_answer_is_yes("sign_uid.sign_okay",
686 _("Sign it? (y/N) ")))
688 uidnode->flag &= ~NODFLG_MARK_A;
689 uidnode=NULL;
693 xfree(user);
696 else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
697 && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
698 if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
699 && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
700 char buf[50];
701 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
702 uidnode->pkt->pkt.user_id->len,
705 /* It's a v3 self-sig. Make it into a v4 self-sig? */
706 if(node->pkt->pkt.signature->version<4 && selfsig)
708 tty_printf(_("The self-signature on \"%s\"\n"
709 "is a PGP 2.x-style signature.\n"),user);
711 /* Note that the regular PGP2 warning below
712 still applies if there are no v4 sigs on
713 this key at all. */
715 if(opt.expert)
716 if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
717 _("Do you want to promote "
718 "it to an OpenPGP self-"
719 "signature? (y/N) ")))
721 force_v4=1;
722 node->flag|=NODFLG_DELSIG;
723 xfree(user);
724 continue;
728 /* Is the current signature expired? */
729 if(node->pkt->pkt.signature->flags.expired)
731 tty_printf(_("Your current signature on \"%s\"\n"
732 "has expired.\n"),user);
734 if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
735 _("Do you want to issue a "
736 "new signature to replace "
737 "the expired one? (y/N) ")))
739 /* Mark these for later deletion. We
740 don't want to delete them here, just in
741 case the replacement signature doesn't
742 happen for some reason. We only delete
743 these after the replacement is already
744 in place. */
746 node->flag|=NODFLG_DELSIG;
747 xfree(user);
748 continue;
752 if(!node->pkt->pkt.signature->flags.exportable && !local)
754 /* It's a local sig, and we want to make a
755 exportable sig. */
756 tty_printf(_("Your current signature on \"%s\"\n"
757 "is a local signature.\n"),user);
759 if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
760 _("Do you want to promote "
761 "it to a full exportable "
762 "signature? (y/N) ")))
764 /* Mark these for later deletion. We
765 don't want to delete them here, just in
766 case the replacement signature doesn't
767 happen for some reason. We only delete
768 these after the replacement is already
769 in place. */
771 node->flag|=NODFLG_DELSIG;
772 xfree(user);
773 continue;
777 /* Fixme: see whether there is a revocation in which
778 * case we should allow to sign it again. */
779 if (!node->pkt->pkt.signature->flags.exportable && local)
780 tty_printf(_(
781 "\"%s\" was already locally signed by key %s\n"),
782 user,keystr_from_sk(sk));
783 else
784 tty_printf(_("\"%s\" was already signed by key %s\n"),
785 user,keystr_from_sk(sk));
787 if(opt.expert
788 && cpr_get_answer_is_yes("sign_uid.dupe_okay",
789 _("Do you want to sign it "
790 "again anyway? (y/N) ")))
792 /* Don't delete the old sig here since this is
793 an --expert thing. */
794 xfree(user);
795 continue;
798 sprintf (buf, "%08lX%08lX",
799 (ulong)sk->keyid[0], (ulong)sk->keyid[1] );
800 write_status_text (STATUS_ALREADY_SIGNED, buf);
801 uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
803 xfree(user);
808 /* check whether any uids are left for signing */
809 if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) )
811 tty_printf(_("Nothing to sign with key %s\n"),keystr_from_sk(sk));
812 continue;
815 /* Ask whether we really should sign these user id(s) */
816 tty_printf("\n");
817 show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
818 tty_printf("\n");
820 if(primary_pk->expiredate && !selfsig)
822 u32 now=make_timestamp();
824 if(primary_pk->expiredate<=now)
826 tty_printf(_("This key has expired!"));
828 if(opt.expert)
830 tty_printf(" ");
831 if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
832 _("Are you sure you still "
833 "want to sign it? (y/N) ")))
834 continue;
836 else
838 tty_printf(_(" Unable to sign.\n"));
839 continue;
842 else
844 tty_printf(_("This key is due to expire on %s.\n"),
845 expirestr_from_pk(primary_pk));
847 if(opt.ask_cert_expire)
849 char *answer=cpr_get("sign_uid.expire",
850 _("Do you want your signature to "
851 "expire at the same time? (Y/n) "));
852 if(answer_is_yes_no_default(answer,1))
854 /* This fixes the signature timestamp we're
855 going to make as now. This is so the
856 expiration date is exactly correct, and not
857 a few seconds off (due to the time it takes
858 to answer the questions, enter the
859 passphrase, etc). */
860 timestamp=now;
861 duration=primary_pk->expiredate-now;
862 force_v4=1;
865 cpr_kill_prompt();
866 xfree(answer);
871 /* Only ask for duration if we haven't already set it to match
872 the expiration of the pk */
873 if(!duration && !selfsig)
875 if(opt.ask_cert_expire)
876 duration=ask_expire_interval(1,opt.def_cert_expire);
877 else
878 duration=parse_expire_string(opt.def_cert_expire);
881 if(duration)
882 force_v4=1;
884 /* Is --pgp2 on, it's a v3 key, all the sigs on the key are
885 currently v3 and we're about to sign it with a v4 sig? If
886 so, danger! */
887 if(PGP2 && all_v3 &&
888 (sk->version>3 || force_v4) && primary_pk->version<=3)
890 tty_printf(_("You may not make an OpenPGP signature on a "
891 "PGP 2.x key while in --pgp2 mode.\n"));
892 tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
894 if(opt.expert)
896 if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
897 _("Are you sure you still "
898 "want to sign it? (y/N) ")))
899 continue;
901 all_v3=0;
903 else
904 continue;
907 if(selfsig)
909 else
911 if(opt.batch || !opt.ask_cert_level)
912 class=0x10+opt.def_cert_level;
913 else
915 char *answer;
917 tty_printf(_("How carefully have you verified the key you are "
918 "about to sign actually belongs\nto the person "
919 "named above? If you don't know what to "
920 "answer, enter \"0\".\n"));
921 tty_printf("\n");
922 tty_printf(_(" (0) I will not answer.%s\n"),
923 opt.def_cert_level==0?" (default)":"");
924 tty_printf(_(" (1) I have not checked at all.%s\n"),
925 opt.def_cert_level==1?" (default)":"");
926 tty_printf(_(" (2) I have done casual checking.%s\n"),
927 opt.def_cert_level==2?" (default)":"");
928 tty_printf(_(" (3) I have done very careful checking.%s\n"),
929 opt.def_cert_level==3?" (default)":"");
930 tty_printf("\n");
932 while(class==0)
934 answer = cpr_get("sign_uid.class",_("Your selection? "
935 "(enter `?' for more information): "));
936 if(answer[0]=='\0')
937 class=0x10+opt.def_cert_level; /* Default */
938 else if(ascii_strcasecmp(answer,"0")==0)
939 class=0x10; /* Generic */
940 else if(ascii_strcasecmp(answer,"1")==0)
941 class=0x11; /* Persona */
942 else if(ascii_strcasecmp(answer,"2")==0)
943 class=0x12; /* Casual */
944 else if(ascii_strcasecmp(answer,"3")==0)
945 class=0x13; /* Positive */
946 else
947 tty_printf(_("Invalid selection.\n"));
949 xfree(answer);
953 if(trust)
954 trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
957 p=get_user_id_native(sk_keyid);
958 tty_printf(_("Are you sure that you want to sign this key with your\n"
959 "key \"%s\" (%s)\n"),p,keystr_from_sk(sk));
960 xfree(p);
962 if(selfsig)
964 tty_printf("\n");
965 tty_printf(_("This will be a self-signature.\n"));
967 if( local )
969 tty_printf("\n");
970 tty_printf(
971 _("WARNING: the signature will not be marked "
972 "as non-exportable.\n"));
975 if( nonrevocable )
977 tty_printf("\n");
978 tty_printf(
979 _("WARNING: the signature will not be marked "
980 "as non-revocable.\n"));
983 else
985 if( local )
987 tty_printf("\n");
988 tty_printf(
989 _("The signature will be marked as non-exportable.\n"));
992 if( nonrevocable )
994 tty_printf("\n");
995 tty_printf(
996 _("The signature will be marked as non-revocable.\n"));
999 switch(class)
1001 case 0x11:
1002 tty_printf("\n");
1003 tty_printf(_("I have not checked this key at all.\n"));
1004 break;
1006 case 0x12:
1007 tty_printf("\n");
1008 tty_printf(_("I have checked this key casually.\n"));
1009 break;
1011 case 0x13:
1012 tty_printf("\n");
1013 tty_printf(_("I have checked this key very carefully.\n"));
1014 break;
1018 tty_printf("\n");
1020 if( opt.batch && opt.answer_yes )
1022 else if( !cpr_get_answer_is_yes("sign_uid.okay",
1023 _("Really sign? (y/N) ")) )
1024 continue;
1026 /* now we can sign the user ids */
1027 reloop: /* (must use this, because we are modifing the list) */
1028 primary_pk = NULL;
1029 for( node=keyblock; node; node = node->next ) {
1030 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
1031 primary_pk = node->pkt->pkt.public_key;
1032 else if( node->pkt->pkttype == PKT_USER_ID
1033 && (node->flag & NODFLG_MARK_A) ) {
1034 PACKET *pkt;
1035 PKT_signature *sig;
1036 struct sign_attrib attrib;
1038 assert( primary_pk );
1039 memset( &attrib, 0, sizeof attrib );
1040 attrib.non_exportable = local;
1041 attrib.non_revocable = nonrevocable;
1042 attrib.trust_depth = trust_depth;
1043 attrib.trust_value = trust_value;
1044 attrib.trust_regexp = trust_regexp;
1045 node->flag &= ~NODFLG_MARK_A;
1047 /* we force creation of a v4 signature for local
1048 * signatures, otherwise we would not generate the
1049 * subpacket with v3 keys and the signature becomes
1050 * exportable */
1052 if(selfsig)
1053 rc = make_keysig_packet( &sig, primary_pk,
1054 node->pkt->pkt.user_id,
1055 NULL,
1057 0x13, 0, force_v4?4:0, 0, 0,
1058 keygen_add_std_prefs, primary_pk);
1059 else
1060 rc = make_keysig_packet( &sig, primary_pk,
1061 node->pkt->pkt.user_id,
1062 NULL,
1064 class, 0, force_v4?4:0,
1065 timestamp, duration,
1066 sign_mk_attrib, &attrib );
1067 if( rc ) {
1068 log_error(_("signing failed: %s\n"), g10_errstr(rc));
1069 goto leave;
1072 *ret_modified = 1; /* we changed the keyblock */
1073 update_trust = 1;
1075 pkt = xmalloc_clear( sizeof *pkt );
1076 pkt->pkttype = PKT_SIGNATURE;
1077 pkt->pkt.signature = sig;
1078 insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
1079 goto reloop;
1083 /* Delete any sigs that got promoted */
1084 for( node=keyblock; node; node = node->next )
1085 if( node->flag & NODFLG_DELSIG)
1086 delete_kbnode(node);
1087 } /* end loop over signators */
1089 leave:
1090 release_sk_list( sk_list );
1091 if( sk )
1092 free_secret_key(sk);
1093 return rc;
1098 /****************
1099 * Change the passphrase of the primary and all secondary keys.
1100 * We use only one passphrase for all keys.
1102 static int
1103 change_passphrase( KBNODE keyblock )
1105 int rc = 0;
1106 int changed=0;
1107 KBNODE node;
1108 PKT_secret_key *sk;
1109 char *passphrase = NULL;
1110 int no_primary_secrets = 0;
1111 int any;
1113 node = find_kbnode( keyblock, PKT_SECRET_KEY );
1114 if( !node ) {
1115 log_error("Oops; secret key not found anymore!\n");
1116 goto leave;
1118 sk = node->pkt->pkt.secret_key;
1120 for (any = 0, node=keyblock; node; node = node->next) {
1121 if (node->pkt->pkttype == PKT_SECRET_KEY
1122 || node->pkt->pkttype == PKT_SECRET_SUBKEY) {
1123 PKT_secret_key *tmpsk = node->pkt->pkt.secret_key;
1124 if (!(tmpsk->is_protected
1125 && (tmpsk->protect.s2k.mode == 1001
1126 || tmpsk->protect.s2k.mode == 1002))) {
1127 any = 1;
1128 break;
1132 if (!any) {
1133 tty_printf (_("Key has only stub or on-card key items - "
1134 "no passphrase to change.\n"));
1135 goto leave;
1138 /* See how to handle this key. */
1139 switch( is_secret_key_protected( sk ) ) {
1140 case -1:
1141 rc = G10ERR_PUBKEY_ALGO;
1142 break;
1143 case 0:
1144 tty_printf(_("This key is not protected.\n"));
1145 break;
1146 default:
1147 if( sk->protect.s2k.mode == 1001 ) {
1148 tty_printf(_("Secret parts of primary key are not available.\n"));
1149 no_primary_secrets = 1;
1151 else if( sk->protect.s2k.mode == 1002 ) {
1152 tty_printf(_("Secret parts of primary key are stored on-card.\n"));
1153 no_primary_secrets = 1;
1155 else {
1156 tty_printf(_("Key is protected.\n"));
1157 rc = check_secret_key( sk, 0 );
1158 if( !rc )
1159 passphrase = get_last_passphrase();
1161 break;
1164 /* Unprotect all subkeys (use the supplied passphrase or ask)*/
1165 for(node=keyblock; !rc && node; node = node->next ) {
1166 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1167 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1168 if ( !(subsk->is_protected
1169 && (subsk->protect.s2k.mode == 1001
1170 || subsk->protect.s2k.mode == 1002))) {
1171 set_next_passphrase( passphrase );
1172 rc = check_secret_key( subsk, 0 );
1173 if( !rc && !passphrase )
1174 passphrase = get_last_passphrase();
1179 if( rc )
1180 tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
1181 else {
1182 DEK *dek = NULL;
1183 STRING2KEY *s2k = xmalloc_secure( sizeof *s2k );
1184 const char *errtext = NULL;
1186 tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
1188 set_next_passphrase( NULL );
1189 for(;;) {
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, NULL);
1194 if( !dek ) {
1195 errtext = N_("passphrase not correctly repeated; try again");
1196 tty_printf ("%s.\n", _(errtext));
1198 else if( !dek->keylen ) {
1199 rc = 0;
1200 tty_printf(_( "You don't want a passphrase -"
1201 " this is probably a *bad* idea!\n\n"));
1202 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
1203 _("Do you really want to do this? (y/N) ")))
1205 changed++;
1206 break;
1209 else { /* okay */
1210 rc = 0;
1211 if( !no_primary_secrets ) {
1212 sk->protect.algo = dek->algo;
1213 sk->protect.s2k = *s2k;
1214 rc = protect_secret_key( sk, dek );
1216 for(node=keyblock; !rc && node; node = node->next ) {
1217 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1218 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1219 if ( !(subsk->is_protected
1220 && (subsk->protect.s2k.mode == 1001
1221 || subsk->protect.s2k.mode == 1002))) {
1222 subsk->protect.algo = dek->algo;
1223 subsk->protect.s2k = *s2k;
1224 rc = protect_secret_key( subsk, dek );
1228 if( rc )
1229 log_error("protect_secret_key failed: %s\n",
1230 g10_errstr(rc) );
1231 else
1232 changed++;
1233 break;
1236 xfree(s2k);
1237 xfree(dek);
1240 leave:
1241 xfree( passphrase );
1242 set_next_passphrase( NULL );
1243 return changed && !rc;
1247 /****************
1248 * There are some keys out (due to a bug in gnupg), where the sequence
1249 * of the packets is wrong. This function fixes that.
1250 * Returns: true if the keyblock has been fixed.
1252 * Note: This function does not work if there is more than one user ID.
1254 static int
1255 fix_keyblock( KBNODE keyblock )
1257 KBNODE node, last, subkey;
1258 int fixed=0;
1260 /* locate key signatures of class 0x10..0x13 behind sub key packets */
1261 for( subkey=last=NULL, node = keyblock; node;
1262 last=node, node = node->next ) {
1263 switch( node->pkt->pkttype ) {
1264 case PKT_PUBLIC_SUBKEY:
1265 case PKT_SECRET_SUBKEY:
1266 if( !subkey )
1267 subkey = last; /* actually it is the one before the subkey */
1268 break;
1269 case PKT_SIGNATURE:
1270 if( subkey ) {
1271 PKT_signature *sig = node->pkt->pkt.signature;
1272 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1273 log_info(_(
1274 "moving a key signature to the correct place\n"));
1275 last->next = node->next;
1276 node->next = subkey->next;
1277 subkey->next = node;
1278 node = last;
1279 fixed=1;
1282 break;
1283 default: break;
1287 return fixed;
1290 static int
1291 parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
1293 const char *p=str;
1295 while(*p)
1297 if(ascii_strncasecmp(p,"l",1)==0)
1299 *localsig=1;
1300 p++;
1302 else if(ascii_strncasecmp(p,"nr",2)==0)
1304 *nonrevokesig=1;
1305 p+=2;
1307 else if(ascii_strncasecmp(p,"t",1)==0)
1309 *trustsig=1;
1310 p++;
1312 else
1313 return 0;
1316 return 1;
1320 /****************
1321 * Menu driven key editor. If seckey_check is true, then a secret key
1322 * that matches username will be looked for. If it is false, not all
1323 * commands will be available.
1325 * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1328 /* Need an SK for this command */
1329 #define KEYEDIT_NEED_SK 1
1330 /* Cannot be viewing the SK for this command */
1331 #define KEYEDIT_NOT_SK 2
1332 /* Must be viewing the SK for this command */
1333 #define KEYEDIT_ONLY_SK 4
1334 /* Match the tail of the string */
1335 #define KEYEDIT_TAIL_MATCH 8
1337 enum cmdids
1339 cmdNONE = 0,
1340 cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1341 cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
1342 cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
1343 cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
1344 cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
1345 cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
1346 cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN,
1347 cmdMINIMIZE, cmdNOP
1350 static struct
1352 const char *name;
1353 enum cmdids id;
1354 int flags;
1355 const char *desc;
1356 } cmds[] =
1358 { "quit" , cmdQUIT , 0, N_("quit this menu") },
1359 { "q" , cmdQUIT , 0, NULL },
1360 { "save" , cmdSAVE , 0, N_("save and quit") },
1361 { "help" , cmdHELP , 0, N_("show this help") },
1362 { "?" , cmdHELP , 0, NULL },
1363 { "fpr" , cmdFPR , 0, N_("show key fingerprint") },
1364 { "list" , cmdLIST , 0, N_("list key and user IDs") },
1365 { "l" , cmdLIST , 0, NULL },
1366 { "uid" , cmdSELUID , 0, N_("select user ID N") },
1367 { "key" , cmdSELKEY , 0, N_("select subkey N") },
1368 { "check" , cmdCHECK , 0, N_("check signatures") },
1369 { "c" , cmdCHECK , 0, NULL },
1370 { "cross-certify", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1371 { "backsign", cmdBACKSIGN , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1372 { "sign" , cmdSIGN , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
1373 N_("sign selected user IDs [* see below for related commands]") },
1374 { "s" , cmdSIGN , KEYEDIT_NOT_SK, NULL },
1375 /* "lsign" and friends will never match since "sign" comes first
1376 and it is a tail match. They are just here so they show up in
1377 the help menu. */
1378 { "lsign" , cmdNOP , 0, N_("sign selected user IDs locally") },
1379 { "tsign" , cmdNOP , 0,
1380 N_("sign selected user IDs with a trust signature") },
1381 { "nrsign" , cmdNOP , 0,
1382 N_("sign selected user IDs with a non-revocable signature") },
1384 { "debug" , cmdDEBUG , 0, NULL },
1385 { "adduid" , cmdADDUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1386 N_("add a user ID") },
1387 { "addphoto", cmdADDPHOTO , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1388 N_("add a photo ID") },
1389 { "deluid" , cmdDELUID , KEYEDIT_NOT_SK,
1390 N_("delete selected user IDs") },
1391 /* delphoto is really deluid in disguise */
1392 { "delphoto", cmdDELUID , KEYEDIT_NOT_SK, NULL },
1394 { "addkey" , cmdADDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1395 N_("add a subkey") },
1397 #ifdef ENABLE_CARD_SUPPORT
1398 { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1399 N_("add a key to a smartcard") },
1400 { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1401 N_("move a key to a smartcard")},
1402 { "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1403 N_("move a backup key to a smartcard")},
1404 #endif /*ENABLE_CARD_SUPPORT*/
1406 { "delkey" , cmdDELKEY , KEYEDIT_NOT_SK,
1407 N_("delete selected subkeys") },
1408 { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1409 N_("add a revocation key") },
1410 { "delsig" , cmdDELSIG , KEYEDIT_NOT_SK,
1411 N_("delete signatures from the selected user IDs") },
1412 { "expire" , cmdEXPIRE , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1413 N_("change the expiration date for the key or selected subkeys") },
1414 { "primary" , cmdPRIMARY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1415 N_("flag the selected user ID as primary")},
1416 { "toggle" , cmdTOGGLE , KEYEDIT_NEED_SK,
1417 N_("toggle between the secret and public key listings") },
1418 { "t" , cmdTOGGLE , KEYEDIT_NEED_SK, NULL },
1419 { "pref" , cmdPREF , KEYEDIT_NOT_SK,
1420 N_("list preferences (expert)")},
1421 { "showpref", cmdSHOWPREF , KEYEDIT_NOT_SK,
1422 N_("list preferences (verbose)") },
1423 { "setpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1424 N_("set preference list for the selected user IDs") },
1425 /* Alias */
1426 { "updpref" , cmdSETPREF , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1428 { "keyserver",cmdPREFKS , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1429 N_("set the preferred keyserver URL for the selected user IDs")},
1430 { "notation", cmdNOTATION , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1431 N_("set a notation for the selected user IDs")},
1432 { "passwd" , cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1433 N_("change the passphrase") },
1434 /* Alias */
1435 { "password", cmdPASSWD , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1437 { "trust" , cmdTRUST , KEYEDIT_NOT_SK, N_("change the ownertrust") },
1438 { "revsig" , cmdREVSIG , KEYEDIT_NOT_SK,
1439 N_("revoke signatures on the selected user IDs") },
1440 { "revuid" , cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1441 N_("revoke selected user IDs") },
1442 /* Alias */
1443 { "revphoto", cmdREVUID , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1445 { "revkey" , cmdREVKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1446 N_("revoke key or selected subkeys") },
1447 { "enable" , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
1448 { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
1449 { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
1450 { "clean", cmdCLEAN , KEYEDIT_NOT_SK,
1451 N_("compact unusable user IDs and remove unusable signatures from key")},
1452 { "minimize", cmdMINIMIZE , KEYEDIT_NOT_SK,
1453 N_("compact unusable user IDs and remove all signatures from key") },
1454 { NULL, cmdNONE, 0, NULL }
1457 #ifdef HAVE_LIBREADLINE
1459 /* These two functions are used by readline for command completion. */
1461 static char *
1462 command_generator(const char *text,int state)
1464 static int list_index,len;
1465 const char *name;
1467 /* If this is a new word to complete, initialize now. This includes
1468 saving the length of TEXT for efficiency, and initializing the
1469 index variable to 0. */
1470 if(!state)
1472 list_index=0;
1473 len=strlen(text);
1476 /* Return the next partial match */
1477 while((name=cmds[list_index].name))
1479 /* Only complete commands that have help text */
1480 if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1481 return strdup(name);
1484 return NULL;
1487 static char **
1488 keyedit_completion(const char *text, int start, int end)
1490 /* If we are at the start of a line, we try and command-complete.
1491 If not, just do nothing for now. */
1493 if(start==0)
1494 return rl_completion_matches(text,command_generator);
1496 rl_attempted_completion_over=1;
1498 return NULL;
1500 #endif /* HAVE_LIBREADLINE */
1503 void
1504 keyedit_menu( const char *username, STRLIST locusr,
1505 STRLIST commands, int quiet, int seckey_check )
1507 enum cmdids cmd = 0;
1508 int rc = 0;
1509 KBNODE keyblock = NULL;
1510 KEYDB_HANDLE kdbhd = NULL;
1511 KBNODE sec_keyblock = NULL;
1512 KEYDB_HANDLE sec_kdbhd = NULL;
1513 KBNODE cur_keyblock;
1514 char *answer = NULL;
1515 int redisplay = 1;
1516 int modified = 0;
1517 int sec_modified = 0;
1518 int toggle;
1519 int have_commands = !!commands;
1521 if ( opt.command_fd != -1 )
1523 else if( opt.batch && !have_commands )
1525 log_error(_("can't do this in batch mode\n"));
1526 goto leave;
1529 #ifdef HAVE_W32_SYSTEM
1530 /* Due to Windows peculiarities we need to make sure that the
1531 trustdb stale check is done before we open another file
1532 (i.e. by searching for a key). In theory we could make sure
1533 that the files are closed after use but the open/close caches
1534 inhibits that and flushing the cache right before the stale
1535 check is not easy to implement. Thus we take the easy way out
1536 and run the stale check as early as possible. Note, that for
1537 non- W32 platforms it is run indirectly trough a call to
1538 get_validity (). */
1539 check_trustdb_stale ();
1540 #endif
1542 /* Get the public key */
1543 rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1544 if( rc )
1545 goto leave;
1546 if( fix_keyblock( keyblock ) )
1547 modified++;
1548 if( collapse_uids( &keyblock ) )
1549 modified++;
1550 reorder_keyblock(keyblock);
1552 if(seckey_check)
1553 {/* see whether we have a matching secret key */
1554 PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1556 sec_kdbhd = keydb_new (1);
1558 byte afp[MAX_FINGERPRINT_LEN];
1559 size_t an;
1561 fingerprint_from_pk (pk, afp, &an);
1562 while (an < MAX_FINGERPRINT_LEN)
1563 afp[an++] = 0;
1564 rc = keydb_search_fpr (sec_kdbhd, afp);
1566 if (!rc)
1568 rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1569 if (rc)
1571 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1572 username, g10_errstr(rc));
1574 else
1576 merge_keys_and_selfsig( sec_keyblock );
1577 if( fix_keyblock( sec_keyblock ) )
1578 sec_modified++;
1582 if (rc) {
1583 sec_keyblock = NULL;
1584 keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1585 rc = 0;
1588 if( sec_keyblock && !quiet )
1589 tty_printf(_("Secret key is available.\n"));
1592 toggle = 0;
1593 cur_keyblock = keyblock;
1594 for(;;) { /* main loop */
1595 int i, arg_number, photo;
1596 const char *arg_string = "";
1597 char *p;
1598 PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1600 tty_printf("\n");
1602 if( redisplay && !quiet )
1604 show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1605 tty_printf("\n");
1606 redisplay = 0;
1608 do {
1609 xfree(answer);
1610 if( have_commands ) {
1611 if( commands ) {
1612 answer = xstrdup( commands->d );
1613 commands = commands->next;
1615 else if( opt.batch ) {
1616 answer = xstrdup("quit");
1618 else
1619 have_commands = 0;
1621 if( !have_commands )
1623 tty_enable_completion(keyedit_completion);
1624 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1625 cpr_kill_prompt();
1626 tty_disable_completion();
1628 trim_spaces(answer);
1629 } while( *answer == '#' );
1631 arg_number = 0; /* Yes, here is the init which egcc complains about */
1632 photo = 0; /* This too */
1633 if( !*answer )
1634 cmd = cmdLIST;
1635 else if( *answer == CONTROL_D )
1636 cmd = cmdQUIT;
1637 else if( digitp(answer ) ) {
1638 cmd = cmdSELUID;
1639 arg_number = atoi(answer);
1641 else {
1642 if( (p=strchr(answer,' ')) ) {
1643 *p++ = 0;
1644 trim_spaces(answer);
1645 trim_spaces(p);
1646 arg_number = atoi(p);
1647 arg_string = p;
1650 for(i=0; cmds[i].name; i++ )
1652 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1654 size_t l=strlen(cmds[i].name);
1655 size_t a=strlen(answer);
1656 if(a>=l)
1658 if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1660 answer[a-l]='\0';
1661 break;
1665 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1666 break;
1668 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1670 tty_printf(_("Need the secret key to do this.\n"));
1671 cmd = cmdNOP;
1673 else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1674 && toggle)
1675 ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1676 && !toggle))
1678 tty_printf(_("Please use the command \"toggle\" first.\n"));
1679 cmd = cmdNOP;
1681 else
1682 cmd = cmds[i].id;
1684 switch( cmd )
1686 case cmdHELP:
1687 for(i=0; cmds[i].name; i++ )
1689 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1690 ; /* skip if we do not have the secret key */
1691 else if( cmds[i].desc )
1692 tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
1695 tty_printf("\n");
1696 tty_printf(_(
1697 "* The `sign' command may be prefixed with an `l' for local "
1698 "signatures (lsign),\n"
1699 " a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
1700 " (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
1702 break;
1704 case cmdLIST:
1705 redisplay = 1;
1706 break;
1708 case cmdFPR:
1709 show_key_and_fingerprint( keyblock );
1710 break;
1712 case cmdSELUID:
1713 if(strlen(arg_string)==NAMEHASH_LEN*2)
1714 redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
1715 else
1716 redisplay=menu_select_uid(cur_keyblock,arg_number);
1717 break;
1719 case cmdSELKEY:
1720 if( menu_select_key( cur_keyblock, arg_number ) )
1721 redisplay = 1;
1722 break;
1724 case cmdCHECK:
1725 /* we can only do this with the public key becuase the
1726 * check functions can't cope with secret keys and it
1727 * is questionable whether this would make sense at all */
1728 check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1729 break;
1731 case cmdSIGN: /* sign (only the public key) */
1733 int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
1735 if( pk->is_revoked )
1737 tty_printf(_("Key is revoked."));
1739 if(opt.expert)
1741 tty_printf(" ");
1742 if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1743 _("Are you sure you still want"
1744 " to sign it? (y/N) ")))
1745 break;
1747 else
1749 tty_printf(_(" Unable to sign.\n"));
1750 break;
1754 if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
1755 && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1756 _("Really sign all user IDs?"
1757 " (y/N) ")))
1759 if(opt.interactive)
1760 interactive=1;
1761 else
1763 tty_printf(_("Hint: Select the user IDs to sign\n"));
1764 have_commands = 0;
1765 break;
1769 /* What sort of signing are we doing? */
1770 if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1772 tty_printf(_("Unknown signature type `%s'\n"),answer);
1773 break;
1776 sign_uids(keyblock, locusr, &modified,
1777 localsig, nonrevokesig, trustsig, interactive);
1779 break;
1781 case cmdDEBUG:
1782 dump_kbnode( cur_keyblock );
1783 break;
1785 case cmdTOGGLE:
1786 toggle = !toggle;
1787 cur_keyblock = toggle? sec_keyblock : keyblock;
1788 redisplay = 1;
1789 break;
1791 case cmdADDPHOTO:
1792 if (RFC2440 || RFC1991 || PGP2)
1794 tty_printf(
1795 _("This command is not allowed while in %s mode.\n"),
1796 RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1797 break;
1799 photo=1;
1800 /* fall through */
1802 case cmdADDUID:
1803 if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
1805 update_trust = 1;
1806 redisplay = 1;
1807 sec_modified = modified = 1;
1808 merge_keys_and_selfsig( sec_keyblock );
1809 merge_keys_and_selfsig( keyblock );
1811 break;
1813 case cmdDELUID: {
1814 int n1;
1816 if( !(n1=count_selected_uids(keyblock)) )
1817 tty_printf(_("You must select at least one user ID.\n"));
1818 else if( real_uids_left(keyblock) < 1 )
1819 tty_printf(_("You can't delete the last user ID!\n"));
1820 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1821 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1822 : _("Really remove this user ID? (y/N) ")
1823 ) ) {
1824 menu_deluid( keyblock, sec_keyblock );
1825 redisplay = 1;
1826 modified = 1;
1827 if( sec_keyblock )
1828 sec_modified = 1;
1831 break;
1833 case cmdDELSIG: {
1834 int n1;
1836 if( !(n1=count_selected_uids(keyblock)) )
1837 tty_printf(_("You must select at least one user ID.\n"));
1838 else if( menu_delsig( keyblock ) ) {
1839 /* no redisplay here, because it may scroll away some
1840 * status output of delsig */
1841 modified = 1;
1844 break;
1846 case cmdADDKEY:
1847 if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1848 redisplay = 1;
1849 sec_modified = modified = 1;
1850 merge_keys_and_selfsig( sec_keyblock );
1851 merge_keys_and_selfsig( keyblock );
1853 break;
1855 #ifdef ENABLE_CARD_SUPPORT
1856 case cmdADDCARDKEY:
1857 if (card_generate_subkey (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 case cmdKEYTOCARD:
1867 KBNODE node=NULL;
1868 switch ( count_selected_keys (sec_keyblock) )
1870 case 0:
1871 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1872 _("Really move the primary key? (y/N) ")))
1873 node = sec_keyblock;
1874 break;
1875 case 1:
1876 for (node = sec_keyblock; node; node = node->next )
1878 if (node->pkt->pkttype == PKT_SECRET_SUBKEY
1879 && node->flag & NODFLG_SELKEY)
1880 break;
1882 break;
1883 default:
1884 tty_printf(_("You must select exactly one key.\n"));
1885 break;
1887 if (node)
1889 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1890 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1892 redisplay = 1;
1893 sec_modified = 1;
1897 break;
1899 case cmdBKUPTOCARD:
1901 /* Ask for a filename, check whether this is really a
1902 backup key as generated by the card generation, parse
1903 that key and store it on card. */
1904 KBNODE node;
1905 const char *fname;
1906 PACKET *pkt;
1907 IOBUF a;
1909 fname = arg_string;
1910 if (!*fname)
1912 tty_printf (_("Command expects a filename argument\n"));
1913 break;
1916 /* Open that file. */
1917 a = iobuf_open (fname);
1918 if (a && is_secured_file (iobuf_get_fd (a)))
1920 iobuf_close (a);
1921 a = NULL;
1922 errno = EPERM;
1924 if (!a)
1926 tty_printf (_("Can't open `%s': %s\n"),
1927 fname, strerror(errno));
1928 break;
1931 /* Parse and check that file. */
1932 pkt = xmalloc (sizeof *pkt);
1933 init_packet (pkt);
1934 rc = parse_packet (a, pkt);
1935 iobuf_close (a);
1936 iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache). */
1937 if (!rc
1938 && pkt->pkttype != PKT_SECRET_KEY
1939 && pkt->pkttype != PKT_SECRET_SUBKEY)
1940 rc = G10ERR_NO_SECKEY;
1941 if (rc)
1943 tty_printf(_("Error reading backup key from `%s': %s\n"),
1944 fname, g10_errstr (rc));
1945 free_packet (pkt);
1946 xfree (pkt);
1947 break;
1949 node = new_kbnode (pkt);
1951 /* Store it. */
1952 if (card_store_subkey (node, 0))
1954 redisplay = 1;
1955 sec_modified = 1;
1957 release_kbnode (node);
1959 break;
1961 #endif /* ENABLE_CARD_SUPPORT */
1963 case cmdDELKEY: {
1964 int n1;
1966 if( !(n1=count_selected_keys( keyblock )) )
1967 tty_printf(_("You must select at least one key.\n"));
1968 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1969 n1 > 1?
1970 _("Do you really want to delete the selected keys? (y/N) "):
1971 _("Do you really want to delete this key? (y/N) ")
1974 else {
1975 menu_delkey( keyblock, sec_keyblock );
1976 redisplay = 1;
1977 modified = 1;
1978 if( sec_keyblock )
1979 sec_modified = 1;
1982 break;
1984 case cmdADDREVOKER:
1986 int sensitive=0;
1988 if(ascii_strcasecmp(arg_string,"sensitive")==0)
1989 sensitive=1;
1990 if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1991 redisplay = 1;
1992 sec_modified = modified = 1;
1993 merge_keys_and_selfsig( sec_keyblock );
1994 merge_keys_and_selfsig( keyblock );
1997 break;
1999 case cmdREVUID: {
2000 int n1;
2002 if( !(n1=count_selected_uids(keyblock)) )
2003 tty_printf(_("You must select at least one user ID.\n"));
2004 else if( cpr_get_answer_is_yes(
2005 "keyedit.revoke.uid.okay",
2006 n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
2007 : _("Really revoke this user ID? (y/N) ")
2008 ) ) {
2009 if(menu_revuid(keyblock,sec_keyblock))
2011 modified=1;
2012 redisplay=1;
2016 break;
2018 case cmdREVKEY:
2020 int n1;
2022 if( !(n1=count_selected_keys( keyblock )) )
2024 if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2025 _("Do you really want to revoke"
2026 " the entire key? (y/N) ")))
2028 if(menu_revkey(keyblock,sec_keyblock))
2029 modified=1;
2031 redisplay=1;
2034 else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2035 n1 > 1?
2036 _("Do you really want to revoke"
2037 " the selected subkeys? (y/N) "):
2038 _("Do you really want to revoke"
2039 " this subkey? (y/N) ")))
2041 if( menu_revsubkey( keyblock, sec_keyblock ) )
2042 modified = 1;
2044 redisplay = 1;
2047 if(modified)
2048 merge_keys_and_selfsig( keyblock );
2050 break;
2052 case cmdEXPIRE:
2053 if( menu_expire( keyblock, sec_keyblock ) )
2055 merge_keys_and_selfsig( sec_keyblock );
2056 merge_keys_and_selfsig( keyblock );
2057 sec_modified = 1;
2058 modified = 1;
2059 redisplay = 1;
2061 break;
2063 case cmdBACKSIGN:
2064 if(menu_backsign(keyblock,sec_keyblock))
2066 sec_modified = 1;
2067 modified = 1;
2068 redisplay = 1;
2070 break;
2072 case cmdPRIMARY:
2073 if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
2074 merge_keys_and_selfsig( keyblock );
2075 modified = 1;
2076 redisplay = 1;
2078 break;
2080 case cmdPASSWD:
2081 if( change_passphrase( sec_keyblock ) )
2082 sec_modified = 1;
2083 break;
2085 case cmdTRUST:
2086 if(opt.trust_model==TM_EXTERNAL)
2088 tty_printf(_("Owner trust may not be set while "
2089 "using an user provided trust database\n"));
2090 break;
2093 show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
2094 tty_printf("\n");
2095 if( edit_ownertrust( find_kbnode( keyblock,
2096 PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
2097 redisplay = 1;
2098 /* No real need to set update_trust here as
2099 edit_ownertrust() calls revalidation_mark()
2100 anyway. */
2101 update_trust=1;
2103 break;
2105 case cmdPREF:
2107 int count=count_selected_uids(keyblock);
2108 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2109 show_names(keyblock,keyblock->pkt->pkt.public_key,
2110 count?NODFLG_SELUID:0,1);
2112 break;
2114 case cmdSHOWPREF:
2116 int count=count_selected_uids(keyblock);
2117 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2118 show_names(keyblock,keyblock->pkt->pkt.public_key,
2119 count?NODFLG_SELUID:0,2);
2121 break;
2123 case cmdSETPREF:
2125 PKT_user_id *tempuid;
2127 keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
2129 tempuid=keygen_get_std_prefs();
2130 tty_printf(_("Set preference list to:\n"));
2131 show_prefs(tempuid,NULL,1);
2132 free_user_id(tempuid);
2134 if(cpr_get_answer_is_yes("keyedit.setpref.okay",
2135 count_selected_uids (keyblock)?
2136 _("Really update the preferences"
2137 " for the selected user IDs? (y/N) "):
2138 _("Really update the preferences? (y/N) ")))
2140 if ( menu_set_preferences (keyblock, sec_keyblock) )
2142 merge_keys_and_selfsig (keyblock);
2143 modified = 1;
2144 redisplay = 1;
2148 break;
2150 case cmdPREFKS:
2151 if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
2152 keyblock, sec_keyblock ) )
2154 merge_keys_and_selfsig( keyblock );
2155 modified = 1;
2156 redisplay = 1;
2158 break;
2160 case cmdNOTATION:
2161 if( menu_set_notation ( *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 cmdNOP:
2171 break;
2173 case cmdREVSIG:
2174 if( menu_revsig( keyblock ) ) {
2175 redisplay = 1;
2176 modified = 1;
2178 break;
2180 case cmdENABLEKEY:
2181 case cmdDISABLEKEY:
2182 if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
2183 redisplay = 1;
2184 modified = 1;
2186 break;
2188 case cmdSHOWPHOTO:
2189 menu_showphoto(keyblock);
2190 break;
2192 case cmdCLEAN:
2193 redisplay=modified=menu_clean(keyblock,0);
2194 break;
2196 case cmdMINIMIZE:
2197 redisplay=modified=menu_clean(keyblock,1);
2198 break;
2200 case cmdQUIT:
2201 if( have_commands )
2202 goto leave;
2203 if( !modified && !sec_modified )
2204 goto leave;
2205 if( !cpr_get_answer_is_yes("keyedit.save.okay",
2206 _("Save changes? (y/N) ")) ) {
2207 if( cpr_enabled()
2208 || cpr_get_answer_is_yes("keyedit.cancel.okay",
2209 _("Quit without saving? (y/N) ")))
2210 goto leave;
2211 break;
2213 /* fall thru */
2214 case cmdSAVE:
2215 if( modified || sec_modified ) {
2216 if( modified ) {
2217 rc = keydb_update_keyblock (kdbhd, keyblock);
2218 if( rc ) {
2219 log_error(_("update failed: %s\n"), g10_errstr(rc) );
2220 break;
2223 if( sec_modified ) {
2224 rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
2225 if( rc ) {
2226 log_error( _("update secret failed: %s\n"),
2227 g10_errstr(rc) );
2228 break;
2232 else
2233 tty_printf(_("Key not changed so no update needed.\n"));
2235 if( update_trust )
2237 revalidation_mark ();
2238 update_trust=0;
2240 goto leave;
2242 case cmdINVCMD:
2243 default:
2244 tty_printf("\n");
2245 tty_printf(_("Invalid command (try \"help\")\n"));
2246 break;
2248 } /* end main loop */
2250 leave:
2251 release_kbnode( keyblock );
2252 release_kbnode( sec_keyblock );
2253 keydb_release (kdbhd);
2254 xfree(answer);
2257 static void
2258 tty_print_notations(int indent,PKT_signature *sig)
2260 int first=1;
2261 struct notation *notation,*nd;
2263 if(indent<0)
2265 first=0;
2266 indent=-indent;
2269 notation=sig_to_notation(sig);
2271 for(nd=notation;nd;nd=nd->next)
2273 if(!first)
2274 tty_printf("%*s",indent,"");
2275 else
2276 first=0;
2278 tty_print_utf8_string(nd->name,strlen(nd->name));
2279 tty_printf("=");
2280 tty_print_utf8_string(nd->value,strlen(nd->value));
2281 tty_printf("\n");
2284 free_notation(notation);
2287 /****************
2288 * show preferences of a public keyblock.
2290 static void
2291 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
2293 const prefitem_t fake={0,0};
2294 const prefitem_t *prefs;
2295 int i;
2297 if( !uid )
2298 return;
2300 if( uid->prefs )
2301 prefs=uid->prefs;
2302 else if(verbose)
2303 prefs=&fake;
2304 else
2305 return;
2307 if (verbose) {
2308 int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
2310 tty_printf (" ");
2311 tty_printf (_("Cipher: "));
2312 for(i=any=0; prefs[i].type; i++ ) {
2313 if( prefs[i].type == PREFTYPE_SYM ) {
2314 const char *s = gcry_cipher_algo_name (prefs[i].value);
2316 if (any)
2317 tty_printf (", ");
2318 any = 1;
2319 /* We don't want to display strings for experimental algos */
2320 if (s && prefs[i].value < 100 )
2321 tty_printf ("%s", s );
2322 else
2323 tty_printf ("[%d]", prefs[i].value);
2324 if (prefs[i].value == CIPHER_ALGO_3DES )
2325 des_seen = 1;
2328 if (!des_seen) {
2329 if (any)
2330 tty_printf (", ");
2331 tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES));
2333 tty_printf ("\n ");
2334 tty_printf (_("Digest: "));
2335 for(i=any=0; prefs[i].type; i++ ) {
2336 if( prefs[i].type == PREFTYPE_HASH ) {
2337 const char *s = gcry_md_algo_name (prefs[i].value);
2339 if (any)
2340 tty_printf (", ");
2341 any = 1;
2342 /* We don't want to display strings for experimental algos */
2343 if (s && prefs[i].value < 100 )
2344 tty_printf ("%s", s );
2345 else
2346 tty_printf ("[%d]", prefs[i].value);
2347 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2348 sha1_seen = 1;
2351 if (!sha1_seen) {
2352 if (any)
2353 tty_printf (", ");
2354 tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
2356 tty_printf ("\n ");
2357 tty_printf (_("Compression: "));
2358 for(i=any=0; prefs[i].type; i++ ) {
2359 if( prefs[i].type == PREFTYPE_ZIP ) {
2360 const char *s=compress_algo_to_string(prefs[i].value);
2362 if (any)
2363 tty_printf (", ");
2364 any = 1;
2365 /* We don't want to display strings for experimental algos */
2366 if (s && prefs[i].value < 100 )
2367 tty_printf ("%s", s );
2368 else
2369 tty_printf ("[%d]", prefs[i].value);
2370 if (prefs[i].value == COMPRESS_ALGO_NONE )
2371 uncomp_seen = 1;
2374 if (!uncomp_seen) {
2375 if (any)
2376 tty_printf (", ");
2377 else {
2378 tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2379 tty_printf (", ");
2381 tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2383 if(uid->flags.mdc || !uid->flags.ks_modify)
2385 tty_printf ("\n ");
2386 tty_printf (_("Features: "));
2387 any=0;
2388 if(uid->flags.mdc)
2390 tty_printf ("MDC");
2391 any=1;
2393 if(!uid->flags.ks_modify)
2395 if(any)
2396 tty_printf (", ");
2397 tty_printf (_("Keyserver no-modify"));
2400 tty_printf("\n");
2402 if(selfsig)
2404 const byte *pref_ks;
2405 size_t pref_ks_len;
2407 pref_ks=parse_sig_subpkt(selfsig->hashed,
2408 SIGSUBPKT_PREF_KS,&pref_ks_len);
2409 if(pref_ks && pref_ks_len)
2411 tty_printf (" ");
2412 tty_printf(_("Preferred keyserver: "));
2413 tty_print_utf8_string(pref_ks,pref_ks_len);
2414 tty_printf("\n");
2417 if(selfsig->flags.notation)
2419 tty_printf (" ");
2420 tty_printf(_("Notations: "));
2421 tty_print_notations(5+strlen(_("Notations: ")),selfsig);
2425 else {
2426 tty_printf(" ");
2427 for(i=0; prefs[i].type; i++ ) {
2428 tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
2429 prefs[i].type == PREFTYPE_HASH ? 'H' :
2430 prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2431 prefs[i].value);
2433 if (uid->flags.mdc)
2434 tty_printf (" [mdc]");
2435 if (!uid->flags.ks_modify)
2436 tty_printf (" [no-ks-modify]");
2437 tty_printf("\n");
2441 /* This is the version of show_key_with_all_names used when
2442 opt.with_colons is used. It prints all available data in a easy to
2443 parse format and does not translate utf8 */
2444 static void
2445 show_key_with_all_names_colon (KBNODE keyblock)
2447 KBNODE node;
2448 int i, j, ulti_hack=0;
2449 byte pk_version=0;
2450 PKT_public_key *primary=NULL;
2452 /* the keys */
2453 for ( node = keyblock; node; node = node->next )
2455 if (node->pkt->pkttype == PKT_PUBLIC_KEY
2456 || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2458 PKT_public_key *pk = node->pkt->pkt.public_key;
2459 u32 keyid[2];
2461 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2463 pk_version = pk->version;
2464 primary=pk;
2467 keyid_from_pk (pk, keyid);
2469 fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2470 if (!pk->is_valid)
2471 putchar ('i');
2472 else if (pk->is_revoked)
2473 putchar ('r');
2474 else if (pk->has_expired)
2475 putchar ('e');
2476 else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2478 int trust = get_validity_info (pk, NULL);
2479 if(trust=='u')
2480 ulti_hack=1;
2481 putchar (trust);
2484 printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2485 nbits_from_pk (pk),
2486 pk->pubkey_algo,
2487 (ulong)keyid[0], (ulong)keyid[1],
2488 (ulong)pk->timestamp,
2489 (ulong)pk->expiredate );
2490 if (node->pkt->pkttype==PKT_PUBLIC_KEY
2491 && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2492 putchar(get_ownertrust_info (pk));
2493 putchar(':');
2494 putchar('\n');
2496 print_fingerprint (pk, NULL, 0);
2497 print_revokers(pk);
2501 /* the user ids */
2502 i = 0;
2503 for (node = keyblock; node; node = node->next)
2505 if ( node->pkt->pkttype == PKT_USER_ID )
2507 PKT_user_id *uid = node->pkt->pkt.user_id;
2509 ++i;
2511 if(uid->attrib_data)
2512 printf("uat:");
2513 else
2514 printf("uid:");
2516 if ( uid->is_revoked )
2517 printf("r::::::::");
2518 else if ( uid->is_expired )
2519 printf("e::::::::");
2520 else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2521 printf("::::::::");
2522 else
2524 int uid_validity;
2526 if( primary && !ulti_hack )
2527 uid_validity = get_validity_info( primary, uid );
2528 else
2529 uid_validity = 'u';
2530 printf("%c::::::::",uid_validity);
2533 if(uid->attrib_data)
2534 printf ("%u %lu",uid->numattribs,uid->attrib_len);
2535 else
2536 print_string (stdout, uid->name, uid->len, ':');
2538 putchar (':');
2539 /* signature class */
2540 putchar (':');
2541 /* capabilities */
2542 putchar (':');
2543 /* preferences */
2544 if (pk_version>3 || uid->selfsigversion>3)
2546 const prefitem_t *prefs = uid->prefs;
2548 for (j=0; prefs && prefs[j].type; j++)
2550 if (j)
2551 putchar (' ');
2552 printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
2553 prefs[j].type == PREFTYPE_HASH ? 'H' :
2554 prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2555 prefs[j].value);
2557 if (uid->flags.mdc)
2558 printf (",mdc");
2559 if (!uid->flags.ks_modify)
2560 printf (",no-ks-modify");
2562 putchar (':');
2563 /* flags */
2564 printf ("%d,", i);
2565 if (uid->is_primary)
2566 putchar ('p');
2567 if (uid->is_revoked)
2568 putchar ('r');
2569 if (uid->is_expired)
2570 putchar ('e');
2571 if ((node->flag & NODFLG_SELUID))
2572 putchar ('s');
2573 if ((node->flag & NODFLG_MARK_A))
2574 putchar ('m');
2575 putchar (':');
2576 putchar('\n');
2581 static void
2582 show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
2584 KBNODE node;
2585 int i=0;
2587 for( node = keyblock; node; node = node->next )
2589 if( node->pkt->pkttype == PKT_USER_ID
2590 && !is_deleted_kbnode(node))
2592 PKT_user_id *uid = node->pkt->pkt.user_id;
2593 ++i;
2594 if(!flag || (flag && (node->flag & flag)))
2596 if(!(flag&NODFLG_MARK_A) && pk)
2597 tty_printf("%s ",uid_trust_string_fixed(pk,uid));
2599 if( flag & NODFLG_MARK_A )
2600 tty_printf(" ");
2601 else if( node->flag & NODFLG_SELUID )
2602 tty_printf("(%d)* ", i);
2603 else if( uid->is_primary )
2604 tty_printf("(%d). ", i);
2605 else
2606 tty_printf("(%d) ", i);
2607 tty_print_utf8_string( uid->name, uid->len );
2608 tty_printf("\n");
2609 if(with_prefs && pk)
2611 if(pk->version>3 || uid->selfsigversion>3)
2613 PKT_signature *selfsig=NULL;
2614 KBNODE signode;
2616 for(signode=node->next;
2617 signode && signode->pkt->pkttype==PKT_SIGNATURE;
2618 signode=signode->next)
2620 if(signode->pkt->pkt.signature->
2621 flags.chosen_selfsig)
2623 selfsig=signode->pkt->pkt.signature;
2624 break;
2628 show_prefs (uid, selfsig, with_prefs == 2);
2630 else
2631 tty_printf(_("There are no preferences on a"
2632 " PGP 2.x-style user ID.\n"));
2639 /****************
2640 * Display the key a the user ids, if only_marked is true, do only
2641 * so for user ids with mark A flag set and dont display the index number
2643 static void
2644 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2645 int with_fpr, int with_subkeys, int with_prefs )
2647 KBNODE node;
2648 int i;
2649 int do_warn = 0;
2650 byte pk_version=0;
2651 PKT_public_key *primary=NULL;
2653 if (opt.with_colons)
2655 show_key_with_all_names_colon (keyblock);
2656 return;
2659 /* the keys */
2660 for( node = keyblock; node; node = node->next ) {
2661 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2662 || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2663 && !is_deleted_kbnode(node)) ) {
2664 PKT_public_key *pk = node->pkt->pkt.public_key;
2665 const char *otrust="err",*trust="err";
2667 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2668 /* do it here, so that debug messages don't clutter the
2669 * output */
2670 static int did_warn = 0;
2672 trust = get_validity_string (pk, NULL);
2673 otrust = get_ownertrust_string (pk);
2675 /* Show a warning once */
2676 if (!did_warn
2677 && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2678 did_warn = 1;
2679 do_warn = 1;
2682 pk_version=pk->version;
2683 primary=pk;
2686 if(pk->is_revoked)
2688 char *user=get_user_id_string_native(pk->revoked.keyid);
2689 const char *algo = gcry_pk_algo_name (pk->revoked.algo);
2690 tty_printf(_("This key was revoked on %s by %s key %s\n"),
2691 revokestr_from_pk(pk),algo?algo:"?",user);
2692 xfree(user);
2695 if(with_revoker)
2697 if( !pk->revkey && pk->numrevkeys )
2698 BUG();
2699 else
2700 for(i=0;i<pk->numrevkeys;i++)
2702 u32 r_keyid[2];
2703 char *user;
2704 const char *algo;
2706 algo = gcry_pk_algo_name (pk->revkey[i].algid);
2707 keyid_from_fingerprint(pk->revkey[i].fpr,
2708 MAX_FINGERPRINT_LEN,r_keyid);
2710 user=get_user_id_string_native(r_keyid);
2711 tty_printf(_("This key may be revoked by %s key %s"),
2712 algo?algo:"?",user);
2714 if(pk->revkey[i].class&0x40)
2716 tty_printf(" ");
2717 tty_printf(_("(sensitive)"));
2720 tty_printf ("\n");
2721 xfree(user);
2725 keyid_from_pk(pk,NULL);
2726 tty_printf("%s%c %4u%c/%s ",
2727 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2728 (node->flag & NODFLG_SELKEY)? '*':' ',
2729 nbits_from_pk( pk ),
2730 pubkey_letter( pk->pubkey_algo ),
2731 keystr(pk->keyid));
2733 tty_printf(_("created: %s"),datestr_from_pk(pk));
2734 tty_printf(" ");
2735 if(pk->is_revoked)
2736 tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2737 else if(pk->has_expired)
2738 tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2739 else
2740 tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2741 tty_printf(" ");
2742 tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2743 tty_printf("\n");
2745 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2747 if(opt.trust_model!=TM_ALWAYS)
2749 tty_printf("%*s", (int)keystrlen()+13,"");
2750 /* Ownertrust is only meaningful for the PGP or
2751 classic trust models */
2752 if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2754 int width=14-strlen(otrust);
2755 if(width<=0)
2756 width=1;
2757 tty_printf(_("trust: %s"), otrust);
2758 tty_printf("%*s",width,"");
2761 tty_printf(_("validity: %s"), trust );
2762 tty_printf("\n");
2764 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2765 && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2767 tty_printf("*** ");
2768 tty_printf(_("This key has been disabled"));
2769 tty_printf("\n");
2773 if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2775 print_fingerprint ( pk, NULL, 2 );
2776 tty_printf("\n");
2779 else if( node->pkt->pkttype == PKT_SECRET_KEY
2780 || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2782 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2783 tty_printf("%s%c %4u%c/%s ",
2784 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2785 (node->flag & NODFLG_SELKEY)? '*':' ',
2786 nbits_from_sk( sk ),
2787 pubkey_letter( sk->pubkey_algo ),
2788 keystr_from_sk(sk));
2789 tty_printf(_("created: %s"),datestr_from_sk(sk));
2790 tty_printf(" ");
2791 tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2792 tty_printf("\n");
2793 if (sk->is_protected && sk->protect.s2k.mode == 1002)
2795 tty_printf(" ");
2796 tty_printf(_("card-no: "));
2797 if (sk->protect.ivlen == 16
2798 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2799 { /* This is an OpenPGP card. */
2800 for (i=8; i < 14; i++)
2802 if (i == 10)
2803 tty_printf (" ");
2804 tty_printf ("%02X", sk->protect.iv[i]);
2807 else
2808 { /* Something is wrong: Print all. */
2809 for (i=0; i < sk->protect.ivlen; i++)
2810 tty_printf ("%02X", sk->protect.iv[i]);
2812 tty_printf ("\n");
2817 show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
2819 if (do_warn)
2820 tty_printf (_("Please note that the shown key validity"
2821 " is not necessarily correct\n"
2822 "unless you restart the program.\n"));
2826 /* Display basic key information. This function is suitable to show
2827 information on the key without any dependencies on the trustdb or
2828 any other internal GnuPG stuff. KEYBLOCK may either be a public or
2829 a secret key.*/
2830 void
2831 show_basic_key_info ( KBNODE keyblock )
2833 KBNODE node;
2834 int i;
2836 /* The primary key */
2837 for (node = keyblock; node; node = node->next)
2839 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2841 PKT_public_key *pk = node->pkt->pkt.public_key;
2843 /* Note, we use the same format string as in other show
2844 functions to make the translation job easier. */
2845 tty_printf ("%s %4u%c/%s ",
2846 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2847 nbits_from_pk( pk ),
2848 pubkey_letter( pk->pubkey_algo ),
2849 keystr_from_pk(pk));
2850 tty_printf(_("created: %s"),datestr_from_pk(pk));
2851 tty_printf(" ");
2852 tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2853 tty_printf("\n");
2854 print_fingerprint ( pk, NULL, 3 );
2855 tty_printf("\n");
2857 else if (node->pkt->pkttype == PKT_SECRET_KEY)
2859 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2860 tty_printf("%s %4u%c/%s",
2861 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2862 nbits_from_sk( sk ),
2863 pubkey_letter( sk->pubkey_algo ),
2864 keystr_from_sk(sk));
2865 tty_printf(_("created: %s"),datestr_from_sk(sk));
2866 tty_printf(" ");
2867 tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2868 tty_printf("\n");
2869 print_fingerprint (NULL, sk, 3 );
2870 tty_printf("\n");
2874 /* The user IDs. */
2875 for (i=0, node = keyblock; node; node = node->next)
2877 if (node->pkt->pkttype == PKT_USER_ID)
2879 PKT_user_id *uid = node->pkt->pkt.user_id;
2880 ++i;
2882 tty_printf (" ");
2883 if (uid->is_revoked)
2884 tty_printf("[%s] ",_("revoked"));
2885 else if ( uid->is_expired )
2886 tty_printf("[%s] ",_("expired"));
2887 tty_print_utf8_string (uid->name, uid->len);
2888 tty_printf ("\n");
2893 static void
2894 show_key_and_fingerprint( KBNODE keyblock )
2896 KBNODE node;
2897 PKT_public_key *pk = NULL;
2899 for( node = keyblock; node; node = node->next )
2901 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2903 pk = node->pkt->pkt.public_key;
2904 tty_printf("pub %4u%c/%s %s ",
2905 nbits_from_pk( pk ),
2906 pubkey_letter( pk->pubkey_algo ),
2907 keystr_from_pk(pk),
2908 datestr_from_pk(pk) );
2910 else if( node->pkt->pkttype == PKT_USER_ID )
2912 PKT_user_id *uid = node->pkt->pkt.user_id;
2913 tty_print_utf8_string( uid->name, uid->len );
2914 break;
2917 tty_printf("\n");
2918 if( pk )
2919 print_fingerprint( pk, NULL, 2 );
2923 /* Show a warning if no uids on the key have the primary uid flag
2924 set. */
2925 static void
2926 no_primary_warning(KBNODE keyblock)
2928 KBNODE node;
2929 int have_primary=0,uid_count=0;
2931 /* TODO: if we ever start behaving differently with a primary or
2932 non-primary attribute ID, we will need to check for attributes
2933 here as well. */
2935 for(node=keyblock; node; node = node->next)
2937 if(node->pkt->pkttype==PKT_USER_ID
2938 && node->pkt->pkt.user_id->attrib_data==NULL)
2940 uid_count++;
2942 if(node->pkt->pkt.user_id->is_primary==2)
2944 have_primary=1;
2945 break;
2950 if(uid_count>1 && !have_primary)
2951 log_info(_("WARNING: no user ID has been marked as primary. This command"
2952 " may\n cause a different user ID to become"
2953 " the assumed primary.\n"));
2956 /****************
2957 * Ask for a new user id, do the selfsignature and put it into
2958 * both keyblocks.
2959 * Return true if there is a new user id
2961 static int
2962 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
2963 int photo, const char *photo_name)
2965 PKT_user_id *uid;
2966 PKT_public_key *pk=NULL;
2967 PKT_secret_key *sk=NULL;
2968 PKT_signature *sig=NULL;
2969 PACKET *pkt;
2970 KBNODE node;
2971 KBNODE pub_where=NULL, sec_where=NULL;
2972 int rc;
2974 for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2975 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2976 pk = node->pkt->pkt.public_key;
2977 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2978 break;
2980 if( !node ) /* no subkey */
2981 pub_where = NULL;
2982 for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2983 if( node->pkt->pkttype == PKT_SECRET_KEY )
2984 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2985 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2986 break;
2988 if( !node ) /* no subkey */
2989 sec_where = NULL;
2990 assert(pk && sk);
2992 if(photo) {
2993 int hasattrib=0;
2995 for( node = pub_keyblock; node; node = node->next )
2996 if( node->pkt->pkttype == PKT_USER_ID &&
2997 node->pkt->pkt.user_id->attrib_data!=NULL)
2999 hasattrib=1;
3000 break;
3003 /* It is legal but bad for compatibility to add a photo ID to a
3004 v3 key as it means that PGP2 will not be able to use that key
3005 anymore. Also, PGP may not expect a photo on a v3 key.
3006 Don't bother to ask this if the key already has a photo - any
3007 damage has already been done at that point. -dms */
3008 if(pk->version==3 && !hasattrib)
3010 if(opt.expert)
3012 tty_printf(_("WARNING: This is a PGP2-style key. "
3013 "Adding a photo ID may cause some versions\n"
3014 " of PGP to reject this key.\n"));
3016 if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
3017 _("Are you sure you still want "
3018 "to add it? (y/N) ")))
3019 return 0;
3021 else
3023 tty_printf(_("You may not add a photo ID to "
3024 "a PGP2-style key.\n"));
3025 return 0;
3029 uid = generate_photo_id(pk,photo_name);
3030 } else
3031 uid = generate_user_id();
3032 if( !uid )
3033 return 0;
3035 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
3036 keygen_add_std_prefs, pk );
3037 free_secret_key( sk );
3038 if( rc ) {
3039 log_error("signing failed: %s\n", g10_errstr(rc) );
3040 free_user_id(uid);
3041 return 0;
3044 /* insert/append to secret keyblock */
3045 pkt = xmalloc_clear( sizeof *pkt );
3046 pkt->pkttype = PKT_USER_ID;
3047 pkt->pkt.user_id = scopy_user_id(uid);
3048 node = new_kbnode(pkt);
3049 if( sec_where )
3050 insert_kbnode( sec_where, node, 0 );
3051 else
3052 add_kbnode( sec_keyblock, node );
3053 pkt = xmalloc_clear( sizeof *pkt );
3054 pkt->pkttype = PKT_SIGNATURE;
3055 pkt->pkt.signature = copy_signature(NULL, sig);
3056 if( sec_where )
3057 insert_kbnode( node, new_kbnode(pkt), 0 );
3058 else
3059 add_kbnode( sec_keyblock, new_kbnode(pkt) );
3060 /* insert/append to public keyblock */
3061 pkt = xmalloc_clear( sizeof *pkt );
3062 pkt->pkttype = PKT_USER_ID;
3063 pkt->pkt.user_id = uid;
3064 node = new_kbnode(pkt);
3065 if( pub_where )
3066 insert_kbnode( pub_where, node, 0 );
3067 else
3068 add_kbnode( pub_keyblock, node );
3069 pkt = xmalloc_clear( sizeof *pkt );
3070 pkt->pkttype = PKT_SIGNATURE;
3071 pkt->pkt.signature = copy_signature(NULL, sig);
3072 if( pub_where )
3073 insert_kbnode( node, new_kbnode(pkt), 0 );
3074 else
3075 add_kbnode( pub_keyblock, new_kbnode(pkt) );
3076 return 1;
3080 /****************
3081 * Remove all selected userids from the keyrings
3083 static void
3084 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3086 KBNODE node;
3087 int selected=0;
3089 for( node = pub_keyblock; node; node = node->next ) {
3090 if( node->pkt->pkttype == PKT_USER_ID ) {
3091 selected = node->flag & NODFLG_SELUID;
3092 if( selected ) {
3093 /* Only cause a trust update if we delete a
3094 non-revoked user id */
3095 if(!node->pkt->pkt.user_id->is_revoked)
3096 update_trust=1;
3097 delete_kbnode( node );
3098 if( sec_keyblock ) {
3099 KBNODE snode;
3100 int s_selected = 0;
3101 PKT_user_id *uid = node->pkt->pkt.user_id;
3102 for( snode = sec_keyblock; snode; snode = snode->next ) {
3103 if( snode->pkt->pkttype == PKT_USER_ID ) {
3104 PKT_user_id *suid = snode->pkt->pkt.user_id;
3106 s_selected =
3107 (uid->len == suid->len
3108 && !memcmp( uid->name, suid->name, uid->len));
3109 if( s_selected )
3110 delete_kbnode( snode );
3112 else if( s_selected
3113 && snode->pkt->pkttype == PKT_SIGNATURE )
3114 delete_kbnode( snode );
3115 else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
3116 s_selected = 0;
3121 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3122 delete_kbnode( node );
3123 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3124 selected = 0;
3126 commit_kbnode( &pub_keyblock );
3127 if( sec_keyblock )
3128 commit_kbnode( &sec_keyblock );
3132 static int
3133 menu_delsig( KBNODE pub_keyblock )
3135 KBNODE node;
3136 PKT_user_id *uid = NULL;
3137 int changed=0;
3139 for( node = pub_keyblock; node; node = node->next ) {
3140 if( node->pkt->pkttype == PKT_USER_ID ) {
3141 uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
3143 else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3144 int okay, valid, selfsig, inv_sig, no_key, other_err;
3146 tty_printf("uid ");
3147 tty_print_utf8_string( uid->name, uid->len );
3148 tty_printf("\n");
3150 okay = inv_sig = no_key = other_err = 0;
3151 if(opt.with_colons)
3152 valid = print_and_check_one_sig_colon( pub_keyblock, node,
3153 &inv_sig, &no_key, &other_err,
3154 &selfsig, 1 );
3155 else
3156 valid = print_and_check_one_sig( pub_keyblock, node,
3157 &inv_sig, &no_key, &other_err,
3158 &selfsig, 1 );
3160 if( valid ) {
3161 okay = cpr_get_answer_yes_no_quit(
3162 "keyedit.delsig.valid",
3163 _("Delete this good signature? (y/N/q)"));
3165 /* Only update trust if we delete a good signature.
3166 The other two cases do not affect trust. */
3167 if(okay)
3168 update_trust=1;
3170 else if( inv_sig || other_err )
3171 okay = cpr_get_answer_yes_no_quit(
3172 "keyedit.delsig.invalid",
3173 _("Delete this invalid signature? (y/N/q)"));
3174 else if( no_key )
3175 okay = cpr_get_answer_yes_no_quit(
3176 "keyedit.delsig.unknown",
3177 _("Delete this unknown signature? (y/N/q)"));
3179 if( okay == -1 )
3180 break;
3181 if( okay && selfsig && !cpr_get_answer_is_yes(
3182 "keyedit.delsig.selfsig",
3183 _("Really delete this self-signature? (y/N)") ))
3184 okay = 0;
3185 if( okay ) {
3186 delete_kbnode( node );
3187 changed++;
3191 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3192 uid = NULL;
3195 if( changed ) {
3196 commit_kbnode( &pub_keyblock );
3197 tty_printf( changed == 1? _("Deleted %d signature.\n")
3198 : _("Deleted %d signatures.\n"), changed );
3200 else
3201 tty_printf( _("Nothing deleted.\n") );
3203 return changed;
3206 static int
3207 menu_clean(KBNODE keyblock,int self_only)
3209 KBNODE uidnode;
3210 int modified=0,select_all=!count_selected_uids(keyblock);
3212 for(uidnode=keyblock->next;
3213 uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
3214 uidnode=uidnode->next)
3216 if(uidnode->pkt->pkttype==PKT_USER_ID
3217 && (uidnode->flag&NODFLG_SELUID || select_all))
3219 int uids=0,sigs=0;
3220 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3221 uidnode->pkt->pkt.user_id->len,
3224 clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
3225 if(uids)
3227 const char *reason;
3229 if(uidnode->pkt->pkt.user_id->is_revoked)
3230 reason=_("revoked");
3231 else if(uidnode->pkt->pkt.user_id->is_expired)
3232 reason=_("expired");
3233 else
3234 reason=_("invalid");
3236 tty_printf("User ID \"%s\" compacted: %s\n",user,reason);
3238 modified=1;
3240 else if(sigs)
3242 tty_printf(sigs==1?
3243 "User ID \"%s\": %d signature removed\n":
3244 "User ID \"%s\": %d signatures removed\n",
3245 user,sigs);
3247 modified=1;
3249 else
3250 tty_printf(_("User ID \"%s\": already clean\n"),user);
3252 xfree(user);
3256 return modified;
3259 /****************
3260 * Remove some of the secondary keys
3262 static void
3263 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3265 KBNODE node;
3266 int selected=0;
3268 for( node = pub_keyblock; node; node = node->next ) {
3269 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3270 selected = node->flag & NODFLG_SELKEY;
3271 if( selected ) {
3272 delete_kbnode( node );
3273 if( sec_keyblock ) {
3274 KBNODE snode;
3275 int s_selected = 0;
3276 u32 ki[2];
3278 keyid_from_pk( node->pkt->pkt.public_key, ki );
3279 for( snode = sec_keyblock; snode; snode = snode->next ) {
3280 if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3281 u32 ki2[2];
3283 keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
3284 s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
3285 if( s_selected )
3286 delete_kbnode( snode );
3288 else if( s_selected
3289 && snode->pkt->pkttype == PKT_SIGNATURE )
3290 delete_kbnode( snode );
3291 else
3292 s_selected = 0;
3297 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3298 delete_kbnode( node );
3299 else
3300 selected = 0;
3302 commit_kbnode( &pub_keyblock );
3303 if( sec_keyblock )
3304 commit_kbnode( &sec_keyblock );
3306 /* No need to set update_trust here since signing keys are no
3307 longer used to certify other keys, so there is no change in
3308 trust when revoking/removing them */
3312 /****************
3313 * Ask for a new revoker, do the selfsignature and put it into
3314 * both keyblocks.
3315 * Return true if there is a new revoker
3317 static int
3318 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
3320 PKT_public_key *pk=NULL,*revoker_pk=NULL;
3321 PKT_secret_key *sk=NULL;
3322 PKT_signature *sig=NULL;
3323 PACKET *pkt;
3324 struct revocation_key revkey;
3325 size_t fprlen;
3326 int rc;
3328 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3329 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3331 pk=pub_keyblock->pkt->pkt.public_key;
3333 if(pk->numrevkeys==0 && pk->version==3)
3335 /* It is legal but bad for compatibility to add a revoker to a
3336 v3 key as it means that PGP2 will not be able to use that key
3337 anymore. Also, PGP may not expect a revoker on a v3 key.
3338 Don't bother to ask this if the key already has a revoker -
3339 any damage has already been done at that point. -dms */
3340 if(opt.expert)
3342 tty_printf(_("WARNING: This is a PGP 2.x-style key. "
3343 "Adding a designated revoker may cause\n"
3344 " some versions of PGP to reject this key.\n"));
3346 if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
3347 _("Are you sure you still want "
3348 "to add it? (y/N) ")))
3349 return 0;
3351 else
3353 tty_printf(_("You may not add a designated revoker to "
3354 "a PGP 2.x-style key.\n"));
3355 return 0;
3359 sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3361 for(;;)
3363 char *answer;
3365 if(revoker_pk)
3366 free_public_key(revoker_pk);
3368 revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
3370 tty_printf("\n");
3372 answer=cpr_get_utf8("keyedit.add_revoker",
3373 _("Enter the user ID of the designated revoker: "));
3374 if(answer[0]=='\0' || answer[0]=='\004')
3376 xfree(answer);
3377 goto fail;
3380 /* Note that I'm requesting CERT here, which usually implies
3381 primary keys only, but some casual testing shows that PGP and
3382 GnuPG both can handle a designated revokation from a
3383 subkey. */
3384 revoker_pk->req_usage=PUBKEY_USAGE_CERT;
3385 rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
3386 if(rc)
3388 log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
3389 xfree(answer);
3390 continue;
3393 xfree(answer);
3395 fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
3396 if(fprlen!=20)
3398 log_error(_("cannot appoint a PGP 2.x style key as a "
3399 "designated revoker\n"));
3400 continue;
3403 revkey.class=0x80;
3404 if(sensitive)
3405 revkey.class|=0x40;
3406 revkey.algid=revoker_pk->pubkey_algo;
3408 if(cmp_public_keys(revoker_pk,pk)==0)
3410 /* This actually causes no harm (after all, a key that
3411 designates itself as a revoker is the same as a
3412 regular key), but it's easy enough to check. */
3413 log_error(_("you cannot appoint a key as its own "
3414 "designated revoker\n"));
3416 continue;
3419 keyid_from_pk(pk,NULL);
3421 /* Does this revkey already exist? */
3422 if(!pk->revkey && pk->numrevkeys)
3423 BUG();
3424 else
3426 int i;
3428 for(i=0;i<pk->numrevkeys;i++)
3430 if(memcmp(&pk->revkey[i],&revkey,
3431 sizeof(struct revocation_key))==0)
3433 char buf[50];
3435 log_error(_("this key has already been designated "
3436 "as a revoker\n"));
3438 sprintf(buf,"%08lX%08lX",
3439 (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
3440 write_status_text(STATUS_ALREADY_SIGNED,buf);
3442 break;
3446 if(i<pk->numrevkeys)
3447 continue;
3450 print_pubkey_info(NULL,revoker_pk);
3451 print_fingerprint(revoker_pk,NULL,2);
3452 tty_printf("\n");
3454 tty_printf(_("WARNING: appointing a key as a designated revoker "
3455 "cannot be undone!\n"));
3457 tty_printf("\n");
3459 if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
3460 _("Are you sure you want to appoint this "
3461 "key as a designated revoker? (y/N) ")))
3462 continue;
3464 free_public_key(revoker_pk);
3465 revoker_pk=NULL;
3466 break;
3469 /* The 1F signature must be at least v4 to carry the revocation key
3470 subpacket. */
3471 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3472 keygen_add_revkey,&revkey );
3473 if( rc )
3475 log_error("signing failed: %s\n", g10_errstr(rc) );
3476 goto fail;
3479 free_secret_key(sk);
3480 sk=NULL;
3482 /* insert into secret keyblock */
3483 pkt = xmalloc_clear( sizeof *pkt );
3484 pkt->pkttype = PKT_SIGNATURE;
3485 pkt->pkt.signature = copy_signature(NULL, sig);
3486 insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3488 /* insert into public keyblock */
3489 pkt = xmalloc_clear( sizeof *pkt );
3490 pkt->pkttype = PKT_SIGNATURE;
3491 pkt->pkt.signature = sig;
3492 insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3494 return 1;
3496 fail:
3497 if(sk)
3498 free_secret_key(sk);
3499 if(sig)
3500 free_seckey_enc(sig);
3501 if(revoker_pk)
3502 free_public_key(revoker_pk);
3504 return 0;
3508 static int
3509 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3511 int n1, signumber, rc;
3512 u32 expiredate;
3513 int mainkey=0;
3514 PKT_secret_key *sk; /* copy of the main sk */
3515 PKT_public_key *main_pk, *sub_pk;
3516 PKT_user_id *uid;
3517 KBNODE node;
3518 u32 keyid[2];
3520 if( count_selected_keys( sec_keyblock ) ) {
3521 tty_printf(_("Please remove selections from the secret keys.\n"));
3522 return 0;
3525 n1 = count_selected_keys( pub_keyblock );
3526 if( n1 > 1 ) {
3527 tty_printf(_("Please select at most one subkey.\n"));
3528 return 0;
3530 else if( n1 )
3531 tty_printf(_("Changing expiration time for a subkey.\n"));
3532 else
3534 tty_printf(_("Changing expiration time for the primary key.\n"));
3535 mainkey=1;
3536 no_primary_warning(pub_keyblock);
3539 expiredate = ask_expiredate();
3540 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3541 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3543 /* Now we can actually change the self signature(s) */
3544 main_pk = sub_pk = NULL;
3545 uid = NULL;
3546 signumber = 0;
3547 for( node=pub_keyblock; node; node = node->next ) {
3548 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3549 main_pk = node->pkt->pkt.public_key;
3550 keyid_from_pk( main_pk, keyid );
3551 main_pk->expiredate = expiredate;
3553 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3554 && (node->flag & NODFLG_SELKEY ) ) {
3555 sub_pk = node->pkt->pkt.public_key;
3556 sub_pk->expiredate = expiredate;
3558 else if( node->pkt->pkttype == PKT_USER_ID )
3559 uid = node->pkt->pkt.user_id;
3560 else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3561 && ( mainkey || sub_pk ) ) {
3562 PKT_signature *sig = node->pkt->pkt.signature;
3563 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3564 && ( (mainkey && uid
3565 && uid->created && (sig->sig_class&~3) == 0x10)
3566 || (!mainkey && sig->sig_class == 0x18) )
3567 && sig->flags.chosen_selfsig )
3569 /* this is a selfsignature which is to be replaced */
3570 PKT_signature *newsig;
3571 PACKET *newpkt;
3572 KBNODE sn;
3573 int signumber2 = 0;
3575 signumber++;
3577 if( (mainkey && main_pk->version < 4)
3578 || (!mainkey && sub_pk->version < 4 ) ) {
3579 log_info(_(
3580 "You can't change the expiration date of a v3 key\n"));
3581 free_secret_key( sk );
3582 return 0;
3585 /* find the corresponding secret self-signature */
3586 for( sn=sec_keyblock; sn; sn = sn->next ) {
3587 if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3588 PKT_signature *b = sn->pkt->pkt.signature;
3589 if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3590 && sig->sig_class == b->sig_class
3591 && ++signumber2 == signumber )
3592 break;
3595 if( !sn )
3596 log_info(_("No corresponding signature in secret ring\n"));
3598 if( mainkey )
3599 rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3600 sk, keygen_add_key_expire, main_pk);
3601 else
3602 rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3603 sk, keygen_add_key_expire, sub_pk );
3604 if( rc ) {
3605 log_error("make_keysig_packet failed: %s\n",
3606 g10_errstr(rc));
3607 free_secret_key( sk );
3608 return 0;
3610 /* replace the packet */
3611 newpkt = xmalloc_clear( sizeof *newpkt );
3612 newpkt->pkttype = PKT_SIGNATURE;
3613 newpkt->pkt.signature = newsig;
3614 free_packet( node->pkt );
3615 xfree( node->pkt );
3616 node->pkt = newpkt;
3617 if( sn ) {
3618 newpkt = xmalloc_clear( sizeof *newpkt );
3619 newpkt->pkttype = PKT_SIGNATURE;
3620 newpkt->pkt.signature = copy_signature( NULL, newsig );
3621 free_packet( sn->pkt );
3622 xfree( sn->pkt );
3623 sn->pkt = newpkt;
3625 sub_pk = NULL;
3630 free_secret_key( sk );
3631 update_trust=1;
3632 return 1;
3635 static int
3636 menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
3638 int rc,modified=0;
3639 PKT_public_key *main_pk;
3640 PKT_secret_key *main_sk,*sub_sk=NULL;
3641 KBNODE node;
3643 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3644 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3646 merge_keys_and_selfsig(pub_keyblock);
3647 main_pk=pub_keyblock->pkt->pkt.public_key;
3648 main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3649 keyid_from_pk(main_pk,NULL);
3651 for(node=pub_keyblock;node;node=node->next)
3653 PKT_public_key *sub_pk=NULL;
3654 KBNODE node2,sig_pk=NULL,sig_sk=NULL;
3655 char *passphrase;
3657 if(sub_sk)
3659 free_secret_key(sub_sk);
3660 sub_sk=NULL;
3663 /* Find a signing subkey with no backsig */
3664 if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
3666 if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
3668 if(node->pkt->pkt.public_key->backsig)
3669 tty_printf(_("signing subkey %s is already cross-certified\n"),
3670 keystr_from_pk(node->pkt->pkt.public_key));
3671 else
3672 sub_pk=node->pkt->pkt.public_key;
3674 else
3675 tty_printf(_("subkey %s does not sign and so does"
3676 " not need to be cross-certified\n"),
3677 keystr_from_pk(node->pkt->pkt.public_key));
3680 if(!sub_pk)
3681 continue;
3683 /* Find the selected selfsig on this subkey */
3684 for(node2=node->next;
3685 node2 && node2->pkt->pkttype==PKT_SIGNATURE;
3686 node2=node2->next)
3687 if(node2->pkt->pkt.signature->version>=4
3688 && node2->pkt->pkt.signature->flags.chosen_selfsig)
3690 sig_pk=node2;
3691 break;
3694 if(!sig_pk)
3695 continue;
3697 /* Find the secret subkey that matches the public subkey */
3698 for(node2=sec_keyblock;node2;node2=node2->next)
3699 if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
3700 && !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
3702 sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
3703 break;
3706 if(!sub_sk)
3708 tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
3709 keystr_from_pk(sub_pk));
3710 continue;
3713 /* Now finally find the matching selfsig on the secret subkey.
3714 We can't use chosen_selfsig here (it's not set for secret
3715 keys), so we just pick the selfsig with the right class.
3716 This is what menu_expire does as well. */
3717 for(node2=node2->next;
3718 node2 && node2->pkt->pkttype!=PKT_SECRET_SUBKEY;
3719 node2=node2->next)
3720 if(node2->pkt->pkttype==PKT_SIGNATURE
3721 && node2->pkt->pkt.signature->version>=4
3722 && node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
3723 && node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
3724 && node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
3726 sig_sk=node2;
3727 break;
3730 /* Now we can get to work. We have a main key and secret part,
3731 a signing subkey with signature and secret part possibly with
3732 signature. */
3734 passphrase=get_last_passphrase();
3735 set_next_passphrase(passphrase);
3736 xfree(passphrase);
3738 rc=make_backsig(sig_pk->pkt->pkt.signature,main_pk,sub_pk,sub_sk);
3739 if(rc==0)
3741 PKT_signature *newsig;
3742 PACKET *newpkt;
3744 passphrase=get_last_passphrase();
3745 set_next_passphrase(passphrase);
3746 xfree(passphrase);
3748 rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
3749 NULL,sub_pk,main_sk,NULL,NULL);
3750 if(rc==0)
3752 /* Put the new sig into place on the pubkey */
3753 newpkt=xmalloc_clear(sizeof(*newpkt));
3754 newpkt->pkttype=PKT_SIGNATURE;
3755 newpkt->pkt.signature=newsig;
3756 free_packet(sig_pk->pkt);
3757 xfree(sig_pk->pkt);
3758 sig_pk->pkt=newpkt;
3760 if(sig_sk)
3762 /* Put the new sig into place on the seckey */
3763 newpkt=xmalloc_clear(sizeof(*newpkt));
3764 newpkt->pkttype=PKT_SIGNATURE;
3765 newpkt->pkt.signature=copy_signature(NULL,newsig);
3766 free_packet(sig_sk->pkt);
3767 xfree(sig_sk->pkt);
3768 sig_sk->pkt=newpkt;
3771 modified=1;
3773 else
3775 log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
3776 break;
3779 else
3781 log_error("make_backsig failed: %s\n",g10_errstr(rc));
3782 break;
3786 set_next_passphrase(NULL);
3788 free_secret_key(main_sk);
3789 if(sub_sk)
3790 free_secret_key(sub_sk);
3792 return modified;
3796 static int
3797 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3799 byte buf[1];
3801 /* first clear all primary uid flags so that we are sure none are
3802 * lingering around */
3803 delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
3804 delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3806 /* if opaque is set,we want to set the primary id */
3807 if (opaque) {
3808 buf[0] = 1;
3809 build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3812 return 0;
3817 * Set the primary uid flag for the selected UID. We will also reset
3818 * all other primary uid flags. For this to work with have to update
3819 * all the signature timestamps. If we would do this with the current
3820 * time, we lose quite a lot of information, so we use a a kludge to
3821 * do this: Just increment the timestamp by one second which is
3822 * sufficient to updated a signature during import.
3824 static int
3825 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3827 PKT_secret_key *sk; /* copy of the main sk */
3828 PKT_public_key *main_pk;
3829 PKT_user_id *uid;
3830 KBNODE node;
3831 u32 keyid[2];
3832 int selected;
3833 int attribute = 0;
3834 int modified = 0;
3836 if ( count_selected_uids (pub_keyblock) != 1 ) {
3837 tty_printf(_("Please select exactly one user ID.\n"));
3838 return 0;
3841 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3842 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3844 /* Now we can actually change the self signature(s) */
3845 main_pk = NULL;
3846 uid = NULL;
3847 selected = 0;
3849 /* Is our selected uid an attribute packet? */
3850 for ( node=pub_keyblock; node; node = node->next )
3851 if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3852 attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3854 for ( node=pub_keyblock; node; node = node->next ) {
3855 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3856 break; /* ready */
3858 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3859 main_pk = node->pkt->pkt.public_key;
3860 keyid_from_pk( main_pk, keyid );
3862 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3863 uid = node->pkt->pkt.user_id;
3864 selected = node->flag & NODFLG_SELUID;
3866 else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3867 PKT_signature *sig = node->pkt->pkt.signature;
3868 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3869 && (uid && (sig->sig_class&~3) == 0x10)
3870 && attribute == (uid->attrib_data!=NULL)
3871 && sig->flags.chosen_selfsig )
3873 if(sig->version < 4) {
3874 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3876 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3877 user);
3878 xfree(user);
3880 else {
3881 /* This is a selfsignature which is to be replaced.
3882 We can just ignore v3 signatures because they are
3883 not able to carry the primary ID flag. We also
3884 ignore self-sigs on user IDs that are not of the
3885 same type that we are making primary. That is, if
3886 we are making a user ID primary, we alter user IDs.
3887 If we are making an attribute packet primary, we
3888 alter attribute packets. */
3890 /* FIXME: We must make sure that we only have one
3891 self-signature per user ID here (not counting
3892 revocations) */
3893 PKT_signature *newsig;
3894 PACKET *newpkt;
3895 const byte *p;
3896 int action;
3898 /* see whether this signature has the primary UID flag */
3899 p = parse_sig_subpkt (sig->hashed,
3900 SIGSUBPKT_PRIMARY_UID, NULL );
3901 if ( !p )
3902 p = parse_sig_subpkt (sig->unhashed,
3903 SIGSUBPKT_PRIMARY_UID, NULL );
3904 if ( p && *p ) /* yes */
3905 action = selected? 0 : -1;
3906 else /* no */
3907 action = selected? 1 : 0;
3909 if (action) {
3910 int rc = update_keysig_packet (&newsig, sig,
3911 main_pk, uid, NULL,
3913 change_primary_uid_cb,
3914 action > 0? "x":NULL );
3915 if( rc ) {
3916 log_error ("update_keysig_packet failed: %s\n",
3917 g10_errstr(rc));
3918 free_secret_key( sk );
3919 return 0;
3921 /* replace the packet */
3922 newpkt = xmalloc_clear( sizeof *newpkt );
3923 newpkt->pkttype = PKT_SIGNATURE;
3924 newpkt->pkt.signature = newsig;
3925 free_packet( node->pkt );
3926 xfree( node->pkt );
3927 node->pkt = newpkt;
3928 modified = 1;
3935 free_secret_key( sk );
3936 return modified;
3941 * Set preferences to new values for the selected user IDs
3943 static int
3944 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3946 PKT_secret_key *sk; /* copy of the main sk */
3947 PKT_public_key *main_pk;
3948 PKT_user_id *uid;
3949 KBNODE node;
3950 u32 keyid[2];
3951 int selected, select_all;
3952 int modified = 0;
3954 no_primary_warning(pub_keyblock);
3956 select_all = !count_selected_uids (pub_keyblock);
3958 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3959 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3961 /* Now we can actually change the self signature(s) */
3962 main_pk = NULL;
3963 uid = NULL;
3964 selected = 0;
3965 for ( node=pub_keyblock; node; node = node->next ) {
3966 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3967 break; /* ready */
3969 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3970 main_pk = node->pkt->pkt.public_key;
3971 keyid_from_pk( main_pk, keyid );
3973 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3974 uid = node->pkt->pkt.user_id;
3975 selected = select_all || (node->flag & NODFLG_SELUID);
3977 else if ( main_pk && uid && selected
3978 && node->pkt->pkttype == PKT_SIGNATURE ) {
3979 PKT_signature *sig = node->pkt->pkt.signature;
3980 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3981 && (uid && (sig->sig_class&~3) == 0x10)
3982 && sig->flags.chosen_selfsig ) {
3983 if( sig->version < 4 ) {
3984 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3986 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3987 user);
3988 xfree(user);
3990 else {
3991 /* This is a selfsignature which is to be replaced
3992 * We have to ignore v3 signatures because they are
3993 * not able to carry the preferences */
3994 PKT_signature *newsig;
3995 PACKET *newpkt;
3996 int rc;
3998 rc = update_keysig_packet (&newsig, sig,
3999 main_pk, uid, NULL,
4001 keygen_upd_std_prefs,
4002 NULL );
4003 if( rc ) {
4004 log_error ("update_keysig_packet failed: %s\n",
4005 g10_errstr(rc));
4006 free_secret_key( sk );
4007 return 0;
4009 /* replace the packet */
4010 newpkt = xmalloc_clear( sizeof *newpkt );
4011 newpkt->pkttype = PKT_SIGNATURE;
4012 newpkt->pkt.signature = newsig;
4013 free_packet( node->pkt );
4014 xfree( node->pkt );
4015 node->pkt = newpkt;
4016 modified = 1;
4022 free_secret_key( sk );
4023 return modified;
4027 static int
4028 menu_set_keyserver_url (const char *url,
4029 KBNODE pub_keyblock, KBNODE sec_keyblock )
4031 PKT_secret_key *sk; /* copy of the main sk */
4032 PKT_public_key *main_pk;
4033 PKT_user_id *uid;
4034 KBNODE node;
4035 u32 keyid[2];
4036 int selected, select_all;
4037 int modified = 0;
4038 char *answer,*uri;
4040 no_primary_warning(pub_keyblock);
4042 if(url)
4043 answer=xstrdup(url);
4044 else
4046 answer=cpr_get_utf8("keyedit.add_keyserver",
4047 _("Enter your preferred keyserver URL: "));
4048 if(answer[0]=='\0' || answer[0]=='\004')
4050 xfree(answer);
4051 return 0;
4055 if(ascii_strcasecmp(answer,"none")==0)
4056 uri=NULL;
4057 else
4059 struct keyserver_spec *keyserver=NULL;
4060 /* Sanity check the format */
4061 keyserver=parse_keyserver_uri(answer,1,NULL,0);
4062 xfree(answer);
4063 if(!keyserver)
4065 log_info(_("could not parse keyserver URL\n"));
4066 return 0;
4068 uri=xstrdup(keyserver->uri);
4069 free_keyserver_spec(keyserver);
4072 select_all = !count_selected_uids (pub_keyblock);
4074 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4075 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4077 /* Now we can actually change the self signature(s) */
4078 main_pk = NULL;
4079 uid = NULL;
4080 selected = 0;
4081 for ( node=pub_keyblock; node; node = node->next )
4083 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4084 break; /* ready */
4086 if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4088 main_pk = node->pkt->pkt.public_key;
4089 keyid_from_pk( main_pk, keyid );
4091 else if ( node->pkt->pkttype == PKT_USER_ID )
4093 uid = node->pkt->pkt.user_id;
4094 selected = select_all || (node->flag & NODFLG_SELUID);
4096 else if ( main_pk && uid && selected
4097 && node->pkt->pkttype == PKT_SIGNATURE )
4099 PKT_signature *sig = node->pkt->pkt.signature;
4100 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4101 && (uid && (sig->sig_class&~3) == 0x10)
4102 && sig->flags.chosen_selfsig)
4104 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4105 if( sig->version < 4 )
4106 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4107 user);
4108 else
4110 /* This is a selfsignature which is to be replaced
4111 * We have to ignore v3 signatures because they are
4112 * not able to carry the subpacket. */
4113 PKT_signature *newsig;
4114 PACKET *newpkt;
4115 int rc;
4116 const byte *p;
4117 size_t plen;
4119 p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
4120 if(p && plen)
4122 tty_printf("Current preferred keyserver for user"
4123 " ID \"%s\": ",user);
4124 tty_print_utf8_string(p,plen);
4125 tty_printf("\n");
4126 if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
4127 uri?_("Are you sure you want to replace it? (y/N) "):
4128 _("Are you sure you want to delete it? (y/N) ")))
4129 continue;
4131 else if(uri==NULL)
4133 /* There is no current keyserver URL, so there
4134 is no point in trying to un-set it. */
4135 continue;
4138 rc = update_keysig_packet (&newsig, sig,
4139 main_pk, uid, NULL,
4141 keygen_add_keyserver_url, uri );
4142 if( rc )
4144 log_error ("update_keysig_packet failed: %s\n",
4145 g10_errstr(rc));
4146 free_secret_key( sk );
4147 xfree(uri);
4148 return 0;
4150 /* replace the packet */
4151 newpkt = xmalloc_clear( sizeof *newpkt );
4152 newpkt->pkttype = PKT_SIGNATURE;
4153 newpkt->pkt.signature = newsig;
4154 free_packet( node->pkt );
4155 xfree( node->pkt );
4156 node->pkt = newpkt;
4157 modified = 1;
4160 xfree(user);
4165 xfree(uri);
4166 free_secret_key( sk );
4167 return modified;
4170 static int
4171 menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
4173 PKT_secret_key *sk; /* copy of the main sk */
4174 PKT_public_key *main_pk;
4175 PKT_user_id *uid;
4176 KBNODE node;
4177 u32 keyid[2];
4178 int selected, select_all;
4179 int modified = 0;
4180 char *answer;
4181 struct notation *notation;
4183 no_primary_warning(pub_keyblock);
4185 if(string)
4186 answer=xstrdup(string);
4187 else
4189 answer=cpr_get_utf8("keyedit.add_notation",
4190 _("Enter the notation: "));
4191 if(answer[0]=='\0' || answer[0]=='\004')
4193 xfree(answer);
4194 return 0;
4198 if(ascii_strcasecmp(answer,"none")==0
4199 || ascii_strcasecmp(answer,"-")==0)
4200 notation=NULL; /* delete them all */
4201 else
4203 notation=string_to_notation(answer,0);
4204 if(!notation)
4206 xfree(answer);
4207 return 0;
4211 xfree(answer);
4213 select_all = !count_selected_uids (pub_keyblock);
4215 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4216 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4218 /* Now we can actually change the self signature(s) */
4219 main_pk = NULL;
4220 uid = NULL;
4221 selected = 0;
4222 for ( node=pub_keyblock; node; node = node->next )
4224 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4225 break; /* ready */
4227 if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4229 main_pk = node->pkt->pkt.public_key;
4230 keyid_from_pk( main_pk, keyid );
4232 else if ( node->pkt->pkttype == PKT_USER_ID )
4234 uid = node->pkt->pkt.user_id;
4235 selected = select_all || (node->flag & NODFLG_SELUID);
4237 else if ( main_pk && uid && selected
4238 && node->pkt->pkttype == PKT_SIGNATURE )
4240 PKT_signature *sig = node->pkt->pkt.signature;
4241 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4242 && (uid && (sig->sig_class&~3) == 0x10)
4243 && sig->flags.chosen_selfsig)
4245 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4246 if( sig->version < 4 )
4247 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4248 user);
4249 else
4251 PKT_signature *newsig;
4252 PACKET *newpkt;
4253 int rc,skip=0,addonly=1;
4255 if(sig->flags.notation)
4257 tty_printf("Current notations for user ID \"%s\":\n",
4258 user);
4259 tty_print_notations(-9,sig);
4261 else
4263 tty_printf("No notations on user ID \"%s\"\n",user);
4264 if(notation==NULL)
4266 /* There are no current notations, so there
4267 is no point in trying to un-set them. */
4268 continue;
4272 if(notation)
4274 struct notation *n;
4275 int deleting=0;
4277 notation->next=sig_to_notation(sig);
4279 for(n=notation->next;n;n=n->next)
4280 if(strcmp(n->name,notation->name)==0)
4282 if(notation->value)
4284 if(strcmp(n->value,notation->value)==0)
4286 if(notation->flags.ignore)
4288 /* Value match with a delete
4289 flag. */
4290 n->flags.ignore=1;
4291 deleting=1;
4293 else
4295 /* Adding the same notation
4296 twice, so don't add it at
4297 all. */
4298 skip=1;
4299 tty_printf("Skipping notation:"
4300 " %s=%s\n",
4301 notation->name,
4302 notation->value);
4303 break;
4307 else
4309 /* No value, so it means delete. */
4310 n->flags.ignore=1;
4311 deleting=1;
4314 if(n->flags.ignore)
4316 tty_printf("Removing notation: %s=%s\n",
4317 n->name,n->value);
4318 addonly=0;
4322 if(!notation->flags.ignore && !skip)
4323 tty_printf("Adding notation: %s=%s\n",
4324 notation->name,notation->value);
4326 /* We tried to delete, but had no matches */
4327 if(notation->flags.ignore && !deleting)
4328 continue;
4330 else
4332 tty_printf("Removing all notations\n");
4333 addonly=0;
4336 if(skip
4337 || (!addonly
4338 && !cpr_get_answer_is_yes("keyedit.confirm_notation",
4339 _("Proceed? (y/N) "))))
4340 continue;
4342 rc = update_keysig_packet (&newsig, sig,
4343 main_pk, uid, NULL,
4345 keygen_add_notations, notation );
4346 if( rc )
4348 log_error ("update_keysig_packet failed: %s\n",
4349 g10_errstr(rc));
4350 free_secret_key( sk );
4351 free_notation(notation);
4352 xfree(user);
4353 return 0;
4356 /* replace the packet */
4357 newpkt = xmalloc_clear( sizeof *newpkt );
4358 newpkt->pkttype = PKT_SIGNATURE;
4359 newpkt->pkt.signature = newsig;
4360 free_packet( node->pkt );
4361 xfree( node->pkt );
4362 node->pkt = newpkt;
4363 modified = 1;
4365 if(notation)
4367 /* Snip off the notation list from the sig */
4368 free_notation(notation->next);
4369 notation->next=NULL;
4372 xfree(user);
4378 free_notation(notation);
4379 free_secret_key( sk );
4380 return modified;
4384 /****************
4385 * Select one user id or remove all selection if index is 0.
4386 * Returns: True if the selection changed;
4388 static int
4389 menu_select_uid( KBNODE keyblock, int idx )
4391 KBNODE node;
4392 int i;
4394 /* first check that the index is valid */
4395 if( idx ) {
4396 for( i=0, node = keyblock; node; node = node->next ) {
4397 if( node->pkt->pkttype == PKT_USER_ID ) {
4398 if( ++i == idx )
4399 break;
4402 if( !node ) {
4403 tty_printf(_("No user ID with index %d\n"), idx );
4404 return 0;
4407 else { /* reset all */
4408 for( i=0, node = keyblock; node; node = node->next ) {
4409 if( node->pkt->pkttype == PKT_USER_ID )
4410 node->flag &= ~NODFLG_SELUID;
4412 return 1;
4414 /* and toggle the new index */
4415 for( i=0, node = keyblock; node; node = node->next ) {
4416 if( node->pkt->pkttype == PKT_USER_ID ) {
4417 if( ++i == idx ) {
4418 if( (node->flag & NODFLG_SELUID) )
4419 node->flag &= ~NODFLG_SELUID;
4420 else
4421 node->flag |= NODFLG_SELUID;
4426 return 1;
4429 /* Search in the keyblock for a uid that matches namehash */
4430 static int
4431 menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
4433 byte hash[NAMEHASH_LEN];
4434 KBNODE node;
4435 int i;
4437 assert(strlen(namehash)==NAMEHASH_LEN*2);
4439 for(i=0;i<NAMEHASH_LEN;i++)
4440 hash[i]=hextobyte(&namehash[i*2]);
4442 for(node=keyblock->next;node;node=node->next)
4444 if(node->pkt->pkttype==PKT_USER_ID)
4446 namehash_from_uid(node->pkt->pkt.user_id);
4447 if(memcmp(node->pkt->pkt.user_id->namehash,hash,NAMEHASH_LEN)==0)
4449 if(node->flag&NODFLG_SELUID)
4450 node->flag &= ~NODFLG_SELUID;
4451 else
4452 node->flag |= NODFLG_SELUID;
4454 break;
4459 if(!node)
4461 tty_printf(_("No user ID with hash %s\n"),namehash);
4462 return 0;
4465 return 1;
4468 /****************
4469 * Select secondary keys
4470 * Returns: True if the selection changed;
4472 static int
4473 menu_select_key( KBNODE keyblock, int idx )
4475 KBNODE node;
4476 int i;
4478 /* first check that the index is valid */
4479 if( idx ) {
4480 for( i=0, node = keyblock; node; node = node->next ) {
4481 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4482 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
4483 if( ++i == idx )
4484 break;
4487 if( !node ) {
4488 tty_printf(_("No subkey with index %d\n"), idx );
4489 return 0;
4492 else { /* reset all */
4493 for( i=0, node = keyblock; node; node = node->next ) {
4494 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4495 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
4496 node->flag &= ~NODFLG_SELKEY;
4498 return 1;
4500 /* and set the new index */
4501 for( i=0, node = keyblock; node; node = node->next ) {
4502 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4503 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
4504 if( ++i == idx ) {
4505 if( (node->flag & NODFLG_SELKEY) )
4506 node->flag &= ~NODFLG_SELKEY;
4507 else
4508 node->flag |= NODFLG_SELKEY;
4513 return 1;
4517 static int
4518 count_uids_with_flag( KBNODE keyblock, unsigned flag )
4520 KBNODE node;
4521 int i=0;
4523 for( node = keyblock; node; node = node->next )
4524 if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
4525 i++;
4526 return i;
4529 static int
4530 count_keys_with_flag( KBNODE keyblock, unsigned flag )
4532 KBNODE node;
4533 int i=0;
4535 for( node = keyblock; node; node = node->next )
4536 if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4537 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4538 && (node->flag & flag) )
4539 i++;
4540 return i;
4543 static int
4544 count_uids( KBNODE keyblock )
4546 KBNODE node;
4547 int i=0;
4549 for( node = keyblock; node; node = node->next )
4550 if( node->pkt->pkttype == PKT_USER_ID )
4551 i++;
4552 return i;
4556 /****************
4557 * Returns true if there is at least one selected user id
4559 static int
4560 count_selected_uids( KBNODE keyblock )
4562 return count_uids_with_flag( keyblock, NODFLG_SELUID);
4565 static int
4566 count_selected_keys( KBNODE keyblock )
4568 return count_keys_with_flag( keyblock, NODFLG_SELKEY);
4571 /* returns how many real (i.e. not attribute) uids are unmarked */
4572 static int
4573 real_uids_left( KBNODE keyblock )
4575 KBNODE node;
4576 int real=0;
4578 for(node=keyblock;node;node=node->next)
4579 if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
4580 !node->pkt->pkt.user_id->attrib_data)
4581 real++;
4583 return real;
4587 * Ask whether the signature should be revoked. If the user commits this,
4588 * flag bit MARK_A is set on the signature and the user ID.
4590 static void
4591 ask_revoke_sig( KBNODE keyblock, KBNODE node )
4593 int doit=0;
4594 PKT_user_id *uid;
4595 PKT_signature *sig = node->pkt->pkt.signature;
4596 KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4598 if( !unode ) {
4599 log_error("Oops: no user ID for signature\n");
4600 return;
4603 uid=unode->pkt->pkt.user_id;
4605 if(opt.with_colons)
4607 if(uid->attrib_data)
4608 printf("uat:::::::::%u %lu",uid->numattribs,uid->attrib_len);
4609 else
4611 printf("uid:::::::::");
4612 print_string (stdout, uid->name, uid->len, ':');
4615 printf("\n");
4617 print_and_check_one_sig_colon(keyblock,node,NULL,NULL,NULL,NULL,1);
4619 else
4621 char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
4622 unode->pkt->pkt.user_id->len,0);
4623 tty_printf(_("user ID: \"%s\"\n"),p);
4624 xfree(p);
4626 tty_printf(_("signed by your key %s on %s%s%s\n"),
4627 keystr(sig->keyid),datestr_from_sig(sig),
4628 sig->flags.exportable?"":_(" (non-exportable)"),"");
4630 if(sig->flags.expired)
4632 tty_printf(_("This signature expired on %s.\n"),
4633 expirestr_from_sig(sig));
4634 /* Use a different question so we can have different help text */
4635 doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
4636 _("Are you sure you still want to revoke it? (y/N) "));
4638 else
4639 doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
4640 _("Create a revocation certificate for this signature? (y/N) "));
4642 if(doit) {
4643 node->flag |= NODFLG_MARK_A;
4644 unode->flag |= NODFLG_MARK_A;
4648 /****************
4649 * Display all user ids of the current public key together with signatures
4650 * done by one of our keys. Then walk over all this sigs and ask the user
4651 * whether he wants to revoke this signature.
4652 * Return: True when the keyblock has changed.
4654 static int
4655 menu_revsig( KBNODE keyblock )
4657 PKT_signature *sig;
4658 PKT_public_key *primary_pk;
4659 KBNODE node;
4660 int changed = 0;
4661 int rc, any, skip=1, all=!count_selected_uids(keyblock);
4662 struct revocation_reason_info *reason = NULL;
4664 assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
4666 /* FIXME: detect duplicates here */
4667 tty_printf(_("You have signed these user IDs on key %s:\n"),
4668 keystr_from_pk(keyblock->pkt->pkt.public_key));
4669 for( node = keyblock; node; node = node->next ) {
4670 node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
4671 if( node->pkt->pkttype == PKT_USER_ID ) {
4672 if( node->flag&NODFLG_SELUID || all ) {
4673 PKT_user_id *uid = node->pkt->pkt.user_id;
4674 /* Hmmm: Should we show only UIDs with a signature? */
4675 tty_printf(" ");
4676 tty_print_utf8_string( uid->name, uid->len );
4677 tty_printf("\n");
4678 skip=0;
4680 else
4681 skip=1;
4683 else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
4684 && ((sig = node->pkt->pkt.signature),
4685 !seckey_available(sig->keyid) ) )
4687 if( (sig->sig_class&~3) == 0x10 )
4689 tty_printf(" ");
4690 tty_printf(_("signed by your key %s on %s%s%s\n"),
4691 keystr(sig->keyid), datestr_from_sig(sig),
4692 sig->flags.exportable?"":_(" (non-exportable)"),
4693 sig->flags.revocable?"":_(" (non-revocable)"));
4694 if(sig->flags.revocable)
4695 node->flag |= NODFLG_SELSIG;
4697 else if( sig->sig_class == 0x30 )
4699 tty_printf(" ");
4700 tty_printf(_("revoked by your key %s on %s\n"),
4701 keystr(sig->keyid),datestr_from_sig(sig));
4706 tty_printf("\n");
4708 /* ask */
4709 for( node = keyblock; node; node = node->next ) {
4710 if( !(node->flag & NODFLG_SELSIG) )
4711 continue;
4712 ask_revoke_sig( keyblock, node );
4715 /* present selected */
4716 any = 0;
4717 for( node = keyblock; node; node = node->next ) {
4718 if( !(node->flag & NODFLG_MARK_A) )
4719 continue;
4720 if( !any ) {
4721 any = 1;
4722 tty_printf(_("You are about to revoke these signatures:\n"));
4724 if( node->pkt->pkttype == PKT_USER_ID ) {
4725 PKT_user_id *uid = node->pkt->pkt.user_id;
4726 tty_printf(" ");
4727 tty_print_utf8_string( uid->name, uid->len );
4728 tty_printf("\n");
4730 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
4731 sig = node->pkt->pkt.signature;
4732 tty_printf(" ");
4733 tty_printf(_("signed by your key %s on %s%s%s\n"),
4734 keystr(sig->keyid), datestr_from_sig(sig),"",
4735 sig->flags.exportable?"":_(" (non-exportable)") );
4738 if( !any )
4739 return 0; /* none selected */
4741 if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
4742 _("Really create the revocation certificates? (y/N) ")) )
4743 return 0; /* forget it */
4745 reason = ask_revocation_reason( 0, 1, 0 );
4746 if( !reason ) { /* user decided to cancel */
4747 return 0;
4750 /* now we can sign the user ids */
4751 reloop: /* (must use this, because we are modifing the list) */
4752 primary_pk = keyblock->pkt->pkt.public_key;
4753 for( node=keyblock; node; node = node->next ) {
4754 KBNODE unode;
4755 PACKET *pkt;
4756 struct sign_attrib attrib;
4757 PKT_secret_key *sk;
4759 if( !(node->flag & NODFLG_MARK_A)
4760 || node->pkt->pkttype != PKT_SIGNATURE )
4761 continue;
4762 unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4763 assert( unode ); /* we already checked this */
4765 memset( &attrib, 0, sizeof attrib );
4766 attrib.reason = reason;
4767 attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
4769 node->flag &= ~NODFLG_MARK_A;
4770 sk = xmalloc_secure_clear( sizeof *sk );
4771 if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
4772 log_info(_("no secret key\n"));
4773 continue;
4775 rc = make_keysig_packet( &sig, primary_pk,
4776 unode->pkt->pkt.user_id,
4777 NULL,
4779 0x30, 0, 0, 0, 0,
4780 sign_mk_attrib,
4781 &attrib );
4782 free_secret_key(sk);
4783 if( rc ) {
4784 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4785 release_revocation_reason_info( reason );
4786 return changed;
4788 changed = 1; /* we changed the keyblock */
4789 update_trust = 1;
4790 /* Are we revoking our own uid? */
4791 if(primary_pk->keyid[0]==sig->keyid[0] &&
4792 primary_pk->keyid[1]==sig->keyid[1])
4793 unode->pkt->pkt.user_id->is_revoked=1;
4794 pkt = xmalloc_clear( sizeof *pkt );
4795 pkt->pkttype = PKT_SIGNATURE;
4796 pkt->pkt.signature = sig;
4797 insert_kbnode( unode, new_kbnode(pkt), 0 );
4798 goto reloop;
4801 release_revocation_reason_info( reason );
4802 return changed;
4805 /* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
4806 keyblock changed. */
4807 static int
4808 menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
4810 PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
4811 PKT_secret_key *sk = copy_secret_key( NULL,
4812 sec_keyblock->pkt->pkt.secret_key );
4813 KBNODE node;
4814 int changed = 0;
4815 int rc;
4816 struct revocation_reason_info *reason = NULL;
4818 /* Note that this is correct as per the RFCs, but nevertheless
4819 somewhat meaningless in the real world. 1991 did define the 0x30
4820 sig class, but PGP 2.x did not actually implement it, so it would
4821 probably be safe to use v4 revocations everywhere. -ds */
4823 for( node = pub_keyblock; node; node = node->next )
4824 if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
4825 node->pkt->pkt.user_id->selfsigversion>3))
4827 if((reason = ask_revocation_reason( 0, 1, 4 )))
4828 break;
4829 else
4830 goto leave;
4833 reloop: /* (better this way because we are modifing the keyring) */
4834 for( node = pub_keyblock; node; node = node->next )
4835 if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
4837 PKT_user_id *uid=node->pkt->pkt.user_id;
4839 if(uid->is_revoked)
4841 char *user=utf8_to_native(uid->name,uid->len,0);
4842 log_info(_("user ID \"%s\" is already revoked\n"),user);
4843 xfree(user);
4845 else
4847 PACKET *pkt;
4848 PKT_signature *sig;
4849 struct sign_attrib attrib;
4850 u32 timestamp=make_timestamp();
4852 if(uid->created>=timestamp)
4854 /* Okay, this is a problem. The user ID selfsig was
4855 created in the future, so we need to warn the user and
4856 set our revocation timestamp one second after that so
4857 everything comes out clean. */
4859 log_info(_("WARNING: a user ID signature is dated %d"
4860 " seconds in the future\n"),uid->created-timestamp);
4862 timestamp=uid->created+1;
4865 memset( &attrib, 0, sizeof attrib );
4866 attrib.reason = reason;
4868 node->flag &= ~NODFLG_SELUID;
4870 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
4871 (reason==NULL)?3:0, timestamp, 0,
4872 sign_mk_attrib, &attrib );
4873 if( rc )
4875 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4876 goto leave;
4878 else
4880 pkt = xmalloc_clear( sizeof *pkt );
4881 pkt->pkttype = PKT_SIGNATURE;
4882 pkt->pkt.signature = sig;
4883 insert_kbnode( node, new_kbnode(pkt), 0 );
4885 /* If the trustdb has an entry for this key+uid then the
4886 trustdb needs an update. */
4887 if(!update_trust
4888 && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
4889 update_trust=1;
4891 changed = 1;
4892 node->pkt->pkt.user_id->is_revoked=1;
4894 goto reloop;
4899 if(changed)
4900 commit_kbnode( &pub_keyblock );
4902 leave:
4903 free_secret_key(sk);
4904 release_revocation_reason_info( reason );
4905 return changed;
4908 /****************
4909 * Revoke the whole key.
4911 static int
4912 menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
4914 PKT_public_key *pk=pub_keyblock->pkt->pkt.public_key;
4915 PKT_secret_key *sk;
4916 int rc,changed = 0;
4917 struct revocation_reason_info *reason;
4918 PACKET *pkt;
4919 PKT_signature *sig;
4921 if(pk->is_revoked)
4923 tty_printf(_("Key %s is already revoked.\n"),keystr_from_pk(pk));
4924 return 0;
4927 reason = ask_revocation_reason( 1, 0, 0 );
4928 /* user decided to cancel */
4929 if( !reason )
4930 return 0;
4932 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
4933 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk,
4934 0x20, 0, opt.force_v4_certs?4:0, 0, 0,
4935 revocation_reason_build_cb, reason );
4936 free_secret_key(sk);
4937 if( rc )
4939 log_error(_("signing failed: %s\n"), g10_errstr(rc));
4940 goto scram;
4943 changed = 1; /* we changed the keyblock */
4945 pkt = xmalloc_clear( sizeof *pkt );
4946 pkt->pkttype = PKT_SIGNATURE;
4947 pkt->pkt.signature = sig;
4948 insert_kbnode( pub_keyblock, new_kbnode(pkt), 0 );
4949 commit_kbnode( &pub_keyblock );
4951 update_trust=1;
4953 scram:
4954 release_revocation_reason_info( reason );
4955 return changed;
4958 static int
4959 menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
4961 PKT_public_key *mainpk;
4962 KBNODE node;
4963 int changed = 0;
4964 int rc;
4965 struct revocation_reason_info *reason = NULL;
4967 reason = ask_revocation_reason( 1, 0, 0 );
4968 if( !reason ) { /* user decided to cancel */
4969 return 0;
4972 reloop: /* (better this way because we are modifing the keyring) */
4973 mainpk = pub_keyblock->pkt->pkt.public_key;
4974 for( node = pub_keyblock; node; node = node->next ) {
4975 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4976 && (node->flag & NODFLG_SELKEY) ) {
4977 PACKET *pkt;
4978 PKT_signature *sig;
4979 PKT_secret_key *sk;
4980 PKT_public_key *subpk = node->pkt->pkt.public_key;
4981 struct sign_attrib attrib;
4983 if(subpk->is_revoked)
4985 tty_printf(_("Subkey %s is already revoked.\n"),
4986 keystr_from_pk(subpk));
4987 continue;
4990 memset( &attrib, 0, sizeof attrib );
4991 attrib.reason = reason;
4993 node->flag &= ~NODFLG_SELKEY;
4994 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
4995 rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
4996 0x28, 0, 0, 0, 0,
4997 sign_mk_attrib, &attrib );
4998 free_secret_key(sk);
4999 if( rc ) {
5000 log_error(_("signing failed: %s\n"), g10_errstr(rc));
5001 release_revocation_reason_info( reason );
5002 return changed;
5004 changed = 1; /* we changed the keyblock */
5006 pkt = xmalloc_clear( sizeof *pkt );
5007 pkt->pkttype = PKT_SIGNATURE;
5008 pkt->pkt.signature = sig;
5009 insert_kbnode( node, new_kbnode(pkt), 0 );
5010 goto reloop;
5013 commit_kbnode( &pub_keyblock );
5014 /*commit_kbnode( &sec_keyblock );*/
5016 /* No need to set update_trust here since signing keys no longer
5017 are used to certify other keys, so there is no change in trust
5018 when revoking/removing them */
5020 release_revocation_reason_info( reason );
5021 return changed;
5024 /* Note that update_ownertrust is going to mark the trustdb dirty when
5025 enabling or disabling a key. This is arguably sub-optimal as
5026 disabled keys are still counted in the web of trust, but perhaps
5027 not worth adding extra complexity to change. -ds */
5028 static int
5029 enable_disable_key( KBNODE keyblock, int disable )
5031 PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
5032 ->pkt->pkt.public_key;
5033 unsigned int trust, newtrust;
5035 trust = newtrust = get_ownertrust (pk);
5036 newtrust &= ~TRUST_FLAG_DISABLED;
5037 if( disable )
5038 newtrust |= TRUST_FLAG_DISABLED;
5039 if( trust == newtrust )
5040 return 0; /* already in that state */
5041 update_ownertrust(pk, newtrust );
5042 return 0;
5046 static void
5047 menu_showphoto( KBNODE keyblock )
5049 KBNODE node;
5050 int select_all = !count_selected_uids(keyblock);
5051 int count=0;
5052 PKT_public_key *pk=NULL;
5054 /* Look for the public key first. We have to be really, really,
5055 explicit as to which photo this is, and what key it is a UID on
5056 since people may want to sign it. */
5058 for( node = keyblock; node; node = node->next )
5060 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
5061 pk = node->pkt->pkt.public_key;
5062 else if( node->pkt->pkttype == PKT_USER_ID )
5064 PKT_user_id *uid = node->pkt->pkt.user_id;
5065 count++;
5067 if((select_all || (node->flag & NODFLG_SELUID)) &&
5068 uid->attribs!=NULL)
5070 int i;
5072 for(i=0;i<uid->numattribs;i++)
5074 byte type;
5075 u32 size;
5077 if(uid->attribs[i].type==ATTRIB_IMAGE &&
5078 parse_image_header(&uid->attribs[i],&type,&size))
5080 tty_printf(_("Displaying %s photo ID of size %ld for "
5081 "key %s (uid %d)\n"),
5082 image_type_to_string(type,1),
5083 (ulong)size,keystr_from_pk(pk),count);
5084 show_photos(&uid->attribs[i],1,pk,NULL);