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