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