* g10.c (main): Add --no-textmode.
[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            
1987                         keyid_from_fingerprint(pk->revkey[i].fpr,
1988                                                MAX_FINGERPRINT_LEN,r_keyid);
1989                         
1990                         user=get_user_id_string (r_keyid);
1991                         tty_printf (_("This key may be revoked by %s key "),
1992                                  pubkey_algo_to_string (pk->revkey[i].algid));
1993                         tty_print_utf8_string (user, strlen (user));
1994                         if ((pk->revkey[i].class&0x40))
1995                           tty_printf (_(" (sensitive)"));
1996                         tty_printf ("\n");
1997                         m_free(user);
1998                       }
1999             }
2000
2001             tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2002                           node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2003                           (node->flag & NODFLG_SELKEY)? '*':' ',
2004                           nbits_from_pk( pk ),
2005                           pubkey_letter( pk->pubkey_algo ),
2006                           (ulong)keyid_from_pk(pk,NULL),
2007                           datestr_from_pk(pk),
2008                           expirestr_from_pk(pk) );
2009             tty_printf("\n");
2010
2011             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2012               {
2013                 tty_printf("                     ");
2014                 tty_printf(_("trust: %-13s"), otrust);
2015                 tty_printf(_("validity: %s"), trust );
2016                 tty_printf("\n");
2017                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2018                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2019                   {
2020                     tty_printf("*** ");
2021                     tty_printf(_("This key has been disabled"));
2022                     tty_printf("\n");
2023                   }
2024               }
2025
2026             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2027               {
2028                 print_fingerprint ( pk, NULL, 2 );
2029                 tty_printf("\n");
2030               }
2031         }
2032         else if( node->pkt->pkttype == PKT_SECRET_KEY
2033             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
2034             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2035             tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2036                           node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2037                           (node->flag & NODFLG_SELKEY)? '*':' ',
2038                           nbits_from_sk( sk ),
2039                           pubkey_letter( sk->pubkey_algo ),
2040                           (ulong)keyid_from_sk(sk,NULL),
2041                           datestr_from_sk(sk),
2042                           expirestr_from_sk(sk) );
2043             tty_printf("\n");
2044         }
2045         else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
2046                  && node->pkt->pkt.signature->sig_class == 0x28       ) {
2047             PKT_signature *sig = node->pkt->pkt.signature;
2048
2049             rc = check_key_signature( keyblock, node, NULL );
2050             if( !rc )
2051                 tty_printf( _("rev! subkey has been revoked: %s\n"),
2052                             datestr_from_sig( sig ) );
2053             else if( rc == G10ERR_BAD_SIGN )
2054                 tty_printf( _("rev- faked revocation found\n") );
2055             else if( rc )
2056                 tty_printf( _("rev? problem checking revocation: %s\n"),
2057                                                          g10_errstr(rc) );
2058         }
2059     }
2060     /* the user ids */
2061     i = 0;
2062     for( node = keyblock; node; node = node->next ) {
2063         if( node->pkt->pkttype == PKT_USER_ID ) {
2064             PKT_user_id *uid = node->pkt->pkt.user_id;
2065             ++i;
2066             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
2067                 if( only_marked )
2068                    tty_printf("     ");
2069                 else if( node->flag & NODFLG_SELUID )
2070                    tty_printf("(%d)* ", i);
2071                 else if( uid->is_primary )
2072                    tty_printf("(%d). ", i);
2073                 else
2074                    tty_printf("(%d)  ", i);
2075                 if ( uid->is_revoked )
2076                     tty_printf (_("[revoked] "));
2077                 if ( uid->is_expired )
2078                     tty_printf (_("[expired] "));
2079                 tty_print_utf8_string( uid->name, uid->len );
2080                 tty_printf("\n");
2081                 if( with_prefs )
2082                   {
2083                     if(pk_version>3 || uid->selfsigversion>3)
2084                       show_prefs (uid, with_prefs == 2);
2085                     else
2086                       tty_printf(_("There are no preferences on a "
2087                                    "PGP 2.x-style user ID.\n"));
2088                   }
2089             }
2090         }
2091     }
2092
2093     if (do_warn)
2094         tty_printf (_("Please note that the shown key validity "
2095                       "is not necessarily correct\n"
2096                       "unless you restart the program.\n")); 
2097
2098 }
2099
2100
2101 /* Display basic key information.  This fucntion is suitable to show
2102    information on the key without any dependencies on the trustdb or
2103    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2104    a secret key.*/
2105 void
2106 show_basic_key_info ( KBNODE keyblock )
2107 {
2108   KBNODE node;
2109   int i;
2110
2111   /* The primary key */
2112   for (node = keyblock; node; node = node->next)
2113     {
2114       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2115         {
2116           PKT_public_key *pk = node->pkt->pkt.public_key;
2117           
2118           /* Note, we use the same format string as in other show
2119              functions to make the translation job easier. */
2120           tty_printf (_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2121                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2122                       ' ',
2123                       nbits_from_pk( pk ),
2124                       pubkey_letter( pk->pubkey_algo ),
2125                       (ulong)keyid_from_pk(pk,NULL),
2126                       datestr_from_pk(pk),
2127                       expirestr_from_pk(pk) );
2128           tty_printf("\n");
2129           print_fingerprint ( pk, NULL, 3 );
2130           tty_printf("\n");
2131         }
2132       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2133         {
2134           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2135           tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2136                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2137                      ' ',
2138                      nbits_from_sk( sk ),
2139                      pubkey_letter( sk->pubkey_algo ),
2140                      (ulong)keyid_from_sk(sk,NULL),
2141                      datestr_from_sk(sk),
2142                      expirestr_from_sk(sk) );
2143           tty_printf("\n");
2144           print_fingerprint (NULL, sk, 3 );
2145           tty_printf("\n");
2146         }
2147     }
2148
2149   /* The user IDs. */
2150   for (i=0, node = keyblock; node; node = node->next)
2151     {
2152       if (node->pkt->pkttype == PKT_USER_ID)
2153         {
2154           PKT_user_id *uid = node->pkt->pkt.user_id;
2155           ++i;
2156      
2157           tty_printf ("     ");
2158           if (uid->is_revoked)
2159             tty_printf ("[revoked] ");
2160           if ( uid->is_expired )
2161             tty_printf ("[expired] ");
2162           tty_print_utf8_string (uid->name, uid->len);
2163           tty_printf ("\n");
2164         }
2165     }
2166 }
2167
2168 static void
2169 show_key_and_fingerprint( KBNODE keyblock )
2170 {
2171     KBNODE node;
2172     PKT_public_key *pk = NULL;
2173
2174     for( node = keyblock; node; node = node->next ) {
2175         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2176             pk = node->pkt->pkt.public_key;
2177             tty_printf("pub   %4u%c/%08lX %s ",
2178                           nbits_from_pk( pk ),
2179                           pubkey_letter( pk->pubkey_algo ),
2180                           (ulong)keyid_from_pk(pk,NULL),
2181                           datestr_from_pk(pk) );
2182         }
2183         else if( node->pkt->pkttype == PKT_USER_ID ) {
2184             PKT_user_id *uid = node->pkt->pkt.user_id;
2185             tty_print_utf8_string( uid->name, uid->len );
2186             break;
2187         }
2188     }
2189     tty_printf("\n");
2190     if( pk )
2191         print_fingerprint( pk, NULL, 2 );
2192 }
2193
2194
2195
2196 /****************
2197  * Ask for a new user id, do the selfsignature and put it into
2198  * both keyblocks.
2199  * Return true if there is a new user id
2200  */
2201 static int
2202 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2203 {
2204     PKT_user_id *uid;
2205     PKT_public_key *pk=NULL;
2206     PKT_secret_key *sk=NULL;
2207     PKT_signature *sig=NULL;
2208     PACKET *pkt;
2209     KBNODE node;
2210     KBNODE pub_where=NULL, sec_where=NULL;
2211     int rc;
2212
2213     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2214         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2215             pk = node->pkt->pkt.public_key;
2216         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2217             break;
2218     }
2219     if( !node ) /* no subkey */
2220         pub_where = NULL;
2221     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2222         if( node->pkt->pkttype == PKT_SECRET_KEY )
2223             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2224         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2225             break;
2226     }
2227     if( !node ) /* no subkey */
2228         sec_where = NULL;
2229     assert(pk && sk);
2230
2231     if(photo) {
2232       int hasattrib=0;
2233
2234       for( node = pub_keyblock; node; node = node->next )
2235         if( node->pkt->pkttype == PKT_USER_ID &&
2236             node->pkt->pkt.user_id->attrib_data!=NULL)
2237           {
2238             hasattrib=1;
2239             break;
2240           }
2241
2242       /* It is legal but bad for compatibility to add a photo ID to a
2243          v3 key as it means that PGP2 will not be able to use that key
2244          anymore.  Also, PGP may not expect a photo on a v3 key.
2245          Don't bother to ask this if the key already has a photo - any
2246          damage has already been done at that point. -dms */
2247       if(pk->version==3 && !hasattrib)
2248         {
2249           if(opt.expert)
2250             {
2251               tty_printf(_("WARNING: This is a PGP2-style key.  "
2252                            "Adding a photo ID may cause some versions\n"
2253                            "         of PGP to reject this key.\n"));
2254
2255               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2256                                         _("Are you sure you still want "
2257                                           "to add it? (y/N) ")))
2258                 return 0;
2259             }
2260           else
2261             {
2262               tty_printf(_("You may not add a photo ID to "
2263                            "a PGP2-style key.\n"));
2264               return 0;
2265             }
2266         }
2267
2268       uid = generate_photo_id(pk);
2269     } else
2270       uid = generate_user_id();
2271     if( !uid )
2272         return 0;
2273
2274     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2275                              keygen_add_std_prefs, pk );
2276     free_secret_key( sk );
2277     if( rc ) {
2278         log_error("signing failed: %s\n", g10_errstr(rc) );
2279         free_user_id(uid);
2280         return 0;
2281     }
2282
2283     /* insert/append to secret keyblock */
2284     pkt = m_alloc_clear( sizeof *pkt );
2285     pkt->pkttype = PKT_USER_ID;
2286     pkt->pkt.user_id = scopy_user_id(uid);
2287     node = new_kbnode(pkt);
2288     if( sec_where )
2289         insert_kbnode( sec_where, node, 0 );
2290     else
2291         add_kbnode( sec_keyblock, node );
2292     pkt = m_alloc_clear( sizeof *pkt );
2293     pkt->pkttype = PKT_SIGNATURE;
2294     pkt->pkt.signature = copy_signature(NULL, sig);
2295     if( sec_where )
2296         insert_kbnode( node, new_kbnode(pkt), 0 );
2297     else
2298         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2299     /* insert/append to public keyblock */
2300     pkt = m_alloc_clear( sizeof *pkt );
2301     pkt->pkttype = PKT_USER_ID;
2302     pkt->pkt.user_id = uid;
2303     node = new_kbnode(pkt);
2304     if( pub_where )
2305         insert_kbnode( pub_where, node, 0 );
2306     else
2307         add_kbnode( pub_keyblock, node );
2308     pkt = m_alloc_clear( sizeof *pkt );
2309     pkt->pkttype = PKT_SIGNATURE;
2310     pkt->pkt.signature = copy_signature(NULL, sig);
2311     if( pub_where )
2312         insert_kbnode( node, new_kbnode(pkt), 0 );
2313     else
2314         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2315     return 1;
2316 }
2317
2318
2319 /****************
2320  * Remove all selceted userids from the keyrings
2321  */
2322 static void
2323 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2324 {
2325     KBNODE node;
2326     int selected=0;
2327
2328     for( node = pub_keyblock; node; node = node->next ) {
2329         if( node->pkt->pkttype == PKT_USER_ID ) {
2330             selected = node->flag & NODFLG_SELUID;
2331             if( selected ) {
2332                 /* Only cause a trust update if we delete a
2333                    non-revoked user id */
2334                 if(!node->pkt->pkt.user_id->is_revoked)
2335                   update_trust=1;
2336                 delete_kbnode( node );
2337                 if( sec_keyblock ) {
2338                     KBNODE snode;
2339                     int s_selected = 0;
2340                     PKT_user_id *uid = node->pkt->pkt.user_id;
2341                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2342                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2343                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2344
2345                             s_selected =
2346                                 (uid->len == suid->len
2347                                  && !memcmp( uid->name, suid->name, uid->len));
2348                             if( s_selected )
2349                                 delete_kbnode( snode );
2350                         }
2351                         else if( s_selected
2352                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2353                             delete_kbnode( snode );
2354                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2355                             s_selected = 0;
2356                     }
2357                 }
2358             }
2359         }
2360         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2361             delete_kbnode( node );
2362         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2363             selected = 0;
2364     }
2365     commit_kbnode( &pub_keyblock );
2366     if( sec_keyblock )
2367         commit_kbnode( &sec_keyblock );
2368 }
2369
2370
2371 static int
2372 menu_delsig( KBNODE pub_keyblock )
2373 {
2374     KBNODE node;
2375     PKT_user_id *uid = NULL;
2376     int changed=0;
2377
2378     for( node = pub_keyblock; node; node = node->next ) {
2379         if( node->pkt->pkttype == PKT_USER_ID ) {
2380             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2381         }
2382         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2383            int okay, valid, selfsig, inv_sig, no_key, other_err;
2384
2385             tty_printf("uid  ");
2386             tty_print_utf8_string( uid->name, uid->len );
2387             tty_printf("\n");
2388
2389            okay = inv_sig = no_key = other_err = 0;
2390             valid = print_and_check_one_sig( pub_keyblock, node,
2391                                             &inv_sig, &no_key, &other_err,
2392                                             &selfsig, 1 );
2393
2394            if( valid ) {
2395                okay = cpr_get_answer_yes_no_quit(
2396                    "keyedit.delsig.valid",
2397                    _("Delete this good signature? (y/N/q)"));
2398
2399                /* Only update trust if we delete a good signature.
2400                   The other two cases do not affect trust. */
2401                if(okay)
2402                  update_trust=1;
2403            }
2404            else if( inv_sig || other_err )
2405                okay = cpr_get_answer_yes_no_quit(
2406                    "keyedit.delsig.invalid",
2407                    _("Delete this invalid signature? (y/N/q)"));
2408            else if( no_key )
2409                okay = cpr_get_answer_yes_no_quit(
2410                    "keyedit.delsig.unknown",
2411                    _("Delete this unknown signature? (y/N/q)"));
2412
2413             if( okay == -1 )
2414                 break;
2415            if( okay && selfsig && !cpr_get_answer_is_yes(
2416                                "keyedit.delsig.selfsig",
2417                               _("Really delete this self-signature? (y/N)") ))
2418                 okay = 0;
2419             if( okay ) {
2420                 delete_kbnode( node );
2421                 changed++;
2422             }
2423
2424         }
2425         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2426             uid = NULL;
2427     }
2428
2429     if( changed ) {
2430         commit_kbnode( &pub_keyblock );
2431         tty_printf( changed == 1? _("Deleted %d signature.\n")
2432                                 : _("Deleted %d signatures.\n"), changed );
2433     }
2434     else
2435         tty_printf( _("Nothing deleted.\n") );
2436
2437     return changed;
2438 }
2439
2440
2441 /****************
2442  * Remove some of the secondary keys
2443  */
2444 static void
2445 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2446 {
2447     KBNODE node;
2448     int selected=0;
2449
2450     for( node = pub_keyblock; node; node = node->next ) {
2451         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2452             selected = node->flag & NODFLG_SELKEY;
2453             if( selected ) {
2454                 delete_kbnode( node );
2455                 if( sec_keyblock ) {
2456                     KBNODE snode;
2457                     int s_selected = 0;
2458                     u32 ki[2];
2459
2460                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2461                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2462                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2463                             u32 ki2[2];
2464
2465                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2466                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2467                             if( s_selected )
2468                                 delete_kbnode( snode );
2469                         }
2470                         else if( s_selected
2471                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2472                             delete_kbnode( snode );
2473                         else
2474                             s_selected = 0;
2475                     }
2476                 }
2477             }
2478         }
2479         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2480             delete_kbnode( node );
2481         else
2482             selected = 0;
2483     }
2484     commit_kbnode( &pub_keyblock );
2485     if( sec_keyblock )
2486         commit_kbnode( &sec_keyblock );
2487
2488     /* No need to set update_trust here since signing keys are no
2489        longer used to certify other keys, so there is no change in
2490        trust when revoking/removing them */
2491 }
2492
2493
2494 /****************
2495  * Ask for a new revoker, do the selfsignature and put it into
2496  * both keyblocks.
2497  * Return true if there is a new revoker
2498  */
2499 static int
2500 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2501 {
2502   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2503   PKT_secret_key *sk=NULL;
2504   PKT_signature *sig=NULL;
2505   PACKET *pkt;
2506   struct revocation_key revkey;
2507   size_t fprlen;
2508   int rc;
2509
2510   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2511   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2512
2513   pk=pub_keyblock->pkt->pkt.public_key;
2514
2515   if(pk->numrevkeys==0 && pk->version==3)
2516     {
2517       /* It is legal but bad for compatibility to add a revoker to a
2518          v3 key as it means that PGP2 will not be able to use that key
2519          anymore.  Also, PGP may not expect a revoker on a v3 key.
2520          Don't bother to ask this if the key already has a revoker -
2521          any damage has already been done at that point. -dms */
2522       if(opt.expert)
2523         {
2524           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2525                        "Adding a designated revoker may cause\n"
2526                        "         some versions of PGP to reject this key.\n"));
2527
2528           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2529                                     _("Are you sure you still want "
2530                                       "to add it? (y/N) ")))
2531             return 0;
2532         }
2533       else
2534         {
2535           tty_printf(_("You may not add a designated revoker to "
2536                        "a PGP 2.x-style key.\n"));
2537           return 0;
2538         }
2539     }
2540
2541   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2542
2543   for(;;)
2544     {
2545       char *answer;
2546       u32 keyid[2];
2547       char *p;
2548       size_t n;
2549
2550       if(revoker_pk)
2551         free_public_key(revoker_pk);
2552
2553       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2554
2555       tty_printf("\n");
2556
2557       answer=cpr_get_utf8("keyedit.add_revoker",
2558                           _("Enter the user ID of the designated revoker: "));
2559       if(answer[0]=='\0' || answer[0]=='\004')
2560         goto fail;
2561
2562       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2563
2564       if(rc)
2565         {
2566           log_error (_("key `%s' not found: %s\n"),answer,g10_errstr(rc));
2567           continue;
2568         }
2569
2570       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2571       if(fprlen!=20)
2572         {
2573           log_error(_("cannot appoint a PGP 2.x style key as a "
2574                       "designated revoker\n"));
2575           continue;
2576         }
2577
2578       revkey.class=0x80;
2579       if(sensitive)
2580         revkey.class|=0x40;
2581       revkey.algid=revoker_pk->pubkey_algo;
2582
2583       if(cmp_public_keys(revoker_pk,pk)==0)
2584         {
2585           /* This actually causes no harm (after all, a key that
2586              designates itself as a revoker is the same as a
2587              regular key), but it's easy enough to check. */
2588           log_error(_("you cannot appoint a key as its own "
2589                       "designated revoker\n"));
2590
2591           continue;
2592         }
2593
2594       keyid_from_pk(pk,NULL);
2595
2596       /* Does this revkey already exist? */
2597       if(!pk->revkey && pk->numrevkeys)
2598         BUG();
2599       else
2600         {
2601           int i;
2602
2603           for(i=0;i<pk->numrevkeys;i++)
2604             {
2605               if(memcmp(&pk->revkey[i],&revkey,
2606                         sizeof(struct revocation_key))==0)
2607                 {
2608                   char buf[50];
2609
2610                   log_error(_("this key has already been designated "
2611                               "as a revoker\n"));
2612
2613                   sprintf(buf,"%08lX%08lX",
2614                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2615                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2616
2617                   break;
2618                 }
2619             }
2620
2621           if(i<pk->numrevkeys)
2622             continue;
2623         }
2624
2625       keyid_from_pk(revoker_pk,keyid);
2626
2627       tty_printf("\npub   %4u%c/%08lX %s   ",
2628                  nbits_from_pk( revoker_pk ),
2629                  pubkey_letter( revoker_pk->pubkey_algo ),
2630                  (ulong)keyid[1], datestr_from_pk(pk) );
2631
2632       p = get_user_id( keyid, &n );
2633       tty_print_utf8_string( p, n );
2634       m_free(p);
2635       tty_printf("\n");
2636       print_fingerprint(revoker_pk,NULL,2);
2637       tty_printf("\n");
2638
2639       tty_printf(_("WARNING: appointing a key as a designated revoker "
2640                    "cannot be undone!\n"));
2641
2642       tty_printf("\n");
2643
2644       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2645                                 _("Are you sure you want to appoint this "
2646                                   "key as a designated revoker? (y/N): ")))
2647         continue;
2648
2649       free_public_key(revoker_pk);
2650       revoker_pk=NULL;
2651       break;
2652     }
2653
2654   /* The 1F signature must be at least v4 to carry the revocation key
2655      subpacket. */
2656   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
2657                            keygen_add_revkey,&revkey );
2658   if( rc )
2659     {
2660       log_error("signing failed: %s\n", g10_errstr(rc) );
2661       goto fail;
2662     }
2663
2664   free_secret_key(sk);
2665   sk=NULL;
2666
2667   /* insert into secret keyblock */
2668   pkt = m_alloc_clear( sizeof *pkt );
2669   pkt->pkttype = PKT_SIGNATURE;
2670   pkt->pkt.signature = copy_signature(NULL, sig);
2671   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2672
2673   /* insert into public keyblock */
2674   pkt = m_alloc_clear( sizeof *pkt );
2675   pkt->pkttype = PKT_SIGNATURE;
2676   pkt->pkt.signature = sig;
2677   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2678
2679   return 1;
2680
2681  fail:
2682   if(sk)
2683     free_secret_key(sk);
2684   if(sig)
2685     free_seckey_enc(sig);
2686   if(revoker_pk)
2687     free_public_key(revoker_pk);
2688
2689   return 0;
2690 }
2691
2692
2693 static int
2694 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
2695 {
2696     int n1, signumber, rc;
2697     u32 expiredate;
2698     int mainkey=0;
2699     PKT_secret_key *sk;    /* copy of the main sk */
2700     PKT_public_key *main_pk, *sub_pk;
2701     PKT_user_id *uid;
2702     KBNODE node;
2703     u32 keyid[2];
2704
2705     if( count_selected_keys( sec_keyblock ) ) {
2706         tty_printf(_("Please remove selections from the secret keys.\n"));
2707         return 0;
2708     }
2709
2710     n1 = count_selected_keys( pub_keyblock );
2711     if( n1 > 1 ) {
2712         tty_printf(_("Please select at most one secondary key.\n"));
2713         return 0;
2714     }
2715     else if( n1 )
2716         tty_printf(_("Changing expiration time for a secondary key.\n"));
2717     else {
2718         tty_printf(_("Changing expiration time for the primary key.\n"));
2719         mainkey=1;
2720     }
2721
2722     expiredate = ask_expiredate();
2723     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2724     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2725
2726     /* Now we can actually change the self signature(s) */
2727     main_pk = sub_pk = NULL;
2728     uid = NULL;
2729     signumber = 0;
2730     for( node=pub_keyblock; node; node = node->next ) {
2731         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2732             main_pk = node->pkt->pkt.public_key;
2733             keyid_from_pk( main_pk, keyid );
2734             main_pk->expiredate = expiredate;
2735         }
2736         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2737                  && (node->flag & NODFLG_SELKEY ) ) {
2738             sub_pk = node->pkt->pkt.public_key;
2739             sub_pk->expiredate = expiredate;
2740         }
2741         else if( node->pkt->pkttype == PKT_USER_ID )
2742             uid = node->pkt->pkt.user_id;
2743         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
2744                  && ( mainkey || sub_pk ) ) {
2745             PKT_signature *sig = node->pkt->pkt.signature;
2746             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2747                 && (    (mainkey && uid && (sig->sig_class&~3) == 0x10)
2748                      || (!mainkey && sig->sig_class == 0x18)  ) ) {
2749                 /* this is a selfsignature which is to be replaced */
2750                 PKT_signature *newsig;
2751                 PACKET *newpkt;
2752                 KBNODE sn;
2753                 int signumber2 = 0;
2754
2755                 signumber++;
2756
2757                 if( (mainkey && main_pk->version < 4)
2758                     || (!mainkey && sub_pk->version < 4 ) ) {
2759                     log_info(_(
2760                         "You can't change the expiration date of a v3 key\n"));
2761                     free_secret_key( sk );
2762                     return 0;
2763                 }
2764
2765                 /* find the corresponding secret self-signature */
2766                 for( sn=sec_keyblock; sn; sn = sn->next ) {
2767                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
2768                         PKT_signature *b = sn->pkt->pkt.signature;
2769                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
2770                             && sig->sig_class == b->sig_class
2771                             && ++signumber2 == signumber )
2772                             break;
2773                     }
2774                 }
2775                 if( !sn )
2776                     log_info(_("No corresponding signature in secret ring\n"));
2777
2778                 if( mainkey )
2779                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
2780                                             sk, keygen_add_key_expire, main_pk);
2781                 else
2782                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
2783                                             sk, keygen_add_key_expire, sub_pk );
2784                 if( rc ) {
2785                     log_error("make_keysig_packet failed: %s\n",
2786                                                     g10_errstr(rc));
2787                     free_secret_key( sk );
2788                     return 0;
2789                 }
2790                 /* replace the packet */
2791                 newpkt = m_alloc_clear( sizeof *newpkt );
2792                 newpkt->pkttype = PKT_SIGNATURE;
2793                 newpkt->pkt.signature = newsig;
2794                 free_packet( node->pkt );
2795                 m_free( node->pkt );
2796                 node->pkt = newpkt;
2797                 if( sn ) {
2798                     newpkt = m_alloc_clear( sizeof *newpkt );
2799                     newpkt->pkttype = PKT_SIGNATURE;
2800                     newpkt->pkt.signature = copy_signature( NULL, newsig );
2801                     free_packet( sn->pkt );
2802                     m_free( sn->pkt );
2803                     sn->pkt = newpkt;
2804                 }
2805                 sub_pk = NULL;
2806             }
2807         }
2808     }
2809
2810     free_secret_key( sk );
2811     update_trust=1;
2812     return 1;
2813 }
2814
2815 static int
2816 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
2817 {
2818     byte buf[1];
2819
2820     /* first clear all primary uid flags so that we are sure none are
2821      * lingering around */
2822     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
2823     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
2824
2825     /* if opaque is set,we want to set the primary id */
2826     if (opaque) { 
2827         buf[0] = 1;
2828         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
2829     }
2830
2831     return 0;
2832 }
2833
2834
2835 /*
2836  * Set the primary uid flag for the selected UID.  We will also reset
2837  * all other primary uid flags.  For this to work with have to update
2838  * all the signature timestamps.  If we would do this with the current
2839  * time, we lose quite a lot of information, so we use a a kludge to
2840  * do this: Just increment the timestamp by one second which is
2841  * sufficient to updated a signature during import.
2842  */
2843 static int
2844 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
2845 {
2846     PKT_secret_key *sk;    /* copy of the main sk */
2847     PKT_public_key *main_pk;
2848     PKT_user_id *uid;
2849     KBNODE node;
2850     u32 keyid[2];
2851     int selected;
2852     int attribute = 0;
2853     int modified = 0;
2854
2855     if ( count_selected_uids (pub_keyblock) != 1 ) {
2856         tty_printf(_("Please select exactly one user ID.\n"));
2857         return 0;
2858     }
2859
2860     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2861     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2862
2863     /* Now we can actually change the self signature(s) */
2864     main_pk = NULL;
2865     uid = NULL;
2866     selected = 0;
2867
2868     /* Is our selected uid an attribute packet? */
2869     for ( node=pub_keyblock; node; node = node->next )
2870       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
2871         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
2872
2873     for ( node=pub_keyblock; node; node = node->next ) {
2874         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2875             break; /* ready */
2876
2877         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2878             main_pk = node->pkt->pkt.public_key;
2879             keyid_from_pk( main_pk, keyid );
2880         }
2881         else if ( node->pkt->pkttype == PKT_USER_ID ) {
2882             uid = node->pkt->pkt.user_id;
2883             selected = node->flag & NODFLG_SELUID;
2884         }
2885         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2886             PKT_signature *sig = node->pkt->pkt.signature;
2887             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2888                 && (uid && (sig->sig_class&~3) == 0x10)
2889                 && attribute == (uid->attrib_data!=NULL)) {
2890               if(sig->version < 4) {
2891                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
2892
2893                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
2894                          user);
2895                 m_free(user);
2896               }
2897               else {
2898                 /* This is a selfsignature which is to be replaced.
2899                    We can just ignore v3 signatures because they are
2900                    not able to carry the primary ID flag.  We also
2901                    ignore self-sigs on user IDs that are not of the
2902                    same type that we are making primary.  That is, if
2903                    we are making a user ID primary, we alter user IDs.
2904                    If we are making an attribute packet primary, we
2905                    alter attribute packets. */
2906
2907                 /* FIXME: We must make sure that we only have one
2908                    self-signature per user ID here (not counting
2909                    revocations) */
2910                 PKT_signature *newsig;
2911                 PACKET *newpkt;
2912                 const byte *p;
2913                 int action;
2914
2915                 /* see whether this signature has the primary UID flag */
2916                 p = parse_sig_subpkt (sig->hashed,
2917                                       SIGSUBPKT_PRIMARY_UID, NULL );
2918                 if ( !p )
2919                     p = parse_sig_subpkt (sig->unhashed,
2920                                           SIGSUBPKT_PRIMARY_UID, NULL );
2921                 if ( p && *p ) /* yes */
2922                     action = selected? 0 : -1;
2923                 else /* no */
2924                     action = selected? 1 : 0;
2925
2926                 if (action) {
2927                     int rc = update_keysig_packet (&newsig, sig,
2928                                                main_pk, uid, NULL,
2929                                                sk,
2930                                                change_primary_uid_cb,
2931                                                action > 0? "x":NULL );
2932                     if( rc ) {
2933                         log_error ("update_keysig_packet failed: %s\n",
2934                                    g10_errstr(rc));
2935                         free_secret_key( sk );
2936                         return 0;
2937                     }
2938                     /* replace the packet */
2939                     newpkt = m_alloc_clear( sizeof *newpkt );
2940                     newpkt->pkttype = PKT_SIGNATURE;
2941                     newpkt->pkt.signature = newsig;
2942                     free_packet( node->pkt );
2943                     m_free( node->pkt );
2944                     node->pkt = newpkt;
2945                     modified = 1;
2946                 }
2947               }
2948             }
2949         }
2950     }
2951
2952     free_secret_key( sk );
2953     return modified;
2954 }
2955
2956
2957 /* 
2958  * Set preferences to new values for the selected user IDs
2959  */
2960 static int
2961 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
2962 {
2963     PKT_secret_key *sk;    /* copy of the main sk */
2964     PKT_public_key *main_pk;
2965     PKT_user_id *uid;
2966     KBNODE node;
2967     u32 keyid[2];
2968     int selected, select_all;
2969     int modified = 0;
2970
2971     select_all = !count_selected_uids (pub_keyblock);
2972
2973     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2974     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2975
2976     /* Now we can actually change the self signature(s) */
2977     main_pk = NULL;
2978     uid = NULL;
2979     selected = 0;
2980     for ( node=pub_keyblock; node; node = node->next ) {
2981         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2982             break; /* ready */
2983
2984         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2985             main_pk = node->pkt->pkt.public_key;
2986             keyid_from_pk( main_pk, keyid );
2987         }
2988         else if ( node->pkt->pkttype == PKT_USER_ID ) {
2989             uid = node->pkt->pkt.user_id;
2990             selected = select_all || (node->flag & NODFLG_SELUID);
2991         }
2992         else if ( main_pk && uid && selected
2993                   && node->pkt->pkttype == PKT_SIGNATURE ) {
2994             PKT_signature *sig = node->pkt->pkt.signature;
2995             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2996                  && (uid && (sig->sig_class&~3) == 0x10) ) {
2997               if( sig->version < 4 ) {
2998                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
2999
3000                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3001                          user);
3002                 m_free(user);
3003               }
3004               else {
3005                 /* This is a selfsignature which is to be replaced 
3006                  * We have to ignore v3 signatures because they are
3007                  * not able to carry the preferences */
3008                 PKT_signature *newsig;
3009                 PACKET *newpkt;
3010                 int rc;
3011
3012                 rc = update_keysig_packet (&newsig, sig,
3013                                            main_pk, uid, NULL,
3014                                            sk,
3015                                            keygen_upd_std_prefs,
3016                                            NULL );
3017                 if( rc ) {
3018                     log_error ("update_keysig_packet failed: %s\n",
3019                                g10_errstr(rc));
3020                     free_secret_key( sk );
3021                     return 0;
3022                 }
3023                 /* replace the packet */
3024                 newpkt = m_alloc_clear( sizeof *newpkt );
3025                 newpkt->pkttype = PKT_SIGNATURE;
3026                 newpkt->pkt.signature = newsig;
3027                 free_packet( node->pkt );
3028                 m_free( node->pkt );
3029                 node->pkt = newpkt;
3030                 modified = 1;
3031               }
3032             }
3033         }
3034     }
3035     
3036     free_secret_key( sk );
3037     return modified;
3038 }
3039
3040
3041 /****************
3042  * Select one user id or remove all selection if index is 0.
3043  * Returns: True if the selection changed;
3044  */
3045 static int
3046 menu_select_uid( KBNODE keyblock, int idx )
3047 {
3048     KBNODE node;
3049     int i;
3050
3051     /* first check that the index is valid */
3052     if( idx ) {
3053         for( i=0, node = keyblock; node; node = node->next ) {
3054             if( node->pkt->pkttype == PKT_USER_ID ) {
3055                 if( ++i == idx )
3056                     break;
3057             }
3058         }
3059         if( !node ) {
3060             tty_printf(_("No user ID with index %d\n"), idx );
3061             return 0;
3062         }
3063     }
3064     else { /* reset all */
3065         for( i=0, node = keyblock; node; node = node->next ) {
3066             if( node->pkt->pkttype == PKT_USER_ID )
3067                 node->flag &= ~NODFLG_SELUID;
3068         }
3069         return 1;
3070     }
3071     /* and toggle the new index */
3072     for( i=0, node = keyblock; node; node = node->next ) {
3073         if( node->pkt->pkttype == PKT_USER_ID ) {
3074             if( ++i == idx ) {
3075                 if( (node->flag & NODFLG_SELUID) )
3076                     node->flag &= ~NODFLG_SELUID;
3077                 else
3078                     node->flag |= NODFLG_SELUID;
3079             }
3080         }
3081     }
3082
3083     return 1;
3084 }
3085
3086 /****************
3087  * Select secondary keys
3088  * Returns: True if the selection changed;
3089  */
3090 static int
3091 menu_select_key( KBNODE keyblock, int idx )
3092 {
3093     KBNODE node;
3094     int i;
3095
3096     /* first check that the index is valid */
3097     if( idx ) {
3098         for( i=0, node = keyblock; node; node = node->next ) {
3099             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3100                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3101                 if( ++i == idx )
3102                     break;
3103             }
3104         }
3105         if( !node ) {
3106             tty_printf(_("No secondary key with index %d\n"), idx );
3107             return 0;
3108         }
3109     }
3110     else { /* reset all */
3111         for( i=0, node = keyblock; node; node = node->next ) {
3112             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3113                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3114                 node->flag &= ~NODFLG_SELKEY;
3115         }
3116         return 1;
3117     }
3118     /* and set the new index */
3119     for( i=0, node = keyblock; node; node = node->next ) {
3120         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3121             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3122             if( ++i == idx ) {
3123                 if( (node->flag & NODFLG_SELKEY) )
3124                     node->flag &= ~NODFLG_SELKEY;
3125                 else
3126                     node->flag |= NODFLG_SELKEY;
3127             }
3128         }
3129     }
3130
3131     return 1;
3132 }
3133
3134
3135 static int
3136 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3137 {
3138     KBNODE node;
3139     int i=0;
3140
3141     for( node = keyblock; node; node = node->next )
3142         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3143             i++;
3144     return i;
3145 }
3146
3147 static int
3148 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3149 {
3150     KBNODE node;
3151     int i=0;
3152
3153     for( node = keyblock; node; node = node->next )
3154         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3155               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3156             && (node->flag & flag) )
3157             i++;
3158     return i;
3159 }
3160
3161 static int
3162 count_uids( KBNODE keyblock )
3163 {
3164     KBNODE node;
3165     int i=0;
3166
3167     for( node = keyblock; node; node = node->next )
3168         if( node->pkt->pkttype == PKT_USER_ID )
3169             i++;
3170     return i;
3171 }
3172
3173
3174 /****************
3175  * Returns true if there is at least one selected user id
3176  */
3177 static int
3178 count_selected_uids( KBNODE keyblock )
3179 {
3180     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3181 }
3182
3183 static int
3184 count_selected_keys( KBNODE keyblock )
3185 {
3186     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3187 }
3188
3189 /* returns how many real (i.e. not attribute) uids are unmarked */
3190 static int
3191 real_uids_left( KBNODE keyblock )
3192 {
3193   KBNODE node;
3194   int real=0;
3195
3196   for(node=keyblock;node;node=node->next)
3197     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3198        !node->pkt->pkt.user_id->attrib_data)
3199       real++;
3200
3201   return real;
3202 }
3203
3204 /*
3205  * Ask whether the signature should be revoked.  If the user commits this,
3206  * flag bit MARK_A is set on the signature and the user ID.
3207  */
3208 static void
3209 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3210 {
3211     int doit=0;
3212     PKT_signature *sig = node->pkt->pkt.signature;
3213     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3214
3215     if( !unode ) {
3216         log_error("Oops: no user ID for signature\n");
3217         return;
3218     }
3219
3220     tty_printf(_("user ID: \""));
3221     tty_print_utf8_string( unode->pkt->pkt.user_id->name,
3222                            unode->pkt->pkt.user_id->len );
3223
3224     if(sig->flags.exportable)
3225       tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
3226                  (ulong)sig->keyid[1], datestr_from_sig(sig) );
3227     else
3228       tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"),
3229                  (ulong)sig->keyid[1], datestr_from_sig(sig) );
3230
3231     if(sig->flags.expired)
3232       {
3233         tty_printf(_("This signature expired on %s.\n"),
3234                    expirestr_from_sig(sig));
3235         /* Use a different question so we can have different help text */
3236         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3237                         _("Are you sure you still want to revoke it? (y/N) "));
3238       }
3239     else
3240       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3241               _("Create a revocation certificate for this signature? (y/N) "));
3242
3243     if(doit) {
3244       node->flag |= NODFLG_MARK_A;
3245       unode->flag |= NODFLG_MARK_A;
3246     }
3247 }
3248
3249 /****************
3250  * Display all user ids of the current public key together with signatures
3251  * done by one of our keys.  Then walk over all this sigs and ask the user
3252  * whether he wants to revoke this signature.
3253  * Return: True when the keyblock has changed.
3254  */
3255 static int
3256 menu_revsig( KBNODE keyblock )
3257 {
3258     PKT_signature *sig;
3259     PKT_public_key *primary_pk;
3260     KBNODE node;
3261     int changed = 0;
3262     int rc, any, skip=1, all=!count_selected_uids(keyblock);
3263     struct revocation_reason_info *reason = NULL;
3264
3265     /* FIXME: detect duplicates here  */
3266     tty_printf(_("You have signed these user IDs:\n"));
3267     for( node = keyblock; node; node = node->next ) {
3268         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
3269         if( node->pkt->pkttype == PKT_USER_ID ) {
3270             if( node->flag&NODFLG_SELUID || all ) {
3271