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