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