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