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