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