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