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