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