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