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