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