Add new SVN only file README.maint
[gnupg.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3  *               2006 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
1558     if(seckey_check)
1559       {/* see whether we have a matching secret key */
1560         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1561
1562         sec_kdbhd = keydb_new (1);
1563         {
1564             byte afp[MAX_FINGERPRINT_LEN];
1565             size_t an;
1566
1567             fingerprint_from_pk (pk, afp, &an);
1568             while (an < MAX_FINGERPRINT_LEN) 
1569                 afp[an++] = 0;
1570             rc = keydb_search_fpr (sec_kdbhd, afp);
1571         }
1572         if (!rc)
1573           {
1574             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1575             if (rc)
1576               {
1577                 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1578                            username, g10_errstr(rc));
1579               }
1580             else
1581               {
1582                 merge_keys_and_selfsig( sec_keyblock );
1583                 if( fix_keyblock( sec_keyblock ) )
1584                   sec_modified++;
1585               }
1586           }
1587
1588         if (rc) {
1589             sec_keyblock = NULL;
1590             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1591             rc = 0;
1592         }
1593
1594         if( sec_keyblock && !quiet )
1595           tty_printf(_("Secret key is available.\n"));
1596     }
1597
1598     toggle = 0;
1599     cur_keyblock = keyblock;
1600     for(;;) { /* main loop */
1601         int i, arg_number, photo;
1602         const char *arg_string = "";
1603         char *p;
1604         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1605
1606         tty_printf("\n");
1607
1608         if( redisplay && !quiet )
1609           {
1610             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1611             tty_printf("\n");
1612             redisplay = 0;
1613           }
1614         do {
1615             xfree(answer);
1616             if( have_commands ) {
1617                 if( commands ) {
1618                     answer = xstrdup( commands->d );
1619                     commands = commands->next;
1620                 }
1621                 else if( opt.batch ) {
1622                     answer = xstrdup("quit");
1623                 }
1624                 else
1625                     have_commands = 0;
1626             }
1627             if( !have_commands )
1628               {
1629 #ifdef HAVE_LIBREADLINE
1630                 tty_enable_completion(keyedit_completion);
1631 #endif
1632                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1633                 cpr_kill_prompt();
1634                 tty_disable_completion();
1635               }
1636             trim_spaces(answer);
1637         } while( *answer == '#' );
1638
1639         arg_number = 0; /* Yes, here is the init which egcc complains about */
1640         photo = 0; /* This too */
1641         if( !*answer )
1642             cmd = cmdLIST;
1643         else if( *answer == CONTROL_D )
1644             cmd = cmdQUIT;
1645         else if( digitp(answer ) ) {
1646             cmd = cmdSELUID;
1647             arg_number = atoi(answer);
1648         }
1649         else {
1650             if( (p=strchr(answer,' ')) ) {
1651                 *p++ = 0;
1652                 trim_spaces(answer);
1653                 trim_spaces(p);
1654                 arg_number = atoi(p);
1655                 arg_string = p;
1656             }
1657
1658             for(i=0; cmds[i].name; i++ )
1659               {
1660                 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1661                   {
1662                     size_t l=strlen(cmds[i].name);
1663                     size_t a=strlen(answer);
1664                     if(a>=l)
1665                       {
1666                         if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1667                           {
1668                             answer[a-l]='\0';
1669                             break;
1670                           }
1671                       }
1672                   }
1673                 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1674                   break;
1675               }
1676             if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1677               {
1678                 tty_printf(_("Need the secret key to do this.\n"));
1679                 cmd = cmdNOP;
1680               }
1681             else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1682                      && toggle)
1683                     ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1684                        && !toggle))
1685               {
1686                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1687                 cmd = cmdNOP;
1688               }
1689             else
1690               cmd = cmds[i].id;
1691         }
1692         switch( cmd )
1693           {
1694           case cmdHELP:
1695             for(i=0; cmds[i].name; i++ )
1696               {
1697                 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1698                   ; /* skip if we do not have the secret key */
1699                 else if( cmds[i].desc )
1700                   tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
1701               }
1702
1703             tty_printf("\n");
1704             tty_printf(_(
1705 "* The `sign' command may be prefixed with an `l' for local "
1706 "signatures (lsign),\n"
1707 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
1708 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
1709
1710             break;
1711
1712           case cmdLIST:
1713             redisplay = 1;
1714             break;
1715
1716           case cmdFPR:
1717             show_key_and_fingerprint( keyblock );
1718             break;
1719
1720           case cmdSELUID:
1721             if(strlen(arg_string)==NAMEHASH_LEN*2)
1722               redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
1723             else
1724               redisplay=menu_select_uid(cur_keyblock,arg_number);
1725             break;
1726
1727           case cmdSELKEY:
1728             if( menu_select_key( cur_keyblock, arg_number ) )
1729                 redisplay = 1;
1730             break;
1731
1732           case cmdCHECK:
1733             /* we can only do this with the public key becuase the
1734              * check functions can't cope with secret keys and it
1735              * is questionable whether this would make sense at all */
1736             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1737             break;
1738
1739           case cmdSIGN: /* sign (only the public key) */
1740             {
1741               int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
1742
1743               if( pk->is_revoked )
1744                 {
1745                   tty_printf(_("Key is revoked."));
1746
1747                   if(opt.expert)
1748                     {
1749                       tty_printf("  ");
1750                       if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1751                                                 _("Are you sure you still want"
1752                                                   " to sign it? (y/N) ")))
1753                         break;
1754                     }
1755                   else
1756                     {
1757                       tty_printf(_("  Unable to sign.\n"));
1758                       break;
1759                     }
1760                 }
1761
1762               if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
1763                  && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1764                                            _("Really sign all user IDs?"
1765                                              " (y/N) ")))
1766                 {
1767                   if(opt.interactive)
1768                     interactive=1;
1769                   else
1770                     {
1771                       tty_printf(_("Hint: Select the user IDs to sign\n"));
1772                       have_commands = 0;
1773                       break;
1774                     }
1775
1776                 }
1777               /* What sort of signing are we doing? */
1778               if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1779                 {
1780                   tty_printf(_("Unknown signature type `%s'\n"),answer);
1781                   break;
1782                 }
1783
1784               sign_uids(keyblock, locusr, &modified,
1785                         localsig, nonrevokesig, trustsig, interactive);
1786             }
1787             break;
1788
1789           case cmdDEBUG:
1790             dump_kbnode( cur_keyblock );
1791             break;
1792
1793           case cmdTOGGLE:
1794             toggle = !toggle;
1795             cur_keyblock = toggle? sec_keyblock : keyblock;
1796             redisplay = 1;
1797             break;
1798
1799           case cmdADDPHOTO:
1800             if (RFC2440 || RFC1991 || PGP2)
1801               {
1802                 tty_printf(
1803                    _("This command is not allowed while in %s mode.\n"),
1804                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1805                 break;
1806               }
1807             photo=1;
1808             /* fall through */
1809
1810           case cmdADDUID:
1811             if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
1812               {
1813                 update_trust = 1;
1814                 redisplay = 1;
1815                 sec_modified = modified = 1;
1816                 merge_keys_and_selfsig( sec_keyblock );
1817                 merge_keys_and_selfsig( keyblock );
1818               }
1819             break;
1820
1821           case cmdDELUID: {
1822                 int n1;
1823
1824                 if( !(n1=count_selected_uids(keyblock)) )
1825                     tty_printf(_("You must select at least one user ID.\n"));
1826                 else if( real_uids_left(keyblock) < 1 )
1827                     tty_printf(_("You can't delete the last user ID!\n"));
1828                 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1829                 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1830                             : _("Really remove this user ID? (y/N) ")
1831                        ) ) {
1832                     menu_deluid( keyblock, sec_keyblock );
1833                     redisplay = 1;
1834                     modified = 1;
1835                     if( sec_keyblock )
1836                        sec_modified = 1;
1837                 }
1838             }
1839             break;
1840
1841           case cmdDELSIG: {
1842                 int n1;
1843
1844                 if( !(n1=count_selected_uids(keyblock)) )
1845                     tty_printf(_("You must select at least one user ID.\n"));
1846                 else if( menu_delsig( keyblock ) ) {
1847                     /* no redisplay here, because it may scroll away some
1848                      * status output of delsig */
1849                     modified = 1;
1850                 }
1851             }
1852             break;
1853
1854           case cmdADDKEY:
1855             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1856                 redisplay = 1;
1857                 sec_modified = modified = 1;
1858                 merge_keys_and_selfsig( sec_keyblock );
1859                 merge_keys_and_selfsig( keyblock );
1860             }
1861             break;
1862
1863 #ifdef ENABLE_CARD_SUPPORT
1864           case cmdADDCARDKEY:
1865             if (card_generate_subkey (keyblock, sec_keyblock)) {
1866                 redisplay = 1;
1867                 sec_modified = modified = 1;
1868                 merge_keys_and_selfsig( sec_keyblock );
1869                 merge_keys_and_selfsig( keyblock );
1870             }
1871             break;
1872
1873         case cmdKEYTOCARD:
1874           {
1875             KBNODE node=NULL;
1876             switch ( count_selected_keys (sec_keyblock) )
1877               {
1878               case 0:
1879                 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1880                                      _("Really move the primary key? (y/N) ")))
1881                   node = sec_keyblock;
1882                 break;
1883               case 1:
1884                 for (node = sec_keyblock; node; node = node->next )
1885                   {
1886                     if (node->pkt->pkttype == PKT_SECRET_SUBKEY 
1887                         && node->flag & NODFLG_SELKEY)
1888                       break;
1889                   }
1890                 break;
1891               default:
1892                 tty_printf(_("You must select exactly one key.\n"));
1893                 break;
1894               }
1895             if (node)
1896               {
1897                 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1898                 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1899                   {
1900                     redisplay = 1;
1901                     sec_modified = 1;
1902                   }
1903               }
1904           }
1905           break;
1906
1907         case cmdBKUPTOCARD:
1908           {
1909             /* Ask for a filename, check whether this is really a
1910                backup key as generated by the card generation, parse
1911                that key and store it on card. */
1912             KBNODE node;
1913             const char *fname;
1914             PACKET *pkt;
1915             IOBUF a;
1916
1917             fname = arg_string;
1918             if (!*fname)
1919               {
1920                 tty_printf (_("Command expects a filename argument\n"));
1921                 break;
1922               }
1923
1924             /* Open that file.  */
1925             a = iobuf_open (fname);
1926             if (a && is_secured_file (iobuf_get_fd (a)))
1927               {
1928                 iobuf_close (a);
1929                 a = NULL;
1930                 errno = EPERM;
1931               }
1932             if (!a)
1933               {
1934                 tty_printf (_("Can't open `%s': %s\n"),
1935                             fname, strerror(errno));
1936                 break;
1937               }
1938             
1939             /* Parse and check that file.  */
1940             pkt = xmalloc (sizeof *pkt);
1941             init_packet (pkt);
1942             rc = parse_packet (a, pkt);
1943             iobuf_close (a);
1944             iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache).  */
1945             if (!rc 
1946                 && pkt->pkttype != PKT_SECRET_KEY 
1947                 && pkt->pkttype != PKT_SECRET_SUBKEY)
1948               rc = G10ERR_NO_SECKEY;
1949             if (rc)
1950               {
1951                 tty_printf(_("Error reading backup key from `%s': %s\n"),
1952                            fname, g10_errstr (rc));
1953                 free_packet (pkt);
1954                 xfree (pkt);
1955                 break;
1956               }
1957             node = new_kbnode (pkt);
1958
1959             /* Store it.  */
1960             if (card_store_subkey (node, 0))
1961               {
1962                 redisplay = 1;
1963                 sec_modified = 1;
1964               }
1965             release_kbnode (node);
1966           }
1967           break;
1968
1969 #endif /* ENABLE_CARD_SUPPORT */
1970
1971           case cmdDELKEY: {
1972                 int n1;
1973
1974                 if( !(n1=count_selected_keys( keyblock )) )
1975                     tty_printf(_("You must select at least one key.\n"));
1976                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1977                        n1 > 1?
1978                    _("Do you really want to delete the selected keys? (y/N) "):
1979                         _("Do you really want to delete this key? (y/N) ")
1980                        ))
1981                     ;
1982                 else {
1983                     menu_delkey( keyblock, sec_keyblock );
1984                     redisplay = 1;
1985                     modified = 1;
1986                     if( sec_keyblock )
1987                        sec_modified = 1;
1988                 }
1989             }
1990             break;
1991
1992           case cmdADDREVOKER:
1993             {
1994               int sensitive=0;
1995
1996               if(ascii_strcasecmp(arg_string,"sensitive")==0)
1997                 sensitive=1;
1998               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1999                 redisplay = 1;
2000                 sec_modified = modified = 1;
2001                 merge_keys_and_selfsig( sec_keyblock );
2002                 merge_keys_and_selfsig( keyblock );
2003               }
2004             }
2005             break;
2006
2007           case cmdREVUID: {
2008                 int n1;
2009
2010                 if( !(n1=count_selected_uids(keyblock)) )
2011                     tty_printf(_("You must select at least one user ID.\n"));
2012                 else if( cpr_get_answer_is_yes(
2013                             "keyedit.revoke.uid.okay",
2014                        n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
2015                              : _("Really revoke this user ID? (y/N) ")
2016                        ) ) {
2017                   if(menu_revuid(keyblock,sec_keyblock))
2018                     {
2019                       modified=1;
2020                       redisplay=1;
2021                     }
2022                 }
2023             }
2024             break;
2025
2026           case cmdREVKEY:
2027             {
2028               int n1;
2029
2030               if( !(n1=count_selected_keys( keyblock )) )
2031                 {
2032                   if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2033                                            _("Do you really want to revoke"
2034                                              " the entire key? (y/N) ")))
2035                     {
2036                       if(menu_revkey(keyblock,sec_keyblock))
2037                         modified=1;
2038
2039                       redisplay=1;
2040                     }
2041                 }
2042               else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2043                                             n1 > 1?
2044                                             _("Do you really want to revoke"
2045                                               " the selected subkeys? (y/N) "):
2046                                             _("Do you really want to revoke"
2047                                               " this subkey? (y/N) ")))
2048                 {
2049                   if( menu_revsubkey( keyblock, sec_keyblock ) )
2050                     modified = 1;
2051
2052                   redisplay = 1;
2053                 }
2054
2055               if(modified)
2056                 merge_keys_and_selfsig( keyblock );
2057             }
2058             break;
2059
2060           case cmdEXPIRE:
2061             if( menu_expire( keyblock, sec_keyblock ) )
2062               {
2063                 merge_keys_and_selfsig( sec_keyblock );
2064                 merge_keys_and_selfsig( keyblock );
2065                 sec_modified = 1;
2066                 modified = 1;
2067                 redisplay = 1;
2068               }
2069             break;
2070
2071           case cmdBACKSIGN:
2072             if(menu_backsign(keyblock,sec_keyblock))
2073               {
2074                 sec_modified = 1;
2075                 modified = 1;
2076                 redisplay = 1;
2077               }
2078             break;
2079
2080           case cmdPRIMARY:
2081             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
2082                 merge_keys_and_selfsig( keyblock );
2083                 modified = 1;
2084                 redisplay = 1;
2085             }
2086             break;
2087
2088           case cmdPASSWD:
2089             if( change_passphrase( sec_keyblock ) )
2090                 sec_modified = 1;
2091             break;
2092
2093           case cmdTRUST:
2094             if(opt.trust_model==TM_EXTERNAL)
2095               {
2096                 tty_printf(_("Owner trust may not be set while "
2097                              "using an user provided trust database\n"));
2098                 break;
2099               }
2100
2101             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
2102             tty_printf("\n");
2103             if( edit_ownertrust( find_kbnode( keyblock,
2104                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
2105                 redisplay = 1;
2106                 /* No real need to set update_trust here as
2107                    edit_ownertrust() calls revalidation_mark()
2108                    anyway. */
2109                 update_trust=1;
2110             }
2111             break;
2112
2113           case cmdPREF:
2114             {
2115               int count=count_selected_uids(keyblock);
2116               assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2117               show_names(keyblock,keyblock->pkt->pkt.public_key,
2118                          count?NODFLG_SELUID:0,1);
2119             }
2120             break;
2121
2122           case cmdSHOWPREF:
2123             {
2124               int count=count_selected_uids(keyblock);
2125               assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2126               show_names(keyblock,keyblock->pkt->pkt.public_key,
2127                          count?NODFLG_SELUID:0,2);
2128             }
2129             break;
2130
2131           case cmdSETPREF:
2132             {
2133               PKT_user_id *tempuid;
2134
2135               keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
2136
2137               tempuid=keygen_get_std_prefs();
2138               tty_printf(_("Set preference list to:\n"));
2139               show_prefs(tempuid,NULL,1);
2140               free_user_id(tempuid);
2141
2142               if(cpr_get_answer_is_yes("keyedit.setpref.okay",
2143                                        count_selected_uids (keyblock)?
2144                                        _("Really update the preferences"
2145                                          " for the selected user IDs? (y/N) "):
2146                                        _("Really update the preferences? (y/N) ")))
2147                 {
2148                   if ( menu_set_preferences (keyblock, sec_keyblock) )
2149                     {
2150                       merge_keys_and_selfsig (keyblock);
2151                       modified = 1;
2152                       redisplay = 1;
2153                     }
2154                 }
2155             }
2156             break;
2157
2158           case cmdPREFKS:
2159             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
2160                                          keyblock, sec_keyblock ) )
2161               {
2162                 merge_keys_and_selfsig( keyblock );
2163                 modified = 1;
2164                 redisplay = 1;
2165               }
2166             break;
2167
2168           case cmdNOTATION:
2169             if( menu_set_notation ( *arg_string?arg_string:NULL,
2170                                     keyblock, sec_keyblock ) )
2171               {
2172                 merge_keys_and_selfsig( keyblock );
2173                 modified = 1;
2174                 redisplay = 1;
2175               }
2176             break;
2177
2178           case cmdNOP:
2179             break;
2180
2181           case cmdREVSIG:
2182             if( menu_revsig( keyblock ) ) {
2183                 redisplay = 1;
2184                 modified = 1;
2185             }
2186             break;
2187
2188           case cmdENABLEKEY:
2189           case cmdDISABLEKEY:
2190             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
2191                 redisplay = 1;
2192                 modified = 1;
2193             }
2194             break;
2195
2196           case cmdSHOWPHOTO:
2197             menu_showphoto(keyblock);
2198             break;
2199
2200           case cmdCLEAN:
2201             redisplay=modified=menu_clean(keyblock,0);
2202             break;
2203
2204           case cmdMINIMIZE:
2205             redisplay=modified=menu_clean(keyblock,1);
2206             break;
2207
2208           case cmdQUIT:
2209             if( have_commands )
2210                 goto leave;
2211             if( !modified && !sec_modified )
2212                 goto leave;
2213             if( !cpr_get_answer_is_yes("keyedit.save.okay",
2214                                         _("Save changes? (y/N) ")) ) {
2215                 if( cpr_enabled()
2216                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
2217                                              _("Quit without saving? (y/N) ")))
2218                     goto leave;
2219                 break;
2220             }
2221             /* fall thru */
2222           case cmdSAVE:
2223             if( modified || sec_modified  ) {
2224                 if( modified ) {
2225                     rc = keydb_update_keyblock (kdbhd, keyblock);
2226                     if( rc ) {
2227                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
2228                         break;
2229                     }
2230                 }
2231                 if( sec_modified ) {
2232                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
2233                     if( rc ) {
2234                         log_error( _("update secret failed: %s\n"),
2235                                    g10_errstr(rc) );
2236                         break;
2237                     }
2238                 }
2239             }
2240             else
2241                 tty_printf(_("Key not changed so no update needed.\n"));
2242
2243             if( update_trust )
2244               {
2245                 revalidation_mark ();
2246                 update_trust=0;
2247               }
2248             goto leave;
2249
2250           case cmdINVCMD:
2251           default:
2252             tty_printf("\n");
2253             tty_printf(_("Invalid command  (try \"help\")\n"));
2254             break;
2255         }
2256     } /* end main loop */
2257
2258   leave:
2259     release_kbnode( keyblock );
2260     release_kbnode( sec_keyblock );
2261     keydb_release (kdbhd);
2262     xfree(answer);
2263 }
2264
2265 static void
2266 tty_print_notations(int indent,PKT_signature *sig)
2267 {
2268   int first=1;
2269   struct notation *notation,*nd;
2270
2271   if(indent<0)
2272     {
2273       first=0;
2274       indent=-indent;
2275     }
2276
2277   notation=sig_to_notation(sig);
2278
2279   for(nd=notation;nd;nd=nd->next)
2280     {
2281       if(!first)
2282         tty_printf("%*s",indent,"");
2283       else
2284         first=0;
2285
2286       tty_print_utf8_string(nd->name,strlen(nd->name));
2287       tty_printf("=");
2288       tty_print_utf8_string(nd->value,strlen(nd->value));
2289       tty_printf("\n");
2290     }
2291
2292   free_notation(notation);
2293 }
2294
2295 /****************
2296  * show preferences of a public keyblock.
2297  */
2298 static void
2299 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
2300 {
2301     const prefitem_t fake={0,0};
2302     const prefitem_t *prefs;
2303     int i;
2304
2305     if( !uid )
2306         return;
2307
2308     if( uid->prefs )
2309         prefs=uid->prefs;
2310     else if(verbose)
2311         prefs=&fake;
2312     else
2313       return;
2314
2315     if (verbose) {
2316         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
2317
2318         tty_printf ("     ");
2319         tty_printf (_("Cipher: "));
2320         for(i=any=0; prefs[i].type; i++ ) {
2321             if( prefs[i].type == PREFTYPE_SYM ) {
2322                 if (any)
2323                     tty_printf (", ");
2324                 any = 1;
2325                 /* We don't want to display strings for experimental algos */
2326                 if (!gcry_cipher_test_algo (prefs[i].value)
2327                     && prefs[i].value < 100 )
2328                     tty_printf ("%s", gcry_cipher_algo_name (prefs[i].value));
2329                 else
2330                     tty_printf ("[%d]", prefs[i].value);
2331                 if (prefs[i].value == CIPHER_ALGO_3DES )
2332                     des_seen = 1;
2333             }    
2334         }
2335         if (!des_seen) {
2336             if (any)
2337                 tty_printf (", ");
2338             tty_printf ("%s", gcry_cipher_algo_name (CIPHER_ALGO_3DES));
2339         }
2340         tty_printf ("\n     ");
2341         tty_printf (_("Digest: "));
2342         for(i=any=0; prefs[i].type; i++ ) {
2343             if( prefs[i].type == PREFTYPE_HASH ) {
2344                 if (any)
2345                     tty_printf (", ");
2346                 any = 1;
2347                 /* We don't want to display strings for experimental algos */
2348                 if (!gcry_md_test_algo (prefs[i].value)
2349                     && prefs[i].value < 100 )
2350                     tty_printf ("%s", gcry_md_algo_name (prefs[i].value) );
2351                 else
2352                     tty_printf ("[%d]", prefs[i].value);
2353                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2354                     sha1_seen = 1;
2355             }
2356         }
2357         if (!sha1_seen) {
2358             if (any)
2359                 tty_printf (", ");
2360             tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
2361         }
2362         tty_printf ("\n     ");
2363         tty_printf (_("Compression: "));
2364         for(i=any=0; prefs[i].type; i++ ) {
2365             if( prefs[i].type == PREFTYPE_ZIP ) {
2366                 const char *s=compress_algo_to_string(prefs[i].value);
2367                 
2368                 if (any)
2369                     tty_printf (", ");
2370                 any = 1;
2371                 /* We don't want to display strings for experimental algos */
2372                 if (s && prefs[i].value < 100 )
2373                     tty_printf ("%s", s );
2374                 else
2375                     tty_printf ("[%d]", prefs[i].value);
2376                 if (prefs[i].value == COMPRESS_ALGO_NONE )
2377                     uncomp_seen = 1;
2378             }
2379         }
2380         if (!uncomp_seen) {
2381             if (any)
2382                 tty_printf (", ");
2383             else {
2384               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2385               tty_printf (", ");
2386             }
2387             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2388         }
2389         if(uid->flags.mdc || !uid->flags.ks_modify)
2390           {
2391             tty_printf ("\n     ");
2392             tty_printf (_("Features: "));
2393             any=0;
2394             if(uid->flags.mdc)
2395               {
2396                 tty_printf ("MDC");
2397                 any=1;
2398               }
2399             if(!uid->flags.ks_modify)
2400               {
2401                 if(any)
2402                   tty_printf (", ");
2403                 tty_printf (_("Keyserver no-modify"));
2404               }
2405           }
2406         tty_printf("\n");
2407
2408         if(selfsig)
2409           {
2410             const byte *pref_ks;
2411             size_t pref_ks_len;
2412
2413             pref_ks=parse_sig_subpkt(selfsig->hashed,
2414                                      SIGSUBPKT_PREF_KS,&pref_ks_len);
2415             if(pref_ks && pref_ks_len)
2416               {
2417                 tty_printf ("     ");
2418                 tty_printf(_("Preferred keyserver: "));
2419                 tty_print_utf8_string(pref_ks,pref_ks_len);
2420                 tty_printf("\n");
2421               }
2422
2423             if(selfsig->flags.notation)
2424               {
2425                 tty_printf ("     ");
2426                 tty_printf(_("Notations: "));
2427                 tty_print_notations(5+strlen(_("Notations: ")),selfsig);
2428               }
2429           }
2430     }
2431     else {
2432         tty_printf("    ");
2433         for(i=0; prefs[i].type; i++ ) {
2434             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
2435                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
2436                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2437                                  prefs[i].value);
2438         }
2439         if (uid->flags.mdc)
2440             tty_printf (" [mdc]");
2441         if (!uid->flags.ks_modify)
2442             tty_printf (" [no-ks-modify]");
2443         tty_printf("\n");
2444     }
2445 }
2446
2447 /* This is the version of show_key_with_all_names used when
2448    opt.with_colons is used.  It prints all available data in a easy to
2449    parse format and does not translate utf8 */
2450 static void
2451 show_key_with_all_names_colon (KBNODE keyblock)
2452 {
2453   KBNODE node;
2454   int i, j, ulti_hack=0;
2455   byte pk_version=0;
2456   PKT_public_key *primary=NULL;
2457
2458   /* the keys */
2459   for ( node = keyblock; node; node = node->next )
2460     {
2461       if (node->pkt->pkttype == PKT_PUBLIC_KEY
2462           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2463         {
2464           PKT_public_key *pk = node->pkt->pkt.public_key;
2465           u32 keyid[2];
2466
2467           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2468             {
2469               pk_version = pk->version;
2470               primary=pk;
2471             }
2472
2473           keyid_from_pk (pk, keyid);
2474
2475           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2476           if (!pk->is_valid)
2477             putchar ('i');
2478           else if (pk->is_revoked)
2479             putchar ('r');
2480           else if (pk->has_expired)
2481             putchar ('e');
2482           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2483             {
2484               int trust = get_validity_info (pk, NULL);
2485               if(trust=='u')
2486                 ulti_hack=1;
2487               putchar (trust);
2488             }
2489
2490           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2491                   nbits_from_pk (pk),
2492                   pk->pubkey_algo,
2493                   (ulong)keyid[0], (ulong)keyid[1],
2494                   (ulong)pk->timestamp,
2495                   (ulong)pk->expiredate );
2496           if (node->pkt->pkttype==PKT_PUBLIC_KEY
2497               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2498             putchar(get_ownertrust_info (pk));
2499           putchar(':');
2500           putchar('\n');
2501           
2502           print_fingerprint (pk, NULL, 0);
2503           print_revokers(pk);
2504         }
2505     }
2506   
2507     /* the user ids */
2508     i = 0;
2509     for (node = keyblock; node; node = node->next) 
2510       {
2511         if ( node->pkt->pkttype == PKT_USER_ID )
2512           {
2513             PKT_user_id *uid = node->pkt->pkt.user_id;
2514
2515             ++i;
2516
2517             if(uid->attrib_data)
2518               printf("uat:");
2519             else
2520               printf("uid:");
2521
2522             if ( uid->is_revoked )
2523               printf("r::::::::");
2524             else if ( uid->is_expired )
2525               printf("e::::::::");
2526             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2527               printf("::::::::");
2528             else
2529               {
2530                 int uid_validity;
2531
2532                 if( primary && !ulti_hack )
2533                   uid_validity = get_validity_info( primary, uid );
2534                 else
2535                   uid_validity = 'u';
2536                 printf("%c::::::::",uid_validity);
2537               }
2538
2539             if(uid->attrib_data)
2540               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2541             else
2542               print_string (stdout, uid->name, uid->len, ':');
2543
2544             putchar (':');
2545             /* signature class */
2546             putchar (':');
2547             /* capabilities */
2548             putchar (':');
2549             /* preferences */
2550             if (pk_version>3 || uid->selfsigversion>3)
2551               {
2552                 const prefitem_t *prefs = uid->prefs;
2553                 
2554                 for (j=0; prefs && prefs[j].type; j++)
2555                   {
2556                     if (j)
2557                       putchar (' ');
2558                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2559                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2560                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2561                             prefs[j].value);
2562                   } 
2563                 if (uid->flags.mdc)
2564                   printf (",mdc");
2565                 if (!uid->flags.ks_modify)
2566                   printf (",no-ks-modify");
2567               } 
2568             putchar (':');
2569             /* flags */
2570             printf ("%d,", i);
2571             if (uid->is_primary)
2572               putchar ('p');
2573             if (uid->is_revoked)
2574               putchar ('r');
2575             if (uid->is_expired)
2576               putchar ('e');
2577             if ((node->flag & NODFLG_SELUID))
2578               putchar ('s');
2579             if ((node->flag & NODFLG_MARK_A))
2580               putchar ('m');
2581             putchar (':');
2582             putchar('\n');
2583           }
2584       }
2585 }
2586
2587 static void
2588 show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
2589 {
2590   KBNODE node;
2591   int i=0;
2592
2593   for( node = keyblock; node; node = node->next )
2594     {
2595       if( node->pkt->pkttype == PKT_USER_ID
2596           && !is_deleted_kbnode(node))
2597         {
2598           PKT_user_id *uid = node->pkt->pkt.user_id;
2599           ++i;
2600           if(!flag || (flag && (node->flag & flag)))
2601             {
2602               if(!(flag&NODFLG_MARK_A) && pk)
2603                 tty_printf("%s ",uid_trust_string_fixed(pk,uid));
2604
2605               if( flag & NODFLG_MARK_A )
2606                 tty_printf("     ");
2607               else if( node->flag & NODFLG_SELUID )
2608                 tty_printf("(%d)* ", i);
2609               else if( uid->is_primary )
2610                 tty_printf("(%d). ", i);
2611               else
2612                 tty_printf("(%d)  ", i);
2613               tty_print_utf8_string( uid->name, uid->len );
2614               tty_printf("\n");
2615               if(with_prefs && pk)
2616                 {
2617                   if(pk->version>3 || uid->selfsigversion>3)
2618                     {
2619                       PKT_signature *selfsig=NULL;
2620                       KBNODE signode;
2621
2622                       for(signode=node->next;
2623                           signode && signode->pkt->pkttype==PKT_SIGNATURE;
2624                           signode=signode->next)
2625                         {
2626                           if(signode->pkt->pkt.signature->
2627                              flags.chosen_selfsig)
2628                             {
2629                               selfsig=signode->pkt->pkt.signature;
2630                               break;
2631                             }
2632                         }
2633
2634                       show_prefs (uid, selfsig, with_prefs == 2);
2635                     }
2636                   else
2637                     tty_printf(_("There are no preferences on a"
2638                                  " PGP 2.x-style user ID.\n"));
2639                 }
2640             }
2641         }
2642     }
2643 }
2644
2645 /****************
2646  * Display the key a the user ids, if only_marked is true, do only
2647  * so for user ids with mark A flag set and dont display the index number
2648  */
2649 static void
2650 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2651                          int with_fpr, int with_subkeys, int with_prefs )
2652 {
2653     KBNODE node;
2654     int i;
2655     int do_warn = 0;
2656     byte pk_version=0;
2657     PKT_public_key *primary=NULL;
2658
2659     if (opt.with_colons)
2660       {
2661         show_key_with_all_names_colon (keyblock);
2662         return;
2663       }
2664
2665     /* the keys */
2666     for( node = keyblock; node; node = node->next ) {
2667         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2668             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2669                 && !is_deleted_kbnode(node)) ) {
2670             PKT_public_key *pk = node->pkt->pkt.public_key;
2671             const char *otrust="err",*trust="err";
2672
2673             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2674                 /* do it here, so that debug messages don't clutter the
2675                  * output */
2676                 static int did_warn = 0;
2677
2678                 trust = get_validity_string (pk, NULL);
2679                 otrust = get_ownertrust_string (pk);
2680
2681                 /* Show a warning once */
2682                 if (!did_warn
2683                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2684                     did_warn = 1;
2685                     do_warn = 1;
2686                 }
2687
2688                 pk_version=pk->version;
2689                 primary=pk;
2690             }
2691
2692             if(pk->is_revoked)
2693               {
2694                 char *user=get_user_id_string_native(pk->revoked.keyid);
2695                 const char *algo = gcry_pk_algo_name (pk->revoked.algo);
2696                 tty_printf(_("This key was revoked on %s by %s key %s\n"),
2697                            revokestr_from_pk(pk),algo?algo:"?",user);
2698                 xfree(user);
2699               }
2700
2701             if(with_revoker)
2702               {
2703                 if( !pk->revkey && pk->numrevkeys )
2704                   BUG();
2705                 else
2706                   for(i=0;i<pk->numrevkeys;i++)
2707                     {
2708                       u32 r_keyid[2];
2709                       char *user;
2710                       const char *algo;
2711
2712                       algo = gcry_pk_algo_name (pk->revkey[i].algid);
2713                       keyid_from_fingerprint(pk->revkey[i].fpr,
2714                                              MAX_FINGERPRINT_LEN,r_keyid);
2715
2716                       user=get_user_id_string_native(r_keyid);
2717                       tty_printf(_("This key may be revoked by %s key %s"),
2718                                  algo?algo:"?",user);
2719
2720                       if(pk->revkey[i].class&0x40)
2721                         {
2722                           tty_printf(" ");
2723                           tty_printf(_("(sensitive)"));
2724                         }
2725
2726                       tty_printf ("\n");
2727                       xfree(user);
2728                     }
2729               }
2730
2731             keyid_from_pk(pk,NULL);
2732             tty_printf("%s%c %4u%c/%s  ",
2733                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2734                        (node->flag & NODFLG_SELKEY)? '*':' ',
2735                        nbits_from_pk( pk ),
2736                        pubkey_letter( pk->pubkey_algo ),
2737                        keystr(pk->keyid));
2738
2739             tty_printf(_("created: %s"),datestr_from_pk(pk));
2740             tty_printf("  ");
2741             if(pk->is_revoked)
2742               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2743             else if(pk->has_expired)
2744               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2745             else
2746               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2747             tty_printf("  ");
2748             tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2749             tty_printf("\n");
2750
2751             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2752               {
2753                 if(opt.trust_model!=TM_ALWAYS)
2754                   {
2755                     tty_printf("%*s", (int)keystrlen()+13,"");
2756                     /* Ownertrust is only meaningful for the PGP or
2757                        classic trust models */
2758                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2759                       {
2760                         int width=14-strlen(otrust);
2761                         if(width<=0)
2762                           width=1;
2763                         tty_printf(_("trust: %s"), otrust);
2764                         tty_printf("%*s",width,"");
2765                       }
2766                     
2767                     tty_printf(_("validity: %s"), trust );
2768                     tty_printf("\n");
2769                   }
2770                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2771                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2772                   {
2773                     tty_printf("*** ");
2774                     tty_printf(_("This key has been disabled"));
2775                     tty_printf("\n");
2776                   }
2777               }
2778
2779             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2780               {
2781                 print_fingerprint ( pk, NULL, 2 );
2782                 tty_printf("\n");
2783               }
2784         }
2785         else if( node->pkt->pkttype == PKT_SECRET_KEY
2786             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2787           {
2788             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2789             tty_printf("%s%c %4u%c/%s  ",
2790                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2791                        (node->flag & NODFLG_SELKEY)? '*':' ',
2792                        nbits_from_sk( sk ),
2793                        pubkey_letter( sk->pubkey_algo ),
2794                        keystr_from_sk(sk));
2795             tty_printf(_("created: %s"),datestr_from_sk(sk));
2796             tty_printf("  ");
2797             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2798             tty_printf("\n");
2799             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2800               {
2801                 tty_printf("                     ");
2802                 tty_printf(_("card-no: ")); 
2803                 if (sk->protect.ivlen == 16
2804                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2805                   { /* This is an OpenPGP card. */
2806                     for (i=8; i < 14; i++)
2807                       {
2808                         if (i == 10)
2809                           tty_printf (" ");
2810                         tty_printf ("%02X", sk->protect.iv[i]);
2811                       }
2812                   }
2813                 else
2814                   { /* Something is wrong: Print all. */
2815                     for (i=0; i < sk->protect.ivlen; i++)
2816                       tty_printf ("%02X", sk->protect.iv[i]);
2817                   }
2818                 tty_printf ("\n");
2819               }
2820           }
2821     }
2822
2823     show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
2824
2825     if (do_warn)
2826         tty_printf (_("Please note that the shown key validity"
2827                       " is not necessarily correct\n"
2828                       "unless you restart the program.\n")); 
2829 }
2830
2831
2832 /* Display basic key information.  This function is suitable to show
2833    information on the key without any dependencies on the trustdb or
2834    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2835    a secret key.*/
2836 void
2837 show_basic_key_info ( KBNODE keyblock )
2838 {
2839   KBNODE node;
2840   int i;
2841
2842   /* The primary key */
2843   for (node = keyblock; node; node = node->next)
2844     {
2845       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2846         {
2847           PKT_public_key *pk = node->pkt->pkt.public_key;
2848           
2849           /* Note, we use the same format string as in other show
2850              functions to make the translation job easier. */
2851           tty_printf ("%s  %4u%c/%s  ",
2852                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2853                       nbits_from_pk( pk ),
2854                       pubkey_letter( pk->pubkey_algo ),
2855                       keystr_from_pk(pk));
2856           tty_printf(_("created: %s"),datestr_from_pk(pk));
2857           tty_printf("  ");
2858           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2859           tty_printf("\n");
2860           print_fingerprint ( pk, NULL, 3 );
2861           tty_printf("\n");
2862         }
2863       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2864         {
2865           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2866           tty_printf("%s  %4u%c/%s",
2867                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2868                      nbits_from_sk( sk ),
2869                      pubkey_letter( sk->pubkey_algo ),
2870                      keystr_from_sk(sk));
2871           tty_printf(_("created: %s"),datestr_from_sk(sk));
2872           tty_printf("  ");
2873           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2874           tty_printf("\n");
2875           print_fingerprint (NULL, sk, 3 );
2876           tty_printf("\n");
2877         }
2878     }
2879
2880   /* The user IDs. */
2881   for (i=0, node = keyblock; node; node = node->next)
2882     {
2883       if (node->pkt->pkttype == PKT_USER_ID)
2884         {
2885           PKT_user_id *uid = node->pkt->pkt.user_id;
2886           ++i;
2887      
2888           tty_printf ("     ");
2889           if (uid->is_revoked)
2890             tty_printf("[%s] ",_("revoked"));
2891           else if ( uid->is_expired )
2892             tty_printf("[%s] ",_("expired"));
2893           tty_print_utf8_string (uid->name, uid->len);
2894           tty_printf ("\n");
2895         }
2896     }
2897 }
2898
2899 static void
2900 show_key_and_fingerprint( KBNODE keyblock )
2901 {
2902   KBNODE node;
2903   PKT_public_key *pk = NULL;
2904
2905   for( node = keyblock; node; node = node->next )
2906     {
2907       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2908         {
2909           pk = node->pkt->pkt.public_key;
2910           tty_printf("pub   %4u%c/%s %s ",
2911                      nbits_from_pk( pk ),
2912                      pubkey_letter( pk->pubkey_algo ),
2913                      keystr_from_pk(pk),
2914                      datestr_from_pk(pk) );
2915         }
2916       else if( node->pkt->pkttype == PKT_USER_ID )
2917         {
2918           PKT_user_id *uid = node->pkt->pkt.user_id;
2919           tty_print_utf8_string( uid->name, uid->len );
2920           break;
2921         }
2922     }
2923   tty_printf("\n");
2924   if( pk )
2925     print_fingerprint( pk, NULL, 2 );
2926 }
2927
2928
2929 /* Show a warning if no uids on the key have the primary uid flag
2930    set. */
2931 static void
2932 no_primary_warning(KBNODE keyblock)
2933 {
2934   KBNODE node;
2935   int have_primary=0,uid_count=0;
2936
2937   /* TODO: if we ever start behaving differently with a primary or
2938      non-primary attribute ID, we will need to check for attributes
2939      here as well. */
2940
2941   for(node=keyblock; node; node = node->next)
2942     {
2943       if(node->pkt->pkttype==PKT_USER_ID
2944          && node->pkt->pkt.user_id->attrib_data==NULL)
2945         {
2946           uid_count++;
2947
2948           if(node->pkt->pkt.user_id->is_primary==2)
2949             {
2950               have_primary=1;
2951               break;
2952             }
2953         }
2954     }
2955
2956   if(uid_count>1 && !have_primary)
2957     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2958                " may\n              cause a different user ID to become"
2959                " the assumed primary.\n"));
2960 }
2961
2962 /****************
2963  * Ask for a new user id, do the selfsignature and put it into
2964  * both keyblocks.
2965  * Return true if there is a new user id
2966  */
2967 static int
2968 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
2969              int photo, const char *photo_name)
2970 {
2971     PKT_user_id *uid;
2972     PKT_public_key *pk=NULL;
2973     PKT_secret_key *sk=NULL;
2974     PKT_signature *sig=NULL;
2975     PACKET *pkt;
2976     KBNODE node;
2977     KBNODE pub_where=NULL, sec_where=NULL;
2978     int rc;
2979
2980     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2981         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2982             pk = node->pkt->pkt.public_key;
2983         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2984             break;
2985     }
2986     if( !node ) /* no subkey */
2987         pub_where = NULL;
2988     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2989         if( node->pkt->pkttype == PKT_SECRET_KEY )
2990             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2991         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2992             break;
2993     }
2994     if( !node ) /* no subkey */
2995         sec_where = NULL;
2996     assert(pk && sk);
2997
2998     if(photo) {
2999       int hasattrib=0;
3000
3001       for( node = pub_keyblock; node; node = node->next )
3002         if( node->pkt->pkttype == PKT_USER_ID &&
3003             node->pkt->pkt.user_id->attrib_data!=NULL)
3004           {
3005             hasattrib=1;
3006             break;
3007           }
3008
3009       /* It is legal but bad for compatibility to add a photo ID to a
3010          v3 key as it means that PGP2 will not be able to use that key
3011          anymore.  Also, PGP may not expect a photo on a v3 key.
3012          Don't bother to ask this if the key already has a photo - any
3013          damage has already been done at that point. -dms */
3014       if(pk->version==3 && !hasattrib)
3015         {
3016           if(opt.expert)
3017             {
3018               tty_printf(_("WARNING: This is a PGP2-style key.  "
3019                            "Adding a photo ID may cause some versions\n"
3020                            "         of PGP to reject this key.\n"));
3021
3022               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
3023                                         _("Are you sure you still want "
3024                                           "to add it? (y/N) ")))
3025                 return 0;
3026             }
3027           else
3028             {
3029               tty_printf(_("You may not add a photo ID to "
3030                            "a PGP2-style key.\n"));
3031               return 0;
3032             }
3033         }
3034
3035       uid = generate_photo_id(pk,photo_name);
3036     } else
3037       uid = generate_user_id();
3038     if( !uid )
3039         return 0;
3040
3041     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
3042                              keygen_add_std_prefs, pk );
3043     free_secret_key( sk );
3044     if( rc ) {
3045         log_error("signing failed: %s\n", g10_errstr(rc) );
3046         free_user_id(uid);
3047         return 0;
3048     }
3049
3050     /* insert/append to secret keyblock */
3051     pkt = xmalloc_clear( sizeof *pkt );
3052     pkt->pkttype = PKT_USER_ID;
3053     pkt->pkt.user_id = scopy_user_id(uid);
3054     node = new_kbnode(pkt);
3055     if( sec_where )
3056         insert_kbnode( sec_where, node, 0 );
3057     else
3058         add_kbnode( sec_keyblock, node );
3059     pkt = xmalloc_clear( sizeof *pkt );
3060     pkt->pkttype = PKT_SIGNATURE;
3061     pkt->pkt.signature = copy_signature(NULL, sig);
3062     if( sec_where )
3063         insert_kbnode( node, new_kbnode(pkt), 0 );
3064     else
3065         add_kbnode( sec_keyblock, new_kbnode(pkt) );
3066     /* insert/append to public keyblock */
3067     pkt = xmalloc_clear( sizeof *pkt );
3068     pkt->pkttype = PKT_USER_ID;
3069     pkt->pkt.user_id = uid;
3070     node = new_kbnode(pkt);
3071     if( pub_where )
3072         insert_kbnode( pub_where, node, 0 );
3073     else
3074         add_kbnode( pub_keyblock, node );
3075     pkt = xmalloc_clear( sizeof *pkt );
3076     pkt->pkttype = PKT_SIGNATURE;
3077     pkt->pkt.signature = copy_signature(NULL, sig);
3078     if( pub_where )
3079         insert_kbnode( node, new_kbnode(pkt), 0 );
3080     else
3081         add_kbnode( pub_keyblock, new_kbnode(pkt) );
3082     return 1;
3083 }
3084
3085
3086 /****************
3087  * Remove all selected userids from the keyrings
3088  */
3089 static void
3090 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3091 {
3092     KBNODE node;
3093     int selected=0;
3094
3095     for( node = pub_keyblock; node; node = node->next ) {
3096         if( node->pkt->pkttype == PKT_USER_ID ) {
3097             selected = node->flag & NODFLG_SELUID;
3098             if( selected ) {
3099                 /* Only cause a trust update if we delete a
3100                    non-revoked user id */
3101                 if(!node->pkt->pkt.user_id->is_revoked)
3102                   update_trust=1;
3103                 delete_kbnode( node );
3104                 if( sec_keyblock ) {
3105                     KBNODE snode;
3106                     int s_selected = 0;
3107                     PKT_user_id *uid = node->pkt->pkt.user_id;
3108                     for( snode = sec_keyblock; snode; snode = snode->next ) {
3109                         if( snode->pkt->pkttype == PKT_USER_ID ) {
3110                             PKT_user_id *suid = snode->pkt->pkt.user_id;
3111
3112                             s_selected =
3113                                 (uid->len == suid->len
3114                                  && !memcmp( uid->name, suid->name, uid->len));
3115                             if( s_selected )
3116                                 delete_kbnode( snode );
3117                         }
3118                         else if( s_selected
3119                                  && snode->pkt->pkttype == PKT_SIGNATURE )
3120                             delete_kbnode( snode );
3121                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
3122                             s_selected = 0;
3123                     }
3124                 }
3125             }
3126         }
3127         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3128             delete_kbnode( node );
3129         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3130             selected = 0;
3131     }
3132     commit_kbnode( &pub_keyblock );
3133     if( sec_keyblock )
3134         commit_kbnode( &sec_keyblock );
3135 }
3136
3137
3138 static int
3139 menu_delsig( KBNODE pub_keyblock )
3140 {
3141     KBNODE node;
3142     PKT_user_id *uid = NULL;
3143     int changed=0;
3144
3145     for( node = pub_keyblock; node; node = node->next ) {
3146         if( node->pkt->pkttype == PKT_USER_ID ) {
3147             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
3148         }
3149         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3150            int okay, valid, selfsig, inv_sig, no_key, other_err;
3151
3152             tty_printf("uid  ");
3153             tty_print_utf8_string( uid->name, uid->len );
3154             tty_printf("\n");
3155
3156             okay = inv_sig = no_key = other_err = 0;
3157             if(opt.with_colons)
3158               valid = print_and_check_one_sig_colon( pub_keyblock, node,
3159                                                &inv_sig, &no_key, &other_err,
3160                                                &selfsig, 1 );
3161             else
3162               valid = print_and_check_one_sig( pub_keyblock, node,
3163                                                &inv_sig, &no_key, &other_err,
3164                                                &selfsig, 1 );
3165
3166            if( valid ) {
3167                okay = cpr_get_answer_yes_no_quit(
3168                    "keyedit.delsig.valid",
3169                    _("Delete this good signature? (y/N/q)"));
3170
3171                /* Only update trust if we delete a good signature.
3172                   The other two cases do not affect trust. */
3173                if(okay)
3174                  update_trust=1;
3175            }
3176            else if( inv_sig || other_err )
3177                okay = cpr_get_answer_yes_no_quit(
3178                    "keyedit.delsig.invalid",
3179                    _("Delete this invalid signature? (y/N/q)"));
3180            else if( no_key )
3181                okay = cpr_get_answer_yes_no_quit(
3182                    "keyedit.delsig.unknown",
3183                    _("Delete this unknown signature? (y/N/q)"));
3184
3185             if( okay == -1 )
3186                 break;
3187            if( okay && selfsig && !cpr_get_answer_is_yes(
3188                                "keyedit.delsig.selfsig",
3189                               _("Really delete this self-signature? (y/N)") ))
3190                 okay = 0;
3191             if( okay ) {
3192                 delete_kbnode( node );
3193                 changed++;
3194             }
3195
3196         }
3197         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3198             uid = NULL;
3199     }
3200
3201     if( changed ) {
3202         commit_kbnode( &pub_keyblock );
3203         tty_printf( changed == 1? _("Deleted %d signature.\n")
3204                                 : _("Deleted %d signatures.\n"), changed );
3205     }
3206     else
3207         tty_printf( _("Nothing deleted.\n") );
3208
3209     return changed;
3210 }
3211
3212 static int
3213 menu_clean(KBNODE keyblock,int self_only)
3214 {
3215   KBNODE uidnode;
3216   int modified=0,select_all=!count_selected_uids(keyblock);
3217
3218   for(uidnode=keyblock->next;
3219       uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
3220       uidnode=uidnode->next)
3221     {
3222       if(uidnode->pkt->pkttype==PKT_USER_ID
3223          && (uidnode->flag&NODFLG_SELUID || select_all))
3224         {
3225           int uids=0,sigs=0;
3226           char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3227                                     uidnode->pkt->pkt.user_id->len,
3228                                     0);
3229
3230           clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
3231           if(uids)
3232             {
3233               const char *reason;
3234
3235               if(uidnode->pkt->pkt.user_id->is_revoked)
3236                 reason=_("revoked");
3237               else if(uidnode->pkt->pkt.user_id->is_expired)
3238                 reason=_("expired");
3239               else
3240                 reason=_("invalid");
3241
3242               tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
3243
3244               modified=1;
3245             }
3246           else if(sigs)
3247             {
3248               tty_printf(sigs==1?
3249                          _("User ID \"%s\": %d signature removed\n") :
3250                          _("User ID \"%s\": %d signatures removed\n"),
3251                          user,sigs);
3252
3253               modified=1;
3254             }
3255           else
3256             {
3257               tty_printf (self_only==1?
3258                           _("User ID \"%s\": already minimized\n") :
3259                           _("User ID \"%s\": already clean\n"),
3260                           user);
3261             }
3262
3263           xfree(user);
3264         }
3265     }
3266
3267   return modified;
3268 }
3269
3270 /****************
3271  * Remove some of the secondary keys
3272  */
3273 static void
3274 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3275 {
3276     KBNODE node;
3277     int selected=0;
3278
3279     for( node = pub_keyblock; node; node = node->next ) {
3280         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3281             selected = node->flag & NODFLG_SELKEY;
3282             if( selected ) {
3283                 delete_kbnode( node );
3284                 if( sec_keyblock ) {
3285                     KBNODE snode;
3286                     int s_selected = 0;
3287                     u32 ki[2];
3288
3289                     keyid_from_pk( node->pkt->pkt.public_key, ki );
3290                     for( snode = sec_keyblock; snode; snode = snode->next ) {
3291                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3292                             u32 ki2[2];
3293
3294                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
3295                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
3296                             if( s_selected )
3297                                 delete_kbnode( snode );
3298                         }
3299                         else if( s_selected
3300                                  && snode->pkt->pkttype == PKT_SIGNATURE )
3301                             delete_kbnode( snode );
3302                         else
3303                             s_selected = 0;
3304                     }
3305                 }
3306             }
3307         }
3308         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3309             delete_kbnode( node );
3310         else
3311             selected = 0;
3312     }
3313     commit_kbnode( &pub_keyblock );
3314     if( sec_keyblock )
3315         commit_kbnode( &sec_keyblock );
3316
3317     /* No need to set update_trust here since signing keys are no
3318        longer used to certify other keys, so there is no change in
3319        trust when revoking/removing them */
3320 }
3321
3322
3323 /****************
3324  * Ask for a new revoker, do the selfsignature and put it into
3325  * both keyblocks.
3326  * Return true if there is a new revoker
3327  */
3328 static int
3329 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
3330 {
3331   PKT_public_key *pk=NULL,*revoker_pk=NULL;
3332   PKT_secret_key *sk=NULL;
3333   PKT_signature *sig=NULL;
3334   PACKET *pkt;
3335   struct revocation_key revkey;
3336   size_t fprlen;
3337   int rc;
3338
3339   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3340   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3341
3342   pk=pub_keyblock->pkt->pkt.public_key;
3343
3344   if(pk->numrevkeys==0 && pk->version==3)
3345     {
3346       /* It is legal but bad for compatibility to add a revoker to a
3347          v3 key as it means that PGP2 will not be able to use that key
3348          anymore.  Also, PGP may not expect a revoker on a v3 key.
3349          Don't bother to ask this if the key already has a revoker -
3350          any damage has already been done at that point. -dms */
3351       if(opt.expert)
3352         {
3353           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
3354                        "Adding a designated revoker may cause\n"
3355                        "         some versions of PGP to reject this key.\n"));
3356
3357           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
3358                                     _("Are you sure you still want "
3359                                       "to add it? (y/N) ")))
3360             return 0;
3361         }
3362       else
3363         {
3364           tty_printf(_("You may not add a designated revoker to "
3365                        "a PGP 2.x-style key.\n"));
3366           return 0;
3367         }
3368     }
3369
3370   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3371
3372   for(;;)
3373     {
3374       char *answer;
3375
3376       if(revoker_pk)
3377         free_public_key(revoker_pk);
3378
3379       revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
3380
3381       tty_printf("\n");
3382
3383       answer=cpr_get_utf8("keyedit.add_revoker",
3384                           _("Enter the user ID of the designated revoker: "));
3385       if(answer[0]=='\0' || answer[0]=='\004')
3386         {
3387           xfree(answer);
3388           goto fail;
3389         }
3390
3391       /* Note that I'm requesting CERT here, which usually implies
3392          primary keys only, but some casual testing shows that PGP and
3393          GnuPG both can handle a designated revokation from a
3394          subkey. */
3395       revoker_pk->req_usage=PUBKEY_USAGE_CERT;
3396       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
3397       if(rc)
3398         {
3399           log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
3400           xfree(answer);
3401           continue;
3402         }
3403
3404       xfree(answer);
3405
3406       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
3407       if(fprlen!=20)
3408         {
3409           log_error(_("cannot appoint a PGP 2.x style key as a "
3410                       "designated revoker\n"));
3411           continue;
3412         }
3413
3414       revkey.class=0x80;
3415       if(sensitive)
3416         revkey.class|=0x40;
3417       revkey.algid=revoker_pk->pubkey_algo;
3418
3419       if(cmp_public_keys(revoker_pk,pk)==0)
3420         {
3421           /* This actually causes no harm (after all, a key that
3422              designates itself as a revoker is the same as a
3423              regular key), but it's easy enough to check. */
3424           log_error(_("you cannot appoint a key as its own "
3425                       "designated revoker\n"));
3426
3427           continue;
3428         }
3429
3430       keyid_from_pk(pk,NULL);
3431
3432       /* Does this revkey already exist? */
3433       if(!pk->revkey && pk->numrevkeys)
3434         BUG();
3435       else
3436         {
3437           int i;
3438
3439           for(i=0;i<pk->numrevkeys;i++)
3440             {
3441               if(memcmp(&pk->revkey[i],&revkey,
3442                         sizeof(struct revocation_key))==0)
3443                 {
3444                   char buf[50];
3445
3446                   log_error(_("this key has already been designated "
3447                               "as a revoker\n"));
3448
3449                   sprintf(buf,"%08lX%08lX",
3450                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
3451                   write_status_text(STATUS_ALREADY_SIGNED,buf);
3452
3453                   break;
3454                 }
3455             }
3456
3457           if(i<pk->numrevkeys)
3458             continue;
3459         }
3460
3461       print_pubkey_info(NULL,revoker_pk);
3462       print_fingerprint(revoker_pk,NULL,2);
3463       tty_printf("\n");
3464
3465       tty_printf(_("WARNING: appointing a key as a designated revoker "
3466                    "cannot be undone!\n"));
3467
3468       tty_printf("\n");
3469
3470       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
3471                                 _("Are you sure you want to appoint this "
3472                                   "key as a designated revoker? (y/N) ")))
3473         continue;
3474
3475       free_public_key(revoker_pk);
3476       revoker_pk=NULL;
3477       break;
3478     }
3479
3480   /* The 1F signature must be at least v4 to carry the revocation key
3481      subpacket. */
3482   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3483                            keygen_add_revkey,&revkey );
3484   if( rc )
3485     {
3486       log_error("signing failed: %s\n", g10_errstr(rc) );
3487       goto fail;
3488     }
3489
3490   free_secret_key(sk);
3491   sk=NULL;
3492
3493   /* insert into secret keyblock */
3494   pkt = xmalloc_clear( sizeof *pkt );
3495   pkt->pkttype = PKT_SIGNATURE;
3496   pkt->pkt.signature = copy_signature(NULL, sig);
3497   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3498
3499   /* insert into public keyblock */
3500   pkt = xmalloc_clear( sizeof *pkt );
3501   pkt->pkttype = PKT_SIGNATURE;
3502   pkt->pkt.signature = sig;
3503   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3504
3505   return 1;
3506
3507  fail:
3508   if(sk)
3509     free_secret_key(sk);
3510   if(sig)
3511     free_seckey_enc(sig);
3512   if(revoker_pk)
3513     free_public_key(revoker_pk);
3514
3515   return 0;
3516 }
3517
3518
3519 static int
3520 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3521 {
3522     int n1, signumber, rc;
3523     u32 expiredate;
3524     int mainkey=0;
3525     PKT_secret_key *sk;    /* copy of the main sk */
3526     PKT_public_key *main_pk, *sub_pk;
3527     PKT_user_id *uid;
3528     KBNODE node;
3529     u32 keyid[2];
3530
3531     if( count_selected_keys( sec_keyblock ) ) {
3532         tty_printf(_("Please remove selections from the secret keys.\n"));
3533         return 0;
3534     }
3535
3536     n1 = count_selected_keys( pub_keyblock );
3537     if( n1 > 1 ) {
3538         tty_printf(_("Please select at most one subkey.\n"));
3539         return 0;
3540     }
3541     else if( n1 )
3542         tty_printf(_("Changing expiration time for a subkey.\n"));
3543     else
3544       {
3545         tty_printf(_("Changing expiration time for the primary key.\n"));
3546         mainkey=1;
3547         no_primary_warning(pub_keyblock);
3548       }
3549
3550     expiredate = ask_expiredate();
3551     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3552     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3553
3554     /* Now we can actually change the self signature(s) */
3555     main_pk = sub_pk = NULL;
3556     uid = NULL;
3557     signumber = 0;
3558     for( node=pub_keyblock; node; node = node->next ) {
3559         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3560             main_pk = node->pkt->pkt.public_key;
3561             keyid_from_pk( main_pk, keyid );
3562             main_pk->expiredate = expiredate;
3563         }
3564         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3565                  && (node->flag & NODFLG_SELKEY ) ) {
3566             sub_pk = node->pkt->pkt.public_key;
3567             sub_pk->expiredate = expiredate;
3568         }
3569         else if( node->pkt->pkttype == PKT_USER_ID )
3570             uid = node->pkt->pkt.user_id;
3571         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3572                  && ( mainkey || sub_pk ) ) {
3573             PKT_signature *sig = node->pkt->pkt.signature;
3574             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3575                 && ( (mainkey && uid
3576                       && uid->created && (sig->sig_class&~3) == 0x10)
3577                      || (!mainkey && sig->sig_class == 0x18)  )
3578                 && sig->flags.chosen_selfsig )
3579               {
3580                 /* this is a selfsignature which is to be replaced */
3581                 PKT_signature *newsig;
3582                 PACKET *newpkt;
3583                 KBNODE sn;
3584                 int signumber2 = 0;
3585
3586                 signumber++;
3587
3588                 if( (mainkey && main_pk->version < 4)
3589                     || (!mainkey && sub_pk->version < 4 ) ) {
3590                     log_info(_(
3591                         "You can't change the expiration date of a v3 key\n"));
3592                     free_secret_key( sk );
3593                     return 0;
3594                 }
3595
3596                 /* find the corresponding secret self-signature */
3597                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3598                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3599                         PKT_signature *b = sn->pkt->pkt.signature;
3600                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3601                             && sig->sig_class == b->sig_class
3602                             && ++signumber2 == signumber )
3603                             break;
3604                     }
3605                 }
3606                 if( !sn )
3607                     log_info(_("No corresponding signature in secret ring\n"));
3608
3609                 if( mainkey )
3610                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3611                                             sk, keygen_add_key_expire, main_pk);
3612                 else
3613                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3614                                             sk, keygen_add_key_expire, sub_pk );
3615                 if( rc ) {
3616                     log_error("make_keysig_packet failed: %s\n",
3617                                                     g10_errstr(rc));
3618                     free_secret_key( sk );
3619                     return 0;
3620                 }
3621                 /* replace the packet */
3622                 newpkt = xmalloc_clear( sizeof *newpkt );
3623                 newpkt->pkttype = PKT_SIGNATURE;
3624                 newpkt->pkt.signature = newsig;
3625                 free_packet( node->pkt );
3626                 xfree( node->pkt );
3627                 node->pkt = newpkt;
3628                 if( sn ) {
3629                     newpkt = xmalloc_clear( sizeof *newpkt );
3630                     newpkt->pkttype = PKT_SIGNATURE;
3631                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3632                     free_packet( sn->pkt );
3633                     xfree( sn->pkt );
3634                     sn->pkt = newpkt;
3635                 }
3636                 sub_pk = NULL;
3637             }
3638         }
3639     }
3640
3641     free_secret_key( sk );
3642     update_trust=1;
3643     return 1;
3644 }
3645
3646 static int
3647 menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
3648 {
3649   int rc,modified=0;
3650   PKT_public_key *main_pk;
3651   PKT_secret_key *main_sk,*sub_sk=NULL;
3652   KBNODE node;
3653
3654   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3655   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3656
3657   merge_keys_and_selfsig(pub_keyblock);
3658   main_pk=pub_keyblock->pkt->pkt.public_key;
3659   main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3660   keyid_from_pk(main_pk,NULL);
3661
3662   for(node=pub_keyblock;node;node=node->next)
3663     {
3664       PKT_public_key *sub_pk=NULL;
3665       KBNODE node2,sig_pk=NULL,sig_sk=NULL;
3666       char *passphrase;
3667
3668       if(sub_sk)
3669         {
3670           free_secret_key(sub_sk);
3671           sub_sk=NULL;
3672         }
3673
3674       /* Find a signing subkey with no backsig */
3675       if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
3676         {
3677           if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
3678             {
3679               if(node->pkt->pkt.public_key->backsig)
3680                 tty_printf(_("signing subkey %s is already cross-certified\n"),
3681                            keystr_from_pk(node->pkt->pkt.public_key));
3682               else
3683                 sub_pk=node->pkt->pkt.public_key;
3684             }
3685           else
3686             tty_printf(_("subkey %s does not sign and so does"
3687                          " not need to be cross-certified\n"),
3688                        keystr_from_pk(node->pkt->pkt.public_key));
3689         }
3690
3691       if(!sub_pk)
3692         continue;
3693
3694       /* Find the selected selfsig on this subkey */
3695       for(node2=node->next;
3696           node2 && node2->pkt->pkttype==PKT_SIGNATURE;
3697           node2=node2->next)
3698         if(node2->pkt->pkt.signature->version>=4
3699            && node2->pkt->pkt.signature->flags.chosen_selfsig)
3700           {
3701             sig_pk=node2;
3702             break;
3703           }
3704
3705       if(!sig_pk)
3706         continue;
3707
3708       /* Find the secret subkey that matches the public subkey */
3709       for(node2=sec_keyblock;node2;node2=node2->next)
3710         if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
3711            && !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
3712           {
3713             sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
3714             break;
3715           }
3716
3717       if(!sub_sk)
3718         {
3719           tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
3720                      keystr_from_pk(sub_pk));
3721           continue;
3722         }
3723
3724       /* Now finally find the matching selfsig on the secret subkey.
3725          We can't use chosen_selfsig here (it's not set for secret
3726          keys), so we just pick the selfsig with the right class.
3727          This is what menu_expire does as well. */
3728       for(node2=node2->next;
3729           node2 && node2->pkt->pkttype!=PKT_SECRET_SUBKEY;
3730           node2=node2->next)
3731         if(node2->pkt->pkttype==PKT_SIGNATURE
3732            && node2->pkt->pkt.signature->version>=4
3733            && node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
3734            && node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
3735            && node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
3736           {
3737             sig_sk=node2;
3738             break;
3739           }
3740
3741       /* Now we can get to work.  We have a main key and secret part,
3742          a signing subkey with signature and secret part possibly with
3743          signature. */
3744
3745       passphrase=get_last_passphrase();
3746       set_next_passphrase(passphrase);
3747       xfree(passphrase);
3748
3749       rc=make_backsig(sig_pk->pkt->pkt.signature,main_pk,sub_pk,sub_sk);
3750       if(rc==0)
3751         {
3752           PKT_signature *newsig;
3753           PACKET *newpkt;
3754
3755           passphrase=get_last_passphrase();
3756           set_next_passphrase(passphrase);
3757           xfree(passphrase);
3758
3759           rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
3760                                   NULL,sub_pk,main_sk,NULL,NULL);
3761           if(rc==0)
3762             {
3763               /* Put the new sig into place on the pubkey */
3764               newpkt=xmalloc_clear(sizeof(*newpkt));
3765               newpkt->pkttype=PKT_SIGNATURE;
3766               newpkt->pkt.signature=newsig;
3767               free_packet(sig_pk->pkt);
3768               xfree(sig_pk->pkt);
3769               sig_pk->pkt=newpkt;
3770
3771               if(sig_sk)
3772                 {
3773                   /* Put the new sig into place on the seckey */
3774                   newpkt=xmalloc_clear(sizeof(*newpkt));
3775                   newpkt->pkttype=PKT_SIGNATURE;
3776                   newpkt->pkt.signature=copy_signature(NULL,newsig);
3777                   free_packet(sig_sk->pkt);
3778                   xfree(sig_sk->pkt);
3779                   sig_sk->pkt=newpkt;
3780                 }
3781
3782               modified=1;
3783             }
3784           else
3785             {
3786               log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
3787               break;
3788             }
3789         }
3790       else