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