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