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