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