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