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