* trustdb.h, trustdb.c (uid_trust_string_fixed): New. Return a fixed-size
[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                   tty_printf("%s ",uid_trust_string_fixed(primary,uid));
2364
2365                 if( only_marked )
2366                   tty_printf("     ");
2367                 else if( node->flag & NODFLG_SELUID )
2368                   tty_printf("(%d)* ", i);
2369                 else if( uid->is_primary )
2370                   tty_printf("(%d). ", i);
2371                 else
2372                   tty_printf("(%d)  ", i);
2373                 tty_print_utf8_string( uid->name, uid->len );
2374                 tty_printf("\n");
2375                 if( with_prefs )
2376                   {
2377                     if(pk_version>3 || uid->selfsigversion>3)
2378                       {
2379                         PKT_signature *selfsig=NULL;
2380                         KBNODE signode;
2381
2382                         for(signode=node->next;
2383                             signode && signode->pkt->pkttype==PKT_SIGNATURE;
2384                             signode=signode->next)
2385                           {
2386                             if(signode->pkt->pkt.signature->
2387                                flags.chosen_selfsig)
2388                               {
2389                                 selfsig=signode->pkt->pkt.signature;
2390                                 break;
2391                               }
2392                           }
2393
2394                         show_prefs (uid, selfsig, with_prefs == 2);
2395                       }
2396                     else
2397                       tty_printf(_("There are no preferences on a"
2398                                    " PGP 2.x-style user ID.\n"));
2399                   }
2400               }
2401           }
2402       }
2403
2404     if (do_warn)
2405         tty_printf (_("Please note that the shown key validity"
2406                       " is not necessarily correct\n"
2407                       "unless you restart the program.\n")); 
2408 }
2409
2410
2411 /* Display basic key information.  This fucntion is suitable to show
2412    information on the key without any dependencies on the trustdb or
2413    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2414    a secret key.*/
2415 void
2416 show_basic_key_info ( KBNODE keyblock )
2417 {
2418   KBNODE node;
2419   int i;
2420
2421   /* The primary key */
2422   for (node = keyblock; node; node = node->next)
2423     {
2424       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2425         {
2426           PKT_public_key *pk = node->pkt->pkt.public_key;
2427           
2428           /* Note, we use the same format string as in other show
2429              functions to make the translation job easier. */
2430           tty_printf ("%s  %4u%c/%s  ",
2431                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2432                       nbits_from_pk( pk ),
2433                       pubkey_letter( pk->pubkey_algo ),
2434                       keystr_from_pk(pk));
2435           tty_printf(_("created: %s"),datestr_from_pk(pk));
2436           tty_printf("  ");
2437           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2438           tty_printf("\n");
2439           print_fingerprint ( pk, NULL, 3 );
2440           tty_printf("\n");
2441         }
2442       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2443         {
2444           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2445           tty_printf("%s  %4u%c/%s",
2446                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2447                      nbits_from_sk( sk ),
2448                      pubkey_letter( sk->pubkey_algo ),
2449                      keystr_from_sk(sk));
2450           tty_printf(_("created: %s"),datestr_from_sk(sk));
2451           tty_printf("  ");
2452           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2453           tty_printf("\n");
2454           print_fingerprint (NULL, sk, 3 );
2455           tty_printf("\n");
2456         }
2457     }
2458
2459   /* The user IDs. */
2460   for (i=0, node = keyblock; node; node = node->next)
2461     {
2462       if (node->pkt->pkttype == PKT_USER_ID)
2463         {
2464           PKT_user_id *uid = node->pkt->pkt.user_id;
2465           ++i;
2466      
2467           tty_printf ("     ");
2468           if (uid->is_revoked)
2469             tty_printf("[%s] ",_("revoked"));
2470           else if ( uid->is_expired )
2471             tty_printf("[%s] ",_("expired"));
2472           tty_print_utf8_string (uid->name, uid->len);
2473           tty_printf ("\n");
2474         }
2475     }
2476 }
2477
2478 static void
2479 show_key_and_fingerprint( KBNODE keyblock )
2480 {
2481   KBNODE node;
2482   PKT_public_key *pk = NULL;
2483
2484   for( node = keyblock; node; node = node->next )
2485     {
2486       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2487         {
2488           pk = node->pkt->pkt.public_key;
2489           tty_printf("pub   %4u%c/%s %s ",
2490                      nbits_from_pk( pk ),
2491                      pubkey_letter( pk->pubkey_algo ),
2492                      keystr_from_pk(pk),
2493                      datestr_from_pk(pk) );
2494         }
2495       else if( node->pkt->pkttype == PKT_USER_ID )
2496         {
2497           PKT_user_id *uid = node->pkt->pkt.user_id;
2498           tty_print_utf8_string( uid->name, uid->len );
2499           break;
2500         }
2501     }
2502   tty_printf("\n");
2503   if( pk )
2504     print_fingerprint( pk, NULL, 2 );
2505 }
2506
2507
2508 /* Show a warning if no uids on the key have the primary uid flag
2509    set. */
2510 static void
2511 no_primary_warning(KBNODE keyblock)
2512 {
2513   KBNODE node;
2514   int have_primary=0,uid_count=0;
2515
2516   /* TODO: if we ever start behaving differently with a primary or
2517      non-primary attribute ID, we will need to check for attributes
2518      here as well. */
2519
2520   for(node=keyblock; node; node = node->next)
2521     {
2522       if(node->pkt->pkttype==PKT_USER_ID
2523          && node->pkt->pkt.user_id->attrib_data==NULL)
2524         {
2525           uid_count++;
2526
2527           if(node->pkt->pkt.user_id->is_primary==2)
2528             {
2529               have_primary=1;
2530               break;
2531             }
2532         }
2533     }
2534
2535   if(uid_count>1 && !have_primary)
2536     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2537                " may\n              cause a different user ID to become"
2538                " the assumed primary.\n"));
2539 }
2540
2541 /****************
2542  * Ask for a new user id, do the selfsignature and put it into
2543  * both keyblocks.
2544  * Return true if there is a new user id
2545  */
2546 static int
2547 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2548 {
2549     PKT_user_id *uid;
2550     PKT_public_key *pk=NULL;
2551     PKT_secret_key *sk=NULL;
2552     PKT_signature *sig=NULL;
2553     PACKET *pkt;
2554     KBNODE node;
2555     KBNODE pub_where=NULL, sec_where=NULL;
2556     int rc;
2557
2558     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2559         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2560             pk = node->pkt->pkt.public_key;
2561         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2562             break;
2563     }
2564     if( !node ) /* no subkey */
2565         pub_where = NULL;
2566     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2567         if( node->pkt->pkttype == PKT_SECRET_KEY )
2568             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2569         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2570             break;
2571     }
2572     if( !node ) /* no subkey */
2573         sec_where = NULL;
2574     assert(pk && sk);
2575
2576     if(photo) {
2577       int hasattrib=0;
2578
2579       for( node = pub_keyblock; node; node = node->next )
2580         if( node->pkt->pkttype == PKT_USER_ID &&
2581             node->pkt->pkt.user_id->attrib_data!=NULL)
2582           {
2583             hasattrib=1;
2584             break;
2585           }
2586
2587       /* It is legal but bad for compatibility to add a photo ID to a
2588          v3 key as it means that PGP2 will not be able to use that key
2589          anymore.  Also, PGP may not expect a photo on a v3 key.
2590          Don't bother to ask this if the key already has a photo - any
2591          damage has already been done at that point. -dms */
2592       if(pk->version==3 && !hasattrib)
2593         {
2594           if(opt.expert)
2595             {
2596               tty_printf(_("WARNING: This is a PGP2-style key.  "
2597                            "Adding a photo ID may cause some versions\n"
2598                            "         of PGP to reject this key.\n"));
2599
2600               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2601                                         _("Are you sure you still want "
2602                                           "to add it? (y/N) ")))
2603                 return 0;
2604             }
2605           else
2606             {
2607               tty_printf(_("You may not add a photo ID to "
2608                            "a PGP2-style key.\n"));
2609               return 0;
2610             }
2611         }
2612
2613       uid = generate_photo_id(pk);
2614     } else
2615       uid = generate_user_id();
2616     if( !uid )
2617         return 0;
2618
2619     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2620                              keygen_add_std_prefs, pk );
2621     free_secret_key( sk );
2622     if( rc ) {
2623         log_error("signing failed: %s\n", g10_errstr(rc) );
2624         free_user_id(uid);
2625         return 0;
2626     }
2627
2628     /* insert/append to secret keyblock */
2629     pkt = m_alloc_clear( sizeof *pkt );
2630     pkt->pkttype = PKT_USER_ID;
2631     pkt->pkt.user_id = scopy_user_id(uid);
2632     node = new_kbnode(pkt);
2633     if( sec_where )
2634         insert_kbnode( sec_where, node, 0 );
2635     else
2636         add_kbnode( sec_keyblock, node );
2637     pkt = m_alloc_clear( sizeof *pkt );
2638     pkt->pkttype = PKT_SIGNATURE;
2639     pkt->pkt.signature = copy_signature(NULL, sig);
2640     if( sec_where )
2641         insert_kbnode( node, new_kbnode(pkt), 0 );
2642     else
2643         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2644     /* insert/append to public keyblock */
2645     pkt = m_alloc_clear( sizeof *pkt );
2646     pkt->pkttype = PKT_USER_ID;
2647     pkt->pkt.user_id = uid;
2648     node = new_kbnode(pkt);
2649     if( pub_where )
2650         insert_kbnode( pub_where, node, 0 );
2651     else
2652         add_kbnode( pub_keyblock, node );
2653     pkt = m_alloc_clear( sizeof *pkt );
2654     pkt->pkttype = PKT_SIGNATURE;
2655     pkt->pkt.signature = copy_signature(NULL, sig);
2656     if( pub_where )
2657         insert_kbnode( node, new_kbnode(pkt), 0 );
2658     else
2659         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2660     return 1;
2661 }
2662
2663
2664 /****************
2665  * Remove all selected userids from the keyrings
2666  */
2667 static void
2668 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2669 {
2670     KBNODE node;
2671     int selected=0;
2672
2673     for( node = pub_keyblock; node; node = node->next ) {
2674         if( node->pkt->pkttype == PKT_USER_ID ) {
2675             selected = node->flag & NODFLG_SELUID;
2676             if( selected ) {
2677                 /* Only cause a trust update if we delete a
2678                    non-revoked user id */
2679                 if(!node->pkt->pkt.user_id->is_revoked)
2680                   update_trust=1;
2681                 delete_kbnode( node );
2682                 if( sec_keyblock ) {
2683                     KBNODE snode;
2684                     int s_selected = 0;
2685                     PKT_user_id *uid = node->pkt->pkt.user_id;
2686                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2687                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2688                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2689
2690                             s_selected =
2691                                 (uid->len == suid->len
2692                                  && !memcmp( uid->name, suid->name, uid->len));
2693                             if( s_selected )
2694                                 delete_kbnode( snode );
2695                         }
2696                         else if( s_selected
2697                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2698                             delete_kbnode( snode );
2699                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2700                             s_selected = 0;
2701                     }
2702                 }
2703             }
2704         }
2705         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2706             delete_kbnode( node );
2707         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2708             selected = 0;
2709     }
2710     commit_kbnode( &pub_keyblock );
2711     if( sec_keyblock )
2712         commit_kbnode( &sec_keyblock );
2713 }
2714
2715
2716 static int
2717 menu_delsig( KBNODE pub_keyblock )
2718 {
2719     KBNODE node;
2720     PKT_user_id *uid = NULL;
2721     int changed=0;
2722
2723     for( node = pub_keyblock; node; node = node->next ) {
2724         if( node->pkt->pkttype == PKT_USER_ID ) {
2725             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2726         }
2727         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2728            int okay, valid, selfsig, inv_sig, no_key, other_err;
2729
2730             tty_printf("uid  ");
2731             tty_print_utf8_string( uid->name, uid->len );
2732             tty_printf("\n");
2733
2734             okay = inv_sig = no_key = other_err = 0;
2735             if(opt.with_colons)
2736               valid = print_and_check_one_sig_colon( pub_keyblock, node,
2737                                                &inv_sig, &no_key, &other_err,
2738                                                &selfsig, 1 );
2739             else
2740               valid = print_and_check_one_sig( pub_keyblock, node,
2741                                                &inv_sig, &no_key, &other_err,
2742                                                &selfsig, 1 );
2743
2744            if( valid ) {
2745                okay = cpr_get_answer_yes_no_quit(
2746                    "keyedit.delsig.valid",
2747                    _("Delete this good signature? (y/N/q)"));
2748
2749                /* Only update trust if we delete a good signature.
2750                   The other two cases do not affect trust. */
2751                if(okay)
2752                  update_trust=1;
2753            }
2754            else if( inv_sig || other_err )
2755                okay = cpr_get_answer_yes_no_quit(
2756                    "keyedit.delsig.invalid",
2757                    _("Delete this invalid signature? (y/N/q)"));
2758            else if( no_key )
2759                okay = cpr_get_answer_yes_no_quit(
2760                    "keyedit.delsig.unknown",
2761                    _("Delete this unknown signature? (y/N/q)"));
2762
2763             if( okay == -1 )
2764                 break;
2765            if( okay && selfsig && !cpr_get_answer_is_yes(
2766                                "keyedit.delsig.selfsig",
2767                               _("Really delete this self-signature? (y/N)") ))
2768                 okay = 0;
2769             if( okay ) {
2770                 delete_kbnode( node );
2771                 changed++;
2772             }
2773
2774         }
2775         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2776             uid = NULL;
2777     }
2778
2779     if( changed ) {
2780         commit_kbnode( &pub_keyblock );
2781         tty_printf( changed == 1? _("Deleted %d signature.\n")
2782                                 : _("Deleted %d signatures.\n"), changed );
2783     }
2784     else
2785         tty_printf( _("Nothing deleted.\n") );
2786
2787     return changed;
2788 }
2789
2790
2791 /****************
2792  * Remove some of the secondary keys
2793  */
2794 static void
2795 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2796 {
2797     KBNODE node;
2798     int selected=0;
2799
2800     for( node = pub_keyblock; node; node = node->next ) {
2801         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2802             selected = node->flag & NODFLG_SELKEY;
2803             if( selected ) {
2804                 delete_kbnode( node );
2805                 if( sec_keyblock ) {
2806                     KBNODE snode;
2807                     int s_selected = 0;
2808                     u32 ki[2];
2809
2810                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2811                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2812                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2813                             u32 ki2[2];
2814
2815                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2816                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2817                             if( s_selected )
2818                                 delete_kbnode( snode );
2819                         }
2820                         else if( s_selected
2821                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2822                             delete_kbnode( snode );
2823                         else
2824                             s_selected = 0;
2825                     }
2826                 }
2827             }
2828         }
2829         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2830             delete_kbnode( node );
2831         else
2832             selected = 0;
2833     }
2834     commit_kbnode( &pub_keyblock );
2835     if( sec_keyblock )
2836         commit_kbnode( &sec_keyblock );
2837
2838     /* No need to set update_trust here since signing keys are no
2839        longer used to certify other keys, so there is no change in
2840        trust when revoking/removing them */
2841 }
2842
2843
2844 /****************
2845  * Ask for a new revoker, do the selfsignature and put it into
2846  * both keyblocks.
2847  * Return true if there is a new revoker
2848  */
2849 static int
2850 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2851 {
2852   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2853   PKT_secret_key *sk=NULL;
2854   PKT_signature *sig=NULL;
2855   PACKET *pkt;
2856   struct revocation_key revkey;
2857   size_t fprlen;
2858   int rc;
2859
2860   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2861   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2862
2863   pk=pub_keyblock->pkt->pkt.public_key;
2864
2865   if(pk->numrevkeys==0 && pk->version==3)
2866     {
2867       /* It is legal but bad for compatibility to add a revoker to a
2868          v3 key as it means that PGP2 will not be able to use that key
2869          anymore.  Also, PGP may not expect a revoker on a v3 key.
2870          Don't bother to ask this if the key already has a revoker -
2871          any damage has already been done at that point. -dms */
2872       if(opt.expert)
2873         {
2874           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2875                        "Adding a designated revoker may cause\n"
2876                        "         some versions of PGP to reject this key.\n"));
2877
2878           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2879                                     _("Are you sure you still want "
2880                                       "to add it? (y/N) ")))
2881             return 0;
2882         }
2883       else
2884         {
2885           tty_printf(_("You may not add a designated revoker to "
2886                        "a PGP 2.x-style key.\n"));
2887           return 0;
2888         }
2889     }
2890
2891   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2892
2893   for(;;)
2894     {
2895       char *answer;
2896
2897       if(revoker_pk)
2898         free_public_key(revoker_pk);
2899
2900       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2901
2902       tty_printf("\n");
2903
2904       answer=cpr_get_utf8("keyedit.add_revoker",
2905                           _("Enter the user ID of the designated revoker: "));
2906       if(answer[0]=='\0' || answer[0]=='\004')
2907         {
2908           m_free(answer);
2909           goto fail;
2910         }
2911
2912       /* Note that I'm requesting SIG here and not CERT.  We're making
2913          a certification, but it is okay to be a subkey. */
2914       revoker_pk->req_usage=PUBKEY_USAGE_SIG;
2915       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2916       if(rc)
2917         {
2918           log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
2919           m_free(answer);
2920           continue;
2921         }
2922
2923       m_free(answer);
2924
2925       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2926       if(fprlen!=20)
2927         {
2928           log_error(_("cannot appoint a PGP 2.x style key as a "
2929                       "designated revoker\n"));
2930           continue;
2931         }
2932
2933       revkey.class=0x80;
2934       if(sensitive)
2935         revkey.class|=0x40;
2936       revkey.algid=revoker_pk->pubkey_algo;
2937
2938       if(cmp_public_keys(revoker_pk,pk)==0)
2939         {
2940           /* This actually causes no harm (after all, a key that
2941              designates itself as a revoker is the same as a
2942              regular key), but it's easy enough to check. */
2943           log_error(_("you cannot appoint a key as its own "
2944                       "designated revoker\n"));
2945
2946           continue;
2947         }
2948
2949       keyid_from_pk(pk,NULL);
2950
2951       /* Does this revkey already exist? */
2952       if(!pk->revkey && pk->numrevkeys)
2953         BUG();
2954       else
2955         {
2956           int i;
2957
2958           for(i=0;i<pk->numrevkeys;i++)
2959             {
2960               if(memcmp(&pk->revkey[i],&revkey,
2961                         sizeof(struct revocation_key))==0)
2962                 {
2963                   char buf[50];
2964
2965                   log_error(_("this key has already been designated "
2966                               "as a revoker\n"));
2967
2968                   sprintf(buf,"%08lX%08lX",
2969                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2970                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2971
2972                   break;
2973                 }
2974             }
2975
2976           if(i<pk->numrevkeys)
2977             continue;
2978         }
2979
2980       print_pubkey_info(NULL,revoker_pk);
2981       print_fingerprint(revoker_pk,NULL,2);
2982       tty_printf("\n");
2983
2984       tty_printf(_("WARNING: appointing a key as a designated revoker "
2985                    "cannot be undone!\n"));
2986
2987       tty_printf("\n");
2988
2989       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2990                                 _("Are you sure you want to appoint this "
2991                                   "key as a designated revoker? (y/N) ")))
2992         continue;
2993
2994       free_public_key(revoker_pk);
2995       revoker_pk=NULL;
2996       break;
2997     }
2998
2999   /* The 1F signature must be at least v4 to carry the revocation key
3000      subpacket. */
3001   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3002                            keygen_add_revkey,&revkey );
3003   if( rc )
3004     {
3005       log_error("signing failed: %s\n", g10_errstr(rc) );
3006       goto fail;
3007     }
3008
3009   free_secret_key(sk);
3010   sk=NULL;
3011
3012   /* insert into secret keyblock */
3013   pkt = m_alloc_clear( sizeof *pkt );
3014   pkt->pkttype = PKT_SIGNATURE;
3015   pkt->pkt.signature = copy_signature(NULL, sig);
3016   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3017
3018   /* insert into public keyblock */
3019   pkt = m_alloc_clear( sizeof *pkt );
3020   pkt->pkttype = PKT_SIGNATURE;
3021   pkt->pkt.signature = sig;
3022   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3023
3024   return 1;
3025
3026  fail:
3027   if(sk)
3028     free_secret_key(sk);
3029   if(sig)
3030     free_seckey_enc(sig);
3031   if(revoker_pk)
3032     free_public_key(revoker_pk);
3033
3034   return 0;
3035 }
3036
3037
3038 static int
3039 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3040 {
3041     int n1, signumber, rc;
3042     u32 expiredate;
3043     int mainkey=0;
3044     PKT_secret_key *sk;    /* copy of the main sk */
3045     PKT_public_key *main_pk, *sub_pk;
3046     PKT_user_id *uid;
3047     KBNODE node;
3048     u32 keyid[2];
3049
3050     if( count_selected_keys( sec_keyblock ) ) {
3051         tty_printf(_("Please remove selections from the secret keys.\n"));
3052         return 0;
3053     }
3054
3055     n1 = count_selected_keys( pub_keyblock );
3056     if( n1 > 1 ) {
3057         tty_printf(_("Please select at most one secondary key.\n"));
3058         return 0;
3059     }
3060     else if( n1 )
3061         tty_printf(_("Changing expiration time for a secondary key.\n"));
3062     else
3063       {
3064         tty_printf(_("Changing expiration time for the primary key.\n"));
3065         mainkey=1;
3066         no_primary_warning(pub_keyblock);
3067       }
3068
3069     expiredate = ask_expiredate();
3070     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3071     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3072
3073     /* Now we can actually change the self signature(s) */
3074     main_pk = sub_pk = NULL;
3075     uid = NULL;
3076     signumber = 0;
3077     for( node=pub_keyblock; node; node = node->next ) {
3078         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3079             main_pk = node->pkt->pkt.public_key;
3080             keyid_from_pk( main_pk, keyid );
3081             main_pk->expiredate = expiredate;
3082         }
3083         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3084                  && (node->flag & NODFLG_SELKEY ) ) {
3085             sub_pk = node->pkt->pkt.public_key;
3086             sub_pk->expiredate = expiredate;
3087         }
3088         else if( node->pkt->pkttype == PKT_USER_ID )
3089             uid = node->pkt->pkt.user_id;
3090         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3091                  && ( mainkey || sub_pk ) ) {
3092             PKT_signature *sig = node->pkt->pkt.signature;
3093             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3094                 && ( (mainkey && uid
3095                       && uid->created && (sig->sig_class&~3) == 0x10)
3096                      || (!mainkey && sig->sig_class == 0x18)  )
3097                 && sig->flags.chosen_selfsig )
3098               {
3099                 /* this is a selfsignature which is to be replaced */
3100                 PKT_signature *newsig;
3101                 PACKET *newpkt;
3102                 KBNODE sn;
3103                 int signumber2 = 0;
3104
3105                 signumber++;
3106
3107                 if( (mainkey && main_pk->version < 4)
3108                     || (!mainkey && sub_pk->version < 4 ) ) {
3109                     log_info(_(
3110                         "You can't change the expiration date of a v3 key\n"));
3111                     free_secret_key( sk );
3112                     return 0;
3113                 }
3114
3115                 /* find the corresponding secret self-signature */
3116                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3117                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3118                         PKT_signature *b = sn->pkt->pkt.signature;
3119                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3120                             && sig->sig_class == b->sig_class
3121                             && ++signumber2 == signumber )
3122                             break;
3123                     }
3124                 }
3125                 if( !sn )
3126                     log_info(_("No corresponding signature in secret ring\n"));
3127
3128                 if( mainkey )
3129                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3130                                             sk, keygen_add_key_expire, main_pk);
3131                 else
3132                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3133                                             sk, keygen_add_key_expire, sub_pk );
3134                 if( rc ) {
3135                     log_error("make_keysig_packet failed: %s\n",
3136                                                     g10_errstr(rc));
3137                     free_secret_key( sk );
3138                     return 0;
3139                 }
3140                 /* replace the packet */
3141                 newpkt = m_alloc_clear( sizeof *newpkt );
3142                 newpkt->pkttype = PKT_SIGNATURE;
3143                 newpkt->pkt.signature = newsig;
3144                 free_packet( node->pkt );
3145                 m_free( node->pkt );
3146                 node->pkt = newpkt;
3147                 if( sn ) {
3148                     newpkt = m_alloc_clear( sizeof *newpkt );
3149                     newpkt->pkttype = PKT_SIGNATURE;
3150                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3151                     free_packet( sn->pkt );
3152                     m_free( sn->pkt );
3153                     sn->pkt = newpkt;
3154                 }
3155                 sub_pk = NULL;
3156             }
3157         }
3158     }
3159
3160     free_secret_key( sk );
3161     update_trust=1;
3162     return 1;
3163 }
3164
3165 static int
3166 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3167 {
3168     byte buf[1];
3169
3170     /* first clear all primary uid flags so that we are sure none are
3171      * lingering around */
3172     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
3173     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3174
3175     /* if opaque is set,we want to set the primary id */
3176     if (opaque) { 
3177         buf[0] = 1;
3178         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3179     }
3180
3181     return 0;
3182 }
3183
3184
3185 /*
3186  * Set the primary uid flag for the selected UID.  We will also reset
3187  * all other primary uid flags.  For this to work with have to update
3188  * all the signature timestamps.  If we would do this with the current
3189  * time, we lose quite a lot of information, so we use a a kludge to
3190  * do this: Just increment the timestamp by one second which is
3191  * sufficient to updated a signature during import.
3192  */
3193 static int
3194 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3195 {
3196     PKT_secret_key *sk;    /* copy of the main sk */
3197     PKT_public_key *main_pk;
3198     PKT_user_id *uid;
3199     KBNODE node;
3200     u32 keyid[2];
3201     int selected;
3202     int attribute = 0;
3203     int modified = 0;
3204
3205     if ( count_selected_uids (pub_keyblock) != 1 ) {
3206         tty_printf(_("Please select exactly one user ID.\n"));
3207         return 0;
3208     }
3209
3210     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3211     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3212
3213     /* Now we can actually change the self signature(s) */
3214     main_pk = NULL;
3215     uid = NULL;
3216     selected = 0;
3217
3218     /* Is our selected uid an attribute packet? */
3219     for ( node=pub_keyblock; node; node = node->next )
3220       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3221         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3222
3223     for ( node=pub_keyblock; node; node = node->next ) {
3224         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3225             break; /* ready */
3226
3227         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3228             main_pk = node->pkt->pkt.public_key;
3229             keyid_from_pk( main_pk, keyid );
3230         }
3231         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3232             uid = node->pkt->pkt.user_id;
3233             selected = node->flag & NODFLG_SELUID;
3234         }
3235         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3236             PKT_signature *sig = node->pkt->pkt.signature;
3237             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3238                  && (uid && (sig->sig_class&~3) == 0x10)
3239                  && attribute == (uid->attrib_data!=NULL)
3240                  && sig->flags.chosen_selfsig )
3241               {
3242               if(sig->version < 4) {
3243                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3244
3245                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3246                          user);
3247                 m_free(user);
3248               }
3249               else {
3250                 /* This is a selfsignature which is to be replaced.
3251                    We can just ignore v3 signatures because they are
3252                    not able to carry the primary ID flag.  We also
3253                    ignore self-sigs on user IDs that are not of the
3254                    same type that we are making primary.  That is, if
3255                    we are making a user ID primary, we alter user IDs.
3256                    If we are making an attribute packet primary, we
3257                    alter attribute packets. */
3258
3259                 /* FIXME: We must make sure that we only have one
3260                    self-signature per user ID here (not counting
3261                    revocations) */
3262                 PKT_signature *newsig;
3263                 PACKET *newpkt;
3264                 const byte *p;
3265                 int action;
3266
3267                 /* see whether this signature has the primary UID flag */
3268                 p = parse_sig_subpkt (sig->hashed,
3269                                       SIGSUBPKT_PRIMARY_UID, NULL );
3270                 if ( !p )
3271                     p = parse_sig_subpkt (sig->unhashed,
3272                                           SIGSUBPKT_PRIMARY_UID, NULL );
3273                 if ( p && *p ) /* yes */
3274                     action = selected? 0 : -1;
3275                 else /* no */
3276                     action = selected? 1 : 0;
3277
3278                 if (action) {
3279                     int rc = update_keysig_packet (&newsig, sig,
3280                                                main_pk, uid, NULL,
3281                                                sk,
3282                                                change_primary_uid_cb,
3283                                                action > 0? "x":NULL );
3284                     if( rc ) {
3285                         log_error ("update_keysig_packet failed: %s\n",
3286                                    g10_errstr(rc));
3287                         free_secret_key( sk );
3288                         return 0;
3289                     }
3290                     /* replace the packet */
3291                     newpkt = m_alloc_clear( sizeof *newpkt );
3292                     newpkt->pkttype = PKT_SIGNATURE;
3293                     newpkt->pkt.signature = newsig;
3294                     free_packet( node->pkt );
3295                     m_free( node->pkt );
3296                     node->pkt = newpkt;
3297                     modified = 1;
3298                 }
3299               }
3300             }
3301         }
3302     }
3303
3304     free_secret_key( sk );
3305     return modified;
3306 }
3307
3308
3309 /* 
3310  * Set preferences to new values for the selected user IDs
3311  */
3312 static int
3313 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3314 {
3315     PKT_secret_key *sk;    /* copy of the main sk */
3316     PKT_public_key *main_pk;
3317     PKT_user_id *uid;
3318     KBNODE node;
3319     u32 keyid[2];
3320     int selected, select_all;
3321     int modified = 0;
3322
3323     no_primary_warning(pub_keyblock);
3324
3325     select_all = !count_selected_uids (pub_keyblock);
3326
3327     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3328     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3329
3330     /* Now we can actually change the self signature(s) */
3331     main_pk = NULL;
3332     uid = NULL;
3333     selected = 0;
3334     for ( node=pub_keyblock; node; node = node->next ) {
3335         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3336             break; /* ready */
3337
3338         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3339             main_pk = node->pkt->pkt.public_key;
3340             keyid_from_pk( main_pk, keyid );
3341         }
3342         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3343             uid = node->pkt->pkt.user_id;
3344             selected = select_all || (node->flag & NODFLG_SELUID);
3345         }
3346         else if ( main_pk && uid && selected
3347                   && node->pkt->pkttype == PKT_SIGNATURE ) {
3348             PKT_signature *sig = node->pkt->pkt.signature;
3349             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3350                  && (uid && (sig->sig_class&~3) == 0x10)
3351                  && sig->flags.chosen_selfsig ) {
3352               if( sig->version < 4 ) {
3353                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3354
3355                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3356                          user);
3357                 m_free(user);
3358               }
3359               else {
3360                 /* This is a selfsignature which is to be replaced 
3361                  * We have to ignore v3 signatures because they are
3362                  * not able to carry the preferences */
3363                 PKT_signature *newsig;
3364                 PACKET *newpkt;
3365                 int rc;
3366
3367                 rc = update_keysig_packet (&newsig, sig,
3368                                            main_pk, uid, NULL,
3369                                            sk,
3370                                            keygen_upd_std_prefs,
3371                                            NULL );
3372                 if( rc ) {
3373                     log_error ("update_keysig_packet failed: %s\n",
3374                                g10_errstr(rc));
3375                     free_secret_key( sk );
3376                     return 0;
3377                 }
3378                 /* replace the packet */
3379                 newpkt = m_alloc_clear( sizeof *newpkt );
3380                 newpkt->pkttype = PKT_SIGNATURE;
3381                 newpkt->pkt.signature = newsig;
3382                 free_packet( node->pkt );
3383                 m_free( node->pkt );
3384                 node->pkt = newpkt;
3385                 modified = 1;
3386               }
3387             }
3388         }
3389     }
3390     
3391     free_secret_key( sk );
3392     return modified;
3393 }
3394
3395
3396 static int
3397 menu_set_keyserver_url (const char *url,
3398                         KBNODE pub_keyblock, KBNODE sec_keyblock )
3399 {
3400   PKT_secret_key *sk;    /* copy of the main sk */
3401   PKT_public_key *main_pk;
3402   PKT_user_id *uid;
3403   KBNODE node;
3404   u32 keyid[2];
3405   int selected, select_all;
3406   int modified = 0;
3407   char *answer,*uri;
3408
3409   no_primary_warning(pub_keyblock);
3410
3411   if(url)
3412     answer=m_strdup(url);
3413   else
3414     {
3415       answer=cpr_get_utf8("keyedit.add_keyserver",
3416                           _("Enter your preferred keyserver URL: "));
3417       if(answer[0]=='\0' || answer[0]=='\004')
3418         {
3419           m_free(answer);
3420           return 0;
3421         }
3422     }
3423
3424   if(ascii_strcasecmp(answer,"none")==0)
3425     uri=NULL;
3426   else
3427     {
3428       struct keyserver_spec *keyserver=NULL;
3429       /* Sanity check the format */
3430       keyserver=parse_keyserver_uri(answer,1,NULL,0);
3431       m_free(answer);
3432       if(!keyserver)
3433         {
3434           log_info(_("could not parse keyserver URL\n"));
3435           return 0;
3436         }
3437       uri=m_strdup(keyserver->uri);
3438       free_keyserver_spec(keyserver);
3439     }
3440
3441   select_all = !count_selected_uids (pub_keyblock);
3442
3443   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3444   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3445
3446   /* Now we can actually change the self signature(s) */
3447   main_pk = NULL;
3448   uid = NULL;
3449   selected = 0;
3450   for ( node=pub_keyblock; node; node = node->next )
3451     {
3452       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3453         break; /* ready */
3454
3455       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
3456         {
3457           main_pk = node->pkt->pkt.public_key;
3458           keyid_from_pk( main_pk, keyid );
3459         }
3460       else if ( node->pkt->pkttype == PKT_USER_ID )
3461         {
3462           uid = node->pkt->pkt.user_id;
3463           selected = select_all || (node->flag & NODFLG_SELUID);
3464         }
3465       else if ( main_pk && uid && selected
3466                 && node->pkt->pkttype == PKT_SIGNATURE )
3467         {
3468           PKT_signature *sig = node->pkt->pkt.signature;
3469           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3470                && (uid && (sig->sig_class&~3) == 0x10) )
3471             {
3472               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3473               if( sig->version < 4 )
3474                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3475                          user);
3476               else
3477                 {
3478                   /* This is a selfsignature which is to be replaced
3479                    * We have to ignore v3 signatures because they are
3480                    * not able to carry the subpacket. */
3481                   PKT_signature *newsig;
3482                   PACKET *newpkt;
3483                   int rc;
3484                   const byte *p;
3485                   size_t plen;
3486
3487                   p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
3488                   if(p && plen)
3489                     {
3490                       tty_printf("Current preferred keyserver for user"
3491                                  " ID \"%s\": ",user);
3492                       tty_print_utf8_string(p,plen);
3493                       tty_printf("\n");
3494                       if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
3495                          uri?_("Are you sure you want to replace it? (y/N) "):
3496                              _("Are you sure you want to delete it? (y/N) ")))
3497                         continue;
3498                     }
3499                   else if(uri==NULL)
3500                     {
3501                       /* There is no current keyserver URL, so there
3502                          is no point in trying to un-set it. */
3503                       continue;
3504                     }
3505
3506                   rc = update_keysig_packet (&newsig, sig,
3507                                              main_pk, uid, NULL,
3508                                              sk,
3509                                              keygen_add_keyserver_url, uri );
3510                   if( rc )
3511                     {
3512                       log_error ("update_keysig_packet failed: %s\n",
3513                                  g10_errstr(rc));
3514                       free_secret_key( sk );
3515                       m_free(uri);
3516                       return 0;
3517                     }
3518                   /* replace the packet */
3519                   newpkt = m_alloc_clear( sizeof *newpkt );
3520                   newpkt->pkttype = PKT_SIGNATURE;
3521                   newpkt->pkt.signature = newsig;
3522                   free_packet( node->pkt );
3523                   m_free( node->pkt );
3524                   node->pkt = newpkt;
3525                   modified = 1;
3526                 }
3527
3528               m_free(user);
3529             }
3530         }
3531     }
3532
3533   m_free(uri);
3534   free_secret_key( sk );
3535   return modified;
3536 }
3537
3538
3539 /****************
3540  * Select one user id or remove all selection if index is 0.
3541  * Returns: True if the selection changed;
3542  */
3543 static int
3544 menu_select_uid( KBNODE keyblock, int idx )
3545 {
3546     KBNODE node;
3547     int i;
3548
3549     /* first check that the index is valid */
3550     if( idx ) {
3551         for( i=0, node = keyblock; node; node = node->next ) {
3552             if( node->pkt->pkttype == PKT_USER_ID ) {
3553                 if( ++i == idx )
3554                     break;
3555             }
3556         }
3557         if( !node ) {
3558             tty_printf(_("No user ID with index %d\n"), idx );
3559             return 0;
3560         }
3561     }
3562     else { /* reset all */
3563         for( i=0, node = keyblock; node; node = node->next ) {
3564             if( node->pkt->pkttype == PKT_USER_ID )
3565                 node->flag &= ~NODFLG_SELUID;
3566         }
3567         return 1;
3568     }
3569     /* and toggle the new index */
3570     for( i=0, node = keyblock; node; node = node->next ) {
3571         if( node->pkt->pkttype == PKT_USER_ID ) {
3572             if( ++i == idx ) {
3573                 if( (node->flag & NODFLG_SELUID) )
3574                     node->flag &= ~NODFLG_SELUID;
3575                 else
3576                     node->flag |= NODFLG_SELUID;
3577             }
3578         }
3579     }
3580
3581     return 1;
3582 }
3583
3584 /****************
3585  * Select secondary keys
3586  * Returns: True if the selection changed;
3587  */
3588 static int
3589 menu_select_key( KBNODE keyblock, int idx )
3590 {
3591     KBNODE node;
3592     int i;
3593
3594     /* first check that the index is valid */
3595     if( idx ) {
3596         for( i=0, node = keyblock; node; node = node->next ) {
3597             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3598                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3599                 if( ++i == idx )
3600                     break;
3601             }
3602         }
3603         if( !node ) {
3604             tty_printf(_("No secondary key with index %d\n"), idx );
3605             return 0;
3606         }
3607     }
3608     else { /* reset all */
3609         for( i=0, node = keyblock; node; node = node->next ) {
3610             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3611                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3612                 node->flag &= ~NODFLG_SELKEY;
3613         }
3614         return 1;
3615     }
3616     /* and set the new index */
3617     for( i=0, node = keyblock; node; node = node->next ) {
3618         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3619             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3620             if( ++i == idx ) {
3621                 if( (node->flag & NODFLG_SELKEY) )
3622                     node->flag &= ~NODFLG_SELKEY;
3623                 else
3624                     node->flag |= NODFLG_SELKEY;
3625             }
3626         }
3627     }
3628
3629     return 1;
3630 }
3631
3632
3633 static int
3634 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3635 {
3636     KBNODE node;
3637     int i=0;
3638
3639     for( node = keyblock; node; node = node->next )
3640         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3641             i++;
3642     return i;
3643 }
3644
3645 static int
3646 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3647 {
3648     KBNODE node;
3649     int i=0;
3650
3651     for( node = keyblock; node; node = node->next )
3652         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3653               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3654             && (node->flag & flag) )
3655             i++;
3656     return i;
3657 }
3658
3659 static int
3660 count_uids( KBNODE keyblock )
3661 {
3662     KBNODE node;
3663     int i=0;
3664
3665     for( node = keyblock; node; node = node->next )
3666         if( node->pkt->pkttype == PKT_USER_ID )
3667             i++;
3668     return i;
3669 }
3670
3671
3672 /****************
3673  * Returns true if there is at least one selected user id
3674  */
3675 static int
3676 count_selected_uids( KBNODE keyblock )
3677 {
3678     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3679 }
3680
3681 static int
3682 count_selected_keys( KBNODE keyblock )
3683 {
3684     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3685 }
3686
3687 /* returns how many real (i.e. not attribute) uids are unmarked */
3688 static int
3689 real_uids_left( KBNODE keyblock )
3690 {
3691   KBNODE node;
3692   int real=0;
3693
3694   for(node=keyblock;node;node=node->next)
3695     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3696        !node->pkt->pkt.user_id->attrib_data)
3697       real++;
3698
3699   return real;
3700 }
3701
3702 /*
3703  * Ask whether the signature should be revoked.  If the user commits this,
3704  * flag bit MARK_A is set on the signature and the user ID.
3705  */
3706 static void
3707 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3708 {
3709     int doit=0;
3710     char *p;
3711     PKT_signature *sig = node->pkt->pkt.signature;
3712     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3713
3714     if( !unode ) {
3715         log_error("Oops: no user ID for signature\n");
3716         return;
3717     }
3718
3719     p=utf8_to_native(unode->pkt->pkt.user_id->name,
3720                      unode->pkt->pkt.user_id->len,0);
3721     tty_printf(_("user ID: \"%s\"\n"),p);
3722     m_free(p);
3723
3724     tty_printf(_("signed by your key %s on %s%s%s\n"),
3725                keystr(sig->keyid),datestr_from_sig(sig),
3726                sig->flags.exportable?"":_(" (non-exportable)"),"");
3727
3728     if(sig->flags.expired)
3729       {
3730         tty_printf(_("This signature expired on %s.\n"),
3731                    expirestr_from_sig(sig));
3732         /* Use a different question so we can have different help text */
3733         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3734                         _("Are you sure you still want to revoke it? (y/N) "));
3735       }
3736     else
3737       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3738               _("Create a revocation certificate for this signature? (y/N) "));
3739
3740     if(doit) {
3741       node->flag |= NODFLG_MARK_A;
3742       unode->flag |= NODFLG_MARK_A;
3743     }
3744 }
3745
3746 /****************
3747  * Display all user ids of the current public key together with signatures
3748  * done by one of our keys.  Then walk over all this sigs and ask the user
3749  * whether he wants to revoke this signature.
3750  * Return: True when the keyblock has changed.
3751  */
3752 static int
3753 menu_revsig( KBNODE keyblock )
3754 {
3755     PKT_signature *sig;
3756     PKT_public_key *primary_pk;
3757     KBNODE node;
3758     int changed = 0;
3759     int rc, any, skip=1, all=!count_selected_uids(keyblock);
3760     struct revocation_reason_info *reason = NULL;
3761
3762     assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3763
3764     /* FIXME: detect duplicates here  */
3765     tty_printf(_("You have signed these user IDs on key %s:\n"),
3766                keystr_from_pk(keyblock->pkt->pkt.public_key));
3767     for( node = keyblock; node; node = node->next ) {
3768         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
3769         if( node->pkt->pkttype == PKT_USER_ID ) {
3770             if( node->flag&NODFLG_SELUID || all ) {
3771               PKT_user_id *uid = node->pkt->pkt.user_id;
3772               /* Hmmm: Should we show only UIDs with a signature? */
3773               tty_printf("     ");
3774               tty_print_utf8_string( uid->name, uid->len );
3775               tty_printf("\n");
3776               skip=0;
3777