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