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