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