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