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