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