* skclist.c (build_sk_list): Don't need to warn about PGP-generated
[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       {
1314         log_error(_("can't do this in batch mode\n"));
1315         goto leave;
1316       }
1317
1318     /* get the public key */
1319     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1320     if( rc )
1321         goto leave;
1322     if( fix_keyblock( keyblock ) )
1323         modified++;
1324     if( collapse_uids( &keyblock ) )
1325         modified++;
1326     reorder_keyblock(keyblock);
1327
1328     if(seckey_check)
1329       {/* see whether we have a matching secret key */
1330         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1331
1332         sec_kdbhd = keydb_new (1);
1333         {
1334             byte afp[MAX_FINGERPRINT_LEN];
1335             size_t an;
1336
1337             fingerprint_from_pk (pk, afp, &an);
1338             while (an < MAX_FINGERPRINT_LEN) 
1339                 afp[an++] = 0;
1340             rc = keydb_search_fpr (sec_kdbhd, afp);
1341         }
1342         if (!rc)
1343           {
1344             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1345             if (rc)
1346               {
1347                 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1348                            username, g10_errstr(rc));
1349               }
1350             else
1351               {
1352                 merge_keys_and_selfsig( sec_keyblock );
1353                 if( fix_keyblock( sec_keyblock ) )
1354                   sec_modified++;
1355               }
1356           }
1357
1358         if (rc) {
1359             sec_keyblock = NULL;
1360             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1361             rc = 0;
1362         }
1363
1364         if( sec_keyblock && !quiet )
1365           tty_printf(_("Secret key is available.\n"));
1366     }
1367
1368     toggle = 0;
1369     cur_keyblock = keyblock;
1370     for(;;) { /* main loop */
1371         int i, arg_number, photo;
1372         const char *arg_string = "";
1373         char *p;
1374         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1375
1376         tty_printf("\n");
1377         if( redisplay && !quiet )
1378           {
1379             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1380             tty_printf("\n");
1381             redisplay = 0;
1382           }
1383         do {
1384             m_free(answer);
1385             if( have_commands ) {
1386                 if( commands ) {
1387                     answer = m_strdup( commands->d );
1388                     commands = commands->next;
1389                 }
1390                 else if( opt.batch ) {
1391                     answer = m_strdup("quit");
1392                 }
1393                 else
1394                     have_commands = 0;
1395             }
1396             if( !have_commands ) {
1397                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1398                 cpr_kill_prompt();
1399             }
1400             trim_spaces(answer);
1401         } while( *answer == '#' );
1402
1403         arg_number = 0; /* Yes, here is the init which egcc complains about */
1404         photo = 0; /* This too */
1405         if( !*answer )
1406             cmd = cmdLIST;
1407         else if( *answer == CONTROL_D )
1408             cmd = cmdQUIT;
1409         else if( digitp(answer ) ) {
1410             cmd = cmdSELUID;
1411             arg_number = atoi(answer);
1412         }
1413         else {
1414             if( (p=strchr(answer,' ')) ) {
1415                 *p++ = 0;
1416                 trim_spaces(answer);
1417                 trim_spaces(p);
1418                 arg_number = atoi(p);
1419                 arg_string = p;
1420             }
1421
1422             for(i=0; cmds[i].name; i++ ) {
1423                 if( !ascii_strcasecmp( answer, cmds[i].name ) )
1424                     break;
1425             }
1426             if( cmds[i].need_sk && !sec_keyblock ) {
1427                 tty_printf(_("Need the secret key to do this.\n"));
1428                 cmd = cmdNOP;
1429             }
1430             else if(  (cmds[i].not_with_sk == 1 && sec_keyblock && toggle)
1431                     ||(cmds[i].not_with_sk == 2 && sec_keyblock && !toggle)) {
1432                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1433                 cmd = cmdNOP;
1434             }
1435             else
1436                 cmd = cmds[i].id;
1437         }
1438         switch( cmd )  {
1439           case cmdHELP:
1440             for(i=0; cmds[i].name; i++ ) {
1441               if( cmds[i].need_sk && !sec_keyblock )
1442                 ; /* skip if we do not have the secret key */
1443               else if( cmds[i].desc )
1444                 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1445             }
1446             break;
1447
1448           case cmdLIST:
1449             redisplay = 1;
1450             break;
1451
1452           case cmdFPR:
1453             show_key_and_fingerprint( keyblock );
1454             break;
1455
1456           case cmdSELUID:
1457             if( menu_select_uid( cur_keyblock, arg_number ) )
1458                 redisplay = 1;
1459             break;
1460
1461           case cmdSELKEY:
1462             if( menu_select_key( cur_keyblock, arg_number ) )
1463                 redisplay = 1;
1464             break;
1465
1466           case cmdCHECK:
1467             /* we can only do this with the public key becuase the
1468              * check functions can't cope with secret keys and it
1469              * is questionable whether this would make sense at all */
1470             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1471             break;
1472
1473           case cmdSIGN: /* sign (only the public key) */
1474           case cmdLSIGN: /* sign (only the public key) */
1475           case cmdNRSIGN: /* sign (only the public key) */
1476           case cmdNRLSIGN: /* sign (only the public key) */
1477           case cmdTSIGN:
1478             if( pk->is_revoked )
1479               {
1480                 tty_printf(_("Key is revoked."));
1481
1482                 if(opt.expert)
1483                   {
1484                     tty_printf("  ");
1485                     if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1486                                               _("Are you sure you still want "
1487                                                 "to sign it? (y/N) ")))
1488                       break;
1489                   }
1490                 else
1491                   {
1492                     tty_printf(_("  Unable to sign.\n"));
1493                     break;
1494                   }
1495               }
1496
1497             if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) )
1498               {
1499                 if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1500                                         _("Really sign all user IDs? (y/N) ")))
1501                   {
1502                     tty_printf(_("Hint: Select the user IDs to sign\n"));
1503                     break;
1504                   }
1505               }
1506
1507             sign_uids( keyblock, locusr, &modified,
1508                        (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
1509                        (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
1510                        (cmd == cmdTSIGN));
1511             break;
1512
1513           case cmdDEBUG:
1514             dump_kbnode( cur_keyblock );
1515             break;
1516
1517           case cmdTOGGLE:
1518             toggle = !toggle;
1519             cur_keyblock = toggle? sec_keyblock : keyblock;
1520             redisplay = 1;
1521             break;
1522
1523           case cmdADDPHOTO:
1524             if (RFC2440 || RFC1991 || PGP2)
1525               {
1526                 tty_printf(
1527                    _("This command is not allowed while in %s mode.\n"),
1528                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1529                 break;
1530               }
1531             photo=1;
1532             /* fall through */
1533
1534           case cmdADDUID:
1535             if( menu_adduid( keyblock, sec_keyblock, photo ) )
1536               {
1537                 update_trust = 1;
1538                 redisplay = 1;
1539                 sec_modified = modified = 1;
1540                 merge_keys_and_selfsig( sec_keyblock );
1541                 merge_keys_and_selfsig( keyblock );
1542               }
1543             break;
1544
1545           case cmdDELUID: {
1546                 int n1;
1547
1548                 if( !(n1=count_selected_uids(keyblock)) )
1549                     tty_printf(_("You must select at least one user ID.\n"));
1550                 else if( real_uids_left(keyblock) < 1 )
1551                     tty_printf(_("You can't delete the last user ID!\n"));
1552                 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1553                 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1554                             : _("Really remove this user ID? (y/N) ")
1555                        ) ) {
1556                     menu_deluid( keyblock, sec_keyblock );
1557                     redisplay = 1;
1558                     modified = 1;
1559                     if( sec_keyblock )
1560                        sec_modified = 1;
1561                 }
1562             }
1563             break;
1564
1565           case cmdDELSIG: {
1566                 int n1;
1567
1568                 if( !(n1=count_selected_uids(keyblock)) )
1569                     tty_printf(_("You must select at least one user ID.\n"));
1570                 else if( menu_delsig( keyblock ) ) {
1571                     /* no redisplay here, because it may scroll away some
1572                      * status output of delsig */
1573                     modified = 1;
1574                 }
1575             }
1576             break;
1577
1578           case cmdADDKEY:
1579             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1580                 redisplay = 1;
1581                 sec_modified = modified = 1;
1582                 merge_keys_and_selfsig( sec_keyblock );
1583                 merge_keys_and_selfsig( keyblock );
1584             }
1585             break;
1586
1587 #ifdef ENABLE_CARD_SUPPORT
1588           case cmdADDCARDKEY:
1589             if (card_generate_subkey (keyblock, sec_keyblock)) {
1590                 redisplay = 1;
1591                 sec_modified = modified = 1;
1592                 merge_keys_and_selfsig( sec_keyblock );
1593                 merge_keys_and_selfsig( keyblock );
1594             }
1595             break;
1596
1597         case cmdKEYTOCARD:
1598           {
1599             KBNODE node=NULL;
1600             switch ( count_selected_keys (sec_keyblock) )
1601               {
1602               case 0:
1603                 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1604                                      _("Really move the primary key? (y/N) ")))
1605                   node = sec_keyblock;
1606                 break;
1607               case 1:
1608                 for (node = sec_keyblock; node; node = node->next )
1609                   {
1610                     if (node->pkt->pkttype == PKT_SECRET_SUBKEY 
1611                         && node->flag & NODFLG_SELKEY)
1612                       break;
1613                   }
1614                 break;
1615               default:
1616                 tty_printf(_("You must select exactly one key.\n"));
1617                 break;
1618               }
1619             if (node)
1620               {
1621                 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1622                 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1623                   {
1624                     redisplay = 1;
1625                     sec_modified = 1;
1626                   }
1627               }
1628           }
1629           break;
1630 #endif /* ENABLE_CARD_SUPPORT */
1631
1632           case cmdDELKEY: {
1633                 int n1;
1634
1635                 if( !(n1=count_selected_keys( keyblock )) )
1636                     tty_printf(_("You must select at least one key.\n"));
1637                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1638                        n1 > 1?
1639                    _("Do you really want to delete the selected keys? (y/N) "):
1640                         _("Do you really want to delete this key? (y/N) ")
1641                        ))
1642                     ;
1643                 else {
1644                     menu_delkey( keyblock, sec_keyblock );
1645                     redisplay = 1;
1646                     modified = 1;
1647                     if( sec_keyblock )
1648                        sec_modified = 1;
1649                 }
1650             }
1651             break;
1652
1653           case cmdADDREVOKER:
1654             {
1655               int sensitive=0;
1656
1657               if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1658                 sensitive=1;
1659               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1660                 redisplay = 1;
1661                 sec_modified = modified = 1;
1662                 merge_keys_and_selfsig( sec_keyblock );
1663                 merge_keys_and_selfsig( keyblock );
1664               }
1665             }
1666             break;
1667
1668           case cmdREVUID: {
1669                 int n1;
1670
1671                 if( !(n1=count_selected_uids(keyblock)) )
1672                     tty_printf(_("You must select at least one user ID.\n"));
1673                 else if( cpr_get_answer_is_yes(
1674                             "keyedit.revoke.uid.okay",
1675                        n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
1676                              : _("Really revoke this user ID? (y/N) ")
1677                        ) ) {
1678                   if(menu_revuid(keyblock,sec_keyblock))
1679                     {
1680                       modified=1;
1681                       redisplay=1;
1682                     }
1683                 }
1684             }
1685             break;
1686
1687           case cmdREVKEY: {
1688                 int n1;
1689
1690                 if( !(n1=count_selected_keys( keyblock )) )
1691                     tty_printf(_("You must select at least one key.\n"));
1692                 else if( sec_keyblock && !cpr_get_answer_is_yes(
1693                             "keyedit.revoke.subkey.okay",
1694                        n1 > 1?
1695                    _("Do you really want to revoke the selected keys? (y/N) "):
1696                    _("Do you really want to revoke this key? (y/N) ")
1697                        ))
1698                     ;
1699                 else {
1700                     if( menu_revkey( keyblock, sec_keyblock ) ) {
1701                         modified = 1;
1702                         /*sec_modified = 1;*/
1703                     }
1704                     redisplay = 1;
1705                 }
1706             }
1707             break;
1708
1709           case cmdEXPIRE:
1710             if( menu_expire( keyblock, sec_keyblock ) ) {
1711                 merge_keys_and_selfsig( sec_keyblock );
1712                 merge_keys_and_selfsig( keyblock );
1713                 sec_modified = 1;
1714                 modified = 1;
1715                 redisplay = 1;
1716             }
1717             break;
1718
1719           case cmdPRIMARY:
1720             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1721                 merge_keys_and_selfsig( keyblock );
1722                 modified = 1;
1723                 redisplay = 1;
1724             }
1725             break;
1726
1727           case cmdPASSWD:
1728             if( change_passphrase( sec_keyblock ) )
1729                 sec_modified = 1;
1730             break;
1731
1732           case cmdTRUST:
1733             if(opt.trust_model==TM_EXTERNAL)
1734               {
1735                 tty_printf(_("Owner trust may not be set while "
1736                              "using an user provided trust database\n"));
1737                 break;
1738               }
1739
1740             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1741             tty_printf("\n");
1742             if( edit_ownertrust( find_kbnode( keyblock,
1743                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1744                 redisplay = 1;
1745                 /* No real need to set update_trust here as
1746                    edit_ownertrust() calls revalidation_mark()
1747                    anyway. */
1748                 update_trust=1;
1749             }
1750             break;
1751
1752           case cmdPREF:
1753             show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1754             break;
1755
1756           case cmdSHOWPREF:
1757             show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1758             break;
1759
1760           case cmdSETPREF:
1761             keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
1762             break;
1763
1764           case cmdUPDPREF: 
1765             {
1766               PKT_user_id *temp=keygen_get_std_prefs();
1767               tty_printf(_("Set preference list to:\n"));
1768               show_prefs(temp,NULL,1);
1769               m_free(temp);
1770             }
1771             if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
1772                                         count_selected_uids (keyblock)?
1773                                        _("Really update the preferences"
1774                                          " for the selected user IDs? (y/N) "):
1775                                    _("Really update the preferences? (y/N) ")))
1776               {
1777
1778                 if ( menu_set_preferences (keyblock, sec_keyblock) )
1779                   {
1780                     merge_keys_and_selfsig (keyblock);
1781                     modified = 1;
1782                     redisplay = 1;
1783                   }
1784               }
1785             break;
1786
1787           case cmdPREFKS:
1788             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
1789                                          keyblock, sec_keyblock ) )
1790               {
1791                 merge_keys_and_selfsig( keyblock );
1792                 modified = 1;
1793                 redisplay = 1;
1794               }
1795             break;
1796
1797           case cmdNOP:
1798             break;
1799
1800           case cmdREVSIG:
1801             if( menu_revsig( keyblock ) ) {
1802                 redisplay = 1;
1803                 modified = 1;
1804             }
1805             break;
1806
1807           case cmdENABLEKEY:
1808           case cmdDISABLEKEY:
1809             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1810                 redisplay = 1;
1811                 modified = 1;
1812             }
1813             break;
1814
1815          case cmdSHOWPHOTO:
1816            menu_showphoto(keyblock);
1817            break;
1818
1819           case cmdQUIT:
1820             if( have_commands )
1821                 goto leave;
1822             if( !modified && !sec_modified )
1823                 goto leave;
1824             if( !cpr_get_answer_is_yes("keyedit.save.okay",
1825                                         _("Save changes? (y/N) ")) ) {
1826                 if( cpr_enabled()
1827                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
1828                                              _("Quit without saving? (y/N) ")))
1829                     goto leave;
1830                 break;
1831             }
1832             /* fall thru */
1833           case cmdSAVE:
1834             if( modified || sec_modified  ) {
1835                 if( modified ) {
1836                     rc = keydb_update_keyblock (kdbhd, keyblock);
1837                     if( rc ) {
1838                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
1839                         break;
1840                     }
1841                 }
1842                 if( sec_modified ) {
1843                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1844                     if( rc ) {
1845                         log_error( _("update secret failed: %s\n"),
1846                                    g10_errstr(rc) );
1847                         break;
1848                     }
1849                 }
1850             }
1851             else
1852                 tty_printf(_("Key not changed so no update needed.\n"));
1853
1854             if( update_trust )
1855               {
1856                 revalidation_mark ();
1857                 update_trust=0;
1858               }
1859             goto leave;
1860
1861           case cmdINVCMD:
1862           default:
1863             tty_printf("\n");
1864             tty_printf(_("Invalid command  (try \"help\")\n"));
1865             break;
1866         }
1867     } /* end main loop */
1868
1869   leave:
1870     release_kbnode( keyblock );
1871     release_kbnode( sec_keyblock );
1872     keydb_release (kdbhd);
1873     m_free(answer);
1874 }
1875
1876
1877 /****************
1878  * show preferences of a public keyblock.
1879  */
1880 static void
1881 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
1882 {
1883     const prefitem_t fake={0,0};
1884     const prefitem_t *prefs;
1885     int i;
1886
1887     if( !uid )
1888         return;
1889
1890     if( uid->prefs )
1891         prefs=uid->prefs;
1892     else if(verbose)
1893         prefs=&fake;
1894     else
1895       return;
1896
1897     if (verbose) {
1898         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1899
1900         tty_printf ("     ");
1901         tty_printf (_("Cipher: "));
1902         for(i=any=0; prefs[i].type; i++ ) {
1903             if( prefs[i].type == PREFTYPE_SYM ) {
1904                 const char *s = cipher_algo_to_string (prefs[i].value);
1905                 
1906                 if (any)
1907                     tty_printf (", ");
1908                 any = 1;
1909                 /* We don't want to display strings for experimental algos */
1910                 if (s && prefs[i].value < 100 )
1911                     tty_printf ("%s", s );
1912                 else
1913                     tty_printf ("[%d]", prefs[i].value);
1914                 if (prefs[i].value == CIPHER_ALGO_3DES )
1915                     des_seen = 1;
1916             }    
1917         }
1918         if (!des_seen) {
1919             if (any)
1920                 tty_printf (", ");
1921             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
1922         }
1923         tty_printf ("\n     ");
1924         tty_printf (_("Digest: "));
1925         for(i=any=0; prefs[i].type; i++ ) {
1926             if( prefs[i].type == PREFTYPE_HASH ) {
1927                 const char *s = digest_algo_to_string (prefs[i].value);
1928                 
1929                 if (any)
1930                     tty_printf (", ");
1931                 any = 1;
1932                 /* We don't want to display strings for experimental algos */
1933                 if (s && prefs[i].value < 100 )
1934                     tty_printf ("%s", s );
1935                 else
1936                     tty_printf ("[%d]", prefs[i].value);
1937                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
1938                     sha1_seen = 1;
1939             }
1940         }
1941         if (!sha1_seen) {
1942             if (any)
1943                 tty_printf (", ");
1944             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
1945         }
1946         tty_printf ("\n     ");
1947         tty_printf (_("Compression: "));
1948         for(i=any=0; prefs[i].type; i++ ) {
1949             if( prefs[i].type == PREFTYPE_ZIP ) {
1950                 const char *s=compress_algo_to_string(prefs[i].value);
1951                 
1952                 if (any)
1953                     tty_printf (", ");
1954                 any = 1;
1955                 /* We don't want to display strings for experimental algos */
1956                 if (s && prefs[i].value < 100 )
1957                     tty_printf ("%s", s );
1958                 else
1959                     tty_printf ("[%d]", prefs[i].value);
1960                 if (prefs[i].value == COMPRESS_ALGO_NONE )
1961                     uncomp_seen = 1;
1962             }
1963         }
1964         if (!uncomp_seen) {
1965             if (any)
1966                 tty_printf (", ");
1967             else {
1968               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
1969               tty_printf (", ");
1970             }
1971             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
1972         }
1973         if(uid->mdc_feature || !uid->ks_modify)
1974           {
1975             tty_printf ("\n     ");
1976             tty_printf (_("Features: "));
1977             any=0;
1978             if(uid->mdc_feature)
1979               {
1980                 tty_printf ("MDC");
1981                 any=1;
1982               }
1983             if(!uid->ks_modify)
1984               {
1985                 if(any)
1986                   tty_printf (", ");
1987                 tty_printf (_("Keyserver no-modify"));
1988               }
1989           }
1990         tty_printf("\n");
1991
1992         if(selfsig)
1993           {
1994             const byte *pref_ks;
1995             size_t pref_ks_len;
1996
1997             pref_ks=parse_sig_subpkt(selfsig->hashed,
1998                                      SIGSUBPKT_PREF_KS,&pref_ks_len);
1999             if(pref_ks && pref_ks_len)
2000               {
2001                 tty_printf ("     ");
2002                 tty_printf(_("Preferred keyserver: "));
2003                 tty_print_utf8_string(pref_ks,pref_ks_len);
2004                 tty_printf("\n");
2005               }
2006           }
2007     }
2008     else {
2009         tty_printf("    ");
2010         for(i=0; prefs[i].type; i++ ) {
2011             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
2012                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
2013                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2014                                  prefs[i].value);
2015         }
2016         if (uid->mdc_feature)
2017             tty_printf (" [mdc]");
2018         if (!uid->ks_modify)
2019             tty_printf (" [no-ks-modify]");
2020         tty_printf("\n");
2021     }
2022 }
2023
2024
2025 /* This is the version of show_key_with_all_names used when
2026    opt.with_colons is used.  It prints all available data in a easy to
2027    parse format and does not translate utf8 */
2028 static void
2029 show_key_with_all_names_colon (KBNODE keyblock)
2030 {
2031   KBNODE node;
2032   int i, j, ulti_hack=0;
2033   byte pk_version=0;
2034   PKT_public_key *primary=NULL;
2035
2036   /* the keys */
2037   for ( node = keyblock; node; node = node->next )
2038     {
2039       if (node->pkt->pkttype == PKT_PUBLIC_KEY
2040           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2041         {
2042           PKT_public_key *pk = node->pkt->pkt.public_key;
2043           u32 keyid[2];
2044
2045           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2046             {
2047               pk_version = pk->version;
2048               primary=pk;
2049             }
2050
2051           keyid_from_pk (pk, keyid);
2052
2053           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2054           if (!pk->is_valid)
2055             putchar ('i');
2056           else if (pk->is_revoked)
2057             putchar ('r');
2058           else if (pk->has_expired)
2059             putchar ('e');
2060           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2061             {
2062               int trust = get_validity_info (pk, NULL);
2063               if(trust=='u')
2064                 ulti_hack=1;
2065               putchar (trust);
2066             }
2067
2068           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2069                   nbits_from_pk (pk),
2070                   pk->pubkey_algo,
2071                   (ulong)keyid[0], (ulong)keyid[1],
2072                   (ulong)pk->timestamp,
2073                   (ulong)pk->expiredate );
2074           if (node->pkt->pkttype==PKT_PUBLIC_KEY
2075               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2076             putchar(get_ownertrust_info (pk));
2077           putchar(':');
2078           putchar('\n');
2079           
2080           print_fingerprint (pk, NULL, 0);
2081
2082           /* print the revoker record */
2083           if( !pk->revkey && pk->numrevkeys )
2084             BUG();
2085           else
2086             {
2087               for (i=0; i < pk->numrevkeys; i++)
2088                 {
2089                   byte *p;
2090
2091                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
2092                   p = pk->revkey[i].fpr;
2093                   for (j=0; j < 20; j++, p++ )
2094                     printf ("%02X", *p);
2095                   printf (":%02x%s:\n", pk->revkey[i].class,
2096                           (pk->revkey[i].class&0x40)?"s":"");
2097                 }
2098             }
2099         }
2100     }
2101   
2102     /* the user ids */
2103     i = 0;
2104     for (node = keyblock; node; node = node->next) 
2105       {
2106         if ( node->pkt->pkttype == PKT_USER_ID )
2107           {
2108             PKT_user_id *uid = node->pkt->pkt.user_id;
2109
2110             ++i;
2111
2112             if(uid->attrib_data)
2113               printf("uat:");
2114             else
2115               printf("uid:");
2116
2117             if ( uid->is_revoked )
2118               printf("r::::::::");
2119             else if ( uid->is_expired )
2120               printf("e::::::::");
2121             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2122               printf("::::::::");
2123             else
2124               {
2125                 int uid_validity;
2126
2127                 if( primary && !ulti_hack )
2128                   uid_validity = get_validity_info( primary, uid );
2129                 else
2130                   uid_validity = 'u';
2131                 printf("%c::::::::",uid_validity);
2132               }
2133
2134             if(uid->attrib_data)
2135               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2136             else
2137               print_string (stdout, uid->name, uid->len, ':');
2138
2139             putchar (':');
2140             /* signature class */
2141             putchar (':');
2142             /* capabilities */
2143             putchar (':');
2144             /* preferences */
2145             if (pk_version>3 || uid->selfsigversion>3)
2146               {
2147                 const prefitem_t *prefs = uid->prefs;
2148                 
2149                 for (j=0; prefs && prefs[j].type; j++)
2150                   {
2151                     if (j)
2152                       putchar (' ');
2153                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2154                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2155                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2156                             prefs[j].value);
2157                   } 
2158                 if (uid->mdc_feature)
2159                   printf (",mdc");
2160                 if (!uid->ks_modify)
2161                   printf (",no-ks-modify");
2162               } 
2163             putchar (':');
2164             /* flags */
2165             printf ("%d,", i);
2166             if (uid->is_primary)
2167               putchar ('p');
2168             if (uid->is_revoked)
2169               putchar ('r');
2170             if (uid->is_expired)
2171               putchar ('e');
2172             if ((node->flag & NODFLG_SELUID))
2173               putchar ('s');
2174             if ((node->flag & NODFLG_MARK_A))
2175               putchar ('m');
2176             putchar (':');
2177             putchar('\n');
2178           }
2179       }
2180 }
2181
2182
2183 /****************
2184  * Display the key a the user ids, if only_marked is true, do only
2185  * so for user ids with mark A flag set and dont display the index number
2186  */
2187 static void
2188 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2189                          int with_fpr, int with_subkeys, int with_prefs )
2190 {
2191     KBNODE node;
2192     int i;
2193     int do_warn = 0;
2194     byte pk_version=0;
2195     PKT_public_key *primary=NULL;
2196
2197     if (opt.with_colons)
2198       {
2199         show_key_with_all_names_colon (keyblock);
2200         return;
2201       }
2202
2203     /* the keys */
2204     for( node = keyblock; node; node = node->next ) {
2205         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2206             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
2207             PKT_public_key *pk = node->pkt->pkt.public_key;
2208             const char *otrust="err",*trust="err";
2209
2210             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2211                 /* do it here, so that debug messages don't clutter the
2212                  * output */
2213                 static int did_warn = 0;
2214
2215                 trust = get_validity_string (pk, NULL);
2216                 otrust = get_ownertrust_string (pk);
2217
2218                 /* Show a warning once */
2219                 if (!did_warn
2220                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2221                     did_warn = 1;
2222                     do_warn = 1;
2223                 }
2224
2225                 pk_version=pk->version;
2226                 primary=pk;
2227             }
2228
2229             if(with_revoker)
2230               {
2231                 if( !pk->revkey && pk->numrevkeys )
2232                   BUG();
2233                 else
2234                   for(i=0;i<pk->numrevkeys;i++)
2235                     {
2236                       u32 r_keyid[2];
2237                       char *user;
2238                       const char *algo=
2239                         pubkey_algo_to_string(pk->revkey[i].algid);
2240
2241                       keyid_from_fingerprint(pk->revkey[i].fpr,
2242                                              MAX_FINGERPRINT_LEN,r_keyid);
2243
2244                       user=get_user_id_string_native(r_keyid);
2245                       tty_printf(_("This key may be revoked by %s key %s"),
2246                                  algo?algo:"?",user);
2247
2248                       if(pk->revkey[i].class&0x40)
2249                         {
2250                           tty_printf(" ");
2251                           tty_printf(_("(sensitive)"));
2252                         }
2253
2254                       tty_printf ("\n");
2255                       m_free(user);
2256                     }
2257               }
2258
2259             keyid_from_pk(pk,NULL);
2260             tty_printf("%s%c %4u%c/%s  ",
2261                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2262                        (node->flag & NODFLG_SELKEY)? '*':' ',
2263                        nbits_from_pk( pk ),
2264                        pubkey_letter( pk->pubkey_algo ),
2265                        keystr(pk->keyid));
2266
2267             tty_printf(_("created: %s"),datestr_from_pk(pk));
2268             tty_printf("  ");
2269             if(pk->is_revoked)
2270               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2271             else if(pk->has_expired)
2272               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2273             else
2274               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2275             tty_printf("  ");
2276             tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2277             tty_printf("\n");
2278
2279             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2280               {
2281                 if(opt.trust_model!=TM_ALWAYS)
2282                   {
2283                     tty_printf("%*s",keystrlen()+13,"");
2284                     /* Ownertrust is only meaningful for the PGP or
2285                        classic trust models */
2286                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2287                       {
2288                         int width=14-strlen(otrust);
2289                         if(width<=0)
2290                           width=1;
2291                         tty_printf(_("trust: %s"), otrust);
2292                         tty_printf("%*s",width,"");
2293                       }
2294                     
2295                     tty_printf(_("validity: %s"), trust );
2296                     tty_printf("\n");
2297                   }
2298                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2299                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2300                   {
2301                     tty_printf("*** ");
2302                     tty_printf(_("This key has been disabled"));
2303                     tty_printf("\n");
2304                   }
2305               }
2306
2307             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2308               {
2309                 print_fingerprint ( pk, NULL, 2 );
2310                 tty_printf("\n");
2311               }
2312         }
2313         else if( node->pkt->pkttype == PKT_SECRET_KEY
2314             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2315           {
2316             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2317             tty_printf("%s%c %4u%c/%s  ",
2318                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2319                        (node->flag & NODFLG_SELKEY)? '*':' ',
2320                        nbits_from_sk( sk ),
2321                        pubkey_letter( sk->pubkey_algo ),
2322                        keystr_from_sk(sk));
2323             tty_printf(_("created: %s"),datestr_from_sk(sk));
2324             tty_printf("  ");
2325             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2326             tty_printf("\n");
2327             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2328               {
2329                 tty_printf("                     ");
2330                 tty_printf(_("card-no: ")); 
2331                 if (sk->protect.ivlen == 16
2332                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2333                   { /* This is an OpenPGP card. */
2334                     for (i=8; i < 14; i++)
2335                       {
2336                         if (i == 10)
2337                           tty_printf (" ");
2338                         tty_printf ("%02X", sk->protect.iv[i]);
2339                       }
2340                   }
2341                 else
2342                   { /* Something is wrong: Print all. */
2343                     for (i=0; i < sk->protect.ivlen; i++)
2344                       tty_printf ("%02X", sk->protect.iv[i]);
2345                   }
2346                 tty_printf ("\n");
2347               }
2348           }
2349     }
2350     
2351     /* the user ids */
2352
2353     i = 0;
2354     for( node = keyblock; node; node = node->next )
2355       {
2356         if( node->pkt->pkttype == PKT_USER_ID )
2357           {
2358             PKT_user_id *uid = node->pkt->pkt.user_id;
2359             ++i;
2360             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A)))
2361               {
2362                 if(!only_marked)
2363                   {
2364                     if(uid->is_revoked)
2365                       tty_printf(_("[%8.8s] "),_("revoked"));
2366                     else if(uid->is_expired)
2367                       tty_printf(_("[%8.8s] "),_("expired"));
2368                     else if(primary)
2369                       tty_printf(_("[%8.8s] "),
2370                                  trust_value_to_string(get_validity(primary,
2371                                                                     uid)));
2372                   }
2373
2374                 if( only_marked )
2375                   tty_printf("     ");
2376                 else if( node->flag & NODFLG_SELUID )
2377                   tty_printf("(%d)* ", i);
2378                 else if( uid->is_primary )
2379                   tty_printf("(%d). ", i);
2380                 else
2381                   tty_printf("(%d)  ", i);
2382                 tty_print_utf8_string( uid->name, uid->len );
2383                 tty_printf("\n");
2384                 if( with_prefs )
2385                   {
2386                     if(pk_version>3 || uid->selfsigversion>3)
2387                       {
2388                         PKT_signature *selfsig=NULL;
2389                         KBNODE signode;
2390
2391                         for(signode=node->next;
2392                             signode && signode->pkt->pkttype==PKT_SIGNATURE;
2393                             signode=signode->next)
2394                           {
2395                             if(signode->pkt->pkt.signature->
2396                                flags.chosen_selfsig)
2397                               {
2398                                 selfsig=signode->pkt->pkt.signature;
2399                                 break;
2400                               }
2401                           }
2402
2403                         show_prefs (uid, selfsig, with_prefs == 2);
2404                       }
2405                     else
2406                       tty_printf(_("There are no preferences on a "
2407                                    "PGP 2.x-style user ID.\n"));
2408                   }
2409               }
2410           }
2411       }
2412
2413     if (do_warn)
2414         tty_printf (_("Please note that the shown key validity "
2415                       "is not necessarily correct\n"
2416                       "unless you restart the program.\n")); 
2417 }
2418
2419
2420 /* Display basic key information.  This fucntion is suitable to show
2421    information on the key without any dependencies on the trustdb or
2422    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2423    a secret key.*/
2424 void
2425 show_basic_key_info ( KBNODE keyblock )
2426 {
2427   KBNODE node;
2428   int i;
2429
2430   /* The primary key */
2431   for (node = keyblock; node; node = node->next)
2432     {
2433       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2434         {
2435           PKT_public_key *pk = node->pkt->pkt.public_key;
2436           
2437           /* Note, we use the same format string as in other show
2438              functions to make the translation job easier. */
2439           tty_printf ("%s  %4u%c/%s  ",
2440                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2441                       nbits_from_pk( pk ),
2442                       pubkey_letter( pk->pubkey_algo ),
2443                       keystr_from_pk(pk));
2444           tty_printf(_("created: %s"),datestr_from_pk(pk));
2445           tty_printf("  ");
2446           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2447           tty_printf("\n");
2448           print_fingerprint ( pk, NULL, 3 );
2449           tty_printf("\n");
2450         }
2451       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2452         {
2453           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2454           tty_printf("%s  %4u%c/%s",
2455                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2456                      nbits_from_sk( sk ),
2457                      pubkey_letter( sk->pubkey_algo ),
2458                      keystr_from_sk(sk));
2459           tty_printf(_("created: %s"),datestr_from_sk(sk));
2460           tty_printf("  ");
2461           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2462           tty_printf("\n");
2463           print_fingerprint (NULL, sk, 3 );
2464           tty_printf("\n");
2465         }
2466     }
2467
2468   /* The user IDs. */
2469   for (i=0, node = keyblock; node; node = node->next)
2470     {
2471       if (node->pkt->pkttype == PKT_USER_ID)
2472         {
2473           PKT_user_id *uid = node->pkt->pkt.user_id;
2474           ++i;
2475      
2476           tty_printf ("     ");
2477           if (uid->is_revoked)
2478             tty_printf("[%s] ",_("revoked"));
2479           else if ( uid->is_expired )
2480             tty_printf("[%s] ",_("expired"));
2481           tty_print_utf8_string (uid->name, uid->len);
2482           tty_printf ("\n");
2483         }
2484     }
2485 }
2486
2487 static void
2488 show_key_and_fingerprint( KBNODE keyblock )
2489 {
2490   KBNODE node;
2491   PKT_public_key *pk = NULL;
2492
2493   for( node = keyblock; node; node = node->next )
2494     {
2495       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2496         {
2497           pk = node->pkt->pkt.public_key;
2498           tty_printf("pub   %4u%c/%s %s ",
2499                      nbits_from_pk( pk ),
2500                      pubkey_letter( pk->pubkey_algo ),
2501                      keystr_from_pk(pk),
2502                      datestr_from_pk(pk) );
2503         }
2504       else if( node->pkt->pkttype == PKT_USER_ID )
2505         {
2506           PKT_user_id *uid = node->pkt->pkt.user_id;
2507           tty_print_utf8_string( uid->name, uid->len );
2508           break;
2509         }
2510     }
2511   tty_printf("\n");
2512   if( pk )
2513     print_fingerprint( pk, NULL, 2 );
2514 }
2515
2516
2517 /* Show a warning if no uids on the key have the primary uid flag
2518    set. */
2519 static void
2520 no_primary_warning(KBNODE keyblock)
2521 {
2522   KBNODE node;
2523   int have_primary=0,uid_count=0;
2524
2525   /* TODO: if we ever start behaving differently with a primary or
2526      non-primary attribute ID, we will need to check for attributes
2527      here as well. */
2528
2529   for(node=keyblock; node; node = node->next)
2530     {
2531       if(node->pkt->pkttype==PKT_USER_ID
2532          && node->pkt->pkt.user_id->attrib_data==NULL)
2533         {
2534           uid_count++;
2535
2536           if(node->pkt->pkt.user_id->is_primary==2)
2537             {
2538               have_primary=1;
2539               break;
2540             }
2541         }
2542     }
2543
2544   if(uid_count>1 && !have_primary)
2545     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2546                " may\n              cause a different user ID to become"
2547                " the assumed primary.\n"));
2548 }
2549
2550 /****************
2551  * Ask for a new user id, do the selfsignature and put it into
2552  * both keyblocks.
2553  * Return true if there is a new user id
2554  */
2555 static int
2556 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2557 {
2558     PKT_user_id *uid;
2559     PKT_public_key *pk=NULL;
2560     PKT_secret_key *sk=NULL;
2561     PKT_signature *sig=NULL;
2562     PACKET *pkt;
2563     KBNODE node;
2564     KBNODE pub_where=NULL, sec_where=NULL;
2565     int rc;
2566
2567     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2568         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2569             pk = node->pkt->pkt.public_key;
2570         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2571             break;
2572     }
2573     if( !node ) /* no subkey */
2574         pub_where = NULL;
2575     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2576         if( node->pkt->pkttype == PKT_SECRET_KEY )
2577             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2578         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2579             break;
2580     }
2581     if( !node ) /* no subkey */
2582         sec_where = NULL;
2583     assert(pk && sk);
2584
2585     if(photo) {
2586       int hasattrib=0;
2587
2588       for( node = pub_keyblock; node; node = node->next )
2589         if( node->pkt->pkttype == PKT_USER_ID &&
2590             node->pkt->pkt.user_id->attrib_data!=NULL)
2591           {
2592             hasattrib=1;
2593             break;
2594           }
2595
2596       /* It is legal but bad for compatibility to add a photo ID to a
2597          v3 key as it means that PGP2 will not be able to use that key
2598          anymore.  Also, PGP may not expect a photo on a v3 key.
2599          Don't bother to ask this if the key already has a photo - any
2600          damage has already been done at that point. -dms */
2601       if(pk->version==3 && !hasattrib)
2602         {
2603           if(opt.expert)
2604             {
2605               tty_printf(_("WARNING: This is a PGP2-style key.  "
2606                            "Adding a photo ID may cause some versions\n"
2607                            "         of PGP to reject this key.\n"));
2608
2609               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2610                                         _("Are you sure you still want "
2611                                           "to add it? (y/N) ")))
2612                 return 0;
2613             }
2614           else
2615             {
2616               tty_printf(_("You may not add a photo ID to "
2617                            "a PGP2-style key.\n"));
2618               return 0;
2619             }
2620         }
2621
2622       uid = generate_photo_id(pk);
2623     } else
2624       uid = generate_user_id();
2625     if( !uid )
2626         return 0;
2627
2628     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2629                              keygen_add_std_prefs, pk );
2630     free_secret_key( sk );
2631     if( rc ) {
2632         log_error("signing failed: %s\n", g10_errstr(rc) );
2633         free_user_id(uid);
2634         return 0;
2635     }
2636
2637     /* insert/append to secret keyblock */
2638     pkt = m_alloc_clear( sizeof *pkt );
2639     pkt->pkttype = PKT_USER_ID;
2640     pkt->pkt.user_id = scopy_user_id(uid);
2641     node = new_kbnode(pkt);
2642     if( sec_where )
2643         insert_kbnode( sec_where, node, 0 );
2644     else
2645         add_kbnode( sec_keyblock, node );
2646     pkt = m_alloc_clear( sizeof *pkt );
2647     pkt->pkttype = PKT_SIGNATURE;
2648     pkt->pkt.signature = copy_signature(NULL, sig);
2649     if( sec_where )
2650         insert_kbnode( node, new_kbnode(pkt), 0 );
2651     else
2652         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2653     /* insert/append to public keyblock */
2654     pkt = m_alloc_clear( sizeof *pkt );
2655     pkt->pkttype = PKT_USER_ID;
2656     pkt->pkt.user_id = uid;
2657     node = new_kbnode(pkt);
2658     if( pub_where )
2659         insert_kbnode( pub_where, node, 0 );
2660     else
2661         add_kbnode( pub_keyblock, node );
2662     pkt = m_alloc_clear( sizeof *pkt );
2663     pkt->pkttype = PKT_SIGNATURE;
2664     pkt->pkt.signature = copy_signature(NULL, sig);
2665     if( pub_where )
2666         insert_kbnode( node, new_kbnode(pkt), 0 );
2667     else
2668         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2669     return 1;
2670 }
2671
2672
2673 /****************
2674  * Remove all selected userids from the keyrings
2675  */
2676 static void
2677 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2678 {
2679     KBNODE node;
2680     int selected=0;
2681
2682     for( node = pub_keyblock; node; node = node->next ) {
2683         if( node->pkt->pkttype == PKT_USER_ID ) {
2684             selected = node->flag & NODFLG_SELUID;
2685             if( selected ) {
2686                 /* Only cause a trust update if we delete a
2687                    non-revoked user id */
2688                 if(!node->pkt->pkt.user_id->is_revoked)
2689                   update_trust=1;
2690                 delete_kbnode( node );
2691                 if( sec_keyblock ) {
2692                     KBNODE snode;
2693                     int s_selected = 0;
2694                     PKT_user_id *uid = node->pkt->pkt.user_id;
2695                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2696                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2697                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2698
2699                             s_selected =
2700                                 (uid->len == suid->len
2701                                  && !memcmp( uid->name, suid->name, uid->len));
2702                             if( s_selected )
2703                                 delete_kbnode( snode );
2704                         }
2705                         else if( s_selected
2706                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2707                             delete_kbnode( snode );
2708                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2709                             s_selected = 0;
2710                     }
2711                 }
2712             }
2713         }
2714         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2715             delete_kbnode( node );
2716         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2717             selected = 0;
2718     }
2719     commit_kbnode( &pub_keyblock );
2720     if( sec_keyblock )
2721         commit_kbnode( &sec_keyblock );
2722 }
2723
2724
2725 static int
2726 menu_delsig( KBNODE pub_keyblock )
2727 {
2728     KBNODE node;
2729     PKT_user_id *uid = NULL;
2730     int changed=0;
2731
2732     for( node = pub_keyblock; node; node = node->next ) {
2733         if( node->pkt->pkttype == PKT_USER_ID ) {
2734             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2735         }
2736         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2737            int okay, valid, selfsig, inv_sig, no_key, other_err;
2738
2739             tty_printf("uid  ");
2740             tty_print_utf8_string( uid->name, uid->len );
2741             tty_printf("\n");
2742
2743             okay = inv_sig = no_key = other_err = 0;
2744             if(opt.with_colons)
2745               valid = print_and_check_one_sig_colon( pub_keyblock, node,
2746                                                &inv_sig, &no_key, &other_err,
2747                                                &selfsig, 1 );
2748             else
2749               valid = print_and_check_one_sig( pub_keyblock, node,
2750                                                &inv_sig, &no_key, &other_err,
2751                                                &selfsig, 1 );
2752
2753            if( valid ) {
2754                okay = cpr_get_answer_yes_no_quit(
2755                    "keyedit.delsig.valid",
2756                    _("Delete this good signature? (y/N/q)"));
2757
2758                /* Only update trust if we delete a good signature.
2759                   The other two cases do not affect trust. */
2760                if(okay)
2761                  update_trust=1;
2762            }
2763            else if( inv_sig || other_err )
2764                okay = cpr_get_answer_yes_no_quit(
2765                    "keyedit.delsig.invalid",
2766                    _("Delete this invalid signature? (y/N/q)"));
2767            else if( no_key )
2768                okay = cpr_get_answer_yes_no_quit(
2769                    "keyedit.delsig.unknown",
2770                    _("Delete this unknown signature? (y/N/q)"));
2771
2772             if( okay == -1 )
2773                 break;
2774            if( okay && selfsig && !cpr_get_answer_is_yes(
2775                                "keyedit.delsig.selfsig",
2776                               _("Really delete this self-signature? (y/N)") ))
2777                 okay = 0;
2778             if( okay ) {
2779                 delete_kbnode( node );
2780                 changed++;
2781             }
2782
2783         }
2784         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2785             uid = NULL;
2786     }
2787
2788     if( changed ) {
2789         commit_kbnode( &pub_keyblock );
2790         tty_printf( changed == 1? _("Deleted %d signature.\n")
2791                                 : _("Deleted %d signatures.\n"), changed );
2792     }
2793     else
2794         tty_printf( _("Nothing deleted.\n") );
2795
2796     return changed;
2797 }
2798
2799
2800 /****************
2801  * Remove some of the secondary keys
2802  */
2803 static void
2804 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2805 {
2806     KBNODE node;
2807     int selected=0;
2808
2809     for( node = pub_keyblock; node; node = node->next ) {
2810         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2811             selected = node->flag & NODFLG_SELKEY;
2812             if( selected ) {
2813                 delete_kbnode( node );
2814                 if( sec_keyblock ) {
2815                     KBNODE snode;
2816                     int s_selected = 0;
2817                     u32 ki[2];
2818
2819                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2820                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2821                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2822                             u32 ki2[2];
2823
2824                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2825                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2826                             if( s_selected )
2827                                 delete_kbnode( snode );
2828                         }
2829                         else if( s_selected
2830                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2831                             delete_kbnode( snode );
2832                         else
2833                             s_selected = 0;
2834                     }
2835                 }
2836             }
2837         }
2838         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2839             delete_kbnode( node );
2840         else
2841             selected = 0;
2842     }
2843     commit_kbnode( &pub_keyblock );
2844     if( sec_keyblock )
2845         commit_kbnode( &sec_keyblock );
2846
2847     /* No need to set update_trust here since signing keys are no
2848        longer used to certify other keys, so there is no change in
2849        trust when revoking/removing them */
2850 }
2851
2852
2853 /****************
2854  * Ask for a new revoker, do the selfsignature and put it into
2855  * both keyblocks.
2856  * Return true if there is a new revoker
2857  */
2858 static int
2859 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2860 {
2861   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2862   PKT_secret_key *sk=NULL;
2863   PKT_signature *sig=NULL;
2864   PACKET *pkt;
2865   struct revocation_key revkey;
2866   size_t fprlen;
2867   int rc;
2868
2869   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2870   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2871
2872   pk=pub_keyblock->pkt->pkt.public_key;
2873
2874   if(pk->numrevkeys==0 && pk->version==3)
2875     {
2876       /* It is legal but bad for compatibility to add a revoker to a
2877          v3 key as it means that PGP2 will not be able to use that key
2878          anymore.  Also, PGP may not expect a revoker on a v3 key.
2879          Don't bother to ask this if the key already has a revoker -
2880          any damage has already been done at that point. -dms */
2881       if(opt.expert)
2882         {
2883           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2884                        "Adding a designated revoker may cause\n"
2885                        "         some versions of PGP to reject this key.\n"));
2886
2887           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2888                                     _("Are you sure you still want "
2889                                       "to add it? (y/N) ")))
2890             return 0;
2891         }
2892       else
2893         {
2894           tty_printf(_("You may not add a designated revoker to "
2895                        "a PGP 2.x-style key.\n"));
2896           return 0;
2897         }
2898     }
2899
2900   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2901
2902   for(;;)
2903     {
2904       char *answer;
2905
2906       if(revoker_pk)
2907         free_public_key(revoker_pk);
2908
2909       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2910
2911       tty_printf("\n");
2912
2913       answer=cpr_get_utf8("keyedit.add_revoker",
2914                           _("Enter the user ID of the designated revoker: "));
2915       if(answer[0]=='\0' || answer[0]=='\004')
2916         {
2917           m_free(answer);
2918           goto fail;
2919         }
2920
2921       /* Note that I'm requesting SIG here and not CERT.  We're making
2922          a certification, but it is okay to be a subkey. */
2923       revoker_pk->req_usage=PUBKEY_USAGE_SIG;
2924       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2925       if(rc)
2926         {
2927           log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
2928           m_free(answer);
2929           continue;
2930         }
2931
2932       m_free(answer);
2933
2934       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2935       if(fprlen!=20)
2936         {
2937           log_error(_("cannot appoint a PGP 2.x style key as a "
2938                       "designated revoker\n"));
2939           continue;
2940         }
2941
2942       revkey.class=0x80;
2943       if(sensitive)
2944         revkey.class|=0x40;
2945       revkey.algid=revoker_pk->pubkey_algo;
2946
2947       if(cmp_public_keys(revoker_pk,pk)==0)
2948         {
2949           /* This actually causes no harm (after all, a key that
2950              designates itself as a revoker is the same as a
2951              regular key), but it's easy enough to check. */
2952           log_error(_("you cannot appoint a key as its own "
2953                       "designated revoker\n"));
2954
2955           continue;
2956         }
2957
2958       keyid_from_pk(pk,NULL);
2959
2960       /* Does this revkey already exist? */
2961       if(!pk->revkey && pk->numrevkeys)
2962         BUG();
2963       else
2964         {
2965           int i;
2966
2967           for(i=0;i<pk->numrevkeys;i++)
2968             {
2969               if(memcmp(&pk->revkey[i],&revkey,
2970                         sizeof(struct revocation_key))==0)
2971                 {
2972                   char buf[50];
2973
2974                   log_error(_("this key has already been designated "
2975                               "as a revoker\n"));
2976
2977                   sprintf(buf,"%08lX%08lX",
2978                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2979                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2980
2981                   break;
2982                 }
2983             }
2984
2985           if(i<pk->numrevkeys)
2986             continue;
2987         }
2988
2989       print_pubkey_info(NULL,revoker_pk);
2990       print_fingerprint(revoker_pk,NULL,2);
2991       tty_printf("\n");
2992
2993       tty_printf(_("WARNING: appointing a key as a designated revoker "
2994                    "cannot be undone!\n"));
2995
2996       tty_printf("\n");
2997
2998       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2999                                 _("Are you sure you want to appoint this "
3000                                   "key as a designated revoker? (y/N) ")))
3001         continue;
3002
3003       free_public_key(revoker_pk);
3004       revoker_pk=NULL;
3005       break;
3006     }
3007
3008   /* The 1F signature must be at least v4 to carry the revocation key
3009      subpacket. */
3010   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3011                            keygen_add_revkey,&revkey );
3012   if( rc )
3013     {
3014       log_error("signing failed: %s\n", g10_errstr(rc) );
3015       goto fail;
3016     }
3017
3018   free_secret_key(sk);
3019   sk=NULL;
3020
3021   /* insert into secret keyblock */
3022   pkt = m_alloc_clear( sizeof *pkt );
3023   pkt->pkttype = PKT_SIGNATURE;
3024   pkt->pkt.signature = copy_signature(NULL, sig);
3025   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3026
3027   /* insert into public keyblock */
3028   pkt = m_alloc_clear( sizeof *pkt );
3029   pkt->pkttype = PKT_SIGNATURE;
3030   pkt->pkt.signature = sig;
3031   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3032
3033   return 1;
3034
3035  fail:
3036   if(sk)
3037     free_secret_key(sk);
3038   if(sig)
3039     free_seckey_enc(sig);
3040   if(revoker_pk)
3041     free_public_key(revoker_pk);
3042
3043   return 0;
3044 }
3045
3046
3047 static int
3048 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3049 {
3050     int n1, signumber, rc;
3051     u32 expiredate;
3052     int mainkey=0;
3053     PKT_secret_key *sk;    /* copy of the main sk */
3054     PKT_public_key *main_pk, *sub_pk;
3055     PKT_user_id *uid;
3056     KBNODE node;
3057     u32 keyid[2];
3058
3059     if( count_selected_keys( sec_keyblock ) ) {
3060         tty_printf(_("Please remove selections from the secret keys.\n"));
3061         return 0;
3062     }
3063
3064     n1 = count_selected_keys( pub_keyblock );
3065     if( n1 > 1 ) {
3066         tty_printf(_("Please select at most one secondary key.\n"));
3067         return 0;
3068     }
3069     else if( n1 )
3070         tty_printf(_("Changing expiration time for a secondary key.\n"));
3071     else
3072       {
3073         tty_printf(_("Changing expiration time for the primary key.\n"));
3074         mainkey=1;
3075         no_primary_warning(pub_keyblock);
3076       }
3077
3078     expiredate = ask_expiredate();
3079     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3080     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3081
3082     /* Now we can actually change the self signature(s) */
3083     main_pk = sub_pk = NULL;
3084     uid = NULL;
3085     signumber = 0;
3086     for( node=pub_keyblock; node; node = node->next ) {
3087         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3088             main_pk = node->pkt->pkt.public_key;
3089             keyid_from_pk( main_pk, keyid );
3090             main_pk->expiredate = expiredate;
3091         }
3092         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3093                  && (node->flag & NODFLG_SELKEY ) ) {
3094             sub_pk = node->pkt->pkt.public_key;
3095             sub_pk->expiredate = expiredate;
3096         }
3097         else if( node->pkt->pkttype == PKT_USER_ID )
3098             uid = node->pkt->pkt.user_id;
3099         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3100                  && ( mainkey || sub_pk ) ) {
3101             PKT_signature *sig = node->pkt->pkt.signature;
3102             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3103                 && ( (mainkey && uid
3104                       && uid->created && (sig->sig_class&~3) == 0x10)
3105                      || (!mainkey && sig->sig_class == 0x18)  )
3106                 && sig->flags.chosen_selfsig )
3107               {
3108                 /* this is a selfsignature which is to be replaced */
3109                 PKT_signature *newsig;
3110                 PACKET *newpkt;
3111                 KBNODE sn;
3112                 int signumber2 = 0;
3113
3114                 signumber++;
3115
3116                 if( (mainkey && main_pk->version < 4)
3117                     || (!mainkey && sub_pk->version < 4 ) ) {
3118                     log_info(_(
3119                         "You can't change the expiration date of a v3 key\n"));
3120                     free_secret_key( sk );
3121                     return 0;
3122                 }
3123
3124                 /* find the corresponding secret self-signature */
3125                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3126                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3127                         PKT_signature *b = sn->pkt->pkt.signature;
3128                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3129                             && sig->sig_class == b->sig_class
3130                             && ++signumber2 == signumber )
3131                             break;
3132                     }
3133                 }
3134                 if( !sn )
3135                     log_info(_("No corresponding signature in secret ring\n"));
3136
3137                 if( mainkey )
3138                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3139                                             sk, keygen_add_key_expire, main_pk);
3140                 else
3141                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3142                                             sk, keygen_add_key_expire, sub_pk );
3143                 if( rc ) {
3144                     log_error("make_keysig_packet failed: %s\n",
3145                                                     g10_errstr(rc));
3146                     free_secret_key( sk );
3147                     return 0;
3148                 }
3149                 /* replace the packet */
3150                 newpkt = m_alloc_clear( sizeof *newpkt );
3151                 newpkt->pkttype = PKT_SIGNATURE;
3152                 newpkt->pkt.signature = newsig;
3153                 free_packet( node->pkt );
3154                 m_free( node->pkt );
3155                 node->pkt = newpkt;
3156                 if( sn ) {
3157                     newpkt = m_alloc_clear( sizeof *newpkt );
3158                     newpkt->pkttype = PKT_SIGNATURE;
3159                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3160                     free_packet( sn->pkt );
3161                     m_free( sn->pkt );
3162                     sn->pkt = newpkt;
3163                 }
3164                 sub_pk = NULL;
3165             }
3166         }
3167     }
3168
3169     free_secret_key( sk );
3170     update_trust=1;
3171     return 1;
3172 }
3173
3174 static int
3175 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3176 {
3177     byte buf[1];
3178
3179     /* first clear all primary uid flags so that we are sure none are
3180      * lingering around */
3181     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
3182     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3183
3184     /* if opaque is set,we want to set the primary id */
3185     if (opaque) { 
3186         buf[0] = 1;
3187         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3188     }
3189
3190     return 0;
3191 }
3192
3193
3194 /*
3195  * Set the primary uid flag for the selected UID.  We will also reset
3196  * all other primary uid flags.  For this to work with have to update
3197  * all the signature timestamps.  If we would do this with the current
3198  * time, we lose quite a lot of information, so we use a a kludge to
3199  * do this: Just increment the timestamp by one second which is
3200  * sufficient to updated a signature during import.
3201  */
3202 static int
3203 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3204 {
3205     PKT_secret_key *sk;    /* copy of the main sk */
3206     PKT_public_key *main_pk;
3207     PKT_user_id *uid;
3208     KBNODE node;
3209     u32 keyid[2];
3210     int selected;
3211     int attribute = 0;
3212     int modified = 0;
3213
3214     if ( count_selected_uids (pub_keyblock) != 1 ) {
3215         tty_printf(_("Please select exactly one user ID.\n"));
3216         return 0;
3217     }
3218
3219     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3220     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3221
3222     /* Now we can actually change the self signature(s) */
3223     main_pk = NULL;
3224     uid = NULL;
3225     selected = 0;
3226
3227     /* Is our selected uid an attribute packet? */
3228     for ( node=pub_keyblock; node; node = node->next )
3229       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3230         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3231
3232     for ( node=pub_keyblock; node; node = node->next ) {
3233         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3234             break; /* ready */
3235
3236         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3237             main_pk = node->pkt->pkt.public_key;
3238             keyid_from_pk( main_pk, keyid );
3239         }
3240         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3241             uid = node->pkt->pkt.user_id;
3242             selected = node->flag & NODFLG_SELUID;
3243         }
3244         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3245             PKT_signature *sig = node->pkt->pkt.signature;
3246             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3247                  && (uid && (sig->sig_class&~3) == 0x10)
3248                  && attribute == (uid->attrib_data!=NULL)
3249                  && sig->flags.chosen_selfsig )
3250               {
3251               if(sig->version < 4) {
3252                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3253
3254                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3255                          user);
3256                 m_free(user);
3257               }
3258               else {
3259                 /* This is a selfsignature which is to be replaced.
3260                    We can just ignore v3 signatures because they are
3261                    not able to carry the primary ID flag.  We also
3262                    ignore self-sigs on user IDs that are not of the
3263                    same type that we are making primary.  That is, if
3264                    we are making a user ID primary, we alter user IDs.
3265                    If we are making an attribute packet primary, we
3266                    alter attribute packets. */
3267
3268                 /* FIXME: We must make sure that we only have one
3269                    self-signature per user ID here (not counting
3270                    revocations) */
3271                 PKT_signature *newsig;
3272                 PACKET *newpkt;
3273                 const byte *p;
3274                 int action;
3275
3276                 /* see whether this signature has the primary UID flag */
3277                 p = parse_sig_subpkt (sig->hashed,
3278                                       SIGSUBPKT_PRIMARY_UID, NULL );
3279                 if ( !p )
3280                     p = parse_sig_subpkt (sig->unhashed,
3281                                           SIGSUBPKT_PRIMARY_UID, NULL );
3282                 if ( p && *p ) /* yes */
3283                     action = selected? 0 : -1;
3284                 else /* no */
3285                     action = selected? 1 : 0;
3286
3287                 if (action) {
3288                     int rc = update_keysig_packet (&newsig, sig,
3289                                                main_pk, uid, NULL,
3290                                                sk,
3291                                                change_primary_uid_cb,
3292                                                action > 0? "x":NULL );
3293                     if( rc ) {
3294                         log_error ("update_keysig_packet failed: %s\n",
3295                                    g10_errstr(rc));
3296                         free_secret_key( sk );
3297                         return 0;
3298                     }
3299                     /* replace the packet */
3300                     newpkt = m_alloc_clear( sizeof *newpkt );
3301                     newpkt->pkttype = PKT_SIGNATURE;
3302                     newpkt->pkt.signature = newsig;
3303                     free_packet( node->pkt );
3304                     m_free( node->pkt );
3305                     node->pkt = newpkt;
3306                     modified = 1;
3307                 }
3308               }
3309             }
3310         }
3311     }
3312
3313     free_secret_key( sk );
3314     return modified;
3315 }
3316
3317
3318 /* 
3319  * Set preferences to new values for the selected user IDs
3320  */
3321 static int
3322 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3323 {
3324     PKT_secret_key *sk;    /* copy of the main sk */
3325     PKT_public_key *main_pk;
3326     PKT_user_id *uid;
3327     KBNODE node;
3328     u32 keyid[2];
3329     int selected, select_all;
3330     int modified = 0;
3331
3332     no_primary_warning(pub_keyblock);
3333
3334     select_all = !count_selected_uids (pub_keyblock);
3335
3336     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3337     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3338
3339     /* Now we can actually change the self signature(s) */
3340     main_pk = NULL;
3341     uid = NULL;
3342     selected = 0;
3343     for ( node=pub_keyblock; node; node = node->next ) {
3344         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3345             break; /* ready */
3346
3347         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3348             main_pk = node->pkt->pkt.public_key;
3349             keyid_from_pk( main_pk, keyid );
3350         }
3351         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3352             uid = node->pkt->pkt.user_id;
3353             selected = select_all || (node->flag & NODFLG_SELUID);
3354         }
3355         else if ( main_pk && uid && selected
3356                   && node->pkt->pkttype == PKT_SIGNATURE ) {
3357             PKT_signature *sig = node->pkt->pkt.signature;
3358             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3359                  && (uid && (sig->sig_class&~3) == 0x10)
3360                  && sig->flags.chosen_selfsig ) {
3361               if( sig->version < 4 ) {
3362                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3363
3364                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3365                          user);
3366                 m_free(user);
3367               }
3368               else {
3369                 /* This is a selfsignature which is to be replaced 
3370                  * We have to ignore v3 signatures because they are
3371                  * not able to carry the preferences */
3372                 PKT_signature *newsig;
3373                 PACKET *newpkt;
3374                 int rc;
3375
3376                 rc = update_keysig_packet (&newsig, sig,
3377                                            main_pk, uid, NULL,
3378                                            sk,
3379                                            keygen_upd_std_prefs,
3380                                            NULL );
3381                 if( rc ) {
3382                     log_error ("update_keysig_packet failed: %s\n",
3383                                g10_errstr(rc));
3384                     free_secret_key( sk );
3385                     return 0;
3386                 }
3387                 /* replace the packet */
3388                 newpkt = m_alloc_clear( sizeof *newpkt );
3389                 newpkt->pkttype = PKT_SIGNATURE;
3390                 newpkt->pkt.signature = newsig;
3391                 free_packet( node->pkt );
3392                 m_free( node->pkt );
3393                 node->pkt = newpkt;
3394                 modified = 1;
3395               }
3396             }
3397         }
3398     }
3399     
3400     free_secret_key( sk );
3401     return modified;
3402 }
3403
3404
3405 static int
3406 menu_set_keyserver_url (const char *url,
3407                         KBNODE pub_keyblock, KBNODE sec_keyblock )
3408 {
3409   PKT_secret_key *sk;    /* copy of the main sk */
3410   PKT_public_key *main_pk;
3411   PKT_user_id *uid;
3412   KBNODE node;
3413   u32 keyid[2];
3414   int selected, select_all;
3415   int modified = 0;
3416   char *answer,*uri;
3417
3418   no_primary_warning(pub_keyblock);
3419
3420   if(url)
3421     answer=m_strdup(url);
3422   else
3423     {
3424       answer=cpr_get_utf8("keyedit.add_keyserver",
3425                           _("Enter your preferred keyserver URL: "));
3426       if(answer[0]=='\0' || answer[0]=='\004')
3427         {
3428           m_free(answer);
3429           return 0;
3430         }
3431     }
3432
3433   if(ascii_strcasecmp(answer,"none")==0)
3434     uri=NULL;
3435   else
3436     {
3437       struct keyserver_spec *keyserver=NULL;
3438       /* Sanity check the format */
3439       keyserver=parse_keyserver_uri(answer,1,NULL,0);
3440       m_free(answer);
3441       if(!keyserver)
3442         {
3443           log_info(_("could not parse keyserver URL\n"));
3444           return 0;
3445         }
3446       uri=m_strdup(keyserver->uri);
3447       free_keyserver_spec(keyserver);
3448     }
3449
3450   select_all = !count_selected_uids (pub_keyblock);
3451
3452   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3453   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3454
3455   /* Now we can actually change the self signature(s) */
3456   main_pk = NULL;
3457   uid = NULL;
3458   selected = 0;
3459   for ( node=pub_keyblock; node; node = node->next )
3460     {
3461       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3462         break; /* ready */
3463
3464       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
3465         {
3466           main_pk = node->pkt->pkt.public_key;
3467           keyid_from_pk( main_pk, keyid );
3468         }
3469       else if ( node->pkt->pkttype == PKT_USER_ID )
3470         {
3471           uid = node->pkt->pkt.user_id;
3472           selected = select_all || (node->flag & NODFLG_SELUID);
3473         }
3474       else if ( main_pk && uid && selected
3475                 && node->pkt->pkttype == PKT_SIGNATURE )
3476         {
3477           PKT_signature *sig = node->pkt->pkt.signature;
3478           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3479                && (uid && (sig->sig_class&~3) == 0x10) )
3480             {
3481               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3482               if( sig->version < 4 )
3483                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3484                          user);
3485               else
3486                 {
3487                   /* This is a selfsignature which is to be replaced
3488                    * We have to ignore v3 signatures because they are
3489                    * not able to carry the subpacket. */
3490                   PKT_signature *newsig;
3491                   PACKET *newpkt;
3492                   int rc;
3493                   const byte *p;
3494                   size_t plen;
3495
3496                   p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
3497                   if(p && plen)
3498                     {
3499                       tty_printf("Current preferred keyserver for user"
3500                                  " ID \"%s\": ",user);
3501                       tty_print_utf8_string(p,plen);
3502                       tty_printf("\n");
3503                       if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
3504                          uri?_("Are you sure you want to replace it? (y/N) "):
3505                              _("Are you sure you want to delete it? (y/N) ")))
3506                         continue;
3507                     }
3508                   else if(uri==NULL)
3509                     {
3510                       /* There is no current keyserver URL, so there
3511                          is no point in trying to un-set it. */
3512                       continue;
3513                     }
3514
3515                   rc = update_keysig_packet (&newsig, sig,
3516                                              main_pk, uid, NULL,
3517                                              sk,
3518                                              keygen_add_keyserver_url, uri );
3519                   if( rc )
3520                     {
3521                       log_error ("update_keysig_packet failed: %s\n",
3522                                  g10_errstr(rc));
3523                       free_secret_key( sk );
3524                       m_free(uri);
3525                       return 0;
3526                     }
3527                   /* replace the packet */
3528                   newpkt = m_alloc_clear( sizeof *newpkt );
3529                   newpkt->pkttype = PKT_SIGNATURE;
3530                   newpkt->pkt.signature = newsig;
3531                   free_packet( node->pkt );
3532                   m_free( node->pkt );
3533                   node->pkt = newpkt;
3534                   modified = 1;
3535                 }
3536
3537               m_free(user);
3538             }
3539         }
3540     }
3541
3542   m_free(uri);
3543   free_secret_key( sk );
3544   return modified;
3545 }
3546
3547
3548 /****************
3549  * Select one user id or remove all selection if index is 0.
3550  * Returns: True if the selection changed;
3551  */
3552 static int
3553 menu_select_uid( KBNODE keyblock, int idx )
3554 {
3555     KBNODE node;
3556     int i;
3557
3558     /* first check that the index is valid */
3559     if( idx ) {
3560         for( i=0, node = keyblock; node; node = node->next ) {
3561             if( node->pkt->pkttype == PKT_USER_ID ) {
3562                 if( ++i == idx )
3563                     break;
3564             }
3565         }
3566         if( !node ) {
3567             tty_printf(_("No user ID with index %d\n"), idx );
3568             return 0;
3569         }
3570     }
3571     else { /* reset all */
3572         for( i=0, node = keyblock; node; node = node->next ) {
3573             if( node->pkt->pkttype == PKT_USER_ID )
3574                 node->flag &= ~NODFLG_SELUID;
3575         }
3576         return 1;
3577     }
3578     /* and toggle the new index */
3579     for( i=0, node = keyblock; node; node = node->next ) {
3580         if( node->pkt->pkttype == PKT_USER_ID ) {
3581             if( ++i == idx ) {
3582                 if( (node->flag & NODFLG_SELUID) )
3583                     node->flag &= ~NODFLG_SELUID;
3584                 else
3585                     node->flag |= NODFLG_SELUID;
3586             }
3587         }
3588     }
3589
3590     return 1;
3591 }
3592
3593 /****************
3594  * Select secondary keys
3595  * Returns: True if the selection changed;
3596  */
3597 static int
3598 menu_select_key( KBNODE keyblock, int idx )
3599 {
3600     KBNODE node;
3601     int i;
3602
3603     /* first check that the index is valid */
3604     if( idx ) {
3605         for( i=0, node = keyblock; node; node = node->next ) {
3606             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3607                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3608                 if( ++i == idx )
3609                     break;
3610             }
3611         }
3612         if( !node ) {
3613             tty_printf(_("No secondary key with index %d\n"), idx );
3614             return 0;
3615         }
3616     }
3617     else { /* reset all */
3618         for( i=0, node = keyblock; node; node = node->next ) {
3619             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3620                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3621                 node->flag &= ~NODFLG_SELKEY;
3622         }
3623         return 1;
3624     }
3625     /* and set the new index */
3626     for( i=0, node = keyblock; node; node = node->next ) {
3627         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3628             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3629             if( ++i == idx ) {
3630                 if( (node->flag & NODFLG_SELKEY) )
3631                     node->flag &= ~NODFLG_SELKEY;
3632                 else
3633                     node->flag |= NODFLG_SELKEY;
3634             }
3635         }
3636     }
3637
3638     return 1;
3639 }
3640
3641
3642 static int
3643 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3644 {
3645     KBNODE node;
3646     int i=0;
3647
3648     for( node = keyblock; node; node = node->next )
3649         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3650             i++;
3651     return i;
3652 }
3653
3654 static int
3655 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3656 {
3657     KBNODE node;
3658     int i=0;
3659
3660     for( node = keyblock; node; node = node->next )
3661         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3662               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3663             && (node->flag & flag) )
3664             i++;
3665     return i;
3666 }
3667
3668 static int
3669 count_uids( KBNODE keyblock )
3670 {
3671     KBNODE node;
3672     int i=0;
3673
3674     for( node = keyblock; node; node = node->next )
3675         if( node->pkt->pkttype == PKT_USER_ID )
3676             i++;
3677     return i;
3678 }
3679
3680
3681 /****************
3682  * Returns true if there is at least one selected user id
3683  */
3684 static int
3685 count_selected_uids( KBNODE keyblock )
3686 {
3687     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3688 }
3689
3690 static int
3691 count_selected_keys( KBNODE keyblock )
3692 {
3693     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3694 }
3695
3696 /* returns how many real (i.e. not attribute) uids are unmarked */
3697 static int
3698 real_uids_left( KBNODE keyblock )
3699 {
3700   KBNODE node;
3701   int real=0;
3702
3703   for(node=keyblock;node;node=node->next)
3704     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3705        !node->pkt->pkt.user_id->attrib_data)
3706       real++;
3707
3708   return real;
3709 }
3710
3711 /*
3712  * Ask whether the signature should be revoked.  If the user commits this,
3713  * flag bit MARK_A is set on the signature and the user ID.
3714  */
3715 static void
3716 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3717 {
3718     int doit=0;
3719     char *p;
3720     PKT_signature *sig = node->pkt->pkt.signature;
3721     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3722
3723     if( !unode ) {
3724         log_error("Oops: no user ID for signature\n");
3725         return;
3726     }
3727
3728     p=utf8_to_native(unode->pkt->pkt.user_id->name,
3729                      unode->pkt->pkt.user_id->len,0);
3730     tty_printf(_("user ID: \"%s\"\n"),p);
3731     m_free(p);
3732
3733     tty_printf(_("signed by your key %s on %s%s%s\n"),
3734                keystr(sig->keyid),datestr_from_sig(sig),
3735                sig->flags.exportable?"":_(" (non-exportable)"),"");
3736
3737     if(sig->flags.expired)
3738       {
3739         tty_printf(_("This signature expired on %s.\n"),
3740                    expirestr_from_sig(sig));
3741         /* Use a different question so we can have different help text */
3742         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3743                         _("Are you sure you still want to revoke it? (y/N) "));
3744       }
3745     else
3746       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3747               _("Create a revocation certificate for this signature? (y/N) "));
3748
3749     if(doit) {
3750       node->flag |= NODFLG_MARK_A;
3751       unode->flag |= NODFLG_MARK_A;
3752     }
3753 }
3754
3755 /****************
3756  * Display all user ids of the current public key together with signatures
3757  * done by one of our keys.  Then walk over all this sigs and ask the user
3758  * whether he wants to revoke this signature.
3759  * Return: True when the keyblock has changed.
3760  */
3761 static int
3762 menu_revsig( KBNODE keyblock )
3763 {
3764     PKT_signature *sig;
3765     PKT_public_key *primary_pk;
3766     KBNODE node;
3767     int changed = 0;
3768     int rc, any, skip=1, all=!count_selected_uids(keyblock);
3769     struct revocation_reason_info *reason = NULL;
3770
3771     assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3772
3773     /* FIXME: detect duplicates here  */
3774     tty_printf(_("You have signed these user IDs on key %s:\n"),
3775                keystr_from_pk(keyblock->pkt->pkt.public_key));