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