* build-packet.c (build_sig_subpkt): Comments.
[gnupg.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3  *               2003 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
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.
11  *
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.
16  *
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
20  */
21
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>
29
30 #include "options.h"
31 #include "packet.h"
32 #include "errors.h"
33 #include "iobuf.h"
34 #include "keydb.h"
35 #include "memory.h"
36 #include "photoid.h"
37 #include "util.h"
38 #include "main.h"
39 #include "trustdb.h"
40 #include "filter.h"
41 #include "ttyio.h"
42 #include "status.h"
43 #include "i18n.h"
44
45 static void show_prefs( PKT_user_id *uid, int verbose );
46 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
47             int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
48 static void show_key_and_fingerprint( KBNODE keyblock );
49 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
50 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
51 static int  menu_delsig( KBNODE pub_keyblock );
52 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
53 static int menu_addrevoker( KBNODE pub_keyblock,
54                             KBNODE sec_keyblock, int sensitive );
55 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
56 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
57 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
58 static int menu_select_uid( KBNODE keyblock, int idx );
59 static int menu_select_key( KBNODE keyblock, int idx );
60 static int count_uids( KBNODE keyblock );
61 static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
62 static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
63 static int count_selected_uids( KBNODE keyblock );
64 static int real_uids_left( KBNODE keyblock );
65 static int count_selected_keys( KBNODE keyblock );
66 static int menu_revsig( KBNODE keyblock );
67 static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
68 static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
69 static int enable_disable_key( KBNODE keyblock, int disable );
70 static void menu_showphoto( KBNODE keyblock );
71
72 static int update_trust=0;
73
74 #define CONTROL_D ('D' - 'A' + 1)
75
76 #define NODFLG_BADSIG (1<<0)  /* bad signature */
77 #define NODFLG_NOKEY  (1<<1)  /* no public key */
78 #define NODFLG_SIGERR (1<<2)  /* other sig error */
79
80 #define NODFLG_MARK_A (1<<4)  /* temporary mark */
81 #define NODFLG_DELSIG (1<<5)  /* to be deleted */
82
83 #define NODFLG_SELUID (1<<8)  /* indicate the selected userid */
84 #define NODFLG_SELKEY (1<<9)  /* indicate the selected key */
85 #define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
86
87 struct sign_attrib {
88     int non_exportable,non_revocable;
89     struct revocation_reason_info *reason;
90     byte trust_depth,trust_value;
91     char *trust_regexp;
92 };
93
94 /****************
95  * Print information about a signature, check it and return true
96  * if the signature is okay. NODE must be a signature packet.
97  */
98 static int
99 print_and_check_one_sig( KBNODE keyblock, KBNODE node,
100                          int *inv_sigs, int *no_key, int *oth_err,
101                         int *is_selfsig, int print_without_key )
102 {
103     PKT_signature *sig = node->pkt->pkt.signature;
104     int rc, sigrc;
105     int is_rev = sig->sig_class == 0x30;
106
107     /* TODO: Make sure a cached sig record here still has the pk that
108        issued it.  See also keylist.c:list_keyblock_print */
109
110     switch( (rc = check_key_signature( keyblock, node, is_selfsig)) ) {
111       case 0:
112         node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
113         sigrc = '!';
114         break;
115       case G10ERR_BAD_SIGN:
116         node->flag = NODFLG_BADSIG;
117         sigrc = '-';
118         if( inv_sigs )
119             ++*inv_sigs;
120         break;
121       case G10ERR_NO_PUBKEY:
122       case G10ERR_UNU_PUBKEY:
123         node->flag = NODFLG_NOKEY;
124         sigrc = '?';
125         if( no_key )
126             ++*no_key;
127         break;
128       default:
129         node->flag = NODFLG_SIGERR;
130         sigrc = '%';
131         if( oth_err )
132             ++*oth_err;
133         break;
134     }
135     if( sigrc != '?' || print_without_key ) {
136         tty_printf("%s%c%c %c%c%c%c%c%c %08lX %s   ",
137                    is_rev? "rev":"sig",sigrc,
138                    (sig->sig_class-0x10>0 &&
139                     sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
140                    sig->flags.exportable?' ':'L',
141                    sig->flags.revocable?' ':'R',
142                    sig->flags.policy_url?'P':' ',
143                    sig->flags.notation?'N':' ',
144                    sig->flags.expired?'X':' ',
145                    (sig->trust_depth>9)?'T':
146                    (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
147                    (ulong)sig->keyid[1], datestr_from_sig(sig));
148         if( sigrc == '%' )
149             tty_printf("[%s] ", g10_errstr(rc) );
150         else if( sigrc == '?' )
151             ;
152         else if( *is_selfsig ) {
153             tty_printf( is_rev? _("[revocation]")
154                               : _("[self-signature]") );
155         }
156         else {
157             size_t n;
158             char *p = get_user_id( sig->keyid, &n );
159             tty_print_utf8_string2( p, n, 40 );
160             m_free(p);
161         }
162         tty_printf("\n");
163
164         if(sig->flags.policy_url && opt.show_policy_url)
165           show_policy_url(sig,3);
166
167         if(sig->flags.notation && opt.show_notation)
168           show_notation(sig,3);
169     }
170
171     return (sigrc == '!');
172 }
173
174
175
176 /****************
177  * Check the keysigs and set the flags to indicate errors.
178  * Returns true if error found.
179  */
180 static int
181 check_all_keysigs( KBNODE keyblock, int only_selected )
182 {
183     KBNODE kbctx;
184     KBNODE node;
185     int inv_sigs = 0;
186     int no_key = 0;
187     int oth_err = 0;
188     int has_selfsig = 0;
189     int mis_selfsig = 0;
190     int selected = !only_selected;
191     int anyuid = 0;
192
193     for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
194         if( node->pkt->pkttype == PKT_USER_ID ) {
195             PKT_user_id *uid = node->pkt->pkt.user_id;
196
197             if( only_selected )
198                 selected = (node->flag & NODFLG_SELUID);
199             if( selected ) {
200                 tty_printf("uid  ");
201                 tty_print_utf8_string( uid->name, uid->len );
202                 tty_printf("\n");
203                 if( anyuid && !has_selfsig )
204                     mis_selfsig++;
205                 has_selfsig = 0;
206                 anyuid = 1;
207             }
208         }
209         else if( selected && node->pkt->pkttype == PKT_SIGNATURE
210                  && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
211                      || node->pkt->pkt.signature->sig_class == 0x30 )  ) {
212             int selfsig;
213
214             if( print_and_check_one_sig( keyblock, node, &inv_sigs,
215                                         &no_key, &oth_err, &selfsig, 0 ) ) {
216                 if( selfsig )
217                     has_selfsig = 1;
218             }
219             /* Hmmm: should we update the trustdb here? */
220         }
221     }
222     if( !has_selfsig )
223         mis_selfsig++;
224     if( inv_sigs == 1 )
225         tty_printf(_("1 bad signature\n") );
226     else if( inv_sigs )
227         tty_printf(_("%d bad signatures\n"), inv_sigs );
228     if( no_key == 1 )
229         tty_printf(_("1 signature not checked due to a missing key\n") );
230     else if( no_key )
231         tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
232     if( oth_err == 1 )
233         tty_printf(_("1 signature not checked due to an error\n") );
234     else if( oth_err )
235         tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
236     if( mis_selfsig == 1 )
237         tty_printf(_("1 user ID without valid self-signature detected\n"));
238     else if( mis_selfsig  )
239         tty_printf(_("%d user IDs without valid self-signatures detected\n"),
240                                                                     mis_selfsig);
241
242     return inv_sigs || no_key || oth_err || mis_selfsig;
243 }
244
245
246
247
248 static int
249 sign_mk_attrib( PKT_signature *sig, void *opaque )
250 {
251     struct sign_attrib *attrib = opaque;
252     byte buf[8];
253
254     if( attrib->non_exportable ) {
255         buf[0] = 0; /* not exportable */
256         build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
257     }
258
259     if( attrib->non_revocable ) {
260         buf[0] = 0; /* not revocable */
261         build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
262     }
263
264     if( attrib->reason )
265         revocation_reason_build_cb( sig, attrib->reason );
266
267     if(attrib->trust_depth)
268       {
269         /* Not critical.  If someone doesn't understand trust sigs,
270            this can still be a valid regular signature. */
271         buf[0] = attrib->trust_depth;
272         buf[1] = attrib->trust_value;
273         build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
274
275         /* Critical.  If someone doesn't understands regexps, this
276            whole sig should be invalid.  Note the +1 for the length -
277            regexps are null terminated. */
278         if(attrib->trust_regexp)
279           build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
280                            attrib->trust_regexp,
281                            strlen(attrib->trust_regexp)+1);
282       }
283
284     return 0;
285 }
286
287 static void
288 trustsig_prompt(byte *trust_value,byte *trust_depth,char **regexp)
289 {
290   char *p;
291
292   *trust_value=0;
293   *trust_depth=0;
294   *regexp=NULL;
295
296   tty_printf("\n");
297   /* Same string as pkclist.c:do_edit_ownertrust */
298   tty_printf(_(
299                "Please decide how far you trust this user to correctly\n"
300                "verify other users' keys (by looking at passports,\n"
301                "checking fingerprints from different sources...)?\n\n"));
302   tty_printf (_("   (%d) I trust marginally\n"), 1);
303   tty_printf (_("   (%d) I trust fully\n"), 2);
304   tty_printf("\n");
305
306   while(*trust_value==0)
307     {
308       p = cpr_get("trustsig_prompt.trust_value",_("Your selection? "));
309       trim_spaces(p);
310       cpr_kill_prompt();
311       /* 60 and 120 are as per RFC2440 */
312       if(p[0]=='1' && !p[1])
313         *trust_value=60;
314       else if(p[0]=='2' && !p[1])
315         *trust_value=120;
316       m_free(p);
317     }
318
319   tty_printf("\n");
320
321   tty_printf(_(
322               "Please enter the depth of this trust signature.\n"
323               "A depth greater than 1 allows the key you are signing to make\n"
324               "trust signatures on your behalf.\n"));
325   tty_printf("\n");
326
327   while(*trust_depth==0)
328     {
329       p = cpr_get("trustsig_prompt.trust_depth",_("Your selection? "));
330       trim_spaces(p);
331       cpr_kill_prompt();
332       *trust_depth=atoi(p);
333       m_free(p);
334       if(*trust_depth<1 || *trust_depth>255)
335         *trust_depth=0;
336     }
337
338   tty_printf("\n");
339
340   tty_printf(_("Please enter a domain to restrict this signature, "
341                "or enter for none.\n"));
342
343   tty_printf("\n");
344
345   p=cpr_get("trustsig_prompt.trust_regexp",_("Your selection? "));
346   trim_spaces(p);
347   cpr_kill_prompt();
348
349   if(strlen(p)>0)
350     {
351       char *q=p;
352       int regexplen=100,ind;
353
354       *regexp=m_alloc(regexplen);
355
356       /* Now mangle the domain the user entered into a regexp.  To do
357          this, \-escape everything that isn't alphanumeric, and attach
358          "<[^>]+[@.]" to the front, and ">$" to the end. */
359
360       strcpy(*regexp,"<[^>]+[@.]");
361       ind=strlen(*regexp);
362
363       while(*q)
364         {
365           if(!((*q>='A' && *q<='Z')
366                || (*q>='a' && *q<='z') || (*q>='0' && *q<='9')))
367             (*regexp)[ind++]='\\';
368
369           (*regexp)[ind++]=*q;
370
371           if((regexplen-ind)<3)
372             {
373               regexplen+=100;
374               *regexp=m_realloc(*regexp,regexplen);
375             }
376
377           q++;
378         }
379
380       (*regexp)[ind]='\0';
381       strcat(*regexp,">$");
382     }
383
384   m_free(p);
385   tty_printf("\n");
386 }
387
388 /****************
389  * Loop over all locusr and and sign the uids after asking.
390  * If no user id is marked, all user ids will be signed;
391  * if some user_ids are marked those will be signed.
392  */
393 static int
394 sign_uids( KBNODE keyblock, STRLIST locusr, int *ret_modified,
395            int local, int nonrevocable, int trust )
396 {
397     int rc = 0;
398     SK_LIST sk_list = NULL;
399     SK_LIST sk_rover = NULL;
400     PKT_secret_key *sk = NULL;
401     KBNODE node, uidnode;
402     PKT_public_key *primary_pk=NULL;
403     int select_all = !count_selected_uids(keyblock);
404     int all_v3=1;
405
406     /* Are there any non-v3 sigs on this key already? */
407     if(opt.pgp2)
408       for(node=keyblock;node;node=node->next)
409         if(node->pkt->pkttype==PKT_SIGNATURE &&
410            node->pkt->pkt.signature->version>3)
411           {
412             all_v3=0;
413             break;
414           }
415
416     /* build a list of all signators.
417      *    
418      * We use the CERT flag to request the primary which must always
419      * be one which is capable of signing keys.  I can't see a reason
420      * why to sign keys using a subkey.  Implementation of USAGE_CERT
421      * is just a hack in getkey.c and does not mean that a subkey
422      * marked as certification capable will be used */
423     rc=build_sk_list( locusr, &sk_list, 0, PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT);
424     if( rc )
425         goto leave;
426
427     /* loop over all signators */
428     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
429         u32 sk_keyid[2],pk_keyid[2];
430         size_t n;
431         char *p,*trust_regexp=NULL;
432         int force_v4=0,class=0,selfsig=0;
433         u32 duration=0,timestamp=0;
434         byte trust_depth=0,trust_value=0;
435
436         if(local || nonrevocable || trust ||
437            opt.cert_policy_url || opt.cert_notation_data)
438           force_v4=1;
439
440         /* we have to use a copy of the sk, because make_keysig_packet
441          * may remove the protection from sk and if we did other
442          * changes to the secret key, we would save the unprotected
443          * version */
444         if( sk )
445             free_secret_key(sk);
446         sk = copy_secret_key( NULL, sk_rover->sk );
447         keyid_from_sk( sk, sk_keyid );
448         /* set mark A for all selected user ids */
449         for( node=keyblock; node; node = node->next ) {
450             if( select_all || (node->flag & NODFLG_SELUID) )
451                 node->flag |= NODFLG_MARK_A;
452             else
453                 node->flag &= ~NODFLG_MARK_A;
454         }
455         /* reset mark for uids which are already signed */
456         uidnode = NULL;
457         for( node=keyblock; node; node = node->next ) {
458             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
459                 primary_pk=node->pkt->pkt.public_key;
460                 keyid_from_pk( primary_pk, pk_keyid );
461
462                 /* Is this a self-sig? */
463                 if(pk_keyid[0]==sk_keyid[0] && pk_keyid[1]==sk_keyid[1])
464                   {
465                     selfsig=1;
466                     /* Do not force a v4 sig here, otherwise it would
467                        be difficult to remake a v3 selfsig.  If this
468                        is a v3->v4 promotion case, then we set
469                        force_v4 later anyway. */
470                     force_v4=0;
471                   }
472             }
473             else if( node->pkt->pkttype == PKT_USER_ID ) {
474                 uidnode = (node->flag & NODFLG_MARK_A)? node : NULL;
475                 if(uidnode)
476                   {
477                     char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
478                                               uidnode->pkt->pkt.user_id->len,
479                                               0);
480
481                     if(uidnode->pkt->pkt.user_id->is_revoked)
482                       {
483                         tty_printf(_("User ID \"%s\" is revoked."),user);
484
485                         if(opt.expert)
486                           {
487                             tty_printf("\n");
488                             /* No, so remove the mark and continue */
489                             if(!cpr_get_answer_is_yes("sign_uid.revoke_okay",
490                                                       _("Are you sure you "
491                                                         "still want to sign "
492                                                         "it? (y/N) ")))
493                               uidnode->flag &= ~NODFLG_MARK_A;
494                           }
495                         else
496                           {
497                             uidnode->flag &= ~NODFLG_MARK_A;
498                             tty_printf(_("  Unable to sign.\n"));
499                           }
500                       }
501                     else if(!uidnode->pkt->pkt.user_id->created)
502                       {
503                         tty_printf(_("WARNING: user ID \"%s\" is not "
504                                      "self-signed.\n"),user);
505                       }
506
507                     m_free(user);
508                   }
509             }
510             else if( uidnode && node->pkt->pkttype == PKT_SIGNATURE
511                 && (node->pkt->pkt.signature->sig_class&~3) == 0x10 ) {
512                 if( sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
513                     && sk_keyid[1] == node->pkt->pkt.signature->keyid[1] ) {
514                     char buf[50];
515                     char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
516                                               uidnode->pkt->pkt.user_id->len,
517                                               0);
518
519                     /* It's a v3 self-sig.  Make it into a v4 self-sig? */
520                     if(node->pkt->pkt.signature->version<4 && selfsig)
521                       {
522                         tty_printf(_("The self-signature on \"%s\"\n"
523                                      "is a PGP 2.x-style signature.\n"),user);
524  
525                         /* Note that the regular PGP2 warning below
526                            still applies if there are no v4 sigs on
527                            this key at all. */
528
529                         if(opt.expert)
530                           if(cpr_get_answer_is_yes("sign_uid.v4_promote_okay",
531                                                    _("Do you want to promote "
532                                                      "it to an OpenPGP self-"
533                                                      "signature? (y/N) ")))
534                             {
535                               force_v4=1;
536                               node->flag|=NODFLG_DELSIG;
537                               m_free(user);
538                               continue;
539                             }
540                       }
541
542                     /* Is the current signature expired? */
543                     if(node->pkt->pkt.signature->flags.expired)
544                       {
545                         tty_printf(_("Your current signature on \"%s\"\n"
546                                      "has expired.\n"),user);
547
548                         if(cpr_get_answer_is_yes("sign_uid.replace_expired_okay",
549                                                  _("Do you want to issue a "
550                                                    "new signature to replace "
551                                                    "the expired one? (y/N) ")))
552                           {
553                             /* Mark these for later deletion.  We
554                                don't want to delete them here, just in
555                                case the replacement signature doesn't
556                                happen for some reason.  We only delete
557                                these after the replacement is already
558                                in place. */
559
560                             node->flag|=NODFLG_DELSIG;
561                             m_free(user);
562                             continue;
563                           }
564                       }
565
566                     if(!node->pkt->pkt.signature->flags.exportable && !local)
567                       {
568                         /* It's a local sig, and we want to make a
569                            exportable sig. */
570                         tty_printf(_("Your current signature on \"%s\"\n"
571                                      "is a local signature.\n"),user);
572
573                         if(cpr_get_answer_is_yes("sign_uid.local_promote_okay",
574                                                  _("Do you want to promote "
575                                                    "it to a full exportable "
576                                                    "signature? (y/N) ")))
577                           {
578                             /* Mark these for later deletion.  We
579                                don't want to delete them here, just in
580                                case the replacement signature doesn't
581                                happen for some reason.  We only delete
582                                these after the replacement is already
583                                in place. */
584
585                             node->flag|=NODFLG_DELSIG;
586                             m_free(user);
587                             continue;
588                           }
589                       }
590
591                     /* Fixme: see whether there is a revocation in which
592                      * case we should allow to sign it again. */
593                     if (!node->pkt->pkt.signature->flags.exportable && local)
594                       tty_printf(_(
595                          "\"%s\" was already locally signed by key %08lX\n"),
596                                  user,(ulong)sk_keyid[1] );
597                     else
598                       tty_printf(_(
599                          "\"%s\" was already signed by key %08lX\n"),
600                                  user,(ulong)sk_keyid[1] );
601
602                     if(opt.expert
603                        && cpr_get_answer_is_yes("sign_uid.dupe_okay",
604                                                 _("Do you want to sign it "
605                                                   "again anyway? (y/N) ")))
606                       {
607                         /* Don't delete the old sig here since this is
608                            an --expert thing. */
609                         m_free(user);
610                         continue;
611                       }
612
613                     sprintf (buf, "%08lX%08lX",
614                              (ulong)sk->keyid[0], (ulong)sk->keyid[1] );
615                     write_status_text (STATUS_ALREADY_SIGNED, buf);
616                     uidnode->flag &= ~NODFLG_MARK_A; /* remove mark */
617
618                     m_free(user);
619                 }
620             }
621         }
622         /* check whether any uids are left for signing */
623         if( !count_uids_with_flag(keyblock, NODFLG_MARK_A) ) {
624             tty_printf(_("Nothing to sign with key %08lX\n"),
625                                                   (ulong)sk_keyid[1] );
626             continue;
627         }
628         /* Ask whether we really should sign these user id(s) */
629         tty_printf("\n");
630         show_key_with_all_names( keyblock, 1, 0, 1, 0, 0 );
631         tty_printf("\n");
632
633         if(primary_pk->expiredate && !selfsig)
634           {
635             u32 now=make_timestamp();
636
637             if(primary_pk->expiredate<=now)
638               {
639                 tty_printf(_("This key has expired!"));
640
641                 if(opt.expert)
642                   {
643                     tty_printf("  ");
644                     if(!cpr_get_answer_is_yes("sign_uid.expired_okay",
645                                               _("Are you sure you still "
646                                                 "want to sign it? (y/N) ")))
647                       continue;
648                   }
649                 else
650                   {
651                     tty_printf(_("  Unable to sign.\n"));
652                     continue;
653                   }
654               }
655             else
656               {
657                 char *answer;
658
659                 tty_printf(_("This key is due to expire on %s.\n"),
660                            expirestr_from_pk(primary_pk));
661
662                 answer=cpr_get("sign_uid.expire",
663                                _("Do you want your signature to "
664                                  "expire at the same time? (Y/n) "));
665                 if(answer_is_yes_no_default(answer,1))
666                   {
667                     /* This fixes the signature timestamp we're going
668                        to make as now.  This is so the expiration date
669                        is exactly correct, and not a few seconds off
670                        (due to the time it takes to answer the
671                        questions, enter the passphrase, etc). */
672                     timestamp=now;
673                     duration=primary_pk->expiredate-now;
674                     force_v4=1;
675                   }
676
677                 cpr_kill_prompt();
678                 m_free(answer);
679               }
680           }
681
682         /* Only ask for duration if we haven't already set it to match
683            the expiration of the pk */
684         if(opt.ask_cert_expire && !duration && !selfsig)
685           duration=ask_expire_interval(1);
686
687         if(duration)
688           force_v4=1;
689
690         /* Is --pgp2 on, it's a v3 key, all the sigs on the key are
691            currently v3 and we're about to sign it with a v4 sig?  If
692            so, danger! */
693         if(opt.pgp2 && all_v3 &&
694            (sk->version>3 || force_v4) && primary_pk->version<=3)
695           {
696             tty_printf(_("You may not make an OpenPGP signature on a "
697                          "PGP 2.x key while in --pgp2 mode.\n"));
698             tty_printf(_("This would make the key unusable in PGP 2.x.\n"));
699
700             if(opt.expert)
701               {
702                 if(!cpr_get_answer_is_yes("sign_uid.v4_on_v3_okay",
703                                           _("Are you sure you still "
704                                             "want to sign it? (y/N) ")))
705                   continue;
706
707                 all_v3=0;
708               }
709             else
710               continue;
711           }
712
713         if(selfsig)
714           ;
715         else
716           {
717             if(opt.batch)
718               class=0x10+opt.def_cert_check_level;
719             else
720               {
721                 char *answer;
722
723                 tty_printf(_("How carefully have you verified the key you are "
724                              "about to sign actually belongs\nto the person "
725                              "named above?  If you don't know what to "
726                              "answer, enter \"0\".\n"));
727                 tty_printf("\n");
728                 tty_printf(_("   (0) I will not answer.%s\n"),
729                            opt.def_cert_check_level==0?" (default)":"");
730                 tty_printf(_("   (1) I have not checked at all.%s\n"),
731                            opt.def_cert_check_level==1?" (default)":"");
732                 tty_printf(_("   (2) I have done casual checking.%s\n"),
733                            opt.def_cert_check_level==2?" (default)":"");
734                 tty_printf(_("   (3) I have done very careful checking.%s\n"),
735                            opt.def_cert_check_level==3?" (default)":"");
736                 tty_printf("\n");
737
738                 while(class==0)
739                   {
740                     answer = cpr_get("sign_uid.class",_("Your selection? "));
741
742                     if(answer[0]=='\0')
743                       class=0x10+opt.def_cert_check_level; /* Default */
744                     else if(ascii_strcasecmp(answer,"0")==0)
745                       class=0x10; /* Generic */
746                     else if(ascii_strcasecmp(answer,"1")==0)
747                       class=0x11; /* Persona */
748                     else if(ascii_strcasecmp(answer,"2")==0)
749                       class=0x12; /* Casual */
750                     else if(ascii_strcasecmp(answer,"3")==0)
751                       class=0x13; /* Positive */
752                     else
753                       tty_printf(_("Invalid selection.\n"));
754
755                     m_free(answer);
756                   }
757               }
758
759             if(trust)
760               trustsig_prompt(&trust_value,&trust_depth,&trust_regexp);
761           }
762
763         tty_printf(_("Are you really sure that you want to sign this key\n"
764                      "with your key: \""));
765         p = get_user_id( sk_keyid, &n );
766         tty_print_utf8_string( p, n );
767         m_free(p); p = NULL;
768         tty_printf("\"\n");
769
770         if(selfsig)
771           {
772             tty_printf(_("\nThis will be a self-signature.\n"));
773
774             if( local )
775               tty_printf(
776                          _("\nWARNING: the signature will not be marked "
777                            "as non-exportable.\n"));
778
779             if( nonrevocable )
780               tty_printf(
781                          _("\nWARNING: the signature will not be marked "
782                            "as non-revocable.\n"));
783           }
784         else
785           {
786             if( local )
787               tty_printf(
788                      _("\nThe signature will be marked as non-exportable.\n"));
789
790             if( nonrevocable )
791               tty_printf(
792                       _("\nThe signature will be marked as non-revocable.\n"));
793
794             switch(class)
795               {
796               case 0x11:
797                 tty_printf(_("\nI have not checked this key at all.\n"));
798                 break;
799
800               case 0x12:
801                 tty_printf(_("\nI have checked this key casually.\n"));
802                 break;
803
804               case 0x13:
805                 tty_printf(_("\nI have checked this key very carefully.\n"));
806                 break;
807               }
808           }
809
810         tty_printf("\n");
811
812         if( opt.batch && opt.answer_yes )
813           ;
814         else if( !cpr_get_answer_is_yes("sign_uid.okay", _("Really sign? ")) )
815             continue;
816
817         /* now we can sign the user ids */
818       reloop: /* (must use this, because we are modifing the list) */
819         primary_pk = NULL;
820         for( node=keyblock; node; node = node->next ) {
821             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
822                 primary_pk = node->pkt->pkt.public_key;
823             else if( node->pkt->pkttype == PKT_USER_ID
824                      && (node->flag & NODFLG_MARK_A) ) {
825                 PACKET *pkt;
826                 PKT_signature *sig;
827                 struct sign_attrib attrib;
828
829                 assert( primary_pk );
830                 memset( &attrib, 0, sizeof attrib );
831                 attrib.non_exportable = local;
832                 attrib.non_revocable = nonrevocable;
833                 attrib.trust_depth = trust_depth;
834                 attrib.trust_value = trust_value;
835                 attrib.trust_regexp = trust_regexp;
836                 node->flag &= ~NODFLG_MARK_A;
837
838                 /* we force creation of a v4 signature for local
839                  * signatures, otherwise we would not generate the
840                  * subpacket with v3 keys and the signature becomes
841                  * exportable */
842
843                 if(selfsig)
844                   rc = make_keysig_packet( &sig, primary_pk,
845                                            node->pkt->pkt.user_id,
846                                            NULL,
847                                            sk,
848                                            0x13, 0, force_v4?4:0, 0, 0,
849                                            keygen_add_std_prefs, primary_pk);
850                 else
851                   rc = make_keysig_packet( &sig, primary_pk,
852                                            node->pkt->pkt.user_id,
853                                            NULL,
854                                            sk,
855                                            class, 0, force_v4?4:0,
856                                            timestamp, duration,
857                                            sign_mk_attrib, &attrib );
858                 if( rc ) {
859                     log_error(_("signing failed: %s\n"), g10_errstr(rc));
860                     goto leave;
861                 }
862
863                 *ret_modified = 1; /* we changed the keyblock */
864                 update_trust = 1;
865
866                 pkt = m_alloc_clear( sizeof *pkt );
867                 pkt->pkttype = PKT_SIGNATURE;
868                 pkt->pkt.signature = sig;
869                 insert_kbnode( node, new_kbnode(pkt), PKT_SIGNATURE );
870                 goto reloop;
871             }
872         }
873
874         /* Delete any sigs that got promoted */
875         for( node=keyblock; node; node = node->next )
876           if( node->flag & NODFLG_DELSIG)
877             delete_kbnode(node);
878     } /* end loop over signators */
879
880   leave:
881     release_sk_list( sk_list );
882     if( sk )
883         free_secret_key(sk);
884     return rc;
885 }
886
887
888
889 /****************
890  * Change the passphrase of the primary and all secondary keys.
891  * We use only one passphrase for all keys.
892  */
893 static int
894 change_passphrase( KBNODE keyblock )
895 {
896     int rc = 0;
897     int changed=0;
898     KBNODE node;
899     PKT_secret_key *sk;
900     char *passphrase = NULL;
901     int no_primary_secrets = 0;
902
903     node = find_kbnode( keyblock, PKT_SECRET_KEY );
904     if( !node ) {
905         log_error("Oops; secret key not found anymore!\n");
906         goto leave;
907     }
908     sk = node->pkt->pkt.secret_key;
909
910     switch( is_secret_key_protected( sk ) ) {
911       case -1:
912         rc = G10ERR_PUBKEY_ALGO;
913         break;
914       case 0:
915         tty_printf(_("This key is not protected.\n"));
916         break;
917       default:
918         if( sk->protect.s2k.mode == 1001 ) {
919             tty_printf(_("Secret parts of primary key are not available.\n"));
920             no_primary_secrets = 1;
921         }
922         else {
923             tty_printf(_("Key is protected.\n"));
924             rc = check_secret_key( sk, 0 );
925             if( !rc )
926                 passphrase = get_last_passphrase();
927         }
928         break;
929     }
930
931     /* unprotect all subkeys (use the supplied passphrase or ask)*/
932     for(node=keyblock; !rc && node; node = node->next ) {
933         if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
934             PKT_secret_key *subsk = node->pkt->pkt.secret_key;
935             set_next_passphrase( passphrase );
936             rc = check_secret_key( subsk, 0 );
937             if( !rc && !passphrase )
938                 passphrase = get_last_passphrase();
939         }
940     }
941
942     if( rc )
943         tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
944     else {
945         DEK *dek = NULL;
946         STRING2KEY *s2k = m_alloc_secure( sizeof *s2k );
947         const char *errtext = NULL;
948
949         tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
950
951         set_next_passphrase( NULL );
952         for(;;) {
953             s2k->mode = opt.s2k_mode;
954             s2k->hash_algo = opt.s2k_digest_algo;
955             dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
956                                      s2k, 2, errtext, NULL);
957             if( !dek ) {
958                 errtext = N_("passphrase not correctly repeated; try again");
959                 tty_printf ("%s.\n", _(errtext));
960             }
961             else if( !dek->keylen ) {
962                 rc = 0;
963                 tty_printf(_( "You don't want a passphrase -"
964                             " this is probably a *bad* idea!\n\n"));
965                 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
966                                _("Do you really want to do this? ")))
967                     changed++;
968                 break;
969             }
970             else { /* okay */
971                 rc = 0;
972                 if( !no_primary_secrets ) {
973                     sk->protect.algo = dek->algo;
974                     sk->protect.s2k = *s2k;
975                     rc = protect_secret_key( sk, dek );
976                 }
977                 for(node=keyblock; !rc && node; node = node->next ) {
978                     if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
979                         PKT_secret_key *subsk = node->pkt->pkt.secret_key;
980                         subsk->protect.algo = dek->algo;
981                         subsk->protect.s2k = *s2k;
982                         rc = protect_secret_key( subsk, dek );
983                     }
984                 }
985                 if( rc )
986                     log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
987                 else
988                     changed++;
989                 break;
990             }
991         }
992         m_free(s2k);
993         m_free(dek);
994     }
995
996   leave:
997     m_free( passphrase );
998     set_next_passphrase( NULL );
999     return changed && !rc;
1000 }
1001
1002
1003 /****************
1004  * There are some keys out (due to a bug in gnupg), where the sequence
1005  * of the packets is wrong.  This function fixes that.
1006  * Returns: true if the keyblock has been fixed.
1007  *
1008  * Note:  This function does not work if there is more than one user ID.
1009  */
1010 static int
1011 fix_keyblock( KBNODE keyblock )
1012 {
1013     KBNODE node, last, subkey;
1014     int fixed=0;
1015
1016     /* locate key signatures of class 0x10..0x13 behind sub key packets */
1017     for( subkey=last=NULL, node = keyblock; node;
1018                                             last=node, node = node->next ) {
1019         switch( node->pkt->pkttype ) {
1020           case PKT_PUBLIC_SUBKEY:
1021           case PKT_SECRET_SUBKEY:
1022             if( !subkey )
1023                 subkey = last; /* actually it is the one before the subkey */
1024             break;
1025           case PKT_SIGNATURE:
1026             if( subkey ) {
1027                 PKT_signature *sig = node->pkt->pkt.signature;
1028                 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1029                     log_info(_(
1030                         "moving a key signature to the correct place\n"));
1031                     last->next = node->next;
1032                     node->next = subkey->next;
1033                     subkey->next = node;
1034                     node = last;
1035                     fixed=1;
1036                 }
1037             }
1038             break;
1039           default: break;
1040         }
1041     }
1042
1043     return fixed;
1044 }
1045
1046 /****************
1047  * Menu driven key editor.  If sign_mode is true semi-automatical signing
1048  * will be performed. commands are ignore in this case
1049  *
1050  * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1051  */
1052
1053 void
1054 keyedit_menu( const char *username, STRLIST locusr, STRLIST commands,
1055                                                     int sign_mode )
1056 {
1057     enum cmdids { cmdNONE = 0,
1058            cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1059            cmdTSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY,
1060            cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID,
1061            cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER,
1062            cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
1063            cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
1064            cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST, cmdNOP };
1065     static struct { const char *name;
1066                     enum cmdids id;
1067                     int need_sk;
1068                     int not_with_sk;
1069                     int signmode;
1070                     const char *desc;
1071                   } cmds[] = {
1072         { N_("quit")    , cmdQUIT      , 0,0,1, N_("quit this menu") },
1073         { N_("q")       , cmdQUIT      , 0,0,1, NULL   },
1074         { N_("save")    , cmdSAVE      , 0,0,1, N_("save and quit") },
1075         { N_("help")    , cmdHELP      , 0,0,1, N_("show this help") },
1076         {    "?"        , cmdHELP      , 0,0,1, NULL   },
1077         { N_("fpr")     , cmdFPR       , 0,0,1, N_("show fingerprint") },
1078         { N_("list")    , cmdLIST      , 0,0,1, N_("list key and user IDs") },
1079         { N_("l")       , cmdLIST      , 0,0,1, NULL   },
1080         { N_("uid")     , cmdSELUID    , 0,0,1, N_("select user ID N") },
1081         { N_("key")     , cmdSELKEY    , 0,0,0, N_("select secondary key N") },
1082         { N_("check")   , cmdCHECK     , 0,0,1, N_("list signatures") },
1083         { N_("c")       , cmdCHECK     , 0,0,1, NULL },
1084         { N_("sign")    , cmdSIGN      , 0,1,1, N_("sign the key") },
1085         { N_("s")       , cmdSIGN      , 0,1,1, NULL },
1086         { N_("tsign")   , cmdTSIGN     , 0,1,1, N_("make a trust signature")},
1087         { N_("lsign")   , cmdLSIGN     , 0,1,1, N_("sign the key locally") },
1088         { N_("nrsign")  , cmdNRSIGN    , 0,1,1, N_("sign the key non-revocably") },
1089         { N_("nrlsign") , cmdNRLSIGN   , 0,1,1, N_("sign the key locally and non-revocably") },
1090         { N_("debug")   , cmdDEBUG     , 0,0,0, NULL },
1091         { N_("adduid")  , cmdADDUID    , 1,1,0, N_("add a user ID") },
1092         { N_("addphoto"), cmdADDPHOTO  , 1,1,0, N_("add a photo ID") },
1093         { N_("deluid")  , cmdDELUID    , 0,1,0, N_("delete user ID") },
1094         /* delphoto is really deluid in disguise */
1095         { N_("delphoto"), cmdDELUID    , 0,1,0, NULL },
1096         { N_("addkey")  , cmdADDKEY    , 1,1,0, N_("add a secondary key") },
1097         { N_("delkey")  , cmdDELKEY    , 0,1,0, N_("delete a secondary key") },
1098         { N_("addrevoker"),cmdADDREVOKER,1,1,0, N_("add a revocation key") },
1099         { N_("delsig")  , cmdDELSIG    , 0,1,0, N_("delete signatures") },
1100         { N_("expire")  , cmdEXPIRE    , 1,1,0, N_("change the expire date") },
1101         { N_("primary") , cmdPRIMARY   , 1,1,0, N_("flag user ID as primary")},
1102         { N_("toggle")  , cmdTOGGLE    , 1,0,0, N_("toggle between secret "
1103                                                    "and public key listing") },
1104         { N_("t"     )  , cmdTOGGLE    , 1,0,0, NULL },
1105         { N_("pref")    , cmdPREF      , 0,1,0, N_("list preferences (expert)") },
1106         { N_("showpref"), cmdSHOWPREF  , 0,1,0, N_("list preferences (verbose)") },
1107         { N_("setpref") , cmdSETPREF   , 1,1,0, N_("set preference list") },
1108         { N_("updpref") , cmdUPDPREF   , 1,1,0, N_("updated preferences") },
1109         { N_("passwd")  , cmdPASSWD    , 1,1,0, N_("change the passphrase") },
1110         { N_("trust")   , cmdTRUST     , 0,1,0, N_("change the ownertrust") },
1111         { N_("revsig")  , cmdREVSIG    , 0,1,0, N_("revoke signatures") },
1112         { N_("revuid")  , cmdREVUID    , 1,1,0, N_("revoke a user ID") },
1113         { N_("revkey")  , cmdREVKEY    , 1,1,0, N_("revoke a secondary key") },
1114         { N_("disable") , cmdDISABLEKEY, 0,1,0, N_("disable a key") },
1115         { N_("enable")  , cmdENABLEKEY , 0,1,0, N_("enable a key") },
1116         { N_("showphoto"),cmdSHOWPHOTO , 0,0,0, N_("show photo ID") },
1117
1118     { NULL, cmdNONE } };
1119     enum cmdids cmd = 0;
1120     int rc = 0;
1121     KBNODE keyblock = NULL;
1122     KEYDB_HANDLE kdbhd = NULL;
1123     KBNODE sec_keyblock = NULL;
1124     KEYDB_HANDLE sec_kdbhd = NULL;
1125     KBNODE cur_keyblock;
1126     char *answer = NULL;
1127     int redisplay = 1;
1128     int modified = 0;
1129     int sec_modified = 0;
1130     int toggle;
1131     int have_commands = !!commands;
1132
1133     if ( opt.command_fd != -1 )
1134         ;
1135     else if( opt.batch && !have_commands  ) {
1136         log_error(_("can't do that in batchmode\n"));
1137         goto leave;
1138     }
1139
1140     if( sign_mode ) {
1141         commands = NULL;
1142         append_to_strlist( &commands, sign_mode == 1? "sign":
1143                            sign_mode == 2?"lsign":
1144                            sign_mode == 3?"nrsign":"nrlsign");
1145         have_commands = 1;
1146     }
1147
1148     /* get the public key */
1149     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1150     if( rc )
1151         goto leave;
1152     if( fix_keyblock( keyblock ) )
1153         modified++;
1154     if( collapse_uids( &keyblock ) )
1155         modified++;
1156     reorder_keyblock(keyblock);
1157
1158     if( !sign_mode ) {/* see whether we have a matching secret key */
1159         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1160
1161         sec_kdbhd = keydb_new (1);
1162         {
1163             byte afp[MAX_FINGERPRINT_LEN];
1164             size_t an;
1165
1166             fingerprint_from_pk (pk, afp, &an);
1167             while (an < MAX_FINGERPRINT_LEN) 
1168                 afp[an++] = 0;
1169             rc = keydb_search_fpr (sec_kdbhd, afp);
1170         }
1171         if (!rc) {
1172             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1173             if (rc) {
1174                 log_error (_("error reading secret keyblock `%s': %s\n"),
1175                                                 username, g10_errstr(rc));
1176             }
1177             else {
1178                 merge_keys_and_selfsig( sec_keyblock );
1179                 if( fix_keyblock( sec_keyblock ) )
1180                     sec_modified++;
1181             }
1182         }
1183
1184         if (rc) {
1185             sec_keyblock = NULL;
1186             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1187             rc = 0;
1188         }
1189     }
1190
1191     if( sec_keyblock ) { 
1192         tty_printf(_("Secret key is available.\n"));
1193     }
1194
1195     toggle = 0;
1196     cur_keyblock = keyblock;
1197     for(;;) { /* main loop */
1198         int i, arg_number, photo;
1199         const char *arg_string = "";
1200         char *p;
1201         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1202
1203         tty_printf("\n");
1204         if( redisplay ) {
1205             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1206             tty_printf("\n");
1207             redisplay = 0;
1208         }
1209         do {
1210             m_free(answer);
1211             if( have_commands ) {
1212                 if( commands ) {
1213                     answer = m_strdup( commands->d );
1214                     commands = commands->next;
1215                 }
1216                 else if( opt.batch ) {
1217                     answer = m_strdup("quit");
1218                 }
1219                 else
1220                     have_commands = 0;
1221             }
1222             if( !have_commands ) {
1223                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1224                 cpr_kill_prompt();
1225             }
1226             trim_spaces(answer);
1227         } while( *answer == '#' );
1228
1229         arg_number = 0; /* Yes, here is the init which egcc complains about */
1230         photo = 0; /* This too */
1231         if( !*answer )
1232             cmd = cmdLIST;
1233         else if( *answer == CONTROL_D )
1234             cmd = cmdQUIT;
1235         else if( isdigit( *answer ) ) {
1236             cmd = cmdSELUID;
1237             arg_number = atoi(answer);
1238         }
1239         else {
1240             if( (p=strchr(answer,' ')) ) {
1241                 *p++ = 0;
1242                 trim_spaces(answer);
1243                 trim_spaces(p);
1244                 arg_number = atoi(p);
1245                 arg_string = p;
1246             }
1247
1248             for(i=0; cmds[i].name; i++ ) {
1249                 if( !ascii_strcasecmp( answer, cmds[i].name ) )
1250                     break;
1251             }
1252             if( sign_mode && !cmds[i].signmode )
1253                 cmd = cmdINVCMD;
1254             else if( cmds[i].need_sk && !sec_keyblock ) {
1255                 tty_printf(_("Need the secret key to do this.\n"));
1256                 cmd = cmdNOP;
1257             }
1258             else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
1259                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1260                 cmd = cmdNOP;
1261             }
1262             else
1263                 cmd = cmds[i].id;
1264         }
1265         switch( cmd )  {
1266           case cmdHELP:
1267             for(i=0; cmds[i].name; i++ ) {
1268                 if( sign_mode && !cmds[i].signmode )
1269                     ;
1270                 else if( cmds[i].need_sk && !sec_keyblock )
1271                     ; /* skip if we do not have the secret key */
1272                 else if( cmds[i].desc )
1273                     tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1274             }
1275             break;
1276
1277           case cmdLIST:
1278             redisplay = 1;
1279             break;
1280
1281           case cmdFPR:
1282             show_key_and_fingerprint( keyblock );
1283             break;
1284
1285           case cmdSELUID:
1286             if( menu_select_uid( cur_keyblock, arg_number ) )
1287                 redisplay = 1;
1288             break;
1289
1290           case cmdSELKEY:
1291             if( menu_select_key( cur_keyblock, arg_number ) )
1292                 redisplay = 1;
1293             break;
1294
1295           case cmdCHECK:
1296             /* we can only do this with the public key becuase the
1297              * check functions can't cope with secret keys and it
1298              * is questionable whether this would make sense at all */
1299             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1300             break;
1301
1302           case cmdSIGN: /* sign (only the public key) */
1303           case cmdLSIGN: /* sign (only the public key) */
1304           case cmdNRSIGN: /* sign (only the public key) */
1305           case cmdNRLSIGN: /* sign (only the public key) */
1306           case cmdTSIGN:
1307             if( pk->is_revoked )
1308               {
1309                 tty_printf(_("Key is revoked."));
1310
1311                 if(opt.expert)
1312                   {
1313                     tty_printf("  ");
1314                     if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1315                                               _("Are you sure you still want "
1316                                                 "to sign it? (y/N) ")))
1317                       break;
1318                   }
1319                 else
1320                   {
1321                     tty_printf(_("  Unable to sign.\n"));
1322                     break;
1323                   }
1324               }
1325
1326             if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) {
1327                 if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1328                                            _("Really sign all user IDs? ")) ) {
1329                     tty_printf(_("Hint: Select the user IDs to sign\n"));
1330                     break;
1331                 }
1332             }
1333             if( !sign_uids( keyblock, locusr, &modified,
1334                             (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
1335                             (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
1336                             (cmd == cmdTSIGN))
1337                 && sign_mode )
1338                 goto do_cmd_save;
1339             break;
1340
1341           case cmdDEBUG:
1342             dump_kbnode( cur_keyblock );
1343             break;
1344
1345           case cmdTOGGLE:
1346             toggle = !toggle;
1347             cur_keyblock = toggle? sec_keyblock : keyblock;
1348             redisplay = 1;
1349             break;
1350
1351           case cmdADDPHOTO:
1352             if (opt.rfc2440 || opt.rfc1991 || opt.pgp2)
1353               {
1354                 tty_printf(
1355                    _("This command is not allowed while in %s mode.\n"),
1356                    opt.rfc2440?"OpenPGP":opt.pgp2?"PGP2":"RFC-1991");
1357                 break;
1358               }
1359             photo=1;
1360             /* fall through */
1361
1362           case cmdADDUID:
1363             if( menu_adduid( keyblock, sec_keyblock, photo ) ) {
1364                 redisplay = 1;
1365                 sec_modified = modified = 1;
1366                 merge_keys_and_selfsig( sec_keyblock );
1367                 merge_keys_and_selfsig( keyblock );
1368             }
1369             break;
1370
1371           case cmdDELUID: {
1372                 int n1;
1373
1374                 if( !(n1=count_selected_uids(keyblock)) )
1375                     tty_printf(_("You must select at least one user ID.\n"));
1376                 else if( real_uids_left(keyblock) < 1 )
1377                     tty_printf(_("You can't delete the last user ID!\n"));
1378                 else if( cpr_get_answer_is_yes(
1379                             "keyedit.remove.uid.okay",
1380                         n1 > 1? _("Really remove all selected user IDs? ")
1381                               : _("Really remove this user ID? ")
1382                        ) ) {
1383                     menu_deluid( keyblock, sec_keyblock );
1384                     redisplay = 1;
1385                     modified = 1;
1386                     if( sec_keyblock )
1387                        sec_modified = 1;
1388                 }
1389             }
1390             break;
1391
1392           case cmdDELSIG: {
1393                 int n1;
1394
1395                 if( !(n1=count_selected_uids(keyblock)) )
1396                     tty_printf(_("You must select at least one user ID.\n"));
1397                 else if( menu_delsig( keyblock ) ) {
1398                     /* no redisplay here, because it may scroll away some
1399                      * status output of delsig */
1400                     modified = 1;
1401                 }
1402             }
1403             break;
1404
1405           case cmdADDKEY:
1406             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1407                 redisplay = 1;
1408                 sec_modified = modified = 1;
1409                 merge_keys_and_selfsig( sec_keyblock );
1410                 merge_keys_and_selfsig( keyblock );
1411             }
1412             break;
1413
1414
1415           case cmdDELKEY: {
1416                 int n1;
1417
1418                 if( !(n1=count_selected_keys( keyblock )) )
1419                     tty_printf(_("You must select at least one key.\n"));
1420                 else if( sec_keyblock && !cpr_get_answer_is_yes(
1421                             "keyedit.remove.subkey.okay",
1422                        n1 > 1?
1423                         _("Do you really want to delete the selected keys? "):
1424                         _("Do you really want to delete this key? ")
1425                        ))
1426                     ;
1427                 else {
1428                     menu_delkey( keyblock, sec_keyblock );
1429                     redisplay = 1;
1430                     modified = 1;
1431                     if( sec_keyblock )
1432                        sec_modified = 1;
1433                 }
1434             }
1435             break;
1436
1437           case cmdADDREVOKER:
1438             {
1439               int sensitive=0;
1440
1441               if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1442                 sensitive=1;
1443               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1444                 redisplay = 1;
1445                 sec_modified = modified = 1;
1446                 merge_keys_and_selfsig( sec_keyblock );
1447                 merge_keys_and_selfsig( keyblock );
1448               }
1449             }
1450             break;
1451
1452           case cmdREVUID: {
1453                 int n1;
1454
1455                 if( !(n1=count_selected_uids(keyblock)) )
1456                     tty_printf(_("You must select at least one user ID.\n"));
1457                 else if( cpr_get_answer_is_yes(
1458                             "keyedit.revoke.uid.okay",
1459                         n1 > 1? _("Really revoke all selected user IDs? ")
1460                               : _("Really revoke this user ID? ")
1461                        ) ) {
1462                   if(menu_revuid(keyblock,sec_keyblock))
1463                     {
1464                       modified=1;
1465                       redisplay=1;
1466                     }
1467                 }
1468             }
1469             break;
1470
1471           case cmdREVKEY: {
1472                 int n1;
1473
1474                 if( !(n1=count_selected_keys( keyblock )) )
1475                     tty_printf(_("You must select at least one key.\n"));
1476                 else if( sec_keyblock && !cpr_get_answer_is_yes(
1477                             "keyedit.revoke.subkey.okay",
1478                        n1 > 1?
1479                         _("Do you really want to revoke the selected keys? "):
1480                         _("Do you really want to revoke this key? ")
1481                        ))
1482                     ;
1483                 else {
1484                     if( menu_revkey( keyblock, sec_keyblock ) ) {
1485                         modified = 1;
1486                         /*sec_modified = 1;*/
1487                     }
1488                     redisplay = 1;
1489                 }
1490             }
1491             break;
1492
1493           case cmdEXPIRE:
1494             if( menu_expire( keyblock, sec_keyblock ) ) {
1495                 merge_keys_and_selfsig( sec_keyblock );
1496                 merge_keys_and_selfsig( keyblock );
1497                 sec_modified = 1;
1498                 modified = 1;
1499                 redisplay = 1;
1500             }
1501             break;
1502
1503           case cmdPRIMARY:
1504             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1505                 merge_keys_and_selfsig( keyblock );
1506                 modified = 1;
1507                 redisplay = 1;
1508             }
1509             break;
1510
1511           case cmdPASSWD:
1512             if( change_passphrase( sec_keyblock ) )
1513                 sec_modified = 1;
1514             break;
1515
1516           case cmdTRUST:
1517             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1518             tty_printf("\n");
1519             if( edit_ownertrust( find_kbnode( keyblock,
1520                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1521                 redisplay = 1;
1522                 /* No real need to set update_trust here as
1523                    edit_ownertrust() calls revalidation_mark()
1524                    anyway. */
1525                 update_trust=1;
1526             }
1527             break;
1528
1529           case cmdPREF:
1530             show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1531             break;
1532
1533           case cmdSHOWPREF:
1534             show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1535             break;
1536
1537           case cmdSETPREF:
1538             keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
1539             break;
1540
1541           case cmdUPDPREF: 
1542             {
1543               PKT_user_id *temp=keygen_get_std_prefs();
1544               tty_printf(_("Current preference list:\n"));
1545               show_prefs(temp,1);
1546               m_free(temp);
1547             }
1548             if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
1549                                         count_selected_uids (keyblock)?
1550                                         _("Really update the preferences"
1551                                           " for the selected user IDs? "):
1552                                        _("Really update the preferences? "))){
1553
1554                 if ( menu_set_preferences (keyblock, sec_keyblock) ) {
1555                     merge_keys_and_selfsig (keyblock);
1556                     modified = 1;
1557                     redisplay = 1;
1558                 }
1559             }
1560             break;
1561
1562           case cmdNOP:
1563             break;
1564
1565           case cmdREVSIG:
1566             if( menu_revsig( keyblock ) ) {
1567                 redisplay = 1;
1568                 modified = 1;
1569             }
1570             break;
1571
1572           case cmdENABLEKEY:
1573           case cmdDISABLEKEY:
1574             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1575                 redisplay = 1;
1576                 modified = 1;
1577             }
1578             break;
1579
1580          case cmdSHOWPHOTO:
1581            menu_showphoto(keyblock);
1582            break;
1583
1584           case cmdQUIT:
1585             if( have_commands )
1586                 goto leave;
1587             if( !modified && !sec_modified )
1588                 goto leave;
1589             if( !cpr_get_answer_is_yes("keyedit.save.okay",
1590                                         _("Save changes? ")) ) {
1591                 if( cpr_enabled()
1592                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
1593                                              _("Quit without saving? ")) )
1594                     goto leave;
1595                 break;
1596             }
1597             /* fall thru */
1598           case cmdSAVE:
1599           do_cmd_save:
1600             if( modified || sec_modified  ) {
1601                 if( modified ) {
1602                     rc = keydb_update_keyblock (kdbhd, keyblock);
1603                     if( rc ) {
1604                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
1605                         break;
1606                     }
1607                 }
1608                 if( sec_modified ) {
1609                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1610                     if( rc ) {
1611                         log_error( _("update secret failed: %s\n"),
1612                                    g10_errstr(rc) );
1613                         break;
1614                     }
1615                 }
1616             }
1617             else
1618                 tty_printf(_("Key not changed so no update needed.\n"));
1619
1620             if( update_trust )
1621               {
1622                 revalidation_mark ();
1623                 update_trust=0;
1624               }
1625             goto leave;
1626
1627           case cmdINVCMD:
1628           default:
1629             tty_printf("\n");
1630             tty_printf(_("Invalid command  (try \"help\")\n"));
1631             break;
1632         }
1633     } /* end main loop */
1634
1635   leave:
1636     release_kbnode( keyblock );
1637     release_kbnode( sec_keyblock );
1638     keydb_release (kdbhd);
1639     m_free(answer);
1640 }
1641
1642
1643 /****************
1644  * show preferences of a public keyblock.
1645  */
1646 static void
1647 show_prefs (PKT_user_id *uid, int verbose)
1648 {
1649     const prefitem_t fake={0,0};
1650     const prefitem_t *prefs;
1651     int i;
1652
1653     if( !uid )
1654         return;
1655
1656     if( uid->prefs )
1657         prefs=uid->prefs;
1658     else if(verbose)
1659         prefs=&fake;
1660     else
1661       return;
1662
1663     if (verbose) {
1664         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1665         tty_printf ("     ");
1666         tty_printf (_("Cipher: "));
1667         for(i=any=0; prefs[i].type; i++ ) {
1668             if( prefs[i].type == PREFTYPE_SYM ) {
1669                 const char *s = cipher_algo_to_string (prefs[i].value);
1670                 
1671                 if (any)
1672                     tty_printf (", ");
1673                 any = 1;
1674                 /* We don't want to display strings for experimental algos */
1675                 if (s && prefs[i].value < 100 )
1676                     tty_printf ("%s", s );
1677                 else
1678                     tty_printf ("[%d]", prefs[i].value);
1679                 if (prefs[i].value == CIPHER_ALGO_3DES )
1680                     des_seen = 1;
1681             }    
1682         }
1683         if (!des_seen) {
1684             if (any)
1685                 tty_printf (", ");
1686             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
1687         }
1688         tty_printf ("\n     ");
1689         tty_printf (_("Digest: "));
1690         for(i=any=0; prefs[i].type; i++ ) {
1691             if( prefs[i].type == PREFTYPE_HASH ) {
1692                 const char *s = digest_algo_to_string (prefs[i].value);
1693                 
1694                 if (any)
1695                     tty_printf (", ");
1696                 any = 1;
1697                 /* We don't want to display strings for experimental algos */
1698                 if (s && prefs[i].value < 100 )
1699                     tty_printf ("%s", s );
1700                 else
1701                     tty_printf ("[%d]", prefs[i].value);
1702                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
1703                     sha1_seen = 1;
1704             }
1705         }
1706         if (!sha1_seen) {
1707             if (any)
1708                 tty_printf (", ");
1709             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
1710         }
1711         tty_printf ("\n     ");
1712         tty_printf (_("Compression: "));
1713         for(i=any=0; prefs[i].type; i++ ) {
1714             if( prefs[i].type == PREFTYPE_ZIP ) {
1715                 const char *s=compress_algo_to_string(prefs[i].value);
1716                 
1717                 if (any)
1718                     tty_printf (", ");
1719                 any = 1;
1720                 /* We don't want to display strings for experimental algos */
1721                 if (s && prefs[i].value < 100 )
1722                     tty_printf ("%s", s );
1723                 else
1724                     tty_printf ("[%d]", prefs[i].value);
1725                 if (prefs[i].value == 0 )
1726                     uncomp_seen = 1;
1727             }
1728         }
1729         if (!uncomp_seen) {
1730             if (any)
1731                 tty_printf (", ");
1732             else {
1733               tty_printf ("%s",compress_algo_to_string(1));
1734               tty_printf (", ");
1735             }
1736             tty_printf ("%s",compress_algo_to_string(0));
1737         }
1738         if(uid->mdc_feature || !uid->ks_modify)
1739           {
1740             tty_printf ("\n     ");
1741             tty_printf (_("Features: "));
1742             any=0;
1743             if(uid->mdc_feature)
1744               {
1745                 tty_printf ("MDC");
1746                 any=1;
1747               }
1748             if(!uid->ks_modify)
1749               {
1750                 if(any)
1751                   tty_printf (", ");
1752                 tty_printf (_("Keyserver no-modify"));
1753               }
1754           }
1755         tty_printf("\n");
1756     }
1757     else {
1758         tty_printf("    ");
1759         for(i=0; prefs[i].type; i++ ) {
1760             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
1761                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
1762                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
1763                                  prefs[i].value);
1764         }
1765         if (uid->mdc_feature)
1766             tty_printf (" [mdc]");
1767         if (!uid->ks_modify)
1768             tty_printf (" [no-ks-modify]");
1769         tty_printf("\n");
1770     }
1771 }
1772
1773
1774 /* This is the version of show_key_with_all_names used when
1775    opt.with_colons is used.  It prints all available data in a easy to
1776    parse format and does not translate utf8 */
1777 static void
1778 show_key_with_all_names_colon (KBNODE keyblock)
1779 {
1780   KBNODE node;
1781   int i, j, ulti_hack=0;
1782   byte pk_version=0;
1783   PKT_public_key *primary=NULL;
1784
1785   /* the keys */
1786   for ( node = keyblock; node; node = node->next )
1787     {
1788       if (node->pkt->pkttype == PKT_PUBLIC_KEY
1789           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
1790         {
1791           PKT_public_key *pk = node->pkt->pkt.public_key;
1792           u32 keyid[2];
1793
1794           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1795             {
1796               pk_version = pk->version;
1797               primary=pk;
1798             }
1799
1800           keyid_from_pk (pk, keyid);
1801
1802           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
1803           if (!pk->is_valid)
1804             putchar ('i');
1805           else if (pk->is_revoked)
1806             putchar ('r');
1807           else if (pk->has_expired)
1808             putchar ('e');
1809           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1810             {
1811               int trust = get_validity_info (pk, NULL);
1812               if(trust=='u')
1813                 ulti_hack=1;
1814               putchar (trust);
1815             }
1816
1817           printf (":%u:%d:%08lX%08lX:%lu:%lu:",
1818                   nbits_from_pk (pk),
1819                   pk->pubkey_algo,
1820                   (ulong)keyid[0], (ulong)keyid[1],
1821                   (ulong)pk->timestamp,
1822                   (ulong)pk->expiredate );
1823           if (pk->local_id)
1824             printf ("%lu", pk->local_id);
1825           putchar (':');
1826           if (node->pkt->pkttype==PKT_PUBLIC_KEY
1827               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1828             putchar(get_ownertrust_info (pk));
1829           putchar(':');
1830           putchar('\n');
1831           
1832           print_fingerprint (pk, NULL, 0);
1833
1834           /* print the revoker record */
1835           if( !pk->revkey && pk->numrevkeys )
1836             BUG();
1837           else
1838             {
1839               for (i=0; i < pk->numrevkeys; i++)
1840                 {
1841                   byte *p;
1842
1843                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
1844                   p = pk->revkey[i].fpr;
1845                   for (j=0; j < 20; j++, p++ )
1846                     printf ("%02X", *p);
1847                   printf (":%02x%s:\n", pk->revkey[i].class,
1848                           (pk->revkey[i].class&0x40)?"s":"");
1849                 }
1850             }
1851         }
1852     }
1853   
1854     /* the user ids */
1855     i = 0;
1856     for (node = keyblock; node; node = node->next) 
1857       {
1858         if ( node->pkt->pkttype == PKT_USER_ID )
1859           {
1860             PKT_user_id *uid = node->pkt->pkt.user_id;
1861
1862             ++i;
1863
1864             if(uid->attrib_data)
1865               printf("uat:");
1866             else
1867               printf("uid:");
1868
1869             if ( uid->is_revoked )
1870               printf("r::::::::");
1871             else if ( uid->is_expired )
1872               printf("e::::::::");
1873             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
1874               printf("::::::::");
1875             else
1876               {
1877                 int uid_validity;
1878
1879                 if( primary && !ulti_hack )
1880                   uid_validity = get_validity_info( primary, uid );
1881                 else
1882                   uid_validity = 'u';
1883                 printf("%c::::::::",uid_validity);
1884               }
1885
1886             if(uid->attrib_data)
1887               printf ("%u %lu",uid->numattribs,uid->attrib_len);
1888             else
1889               print_string (stdout, uid->name, uid->len, ':');
1890
1891             putchar (':');
1892             /* signature class */
1893             putchar (':');
1894             /* capabilities */
1895             putchar (':');
1896             /* preferences */
1897             if (pk_version>3 || uid->selfsigversion>3)
1898               {
1899                 const prefitem_t *prefs = uid->prefs;
1900                 
1901                 for (j=0; prefs && prefs[j].type; j++)
1902                   {
1903                     if (j)
1904                       putchar (' ');
1905                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
1906                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
1907                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
1908                             prefs[j].value);
1909                   } 
1910                 if (uid->mdc_feature)
1911                   printf (",mdc");
1912                 if (!uid->ks_modify)
1913                   printf (",no-ks-modify");
1914               } 
1915             putchar (':');
1916             /* flags */
1917             printf ("%d,", i);
1918             if (uid->is_primary)
1919               putchar ('p');
1920             if (uid->is_revoked)
1921               putchar ('r');
1922             if (uid->is_expired)
1923               putchar ('e');
1924             if ((node->flag & NODFLG_SELUID))
1925               putchar ('s');
1926             if ((node->flag & NODFLG_MARK_A))
1927               putchar ('m');
1928             putchar (':');
1929             putchar('\n');
1930           }
1931       }
1932 }
1933
1934
1935 /****************
1936  * Display the key a the user ids, if only_marked is true, do only
1937  * so for user ids with mark A flag set and dont display the index number
1938  */
1939 static void
1940 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
1941                          int with_fpr, int with_subkeys, int with_prefs )
1942 {
1943     KBNODE node;
1944     int i, rc;
1945     int do_warn = 0;
1946     byte pk_version=0;
1947
1948     if (opt.with_colons)
1949       {
1950         show_key_with_all_names_colon (keyblock);
1951         return;
1952       }
1953
1954     /* the keys */
1955     for( node = keyblock; node; node = node->next ) {
1956         if( node->pkt->pkttype == PKT_PUBLIC_KEY
1957             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
1958             PKT_public_key *pk = node->pkt->pkt.public_key;
1959             const char *otrust="err",*trust="err";
1960
1961             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
1962                 /* do it here, so that debug messages don't clutter the
1963                  * output */
1964                 static int did_warn = 0;
1965
1966                 trust = get_validity_string (pk, NULL);
1967                 otrust = get_ownertrust_string (pk);
1968
1969                 /* Show a warning once */
1970                 if (!did_warn
1971                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
1972                     did_warn = 1;
1973                     do_warn = 1;
1974                 }
1975
1976                 pk_version=pk->version;
1977             }
1978
1979             if(with_revoker) {
1980                 if( !pk->revkey && pk->numrevkeys )
1981                     BUG();
1982                 else
1983                     for(i=0;i<pk->numrevkeys;i++) {
1984                         u32 r_keyid[2];
1985                         char *user;
1986                         const char *algo=
1987                           pubkey_algo_to_string(pk->revkey[i].algid);
1988
1989                         keyid_from_fingerprint(pk->revkey[i].fpr,
1990                                                MAX_FINGERPRINT_LEN,r_keyid);
1991                         
1992                         user=get_user_id_string (r_keyid);
1993                         tty_printf (_("This key may be revoked by %s key "),
1994                                     algo?algo:"?");
1995                         tty_print_utf8_string (user, strlen (user));
1996                         if ((pk->revkey[i].class&0x40))
1997                           tty_printf (_(" (sensitive)"));
1998                         tty_printf ("\n");
1999                         m_free(user);
2000                       }
2001             }
2002
2003             tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2004                           node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2005                           (node->flag & NODFLG_SELKEY)? '*':' ',
2006                           nbits_from_pk( pk ),
2007                           pubkey_letter( pk->pubkey_algo ),
2008                           (ulong)keyid_from_pk(pk,NULL),
2009                           datestr_from_pk(pk),
2010                           expirestr_from_pk(pk) );
2011             tty_printf("\n");
2012
2013             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2014               {
2015                 tty_printf("                     ");
2016                 tty_printf(_("trust: %-13s"), otrust);
2017                 tty_printf(_("validity: %s"), trust );
2018                 tty_printf("\n");
2019                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2020                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2021                   {
2022                     tty_printf("*** ");
2023                     tty_printf(_("This key has been disabled"));
2024                     tty_printf("\n");
2025                   }
2026               }
2027
2028             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2029               {
2030                 print_fingerprint ( pk, NULL, 2 );
2031                 tty_printf("\n");
2032               }
2033         }
2034         else if( node->pkt->pkttype == PKT_SECRET_KEY
2035             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
2036             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2037             tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2038                           node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2039                           (node->flag & NODFLG_SELKEY)? '*':' ',
2040                           nbits_from_sk( sk ),
2041                           pubkey_letter( sk->pubkey_algo ),
2042                           (ulong)keyid_from_sk(sk,NULL),
2043                           datestr_from_sk(sk),
2044                           expirestr_from_sk(sk) );
2045             tty_printf("\n");
2046         }
2047         else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
2048                  && node->pkt->pkt.signature->sig_class == 0x28       ) {
2049             PKT_signature *sig = node->pkt->pkt.signature;
2050
2051             rc = check_key_signature( keyblock, node, NULL );
2052             if( !rc )
2053                 tty_printf( _("rev! subkey has been revoked: %s\n"),
2054                             datestr_from_sig( sig ) );
2055             else if( rc == G10ERR_BAD_SIGN )
2056                 tty_printf( _("rev- faked revocation found\n") );
2057             else if( rc )
2058                 tty_printf( _("rev? problem checking revocation: %s\n"),
2059                                                          g10_errstr(rc) );
2060         }
2061     }
2062     /* the user ids */
2063     i = 0;
2064     for( node = keyblock; node; node = node->next ) {
2065         if( node->pkt->pkttype == PKT_USER_ID ) {
2066             PKT_user_id *uid = node->pkt->pkt.user_id;
2067             ++i;
2068             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
2069                 if( only_marked )
2070                    tty_printf("     ");
2071                 else if( node->flag & NODFLG_SELUID )
2072                    tty_printf("(%d)* ", i);
2073                 else if( uid->is_primary )
2074                    tty_printf("(%d). ", i);
2075                 else
2076                    tty_printf("(%d)  ", i);
2077                 if ( uid->is_revoked )
2078                     tty_printf (_("[revoked] "));
2079                 if ( uid->is_expired )
2080                     tty_printf (_("[expired] "));
2081                 tty_print_utf8_string( uid->name, uid->len );
2082                 tty_printf("\n");
2083                 if( with_prefs )
2084                   {
2085                     if(pk_version>3 || uid->selfsigversion>3)
2086                       show_prefs (uid, with_prefs == 2);
2087                     else
2088                       tty_printf(_("There are no preferences on a "
2089                                    "PGP 2.x-style user ID.\n"));
2090                   }
2091             }
2092         }
2093     }
2094
2095     if (do_warn)
2096         tty_printf (_("Please note that the shown key validity "
2097                       "is not necessarily correct\n"
2098                       "unless you restart the program.\n")); 
2099
2100 }
2101
2102
2103 /* Display basic key information.  This fucntion is suitable to show
2104    information on the key without any dependencies on the trustdb or
2105    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2106    a secret key.*/
2107 void
2108 show_basic_key_info ( KBNODE keyblock )
2109 {
2110   KBNODE node;
2111   int i;
2112
2113   /* The primary key */
2114   for (node = keyblock; node; node = node->next)
2115     {
2116       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2117         {
2118           PKT_public_key *pk = node->pkt->pkt.public_key;
2119           
2120           /* Note, we use the same format string as in other show
2121              functions to make the translation job easier. */
2122           tty_printf (_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2123                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2124                       ' ',
2125                       nbits_from_pk( pk ),
2126                       pubkey_letter( pk->pubkey_algo ),
2127                       (ulong)keyid_from_pk(pk,NULL),
2128                       datestr_from_pk(pk),
2129                       expirestr_from_pk(pk) );
2130           tty_printf("\n");
2131           print_fingerprint ( pk, NULL, 3 );
2132           tty_printf("\n");
2133         }
2134       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2135         {
2136           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2137           tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2138                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2139                      ' ',
2140                      nbits_from_sk( sk ),
2141                      pubkey_letter( sk->pubkey_algo ),
2142                      (ulong)keyid_from_sk(sk,NULL),
2143                      datestr_from_sk(sk),
2144                      expirestr_from_sk(sk) );
2145           tty_printf("\n");
2146           print_fingerprint (NULL, sk, 3 );
2147           tty_printf("\n");
2148         }
2149     }
2150
2151   /* The user IDs. */
2152   for (i=0, node = keyblock; node; node = node->next)
2153     {
2154       if (node->pkt->pkttype == PKT_USER_ID)
2155         {
2156           PKT_user_id *uid = node->pkt->pkt.user_id;
2157           ++i;
2158      
2159           tty_printf ("     ");
2160           if (uid->is_revoked)
2161             tty_printf ("[revoked] ");
2162           if ( uid->is_expired )
2163             tty_printf ("[expired] ");
2164           tty_print_utf8_string (uid->name, uid->len);
2165           tty_printf ("\n");
2166         }
2167     }
2168 }
2169
2170 static void
2171 show_key_and_fingerprint( KBNODE keyblock )
2172 {
2173     KBNODE node;
2174     PKT_public_key *pk = NULL;
2175
2176     for( node = keyblock; node; node = node->next ) {
2177         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2178             pk = node->pkt->pkt.public_key;
2179             tty_printf("pub   %4u%c/%08lX %s ",
2180                           nbits_from_pk( pk ),
2181                           pubkey_letter( pk->pubkey_algo ),
2182                           (ulong)keyid_from_pk(pk,NULL),
2183                           datestr_from_pk(pk) );
2184         }
2185         else if( node->pkt->pkttype == PKT_USER_ID ) {
2186             PKT_user_id *uid = node->pkt->pkt.user_id;
2187             tty_print_utf8_string( uid->name, uid->len );
2188             break;
2189         }
2190     }
2191     tty_printf("\n");
2192     if( pk )
2193         print_fingerprint( pk, NULL, 2 );
2194 }
2195
2196
2197
2198 /****************
2199  * Ask for a new user id, do the selfsignature and put it into
2200  * both keyblocks.
2201  * Return true if there is a new user id
2202  */
2203 static int
2204 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2205 {
2206     PKT_user_id *uid;
2207     PKT_public_key *pk=NULL;
2208     PKT_secret_key *sk=NULL;
2209     PKT_signature *sig=NULL;
2210     PACKET *pkt;
2211     KBNODE node;
2212     KBNODE pub_where=NULL, sec_where=NULL;
2213     int rc;
2214
2215     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2216         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2217             pk = node->pkt->pkt.public_key;
2218         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2219             break;
2220     }
2221     if( !node ) /* no subkey */
2222         pub_where = NULL;
2223     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2224         if( node->pkt->pkttype == PKT_SECRET_KEY )
2225             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2226         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2227             break;
2228     }
2229     if( !node ) /* no subkey */
2230         sec_where = NULL;
2231     assert(pk && sk);
2232
2233     if(photo) {
2234       int hasattrib=0;
2235
2236       for( node = pub_keyblock; node; node = node->next )
2237         if( node->pkt->pkttype == PKT_USER_ID &&
2238             node->pkt->pkt.user_id->attrib_data!=NULL)
2239           {
2240             hasattrib=1;
2241             break;
2242           }
2243
2244       /* It is legal but bad for compatibility to add a photo ID to a
2245          v3 key as it means that PGP2 will not be able to use that key
2246          anymore.  Also, PGP may not expect a photo on a v3 key.
2247          Don't bother to ask this if the key already has a photo - any
2248          damage has already been done at that point. -dms */
2249       if(pk->version==3 && !hasattrib)
2250         {
2251           if(opt.expert)
2252             {
2253               tty_printf(_("WARNING: This is a PGP2-style key.  "
2254                            "Adding a photo ID may cause some versions\n"
2255                            "         of PGP to reject this key.\n"));
2256
2257               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2258                                         _("Are you sure you still want "
2259                                           "to add it? (y/N) ")))
2260                 return 0;
2261             }
2262           else
2263             {
2264               tty_printf(_("You may not add a photo ID to "
2265                            "a PGP2-style key.\n"));
2266               return 0;
2267             }
2268         }
2269
2270       uid = generate_photo_id(pk);
2271     } else
2272       uid = generate_user_id();
2273     if( !uid )
2274         return 0;
2275
2276     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2277                              keygen_add_std_prefs, pk );
2278     free_secret_key( sk );
2279     if( rc ) {
2280         log_error("signing failed: %s\n", g10_errstr(rc) );
2281         free_user_id(uid);
2282         return 0;
2283     }
2284
2285     /* insert/append to secret keyblock */
2286     pkt = m_alloc_clear( sizeof *pkt );
2287     pkt->pkttype = PKT_USER_ID;
2288     pkt->pkt.user_id = scopy_user_id(uid);
2289     node = new_kbnode(pkt);
2290     if( sec_where )
2291         insert_kbnode( sec_where, node, 0 );
2292     else
2293         add_kbnode( sec_keyblock, node );
2294     pkt = m_alloc_clear( sizeof *pkt );
2295     pkt->pkttype = PKT_SIGNATURE;
2296     pkt->pkt.signature = copy_signature(NULL, sig);
2297     if( sec_where )
2298         insert_kbnode( node, new_kbnode(pkt), 0 );
2299     else
2300         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2301     /* insert/append to public keyblock */
2302     pkt = m_alloc_clear( sizeof *pkt );
2303     pkt->pkttype = PKT_USER_ID;
2304     pkt->pkt.user_id = uid;
2305     node = new_kbnode(pkt);
2306     if( pub_where )
2307         insert_kbnode( pub_where, node, 0 );
2308     else
2309         add_kbnode( pub_keyblock, node );
2310     pkt = m_alloc_clear( sizeof *pkt );
2311     pkt->pkttype = PKT_SIGNATURE;
2312     pkt->pkt.signature = copy_signature(NULL, sig);
2313     if( pub_where )
2314         insert_kbnode( node, new_kbnode(pkt), 0 );
2315     else
2316         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2317     return 1;
2318 }
2319
2320
2321 /****************
2322  * Remove all selceted userids from the keyrings
2323  */
2324 static void
2325 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2326 {
2327     KBNODE node;
2328     int selected=0;
2329
2330     for( node = pub_keyblock; node; node = node->next ) {
2331         if( node->pkt->pkttype == PKT_USER_ID ) {
2332             selected = node->flag & NODFLG_SELUID;
2333             if( selected ) {
2334                 /* Only cause a trust update if we delete a
2335                    non-revoked user id */
2336                 if(!node->pkt->pkt.user_id->is_revoked)
2337                   update_trust=1;
2338                 delete_kbnode( node );
2339                 if( sec_keyblock ) {
2340                     KBNODE snode;
2341                     int s_selected = 0;
2342                     PKT_user_id *uid = node->pkt->pkt.user_id;
2343                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2344                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2345                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2346
2347                             s_selected =
2348                                 (uid->len == suid->len
2349                                  && !memcmp( uid->name, suid->name, uid->len));
2350                             if( s_selected )
2351                                 delete_kbnode( snode );
2352                         }
2353                         else if( s_selected
2354                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2355                             delete_kbnode( snode );
2356                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2357                             s_selected = 0;
2358                     }
2359                 }
2360             }
2361         }
2362         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2363             delete_kbnode( node );
2364         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2365             selected = 0;
2366     }
2367     commit_kbnode( &pub_keyblock );
2368     if( sec_keyblock )
2369         commit_kbnode( &sec_keyblock );
2370 }
2371
2372
2373 static int
2374 menu_delsig( KBNODE pub_keyblock )
2375 {
2376     KBNODE node;
2377     PKT_user_id *uid = NULL;
2378     int changed=0;
2379
2380     for( node = pub_keyblock; node; node = node->next ) {
2381         if( node->pkt->pkttype == PKT_USER_ID ) {
2382             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2383         }
2384         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2385            int okay, valid, selfsig, inv_sig, no_key, other_err;
2386
2387             tty_printf("uid  ");
2388             tty_print_utf8_string( uid->name, uid->len );
2389             tty_printf("\n");
2390
2391            okay = inv_sig = no_key = other_err = 0;
2392             valid = print_and_check_one_sig( pub_keyblock, node,
2393                                             &inv_sig, &no_key, &other_err,
2394                                             &selfsig, 1 );
2395
2396            if( valid ) {
2397                okay = cpr_get_answer_yes_no_quit(
2398                    "keyedit.delsig.valid",
2399                    _("Delete this good signature? (y/N/q)"));
2400
2401                /* Only update trust if we delete a good signature.
2402                   The other two cases do not affect trust. */
2403                if(okay)
2404                  update_trust=1;
2405            }
2406            else if( inv_sig || other_err )
2407                okay = cpr_get_answer_yes_no_quit(
2408                    "keyedit.delsig.invalid",
2409                    _("Delete this invalid signature? (y/N/q)"));
2410            else if( no_key )
2411                okay = cpr_get_answer_yes_no_quit(
2412                    "keyedit.delsig.unknown",
2413                    _("Delete this unknown signature? (y/N/q)"));
2414
2415             if( okay == -1 )
2416                 break;
2417            if( okay && selfsig && !cpr_get_answer_is_yes(
2418                                "keyedit.delsig.selfsig",
2419                               _("Really delete this self-signature? (y/N)") ))
2420                 okay = 0;
2421             if( okay ) {
2422                 delete_kbnode( node );
2423                 changed++;
2424             }
2425
2426         }
2427         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2428             uid = NULL;
2429     }
2430
2431     if( changed ) {
2432         commit_kbnode( &pub_keyblock );
2433         tty_printf( changed == 1? _("Deleted %d signature.\n")
2434                                 : _("Deleted %d signatures.\n"), changed );
2435     }
2436     else
2437         tty_printf( _("Nothing deleted.\n") );
2438
2439     return changed;
2440 }
2441
2442
2443 /****************
2444  * Remove some of the secondary keys
2445  */
2446 static void
2447 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2448 {
2449     KBNODE node;
2450     int selected=0;
2451
2452     for( node = pub_keyblock; node; node = node->next ) {
2453         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2454             selected = node->flag & NODFLG_SELKEY;
2455             if( selected ) {
2456                 delete_kbnode( node );
2457                 if( sec_keyblock ) {
2458                     KBNODE snode;
2459                     int s_selected = 0;
2460                     u32 ki[2];
2461
2462                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2463                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2464                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2465                             u32 ki2[2];
2466
2467                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2468                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2469                             if( s_selected )
2470                                 delete_kbnode( snode );
2471                         }
2472                         else if( s_selected
2473                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2474                             delete_kbnode( snode );
2475                         else
2476                             s_selected = 0;
2477                     }
2478                 }
2479             }
2480         }
2481         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2482             delete_kbnode( node );
2483         else
2484             selected = 0;
2485     }
2486     commit_kbnode( &pub_keyblock );
2487     if( sec_keyblock )
2488         commit_kbnode( &sec_keyblock );
2489
2490     /* No need to set update_trust here since signing keys are no
2491        longer used to certify other keys, so there is no change in
2492        trust when revoking/removing them */
2493 }
2494
2495
2496 /****************
2497  * Ask for a new revoker, do the selfsignature and put it into
2498  * both keyblocks.
2499  * Return true if there is a new revoker
2500  */
2501 static int
2502 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2503 {
2504   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2505   PKT_secret_key *sk=NULL;
2506   PKT_signature *sig=NULL;
2507   PACKET *pkt;
2508   struct revocation_key revkey;
2509   size_t fprlen;
2510   int rc;
2511
2512   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2513   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2514
2515   pk=pub_keyblock->pkt->pkt.public_key;
2516
2517   if(pk->numrevkeys==0 && pk->version==3)
2518     {
2519       /* It is legal but bad for compatibility to add a revoker to a
2520          v3 key as it means that PGP2 will not be able to use that key
2521          anymore.  Also, PGP may not expect a revoker on a v3 key.
2522          Don't bother to ask this if the key already has a revoker -
2523          any damage has already been done at that point. -dms */
2524       if(opt.expert)
2525         {
2526           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2527                        "Adding a designated revoker may cause\n"
2528                        "         some versions of PGP to reject this key.\n"));
2529
2530           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2531                                     _("Are you sure you still want "
2532                                       "to add it? (y/N) ")))
2533             return 0;
2534         }
2535       else
2536         {
2537           tty_printf(_("You may not add a designated revoker to "
2538                        "a PGP 2.x-style key.\n"));
2539           return 0;
2540         }
2541     }
2542
2543   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2544
2545   for(;;)
2546     {
2547       char *answer;
2548       u32 keyid[2];
2549       char *p;
2550       size_t n;
2551
2552       if(revoker_pk)
2553         free_public_key(revoker_pk);
2554
2555       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2556
2557       tty_printf("\n");
2558
2559       answer=cpr_get_utf8("keyedit.add_revoker",
2560                           _("Enter the user ID of the designated revoker: "));
2561       if(answer[0]=='\0' || answer[0]=='\004')
2562         goto fail;
2563
2564       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2565
2566       if(rc)
2567         {
2568           log_error (_("key `%s' not found: %s\n"),answer,g10_errstr(rc));
2569           continue;
2570         }
2571
2572       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2573       if(fprlen!=20)
2574         {
2575           log_error(_("cannot appoint a PGP 2.x style key as a "
2576                       "designated revoker\n"));
2577           continue;
2578         }
2579
2580       revkey.class=0x80;
2581       if(sensitive)
2582         revkey.class|=0x40;
2583       revkey.algid=revoker_pk->pubkey_algo;
2584
2585       if(cmp_public_keys(revoker_pk,pk)==0)
2586         {
2587           /* This actually causes no harm (after all, a key that
2588              designates itself as a revoker is the same as a
2589              regular key), but it's easy enough to check. */
2590           log_error(_("you cannot appoint a key as its own "
2591                       "designated revoker\n"));
2592
2593           continue;
2594         }
2595
2596       keyid_from_pk(pk,NULL);
2597
2598       /* Does this revkey already exist? */
2599       if(!pk->revkey && pk->numrevkeys)
2600         BUG();
2601       else
2602         {
2603           int i;
2604
2605           for(i=0;i<pk->numrevkeys;i++)
2606             {
2607               if(memcmp(&pk->revkey[i],&revkey,
2608                         sizeof(struct revocation_key))==0)
2609                 {
2610                   char buf[50];
2611
2612                   log_error(_("this key has already been designated "
2613                               "as a revoker\n"));
2614
2615                   sprintf(buf,"%08lX%08lX",
2616                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2617                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2618
2619                   break;
2620                 }
2621             }
2622
2623           if(i<pk->numrevkeys)
2624             continue;
2625         }
2626
2627       keyid_from_pk(revoker_pk,keyid);
2628
2629       tty_printf("\npub   %4u%c/%08lX %s   ",
2630                  nbits_from_pk( revoker_pk ),
2631                  pubkey_letter( revoker_pk->pubkey_algo ),
2632                  (ulong)keyid[1], datestr_from_pk(pk) );
2633
2634       p = get_user_id( keyid, &n );
2635       tty_print_utf8_string( p, n );
2636       m_free(p);
2637       tty_printf("\n");
2638       print_fingerprint(revoker_pk,NULL,2);
2639       tty_printf("\n");
2640
2641       tty_printf(_("WARNING: appointing a key as a designated revoker "
2642                    "cannot be undone!\n"));
2643
2644       tty_printf("\n");
2645
2646       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2647                                 _("Are you sure you want to appoint this "
2648                                   "key as a designated revoker? (y/N): ")))
2649         continue;
2650
2651       free_public_key(revoker_pk);
2652       revoker_pk=NULL;
2653       break;
2654     }
2655
2656   /* The 1F signature must be at least v4 to carry the revocation key
2657      subpacket. */
2658   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
2659                            keygen_add_revkey,&revkey );
2660   if( rc )
2661     {
2662       log_error("signing failed: %s\n", g10_errstr(rc) );
2663       goto fail;
2664     }
2665
2666   free_secret_key(sk);
2667   sk=NULL;
2668
2669   /* insert into secret keyblock */
2670   pkt = m_alloc_clear( sizeof *pkt );
2671   pkt->pkttype = PKT_SIGNATURE;
2672   pkt->pkt.signature = copy_signature(NULL, sig);
2673   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2674
2675   /* insert into public keyblock */
2676   pkt = m_alloc_clear( sizeof *pkt );
2677   pkt->pkttype = PKT_SIGNATURE;
2678   pkt->pkt.signature = sig;
2679   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2680
2681   return 1;
2682
2683  fail:
2684   if(sk)
2685     free_secret_key(sk);
2686   if(sig)
2687     free_seckey_enc(sig);
2688   if(revoker_pk)
2689     free_public_key(revoker_pk);
2690
2691   return 0;
2692 }
2693
2694
2695 static int
2696 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
2697 {
2698     int n1, signumber, rc;
2699     u32 expiredate;
2700     int mainkey=0;
2701     PKT_secret_key *sk;    /* copy of the main sk */
2702     PKT_public_key *main_pk, *sub_pk;
2703     PKT_user_id *uid;
2704     KBNODE node;
2705     u32 keyid[2];
2706
2707     if( count_selected_keys( sec_keyblock ) ) {
2708         tty_printf(_("Please remove selections from the secret keys.\n"));
2709         return 0;
2710     }
2711
2712     n1 = count_selected_keys( pub_keyblock );
2713     if( n1 > 1 ) {
2714         tty_printf(_("Please select at most one secondary key.\n"));
2715         return 0;
2716     }
2717     else if( n1 )
2718         tty_printf(_("Changing expiration time for a secondary key.\n"));
2719     else {
2720         tty_printf(_("Changing expiration time for the primary key.\n"));
2721         mainkey=1;
2722     }
2723
2724     expiredate = ask_expiredate();
2725     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2726     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2727
2728     /* Now we can actually change the self signature(s) */
2729     main_pk = sub_pk = NULL;
2730     uid = NULL;
2731     signumber = 0;
2732     for( node=pub_keyblock; node; node = node->next ) {
2733         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2734             main_pk = node->pkt->pkt.public_key;
2735             keyid_from_pk( main_pk, keyid );
2736             main_pk->expiredate = expiredate;
2737         }
2738         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2739                  && (node->flag & NODFLG_SELKEY ) ) {
2740             sub_pk = node->pkt->pkt.public_key;
2741             sub_pk->expiredate = expiredate;
2742         }
2743         else if( node->pkt->pkttype == PKT_USER_ID )
2744             uid = node->pkt->pkt.user_id;
2745         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
2746                  && ( mainkey || sub_pk ) ) {
2747             PKT_signature *sig = node->pkt->pkt.signature;
2748             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2749                 && (    (mainkey && uid && (sig->sig_class&~3) == 0x10)
2750                      || (!mainkey && sig->sig_class == 0x18)  ) ) {
2751                 /* this is a selfsignature which is to be replaced */
2752                 PKT_signature *newsig;
2753                 PACKET *newpkt;
2754                 KBNODE sn;
2755                 int signumber2 = 0;
2756
2757                 signumber++;
2758
2759                 if( (mainkey && main_pk->version < 4)
2760                     || (!mainkey && sub_pk->version < 4 ) ) {
2761                     log_info(_(
2762                         "You can't change the expiration date of a v3 key\n"));
2763                     free_secret_key( sk );
2764                     return 0;
2765                 }
2766
2767                 /* find the corresponding secret self-signature */
2768                 for( sn=sec_keyblock; sn; sn = sn->next ) {
2769                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
2770                         PKT_signature *b = sn->pkt->pkt.signature;
2771                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
2772                             && sig->sig_class == b->sig_class
2773                             && ++signumber2 == signumber )
2774                             break;
2775                     }
2776                 }
2777                 if( !sn )
2778                     log_info(_("No corresponding signature in secret ring\n"));
2779
2780                 if( mainkey )
2781                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
2782                                             sk, keygen_add_key_expire, main_pk);
2783                 else
2784                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
2785                                             sk, keygen_add_key_expire, sub_pk );
2786                 if( rc ) {
2787                     log_error("make_keysig_packet failed: %s\n",
2788                                                     g10_errstr(rc));
2789                     free_secret_key( sk );
2790                     return 0;
2791                 }
2792                 /* replace the packet */
2793                 newpkt = m_alloc_clear( sizeof *newpkt );
2794                 newpkt->pkttype = PKT_SIGNATURE;
2795                 newpkt->pkt.signature = newsig;
2796                 free_packet( node->pkt );
2797                 m_free( node->pkt );
2798                 node->pkt = newpkt;
2799                 if( sn ) {
2800                     newpkt = m_alloc_clear( sizeof *newpkt );
2801                     newpkt->pkttype = PKT_SIGNATURE;
2802                     newpkt->pkt.signature = copy_signature( NULL, newsig );
2803                     free_packet( sn->pkt );
2804                     m_free( sn->pkt );
2805                     sn->pkt = newpkt;
2806                 }
2807                 sub_pk = NULL;
2808             }
2809         }
2810     }
2811
2812     free_secret_key( sk );
2813     update_trust=1;
2814     return 1;
2815 }
2816
2817 static int
2818 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
2819 {
2820     byte buf[1];
2821
2822     /* first clear all primary uid flags so that we are sure none are
2823      * lingering around */
2824     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
2825     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
2826
2827     /* if opaque is set,we want to set the primary id */
2828     if (opaque) { 
2829         buf[0] = 1;
2830         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
2831     }
2832
2833     return 0;
2834 }
2835
2836
2837 /*
2838  * Set the primary uid flag for the selected UID.  We will also reset
2839  * all other primary uid flags.  For this to work with have to update
2840  * all the signature timestamps.  If we would do this with the current
2841  * time, we lose quite a lot of information, so we use a a kludge to
2842  * do this: Just increment the timestamp by one second which is
2843  * sufficient to updated a signature during import.
2844  */
2845 static int
2846 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
2847 {
2848     PKT_secret_key *sk;    /* copy of the main sk */
2849     PKT_public_key *main_pk;
2850     PKT_user_id *uid;
2851     KBNODE node;
2852     u32 keyid[2];
2853     int selected;
2854     int attribute = 0;
2855     int modified = 0;
2856
2857     if ( count_selected_uids (pub_keyblock) != 1 ) {
2858         tty_printf(_("Please select exactly one user ID.\n"));
2859         return 0;
2860     }
2861
2862     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2863     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2864
2865     /* Now we can actually change the self signature(s) */
2866     main_pk = NULL;
2867     uid = NULL;
2868     selected = 0;
2869
2870     /* Is our selected uid an attribute packet? */
2871     for ( node=pub_keyblock; node; node = node->next )
2872       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
2873         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
2874
2875     for ( node=pub_keyblock; node; node = node->next ) {
2876         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2877             break; /* ready */
2878
2879         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2880             main_pk = node->pkt->pkt.public_key;
2881             keyid_from_pk( main_pk, keyid );
2882         }
2883         else if ( node->pkt->pkttype == PKT_USER_ID ) {
2884             uid = node->pkt->pkt.user_id;
2885             selected = node->flag & NODFLG_SELUID;
2886         }
2887         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2888             PKT_signature *sig = node->pkt->pkt.signature;
2889             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2890                 && (uid && (sig->sig_class&~3) == 0x10)
2891                 && attribute == (uid->attrib_data!=NULL)) {
2892               if(sig->version < 4) {
2893                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
2894
2895                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
2896                          user);
2897                 m_free(user);
2898               }
2899               else {
2900                 /* This is a selfsignature which is to be replaced.
2901                    We can just ignore v3 signatures because they are
2902                    not able to carry the primary ID flag.  We also
2903                    ignore self-sigs on user IDs that are not of the
2904                    same type that we are making primary.  That is, if
2905                    we are making a user ID primary, we alter user IDs.
2906                    If we are making an attribute packet primary, we
2907                    alter attribute packets. */
2908
2909                 /* FIXME: We must make sure that we only have one
2910                    self-signature per user ID here (not counting
2911                    revocations) */
2912                 PKT_signature *newsig;
2913                 PACKET *newpkt;
2914                 const byte *p;
2915                 int action;
2916
2917                 /* see whether this signature has the primary UID flag */
2918                 p = parse_sig_subpkt (sig->hashed,
2919                                       SIGSUBPKT_PRIMARY_UID, NULL );
2920                 if ( !p )
2921                     p = parse_sig_subpkt (sig->unhashed,
2922                                           SIGSUBPKT_PRIMARY_UID, NULL );
2923                 if ( p && *p ) /* yes */
2924                     action = selected? 0 : -1;
2925                 else /* no */
2926                     action = selected? 1 : 0;
2927
2928                 if (action) {
2929                     int rc = update_keysig_packet (&newsig, sig,
2930                                                main_pk, uid, NULL,
2931                                                sk,
2932                                                change_primary_uid_cb,
2933                                                action > 0? "x":NULL );
2934                     if( rc ) {
2935                         log_error ("update_keysig_packet failed: %s\n",
2936                                    g10_errstr(rc));
2937                         free_secret_key( sk );
2938                         return 0;
2939                     }
2940                     /* replace the packet */
2941                     newpkt = m_alloc_clear( sizeof *newpkt );
2942                     newpkt->pkttype = PKT_SIGNATURE;
2943                     newpkt->pkt.signature = newsig;
2944                     free_packet( node->pkt );
2945                     m_free( node->pkt );
2946                     node->pkt = newpkt;
2947                     modified = 1;
2948                 }
2949               }
2950             }
2951         }
2952     }
2953
2954     free_secret_key( sk );
2955     return modified;
2956 }
2957
2958
2959 /* 
2960  * Set preferences to new values for the selected user IDs
2961  */
2962 static int
2963 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
2964 {
2965     PKT_secret_key *sk;    /* copy of the main sk */
2966     PKT_public_key *main_pk;
2967     PKT_user_id *uid;
2968     KBNODE node;
2969     u32 keyid[2];
2970     int selected, select_all;
2971     int modified = 0;
2972
2973     select_all = !count_selected_uids (pub_keyblock);
2974
2975     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2976     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2977
2978     /* Now we can actually change the self signature(s) */
2979     main_pk = NULL;
2980     uid = NULL;
2981     selected = 0;
2982     for ( node=pub_keyblock; node; node = node->next ) {
2983         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2984             break; /* ready */
2985
2986         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2987             main_pk = node->pkt->pkt.public_key;
2988             keyid_from_pk( main_pk, keyid );
2989         }
2990         else if ( node->pkt->pkttype == PKT_USER_ID ) {
2991             uid = node->pkt->pkt.user_id;
2992             selected = select_all || (node->flag & NODFLG_SELUID);
2993         }
2994         else if ( main_pk && uid && selected
2995                   && node->pkt->pkttype == PKT_SIGNATURE ) {
2996             PKT_signature *sig = node->pkt->pkt.signature;
2997             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2998                  && (uid && (sig->sig_class&~3) == 0x10) ) {
2999               if( sig->version < 4 ) {
3000                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3001
3002                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3003                          user);
3004                 m_free(user);
3005               }
3006               else {
3007                 /* This is a selfsignature which is to be replaced 
3008                  * We have to ignore v3 signatures because they are
3009                  * not able to carry the preferences */
3010                 PKT_signature *newsig;
3011                 PACKET *newpkt;
3012                 int rc;
3013
3014                 rc = update_keysig_packet (&newsig, sig,
3015                                            main_pk, uid, NULL,
3016                                            sk,
3017                                            keygen_upd_std_prefs,
3018                                            NULL );
3019                 if( rc ) {
3020                     log_error ("update_keysig_packet failed: %s\n",
3021                                g10_errstr(rc));
3022                     free_secret_key( sk );
3023                     return 0;
3024                 }
3025                 /* replace the packet */
3026                 newpkt = m_alloc_clear( sizeof *newpkt );
3027                 newpkt->pkttype = PKT_SIGNATURE;
3028                 newpkt->pkt.signature = newsig;
3029                 free_packet( node->pkt );
3030                 m_free( node->pkt );
3031                 node->pkt = newpkt;
3032                 modified = 1;
3033               }
3034             }
3035         }
3036     }
3037     
3038     free_secret_key( sk );
3039     return modified;
3040 }
3041
3042
3043 /****************
3044  * Select one user id or remove all selection if index is 0.
3045  * Returns: True if the selection changed;
3046  */
3047 static int
3048 menu_select_uid( KBNODE keyblock, int idx )
3049 {
3050     KBNODE node;
3051     int i;
3052
3053     /* first check that the index is valid */
3054     if( idx ) {
3055         for( i=0, node = keyblock; node; node = node->next ) {
3056             if( node->pkt->pkttype == PKT_USER_ID ) {
3057                 if( ++i == idx )
3058                     break;
3059             }
3060         }
3061         if( !node ) {
3062             tty_printf(_("No user ID with index %d\n"), idx );
3063             return 0;
3064         }
3065     }
3066     else { /* reset all */
3067         for( i=0, node = keyblock; node; node = node->next ) {
3068             if( node->pkt->pkttype == PKT_USER_ID )
3069                 node->flag &= ~NODFLG_SELUID;
3070         }
3071         return 1;
3072     }
3073     /* and toggle the new index */
3074     for( i=0, node = keyblock; node; node = node->next ) {
3075         if( node->pkt->pkttype == PKT_USER_ID ) {
3076             if( ++i == idx ) {
3077                 if( (node->flag & NODFLG_SELUID) )
3078                     node->flag &= ~NODFLG_SELUID;
3079                 else
3080                     node->flag |= NODFLG_SELUID;
3081             }
3082         }
3083     }
3084
3085     return 1;
3086 }
3087
3088 /****************
3089  * Select secondary keys
3090  * Returns: True if the selection changed;
3091  */
3092 static int
3093 menu_select_key( KBNODE keyblock, int idx )
3094 {
3095     KBNODE node;
3096     int i;
3097
3098     /* first check that the index is valid */
3099     if( idx ) {
3100         for( i=0, node = keyblock; node; node = node->next ) {
3101             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3102                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3103                 if( ++i == idx )
3104                     break;
3105             }
3106         }
3107         if( !node ) {
3108             tty_printf(_("No secondary key with index %d\n"), idx );
3109             return 0;
3110         }
3111     }
3112     else { /* reset all */
3113         for( i=0, node = keyblock; node; node = node->next ) {
3114             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3115                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3116                 node->flag &= ~NODFLG_SELKEY;
3117         }
3118         return 1;
3119     }
3120     /* and set the new index */
3121     for( i=0, node = keyblock; node; node = node->next ) {
3122         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3123             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3124             if( ++i == idx ) {
3125                 if( (node->flag & NODFLG_SELKEY) )
3126                     node->flag &= ~NODFLG_SELKEY;
3127                 else
3128                     node->flag |= NODFLG_SELKEY;
3129             }
3130         }
3131     }
3132
3133     return 1;
3134 }
3135
3136
3137 static int
3138 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3139 {
3140     KBNODE node;
3141     int i=0;
3142
3143     for( node = keyblock; node; node = node->next )
3144         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3145             i++;
3146     return i;
3147 }
3148
3149 static int
3150 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3151 {
3152     KBNODE node;
3153     int i=0;
3154
3155     for( node = keyblock; node; node = node->next )
3156         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3157               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3158             && (node->flag & flag) )
3159             i++;
3160     return i;
3161 }
3162
3163 static int
3164 count_uids( KBNODE keyblock )
3165 {
3166     KBNODE node;
3167     int i=0;
3168
3169     for( node = keyblock; node; node = node->next )
3170         if( node->pkt->pkttype == PKT_USER_ID )
3171             i++;
3172     return i;
3173 }
3174
3175
3176 /****************
3177  * Returns true if there is at least one selected user id
3178  */
3179 static int
3180 count_selected_uids( KBNODE keyblock )
3181 {
3182     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3183 }
3184
3185 static int
3186 count_selected_keys( KBNODE keyblock )
3187 {
3188     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3189 }
3190
3191 /* returns how many real (i.e. not attribute) uids are unmarked */
3192 static int
3193 real_uids_left( KBNODE keyblock )
3194 {
3195   KBNODE node;
3196   int real=0;
3197
3198   for(node=keyblock;node;node=node->next)
3199     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3200        !node->pkt->pkt.user_id->attrib_data)
3201       real++;
3202
3203   return real;
3204 }
3205
3206 /*
3207  * Ask whether the signature should be revoked.  If the user commits this,
3208  * flag bit MARK_A is set on the signature and the user ID.
3209  */
3210 static void
3211 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3212 {
3213     int doit=0;
3214     PKT_signature *sig = node->pkt->pkt.signature;
3215     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3216
3217     if( !unode ) {
3218         log_error("Oops: no user ID for signature\n");
3219         return;
3220     }
3221
3222     tty_printf(_("user ID: \""));
3223     tty_print_utf8_string( unode->pkt->pkt.user_id->name,
3224                            unode->pkt->pkt.user_id->len );
3225
3226     if(sig->flags.exportable)
3227       tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
3228                  (ulong)sig->keyid[1], datestr_from_sig(sig) );
3229     else
3230       tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"),
3231                  (ulong)sig->keyid[1], datestr_from_sig(sig) );
3232
3233     if(sig->flags.expired)
3234       {
3235         tty_printf(_("This signature expired on %s.\n"),
3236                    expirestr_from_sig(sig));
3237         /* Use a different question so we can have different help text */
3238         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3239                         _("Are you sure you still want to revoke it? (y/N) "));
3240       }
3241     else
3242       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3243               _("Create a revocation certificate for this signature? (y/N) "));
3244
3245     if(doit) {
3246       node->flag |= NODFLG_MARK_A;
3247       unode->flag |= NODFLG_MARK_A;
3248     }
3249 }
3250
3251 /****************
3252  * Display all user ids of the current public key together with signatures
3253  * done by one of our keys.  Then walk over all this sigs and ask the user
3254  * whether he wants to revoke this signature.
3255  * Return: True when the keyblock has changed.
3256  */
3257 static int
3258 menu_revsig( KBNODE keyblock )
3259 {
3260     PKT_signature *sig;
3261     PKT_public_key *primary_pk;
3262     KBNODE node;
3263     int changed = 0;
3264     int rc, any, skip=1, all=!count_selected_uids(keyblock);
3265     struct revocation_reason_info *reason = NULL;
3266
3267     /* FIXME: detect duplicates here  */
3268     tty_printf(_("You have signed these user IDs:\n"));
3269     for( node = keyblock; node; node = node->next ) {
3270         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
3271    &n