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