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