* options.h, getkey.c (merge_selfsigs_subkey), gpg.c (main), sig-check.c
[gnupg.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3  *               2005 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include <ctype.h>
30 #ifdef HAVE_LIBREADLINE
31 #include <stdio.h>
32 #include <readline/readline.h>
33 #endif
34 #include "options.h"
35 #include "packet.h"
36 #include "errors.h"
37 #include "iobuf.h"
38 #include "keydb.h"
39 #include "memory.h"
40 #include "photoid.h"
41 #include "util.h"
42 #include "main.h"
43 #include "trustdb.h"
44 #include "filter.h"
45 #include "ttyio.h"
46 #include "status.h"
47 #include "i18n.h"
48 #include "keyserver-internal.h"
49
50 static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
51 static void show_names(KBNODE keyblock,PKT_public_key *pk,
52                        unsigned int flag,int with_prefs);
53 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
54             int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
55 static void show_key_and_fingerprint( KBNODE keyblock );
56 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock,
57                         int photo, const char *photo_name );
58 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
59 static int menu_delsig( KBNODE pub_keyblock );
60 static int menu_clean_sigs_from_uids(KBNODE keyblock);
61 static int menu_clean_uids_from_key(KBNODE keyblock);
62 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
63 static int menu_addrevoker( KBNODE pub_keyblock,
64                             KBNODE sec_keyblock, int sensitive );
65 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
66 static int menu_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, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
1342     cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
1343     cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN, 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     { "sign"    , cmdSIGN      , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
1367       N_("sign selected user IDs [* see below for related commands]") },
1368     { "s"       , cmdSIGN      , KEYEDIT_NOT_SK, NULL },
1369     /* "lsign" and friends will never match since "sign" comes first
1370        and it is a tail match.  They are just here so they show up in
1371        the help menu. */
1372     { "lsign"   , cmdNOP       , 0, N_("sign selected user IDs locally") },
1373     { "tsign"   , cmdNOP       , 0,
1374       N_("sign selected user IDs with a trust signature") },
1375     { "nrsign"  , cmdNOP       , 0,
1376       N_("sign selected user IDs with a non-revocable signature") },
1377
1378     { "debug"   , cmdDEBUG     , 0, NULL },
1379     { "adduid"  , cmdADDUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1380       N_("add a user ID") },
1381     { "addphoto", cmdADDPHOTO  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1382       N_("add a photo ID") },
1383     { "deluid"  , cmdDELUID    , KEYEDIT_NOT_SK,
1384       N_("delete selected user IDs") },
1385     /* delphoto is really deluid in disguise */
1386     { "delphoto", cmdDELUID    , KEYEDIT_NOT_SK, NULL },
1387
1388     { "addkey"  , cmdADDKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1389       N_("add a subkey") },
1390
1391 #ifdef ENABLE_CARD_SUPPORT
1392     { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1393       N_("add a key to a smartcard") },
1394     { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK, 
1395       N_("move a key to a smartcard")},
1396     { "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK, 
1397       N_("move a backup key to a smartcard")},
1398 #endif /*ENABLE_CARD_SUPPORT*/
1399
1400     { "delkey"  , cmdDELKEY    , KEYEDIT_NOT_SK,
1401       N_("delete selected subkeys") },
1402     { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1403       N_("add a revocation key") },
1404     { "delsig"  , cmdDELSIG    , KEYEDIT_NOT_SK,
1405       N_("delete signatures from the selected user IDs") },
1406     { "expire"  , cmdEXPIRE    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1407       N_("change the expiration date for the key or selected subkeys") },
1408     { "primary" , cmdPRIMARY   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1409       N_("flag the selected user ID as primary")},
1410     { "toggle"  , cmdTOGGLE    , KEYEDIT_NEED_SK,
1411       N_("toggle between the secret and public key listings") },
1412     { "t"       , cmdTOGGLE    , KEYEDIT_NEED_SK, NULL },
1413     { "pref"    , cmdPREF      , KEYEDIT_NOT_SK,
1414       N_("list preferences (expert)")},
1415     { "showpref", cmdSHOWPREF  , KEYEDIT_NOT_SK,
1416       N_("list preferences (verbose)") },
1417     { "setpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1418       N_("set preference list for the selected user IDs") },
1419     /* Alias */
1420     { "updpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1421
1422     { "keyserver",cmdPREFKS    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1423       N_("set preferred keyserver URL for the selected user IDs")},
1424     { "passwd"  , cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1425       N_("change the passphrase") },
1426     /* Alias */
1427     { "password", cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1428
1429     { "trust"   , cmdTRUST     , KEYEDIT_NOT_SK, N_("change the ownertrust") },
1430     { "revsig"  , cmdREVSIG    , KEYEDIT_NOT_SK,
1431       N_("revoke signatures on the selected user IDs") },
1432     { "revuid"  , cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1433       N_("revoke selected user IDs") },
1434     /* Alias */
1435     { "revphoto", cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1436
1437     { "revkey"  , cmdREVKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1438       N_("revoke key or selected subkeys") },
1439     { "enable"  , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
1440     { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
1441     { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
1442     { "clean",    cmdCLEAN     , KEYEDIT_NOT_SK,
1443       N_("clean unusable parts from key") },
1444     { NULL, cmdNONE, 0, NULL }
1445   };
1446
1447
1448 #ifdef HAVE_LIBREADLINE
1449
1450 /* These two functions are used by readline for command completion. */
1451
1452 static char *
1453 command_generator(const char *text,int state)
1454 {
1455   static int list_index,len;
1456   const char *name;
1457
1458   /* If this is a new word to complete, initialize now.  This includes
1459      saving the length of TEXT for efficiency, and initializing the
1460      index variable to 0. */
1461   if(!state)
1462     {
1463       list_index=0;
1464       len=strlen(text);
1465     }
1466
1467   /* Return the next partial match */
1468   while((name=cmds[list_index].name))
1469     {
1470       /* Only complete commands that have help text */
1471       if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1472         return strdup(name);
1473     }
1474
1475   return NULL;
1476 }
1477
1478 static char **
1479 keyedit_completion(const char *text, int start, int end)
1480 {
1481   /* If we are at the start of a line, we try and command-complete.
1482      If not, just do nothing for now. */
1483
1484   if(start==0)
1485     return rl_completion_matches(text,command_generator);
1486
1487   rl_attempted_completion_over=1;
1488
1489   return NULL;
1490 }
1491 #endif /* HAVE_LIBREADLINE */
1492
1493
1494 void
1495 keyedit_menu( const char *username, STRLIST locusr,
1496               STRLIST commands, int quiet, int seckey_check )
1497 {
1498     enum cmdids cmd = 0;
1499     int rc = 0;
1500     KBNODE keyblock = NULL;
1501     KEYDB_HANDLE kdbhd = NULL;
1502     KBNODE sec_keyblock = NULL;
1503     KEYDB_HANDLE sec_kdbhd = NULL;
1504     KBNODE cur_keyblock;
1505     char *answer = NULL;
1506     int redisplay = 1;
1507     int modified = 0;
1508     int sec_modified = 0;
1509     int toggle;
1510     int have_commands = !!commands;
1511
1512     if ( opt.command_fd != -1 )
1513         ;
1514     else if( opt.batch && !have_commands )
1515       {
1516         log_error(_("can't do this in batch mode\n"));
1517         goto leave;
1518       }
1519
1520 #ifdef HAVE_W32_SYSTEM
1521     /* Due to Windows peculiarities we need to make sure that the
1522        trustdb stale check is done before we open another file
1523        (i.e. by searching for a key).  In theory we could make sure
1524        that the files are closed after use but the open/close caches
1525        inhibits that and flushing the cache right before the stale
1526        check is not easy to implement.  Thus we take the easy way out
1527        and run the stale check as early as possible.  Note, that for
1528        non- W32 platforms it is run indirectly trough a call to
1529        get_validity ().  */
1530     check_trustdb_stale ();
1531 #endif
1532
1533     /* Get the public key */
1534     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1535     if( rc )
1536         goto leave;
1537     if( fix_keyblock( keyblock ) )
1538         modified++;
1539     if( collapse_uids( &keyblock ) )
1540         modified++;
1541     reorder_keyblock(keyblock);
1542
1543     if(seckey_check)
1544       {/* see whether we have a matching secret key */
1545         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1546
1547         sec_kdbhd = keydb_new (1);
1548         {
1549             byte afp[MAX_FINGERPRINT_LEN];
1550             size_t an;
1551
1552             fingerprint_from_pk (pk, afp, &an);
1553             while (an < MAX_FINGERPRINT_LEN) 
1554                 afp[an++] = 0;
1555             rc = keydb_search_fpr (sec_kdbhd, afp);
1556         }
1557         if (!rc)
1558           {
1559             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1560             if (rc)
1561               {
1562                 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1563                            username, g10_errstr(rc));
1564               }
1565             else
1566               {
1567                 merge_keys_and_selfsig( sec_keyblock );
1568                 if( fix_keyblock( sec_keyblock ) )
1569                   sec_modified++;
1570               }
1571           }
1572
1573         if (rc) {
1574             sec_keyblock = NULL;
1575             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1576             rc = 0;
1577         }
1578
1579         if( sec_keyblock && !quiet )
1580           tty_printf(_("Secret key is available.\n"));
1581     }
1582
1583     toggle = 0;
1584     cur_keyblock = keyblock;
1585     for(;;) { /* main loop */
1586         int i, arg_number, photo;
1587         const char *arg_string = "";
1588         char *p;
1589         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1590
1591         tty_printf("\n");
1592
1593         if( redisplay && !quiet )
1594           {
1595             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1596             tty_printf("\n");
1597             redisplay = 0;
1598           }
1599         do {
1600             xfree(answer);
1601             if( have_commands ) {
1602                 if( commands ) {
1603                     answer = xstrdup( commands->d );
1604                     commands = commands->next;
1605                 }
1606                 else if( opt.batch ) {
1607                     answer = xstrdup("quit");
1608                 }
1609                 else
1610                     have_commands = 0;
1611             }
1612             if( !have_commands )
1613               {
1614                 tty_enable_completion(keyedit_completion);
1615                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1616                 cpr_kill_prompt();
1617                 tty_disable_completion();
1618               }
1619             trim_spaces(answer);
1620         } while( *answer == '#' );
1621
1622         arg_number = 0; /* Yes, here is the init which egcc complains about */
1623         photo = 0; /* This too */
1624         if( !*answer )
1625             cmd = cmdLIST;
1626         else if( *answer == CONTROL_D )
1627             cmd = cmdQUIT;
1628         else if( digitp(answer ) ) {
1629             cmd = cmdSELUID;
1630             arg_number = atoi(answer);
1631         }
1632         else {
1633             if( (p=strchr(answer,' ')) ) {
1634                 *p++ = 0;
1635                 trim_spaces(answer);
1636                 trim_spaces(p);
1637                 arg_number = atoi(p);
1638                 arg_string = p;
1639             }
1640
1641             for(i=0; cmds[i].name; i++ )
1642               {
1643                 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1644                   {
1645                     size_t l=strlen(cmds[i].name);
1646                     size_t a=strlen(answer);
1647                     if(a>=l)
1648                       {
1649                         if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1650                           {
1651                             answer[a-l]='\0';
1652                             break;
1653                           }
1654                       }
1655                   }
1656                 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1657                   break;
1658               }
1659             if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1660               {
1661                 tty_printf(_("Need the secret key to do this.\n"));
1662                 cmd = cmdNOP;
1663               }
1664             else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1665                      && toggle)
1666                     ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1667                        && !toggle))
1668               {
1669                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1670                 cmd = cmdNOP;
1671               }
1672             else
1673               cmd = cmds[i].id;
1674         }
1675         switch( cmd )
1676           {
1677           case cmdHELP:
1678             for(i=0; cmds[i].name; i++ )
1679               {
1680                 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1681                   ; /* skip if we do not have the secret key */
1682                 else if( cmds[i].desc )
1683                   tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
1684               }
1685
1686             tty_printf("\n");
1687             tty_printf(_(
1688 "* The `sign' command may be prefixed with an `l' for local "
1689 "signatures (lsign),\n"
1690 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
1691 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
1692
1693             break;
1694
1695           case cmdLIST:
1696             redisplay = 1;
1697             break;
1698
1699           case cmdFPR:
1700             show_key_and_fingerprint( keyblock );
1701             break;
1702
1703           case cmdSELUID:
1704             if(strlen(arg_string)==NAMEHASH_LEN*2)
1705               redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
1706             else
1707               redisplay=menu_select_uid(cur_keyblock,arg_number);
1708             break;
1709
1710           case cmdSELKEY:
1711             if( menu_select_key( cur_keyblock, arg_number ) )
1712                 redisplay = 1;
1713             break;
1714
1715           case cmdCHECK:
1716             /* we can only do this with the public key becuase the
1717              * check functions can't cope with secret keys and it
1718              * is questionable whether this would make sense at all */
1719             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1720             break;
1721
1722           case cmdSIGN: /* sign (only the public key) */
1723             {
1724               int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
1725
1726               if( pk->is_revoked )
1727                 {
1728                   tty_printf(_("Key is revoked."));
1729
1730                   if(opt.expert)
1731                     {
1732                       tty_printf("  ");
1733                       if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1734                                                 _("Are you sure you still want"
1735                                                   " to sign it? (y/N) ")))
1736                         break;
1737                     }
1738                   else
1739                     {
1740                       tty_printf(_("  Unable to sign.\n"));
1741                       break;
1742                     }
1743                 }
1744
1745               if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
1746                  && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1747                                            _("Really sign all user IDs?"
1748                                              " (y/N) ")))
1749                 {
1750                   if(opt.interactive)
1751                     interactive=1;
1752                   else
1753                     {
1754                       tty_printf(_("Hint: Select the user IDs to sign\n"));
1755                       have_commands = 0;
1756                       break;
1757                     }
1758
1759                 }
1760               /* What sort of signing are we doing? */
1761               if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1762                 {
1763                   tty_printf(_("Unknown signature type `%s'\n"),answer);
1764                   break;
1765                 }
1766
1767               sign_uids(keyblock, locusr, &modified,
1768                         localsig, nonrevokesig, trustsig, interactive);
1769             }
1770             break;
1771
1772           case cmdDEBUG:
1773             dump_kbnode( cur_keyblock );
1774             break;
1775
1776           case cmdTOGGLE:
1777             toggle = !toggle;
1778             cur_keyblock = toggle? sec_keyblock : keyblock;
1779             redisplay = 1;
1780             break;
1781
1782           case cmdADDPHOTO:
1783             if (RFC2440 || RFC1991 || PGP2)
1784               {
1785                 tty_printf(
1786                    _("This command is not allowed while in %s mode.\n"),
1787                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1788                 break;
1789               }
1790             photo=1;
1791             /* fall through */
1792
1793           case cmdADDUID:
1794             if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
1795               {
1796                 update_trust = 1;
1797                 redisplay = 1;
1798                 sec_modified = modified = 1;
1799                 merge_keys_and_selfsig( sec_keyblock );
1800                 merge_keys_and_selfsig( keyblock );
1801               }
1802             break;
1803
1804           case cmdDELUID: {
1805                 int n1;
1806
1807                 if( !(n1=count_selected_uids(keyblock)) )
1808                     tty_printf(_("You must select at least one user ID.\n"));
1809                 else if( real_uids_left(keyblock) < 1 )
1810                     tty_printf(_("You can't delete the last user ID!\n"));
1811                 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1812                 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1813                             : _("Really remove this user ID? (y/N) ")
1814                        ) ) {
1815                     menu_deluid( keyblock, sec_keyblock );
1816                     redisplay = 1;
1817                     modified = 1;
1818                     if( sec_keyblock )
1819                        sec_modified = 1;
1820                 }
1821             }
1822             break;
1823
1824           case cmdDELSIG: {
1825                 int n1;
1826
1827                 if( !(n1=count_selected_uids(keyblock)) )
1828                     tty_printf(_("You must select at least one user ID.\n"));
1829                 else if( menu_delsig( keyblock ) ) {
1830                     /* no redisplay here, because it may scroll away some
1831                      * status output of delsig */
1832                     modified = 1;
1833                 }
1834             }
1835             break;
1836
1837           case cmdADDKEY:
1838             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1839                 redisplay = 1;
1840                 sec_modified = modified = 1;
1841                 merge_keys_and_selfsig( sec_keyblock );
1842                 merge_keys_and_selfsig( keyblock );
1843             }
1844             break;
1845
1846 #ifdef ENABLE_CARD_SUPPORT
1847           case cmdADDCARDKEY:
1848             if (card_generate_subkey (keyblock, sec_keyblock)) {
1849                 redisplay = 1;
1850                 sec_modified = modified = 1;
1851                 merge_keys_and_selfsig( sec_keyblock );
1852                 merge_keys_and_selfsig( keyblock );
1853             }
1854             break;
1855
1856         case cmdKEYTOCARD:
1857           {
1858             KBNODE node=NULL;
1859             switch ( count_selected_keys (sec_keyblock) )
1860               {
1861               case 0:
1862                 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1863                                      _("Really move the primary key? (y/N) ")))
1864                   node = sec_keyblock;
1865                 break;
1866               case 1:
1867                 for (node = sec_keyblock; node; node = node->next )
1868                   {
1869                     if (node->pkt->pkttype == PKT_SECRET_SUBKEY 
1870                         && node->flag & NODFLG_SELKEY)
1871                       break;
1872                   }
1873                 break;
1874               default:
1875                 tty_printf(_("You must select exactly one key.\n"));
1876                 break;
1877               }
1878             if (node)
1879               {
1880                 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1881                 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1882                   {
1883                     redisplay = 1;
1884                     sec_modified = 1;
1885                   }
1886               }
1887           }
1888           break;
1889
1890         case cmdBKUPTOCARD:
1891           {
1892             /* Ask for a filename, check whether this is really a
1893                backup key as generated by the card generation, parse
1894                that key and store it on card. */
1895             KBNODE node;
1896             const char *fname;
1897             PACKET *pkt;
1898             IOBUF a;
1899
1900             fname = arg_string;
1901             if (!*fname)
1902               {
1903                 tty_printf (_("Command expects a filename argument\n"));
1904                 break;
1905               }
1906
1907             /* Open that file.  */
1908             a = iobuf_open (fname);
1909             if (a && is_secured_file (iobuf_get_fd (a)))
1910               {
1911                 iobuf_close (a);
1912                 a = NULL;
1913                 errno = EPERM;
1914               }
1915             if (!a)
1916               {
1917                 tty_printf (_("Can't open `%s': %s\n"),
1918                             fname, strerror(errno));
1919                 break;
1920               }
1921             
1922             /* Parse and check that file.  */
1923             pkt = xmalloc (sizeof *pkt);
1924             init_packet (pkt);
1925             rc = parse_packet (a, pkt);
1926             iobuf_close (a);
1927             iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache).  */
1928             if (!rc 
1929                 && pkt->pkttype != PKT_SECRET_KEY 
1930                 && pkt->pkttype != PKT_SECRET_SUBKEY)
1931               rc = G10ERR_NO_SECKEY;
1932             if (rc)
1933               {
1934                 tty_printf(_("Error reading backup key from `%s': %s\n"),
1935                            fname, g10_errstr (rc));
1936                 free_packet (pkt);
1937                 xfree (pkt);
1938                 break;
1939               }
1940             node = new_kbnode (pkt);
1941
1942             /* Store it.  */
1943             if (card_store_subkey (node, 0))
1944               {
1945                 redisplay = 1;
1946                 sec_modified = 1;
1947               }
1948             release_kbnode (node);
1949           }
1950           break;
1951
1952 #endif /* ENABLE_CARD_SUPPORT */
1953
1954           case cmdDELKEY: {
1955                 int n1;
1956
1957                 if( !(n1=count_selected_keys( keyblock )) )
1958                     tty_printf(_("You must select at least one key.\n"));
1959                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1960                        n1 > 1?
1961                    _("Do you really want to delete the selected keys? (y/N) "):
1962                         _("Do you really want to delete this key? (y/N) ")
1963                        ))
1964                     ;
1965                 else {
1966                     menu_delkey( keyblock, sec_keyblock );
1967                     redisplay = 1;
1968                     modified = 1;
1969                     if( sec_keyblock )
1970                        sec_modified = 1;
1971                 }
1972             }
1973             break;
1974
1975           case cmdADDREVOKER:
1976             {
1977               int sensitive=0;
1978
1979               if(ascii_strcasecmp(arg_string,"sensitive")==0)
1980                 sensitive=1;
1981               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1982                 redisplay = 1;
1983                 sec_modified = modified = 1;
1984                 merge_keys_and_selfsig( sec_keyblock );
1985                 merge_keys_and_selfsig( keyblock );
1986               }
1987             }
1988             break;
1989
1990           case cmdREVUID: {
1991                 int n1;
1992
1993                 if( !(n1=count_selected_uids(keyblock)) )
1994                     tty_printf(_("You must select at least one user ID.\n"));
1995                 else if( cpr_get_answer_is_yes(
1996                             "keyedit.revoke.uid.okay",
1997                        n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
1998                              : _("Really revoke this user ID? (y/N) ")
1999                        ) ) {
2000                   if(menu_revuid(keyblock,sec_keyblock))
2001                     {
2002                       modified=1;
2003                       redisplay=1;
2004                     }
2005                 }
2006             }
2007             break;
2008
2009           case cmdREVKEY:
2010             {
2011               int n1;
2012
2013               if( !(n1=count_selected_keys( keyblock )) )
2014                 {
2015                   if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2016                                            _("Do you really want to revoke"
2017                                              " the entire key? (y/N) ")))
2018                     {
2019                       if(menu_revkey(keyblock,sec_keyblock))
2020                         modified=1;
2021
2022                       redisplay=1;
2023                     }
2024                 }
2025               else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2026                                             n1 > 1?
2027                                             _("Do you really want to revoke"
2028                                               " the selected subkeys? (y/N) "):
2029                                             _("Do you really want to revoke"
2030                                               " this subkey? (y/N) ")))
2031                 {
2032                   if( menu_revsubkey( keyblock, sec_keyblock ) )
2033                     modified = 1;
2034
2035                   redisplay = 1;
2036                 }
2037
2038               if(modified)
2039                 merge_keys_and_selfsig( keyblock );
2040             }
2041             break;
2042
2043           case cmdEXPIRE:
2044             if( menu_expire( keyblock, sec_keyblock ) )
2045               {
2046                 merge_keys_and_selfsig( sec_keyblock );
2047                 merge_keys_and_selfsig( keyblock );
2048                 sec_modified = 1;
2049                 modified = 1;
2050                 redisplay = 1;
2051               }
2052             break;
2053
2054           case cmdPRIMARY:
2055             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
2056                 merge_keys_and_selfsig( keyblock );
2057                 modified = 1;
2058                 redisplay = 1;
2059             }
2060             break;
2061
2062           case cmdPASSWD:
2063             if( change_passphrase( sec_keyblock ) )
2064                 sec_modified = 1;
2065             break;
2066
2067           case cmdTRUST:
2068             if(opt.trust_model==TM_EXTERNAL)
2069               {
2070                 tty_printf(_("Owner trust may not be set while "
2071                              "using an user provided trust database\n"));
2072                 break;
2073               }
2074
2075             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
2076             tty_printf("\n");
2077             if( edit_ownertrust( find_kbnode( keyblock,
2078                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
2079                 redisplay = 1;
2080                 /* No real need to set update_trust here as
2081                    edit_ownertrust() calls revalidation_mark()
2082                    anyway. */
2083                 update_trust=1;
2084             }
2085             break;
2086
2087           case cmdPREF:
2088             {
2089               int count=count_selected_uids(keyblock);
2090               assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2091               show_names(keyblock,keyblock->pkt->pkt.public_key,
2092                          count?NODFLG_SELUID:0,1);
2093             }
2094             break;
2095
2096           case cmdSHOWPREF:
2097             {
2098               int count=count_selected_uids(keyblock);
2099               assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2100               show_names(keyblock,keyblock->pkt->pkt.public_key,
2101                          count?NODFLG_SELUID:0,2);
2102             }
2103             break;
2104
2105           case cmdSETPREF:
2106             {
2107               PKT_user_id *tempuid;
2108
2109               keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
2110
2111               tempuid=keygen_get_std_prefs();
2112               tty_printf(_("Set preference list to:\n"));
2113               show_prefs(tempuid,NULL,1);
2114               free_user_id(tempuid);
2115
2116               if(cpr_get_answer_is_yes("keyedit.setpref.okay",
2117                                        count_selected_uids (keyblock)?
2118                                        _("Really update the preferences"
2119                                          " for the selected user IDs? (y/N) "):
2120                                        _("Really update the preferences? (y/N) ")))
2121                 {
2122                   if ( menu_set_preferences (keyblock, sec_keyblock) )
2123                     {
2124                       merge_keys_and_selfsig (keyblock);
2125                       modified = 1;
2126                       redisplay = 1;
2127                     }
2128                 }
2129             }
2130             break;
2131
2132           case cmdPREFKS:
2133             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
2134                                          keyblock, sec_keyblock ) )
2135               {
2136                 merge_keys_and_selfsig( keyblock );
2137                 modified = 1;
2138                 redisplay = 1;
2139               }
2140             break;
2141
2142           case cmdNOP:
2143             break;
2144
2145           case cmdREVSIG:
2146             if( menu_revsig( keyblock ) ) {
2147                 redisplay = 1;
2148                 modified = 1;
2149             }
2150             break;
2151
2152           case cmdENABLEKEY:
2153           case cmdDISABLEKEY:
2154             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
2155                 redisplay = 1;
2156                 modified = 1;
2157             }
2158             break;
2159
2160           case cmdSHOWPHOTO:
2161             menu_showphoto(keyblock);
2162             break;
2163
2164           case cmdCLEAN:
2165             {
2166               if(*arg_string)
2167                 {
2168                   if(ascii_strcasecmp(arg_string,"sigs")==0
2169                      || ascii_strcasecmp(arg_string,"signatures")==0
2170                      || ascii_strcasecmp(arg_string,"certs")==0
2171                      || ascii_strcasecmp(arg_string,"certificates")==0)
2172                     modified=menu_clean_sigs_from_uids(keyblock);
2173                   else if(ascii_strcasecmp(arg_string,"uids")==0)
2174                     redisplay=modified=menu_clean_uids_from_key(keyblock);
2175                   else
2176                     tty_printf("Unable to clean `%s'\n",arg_string);
2177                 }
2178               else
2179                 {
2180                   modified=menu_clean_sigs_from_uids(keyblock);
2181                   modified+=menu_clean_uids_from_key(keyblock);
2182                   redisplay=modified;
2183                 }
2184             }
2185             break;
2186
2187           case cmdQUIT:
2188             if( have_commands )
2189                 goto leave;
2190             if( !modified && !sec_modified )
2191                 goto leave;
2192             if( !cpr_get_answer_is_yes("keyedit.save.okay",
2193                                         _("Save changes? (y/N) ")) ) {
2194                 if( cpr_enabled()
2195                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
2196                                              _("Quit without saving? (y/N) ")))
2197                     goto leave;
2198                 break;
2199             }
2200             /* fall thru */
2201           case cmdSAVE:
2202             if( modified || sec_modified  ) {
2203                 if( modified ) {
2204                     rc = keydb_update_keyblock (kdbhd, keyblock);
2205                     if( rc ) {
2206                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
2207                         break;
2208                     }
2209                 }
2210                 if( sec_modified ) {
2211                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
2212                     if( rc ) {
2213                         log_error( _("update secret failed: %s\n"),
2214                                    g10_errstr(rc) );
2215                         break;
2216                     }
2217                 }
2218             }
2219             else
2220                 tty_printf(_("Key not changed so no update needed.\n"));
2221
2222             if( update_trust )
2223               {
2224                 revalidation_mark ();
2225                 update_trust=0;
2226               }
2227             goto leave;
2228
2229           case cmdINVCMD:
2230           default:
2231             tty_printf("\n");
2232             tty_printf(_("Invalid command  (try \"help\")\n"));
2233             break;
2234         }
2235     } /* end main loop */
2236
2237   leave:
2238     release_kbnode( keyblock );
2239     release_kbnode( sec_keyblock );
2240     keydb_release (kdbhd);
2241     xfree(answer);
2242 }
2243
2244
2245 \f
2246 /****************
2247  * show preferences of a public keyblock.
2248  */
2249 static void
2250 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
2251 {
2252     const prefitem_t fake={0,0};
2253     const prefitem_t *prefs;
2254     int i;
2255
2256     if( !uid )
2257         return;
2258
2259     if( uid->prefs )
2260         prefs=uid->prefs;
2261     else if(verbose)
2262         prefs=&fake;
2263     else
2264       return;
2265
2266     if (verbose) {
2267         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
2268
2269         tty_printf ("     ");
2270         tty_printf (_("Cipher: "));
2271         for(i=any=0; prefs[i].type; i++ ) {
2272             if( prefs[i].type == PREFTYPE_SYM ) {
2273                 const char *s = cipher_algo_to_string (prefs[i].value);
2274                 
2275                 if (any)
2276                     tty_printf (", ");
2277                 any = 1;
2278                 /* We don't want to display strings for experimental algos */
2279                 if (s && prefs[i].value < 100 )
2280                     tty_printf ("%s", s );
2281                 else
2282                     tty_printf ("[%d]", prefs[i].value);
2283                 if (prefs[i].value == CIPHER_ALGO_3DES )
2284                     des_seen = 1;
2285             }    
2286         }
2287         if (!des_seen) {
2288             if (any)
2289                 tty_printf (", ");
2290             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
2291         }
2292         tty_printf ("\n     ");
2293         tty_printf (_("Digest: "));
2294         for(i=any=0; prefs[i].type; i++ ) {
2295             if( prefs[i].type == PREFTYPE_HASH ) {
2296                 const char *s = digest_algo_to_string (prefs[i].value);
2297                 
2298                 if (any)
2299                     tty_printf (", ");
2300                 any = 1;
2301                 /* We don't want to display strings for experimental algos */
2302                 if (s && prefs[i].value < 100 )
2303                     tty_printf ("%s", s );
2304                 else
2305                     tty_printf ("[%d]", prefs[i].value);
2306                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2307                     sha1_seen = 1;
2308             }
2309         }
2310         if (!sha1_seen) {
2311             if (any)
2312                 tty_printf (", ");
2313             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
2314         }
2315         tty_printf ("\n     ");
2316         tty_printf (_("Compression: "));
2317         for(i=any=0; prefs[i].type; i++ ) {
2318             if( prefs[i].type == PREFTYPE_ZIP ) {
2319                 const char *s=compress_algo_to_string(prefs[i].value);
2320                 
2321                 if (any)
2322                     tty_printf (", ");
2323                 any = 1;
2324                 /* We don't want to display strings for experimental algos */
2325                 if (s && prefs[i].value < 100 )
2326                     tty_printf ("%s", s );
2327                 else
2328                     tty_printf ("[%d]", prefs[i].value);
2329                 if (prefs[i].value == COMPRESS_ALGO_NONE )
2330                     uncomp_seen = 1;
2331             }
2332         }
2333         if (!uncomp_seen) {
2334             if (any)
2335                 tty_printf (", ");
2336             else {
2337               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2338               tty_printf (", ");
2339             }
2340             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2341         }
2342         if(uid->mdc_feature || !uid->ks_modify)
2343           {
2344             tty_printf ("\n     ");
2345             tty_printf (_("Features: "));
2346             any=0;
2347             if(uid->mdc_feature)
2348               {
2349                 tty_printf ("MDC");
2350                 any=1;
2351               }
2352             if(!uid->ks_modify)
2353               {
2354                 if(any)
2355                   tty_printf (", ");
2356                 tty_printf (_("Keyserver no-modify"));
2357               }
2358           }
2359         tty_printf("\n");
2360
2361         if(selfsig)
2362           {
2363             const byte *pref_ks;
2364             size_t pref_ks_len;
2365
2366             pref_ks=parse_sig_subpkt(selfsig->hashed,
2367                                      SIGSUBPKT_PREF_KS,&pref_ks_len);
2368             if(pref_ks && pref_ks_len)
2369               {
2370                 tty_printf ("     ");
2371                 tty_printf(_("Preferred keyserver: "));
2372                 tty_print_utf8_string(pref_ks,pref_ks_len);
2373                 tty_printf("\n");
2374               }
2375           }
2376     }
2377     else {
2378         tty_printf("    ");
2379         for(i=0; prefs[i].type; i++ ) {
2380             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
2381                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
2382                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2383                                  prefs[i].value);
2384         }
2385         if (uid->mdc_feature)
2386             tty_printf (" [mdc]");
2387         if (!uid->ks_modify)
2388             tty_printf (" [no-ks-modify]");
2389         tty_printf("\n");
2390     }
2391 }
2392
2393 /* This is the version of show_key_with_all_names used when
2394    opt.with_colons is used.  It prints all available data in a easy to
2395    parse format and does not translate utf8 */
2396 static void
2397 show_key_with_all_names_colon (KBNODE keyblock)
2398 {
2399   KBNODE node;
2400   int i, j, ulti_hack=0;
2401   byte pk_version=0;
2402   PKT_public_key *primary=NULL;
2403
2404   /* the keys */
2405   for ( node = keyblock; node; node = node->next )
2406     {
2407       if (node->pkt->pkttype == PKT_PUBLIC_KEY
2408           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2409         {
2410           PKT_public_key *pk = node->pkt->pkt.public_key;
2411           u32 keyid[2];
2412
2413           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2414             {
2415               pk_version = pk->version;
2416               primary=pk;
2417             }
2418
2419           keyid_from_pk (pk, keyid);
2420
2421           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2422           if (!pk->is_valid)
2423             putchar ('i');
2424           else if (pk->is_revoked)
2425             putchar ('r');
2426           else if (pk->has_expired)
2427             putchar ('e');
2428           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2429             {
2430               int trust = get_validity_info (pk, NULL);
2431               if(trust=='u')
2432                 ulti_hack=1;
2433               putchar (trust);
2434             }
2435
2436           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2437                   nbits_from_pk (pk),
2438                   pk->pubkey_algo,
2439                   (ulong)keyid[0], (ulong)keyid[1],
2440                   (ulong)pk->timestamp,
2441                   (ulong)pk->expiredate );
2442           if (node->pkt->pkttype==PKT_PUBLIC_KEY
2443               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2444             putchar(get_ownertrust_info (pk));
2445           putchar(':');
2446           putchar('\n');
2447           
2448           print_fingerprint (pk, NULL, 0);
2449
2450           /* print the revoker record */
2451           if( !pk->revkey && pk->numrevkeys )
2452             BUG();
2453           else
2454             {
2455               for (i=0; i < pk->numrevkeys; i++)
2456                 {
2457                   byte *p;
2458
2459                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
2460                   p = pk->revkey[i].fpr;
2461                   for (j=0; j < 20; j++, p++ )
2462                     printf ("%02X", *p);
2463                   printf (":%02x%s:\n", pk->revkey[i].class,
2464                           (pk->revkey[i].class&0x40)?"s":"");
2465                 }
2466             }
2467         }
2468     }
2469   
2470     /* the user ids */
2471     i = 0;
2472     for (node = keyblock; node; node = node->next) 
2473       {
2474         if ( node->pkt->pkttype == PKT_USER_ID )
2475           {
2476             PKT_user_id *uid = node->pkt->pkt.user_id;
2477
2478             ++i;
2479
2480             if(uid->attrib_data)
2481               printf("uat:");
2482             else
2483               printf("uid:");
2484
2485             if ( uid->is_revoked )
2486               printf("r::::::::");
2487             else if ( uid->is_expired )
2488               printf("e::::::::");
2489             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2490               printf("::::::::");
2491             else
2492               {
2493                 int uid_validity;
2494
2495                 if( primary && !ulti_hack )
2496                   uid_validity = get_validity_info( primary, uid );
2497                 else
2498                   uid_validity = 'u';
2499                 printf("%c::::::::",uid_validity);
2500               }
2501
2502             if(uid->attrib_data)
2503               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2504             else
2505               print_string (stdout, uid->name, uid->len, ':');
2506
2507             putchar (':');
2508             /* signature class */
2509             putchar (':');
2510             /* capabilities */
2511             putchar (':');
2512             /* preferences */
2513             if (pk_version>3 || uid->selfsigversion>3)
2514               {
2515                 const prefitem_t *prefs = uid->prefs;
2516                 
2517                 for (j=0; prefs && prefs[j].type; j++)
2518                   {
2519                     if (j)
2520                       putchar (' ');
2521                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2522                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2523                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2524                             prefs[j].value);
2525                   } 
2526                 if (uid->mdc_feature)
2527                   printf (",mdc");
2528                 if (!uid->ks_modify)
2529                   printf (",no-ks-modify");
2530               } 
2531             putchar (':');
2532             /* flags */
2533             printf ("%d,", i);
2534             if (uid->is_primary)
2535               putchar ('p');
2536             if (uid->is_revoked)
2537               putchar ('r');
2538             if (uid->is_expired)
2539               putchar ('e');
2540             if ((node->flag & NODFLG_SELUID))
2541               putchar ('s');
2542             if ((node->flag & NODFLG_MARK_A))
2543               putchar ('m');
2544             putchar (':');
2545             putchar('\n');
2546           }
2547       }
2548 }
2549
2550 static void
2551 show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
2552 {
2553   KBNODE node;
2554   int i=0;
2555
2556   for( node = keyblock; node; node = node->next )
2557     {
2558       if( node->pkt->pkttype == PKT_USER_ID
2559           && !is_deleted_kbnode(node))
2560         {
2561           PKT_user_id *uid = node->pkt->pkt.user_id;
2562           ++i;
2563           if(!flag || (flag && (node->flag & flag)))
2564             {
2565               if(!(flag&NODFLG_MARK_A) && pk)
2566                 tty_printf("%s ",uid_trust_string_fixed(pk,uid));
2567
2568               if( flag & NODFLG_MARK_A )
2569                 tty_printf("     ");
2570               else if( node->flag & NODFLG_SELUID )
2571                 tty_printf("(%d)* ", i);
2572               else if( uid->is_primary )
2573                 tty_printf("(%d). ", i);
2574               else
2575                 tty_printf("(%d)  ", i);
2576               tty_print_utf8_string( uid->name, uid->len );
2577               tty_printf("\n");
2578               if(with_prefs && pk)
2579                 {
2580                   if(pk->version>3 || uid->selfsigversion>3)
2581                     {
2582                       PKT_signature *selfsig=NULL;
2583                       KBNODE signode;
2584
2585                       for(signode=node->next;
2586                           signode && signode->pkt->pkttype==PKT_SIGNATURE;
2587                           signode=signode->next)
2588                         {
2589                           if(signode->pkt->pkt.signature->
2590                              flags.chosen_selfsig)
2591                             {
2592                               selfsig=signode->pkt->pkt.signature;
2593                               break;
2594                             }
2595                         }
2596
2597                       show_prefs (uid, selfsig, with_prefs == 2);
2598                     }
2599                   else
2600                     tty_printf(_("There are no preferences on a"
2601                                  " PGP 2.x-style user ID.\n"));
2602                 }
2603             }
2604         }
2605     }
2606 }
2607
2608 /****************
2609  * Display the key a the user ids, if only_marked is true, do only
2610  * so for user ids with mark A flag set and dont display the index number
2611  */
2612 static void
2613 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2614                          int with_fpr, int with_subkeys, int with_prefs )
2615 {
2616     KBNODE node;
2617     int i;
2618     int do_warn = 0;
2619     byte pk_version=0;
2620     PKT_public_key *primary=NULL;
2621
2622     if (opt.with_colons)
2623       {
2624         show_key_with_all_names_colon (keyblock);
2625         return;
2626       }
2627
2628     /* the keys */
2629     for( node = keyblock; node; node = node->next ) {
2630         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2631             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2632                 && !is_deleted_kbnode(node)) ) {
2633             PKT_public_key *pk = node->pkt->pkt.public_key;
2634             const char *otrust="err",*trust="err";
2635
2636             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2637                 /* do it here, so that debug messages don't clutter the
2638                  * output */
2639                 static int did_warn = 0;
2640
2641                 trust = get_validity_string (pk, NULL);
2642                 otrust = get_ownertrust_string (pk);
2643
2644                 /* Show a warning once */
2645                 if (!did_warn
2646                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2647                     did_warn = 1;
2648                     do_warn = 1;
2649                 }
2650
2651                 pk_version=pk->version;
2652                 primary=pk;
2653             }
2654
2655             if(pk->is_revoked)
2656               {
2657                 char *user=get_user_id_string_native(pk->revoked.keyid);
2658                 const char *algo=pubkey_algo_to_string(pk->revoked.algo);
2659                 tty_printf(_("This key was revoked on %s by %s key %s\n"),
2660                            revokestr_from_pk(pk),algo?algo:"?",user);
2661                 xfree(user);
2662               }
2663
2664             if(with_revoker)
2665               {
2666                 if( !pk->revkey && pk->numrevkeys )
2667                   BUG();
2668                 else
2669                   for(i=0;i<pk->numrevkeys;i++)
2670                     {
2671                       u32 r_keyid[2];
2672                       char *user;
2673                       const char *algo=
2674                         pubkey_algo_to_string(pk->revkey[i].algid);
2675
2676                       keyid_from_fingerprint(pk->revkey[i].fpr,
2677                                              MAX_FINGERPRINT_LEN,r_keyid);
2678
2679                       user=get_user_id_string_native(r_keyid);
2680                       tty_printf(_("This key may be revoked by %s key %s"),
2681                                  algo?algo:"?",user);
2682
2683                       if(pk->revkey[i].class&0x40)
2684                         {
2685                           tty_printf(" ");
2686                           tty_printf(_("(sensitive)"));
2687                         }
2688
2689                       tty_printf ("\n");
2690                       xfree(user);
2691                     }
2692               }
2693
2694             keyid_from_pk(pk,NULL);
2695             tty_printf("%s%c %4u%c/%s  ",
2696                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2697                        (node->flag & NODFLG_SELKEY)? '*':' ',
2698                        nbits_from_pk( pk ),
2699                        pubkey_letter( pk->pubkey_algo ),
2700                        keystr(pk->keyid));
2701
2702             tty_printf(_("created: %s"),datestr_from_pk(pk));
2703             tty_printf("  ");
2704             if(pk->is_revoked)
2705               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2706             else if(pk->has_expired)
2707               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2708             else
2709               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2710             tty_printf("  ");
2711             tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2712             tty_printf("\n");
2713
2714             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2715               {
2716                 if(opt.trust_model!=TM_ALWAYS)
2717                   {
2718                     tty_printf("%*s", (int)keystrlen()+13,"");
2719                     /* Ownertrust is only meaningful for the PGP or
2720                        classic trust models */
2721                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2722                       {
2723                         int width=14-strlen(otrust);
2724                         if(width<=0)
2725                           width=1;
2726                         tty_printf(_("trust: %s"), otrust);
2727                         tty_printf("%*s",width,"");
2728                       }
2729                     
2730                     tty_printf(_("validity: %s"), trust );
2731                     tty_printf("\n");
2732                   }
2733                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2734                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2735                   {
2736                     tty_printf("*** ");
2737                     tty_printf(_("This key has been disabled"));
2738                     tty_printf("\n");
2739                   }
2740               }
2741
2742             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2743               {
2744                 print_fingerprint ( pk, NULL, 2 );
2745                 tty_printf("\n");
2746               }
2747         }
2748         else if( node->pkt->pkttype == PKT_SECRET_KEY
2749             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2750           {
2751             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2752             tty_printf("%s%c %4u%c/%s  ",
2753                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2754                        (node->flag & NODFLG_SELKEY)? '*':' ',
2755                        nbits_from_sk( sk ),
2756                        pubkey_letter( sk->pubkey_algo ),
2757                        keystr_from_sk(sk));
2758             tty_printf(_("created: %s"),datestr_from_sk(sk));
2759             tty_printf("  ");
2760             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2761             tty_printf("\n");
2762             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2763               {
2764                 tty_printf("                     ");
2765                 tty_printf(_("card-no: ")); 
2766                 if (sk->protect.ivlen == 16
2767                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2768                   { /* This is an OpenPGP card. */
2769                     for (i=8; i < 14; i++)
2770                       {
2771                         if (i == 10)
2772                           tty_printf (" ");
2773                         tty_printf ("%02X", sk->protect.iv[i]);
2774                       }
2775                   }
2776                 else
2777                   { /* Something is wrong: Print all. */
2778                     for (i=0; i < sk->protect.ivlen; i++)
2779                       tty_printf ("%02X", sk->protect.iv[i]);
2780                   }
2781                 tty_printf ("\n");
2782               }
2783           }
2784     }
2785
2786     show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
2787
2788     if (do_warn)
2789         tty_printf (_("Please note that the shown key validity"
2790                       " is not necessarily correct\n"
2791                       "unless you restart the program.\n")); 
2792 }
2793
2794
2795 /* Display basic key information.  This function is suitable to show
2796    information on the key without any dependencies on the trustdb or
2797    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2798    a secret key.*/
2799 void
2800 show_basic_key_info ( KBNODE keyblock )
2801 {
2802   KBNODE node;
2803   int i;
2804
2805   /* The primary key */
2806   for (node = keyblock; node; node = node->next)
2807     {
2808       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2809         {
2810           PKT_public_key *pk = node->pkt->pkt.public_key;
2811           
2812           /* Note, we use the same format string as in other show
2813              functions to make the translation job easier. */
2814           tty_printf ("%s  %4u%c/%s  ",
2815                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2816                       nbits_from_pk( pk ),
2817                       pubkey_letter( pk->pubkey_algo ),
2818                       keystr_from_pk(pk));
2819           tty_printf(_("created: %s"),datestr_from_pk(pk));
2820           tty_printf("  ");
2821           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2822           tty_printf("\n");
2823           print_fingerprint ( pk, NULL, 3 );
2824           tty_printf("\n");
2825         }
2826       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2827         {
2828           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2829           tty_printf("%s  %4u%c/%s",
2830                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2831                      nbits_from_sk( sk ),
2832                      pubkey_letter( sk->pubkey_algo ),
2833                      keystr_from_sk(sk));
2834           tty_printf(_("created: %s"),datestr_from_sk(sk));
2835           tty_printf("  ");
2836           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2837           tty_printf("\n");
2838           print_fingerprint (NULL, sk, 3 );
2839           tty_printf("\n");
2840         }
2841     }
2842
2843   /* The user IDs. */
2844   for (i=0, node = keyblock; node; node = node->next)
2845     {
2846       if (node->pkt->pkttype == PKT_USER_ID)
2847         {
2848           PKT_user_id *uid = node->pkt->pkt.user_id;
2849           ++i;
2850      
2851           tty_printf ("     ");
2852           if (uid->is_revoked)
2853             tty_printf("[%s] ",_("revoked"));
2854           else if ( uid->is_expired )
2855             tty_printf("[%s] ",_("expired"));
2856           tty_print_utf8_string (uid->name, uid->len);
2857           tty_printf ("\n");
2858         }
2859     }
2860 }
2861
2862 static void
2863 show_key_and_fingerprint( KBNODE keyblock )
2864 {
2865   KBNODE node;
2866   PKT_public_key *pk = NULL;
2867
2868   for( node = keyblock; node; node = node->next )
2869     {
2870       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2871         {
2872           pk = node->pkt->pkt.public_key;
2873           tty_printf("pub   %4u%c/%s %s ",
2874                      nbits_from_pk( pk ),
2875                      pubkey_letter( pk->pubkey_algo ),
2876                      keystr_from_pk(pk),
2877                      datestr_from_pk(pk) );
2878         }
2879       else if( node->pkt->pkttype == PKT_USER_ID )
2880         {
2881           PKT_user_id *uid = node->pkt->pkt.user_id;
2882           tty_print_utf8_string( uid->name, uid->len );
2883           break;
2884         }
2885     }
2886   tty_printf("\n");
2887   if( pk )
2888     print_fingerprint( pk, NULL, 2 );
2889 }
2890
2891
2892 /* Show a warning if no uids on the key have the primary uid flag
2893    set. */
2894 static void
2895 no_primary_warning(KBNODE keyblock)
2896 {
2897   KBNODE node;
2898   int have_primary=0,uid_count=0;
2899
2900   /* TODO: if we ever start behaving differently with a primary or
2901      non-primary attribute ID, we will need to check for attributes
2902      here as well. */
2903
2904   for(node=keyblock; node; node = node->next)
2905     {
2906       if(node->pkt->pkttype==PKT_USER_ID
2907          && node->pkt->pkt.user_id->attrib_data==NULL)
2908         {
2909           uid_count++;
2910
2911           if(node->pkt->pkt.user_id->is_primary==2)
2912             {
2913               have_primary=1;
2914               break;
2915             }
2916         }
2917     }
2918
2919   if(uid_count>1 && !have_primary)
2920     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2921                " may\n              cause a different user ID to become"
2922                " the assumed primary.\n"));
2923 }
2924
2925 /****************
2926  * Ask for a new user id, do the selfsignature and put it into
2927  * both keyblocks.
2928  * Return true if there is a new user id
2929  */
2930 static int
2931 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
2932              int photo, const char *photo_name)
2933 {
2934     PKT_user_id *uid;
2935     PKT_public_key *pk=NULL;
2936     PKT_secret_key *sk=NULL;
2937     PKT_signature *sig=NULL;
2938     PACKET *pkt;
2939     KBNODE node;
2940     KBNODE pub_where=NULL, sec_where=NULL;
2941     int rc;
2942
2943     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2944         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2945             pk = node->pkt->pkt.public_key;
2946         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2947             break;
2948     }
2949     if( !node ) /* no subkey */
2950         pub_where = NULL;
2951     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2952         if( node->pkt->pkttype == PKT_SECRET_KEY )
2953             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2954         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2955             break;
2956     }
2957     if( !node ) /* no subkey */
2958         sec_where = NULL;
2959     assert(pk && sk);
2960
2961     if(photo) {
2962       int hasattrib=0;
2963
2964       for( node = pub_keyblock; node; node = node->next )
2965         if( node->pkt->pkttype == PKT_USER_ID &&
2966             node->pkt->pkt.user_id->attrib_data!=NULL)
2967           {
2968             hasattrib=1;
2969             break;
2970           }
2971
2972       /* It is legal but bad for compatibility to add a photo ID to a
2973          v3 key as it means that PGP2 will not be able to use that key
2974          anymore.  Also, PGP may not expect a photo on a v3 key.
2975          Don't bother to ask this if the key already has a photo - any
2976          damage has already been done at that point. -dms */
2977       if(pk->version==3 && !hasattrib)
2978         {
2979           if(opt.expert)
2980             {
2981               tty_printf(_("WARNING: This is a PGP2-style key.  "
2982                            "Adding a photo ID may cause some versions\n"
2983                            "         of PGP to reject this key.\n"));
2984
2985               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2986                                         _("Are you sure you still want "
2987                                           "to add it? (y/N) ")))
2988                 return 0;
2989             }
2990           else
2991             {
2992               tty_printf(_("You may not add a photo ID to "
2993                            "a PGP2-style key.\n"));
2994               return 0;
2995             }
2996         }
2997
2998       uid = generate_photo_id(pk,photo_name);
2999     } else
3000       uid = generate_user_id();
3001     if( !uid )
3002         return 0;
3003
3004     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
3005                              keygen_add_std_prefs, pk );
3006     free_secret_key( sk );
3007     if( rc ) {
3008         log_error("signing failed: %s\n", g10_errstr(rc) );
3009         free_user_id(uid);
3010         return 0;
3011     }
3012
3013     /* insert/append to secret keyblock */
3014     pkt = xmalloc_clear( sizeof *pkt );
3015     pkt->pkttype = PKT_USER_ID;
3016     pkt->pkt.user_id = scopy_user_id(uid);
3017     node = new_kbnode(pkt);
3018     if( sec_where )
3019         insert_kbnode( sec_where, node, 0 );
3020     else
3021         add_kbnode( sec_keyblock, node );
3022     pkt = xmalloc_clear( sizeof *pkt );
3023     pkt->pkttype = PKT_SIGNATURE;
3024     pkt->pkt.signature = copy_signature(NULL, sig);
3025     if( sec_where )
3026         insert_kbnode( node, new_kbnode(pkt), 0 );
3027     else
3028         add_kbnode( sec_keyblock, new_kbnode(pkt) );
3029     /* insert/append to public keyblock */
3030     pkt = xmalloc_clear( sizeof *pkt );
3031     pkt->pkttype = PKT_USER_ID;
3032     pkt->pkt.user_id = uid;
3033     node = new_kbnode(pkt);
3034     if( pub_where )
3035         insert_kbnode( pub_where, node, 0 );
3036     else
3037         add_kbnode( pub_keyblock, node );
3038     pkt = xmalloc_clear( sizeof *pkt );
3039     pkt->pkttype = PKT_SIGNATURE;
3040     pkt->pkt.signature = copy_signature(NULL, sig);
3041     if( pub_where )
3042         insert_kbnode( node, new_kbnode(pkt), 0 );
3043     else
3044         add_kbnode( pub_keyblock, new_kbnode(pkt) );
3045     return 1;
3046 }
3047
3048
3049 /****************
3050  * Remove all selected userids from the keyrings
3051  */
3052 static void
3053 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3054 {
3055     KBNODE node;
3056     int selected=0;
3057
3058     for( node = pub_keyblock; node; node = node->next ) {
3059         if( node->pkt->pkttype == PKT_USER_ID ) {
3060             selected = node->flag & NODFLG_SELUID;
3061             if( selected ) {
3062                 /* Only cause a trust update if we delete a
3063                    non-revoked user id */
3064                 if(!node->pkt->pkt.user_id->is_revoked)
3065                   update_trust=1;
3066                 delete_kbnode( node );
3067                 if( sec_keyblock ) {
3068                     KBNODE snode;
3069                     int s_selected = 0;
3070                     PKT_user_id *uid = node->pkt->pkt.user_id;
3071                     for( snode = sec_keyblock; snode; snode = snode->next ) {
3072                         if( snode->pkt->pkttype == PKT_USER_ID ) {
3073                             PKT_user_id *suid = snode->pkt->pkt.user_id;
3074
3075                             s_selected =
3076                                 (uid->len == suid->len
3077                                  && !memcmp( uid->name, suid->name, uid->len));
3078                             if( s_selected )
3079                                 delete_kbnode( snode );
3080                         }
3081                         else if( s_selected
3082                                  && snode->pkt->pkttype == PKT_SIGNATURE )
3083                             delete_kbnode( snode );
3084                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
3085                             s_selected = 0;
3086                     }
3087                 }
3088             }
3089         }
3090         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3091             delete_kbnode( node );
3092         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3093             selected = 0;
3094     }
3095     commit_kbnode( &pub_keyblock );
3096     if( sec_keyblock )
3097         commit_kbnode( &sec_keyblock );
3098 }
3099
3100
3101 static int
3102 menu_delsig( KBNODE pub_keyblock )
3103 {
3104     KBNODE node;
3105     PKT_user_id *uid = NULL;
3106     int changed=0;
3107
3108     for( node = pub_keyblock; node; node = node->next ) {
3109         if( node->pkt->pkttype == PKT_USER_ID ) {
3110             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
3111         }
3112         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3113            int okay, valid, selfsig, inv_sig, no_key, other_err;
3114
3115             tty_printf("uid  ");
3116             tty_print_utf8_string( uid->name, uid->len );
3117             tty_printf("\n");
3118
3119             okay = inv_sig = no_key = other_err = 0;
3120             if(opt.with_colons)
3121               valid = print_and_check_one_sig_colon( pub_keyblock, node,
3122                                                &inv_sig, &no_key, &other_err,
3123                                                &selfsig, 1 );
3124             else
3125               valid = print_and_check_one_sig( pub_keyblock, node,
3126                                                &inv_sig, &no_key, &other_err,
3127                                                &selfsig, 1 );
3128
3129            if( valid ) {
3130                okay = cpr_get_answer_yes_no_quit(
3131                    "keyedit.delsig.valid",
3132                    _("Delete this good signature? (y/N/q)"));
3133
3134                /* Only update trust if we delete a good signature.
3135                   The other two cases do not affect trust. */
3136                if(okay)
3137                  update_trust=1;
3138            }
3139            else if( inv_sig || other_err )
3140                okay = cpr_get_answer_yes_no_quit(
3141                    "keyedit.delsig.invalid",
3142                    _("Delete this invalid signature? (y/N/q)"));
3143            else if( no_key )
3144                okay = cpr_get_answer_yes_no_quit(
3145                    "keyedit.delsig.unknown",
3146                    _("Delete this unknown signature? (y/N/q)"));
3147
3148             if( okay == -1 )
3149                 break;
3150            if( okay && selfsig && !cpr_get_answer_is_yes(
3151                                "keyedit.delsig.selfsig",
3152                               _("Really delete this self-signature? (y/N)") ))
3153                 okay = 0;
3154             if( okay ) {
3155                 delete_kbnode( node );
3156                 changed++;
3157             }
3158
3159         }
3160         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3161             uid = NULL;
3162     }
3163
3164     if( changed ) {
3165         commit_kbnode( &pub_keyblock );
3166         tty_printf( changed == 1? _("Deleted %d signature.\n")
3167                                 : _("Deleted %d signatures.\n"), changed );
3168     }
3169     else
3170         tty_printf( _("Nothing deleted.\n") );
3171
3172     return changed;
3173 }
3174
3175 static int
3176 menu_clean_sigs_from_uids(KBNODE keyblock)
3177 {
3178   KBNODE uidnode;
3179   int modified=0;
3180   int select_all=!count_selected_uids(keyblock);
3181
3182   for(uidnode=keyblock->next;uidnode;uidnode=uidnode->next)
3183     {
3184       if(uidnode->pkt->pkttype==PKT_USER_ID
3185          && (uidnode->flag&NODFLG_SELUID || select_all))
3186         {
3187           int deleted;
3188           char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3189                                     uidnode->pkt->pkt.user_id->len,
3190                                     0);
3191           deleted=clean_sigs_from_uid(keyblock,uidnode,opt.verbose);
3192           if(deleted)
3193             {
3194               tty_printf(deleted==1?
3195                          "User ID \"%s\": %d signature removed.\n":
3196                          "User ID \"%s\": %d signatures removed.\n",
3197                          user,deleted);
3198               modified=1;
3199             }
3200           else
3201             tty_printf(_("User ID \"%s\": already clean.\n"),user);
3202
3203           xfree(user);
3204         }
3205     }
3206
3207   return modified;
3208 }
3209
3210 static int
3211 menu_clean_uids_from_key(KBNODE keyblock)
3212 {
3213   int modified=clean_uids_from_key(keyblock,0);
3214
3215   if(modified)
3216     {
3217       KBNODE node,uidnode=NULL;
3218
3219       for(node=keyblock->next;node;node=node->next)
3220         {
3221           if(node->pkt->pkttype==PKT_USER_ID)
3222             uidnode=node;
3223           else if(uidnode && node->pkt->pkttype==PKT_SIGNATURE
3224                   && is_deleted_kbnode(node))
3225             {
3226               const char *reason;
3227               char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3228                                         uidnode->pkt->pkt.user_id->len,0);
3229
3230               if(uidnode->pkt->pkt.user_id->is_revoked)
3231                 reason=_("revoked");
3232               else if(uidnode->pkt->pkt.user_id->is_expired)
3233                 reason=_("expired");
3234               else
3235                 reason=_("invalid");
3236
3237               tty_printf("User ID \"%s\" compacted: %s\n",user,reason);
3238
3239               uidnode=NULL;
3240
3241               xfree(user);
3242             }
3243         }
3244     }
3245   else
3246     tty_printf("No user IDs are compactable.\n");
3247
3248   return modified;
3249 }
3250
3251 /****************
3252  * Remove some of the secondary keys
3253  */
3254 static void