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