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