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