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