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