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