2004-02-26 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / keyedit.c
blob4da174e3cf7441d7b846b5f9658d129b33ab1e96
1 /* keyedit.c - keyedit stuff
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <ctype.h>
30 #include "gpg.h"
31 #include "options.h"
32 #include "packet.h"
33 #include "errors.h"
34 #include "iobuf.h"
35 #include "keydb.h"
36 #include "memory.h"
37 #include "photoid.h"
38 #include "util.h"
39 #include "main.h"
40 #include "trustdb.h"
41 #include "filter.h"
42 #include "ttyio.h"
43 #include "status.h"
44 #include "i18n.h"
46 static void show_prefs( PKT_user_id *uid, int verbose );
47 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
48 int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
49 static void show_key_and_fingerprint( KBNODE keyblock );
50 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
51 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
52 static int menu_delsig( KBNODE pub_keyblock );
53 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
54 static int menu_addrevoker( KBNODE pub_keyblock,
55 KBNODE sec_keyblock, int sensitive );
56 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
57 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
58 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
59 static int menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock );
60 static int menu_select_uid( KBNODE keyblock, int idx );
61 static int menu_select_key( KBNODE keyblock, int idx );
62 static int count_uids( KBNODE keyblock );
63 static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
64 static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
65 static int count_selected_uids( KBNODE keyblock );
66 static int real_uids_left( KBNODE keyblock );
67 static int count_selected_keys( KBNODE keyblock );
68 static int menu_revsig( KBNODE keyblock );
69 static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
70 static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
71 static int enable_disable_key( KBNODE keyblock, int disable );
72 static void menu_showphoto( KBNODE keyblock );
74 static int update_trust=0;
76 #define CONTROL_D ('D' - 'A' + 1)
78 #define NODFLG_BADSIG (1<<0) /* bad signature */
79 #define NODFLG_NOKEY (1<<1) /* no public key */
80 #define NODFLG_SIGERR (1<<2) /* other sig error */
82 #define NODFLG_MARK_A (1<<4) /* temporary mark */
83 #define NODFLG_DELSIG (1<<5) /* to be deleted */
85 #define NODFLG_SELUID (1<<8) /* indicate the selected userid */
86 #define NODFLG_SELKEY (1<<9) /* indicate the selected key */
87 #define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
89 struct sign_attrib {
90 int non_exportable,non_revocable;
91 struct revocation_reason_info *reason;
92 byte trust_depth,trust_value;
93 char *trust_regexp;
96 /****************
97 * Print information about a signature, check it and return true
98 * if the signature is okay. NODE must be a signature packet.
100 static int
101 print_and_check_one_sig( KBNODE keyblock, KBNODE node,
102 int *inv_sigs, int *no_key, int *oth_err,
103 int *is_selfsig, int print_without_key )
105 PKT_signature *sig = node->pkt->pkt.signature;
106 int rc, sigrc;
107 int is_rev = sig->sig_class == 0x30;
109 /* TODO: Make sure a cached sig record here still has the pk that
110 issued it. See also keylist.c:list_keyblock_print */
112 rc = check_key_signature (keyblock, node, is_selfsig);
113 switch ( gpg_err_code (rc) ) {
114 case 0:
115 node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
116 sigrc = '!';
117 break;
118 case GPG_ERR_BAD_SIGNATURE:
119 node->flag = NODFLG_BADSIG;
120 sigrc = '-';
121 if( inv_sigs )
122 ++*inv_sigs;
123 break;
124 case GPG_ERR_NO_PUBKEY:
125 case GPG_ERR_UNUSABLE_PUBKEY:
126 node->flag = NODFLG_NOKEY;
127 sigrc = '?';
128 if( no_key )
129 ++*no_key;
130 break;
131 default:
132 node->flag = NODFLG_SIGERR;
133 sigrc = '%';
134 if( oth_err )
135 ++*oth_err;
136 break;
138 if( sigrc != '?' || print_without_key ) {
139 tty_printf("%s%c%c %c%c%c%c%c%c ",
140 is_rev? "rev":"sig",sigrc,
141 (sig->sig_class-0x10>0 &&
142 sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
143 sig->flags.exportable?' ':'L',
144 sig->flags.revocable?' ':'R',
145 sig->flags.policy_url?'P':' ',
146 sig->flags.notation?'N':' ',
147 sig->flags.expired?'X':' ',
148 (sig->trust_depth>9)?'T':
149 (sig->trust_depth>0)?'0'+sig->trust_depth:' ');
150 if(opt.list_options&LIST_SHOW_LONG_KEYID)
151 tty_printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]);
152 else
153 tty_printf("%08lX",(ulong)sig->keyid[1]);
154 tty_printf(" %s", datestr_from_sig(sig));
155 if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
156 tty_printf(" %s",expirestr_from_sig(sig));
157 tty_printf(" ");
158 if( sigrc == '%' )
159 tty_printf("[%s] ", gpg_strerror (rc) );
160 else if( sigrc == '?' )
162 else if( *is_selfsig ) {
163 tty_printf( is_rev? _("[revocation]")
164 : _("[self-signature]") );
166 else {
167 size_t n;
168 char *p = get_user_id( sig->keyid, &n );
169 tty_print_utf8_string2( p, n, 40 );
170 xfree (p);
172 tty_printf("\n");
174 if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY))
175 show_policy_url(sig,3,0);
177 if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
178 show_notation(sig,3,0);
180 if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
181 show_keyserver_url(sig,3,0);
184 return (sigrc == '!');
189 /****************
190 * Check the keysigs and set the flags to indicate errors.
191 * Returns true if error found.
193 static int
194 check_all_keysigs( KBNODE keyblock, int only_selected )
196 KBNODE kbctx;
197 KBNODE node;
198 int inv_sigs = 0;
199 int no_key = 0;
200 int oth_err = 0;
201 int has_selfsig = 0;
202 int mis_selfsig = 0;
203 int selected = !only_selected;
204 int anyuid = 0;
206 for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
207 if( node->pkt->pkttype == PKT_USER_ID ) {
208 PKT_user_id *uid = node->pkt->pkt.user_id;
210 if( only_selected )
211 selected = (node->flag & NODFLG_SELUID);
212 if( selected ) {
213 tty_printf("uid ");
214 tty_print_utf8_string( uid->name, uid->len );
215 tty_printf("\n");
216 if( anyuid && !has_selfsig )
217 mis_selfsig++;
218 has_selfsig = 0;
219 anyuid = 1;
222 else if( selected && node->pkt->pkttype == PKT_SIGNATURE
223 && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
224 || node->pkt->pkt.signature->sig_class == 0x30 ) ) {
225 int selfsig;
227 if( print_and_check_one_sig( keyblock, node, &inv_sigs,
228 &no_key, &oth_err, &selfsig, 0 ) ) {
229 if( selfsig )
230 has_selfsig = 1;
232 /* Hmmm: should we update the trustdb here? */
235 if( !has_selfsig )
236 mis_selfsig++;
237 if( inv_sigs == 1 )
238 tty_printf(_("1 bad signature\n") );
239 else if( inv_sigs )
240 tty_printf(_("%d bad signatures\n"), inv_sigs );
241 if( no_key == 1 )
242 tty_printf(_("1 signature not checked due to a missing key\n") );
243 else if( no_key )
244 tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
245 if( oth_err == 1 )
246 tty_printf(_("1 signature not checked due to an error\n") );
247 else if( oth_err )
248 tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
249 if( mis_selfsig == 1 )
250 tty_printf(_("1 user ID without valid self-signature detected\n"));
251 else if( mis_selfsig )
252 tty_printf(_("%d user IDs without valid self-signatures detected\n"),
253 mis_selfsig);
255 return inv_sigs || no_key || oth_err || mis_selfsig;
261 static int
262 sign_mk_attrib( PKT_signature *sig, void *opaque )
264 struct sign_attrib *attrib = opaque;
265 byte buf[8];
267 if( attrib->non_exportable ) {
268 buf[0] = 0; /* not exportable */
269 build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
272 if( attrib->non_revocable ) {
273 buf[0] = 0; /* not revocable */
274 build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
277 if( attrib->reason )
278 revocation_reason_build_cb( sig, attrib->reason );
280 if(attrib->trust_depth)
282 /* Not critical. If someone doesn't understand trust sigs,
283 this can still be a valid regular signature. */
284 buf[0] = attrib->trust_depth;
285 buf[1] = attrib->trust_value;
286 build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
288 /* Critical. If someone doesn't understands regexps, this
289 whole sig should be invalid. Note the +1 for the length -
290 regexps are null terminated. */
291 if(attrib->trust_regexp)
292 build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
293 attrib->trust_regexp,
294 strlen(attrib->trust_regexp)+1);
297 return 0;
300 static void
301 trustsig_prompt(byte *trust_value, byte *trust_depth, char **regexp)
303 char *p;
305 *trust_value=0;
306 *trust_depth=0;
307 *regexp=NULL;
309 tty_printf("\n");
310 /* Same string as pkclist.c:do_edit_ownertrust */
311 tty_printf(_(
312 "Please decide how far you trust this user to correctly\n"
313 "verify other users' keys (by looking at passports,\n"
314 "checking fingerprints from different sources...)?\n\n"));
315 tty_printf (_(" (%d) I trust marginally\n"), 1);
316 tty_printf (_(" (%d) I trust fully\n"), 2);
317 tty_printf("\n");
319 while(*trust_value==0)
321 p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
322 trim_spaces(p);
323 cpr_kill_prompt();
324 /* 60 and 120 are as per RFC2440 */
325 if(p[0]=='1' && !p[1])
326 *trust_value=60;
327 else if(p[0]=='2' && !p[1])
328 *trust_value=120;
329 xfree (p);
332 tty_printf("\n");
334 tty_printf(_(
335 "Please enter the depth of this trust signature.\n"
336 "A depth greater than 1 allows the key you are signing to make\n"
337 "trust signatures on your behalf.\n"));
338 tty_printf("\n");
340 while(*trust_depth==0)
342 p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
343 trim_spaces(p);
344 cpr_kill_prompt();
345 *trust_depth=atoi(p);
346 xfree (p);
347 if(*trust_depth < 1 )
348 *trust_depth=0;
351 tty_printf("\n");
353 tty_printf(_("Please enter a domain to restrict this signature, "
354 "or enter for none.\n"));
356 tty_printf("\n");
358 p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
359 trim_spaces(p);
360 cpr_kill_prompt();
362 if(strlen(p)>0)
364 char *q=p;
365 int regexplen=100,ind;
367 *regexp=xmalloc (regexplen);
369 /* Now mangle the domain the user entered into a regexp. To do
370 this, \-escape everything that isn't alphanumeric, and attach
371 "<[^>]+[@.]" to the front, and ">$" to the end. */
373 strcpy(*regexp,"<[^>]+[@.]");
374 ind=strlen(*regexp);
376 while(*q)
378 if(!((*q>='A' && *q<='Z')
379 || (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
380 (*regexp)[ind++]='\\';
382 (*regexp)[ind++]=*q;
384 if((regexplen-ind)<3)
386 regexplen+=100;
387 *regexp=xrealloc(*regexp,regexplen);
390 q++;
393 (*regexp)[ind]='\0';
394 strcat(*regexp,">$");
397 xfree (p);
398 tty_printf("\n");
401 /****************
402 * Loop over all locusr and and sign the uids after asking.
403 * If no user id is marked, all user ids will be signed;
404 * if some user_ids are marked those will be signed.
406 static int
407 sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
408 int local, int nonrevocable, int trust )
410 int rc = 0;
411 SK_LIST sk_list = NULL;
412 SK_LIST sk_rover = NULL;
413 PKT_secret_key *sk = NULL;
414 KBNODE node, uidnode;
415 PKT_public_key *primary_pk=NULL;
416 int select_all = !count_selected_uids(keyblock);
417 int all_v3=1;
419 /* Are there any non-v3 sigs on this key already? */
420 if(PGP2)
421 for(node=keyblock;node;node=node->next)
422 if(node->pkt->pkttype==PKT_SIGNATURE &&
423 node->pkt->pkt.signature->version>3)
425 all_v3=0;
426 break;
429 /* build a list of all signators.
431 * We use the CERT flag to request the primary which must always
432 * be one which is capable of signing keys. I can't see a reason
433 * why to sign keys using a subkey. Implementation of USAGE_CERT
434 * is just a hack in getkey.c and does not mean that a subkey
435 * marked as certification capable will be used */
436 rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT);
437 if( rc )
438 goto leave;
440 /* loop over all signators */
441 for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
442 u32 sk_keyid[2],pk_keyid[2];
443 size_t n;
444 char *p,*trust_regexp=NULL;
445 int force_v4=0,class=0,selfsig=0;
446 u32 duration=0,timestamp=0;
447 byte trust_depth=0,trust_value=0;
449 if(local || nonrevocable || trust ||
450 opt.cert_policy_url || opt.cert_notation_data)
451 force_v4=1;
453 /* we have to use a copy of the sk, because make_keysig_packet
454 * may remove the protection from sk and if we did other
455 * changes to the secret key, we would save the unprotected
456 * version */
457 if( sk )
458 free_secret_key(sk);
459 sk = copy_secret_key( NULL, sk_rover->sk );
460 keyid_from_sk( sk, sk_keyid );
461 /* set mark A for all selected user ids */
462 for( node=keyblock; node; node = node->next ) {
463 if( select_all || (node->flag & NODFLG_SELUID) )
464 node->flag |= NODFLG_MARK_A;
465 else
466 node->flag &= ~NODFLG_MARK_A;
468 /* reset mark for uids which are already signed */
469 uidnode = NULL;
470 for( node=keyblock; node; node = node->next ) {
471 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
472 primary_pk=node->pkt->pkt.public_key;
473 keyid_from_pk( primary_pk, pk_keyid );
475 /* Is this a self-sig? */
476 if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
478 selfsig=1;
479 /* Do not force a v4 sig here, otherwise it would
480 be difficult to remake a v3 selfsig. If this
481 is a v3->v4 promotion case, then we set
482 force_v4 later anyway. */
483 force_v4=0;
486 else if( node->pkt->pkttype == PKT_USER_ID ) {
487 uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
488 if(uidnode)
490 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
491 uidnode->pkt->pkt.user_id->len,
494 if(uidnode->pkt->pkt.user_id->is_revoked)
496 tty_printf(_("User ID \"%s\" is revoked."),user);
498 if(opt.expert)
500 tty_printf("\n");
501 /* No, so remove the mark and continue */
502 if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
503 _("Are you sure you "
504 "still want to sign "
505 "it? (y/N) ")))
506 uidnode->flag &= ~NODFLG_MARK_A;
508 else
510 uidnode->flag &= ~NODFLG_MARK_A;
511 tty_printf(_(" Unable to sign.\n"));
514 else if(uidnode->pkt->pkt.user_id->is_expired)
516 tty_printf(_("User ID \"%s\" is expired."),user);
518 if(opt.expert)
520 tty_printf("\n");
521 /* No, so remove the mark and continue */
522 if(!cpr_get_answer_is_yes("sign_uid.expire_okay",
523 _("Are you sure you "
524 "still want to sign "
525 "it? (y/N) ")))
526 uidnode->flag &= ~NODFLG_MARK_A;
528 else
530 uidnode->flag &= ~NODFLG_MARK_A;
531 tty_printf(_(" Unable to sign.\n"));
534 else if(!uidnode->pkt->pkt.user_id->created && !selfsig)
536 tty_printf(_("User ID \"%s\" is not self-signed."),
537 user);
539 if(opt.expert)
541 tty_printf("\n");
542 /* No, so remove the mark and continue */
543 if(!cpr_get_answer_is_yes("sign_uid.nosig_okay",
544 _("Are you sure you "
545 "still want to sign "
546 "it? (y/N) ")))
547 uidnode->flag &= ~NODFLG_MARK_A;
549 else
551 uidnode->flag &= ~NODFLG_MARK_A;
552 tty_printf(_(" Unable to sign.\n"));
555 xfree (user);
558 else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
559 && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
560 if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
561 && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
562 char buf[50];
563 char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
564 uidnode->pkt->pkt.user_id->len,
567 /* It's a v3 self-sig. Make it into a v4 self-sig? */
568 if(node->pkt->pkt.signature->version<4 && selfsig)
570 tty_printf(_("The self-signature on \"%s\"\n"
571 "is a PGP 2.x-style signature.\n"),user);
573 /* Note that the regular PGP2 warning below
574 still applies if there are no v4 sigs on
575 this key at all. */
577 if(opt.expert)
578 if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
579 _("Do you want to promote "
580 "it to an OpenPGP self-"
581 "signature? (y/N) ")))
583 force_v4=1;
584 node->flag|=NODFLG_DELSIG;
585 xfree (user);
586 continue;
590 /* Is the current signature expired? */
591 if(node->pkt->pkt.signature->flags.expired)
593 tty_printf(_("Your current signature on \"%s\"\n"
594 "has expired.\n"),user);
596 if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
597 _("Do you want to issue a "
598 "new signature to replace "
599 "the expired one? (y/N) ")))
601 /* Mark these for later deletion. We
602 don't want to delete them here, just in
603 case the replacement signature doesn't
604 happen for some reason. We only delete
605 these after the replacement is already
606 in place. */
608 node->flag|=NODFLG_DELSIG;
609 xfree (user);
610 continue;
614 if(!node->pkt->pkt.signature->flags.exportable && !local)
616 /* It's a local sig, and we want to make a
617 exportable sig. */
618 tty_printf(_("Your current signature on \"%s\"\n"
619 "is a local signature.\n"),user);
621 if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
622 _("Do you want to promote "
623 "it to a full exportable "
624 "signature? (y/N) ")))
626 /* Mark these for later deletion. We
627 don't want to delete them here, just in
628 case the replacement signature doesn't
629 happen for some reason. We only delete
630 these after the replacement is already
631 in place. */
633 node->flag|=NODFLG_DELSIG;
634 xfree (user);
635 continue;
639 /* Fixme: see whether there is a revocation in which
640 * case we should allow to sign it again. */
641 if (!node->pkt->pkt.signature->flags.exportable && local)
642 tty_printf(_(
643 "\"%s\" was already locally signed by key %08lX\n"),
644 user,(ulong)sk_keyid[1] );
645 else
646 tty_printf(_(
647 "\"%s\" was already signed by key %08lX\n"),
648 user,(ulong)sk_keyid[1] );
650 if(opt.expert
651 && cpr_get_answer_is_yes("sign_uid.dupe_okay",
652 _("Do you want to sign it "
653 "again anyway? (y/N) ")))
655 /* Don't delete the old sig here since this is
656 an --expert thing. */
657 xfree (user);
658 continue;
661 sprintf (buf, "%08lX%08lX",
662 (ulong)sk->keyid[0], (ulong)sk->keyid[1] );
663 write_status_text (STATUS_ALREADY_SIGNED, buf);
664 uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
666 xfree (user);
670 /* check whether any uids are left for signing */
671 if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) ) {
672 tty_printf(_("Nothing to sign with key %08lX\n"),
673 (ulong)sk_keyid[1] );
674 continue;
676 /* Ask whether we really should sign these user id(s) */
677 tty_printf("\n");
678 show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
679 tty_printf("\n");
681 if(primary_pk->expiredate && !selfsig)
683 u32 now=make_timestamp();
685 if(primary_pk->expiredate<=now)
687 tty_printf(_("This key has expired!"));
689 if(opt.expert)
691 tty_printf(" ");
692 if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
693 _("Are you sure you still "
694 "want to sign it? (y/N) ")))
695 continue;
697 else
699 tty_printf(_(" Unable to sign.\n"));
700 continue;
703 else
705 char *answer;
707 tty_printf(_("This key is due to expire on %s.\n"),
708 expirestr_from_pk(primary_pk));
710 answer=cpr_get("sign_uid.expire",
711 _("Do you want your signature to "
712 "expire at the same time? (Y/n) "));
713 if(answer_is_yes_no_default(answer,1))
715 /* This fixes the signature timestamp we're going
716 to make as now. This is so the expiration date
717 is exactly correct, and not a few seconds off
718 (due to the time it takes to answer the
719 questions, enter the passphrase, etc). */
720 timestamp=now;
721 duration=primary_pk->expiredate-now;
722 force_v4=1;
725 cpr_kill_prompt();
726 xfree (answer);
730 /* Only ask for duration if we haven't already set it to match
731 the expiration of the pk */
732 if(opt.ask_cert_expire && !duration && !selfsig)
733 duration=ask_expire_interval(1);
735 if(duration)
736 force_v4=1;
738 /* Is --pgp2 on, it's a v3 key, all the sigs on the key are
739 currently v3 and we're about to sign it with a v4 sig? If
740 so, danger! */
741 if(PGP2 && all_v3 &&
742 (sk->version>3 || force_v4) && primary_pk->version<=3)
744 tty_printf(_("You may not make an OpenPGP signature on a "
745 "PGP 2.x key while in --pgp2 mode.\n"));
746 tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
748 if(opt.expert)
750 if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
751 _("Are you sure you still "
752 "want to sign it? (y/N) ")))
753 continue;
755 all_v3=0;
757 else
758 continue;
761 if(selfsig)
763 else
765 if(opt.batch)
766 class=0x10+opt.def_cert_check_level;
767 else
769 char *answer;
771 tty_printf(_("How carefully have you verified the key you are "
772 "about to sign actually belongs\nto the person "
773 "named above? If you don't know what to "
774 "answer, enter \"0\".\n"));
775 tty_printf("\n");
776 tty_printf(_(" (0) I will not answer.%s\n"),
777 opt.def_cert_check_level==0?" (default)":"");
778 tty_printf(_(" (1) I have not checked at all.%s\n"),
779 opt.def_cert_check_level==1?" (default)":"");
780 tty_printf(_(" (2) I have done casual checking.%s\n"),
781 opt.def_cert_check_level==2?" (default)":"");
782 tty_printf(_(" (3) I have done very careful checking.%s\n"),
783 opt.def_cert_check_level==3?" (default)":"");
784 tty_printf("\n");
786 while(class==0)
788 answer = cpr_get("sign_uid.class",_("Your selection? "
789 "(enter '?' for more information): "));
791 if(answer[0]=='\0')
792 class=0x10+opt.def_cert_check_level; /* Default */
793 else if(ascii_strcasecmp(answer,"0")==0)
794 class=0x10; /* Generic */
795 else if(ascii_strcasecmp(answer,"1")==0)
796 class=0x11; /* Persona */
797 else if(ascii_strcasecmp(answer,"2")==0)
798 class=0x12; /* Casual */
799 else if(ascii_strcasecmp(answer,"3")==0)
800 class=0x13; /* Positive */
801 else
802 tty_printf(_("Invalid selection.\n"));
804 xfree (answer);
808 if(trust)
809 trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
812 tty_printf(_("Are you really sure that you want to sign this key\n"
813 "with your key: \""));
814 p = get_user_id( sk_keyid, &n );
815 tty_print_utf8_string( p, n );
816 xfree (p); p = NULL;
817 tty_printf("\" (%08lX)\n",(ulong)sk_keyid[1]);
819 if(selfsig)
821 tty_printf(_("\nThis will be a self-signature.\n"));
823 if( local )
824 tty_printf(
825 _("\nWARNING: the signature will not be marked "
826 "as non-exportable.\n"));
828 if( nonrevocable )
829 tty_printf(
830 _("\nWARNING: the signature will not be marked "
831 "as non-revocable.\n"));
833 else
835 if( local )
836 tty_printf(
837 _("\nThe signature will be marked as non-exportable.\n"));
839 if( nonrevocable )
840 tty_printf(
841 _("\nThe signature will be marked as non-revocable.\n"));
843 switch(class)
845 case 0x11:
846 tty_printf(_("\nI have not checked this key at all.\n"));
847 break;
849 case 0x12:
850 tty_printf(_("\nI have checked this key casually.\n"));
851 break;
853 case 0x13:
854 tty_printf(_("\nI have checked this key very carefully.\n"));
855 break;
859 tty_printf("\n");
861 if( opt.batch && opt.answer_yes )
863 else if( !cpr_get_answer_is_yes("sign_uid.okay", _("Really sign? ")) )
864 continue;
866 /* now we can sign the user ids */
867 reloop: /* (must use this, because we are modifing the list) */
868 primary_pk = NULL;
869 for( node=keyblock; node; node = node->next ) {
870 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
871 primary_pk = node->pkt->pkt.public_key;
872 else if( node->pkt->pkttype == PKT_USER_ID
873 && (node->flag & NODFLG_MARK_A) ) {
874 PACKET *pkt;
875 PKT_signature *sig;
876 struct sign_attrib attrib;
878 assert( primary_pk );
879 memset( &attrib, 0, sizeof attrib );
880 attrib.non_exportable = local;
881 attrib.non_revocable = nonrevocable;
882 attrib.trust_depth = trust_depth;
883 attrib.trust_value = trust_value;
884 attrib.trust_regexp = trust_regexp;
885 node->flag &= ~NODFLG_MARK_A;
887 /* we force creation of a v4 signature for local
888 * signatures, otherwise we would not generate the
889 * subpacket with v3 keys and the signature becomes
890 * exportable */
892 if(selfsig)
893 rc = make_keysig_packet( &sig, primary_pk,
894 node->pkt->pkt.user_id,
895 NULL,
897 0x13, 0, force_v4?4:0, 0, 0,
898 keygen_add_std_prefs, primary_pk);
899 else
900 rc = make_keysig_packet( &sig, primary_pk,
901 node->pkt->pkt.user_id,
902 NULL,
904 class, 0, force_v4?4:0,
905 timestamp, duration,
906 sign_mk_attrib, &attrib );
907 if( rc ) {
908 log_error(_("signing failed: %s\n"), gpg_strerror (rc));
909 goto leave;
912 *ret_modified = 1; /* we changed the keyblock */
913 update_trust = 1;
915 pkt = xcalloc (1, sizeof *pkt );
916 pkt->pkttype = PKT_SIGNATURE;
917 pkt->pkt.signature = sig;
918 insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
919 goto reloop;
923 /* Delete any sigs that got promoted */
924 for( node=keyblock; node; node = node->next )
925 if( node->flag & NODFLG_DELSIG)
926 delete_kbnode(node);
927 } /* end loop over signators */
929 leave:
930 release_sk_list( sk_list );
931 if( sk )
932 free_secret_key(sk);
933 return rc;
938 /****************
939 * Change the passphrase of the primary and all secondary keys.
940 * We use only one passphrase for all keys.
942 static int
943 change_passphrase( KBNODE keyblock )
945 int rc = 0;
946 int changed=0;
947 KBNODE node;
948 PKT_secret_key *sk;
949 char *passphrase = NULL;
950 int no_primary_secrets = 0;
952 node = find_kbnode( keyblock, PKT_SECRET_KEY );
953 if( !node ) {
954 log_error("Oops; secret key not found anymore!\n");
955 goto leave;
957 sk = node->pkt->pkt.secret_key;
959 switch( is_secret_key_protected( sk ) ) {
960 case -1:
961 rc = GPG_ERR_PUBKEY_ALGO;
962 break;
963 case 0:
964 tty_printf(_("This key is not protected.\n"));
965 break;
966 default:
967 if( sk->protect.s2k.mode == 1001 ) {
968 tty_printf(_("Secret parts of primary key are not available.\n"));
969 no_primary_secrets = 1;
971 else if( sk->protect.s2k.mode == 1002 ) {
972 tty_printf(_("Secret key is actually stored on a card.\n"));
973 goto leave;
975 else {
976 tty_printf(_("Key is protected.\n"));
977 rc = check_secret_key( sk, 0 );
978 if( !rc )
979 passphrase = get_last_passphrase();
981 break;
984 /* unprotect all subkeys (use the supplied passphrase or ask)*/
985 for(node=keyblock; !rc && node; node = node->next ) {
986 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
987 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
988 set_next_passphrase( passphrase );
989 rc = check_secret_key( subsk, 0 );
990 if( !rc && !passphrase )
991 passphrase = get_last_passphrase();
995 if( rc )
996 tty_printf(_("Can't edit this key: %s\n"), gpg_strerror (rc));
997 else {
998 DEK *dek = NULL;
999 STRING2KEY *s2k = xmalloc_secure ( sizeof *s2k );
1000 const char *errtext = NULL;
1002 tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
1004 set_next_passphrase( NULL );
1005 for(;;) {
1006 s2k->mode = opt.s2k_mode;
1007 s2k->hash_algo = opt.s2k_digest_algo;
1008 dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
1009 s2k, 2, errtext, NULL);
1010 if( !dek ) {
1011 errtext = N_("passphrase not correctly repeated; try again");
1012 tty_printf ("%s.\n", _(errtext));
1014 else if( !dek->keylen ) {
1015 rc = 0;
1016 tty_printf(_( "You don't want a passphrase -"
1017 " this is probably a *bad* idea!\n\n"));
1018 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
1019 _("Do you really want to do this? ")))
1021 changed++;
1022 break;
1025 else { /* okay */
1026 rc = 0;
1027 if( !no_primary_secrets ) {
1028 sk->protect.algo = dek->algo;
1029 sk->protect.s2k = *s2k;
1030 rc = protect_secret_key( sk, dek );
1032 for(node=keyblock; !rc && node; node = node->next ) {
1033 if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1034 PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1035 subsk->protect.algo = dek->algo;
1036 subsk->protect.s2k = *s2k;
1037 rc = protect_secret_key( subsk, dek );
1040 if( rc )
1041 log_error("protect_secret_key failed: %s\n", gpg_strerror (rc) );
1042 else
1043 changed++;
1044 break;
1047 xfree (s2k);
1048 xfree (dek);
1051 leave:
1052 xfree ( passphrase );
1053 set_next_passphrase( NULL );
1054 return changed && !rc;
1058 /****************
1059 * There are some keys out (due to a bug in gnupg), where the sequence
1060 * of the packets is wrong. This function fixes that.
1061 * Returns: true if the keyblock has been fixed.
1063 * Note: This function does not work if there is more than one user ID.
1065 static int
1066 fix_keyblock( KBNODE keyblock )
1068 KBNODE node, last, subkey;
1069 int fixed=0;
1071 /* locate key signatures of class 0x10..0x13 behind sub key packets */
1072 for( subkey=last=NULL, node = keyblock; node;
1073 last=node, node = node->next ) {
1074 switch( node->pkt->pkttype ) {
1075 case PKT_PUBLIC_SUBKEY:
1076 case PKT_SECRET_SUBKEY:
1077 if( !subkey )
1078 subkey = last; /* actually it is the one before the subkey */
1079 break;
1080 case PKT_SIGNATURE:
1081 if( subkey ) {
1082 PKT_signature *sig = node->pkt->pkt.signature;
1083 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1084 log_info(_(
1085 "moving a key signature to the correct place\n"));
1086 last->next = node->next;
1087 node->next = subkey->next;
1088 subkey->next = node;
1089 node = last;
1090 fixed=1;
1093 break;
1094 default: break;
1098 return fixed;
1101 /****************
1102 * Menu driven key editor. If sign_mode is true semi-automatical signing
1103 * will be performed. commands are ignore in this case
1105 * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1108 void
1109 keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
1110 int sign_mode )
1112 enum cmdids { cmdNONE = 0,
1113 cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1114 cmdTSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY,
1115 cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID,
1116 cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER,
1117 cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
1118 cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
1119 cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
1120 cmdNOP };
1121 static struct { const char *name;
1122 enum cmdids id;
1123 int need_sk;
1124 int not_with_sk;
1125 int signmode;
1126 const char *desc;
1127 } cmds[] = {
1128 { N_("quit") , cmdQUIT , 0,0,1, N_("quit this menu") },
1129 { N_("q") , cmdQUIT , 0,0,1, NULL },
1130 { N_("save") , cmdSAVE , 0,0,1, N_("save and quit") },
1131 { N_("help") , cmdHELP , 0,0,1, N_("show this help") },
1132 { "?" , cmdHELP , 0,0,1, NULL },
1133 { N_("fpr") , cmdFPR , 0,0,1, N_("show fingerprint") },
1134 { N_("list") , cmdLIST , 0,0,1, N_("list key and user IDs") },
1135 { N_("l") , cmdLIST , 0,0,1, NULL },
1136 { N_("uid") , cmdSELUID , 0,0,1, N_("select user ID N") },
1137 { N_("key") , cmdSELKEY , 0,0,0, N_("select secondary key N") },
1138 { N_("check") , cmdCHECK , 0,0,1, N_("list signatures") },
1139 { N_("c") , cmdCHECK , 0,0,1, NULL },
1140 { N_("sign") , cmdSIGN , 0,1,1, N_("sign the key") },
1141 { N_("s") , cmdSIGN , 0,1,1, NULL },
1142 { N_("tsign") , cmdTSIGN , 0,1,1, N_("make a trust signature")},
1143 { N_("lsign") , cmdLSIGN , 0,1,1, N_("sign the key locally") },
1144 { N_("nrsign") , cmdNRSIGN , 0,1,1, N_("sign the key non-revocably") },
1145 { N_("nrlsign") , cmdNRLSIGN , 0,1,1, N_("sign the key locally and non-revocably") },
1146 { N_("debug") , cmdDEBUG , 0,0,0, NULL },
1147 { N_("adduid") , cmdADDUID , 1,1,0, N_("add a user ID") },
1148 { N_("addphoto"), cmdADDPHOTO , 1,1,0, N_("add a photo ID") },
1149 { N_("deluid") , cmdDELUID , 0,1,0, N_("delete user ID") },
1150 /* delphoto is really deluid in disguise */
1151 { N_("delphoto"), cmdDELUID , 0,1,0, NULL },
1152 { N_("addkey") , cmdADDKEY , 1,1,0, N_("add a secondary key") },
1153 { N_("delkey") , cmdDELKEY , 0,1,0, N_("delete a secondary key") },
1154 { N_("addrevoker"),cmdADDREVOKER,1,1,0, N_("add a revocation key") },
1155 { N_("delsig") , cmdDELSIG , 0,1,0, N_("delete signatures") },
1156 { N_("expire") , cmdEXPIRE , 1,1,0, N_("change the expire date") },
1157 { N_("primary") , cmdPRIMARY , 1,1,0, N_("flag user ID as primary")},
1158 { N_("toggle") , cmdTOGGLE , 1,0,0, N_("toggle between secret "
1159 "and public key listing") },
1160 { N_("t" ) , cmdTOGGLE , 1,0,0, NULL },
1161 { N_("pref") , cmdPREF , 0,1,0,
1162 N_("list preferences (expert)")},
1163 { N_("showpref"), cmdSHOWPREF , 0,1,0,
1164 N_("list preferences (verbose)")},
1165 { N_("setpref") , cmdSETPREF , 1,1,0, N_("set preference list") },
1166 { N_("updpref") , cmdUPDPREF , 1,1,0, N_("updated preferences") },
1167 { N_("keyserver"),cmdPREFKS , 1,1,0,
1168 N_("set preferred keyserver URL")},
1169 { N_("passwd") , cmdPASSWD , 1,1,0, N_("change the passphrase") },
1170 { N_("trust") , cmdTRUST , 0,1,0, N_("change the ownertrust") },
1171 { N_("revsig") , cmdREVSIG , 0,1,0, N_("revoke signatures") },
1172 { N_("revuid") , cmdREVUID , 1,1,0, N_("revoke a user ID") },
1173 { N_("revkey") , cmdREVKEY , 1,1,0, N_("revoke a secondary key") },
1174 { N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") },
1175 { N_("enable") , cmdENABLEKEY , 0,1,0, N_("enable a key") },
1176 { N_("showphoto"),cmdSHOWPHOTO , 0,0,0, N_("show photo ID") },
1178 { NULL, cmdNONE } };
1179 enum cmdids cmd = 0;
1180 int rc = 0;
1181 KBNODE keyblock = NULL;
1182 KEYDB_HANDLE kdbhd = NULL;
1183 KBNODE sec_keyblock = NULL;
1184 KEYDB_HANDLE sec_kdbhd = NULL;
1185 KBNODE cur_keyblock;
1186 char *answer = NULL;
1187 int redisplay = 1;
1188 int modified = 0;
1189 int sec_modified = 0;
1190 int toggle;
1191 int have_commands = !!commands;
1193 if ( opt.command_fd != -1 )
1195 else if( opt.batch && !have_commands ) {
1196 log_error(_("can't do that in batchmode\n"));
1197 goto leave;
1200 if( sign_mode ) {
1201 commands = NULL;
1202 append_to_strlist( &commands, sign_mode == 1? "sign":
1203 sign_mode == 2?"lsign":
1204 sign_mode == 3?"nrsign":"nrlsign");
1205 have_commands = 1;
1208 /* get the public key */
1209 rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1210 if( rc )
1211 goto leave;
1212 if( fix_keyblock( keyblock ) )
1213 modified++;
1214 if( collapse_uids( &keyblock ) )
1215 modified++;
1216 reorder_keyblock(keyblock);
1218 if( !sign_mode ) {/* see whether we have a matching secret key */
1219 PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1221 sec_kdbhd = keydb_new (1);
1223 byte afp[MAX_FINGERPRINT_LEN];
1224 size_t an;
1226 fingerprint_from_pk (pk, afp, &an);
1227 while (an < MAX_FINGERPRINT_LEN)
1228 afp[an++] = 0;
1229 rc = keydb_search_fpr (sec_kdbhd, afp);
1231 if (!rc) {
1232 rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1233 if (rc) {
1234 log_error (_("error reading secret keyblock `%s': %s\n"),
1235 username, gpg_strerror (rc));
1237 else {
1238 merge_keys_and_selfsig( sec_keyblock );
1239 if( fix_keyblock( sec_keyblock ) )
1240 sec_modified++;
1244 if (rc) {
1245 sec_keyblock = NULL;
1246 keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1247 rc = 0;
1251 if( sec_keyblock ) {
1252 tty_printf(_("Secret key is available.\n"));
1255 toggle = 0;
1256 cur_keyblock = keyblock;
1257 for(;;) { /* main loop */
1258 int i, arg_number, photo;
1259 const char *arg_string = "";
1260 char *p;
1261 PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1263 tty_printf("\n");
1264 if( redisplay ) {
1265 show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1266 tty_printf("\n");
1267 redisplay = 0;
1269 do {
1270 xfree (answer);
1271 if( have_commands ) {
1272 if( commands ) {
1273 answer = xstrdup ( commands->d );
1274 commands = commands->next;
1276 else if( opt.batch ) {
1277 answer = xstrdup ("quit");
1279 else
1280 have_commands = 0;
1282 if( !have_commands ) {
1283 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1284 cpr_kill_prompt();
1286 trim_spaces(answer);
1287 } while( *answer == '#' );
1289 arg_number = 0; /* Yes, here is the init which egcc complains about */
1290 photo = 0; /* This too */
1291 if( !*answer )
1292 cmd = cmdLIST;
1293 else if( *answer == CONTROL_D )
1294 cmd = cmdQUIT;
1295 else if( digitp( answer ) ) {
1296 cmd = cmdSELUID;
1297 arg_number = atoi(answer);
1299 else {
1300 if( (p=strchr(answer,' ')) ) {
1301 *p++ = 0;
1302 trim_spaces(answer);
1303 trim_spaces(p);
1304 arg_number = atoi(p);
1305 arg_string = p;
1308 for(i=0; cmds[i].name; i++ ) {
1309 if( !ascii_strcasecmp( answer, cmds[i].name ) )
1310 break;
1312 if( sign_mode && !cmds[i].signmode )
1313 cmd = cmdINVCMD;
1314 else if( cmds[i].need_sk && !sec_keyblock ) {
1315 tty_printf(_("Need the secret key to do this.\n"));
1316 cmd = cmdNOP;
1318 else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
1319 tty_printf(_("Please use the command \"toggle\" first.\n"));
1320 cmd = cmdNOP;
1322 else
1323 cmd = cmds[i].id;
1325 switch( cmd ) {
1326 case cmdHELP:
1327 for(i=0; cmds[i].name; i++ ) {
1328 if( sign_mode && !cmds[i].signmode )
1330 else if( cmds[i].need_sk && !sec_keyblock )
1331 ; /* skip if we do not have the secret key */
1332 else if( cmds[i].desc )
1333 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1335 break;
1337 case cmdLIST:
1338 redisplay = 1;
1339 break;
1341 case cmdFPR:
1342 show_key_and_fingerprint( keyblock );
1343 break;
1345 case cmdSELUID:
1346 if( menu_select_uid( cur_keyblock, arg_number ) )
1347 redisplay = 1;
1348 break;
1350 case cmdSELKEY:
1351 if( menu_select_key( cur_keyblock, arg_number ) )
1352 redisplay = 1;
1353 break;
1355 case cmdCHECK:
1356 /* we can only do this with the public key becuase the
1357 * check functions can't cope with secret keys and it
1358 * is questionable whether this would make sense at all */
1359 check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1360 break;
1362 case cmdSIGN: /* sign (only the public key) */
1363 case cmdLSIGN: /* sign (only the public key) */
1364 case cmdNRSIGN: /* sign (only the public key) */
1365 case cmdNRLSIGN: /* sign (only the public key) */
1366 case cmdTSIGN:
1367 if( pk->is_revoked )
1369 tty_printf(_("Key is revoked."));
1371 if(opt.expert)
1373 tty_printf(" ");
1374 if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1375 _("Are you sure you still want "
1376 "to sign it? (y/N) ")))
1377 break;
1379 else
1381 tty_printf(_(" Unable to sign.\n"));
1382 break;
1386 if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) {
1387 if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1388 _("Really sign all user IDs? ")) ) {
1389 tty_printf(_("Hint: Select the user IDs to sign\n"));
1390 break;
1393 if( !sign_uids( keyblock, locusr, &modified,
1394 (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
1395 (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
1396 (cmd == cmdTSIGN))
1397 && sign_mode )
1398 goto do_cmd_save;
1399 break;
1401 case cmdDEBUG:
1402 dump_kbnode( cur_keyblock );
1403 break;
1405 case cmdTOGGLE:
1406 toggle = !toggle;
1407 cur_keyblock = toggle? sec_keyblock : keyblock;
1408 redisplay = 1;
1409 break;
1411 case cmdADDPHOTO:
1412 if (RFC2440 || RFC1991 || PGP2)
1414 tty_printf(
1415 _("This command is not allowed while in %s mode.\n"),
1416 RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1417 break;
1419 photo=1;
1420 /* fall through */
1422 case cmdADDUID:
1423 if( menu_adduid( keyblock, sec_keyblock, photo ) ) {
1424 redisplay = 1;
1425 sec_modified = modified = 1;
1426 merge_keys_and_selfsig( sec_keyblock );
1427 merge_keys_and_selfsig( keyblock );
1429 break;
1431 case cmdDELUID: {
1432 int n1;
1434 if( !(n1=count_selected_uids(keyblock)) )
1435 tty_printf(_("You must select at least one user ID.\n"));
1436 else if( real_uids_left(keyblock) < 1 )
1437 tty_printf(_("You can't delete the last user ID!\n"));
1438 else if( cpr_get_answer_is_yes(
1439 "keyedit.remove.uid.okay",
1440 n1 > 1? _("Really remove all selected user IDs? ")
1441 : _("Really remove this user ID? ")
1442 ) ) {
1443 menu_deluid( keyblock, sec_keyblock );
1444 redisplay = 1;
1445 modified = 1;
1446 if( sec_keyblock )
1447 sec_modified = 1;
1450 break;
1452 case cmdDELSIG: {
1453 int n1;
1455 if( !(n1=count_selected_uids(keyblock)) )
1456 tty_printf(_("You must select at least one user ID.\n"));
1457 else if( menu_delsig( keyblock ) ) {
1458 /* no redisplay here, because it may scroll away some
1459 * status output of delsig */
1460 modified = 1;
1463 break;
1465 case cmdADDKEY:
1466 if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1467 redisplay = 1;
1468 sec_modified = modified = 1;
1469 merge_keys_and_selfsig( sec_keyblock );
1470 merge_keys_and_selfsig( keyblock );
1472 break;
1475 case cmdDELKEY: {
1476 int n1;
1478 if( !(n1=count_selected_keys( keyblock )) )
1479 tty_printf(_("You must select at least one key.\n"));
1480 else if( sec_keyblock && !cpr_get_answer_is_yes(
1481 "keyedit.remove.subkey.okay",
1482 n1 > 1?
1483 _("Do you really want to delete the selected keys? "):
1484 _("Do you really want to delete this key? ")
1487 else {
1488 menu_delkey( keyblock, sec_keyblock );
1489 redisplay = 1;
1490 modified = 1;
1491 if( sec_keyblock )
1492 sec_modified = 1;
1495 break;
1497 case cmdADDREVOKER:
1499 int sensitive=0;
1501 if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1502 sensitive=1;
1503 if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1504 redisplay = 1;
1505 sec_modified = modified = 1;
1506 merge_keys_and_selfsig( sec_keyblock );
1507 merge_keys_and_selfsig( keyblock );
1510 break;
1512 case cmdREVUID: {
1513 int n1;
1515 if( !(n1=count_selected_uids(keyblock)) )
1516 tty_printf(_("You must select at least one user ID.\n"));
1517 else if( cpr_get_answer_is_yes(
1518 "keyedit.revoke.uid.okay",
1519 n1 > 1? _("Really revoke all selected user IDs? ")
1520 : _("Really revoke this user ID? ")
1521 ) ) {
1522 if(menu_revuid(keyblock,sec_keyblock))
1524 modified=1;
1525 redisplay=1;
1529 break;
1531 case cmdREVKEY: {
1532 int n1;
1534 if( !(n1=count_selected_keys( keyblock )) )
1535 tty_printf(_("You must select at least one key.\n"));
1536 else if( sec_keyblock && !cpr_get_answer_is_yes(
1537 "keyedit.revoke.subkey.okay",
1538 n1 > 1?
1539 _("Do you really want to revoke the selected keys? "):
1540 _("Do you really want to revoke this key? ")
1543 else {
1544 if( menu_revkey( keyblock, sec_keyblock ) ) {
1545 modified = 1;
1546 /*sec_modified = 1;*/
1548 redisplay = 1;
1551 break;
1553 case cmdEXPIRE:
1554 if( menu_expire( keyblock, sec_keyblock ) ) {
1555 merge_keys_and_selfsig( sec_keyblock );
1556 merge_keys_and_selfsig( keyblock );
1557 sec_modified = 1;
1558 modified = 1;
1559 redisplay = 1;
1561 break;
1563 case cmdPRIMARY:
1564 if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1565 merge_keys_and_selfsig( keyblock );
1566 modified = 1;
1567 redisplay = 1;
1569 break;
1571 case cmdPASSWD:
1572 if( change_passphrase( sec_keyblock ) )
1573 sec_modified = 1;
1574 break;
1576 case cmdTRUST:
1577 show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1578 tty_printf("\n");
1579 if( edit_ownertrust( find_kbnode( keyblock,
1580 PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1581 redisplay = 1;
1582 /* No real need to set update_trust here as
1583 edit_ownertrust() calls revalidation_mark()
1584 anyway. */
1585 update_trust=1;
1587 break;
1589 case cmdPREF:
1590 show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1591 break;
1593 case cmdSHOWPREF:
1594 show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1595 break;
1597 case cmdSETPREF:
1598 keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
1599 break;
1601 case cmdUPDPREF:
1603 PKT_user_id *temp=keygen_get_std_prefs();
1604 tty_printf(_("Current preference list:\n"));
1605 show_prefs(temp,1);
1606 xfree (temp);
1608 if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
1609 count_selected_uids (keyblock)?
1610 _("Really update the preferences"
1611 " for the selected user IDs? "):
1612 _("Really update the preferences? "))){
1614 if ( menu_set_preferences (keyblock, sec_keyblock) ) {
1615 merge_keys_and_selfsig (keyblock);
1616 modified = 1;
1617 redisplay = 1;
1620 break;
1622 case cmdPREFKS:
1623 if( menu_set_keyserver_url ( keyblock, sec_keyblock ) ) {
1624 merge_keys_and_selfsig( keyblock );
1625 modified = 1;
1626 redisplay = 1;
1628 break;
1630 case cmdNOP:
1631 break;
1633 case cmdREVSIG:
1634 if( menu_revsig( keyblock ) ) {
1635 redisplay = 1;
1636 modified = 1;
1638 break;
1640 case cmdENABLEKEY:
1641 case cmdDISABLEKEY:
1642 if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1643 redisplay = 1;
1644 modified = 1;
1646 break;
1648 case cmdSHOWPHOTO:
1649 menu_showphoto(keyblock);
1650 break;
1652 case cmdQUIT:
1653 if( have_commands )
1654 goto leave;
1655 if( !modified && !sec_modified )
1656 goto leave;
1657 if( !cpr_get_answer_is_yes("keyedit.save.okay",
1658 _("Save changes? ")) ) {
1659 if( cpr_enabled()
1660 || cpr_get_answer_is_yes("keyedit.cancel.okay",
1661 _("Quit without saving? ")) )
1662 goto leave;
1663 break;
1665 /* fall thru */
1666 case cmdSAVE:
1667 do_cmd_save:
1668 if( modified || sec_modified ) {
1669 if( modified ) {
1670 rc = keydb_update_keyblock (kdbhd, keyblock);
1671 if( rc ) {
1672 log_error(_("update failed: %s\n"), gpg_strerror (rc) );
1673 break;
1676 if( sec_modified ) {
1677 rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1678 if( rc ) {
1679 log_error( _("update secret failed: %s\n"),
1680 gpg_strerror (rc) );
1681 break;
1685 else
1686 tty_printf(_("Key not changed so no update needed.\n"));
1688 if( update_trust )
1690 revalidation_mark ();
1691 update_trust=0;
1693 goto leave;
1695 case cmdINVCMD:
1696 default:
1697 tty_printf("\n");
1698 tty_printf(_("Invalid command (try \"help\")\n"));
1699 break;
1701 } /* end main loop */
1703 leave:
1704 release_kbnode( keyblock );
1705 release_kbnode( sec_keyblock );
1706 keydb_release (kdbhd);
1707 xfree (answer);
1711 /****************
1712 * show preferences of a public keyblock.
1714 static void
1715 show_prefs (PKT_user_id *uid, int verbose)
1717 const prefitem_t fake={0,0};
1718 const prefitem_t *prefs;
1719 int i;
1721 if( !uid )
1722 return;
1724 if( uid->prefs )
1725 prefs=uid->prefs;
1726 else if(verbose)
1727 prefs=&fake;
1728 else
1729 return;
1731 if (verbose) {
1732 int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1733 tty_printf (" ");
1734 tty_printf (_("Cipher: "));
1735 for(i=any=0; prefs[i].type; i++ ) {
1736 if( prefs[i].type == PREFTYPE_SYM ) {
1737 const char *s = gcry_cipher_algo_name (prefs[i].value);
1739 if (any)
1740 tty_printf (", ");
1741 any = 1;
1742 /* We don't want to display strings for experimental algos */
1743 if (s && prefs[i].value < 100 )
1744 tty_printf ("%s", s );
1745 else
1746 tty_printf ("[%d]", prefs[i].value);
1747 if (prefs[i].value == CIPHER_ALGO_3DES )
1748 des_seen = 1;
1751 if (!des_seen) {
1752 if (any)
1753 tty_printf (", ");
1754 tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES));
1756 tty_printf ("\n ");
1757 tty_printf (_("Digest: "));
1758 for(i=any=0; prefs[i].type; i++ ) {
1759 if( prefs[i].type == PREFTYPE_HASH ) {
1760 const char *s = gcry_md_algo_name (prefs[i].value);
1762 if (any)
1763 tty_printf (", ");
1764 any = 1;
1765 /* We don't want to display strings for experimental algos */
1766 if (s && prefs[i].value < 100 )
1767 tty_printf ("%s", s );
1768 else
1769 tty_printf ("[%d]", prefs[i].value);
1770 if (prefs[i].value == DIGEST_ALGO_SHA1 )
1771 sha1_seen = 1;
1774 if (!sha1_seen) {
1775 if (any)
1776 tty_printf (", ");
1777 tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
1779 tty_printf ("\n ");
1780 tty_printf (_("Compression: "));
1781 for(i=any=0; prefs[i].type; i++ ) {
1782 if( prefs[i].type == PREFTYPE_ZIP ) {
1783 const char *s=compress_algo_to_string(prefs[i].value);
1785 if (any)
1786 tty_printf (", ");
1787 any = 1;
1788 /* We don't want to display strings for experimental algos */
1789 if (s && prefs[i].value < 100 )
1790 tty_printf ("%s", s );
1791 else
1792 tty_printf ("[%d]", prefs[i].value);
1793 if (prefs[i].value == 0 )
1794 uncomp_seen = 1;
1797 if (!uncomp_seen) {
1798 if (any)
1799 tty_printf (", ");
1800 else {
1801 tty_printf ("%s",compress_algo_to_string(1));
1802 tty_printf (", ");
1804 tty_printf ("%s",compress_algo_to_string(0));
1806 if(uid->mdc_feature || !uid->ks_modify)
1808 tty_printf ("\n ");
1809 tty_printf (_("Features: "));
1810 any=0;
1811 if(uid->mdc_feature)
1813 tty_printf ("MDC");
1814 any=1;
1816 if(!uid->ks_modify)
1818 if(any)
1819 tty_printf (", ");
1820 tty_printf (_("Keyserver no-modify"));
1823 tty_printf("\n");
1825 else {
1826 tty_printf(" ");
1827 for(i=0; prefs[i].type; i++ ) {
1828 tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
1829 prefs[i].type == PREFTYPE_HASH ? 'H' :
1830 prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
1831 prefs[i].value);
1833 if (uid->mdc_feature)
1834 tty_printf (" [mdc]");
1835 if (!uid->ks_modify)
1836 tty_printf (" [no-ks-modify]");
1837 tty_printf("\n");
1842 /* This is the version of show_key_with_all_names used when
1843 opt.with_colons is used. It prints all available data in a easy to
1844 parse format and does not translate utf8 */
1845 static void
1846 show_key_with_all_names_colon (KBNODE keyblock)
1848 KBNODE node;
1849 int i, j, ulti_hack=0;
1850 byte pk_version=0;
1851 PKT_public_key *primary=NULL;
1853 /* the keys */
1854 for ( node = keyblock; node; node = node->next )
1856 if (node->pkt->pkttype == PKT_PUBLIC_KEY
1857 || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
1859 PKT_public_key *pk = node->pkt->pkt.public_key;
1860 u32 keyid[2];
1862 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1864 pk_version = pk->version;
1865 primary=pk;
1868 keyid_from_pk (pk, keyid);
1870 fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
1871 if (!pk->is_valid)
1872 putchar ('i');
1873 else if (pk->is_revoked)
1874 putchar ('r');
1875 else if (pk->has_expired)
1876 putchar ('e');
1877 else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1879 int trust = get_validity_info (pk, NULL);
1880 if(trust=='u')
1881 ulti_hack=1;
1882 putchar (trust);
1885 printf (":%u:%d:%08lX%08lX:%lu:%lu:",
1886 nbits_from_pk (pk),
1887 pk->pubkey_algo,
1888 (ulong)keyid[0], (ulong)keyid[1],
1889 (ulong)pk->timestamp,
1890 (ulong)pk->expiredate );
1891 if (pk->local_id)
1892 printf ("%lu", pk->local_id);
1893 putchar (':');
1894 if (node->pkt->pkttype==PKT_PUBLIC_KEY
1895 && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1896 putchar(get_ownertrust_info (pk));
1897 putchar(':');
1898 putchar('\n');
1900 print_fingerprint (pk, NULL, 0);
1902 /* print the revoker record */
1903 if( !pk->revkey && pk->numrevkeys )
1904 BUG();
1905 else
1907 for (i=0; i < pk->numrevkeys; i++)
1909 byte *p;
1911 printf ("rvk:::%d::::::", pk->revkey[i].algid);
1912 p = pk->revkey[i].fpr;
1913 for (j=0; j < 20; j++, p++ )
1914 printf ("%02X", *p);
1915 printf (":%02x%s:\n", pk->revkey[i].class,
1916 (pk->revkey[i].class&0x40)?"s":"");
1922 /* the user ids */
1923 i = 0;
1924 for (node = keyblock; node; node = node->next)
1926 if ( node->pkt->pkttype == PKT_USER_ID )
1928 PKT_user_id *uid = node->pkt->pkt.user_id;
1930 ++i;
1932 if(uid->attrib_data)
1933 printf("uat:");
1934 else
1935 printf("uid:");
1937 if ( uid->is_revoked )
1938 printf("r::::::::");
1939 else if ( uid->is_expired )
1940 printf("e::::::::");
1941 else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
1942 printf("::::::::");
1943 else
1945 int uid_validity;
1947 if( primary && !ulti_hack )
1948 uid_validity = get_validity_info( primary, uid );
1949 else
1950 uid_validity = 'u';
1951 printf("%c::::::::",uid_validity);
1954 if(uid->attrib_data)
1955 printf ("%u %lu",uid->numattribs,uid->attrib_len);
1956 else
1957 print_string (stdout, uid->name, uid->len, ':');
1959 putchar (':');
1960 /* signature class */
1961 putchar (':');
1962 /* capabilities */
1963 putchar (':');
1964 /* preferences */
1965 if (pk_version>3 || uid->selfsigversion>3)
1967 const prefitem_t *prefs = uid->prefs;
1969 for (j=0; prefs && prefs[j].type; j++)
1971 if (j)
1972 putchar (' ');
1973 printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
1974 prefs[j].type == PREFTYPE_HASH ? 'H' :
1975 prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
1976 prefs[j].value);
1978 if (uid->mdc_feature)
1979 printf (",mdc");
1980 if (!uid->ks_modify)
1981 printf (",no-ks-modify");
1983 putchar (':');
1984 /* flags */
1985 printf ("%d,", i);
1986 if (uid->is_primary)
1987 putchar ('p');
1988 if (uid->is_revoked)
1989 putchar ('r');
1990 if (uid->is_expired)
1991 putchar ('e');
1992 if ((node->flag & NODFLG_SELUID))
1993 putchar ('s');
1994 if ((node->flag & NODFLG_MARK_A))
1995 putchar ('m');
1996 putchar (':');
1997 putchar('\n');
2003 /****************
2004 * Display the key a the user ids, if only_marked is true, do only
2005 * so for user ids with mark A flag set and dont display the index number
2007 static void
2008 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2009 int with_fpr, int with_subkeys, int with_prefs )
2011 KBNODE node;
2012 int i, rc;
2013 int do_warn = 0;
2014 byte pk_version=0;
2015 PKT_public_key *primary=NULL;
2017 if (opt.with_colons)
2019 show_key_with_all_names_colon (keyblock);
2020 return;
2023 /* the keys */
2024 for( node = keyblock; node; node = node->next ) {
2025 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2026 || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
2027 PKT_public_key *pk = node->pkt->pkt.public_key;
2028 const char *otrust="err",*trust="err";
2030 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2031 /* do it here, so that debug messages don't clutter the
2032 * output */
2033 static int did_warn = 0;
2035 trust = get_validity_string (pk, NULL);
2036 otrust = get_ownertrust_string (pk);
2038 /* Show a warning once */
2039 if (!did_warn
2040 && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2041 did_warn = 1;
2042 do_warn = 1;
2045 pk_version = pk->version;
2046 primary = pk;
2049 if(with_revoker) {
2050 if( !pk->revkey && pk->numrevkeys )
2051 BUG();
2052 else
2053 for(i=0;i<pk->numrevkeys;i++) {
2054 u32 r_keyid[2];
2055 char *user;
2056 const char *algo=
2057 gcry_pk_algo_name (pk->revkey[i].algid);
2059 keyid_from_fingerprint(pk->revkey[i].fpr,
2060 MAX_FINGERPRINT_LEN,r_keyid);
2062 user=get_user_id_string (r_keyid);
2063 tty_printf (_("This key may be revoked by %s key "),
2064 algo?algo:"?");
2065 tty_print_utf8_string (user, strlen (user));
2066 if ((pk->revkey[i].class&0x40))
2067 tty_printf (_(" (sensitive)"));
2068 tty_printf ("\n");
2069 xfree (user);
2073 keyid_from_pk(pk,NULL);
2074 tty_printf("%s%c %4u%c/",
2075 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2076 (node->flag & NODFLG_SELKEY)? '*':' ',
2077 nbits_from_pk( pk ),
2078 pubkey_letter( pk->pubkey_algo ));
2080 if(opt.list_options&LIST_SHOW_LONG_KEYID)
2081 tty_printf("%08lX",(ulong)pk->keyid[0]);
2083 tty_printf("%08lX ",(ulong)pk->keyid[1]);
2084 tty_printf(_("created: %s expires: %s"),
2085 datestr_from_pk(pk),
2086 expirestr_from_pk(pk) );
2087 tty_printf("\n");
2089 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2091 tty_printf(" ");
2092 if(opt.list_options&LIST_SHOW_LONG_KEYID)
2093 tty_printf(" ");
2094 tty_printf(_("trust: %-13s"), otrust);
2095 tty_printf(_("validity: %s"), trust );
2096 tty_printf("\n");
2097 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2098 && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2100 tty_printf("*** ");
2101 tty_printf(_("This key has been disabled"));
2102 tty_printf("\n");
2106 if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2108 print_fingerprint ( pk, NULL, 2 );
2109 tty_printf("\n");
2112 else if( node->pkt->pkttype == PKT_SECRET_KEY
2113 || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
2114 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2115 tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
2116 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2117 (node->flag & NODFLG_SELKEY)? '*':' ',
2118 nbits_from_sk( sk ),
2119 pubkey_letter( sk->pubkey_algo ),
2120 (ulong)keyid_from_sk(sk,NULL),
2121 datestr_from_sk(sk),
2122 expirestr_from_sk(sk) );
2123 tty_printf("\n");
2125 else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
2126 && node->pkt->pkt.signature->sig_class == 0x28 ) {
2127 PKT_signature *sig = node->pkt->pkt.signature;
2129 rc = check_key_signature( keyblock, node, NULL );
2130 if( !rc )
2131 tty_printf( _("rev! subkey has been revoked: %s\n"),
2132 datestr_from_sig( sig ) );
2133 else if( gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE )
2134 tty_printf( _("rev- faked revocation found\n") );
2135 else if( rc )
2136 tty_printf( _("rev? problem checking revocation: %s\n"),
2137 gpg_strerror (rc) );
2140 /* the user ids */
2141 i = 0;
2142 for( node = keyblock; node; node = node->next ) {
2143 if( node->pkt->pkttype == PKT_USER_ID ) {
2144 PKT_user_id *uid = node->pkt->pkt.user_id;
2145 ++i;
2146 if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
2147 if(opt.list_options&LIST_SHOW_VALIDITY && primary)
2148 tty_printf("[%8.8s] ",
2149 trust_value_to_string(get_validity(primary,uid)));
2150 if( only_marked )
2151 tty_printf(" ");
2152 else if( node->flag & NODFLG_SELUID )
2153 tty_printf("(%d)* ", i);
2154 else if( uid->is_primary )
2155 tty_printf("(%d). ", i);
2156 else
2157 tty_printf("(%d) ", i);
2158 if ( uid->is_revoked )
2159 tty_printf (_("[revoked] "));
2160 if ( uid->is_expired )
2161 tty_printf (_("[expired] "));
2162 tty_print_utf8_string( uid->name, uid->len );
2163 tty_printf("\n");
2164 if( with_prefs )
2166 if(pk_version>3 || uid->selfsigversion>3)
2167 show_prefs (uid, with_prefs == 2);
2168 else
2169 tty_printf(_("There are no preferences on a "
2170 "PGP 2.x-style user ID.\n"));
2176 if (do_warn)
2177 tty_printf (_("Please note that the shown key validity "
2178 "is not necessarily correct\n"
2179 "unless you restart the program.\n"));
2184 /* Display basic key information. This fucntion is suitable to show
2185 information on the key without any dependencies on the trustdb or
2186 any other internal GnuPG stuff. KEYBLOCK may either be a public or
2187 a secret key.*/
2188 void
2189 show_basic_key_info ( KBNODE keyblock )
2191 KBNODE node;
2192 int i;
2194 /* The primary key */
2195 for (node = keyblock; node; node = node->next)
2197 if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2199 PKT_public_key *pk = node->pkt->pkt.public_key;
2201 /* Note, we use the same format string as in other show
2202 functions to make the translation job easier. */
2203 tty_printf (_("%s%c %4u%c/%08lX created: %s expires: %s"),
2204 node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2205 ' ',
2206 nbits_from_pk( pk ),
2207 pubkey_letter( pk->pubkey_algo ),
2208 (ulong)keyid_from_pk(pk,NULL),
2209 datestr_from_pk(pk),
2210 expirestr_from_pk(pk) );
2211 tty_printf("\n");
2212 print_fingerprint ( pk, NULL, 3 );
2213 tty_printf("\n");
2215 else if (node->pkt->pkttype == PKT_SECRET_KEY)
2217 PKT_secret_key *sk = node->pkt->pkt.secret_key;
2218 tty_printf(_("%s%c %4u%c/%08lX created: %s expires: %s"),
2219 node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2220 ' ',
2221 nbits_from_sk( sk ),
2222 pubkey_letter( sk->pubkey_algo ),
2223 (ulong)keyid_from_sk(sk,NULL),
2224 datestr_from_sk(sk),
2225 expirestr_from_sk(sk) );
2226 tty_printf("\n");
2227 print_fingerprint (NULL, sk, 3 );
2228 tty_printf("\n");
2232 /* The user IDs. */
2233 for (i=0, node = keyblock; node; node = node->next)
2235 if (node->pkt->pkttype == PKT_USER_ID)
2237 PKT_user_id *uid = node->pkt->pkt.user_id;
2238 ++i;
2240 tty_printf (" ");
2241 if (uid->is_revoked)
2242 tty_printf ("[revoked] ");
2243 if ( uid->is_expired )
2244 tty_printf ("[expired] ");
2245 tty_print_utf8_string (uid->name, uid->len);
2246 tty_printf ("\n");
2251 static void
2252 show_key_and_fingerprint( KBNODE keyblock )
2254 KBNODE node;
2255 PKT_public_key *pk = NULL;
2257 for( node = keyblock; node; node = node->next ) {
2258 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2259 pk = node->pkt->pkt.public_key;
2260 tty_printf("pub %4u%c/%08lX %s ",
2261 nbits_from_pk( pk ),
2262 pubkey_letter( pk->pubkey_algo ),
2263 (ulong)keyid_from_pk(pk,NULL),
2264 datestr_from_pk(pk) );
2266 else if( node->pkt->pkttype == PKT_USER_ID ) {
2267 PKT_user_id *uid = node->pkt->pkt.user_id;
2268 tty_print_utf8_string( uid->name, uid->len );
2269 break;
2272 tty_printf("\n");
2273 if( pk )
2274 print_fingerprint( pk, NULL, 2 );
2278 /* Show a warning if no uids on the key have the primary uid flag
2279 set. */
2280 static void
2281 no_primary_warning(KBNODE keyblock, int uids)
2283 KBNODE node;
2284 int select_all=1,have_uid=0,uid_count=0;
2286 if(uids)
2287 select_all=!count_selected_uids(keyblock);
2289 /* TODO: if we ever start behaving differently with a primary or
2290 non-primary attribute ID, we will need to check for attributes
2291 here as well. */
2293 for(node=keyblock; node; node = node->next)
2295 if(node->pkt->pkttype==PKT_USER_ID
2296 && node->pkt->pkt.user_id->attrib_data==NULL)
2298 uid_count++;
2300 if((select_all || (node->flag & NODFLG_SELUID))
2301 && node->pkt->pkt.user_id->is_primary==2)
2302 have_uid|=2;
2303 else
2304 have_uid|=1;
2308 if(uid_count>1 && have_uid&1 && !(have_uid&2))
2309 log_info(_("WARNING: no user ID has been marked as primary. This command "
2310 "may\n cause a different user ID to become the assumed primary.\n"));
2313 /****************
2314 * Ask for a new user id, do the selfsignature and put it into
2315 * both keyblocks.
2316 * Return true if there is a new user id
2318 static int
2319 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2321 PKT_user_id *uid;
2322 PKT_public_key *pk=NULL;
2323 PKT_secret_key *sk=NULL;
2324 PKT_signature *sig=NULL;
2325 PACKET *pkt;
2326 KBNODE node;
2327 KBNODE pub_where=NULL, sec_where=NULL;
2328 int rc;
2330 for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2331 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2332 pk = node->pkt->pkt.public_key;
2333 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2334 break;
2336 if( !node ) /* no subkey */
2337 pub_where = NULL;
2338 for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2339 if( node->pkt->pkttype == PKT_SECRET_KEY )
2340 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2341 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2342 break;
2344 if( !node ) /* no subkey */
2345 sec_where = NULL;
2346 assert(pk && sk);
2348 if(photo) {
2349 int hasattrib=0;
2351 for( node = pub_keyblock; node; node = node->next )
2352 if( node->pkt->pkttype == PKT_USER_ID &&
2353 node->pkt->pkt.user_id->attrib_data!=NULL)
2355 hasattrib=1;
2356 break;
2359 /* It is legal but bad for compatibility to add a photo ID to a
2360 v3 key as it means that PGP2 will not be able to use that key
2361 anymore. Also, PGP may not expect a photo on a v3 key.
2362 Don't bother to ask this if the key already has a photo - any
2363 damage has already been done at that point. -dms */
2364 if(pk->version==3 && !hasattrib)
2366 if(opt.expert)
2368 tty_printf(_("WARNING: This is a PGP2-style key. "
2369 "Adding a photo ID may cause some versions\n"
2370 " of PGP to reject this key.\n"));
2372 if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2373 _("Are you sure you still want "
2374 "to add it? (y/N) ")))
2375 return 0;
2377 else
2379 tty_printf(_("You may not add a photo ID to "
2380 "a PGP2-style key.\n"));
2381 return 0;
2385 uid = generate_photo_id(pk);
2386 } else
2387 uid = generate_user_id();
2388 if( !uid )
2389 return 0;
2391 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2392 keygen_add_std_prefs, pk );
2393 free_secret_key( sk );
2394 if( rc ) {
2395 log_error("signing failed: %s\n", gpg_strerror (rc) );
2396 free_user_id(uid);
2397 return 0;
2400 /* insert/append to secret keyblock */
2401 pkt = xcalloc (1, sizeof *pkt );
2402 pkt->pkttype = PKT_USER_ID;
2403 pkt->pkt.user_id = scopy_user_id(uid);
2404 node = new_kbnode(pkt);
2405 if( sec_where )
2406 insert_kbnode( sec_where, node, 0 );
2407 else
2408 add_kbnode( sec_keyblock, node );
2409 pkt = xcalloc (1, sizeof *pkt );
2410 pkt->pkttype = PKT_SIGNATURE;
2411 pkt->pkt.signature = copy_signature(NULL, sig);
2412 if( sec_where )
2413 insert_kbnode( node, new_kbnode(pkt), 0 );
2414 else
2415 add_kbnode( sec_keyblock, new_kbnode(pkt) );
2416 /* insert/append to public keyblock */
2417 pkt = xcalloc (1, sizeof *pkt );
2418 pkt->pkttype = PKT_USER_ID;
2419 pkt->pkt.user_id = uid;
2420 node = new_kbnode(pkt);
2421 if( pub_where )
2422 insert_kbnode( pub_where, node, 0 );
2423 else
2424 add_kbnode( pub_keyblock, node );
2425 pkt = xcalloc (1, sizeof *pkt );
2426 pkt->pkttype = PKT_SIGNATURE;
2427 pkt->pkt.signature = copy_signature(NULL, sig);
2428 if( pub_where )
2429 insert_kbnode( node, new_kbnode(pkt), 0 );
2430 else
2431 add_kbnode( pub_keyblock, new_kbnode(pkt) );
2432 return 1;
2436 /****************
2437 * Remove all selceted userids from the keyrings
2439 static void
2440 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2442 KBNODE node;
2443 int selected=0;
2445 for( node = pub_keyblock; node; node = node->next ) {
2446 if( node->pkt->pkttype == PKT_USER_ID ) {
2447 selected = node->flag & NODFLG_SELUID;
2448 if( selected ) {
2449 /* Only cause a trust update if we delete a
2450 non-revoked user id */
2451 if(!node->pkt->pkt.user_id->is_revoked)
2452 update_trust=1;
2453 delete_kbnode( node );
2454 if( sec_keyblock ) {
2455 KBNODE snode;
2456 int s_selected = 0;
2457 PKT_user_id *uid = node->pkt->pkt.user_id;
2458 for( snode = sec_keyblock; snode; snode = snode->next ) {
2459 if( snode->pkt->pkttype == PKT_USER_ID ) {
2460 PKT_user_id *suid = snode->pkt->pkt.user_id;
2462 s_selected =
2463 (uid->len == suid->len
2464 && !memcmp( uid->name, suid->name, uid->len));
2465 if( s_selected )
2466 delete_kbnode( snode );
2468 else if( s_selected
2469 && snode->pkt->pkttype == PKT_SIGNATURE )
2470 delete_kbnode( snode );
2471 else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2472 s_selected = 0;
2477 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2478 delete_kbnode( node );
2479 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2480 selected = 0;
2482 commit_kbnode( &pub_keyblock );
2483 if( sec_keyblock )
2484 commit_kbnode( &sec_keyblock );
2488 static int
2489 menu_delsig( KBNODE pub_keyblock )
2491 KBNODE node;
2492 PKT_user_id *uid = NULL;
2493 int changed=0;
2495 for( node = pub_keyblock; node; node = node->next ) {
2496 if( node->pkt->pkttype == PKT_USER_ID ) {
2497 uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2499 else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2500 int okay, valid, selfsig, inv_sig, no_key, other_err;
2502 tty_printf("uid ");
2503 tty_print_utf8_string( uid->name, uid->len );
2504 tty_printf("\n");
2506 okay = inv_sig = no_key = other_err = 0;
2507 valid = print_and_check_one_sig( pub_keyblock, node,
2508 &inv_sig, &no_key, &other_err,
2509 &selfsig, 1 );
2511 if( valid ) {
2512 okay = cpr_get_answer_yes_no_quit(
2513 "keyedit.delsig.valid",
2514 _("Delete this good signature? (y/N/q)"));
2516 /* Only update trust if we delete a good signature.
2517 The other two cases do not affect trust. */
2518 if(okay)
2519 update_trust=1;
2521 else if( inv_sig || other_err )
2522 okay = cpr_get_answer_yes_no_quit(
2523 "keyedit.delsig.invalid",
2524 _("Delete this invalid signature? (y/N/q)"));
2525 else if( no_key )
2526 okay = cpr_get_answer_yes_no_quit(
2527 "keyedit.delsig.unknown",
2528 _("Delete this unknown signature? (y/N/q)"));
2530 if( okay == -1 )
2531 break;
2532 if( okay && selfsig && !cpr_get_answer_is_yes(
2533 "keyedit.delsig.selfsig",
2534 _("Really delete this self-signature? (y/N)") ))
2535 okay = 0;
2536 if( okay ) {
2537 delete_kbnode( node );
2538 changed++;
2542 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2543 uid = NULL;
2546 if( changed ) {
2547 commit_kbnode( &pub_keyblock );
2548 tty_printf( changed == 1? _("Deleted %d signature.\n")
2549 : _("Deleted %d signatures.\n"), changed );
2551 else
2552 tty_printf( _("Nothing deleted.\n") );
2554 return changed;
2558 /****************
2559 * Remove some of the secondary keys
2561 static void
2562 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2564 KBNODE node;
2565 int selected=0;
2567 for( node = pub_keyblock; node; node = node->next ) {
2568 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2569 selected = node->flag & NODFLG_SELKEY;
2570 if( selected ) {
2571 delete_kbnode( node );
2572 if( sec_keyblock ) {
2573 KBNODE snode;
2574 int s_selected = 0;
2575 u32 ki[2];
2577 keyid_from_pk( node->pkt->pkt.public_key, ki );
2578 for( snode = sec_keyblock; snode; snode = snode->next ) {
2579 if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2580 u32 ki2[2];
2582 keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2583 s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2584 if( s_selected )
2585 delete_kbnode( snode );
2587 else if( s_selected
2588 && snode->pkt->pkttype == PKT_SIGNATURE )
2589 delete_kbnode( snode );
2590 else
2591 s_selected = 0;
2596 else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2597 delete_kbnode( node );
2598 else
2599 selected = 0;
2601 commit_kbnode( &pub_keyblock );
2602 if( sec_keyblock )
2603 commit_kbnode( &sec_keyblock );
2605 /* No need to set update_trust here since signing keys are no
2606 longer used to certify other keys, so there is no change in
2607 trust when revoking/removing them */
2611 /****************
2612 * Ask for a new revoker, do the selfsignature and put it into
2613 * both keyblocks.
2614 * Return true if there is a new revoker
2616 static int
2617 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2619 PKT_public_key *pk=NULL,*revoker_pk=NULL;
2620 PKT_secret_key *sk=NULL;
2621 PKT_signature *sig=NULL;
2622 PACKET *pkt;
2623 struct revocation_key revkey;
2624 size_t fprlen;
2625 int rc;
2627 assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2628 assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2630 pk=pub_keyblock->pkt->pkt.public_key;
2632 if(pk->numrevkeys==0 && pk->version==3)
2634 /* It is legal but bad for compatibility to add a revoker to a
2635 v3 key as it means that PGP2 will not be able to use that key
2636 anymore. Also, PGP may not expect a revoker on a v3 key.
2637 Don't bother to ask this if the key already has a revoker -
2638 any damage has already been done at that point. -dms */
2639 if(opt.expert)
2641 tty_printf(_("WARNING: This is a PGP 2.x-style key. "
2642 "Adding a designated revoker may cause\n"
2643 " some versions of PGP to reject this key.\n"));
2645 if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2646 _("Are you sure you still want "
2647 "to add it? (y/N) ")))
2648 return 0;
2650 else
2652 tty_printf(_("You may not add a designated revoker to "
2653 "a PGP 2.x-style key.\n"));
2654 return 0;
2658 sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2660 for(;;)
2662 char *answer;
2663 u32 keyid[2];
2664 char *p;
2665 size_t n;
2667 if(revoker_pk)
2668 free_public_key(revoker_pk);
2670 revoker_pk=xcalloc (1,sizeof(*revoker_pk));
2672 tty_printf("\n");
2674 answer=cpr_get_utf8("keyedit.add_revoker",
2675 _("Enter the user ID of the designated revoker: "));
2676 if(answer[0]=='\0' || answer[0]=='\004')
2678 xfree(answer); answer = NULL;
2679 goto fail;
2682 rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2684 if(rc)
2686 log_error (_("key `%s' not found: %s\n"),answer,gpg_strerror (rc));
2687 xfree (answer); answer = NULL;
2688 continue;
2691 xfree (answer); answer = NULL;
2694 fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2695 if(fprlen!=20)
2697 log_error(_("cannot appoint a PGP 2.x style key as a "
2698 "designated revoker\n"));
2699 continue;
2702 revkey.class=0x80;
2703 if(sensitive)
2704 revkey.class|=0x40;
2705 revkey.algid=revoker_pk->pubkey_algo;
2707 if(cmp_public_keys(revoker_pk,pk)==0)
2709 /* This actually causes no harm (after all, a key that
2710 designates itself as a revoker is the same as a
2711 regular key), but it's easy enough to check. */
2712 log_error(_("you cannot appoint a key as its own "
2713 "designated revoker\n"));
2715 continue;
2718 keyid_from_pk(pk,NULL);
2720 /* Does this revkey already exist? */
2721 if(!pk->revkey && pk->numrevkeys)
2722 BUG();
2723 else
2725 int i;
2727 for(i=0;i<pk->numrevkeys;i++)
2729 if(memcmp(&pk->revkey[i],&revkey,
2730 sizeof(struct revocation_key))==0)
2732 char buf[50];
2734 log_error(_("this key has already been designated "
2735 "as a revoker\n"));
2737 sprintf(buf,"%08lX%08lX",
2738 (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2739 write_status_text(STATUS_ALREADY_SIGNED,buf);
2741 break;
2745 if(i<pk->numrevkeys)
2746 continue;
2749 keyid_from_pk(revoker_pk,keyid);
2751 tty_printf("\npub %4u%c/%08lX %s ",
2752 nbits_from_pk( revoker_pk ),
2753 pubkey_letter( revoker_pk->pubkey_algo ),
2754 (ulong)keyid[1], datestr_from_pk(pk) );
2756 p = get_user_id( keyid, &n );
2757 tty_print_utf8_string( p, n );
2758 xfree (p);
2759 tty_printf("\n");
2760 print_fingerprint(revoker_pk,NULL,2);
2761 tty_printf("\n");
2763 tty_printf(_("WARNING: appointing a key as a designated revoker "
2764 "cannot be undone!\n"));
2766 tty_printf("\n");
2768 if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2769 _("Are you sure you want to appoint this "
2770 "key as a designated revoker? (y/N): ")))
2771 continue;
2773 free_public_key(revoker_pk);
2774 revoker_pk=NULL;
2775 break;
2778 /* The 1F signature must be at least v4 to carry the revocation key
2779 subpacket. */
2780 rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
2781 keygen_add_revkey,&revkey );
2782 if( rc )
2784 log_error("signing failed: %s\n", gpg_strerror (rc) );
2785 goto fail;
2788 free_secret_key(sk);
2789 sk=NULL;
2791 /* insert into secret keyblock */
2792 pkt = xcalloc (1, sizeof *pkt );
2793 pkt->pkttype = PKT_SIGNATURE;
2794 pkt->pkt.signature = copy_signature(NULL, sig);
2795 insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2797 /* insert into public keyblock */
2798 pkt = xcalloc (1, sizeof *pkt );
2799 pkt->pkttype = PKT_SIGNATURE;
2800 pkt->pkt.signature = sig;
2801 insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2803 return 1;
2805 fail:
2806 if(sk)
2807 free_secret_key(sk);
2808 if(sig)
2809 free_seckey_enc(sig);
2810 if(revoker_pk)
2811 free_public_key(revoker_pk);
2813 return 0;
2817 static int
2818 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
2820 int n1, signumber, rc;
2821 u32 expiredate;
2822 int mainkey=0;
2823 PKT_secret_key *sk; /* copy of the main sk */
2824 PKT_public_key *main_pk, *sub_pk;
2825 PKT_user_id *uid;
2826 KBNODE node;
2827 u32 keyid[2];
2829 if( count_selected_keys( sec_keyblock ) ) {
2830 tty_printf(_("Please remove selections from the secret keys.\n"));
2831 return 0;
2834 n1 = count_selected_keys( pub_keyblock );
2835 if( n1 > 1 ) {
2836 tty_printf(_("Please select at most one secondary key.\n"));
2837 return 0;
2839 else if( n1 )
2840 tty_printf(_("Changing expiration time for a secondary key.\n"));
2841 else {
2842 tty_printf(_("Changing expiration time for the primary key.\n"));
2843 mainkey=1;
2846 no_primary_warning(pub_keyblock,0);
2848 expiredate = ask_expiredate();
2849 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2850 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2852 /* Now we can actually change the self signature(s) */
2853 main_pk = sub_pk = NULL;
2854 uid = NULL;
2855 signumber = 0;
2856 for( node=pub_keyblock; node; node = node->next ) {
2857 if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2858 main_pk = node->pkt->pkt.public_key;
2859 keyid_from_pk( main_pk, keyid );
2860 main_pk->expiredate = expiredate;
2862 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2863 && (node->flag & NODFLG_SELKEY ) ) {
2864 sub_pk = node->pkt->pkt.public_key;
2865 sub_pk->expiredate = expiredate;
2867 else if( node->pkt->pkttype == PKT_USER_ID )
2868 uid = node->pkt->pkt.user_id;
2869 else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
2870 && ( mainkey || sub_pk ) ) {
2871 PKT_signature *sig = node->pkt->pkt.signature;
2872 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2873 && ( (mainkey && uid
2874 && uid->created && (sig->sig_class&~3) == 0x10)
2875 || (!mainkey && sig->sig_class == 0x18) ) ) {
2876 /* this is a selfsignature which is to be replaced */
2877 PKT_signature *newsig;
2878 PACKET *newpkt;
2879 KBNODE sn;
2880 int signumber2 = 0;
2882 signumber++;
2884 if( (mainkey && main_pk->version < 4)
2885 || (!mainkey && sub_pk->version < 4 ) ) {
2886 log_info(_(
2887 "You can't change the expiration date of a v3 key\n"));
2888 free_secret_key( sk );
2889 return 0;
2892 /* find the corresponding secret self-signature */
2893 for( sn=sec_keyblock; sn; sn = sn->next ) {
2894 if( sn->pkt->pkttype == PKT_SIGNATURE ) {
2895 PKT_signature *b = sn->pkt->pkt.signature;
2896 if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
2897 && sig->sig_class == b->sig_class
2898 && ++signumber2 == signumber )
2899 break;
2902 if( !sn )
2903 log_info(_("No corresponding signature in secret ring\n"));
2905 if( mainkey )
2906 rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
2907 sk, keygen_add_key_expire, main_pk);
2908 else
2909 rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
2910 sk, keygen_add_key_expire, sub_pk );
2911 if( rc ) {
2912 log_error("make_keysig_packet failed: %s\n",
2913 gpg_strerror (rc));
2914 free_secret_key( sk );
2915 return 0;
2917 /* replace the packet */
2918 newpkt = xcalloc (1, sizeof *newpkt );
2919 newpkt->pkttype = PKT_SIGNATURE;
2920 newpkt->pkt.signature = newsig;
2921 free_packet( node->pkt );
2922 xfree ( node->pkt );
2923 node->pkt = newpkt;
2924 if( sn ) {
2925 newpkt = xcalloc (1, sizeof *newpkt );
2926 newpkt->pkttype = PKT_SIGNATURE;
2927 newpkt->pkt.signature = copy_signature( NULL, newsig );
2928 free_packet( sn->pkt );
2929 xfree ( sn->pkt );
2930 sn->pkt = newpkt;
2932 sub_pk = NULL;
2937 free_secret_key( sk );
2938 update_trust=1;
2939 return 1;
2942 static int
2943 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
2945 byte buf[1];
2947 /* first clear all primary uid flags so that we are sure none are
2948 * lingering around */
2949 delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
2950 delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
2952 /* if opaque is set,we want to set the primary id */
2953 if (opaque) {
2954 buf[0] = 1;
2955 build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
2958 return 0;
2963 * Set the primary uid flag for the selected UID. We will also reset
2964 * all other primary uid flags. For this to work with have to update
2965 * all the signature timestamps. If we would do this with the current
2966 * time, we lose quite a lot of information, so we use a a kludge to
2967 * do this: Just increment the timestamp by one second which is
2968 * sufficient to updated a signature during import.
2970 static int
2971 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
2973 PKT_secret_key *sk; /* copy of the main sk */
2974 PKT_public_key *main_pk;
2975 PKT_user_id *uid;
2976 KBNODE node;
2977 u32 keyid[2];
2978 int selected;
2979 int attribute = 0;
2980 int modified = 0;
2982 if ( count_selected_uids (pub_keyblock) != 1 ) {
2983 tty_printf(_("Please select exactly one user ID.\n"));
2984 return 0;
2987 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2988 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2990 /* Now we can actually change the self signature(s) */
2991 main_pk = NULL;
2992 uid = NULL;
2993 selected = 0;
2995 /* Is our selected uid an attribute packet? */
2996 for ( node=pub_keyblock; node; node = node->next )
2997 if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
2998 attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3000 for ( node=pub_keyblock; node; node = node->next ) {
3001 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3002 break; /* ready */
3004 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3005 main_pk = node->pkt->pkt.public_key;
3006 keyid_from_pk( main_pk, keyid );
3008 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3009 uid = node->pkt->pkt.user_id;
3010 selected = node->flag & NODFLG_SELUID;
3012 else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3013 PKT_signature *sig = node->pkt->pkt.signature;
3014 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3015 && (uid && (sig->sig_class&~3) == 0x10)
3016 && attribute == (uid->attrib_data!=NULL)) {
3017 if(sig->version < 4) {
3018 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3020 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3021 user);
3022 xfree (user);
3024 else {
3025 /* This is a selfsignature which is to be replaced.
3026 We can just ignore v3 signatures because they are
3027 not able to carry the primary ID flag. We also
3028 ignore self-sigs on user IDs that are not of the
3029 same type that we are making primary. That is, if
3030 we are making a user ID primary, we alter user IDs.
3031 If we are making an attribute packet primary, we
3032 alter attribute packets. */
3034 /* FIXME: We must make sure that we only have one
3035 self-signature per user ID here (not counting
3036 revocations) */
3037 PKT_signature *newsig;
3038 PACKET *newpkt;
3039 const byte *p;
3040 int action;
3042 /* see whether this signature has the primary UID flag */
3043 p = parse_sig_subpkt (sig->hashed,
3044 SIGSUBPKT_PRIMARY_UID, NULL );
3045 if ( !p )
3046 p = parse_sig_subpkt (sig->unhashed,
3047 SIGSUBPKT_PRIMARY_UID, NULL );
3048 if ( p && *p ) /* yes */
3049 action = selected? 0 : -1;
3050 else /* no */
3051 action = selected? 1 : 0;
3053 if (action) {
3054 int rc = update_keysig_packet (&newsig, sig,
3055 main_pk, uid, NULL,
3057 change_primary_uid_cb,
3058 action > 0? "x":NULL );
3059 if( rc ) {
3060 log_error ("update_keysig_packet failed: %s\n",
3061 gpg_strerror (rc));
3062 free_secret_key( sk );
3063 return 0;
3065 /* replace the packet */
3066 newpkt = xcalloc (1, sizeof *newpkt );
3067 newpkt->pkttype = PKT_SIGNATURE;
3068 newpkt->pkt.signature = newsig;
3069 free_packet( node->pkt );
3070 xfree ( node->pkt );
3071 node->pkt = newpkt;
3072 modified = 1;
3079 free_secret_key( sk );
3080 return modified;
3085 * Set preferences to new values for the selected user IDs
3087 static int
3088 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3090 PKT_secret_key *sk; /* copy of the main sk */
3091 PKT_public_key *main_pk;
3092 PKT_user_id *uid;
3093 KBNODE node;
3094 u32 keyid[2];
3095 int selected, select_all;
3096 int modified = 0;
3098 no_primary_warning(pub_keyblock,1);
3100 select_all = !count_selected_uids (pub_keyblock);
3102 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3103 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3105 /* Now we can actually change the self signature(s) */
3106 main_pk = NULL;
3107 uid = NULL;
3108 selected = 0;
3109 for ( node=pub_keyblock; node; node = node->next ) {
3110 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3111 break; /* ready */
3113 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3114 main_pk = node->pkt->pkt.public_key;
3115 keyid_from_pk( main_pk, keyid );
3117 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3118 uid = node->pkt->pkt.user_id;
3119 selected = select_all || (node->flag & NODFLG_SELUID);
3121 else if ( main_pk && uid && selected
3122 && node->pkt->pkttype == PKT_SIGNATURE ) {
3123 PKT_signature *sig = node->pkt->pkt.signature;
3124 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3125 && (uid && (sig->sig_class&~3) == 0x10) ) {
3126 if( sig->version < 4 ) {
3127 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3129 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3130 user);
3131 xfree (user);
3133 else {
3134 /* This is a selfsignature which is to be replaced
3135 * We have to ignore v3 signatures because they are
3136 * not able to carry the preferences */
3137 PKT_signature *newsig;
3138 PACKET *newpkt;
3139 int rc;
3141 rc = update_keysig_packet (&newsig, sig,
3142 main_pk, uid, NULL,
3144 keygen_upd_std_prefs,
3145 NULL );
3146 if( rc ) {
3147 log_error ("update_keysig_packet failed: %s\n",
3148 gpg_strerror (rc));
3149 free_secret_key( sk );
3150 return 0;
3152 /* replace the packet */
3153 newpkt = xcalloc (1, sizeof *newpkt );
3154 newpkt->pkttype = PKT_SIGNATURE;
3155 newpkt->pkt.signature = newsig;
3156 free_packet( node->pkt );
3157 xfree ( node->pkt );
3158 node->pkt = newpkt;
3159 modified = 1;
3165 free_secret_key( sk );
3166 return modified;
3171 static int
3172 menu_set_keyserver_url (KBNODE pub_keyblock, KBNODE sec_keyblock )
3174 PKT_secret_key *sk; /* copy of the main sk */
3175 PKT_public_key *main_pk;
3176 PKT_user_id *uid;
3177 KBNODE node;
3178 u32 keyid[2];
3179 int selected, select_all;
3180 int modified = 0;
3181 char *answer;
3183 no_primary_warning(pub_keyblock,1);
3185 answer=cpr_get_utf8("keyedit.add_keyserver",
3186 _("Enter your preferred keyserver URL: "));
3187 if(answer[0]=='\0' || answer[0]=='\004')
3189 xfree(answer);
3190 return 0;
3193 select_all = !count_selected_uids (pub_keyblock);
3195 node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3196 sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3198 /* Now we can actually change the self signature(s) */
3199 main_pk = NULL;
3200 uid = NULL;
3201 selected = 0;
3202 for ( node=pub_keyblock; node; node = node->next ) {
3203 if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3204 break; /* ready */
3206 if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3207 main_pk = node->pkt->pkt.public_key;
3208 keyid_from_pk( main_pk, keyid );
3210 else if ( node->pkt->pkttype == PKT_USER_ID ) {
3211 uid = node->pkt->pkt.user_id;
3212 selected = select_all || (node->flag & NODFLG_SELUID);
3214 else if ( main_pk && uid && selected
3215 && node->pkt->pkttype == PKT_SIGNATURE ) {
3216 PKT_signature *sig = node->pkt->pkt.signature;
3217 if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3218 && (uid && (sig->sig_class&~3) == 0x10) ) {
3219 if( sig->version < 4 ) {
3220 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3222 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3223 user);
3224 xfree(user);
3226 else {
3227 /* This is a selfsignature which is to be replaced
3228 * We have to ignore v3 signatures because they are
3229 * not able to carry the preferences */
3230 PKT_signature *newsig;
3231 PACKET *newpkt;
3232 int rc;
3234 rc = update_keysig_packet (&newsig, sig,
3235 main_pk, uid, NULL,
3237 keygen_add_keyserver_url,
3238 answer );
3239 if( rc ) {
3240 log_error ("update_keysig_packet failed: %s\n",
3241 gpg_strerror (rc));
3242 xfree(answer);
3243 free_secret_key( sk );
3244 return 0;
3246 /* replace the packet */
3247 newpkt = xcalloc (1, sizeof *newpkt );
3248 newpkt->pkttype = PKT_SIGNATURE;
3249 newpkt->pkt.signature = newsig;
3250 free_packet( node->pkt );
3251 xfree (node->pkt);
3252 node->pkt = newpkt;
3253 modified = 1;
3259 xfree(answer);
3260 free_secret_key( sk );
3261 return modified;
3265 /****************
3266 * Select one user id or remove all selection if index is 0.
3267 * Returns: True if the selection changed;
3269 static int
3270 menu_select_uid( KBNODE keyblock, int idx )
3272 KBNODE node;
3273 int i;
3275 /* first check that the index is valid */
3276 if( idx ) {
3277 for( i=0, node = keyblock; node; node = node->next ) {
3278 if( node->pkt->pkttype == PKT_USER_ID ) {
3279 if( ++i == idx )
3280 break;
3283 if( !node ) {
3284 tty_printf(_("No user ID with index %d\n"), idx );
3285 return 0;
3288 else { /* reset all */
3289 for( i=0, node = keyblock; node; node = node->next ) {
3290 if( node->pkt->pkttype == PKT_USER_ID )
3291 node->flag &= ~NODFLG_SELUID;
3293 return 1;
3295 /* and toggle the new index */
3296 for( i=0, node = keyblock; node; node = node->next ) {
3297 if( node->pkt->pkttype == PKT_USER_ID ) {
3298 if( ++i == idx ) {
3299 if( (node->flag & NODFLG_SELUID) )
3300 node->flag &= ~NODFLG_SELUID;
3301 else
3302 node->flag |= NODFLG_SELUID;
3307 return 1;
3310 /****************
3311 * Select secondary keys
3312 * Returns: True if the selection changed;
3314 static int
3315 menu_select_key( KBNODE keyblock, int idx )
3317 KBNODE node;
3318 int i;
3320 /* first check that the index is valid */
3321 if( idx ) {
3322 for( i=0, node = keyblock; node; node = node->next ) {
3323 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3324 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3325 if( ++i == idx )
3326 break;
3329 if( !node ) {
3330 tty_printf(_("No secondary key with index %d\n"), idx );
3331 return 0;
3334 else { /* reset all */
3335 for( i=0, node = keyblock; node; node = node->next ) {
3336 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3337 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3338 node->flag &= ~NODFLG_SELKEY;
3340 return 1;
3342 /* and set the new index */
3343 for( i=0, node = keyblock; node; node = node->next ) {
3344 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3345 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3346 if( ++i == idx ) {
3347 if( (node->flag & NODFLG_SELKEY) )
3348 node->flag &= ~NODFLG_SELKEY;
3349 else
3350 node->flag |= NODFLG_SELKEY;
3355 return 1;
3359 static int
3360 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3362 KBNODE node;
3363 int i=0;
3365 for( node = keyblock; node; node = node->next )
3366 if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3367 i++;
3368 return i;
3371 static int
3372 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3374 KBNODE node;
3375 int i=0;
3377 for( node = keyblock; node; node = node->next )
3378 if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3379 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3380 && (node->flag & flag) )
3381 i++;
3382 return i;
3385 static int
3386 count_uids( KBNODE keyblock )
3388 KBNODE node;
3389 int i=0;
3391 for( node = keyblock; node; node = node->next )
3392 if( node->pkt->pkttype == PKT_USER_ID )
3393 i++;
3394 return i;
3398 /****************
3399 * Returns true if there is at least one selected user id
3401 static int
3402 count_selected_uids( KBNODE keyblock )
3404 return count_uids_with_flag( keyblock, NODFLG_SELUID);
3407 static int
3408 count_selected_keys( KBNODE keyblock )
3410 return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3413 /* returns how many real (i.e. not attribute) uids are unmarked */
3414 static int
3415 real_uids_left( KBNODE keyblock )
3417 KBNODE node;
3418 int real=0;
3420 for(node=keyblock;node;node=node->next)
3421 if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3422 !node->pkt->pkt.user_id->attrib_data)
3423 real++;
3425 return real;
3429 * Ask whether the signature should be revoked. If the user commits this,
3430 * flag bit MARK_A is set on the signature and the user ID.
3432 static void
3433 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3435 int doit=0;
3436 PKT_signature *sig = node->pkt->pkt.signature;
3437 KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3439 if( !unode ) {
3440 log_error("Oops: no user ID for signature\n");
3441 return;
3444 tty_printf(_("user ID: \""));
3445 tty_print_utf8_string( unode->pkt->pkt.user_id->name,
3446 unode->pkt->pkt.user_id->len );
3448 if(sig->flags.exportable)
3449 tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
3450 (ulong)sig->keyid[1], datestr_from_sig(sig) );
3451 else
3452 tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"),
3453 (ulong)sig->keyid[1], datestr_from_sig(sig) );
3455 if(sig->flags.expired)
3457 tty_printf(_("This signature expired on %s.\n"),
3458 expirestr_from_sig(sig));
3459 /* Use a different question so we can have different help text */
3460 doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3461 _("Are you sure you still want to revoke it? (y/N) "));
3463 else
3464 doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3465 _("Create a revocation certificate for this signature? (y/N) "));
3467 if(doit) {
3468 node->flag |= NODFLG_MARK_A;
3469 unode->flag |= NODFLG_MARK_A;
3473 /****************
3474 * Display all user ids of the current public key together with signatures
3475 * done by one of our keys. Then walk over all this sigs and ask the user
3476 * whether he wants to revoke this signature.
3477 * Return: True when the keyblock has changed.
3479 static int
3480 menu_revsig( KBNODE keyblock )
3482 PKT_signature *sig;
3483 PKT_public_key *primary_pk;
3484 KBNODE node;
3485 int changed = 0;
3486 int rc, any, skip=1, all=!count_selected_uids(keyblock);
3487 struct revocation_reason_info *reason = NULL;
3489 /* FIXME: detect duplicates here */
3490 tty_printf(_("You have signed these user IDs:\n"));
3491 for( node = keyblock; node; node = node->next ) {
3492 node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
3493 if( node->pkt->pkttype == PKT_USER_ID ) {
3494 if( node->flag&NODFLG_SELUID || all ) {
3495 PKT_user_id *uid = node->pkt->pkt.user_id;
3496 /* Hmmm: Should we show only UIDs with a signature? */
3497 tty_printf(" ");
3498 tty_print_utf8_string( uid->name, uid->len );
3499 tty_printf("\n");
3500 skip=0;
3502 else
3503 skip=1;
3505 else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
3506 && ((sig = node->pkt->pkt.signature),
3507 !seckey_available(sig->keyid) ) ) {
3508 if( (sig->sig_class&~3) == 0x10 ) {
3509 tty_printf(_(" signed by %08lX at %s%s%s\n"),
3510 (ulong)sig->keyid[1], datestr_from_sig(sig),
3511 sig->flags.exportable?"":" (non-exportable)",
3512 sig->flags.revocable?"":" (non-revocable)");
3513 if(sig->flags.revocable)
3514 node->flag |= NODFLG_SELSIG;
3516 else if( sig->sig_class == 0x30 ) {
3517 tty_printf(_(" revoked by %08lX at %s\n"),
3518 (ulong)sig->keyid[1], datestr_from_sig(sig) );
3523 /* ask */
3524 for( node = keyblock; node; node = node->next ) {
3525 if( !(node->flag & NODFLG_SELSIG) )
3526 continue;
3527 ask_revoke_sig( keyblock, node );
3530 /* present selected */
3531 any = 0;
3532 for( node = keyblock; node; node = node->next ) {
3533 if( !(node->flag & NODFLG_MARK_A) )
3534 continue;
3535 if( !any ) {
3536 any = 1;
3537 tty_printf(_("You are about to revoke these signatures:\n"));
3539 if( node->pkt->pkttype == PKT_USER_ID ) {
3540 PKT_user_id *uid = node->pkt->pkt.user_id;
3541 tty_printf(" ");
3542 tty_print_utf8_string( uid->name, uid->len );
3543 tty_printf("\n");
3545 else if( node->pkt->pkttype == PKT_SIGNATURE ) {
3546 sig = node->pkt->pkt.signature;
3547 tty_printf(_(" signed by %08lX at %s%s\n"),
3548 (ulong)sig->keyid[1], datestr_from_sig(sig),
3549 sig->flags.exportable?"":_(" (non-exportable)") );
3552 if( !any )
3553 return 0; /* none selected */
3555 if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
3556 _("Really create the revocation certificates? (y/N) ")) )
3557 return 0; /* forget it */
3559 reason = ask_revocation_reason( 0, 1, 0 );
3560 if( !reason ) { /* user decided to cancel */
3561 return 0;
3564 /* now we can sign the user ids */
3565 reloop: /* (must use this, because we are modifing the list) */
3566 primary_pk = keyblock->pkt->pkt.public_key;
3567 for( node=keyblock; node; node = node->next ) {
3568 KBNODE unode;
3569 PACKET *pkt;
3570 struct sign_attrib attrib;
3571 PKT_secret_key *sk;
3573 if( !(node->flag & NODFLG_MARK_A)
3574 || node->pkt->pkttype != PKT_SIGNATURE )
3575 continue;
3576 unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3577 assert( unode ); /* we already checked this */
3579 memset( &attrib, 0, sizeof attrib );
3580 attrib.reason = reason;
3581 attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
3583 node->flag &= ~NODFLG_MARK_A;
3584 sk = xcalloc_secure (1, sizeof *sk );
3585 if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
3586 log_info(_("no secret key\n"));
3587 continue;
3589 rc = make_keysig_packet( &sig, primary_pk,
3590 unode->pkt->pkt.user_id,
3591 NULL,
3593 0x30, 0, 0, 0, 0,
3594 sign_mk_attrib,
3595 &attrib );
3596 free_secret_key(sk);
3597 if( rc ) {
3598 log_error(_("signing failed: %s\n"), gpg_strerror (rc));
3599 release_revocation_reason_info( reason );
3600 return changed;
3602 changed = 1; /* we changed the keyblock */
3603 update_trust = 1;
3604 /* Are we revoking our own uid? */
3605 if(primary_pk->keyid[0]==sig->keyid[0] &&
3606 primary_pk->keyid[1]==sig->keyid[1])
3607 unode->pkt->pkt.user_id->is_revoked=1;
3608 pkt = xcalloc (1, sizeof *pkt );
3609 pkt->pkttype = PKT_SIGNATURE;
3610 pkt->pkt.signature = sig;
3611 insert_kbnode( unode, new_kbnode(pkt), 0 );
3612 goto reloop;
3615 release_revocation_reason_info( reason );
3616 return changed;
3619 /* Revoke a user ID (i.e. revoke a user ID selfsig). Return true if
3620 keyblock changed. */
3621 static int
3622 menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3624 PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
3625 PKT_secret_key *sk = copy_secret_key( NULL,
3626 sec_keyblock->pkt->pkt.secret_key );
3627 KBNODE node;
3628 int changed = 0;
3629 int rc;
3630 struct revocation_reason_info *reason = NULL;
3632 /* Note that this is correct as per the RFCs, but nevertheless
3633 somewhat meaningless in the real world. 1991 did define the 0x30
3634 sig class, but PGP 2.x did not actually implement it, so it would
3635 probably be safe to use v4 revocations everywhere. -ds */
3637 for( node = pub_keyblock; node; node = node->next )
3638 if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
3639 node->pkt->pkt.user_id->selfsigversion>3))
3641 if((reason = ask_revocation_reason( 0, 1, 4 )))
3642 break;
3643 else
3644 goto leave;
3647 reloop: /* (better this way because we are modifing the keyring) */
3648 for( node = pub_keyblock; node; node = node->next )
3649 if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
3651 PKT_user_id *uid=node->pkt->pkt.user_id;
3653 if(uid->is_revoked)
3655 char *user=utf8_to_native(uid->name,uid->len,0);
3656 log_info(_("user ID \"%s\" is already revoked\n"),user);
3657 xfree (user);
3659 else
3661 PACKET *pkt;
3662 PKT_signature *sig;
3663 struct sign_attrib attrib;
3664 u32 timestamp=make_timestamp();
3666 if(uid->created>=timestamp)
3668 /* Okay, this is a problem. The user ID selfsig was
3669 created in the future, so we need to warn the user and
3670 set our revocation timestamp one second after that so
3671 everything comes out clean. */
3673 log_info(_("WARNING: a user ID signature is dated %d"
3674 " seconds in the future\n"),uid->created-timestamp);
3676 timestamp=uid->created+1;
3679 memset( &attrib, 0, sizeof attrib );
3680 attrib.reason = reason;
3682 node->flag &= ~NODFLG_SELUID;
3684 rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
3685 (reason==NULL)?3:0, timestamp, 0,
3686 sign_mk_attrib, &attrib );
3687 if( rc )
3689 log_error(_("signing failed: %s\n"), gpg_strerror (rc));
3690 goto leave;
3692 else
3694 pkt = xcalloc (1, sizeof *pkt );
3695 pkt->pkttype = PKT_SIGNATURE;
3696 pkt->pkt.signature = sig;
3697 insert_kbnode( node, new_kbnode(pkt), 0 );
3699 /* If the trustdb has an entry for this key+uid then the
3700 trustdb needs an update. */
3701 if(!update_trust
3702 && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
3703 update_trust=1;
3705 changed = 1;
3706 node->pkt->pkt.user_id->is_revoked=1;
3708 goto reloop;
3713 if(changed)
3714 commit_kbnode( &pub_keyblock );
3716 leave:
3717 free_secret_key(sk);
3718 release_revocation_reason_info( reason );
3719 return changed;
3722 /****************
3723 * Revoke some of the secondary keys.
3724 * Hmmm: Should we add a revocation to the secret keyring too?
3725 * Does its all make sense to duplicate most of the information?
3727 static int
3728 menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3730 PKT_public_key *mainpk;
3731 KBNODE node;
3732 int changed = 0;
3733 int rc;
3734 struct revocation_reason_info *reason = NULL;
3736 reason = ask_revocation_reason( 1, 0, 0 );
3737 if( !reason ) { /* user decided to cancel */
3738 return 0;
3741 reloop: /* (better this way because we are modifing the keyring) */
3742 mainpk = pub_keyblock->pkt->pkt.public_key;
3743 for( node = pub_keyblock; node; node = node->next ) {
3744 if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3745 && (node->flag & NODFLG_SELKEY) ) {
3746 PACKET *pkt;
3747 PKT_signature *sig;
3748 PKT_secret_key *sk;
3749 PKT_public_key *subpk = node->pkt->pkt.public_key;
3750 struct sign_attrib attrib;
3752 memset( &attrib, 0, sizeof attrib );
3753 attrib.reason = reason;
3755 node->flag &= ~NODFLG_SELKEY;
3756 sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
3757 rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
3758 0x28, 0, 0, 0, 0,
3759 sign_mk_attrib, &attrib );
3760 free_secret_key(sk);
3761 if( rc ) {
3762 log_error(_("signing failed: %s\n"), gpg_strerror (rc));
3763 release_revocation_reason_info( reason );
3764 return changed;
3766 changed = 1; /* we changed the keyblock */
3768 pkt = xcalloc (1, sizeof *pkt );
3769 pkt->pkttype = PKT_SIGNATURE;
3770 pkt->pkt.signature = sig;
3771 insert_kbnode( node, new_kbnode(pkt), 0 );
3772 goto reloop;
3775 commit_kbnode( &pub_keyblock );
3776 /*commit_kbnode( &sec_keyblock );*/
3778 /* No need to set update_trust here since signing keys no longer
3779 are used to certify other keys, so there is no change in trust
3780 when revoking/removing them */
3782 release_revocation_reason_info( reason );
3783 return changed;
3786 /* Note that update_ownertrust is going to mark the trustdb dirty when
3787 enabling or disabling a key. This is arguably sub-optimal as
3788 disabled keys are still counted in the web of trust, but perhaps
3789 not worth adding extra complexity to change. -ds */
3790 static int
3791 enable_disable_key( KBNODE keyblock, int disable )
3793 PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
3794 ->pkt->pkt.public_key;
3795 unsigned int trust, newtrust;
3797 trust = newtrust = get_ownertrust (pk);
3798 newtrust &= ~TRUST_FLAG_DISABLED;
3799 if( disable )
3800 newtrust |= TRUST_FLAG_DISABLED;
3801 if( trust == newtrust )
3802 return 0; /* already in that state */
3803 update_ownertrust(pk, newtrust );
3804 return 0;
3808 static void
3809 menu_showphoto( KBNODE keyblock )
3811 KBNODE node;
3812 int select_all = !count_selected_uids(keyblock);
3813 int count=0;
3814 PKT_public_key *pk=NULL;
3815 u32 keyid[2];
3817 /* Look for the public key first. We have to be really, really,
3818 explicit as to which photo this is, and what key it is a UID on
3819 since people may want to sign it. */
3821 for( node = keyblock; node; node = node->next )
3823 if( node->pkt->pkttype == PKT_PUBLIC_KEY )
3825 pk = node->pkt->pkt.public_key;
3826 keyid_from_pk(pk, keyid);
3828 else if( node->pkt->pkttype == PKT_USER_ID )
3830 PKT_user_id *uid = node->pkt->pkt.user_id;
3831 count++;
3833 if((select_all || (node->flag & NODFLG_SELUID)) &&
3834 uid->attribs!=NULL)
3836 int i;
3838 for(i=0;i<uid->numattribs;i++)
3840 byte type;
3841 u32 size;
3843 if(uid->attribs[i].type==ATTRIB_IMAGE &&
3844 parse_image_header(&uid->attribs[i],&type,&size))
3846 tty_printf(_("Displaying %s photo ID of size %ld for "
3847 "key 0x%08lX (uid %d)\n"),
3848 image_type_to_string(type,1),
3849 (ulong)size,(ulong)keyid[1],count);
3850 show_photos(&uid->attribs[i],1,pk,NULL);