* card-util.c, delkey.c, keygen.c, plaintext.c, keyedit.c, passphrase.c,
[gnupg.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <ctype.h>
29
30 #include "options.h"
31 #include "packet.h"
32 #include "errors.h"
33 #include "iobuf.h"
34 #include "keydb.h"
35 #include "memory.h"
36 #include "photoid.h"
37 #include "util.h"
38 #include "main.h"
39 #include "trustdb.h"
40 #include "filter.h"
41 #include "ttyio.h"
42 #include "status.h"
43 #include "i18n.h"
44 #include "keyserver-internal.h"
45
46 static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
47 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
48             int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
49 static void show_key_and_fingerprint( KBNODE keyblock );
50 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock, int photo );
51 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
52 static int  menu_delsig( KBNODE pub_keyblock );
53 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
54 static int menu_addrevoker( KBNODE pub_keyblock,
55                             KBNODE sec_keyblock, int sensitive );
56 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
57 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
58 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
59 static int menu_set_keyserver_url (const char *url,
60                                    KBNODE pub_keyblock, KBNODE sec_keyblock );
61 static int menu_select_uid( KBNODE keyblock, int idx );
62 static int menu_select_key( KBNODE keyblock, int idx );
63 static int count_uids( KBNODE keyblock );
64 static int count_uids_with_flag( KBNODE keyblock, unsigned flag );
65 static int count_keys_with_flag( KBNODE keyblock, unsigned flag );
66 static int count_selected_uids( KBNODE keyblock );
67 static int real_uids_left( KBNODE keyblock );
68 static int count_selected_keys( KBNODE keyblock );
69 static int menu_revsig( KBNODE keyblock );
70 static int menu_revuid( KBNODE keyblock, KBNODE sec_keyblock );
71 static int menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
72 static int enable_disable_key( KBNODE keyblock, int disable );
73 static void menu_showphoto( KBNODE keyblock );
74
75 static int update_trust=0;
76
77 #define CONTROL_D ('D' - 'A' + 1)
78
79 #define NODFLG_BADSIG (1<<0)  /* bad signature */
80 #define NODFLG_NOKEY  (1<<1)  /* no public key */
81 #define NODFLG_SIGERR (1<<2)  /* other sig error */
82
83 #define NODFLG_MARK_A (1<<4)  /* temporary mark */
84 #define NODFLG_DELSIG (1<<5)  /* to be deleted */
85
86 #define NODFLG_SELUID (1<<8)  /* indicate the selected userid */
87 #define NODFLG_SELKEY (1<<9)  /* indicate the selected key */
88 #define NODFLG_SELSIG (1<<10) /* indicate a selected signature */
89
90 struct sign_attrib {
91     int non_exportable,non_revocable;
92     struct revocation_reason_info *reason;
93     byte trust_depth,trust_value;
94     char *trust_regexp;
95 };
96
97
98 #ifdef ENABLE_CARD_SUPPORT
99 /* Given a node SEC_NODE with a secret key or subkey, locate the
100    corresponding public key from pub_keyblock. */
101 static PKT_public_key *
102 find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
103 {
104   KBNODE node = pub_keyblock;
105   PKT_secret_key *sk;
106   PKT_public_key *pk;
107   
108   if (sec_node->pkt->pkttype == PKT_SECRET_KEY
109       && node->pkt->pkttype == PKT_PUBLIC_KEY)
110     return node->pkt->pkt.public_key;
111   if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
112     return NULL;
113   sk = sec_node->pkt->pkt.secret_key;
114   for (; node; node = node->next)
115     if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
116       {
117         pk = node->pkt->pkt.public_key;
118         if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
119           return pk;
120       }
121       
122   return NULL;
123 }
124 #endif /* ENABLE_CARD_SUPPORT */
125
126
127 /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
128    code in keylist.c. */
129 static int
130 print_and_check_one_sig_colon( KBNODE keyblock, KBNODE node,
131                                int *inv_sigs, int *no_key, int *oth_err,
132                                int *is_selfsig, int print_without_key )
133 {
134   PKT_signature *sig = node->pkt->pkt.signature;
135   int rc, sigrc;
136
137   /* TODO: Make sure a cached sig record here still has the pk that
138      issued it.  See also keylist.c:list_keyblock_print */
139
140   switch((rc=check_key_signature(keyblock,node,is_selfsig)))
141     {
142     case 0:
143       node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
144       sigrc = '!';
145       break;
146     case G10ERR_BAD_SIGN:
147       node->flag = NODFLG_BADSIG;
148       sigrc = '-';
149       if( inv_sigs )
150         ++*inv_sigs;
151       break;
152     case G10ERR_NO_PUBKEY:
153     case G10ERR_UNU_PUBKEY:
154       node->flag = NODFLG_NOKEY;
155       sigrc = '?';
156       if( no_key )
157         ++*no_key;
158       break;
159     default:
160       node->flag = NODFLG_SIGERR;
161       sigrc = '%';
162       if( oth_err )
163         ++*oth_err;
164       break;
165     }
166
167   if( sigrc != '?' || print_without_key )
168     {
169       printf("sig:%c::%d:%08lX%08lX:%lu:%lu:",
170              sigrc,sig->pubkey_algo,(ulong)sig->keyid[0],(ulong)sig->keyid[1],
171              (ulong)sig->timestamp,(ulong)sig->expiredate);
172
173       if(sig->trust_depth || sig->trust_value)
174         printf("%d %d",sig->trust_depth,sig->trust_value);
175
176       printf(":");
177
178       if(sig->trust_regexp)
179         print_string(stdout,sig->trust_regexp,strlen(sig->trust_regexp),':');
180
181       printf("::%02x%c\n",sig->sig_class,sig->flags.exportable?'x':'l');
182
183       if(opt.show_subpackets)
184         print_subpackets_colon(sig);
185     }
186
187   return (sigrc == '!');
188 }
189
190
191 /****************
192  * Print information about a signature, check it and return true
193  * if the signature is okay. NODE must be a signature packet.
194  */
195 static int
196 print_and_check_one_sig( KBNODE keyblock, KBNODE node,
197                          int *inv_sigs, int *no_key, int *oth_err,
198                         int *is_selfsig, int print_without_key )
199 {
200     PKT_signature *sig = node->pkt->pkt.signature;
201     int rc, sigrc;
202     int is_rev = sig->sig_class == 0x30;
203
204     /* TODO: Make sure a cached sig record here still has the pk that
205        issued it.  See also keylist.c:list_keyblock_print */
206
207     switch( (rc = check_key_signature( keyblock, node, is_selfsig)) ) {
208       case 0:
209         node->flag &= ~(NODFLG_BADSIG|NODFLG_NOKEY|NODFLG_SIGERR);
210         sigrc = '!';
211         break;
212       case G10ERR_BAD_SIGN:
213         node->flag = NODFLG_BADSIG;
214         sigrc = '-';
215         if( inv_sigs )
216             ++*inv_sigs;
217         break;
218       case G10ERR_NO_PUBKEY:
219       case G10ERR_UNU_PUBKEY:
220         node->flag = NODFLG_NOKEY;
221         sigrc = '?';
222         if( no_key )
223             ++*no_key;
224         break;
225       default:
226         node->flag = NODFLG_SIGERR;
227         sigrc = '%';
228         if( oth_err )
229             ++*oth_err;
230         break;
231     }
232     if( sigrc != '?' || print_without_key ) {
233         tty_printf("%s%c%c %c%c%c%c%c%c %s %s",
234                    is_rev? "rev":"sig",sigrc,
235                    (sig->sig_class-0x10>0 &&
236                     sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
237                    sig->flags.exportable?' ':'L',
238                    sig->flags.revocable?' ':'R',
239                    sig->flags.policy_url?'P':' ',
240                    sig->flags.notation?'N':' ',
241                    sig->flags.expired?'X':' ',
242                    (sig->trust_depth>9)?'T':
243                    (sig->trust_depth>0)?'0'+sig->trust_depth:' ',
244                    keystr(sig->keyid),datestr_from_sig(sig));
245         if(opt.list_options&LIST_SHOW_SIG_EXPIRE)
246           tty_printf(" %s",expirestr_from_sig(sig));
247         tty_printf("  ");
248         if( sigrc == '%' )
249             tty_printf("[%s] ", g10_errstr(rc) );
250         else if( sigrc == '?' )
251             ;
252         else if( *is_selfsig ) {
253             tty_printf( is_rev? _("[revocation]")
254                               : _("[self-signature]") );
255         }
256         else
257           {
258             size_t n;
259             char *p = get_user_id( sig->keyid, &n );
260             tty_print_utf8_string2(p, n, opt.screen_columns-keystrlen()-26-
261                                ((opt.list_options&LIST_SHOW_SIG_EXPIRE)?11:0));
262             m_free(p);
263           }
264         tty_printf("\n");
265
266         if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY_URLS))
267           show_policy_url(sig,3,0);
268
269         if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATIONS))
270           show_notation(sig,3,0,
271                         ((opt.list_options&LIST_SHOW_STD_NOTATIONS)?1:0)+
272                         ((opt.list_options&LIST_SHOW_USER_NOTATIONS)?2:0));
273
274         if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER_URLS))
275           show_keyserver_url(sig,3,0);
276     }
277
278     return (sigrc == '!');
279 }
280
281
282
283 /****************
284  * Check the keysigs and set the flags to indicate errors.
285  * Returns true if error found.
286  */
287 static int
288 check_all_keysigs( KBNODE keyblock, int only_selected )
289 {
290     KBNODE kbctx;
291     KBNODE node;
292     int inv_sigs = 0;
293     int no_key = 0;
294     int oth_err = 0;
295     int has_selfsig = 0;
296     int mis_selfsig = 0;
297     int selected = !only_selected;
298     int anyuid = 0;
299
300     for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
301         if( node->pkt->pkttype == PKT_USER_ID ) {
302             PKT_user_id *uid = node->pkt->pkt.user_id;
303
304             if( only_selected )
305                 selected = (node->flag & NODFLG_SELUID);
306             if( selected ) {
307                 tty_printf("uid  ");
308                 tty_print_utf8_string( uid->name, uid->len );
309                 tty_printf("\n");
310                 if( anyuid && !has_selfsig )
311                     mis_selfsig++;
312                 has_selfsig = 0;
313                 anyuid = 1;
314             }
315         }
316         else if( selected && node->pkt->pkttype == PKT_SIGNATURE
317                  && ( (node->pkt->pkt.signature->sig_class&~3) == 0x10
318                      || node->pkt->pkt.signature->sig_class == 0x30 )  ) {
319             int selfsig;
320
321             if( print_and_check_one_sig( keyblock, node, &inv_sigs,
322                                         &no_key, &oth_err, &selfsig, 0 ) ) {
323                 if( selfsig )
324                     has_selfsig = 1;
325             }
326             /* Hmmm: should we update the trustdb here? */
327         }
328     }
329     if( !has_selfsig )
330         mis_selfsig++;
331     if( inv_sigs == 1 )
332         tty_printf(_("1 bad signature\n") );
333     else if( inv_sigs )
334         tty_printf(_("%d bad signatures\n"), inv_sigs );
335     if( no_key == 1 )
336         tty_printf(_("1 signature not checked due to a missing key\n") );
337     else if( no_key )
338         tty_printf(_("%d signatures not checked due to missing keys\n"), no_key );
339     if( oth_err == 1 )
340         tty_printf(_("1 signature not checked due to an error\n") );
341     else if( oth_err )
342         tty_printf(_("%d signatures not checked due to errors\n"), oth_err );
343     if( mis_selfsig == 1 )
344         tty_printf(_("1 user ID without valid self-signature detected\n"));
345     else if( mis_selfsig  )
346         tty_printf(_("%d user IDs without valid self-signatures detected\n"),
347                                                                     mis_selfsig);
348
349     return inv_sigs || no_key || oth_err || mis_selfsig;
350 }
351
352
353 static int
354 sign_mk_attrib( PKT_signature *sig, void *opaque )
355 {
356     struct sign_attrib *attrib = opaque;
357     byte buf[8];
358
359     if( attrib->non_exportable ) {
360         buf[0] = 0; /* not exportable */
361         build_sig_subpkt( sig, SIGSUBPKT_EXPORTABLE, buf, 1 );
362     }
363
364     if( attrib->non_revocable ) {
365         buf[0] = 0; /* not revocable */
366         build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
367     }
368
369     if( attrib->reason )
370         revocation_reason_build_cb( sig, attrib->reason );
371
372     if(attrib->trust_depth)
373       {
374         /* Not critical.  If someone doesn't understand trust sigs,
375            this can still be a valid regular signature. */
376         buf[0] = attrib->trust_depth;
377         buf[1] = attrib->trust_value;
378         build_sig_subpkt(sig,SIGSUBPKT_TRUST,buf,2);
379
380         /* Critical.  If someone doesn't understands regexps, this
381            whole sig should be invalid.  Note the +1 for the length -
382            regexps are null terminated. */
383         if(attrib->trust_regexp)
384           build_sig_subpkt(sig,SIGSUBPKT_FLAG_CRITICAL|SIGSUBPKT_REGEXP,
385                            attrib->trust_regexp,
386                            strlen(attrib->trust_regexp)+1);
387       }
388
389     return 0;
390 }
391
392 static void
393 trustsig_prompt(byte *trust_value,byte *trust_depth,char **regexp)
394 {
395   char *p;
396
397   *trust_value=0;
398   *trust_depth=0;
399   *regexp=NULL;
400
401   /* 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 /****************
1218  * Menu driven key editor.  If seckey_check is true, then a secret key
1219  * that matches username will be looked for.  If it is false, not all
1220  * commands will be available.
1221  *
1222  * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1223  */
1224
1225 void
1226 keyedit_menu( const char *username, STRLIST locusr,
1227               STRLIST commands, int quiet, int seckey_check )
1228 {
1229     enum cmdids { cmdNONE = 0,
1230            cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1231            cmdTSIGN, cmdLSIGN, cmdNRSIGN, cmdNRLSIGN, cmdREVSIG, cmdREVKEY,
1232            cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG, cmdSAVE, cmdADDUID,
1233            cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY, cmdADDREVOKER,
1234            cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF, cmdEXPIRE,
1235            cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF, cmdUPDPREF,
1236            cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
1237            cmdADDCARDKEY, cmdKEYTOCARD,
1238    cmdNOP };
1239     static struct { const char *name;
1240                     enum cmdids id;
1241                     int need_sk;
1242                     int not_with_sk;  /* but 2 == must use SK */
1243                     const char *desc;
1244                   } cmds[] = { 
1245         { N_("quit")    , cmdQUIT      , 0,0, N_("quit this menu") },
1246         { N_("q")       , cmdQUIT      , 0,0, NULL   },
1247         { N_("save")    , cmdSAVE      , 0,0, N_("save and quit") },
1248         { N_("help")    , cmdHELP      , 0,0, N_("show this help") },
1249         {    "?"        , cmdHELP      , 0,0, NULL   },
1250         { N_("fpr")     , cmdFPR       , 0,0, N_("show fingerprint") },
1251         { N_("list")    , cmdLIST      , 0,0, N_("list key and user IDs") },
1252         { N_("l")       , cmdLIST      , 0,0, NULL   },
1253         { N_("uid")     , cmdSELUID    , 0,0, N_("select user ID N") },
1254         { N_("key")     , cmdSELKEY    , 0,0, N_("select secondary key N") },
1255         { N_("check")   , cmdCHECK     , 0,0, N_("list signatures") },
1256         { N_("c")       , cmdCHECK     , 0,0, NULL },
1257         { N_("sign")    , cmdSIGN      , 0,1, N_("sign the key") },
1258         { N_("s")       , cmdSIGN      , 0,1, NULL },
1259         { N_("tsign")   , cmdTSIGN     , 0,1, N_("make a trust signature")},
1260         { N_("lsign")   , cmdLSIGN     , 0,1, N_("sign the key locally") },
1261         { N_("nrsign")  , cmdNRSIGN    , 0,1, N_("sign the key non-revocably") },
1262         { N_("nrlsign") , cmdNRLSIGN   , 0,1, N_("sign the key locally and non-revocably") },
1263         { N_("debug")   , cmdDEBUG     , 0,0, NULL },
1264         { N_("adduid")  , cmdADDUID    , 1,1, N_("add a user ID") },
1265         { N_("addphoto"), cmdADDPHOTO  , 1,1, N_("add a photo ID") },
1266         { N_("deluid")  , cmdDELUID    , 0,1, N_("delete user ID") },
1267         /* delphoto is really deluid in disguise */
1268         { N_("delphoto"), cmdDELUID    , 0,1, NULL },
1269         { N_("addkey")  , cmdADDKEY    , 1,1, N_("add a secondary key") },
1270 #ifdef ENABLE_CARD_SUPPORT
1271         { N_("addcardkey"), cmdADDCARDKEY , 1,1, N_("add a key to a smartcard") },
1272         { N_("keytocard"), cmdKEYTOCARD , 1,2, N_("move a key to a smartcard")},
1273 #endif /*ENABLE_CARD_SUPPORT*/
1274         { N_("delkey")  , cmdDELKEY    , 0,1, N_("delete a secondary key") },
1275         { N_("addrevoker"),cmdADDREVOKER,1,1, N_("add a revocation key") },
1276         { N_("delsig")  , cmdDELSIG    , 0,1, N_("delete signatures") },
1277         { N_("expire")  , cmdEXPIRE    , 1,1, N_("change the expire date") },
1278         { N_("primary") , cmdPRIMARY   , 1,1, N_("flag user ID as primary")},
1279         { N_("toggle")  , cmdTOGGLE    , 1,0, N_("toggle between secret "
1280                                                  "and public key listing") },
1281         { N_("t"     )  , cmdTOGGLE    , 1,0, NULL },
1282         { N_("pref")    , cmdPREF      , 0,1, N_("list preferences (expert)")},
1283         { N_("showpref"), cmdSHOWPREF  , 0,1, N_("list preferences (verbose)") },
1284         { N_("setpref") , cmdSETPREF   , 1,1, N_("set preference list") },
1285         { N_("updpref") , cmdUPDPREF   , 1,1, N_("updated preferences") },
1286         { N_("keyserver"),cmdPREFKS    , 1,1, N_("set preferred keyserver URL")},
1287         { N_("passwd")  , cmdPASSWD    , 1,1, N_("change the passphrase") },
1288         { N_("trust")   , cmdTRUST     , 0,1, N_("change the ownertrust") },
1289         { N_("revsig")  , cmdREVSIG    , 0,1, N_("revoke signatures") },
1290         { N_("revuid")  , cmdREVUID    , 1,1, N_("revoke a user ID") },
1291         { N_("revkey")  , cmdREVKEY    , 1,1, N_("revoke a secondary key") },
1292         { N_("disable") , cmdDISABLEKEY, 0,1, N_("disable a key") },
1293         { N_("enable")  , cmdENABLEKEY , 0,1, N_("enable a key") },
1294         { N_("showphoto"),cmdSHOWPHOTO , 0,0, N_("show photo ID") },
1295         { NULL, cmdNONE, 0, 0, NULL } };
1296     enum cmdids cmd = 0;
1297     int rc = 0;
1298     KBNODE keyblock = NULL;
1299     KEYDB_HANDLE kdbhd = NULL;
1300     KBNODE sec_keyblock = NULL;
1301     KEYDB_HANDLE sec_kdbhd = NULL;
1302     KBNODE cur_keyblock;
1303     char *answer = NULL;
1304     int redisplay = 1;
1305     int modified = 0;
1306     int sec_modified = 0;
1307     int toggle;
1308     int have_commands = !!commands;
1309
1310     if ( opt.command_fd != -1 )
1311         ;
1312     else if( opt.batch && !have_commands  )
1313       {
1314         log_error(_("can't do this in batch mode\n"));
1315         goto leave;
1316       }
1317
1318     /* get the public key */
1319     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1320     if( rc )
1321         goto leave;
1322     if( fix_keyblock( keyblock ) )
1323         modified++;
1324     if( collapse_uids( &keyblock ) )
1325         modified++;
1326     reorder_keyblock(keyblock);
1327
1328     if(seckey_check)
1329       {/* see whether we have a matching secret key */
1330         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1331
1332         sec_kdbhd = keydb_new (1);
1333         {
1334             byte afp[MAX_FINGERPRINT_LEN];
1335             size_t an;
1336
1337             fingerprint_from_pk (pk, afp, &an);
1338             while (an < MAX_FINGERPRINT_LEN) 
1339                 afp[an++] = 0;
1340             rc = keydb_search_fpr (sec_kdbhd, afp);
1341         }
1342         if (!rc)
1343           {
1344             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1345             if (rc)
1346               {
1347                 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1348                            username, g10_errstr(rc));
1349               }
1350             else
1351               {
1352                 merge_keys_and_selfsig( sec_keyblock );
1353                 if( fix_keyblock( sec_keyblock ) )
1354                   sec_modified++;
1355               }
1356           }
1357
1358         if (rc) {
1359             sec_keyblock = NULL;
1360             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1361             rc = 0;
1362         }
1363
1364         if( sec_keyblock && !quiet )
1365           tty_printf(_("Secret key is available.\n"));
1366     }
1367
1368     toggle = 0;
1369     cur_keyblock = keyblock;
1370     for(;;) { /* main loop */
1371         int i, arg_number, photo;
1372         const char *arg_string = "";
1373         char *p;
1374         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1375
1376         tty_printf("\n");
1377         if( redisplay && !quiet )
1378           {
1379             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1380             tty_printf("\n");
1381             redisplay = 0;
1382           }
1383         do {
1384             m_free(answer);
1385             if( have_commands ) {
1386                 if( commands ) {
1387                     answer = m_strdup( commands->d );
1388                     commands = commands->next;
1389                 }
1390                 else if( opt.batch ) {
1391                     answer = m_strdup("quit");
1392                 }
1393                 else
1394                     have_commands = 0;
1395             }
1396             if( !have_commands ) {
1397                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1398                 cpr_kill_prompt();
1399             }
1400             trim_spaces(answer);
1401         } while( *answer == '#' );
1402
1403         arg_number = 0; /* Yes, here is the init which egcc complains about */
1404         photo = 0; /* This too */
1405         if( !*answer )
1406             cmd = cmdLIST;
1407         else if( *answer == CONTROL_D )
1408             cmd = cmdQUIT;
1409         else if( digitp(answer ) ) {
1410             cmd = cmdSELUID;
1411             arg_number = atoi(answer);
1412         }
1413         else {
1414             if( (p=strchr(answer,' ')) ) {
1415                 *p++ = 0;
1416                 trim_spaces(answer);
1417                 trim_spaces(p);
1418                 arg_number = atoi(p);
1419                 arg_string = p;
1420             }
1421
1422             for(i=0; cmds[i].name; i++ ) {
1423                 if( !ascii_strcasecmp( answer, cmds[i].name ) )
1424                     break;
1425             }
1426             if( cmds[i].need_sk && !sec_keyblock ) {
1427                 tty_printf(_("Need the secret key to do this.\n"));
1428                 cmd = cmdNOP;
1429             }
1430             else if(  (cmds[i].not_with_sk == 1 && sec_keyblock && toggle)
1431                     ||(cmds[i].not_with_sk == 2 && sec_keyblock && !toggle)) {
1432                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1433                 cmd = cmdNOP;
1434             }
1435             else
1436                 cmd = cmds[i].id;
1437         }
1438         switch( cmd )  {
1439           case cmdHELP:
1440             for(i=0; cmds[i].name; i++ ) {
1441               if( cmds[i].need_sk && !sec_keyblock )
1442                 ; /* skip if we do not have the secret key */
1443               else if( cmds[i].desc )
1444                 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1445             }
1446             break;
1447
1448           case cmdLIST:
1449             redisplay = 1;
1450             break;
1451
1452           case cmdFPR:
1453             show_key_and_fingerprint( keyblock );
1454             break;
1455
1456           case cmdSELUID:
1457             if( menu_select_uid( cur_keyblock, arg_number ) )
1458                 redisplay = 1;
1459             break;
1460
1461           case cmdSELKEY:
1462             if( menu_select_key( cur_keyblock, arg_number ) )
1463                 redisplay = 1;
1464             break;
1465
1466           case cmdCHECK:
1467             /* we can only do this with the public key becuase the
1468              * check functions can't cope with secret keys and it
1469              * is questionable whether this would make sense at all */
1470             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1471             break;
1472
1473           case cmdSIGN: /* sign (only the public key) */
1474           case cmdLSIGN: /* sign (only the public key) */
1475           case cmdNRSIGN: /* sign (only the public key) */
1476           case cmdNRLSIGN: /* sign (only the public key) */
1477           case cmdTSIGN:
1478             if( pk->is_revoked )
1479               {
1480                 tty_printf(_("Key is revoked."));
1481
1482                 if(opt.expert)
1483                   {
1484                     tty_printf("  ");
1485                     if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1486                                               _("Are you sure you still want "
1487                                                 "to sign it? (y/N) ")))
1488                       break;
1489                   }
1490                 else
1491                   {
1492                     tty_printf(_("  Unable to sign.\n"));
1493                     break;
1494                   }
1495               }
1496
1497             if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) )
1498               {
1499                 if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1500                                         _("Really sign all user IDs? (y/N) ")))
1501                   {
1502                     tty_printf(_("Hint: Select the user IDs to sign\n"));
1503                     break;
1504                   }
1505               }
1506
1507             sign_uids( keyblock, locusr, &modified,
1508                        (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
1509                        (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
1510                        (cmd == cmdTSIGN));
1511             break;
1512
1513           case cmdDEBUG:
1514             dump_kbnode( cur_keyblock );
1515             break;
1516
1517           case cmdTOGGLE:
1518             toggle = !toggle;
1519             cur_keyblock = toggle? sec_keyblock : keyblock;
1520             redisplay = 1;
1521             break;
1522
1523           case cmdADDPHOTO:
1524             if (RFC2440 || RFC1991 || PGP2)
1525               {
1526                 tty_printf(
1527                    _("This command is not allowed while in %s mode.\n"),
1528                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1529                 break;
1530               }
1531             photo=1;
1532             /* fall through */
1533
1534           case cmdADDUID:
1535             if( menu_adduid( keyblock, sec_keyblock, photo ) )
1536               {
1537                 update_trust = 1;
1538                 redisplay = 1;
1539                 sec_modified = modified = 1;
1540                 merge_keys_and_selfsig( sec_keyblock );
1541                 merge_keys_and_selfsig( keyblock );
1542               }
1543             break;
1544
1545           case cmdDELUID: {
1546                 int n1;
1547
1548                 if( !(n1=count_selected_uids(keyblock)) )
1549                     tty_printf(_("You must select at least one user ID.\n"));
1550                 else if( real_uids_left(keyblock) < 1 )
1551                     tty_printf(_("You can't delete the last user ID!\n"));
1552                 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1553                 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1554                             : _("Really remove this user ID? (y/N) ")
1555                        ) ) {
1556                     menu_deluid( keyblock, sec_keyblock );
1557                     redisplay = 1;
1558                     modified = 1;
1559                     if( sec_keyblock )
1560                        sec_modified = 1;
1561                 }
1562             }
1563             break;
1564
1565           case cmdDELSIG: {
1566                 int n1;
1567
1568                 if( !(n1=count_selected_uids(keyblock)) )
1569                     tty_printf(_("You must select at least one user ID.\n"));
1570                 else if( menu_delsig( keyblock ) ) {
1571                     /* no redisplay here, because it may scroll away some
1572                      * status output of delsig */
1573                     modified = 1;
1574                 }
1575             }
1576             break;
1577
1578           case cmdADDKEY:
1579             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1580                 redisplay = 1;
1581                 sec_modified = modified = 1;
1582                 merge_keys_and_selfsig( sec_keyblock );
1583                 merge_keys_and_selfsig( keyblock );
1584             }
1585             break;
1586
1587 #ifdef ENABLE_CARD_SUPPORT
1588           case cmdADDCARDKEY:
1589             if (card_generate_subkey (keyblock, sec_keyblock)) {
1590                 redisplay = 1;
1591                 sec_modified = modified = 1;
1592                 merge_keys_and_selfsig( sec_keyblock );
1593                 merge_keys_and_selfsig( keyblock );
1594             }
1595             break;
1596
1597         case cmdKEYTOCARD:
1598           {
1599             KBNODE node=NULL;
1600             switch ( count_selected_keys (sec_keyblock) )
1601               {
1602               case 0:
1603                 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1604                                      _("Really move the primary key? (y/N) ")))
1605                   node = sec_keyblock;
1606                 break;
1607               case 1:
1608                 for (node = sec_keyblock; node; node = node->next )
1609                   {
1610                     if (node->pkt->pkttype == PKT_SECRET_SUBKEY 
1611                         && node->flag & NODFLG_SELKEY)
1612                       break;
1613                   }
1614                 break;
1615               default:
1616                 tty_printf(_("You must select exactly one key.\n"));
1617                 break;
1618               }
1619             if (node)
1620               {
1621                 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1622                 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1623                   {
1624                     redisplay = 1;
1625                     sec_modified = 1;
1626                   }
1627               }
1628           }
1629           break;
1630 #endif /* ENABLE_CARD_SUPPORT */
1631
1632           case cmdDELKEY: {
1633                 int n1;
1634
1635                 if( !(n1=count_selected_keys( keyblock )) )
1636                     tty_printf(_("You must select at least one key.\n"));
1637                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1638                        n1 > 1?
1639                    _("Do you really want to delete the selected keys? (y/N) "):
1640                         _("Do you really want to delete this key? (y/N) ")
1641                        ))
1642                     ;
1643                 else {
1644                     menu_delkey( keyblock, sec_keyblock );
1645                     redisplay = 1;
1646                     modified = 1;
1647                     if( sec_keyblock )
1648                        sec_modified = 1;
1649                 }
1650             }
1651             break;
1652
1653           case cmdADDREVOKER:
1654             {
1655               int sensitive=0;
1656
1657               if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1658                 sensitive=1;
1659               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1660                 redisplay = 1;
1661                 sec_modified = modified = 1;
1662                 merge_keys_and_selfsig( sec_keyblock );
1663                 merge_keys_and_selfsig( keyblock );
1664               }
1665             }
1666             break;
1667
1668           case cmdREVUID: {
1669                 int n1;
1670
1671                 if( !(n1=count_selected_uids(keyblock)) )
1672                     tty_printf(_("You must select at least one user ID.\n"));
1673                 else if( cpr_get_answer_is_yes(
1674                             "keyedit.revoke.uid.okay",
1675                        n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
1676                              : _("Really revoke this user ID? (y/N) ")
1677                        ) ) {
1678                   if(menu_revuid(keyblock,sec_keyblock))
1679                     {
1680                       modified=1;
1681                       redisplay=1;
1682                     }
1683                 }
1684             }
1685             break;
1686
1687           case cmdREVKEY: {
1688                 int n1;
1689
1690                 if( !(n1=count_selected_keys( keyblock )) )
1691                     tty_printf(_("You must select at least one key.\n"));
1692                 else if( sec_keyblock && !cpr_get_answer_is_yes(
1693                             "keyedit.revoke.subkey.okay",
1694                        n1 > 1?
1695                    _("Do you really want to revoke the selected keys? (y/N) "):
1696                    _("Do you really want to revoke this key? (y/N) ")
1697                        ))
1698                     ;
1699                 else {
1700                     if( menu_revkey( keyblock, sec_keyblock ) ) {
1701                         modified = 1;
1702                         /*sec_modified = 1;*/
1703                     }
1704                     redisplay = 1;
1705                 }
1706             }
1707             break;
1708
1709           case cmdEXPIRE:
1710             if( menu_expire( keyblock, sec_keyblock ) ) {
1711                 merge_keys_and_selfsig( sec_keyblock );
1712                 merge_keys_and_selfsig( keyblock );
1713                 sec_modified = 1;
1714                 modified = 1;
1715                 redisplay = 1;
1716             }
1717             break;
1718
1719           case cmdPRIMARY:
1720             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1721                 merge_keys_and_selfsig( keyblock );
1722                 modified = 1;
1723                 redisplay = 1;
1724             }
1725             break;
1726
1727           case cmdPASSWD:
1728             if( change_passphrase( sec_keyblock ) )
1729                 sec_modified = 1;
1730             break;
1731
1732           case cmdTRUST:
1733             if(opt.trust_model==TM_EXTERNAL)
1734               {
1735                 tty_printf(_("Owner trust may not be set while "
1736                              "using an user provided trust database\n"));
1737                 break;
1738               }
1739
1740             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1741             tty_printf("\n");
1742             if( edit_ownertrust( find_kbnode( keyblock,
1743                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1744                 redisplay = 1;
1745                 /* No real need to set update_trust here as
1746                    edit_ownertrust() calls revalidation_mark()
1747                    anyway. */
1748                 update_trust=1;
1749             }
1750             break;
1751
1752           case cmdPREF:
1753             show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1754             break;
1755
1756           case cmdSHOWPREF:
1757             show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1758             break;
1759
1760           case cmdSETPREF:
1761             keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
1762             break;
1763
1764           case cmdUPDPREF: 
1765             {
1766               PKT_user_id *temp=keygen_get_std_prefs();
1767               tty_printf(_("Set preference list to:\n"));
1768               show_prefs(temp,NULL,1);
1769               m_free(temp);
1770             }
1771             if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
1772                                         count_selected_uids (keyblock)?
1773                                        _("Really update the preferences"
1774                                          " for the selected user IDs? (y/N) "):
1775                                    _("Really update the preferences? (y/N) ")))
1776               {
1777
1778                 if ( menu_set_preferences (keyblock, sec_keyblock) )
1779                   {
1780                     merge_keys_and_selfsig (keyblock);
1781                     modified = 1;
1782                     redisplay = 1;
1783                   }
1784               }
1785             break;
1786
1787           case cmdPREFKS:
1788             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
1789                                          keyblock, sec_keyblock ) )
1790               {
1791                 merge_keys_and_selfsig( keyblock );
1792                 modified = 1;
1793                 redisplay = 1;
1794               }
1795             break;
1796
1797           case cmdNOP:
1798             break;
1799
1800           case cmdREVSIG:
1801             if( menu_revsig( keyblock ) ) {
1802                 redisplay = 1;
1803                 modified = 1;
1804             }
1805             break;
1806
1807           case cmdENABLEKEY:
1808           case cmdDISABLEKEY:
1809             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1810                 redisplay = 1;
1811                 modified = 1;
1812             }
1813             break;
1814
1815          case cmdSHOWPHOTO:
1816            menu_showphoto(keyblock);
1817            break;
1818
1819           case cmdQUIT:
1820             if( have_commands )
1821                 goto leave;
1822             if( !modified && !sec_modified )
1823                 goto leave;
1824             if( !cpr_get_answer_is_yes("keyedit.save.okay",
1825                                         _("Save changes? (y/N) ")) ) {
1826                 if( cpr_enabled()
1827                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
1828                                              _("Quit without saving? (y/N) ")))
1829                     goto leave;
1830                 break;
1831             }
1832             /* fall thru */
1833           case cmdSAVE:
1834             if( modified || sec_modified  ) {
1835                 if( modified ) {
1836                     rc = keydb_update_keyblock (kdbhd, keyblock);
1837                     if( rc ) {
1838                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
1839                         break;
1840                     }
1841                 }
1842                 if( sec_modified ) {
1843                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1844                     if( rc ) {
1845                         log_error( _("update secret failed: %s\n"),
1846                                    g10_errstr(rc) );
1847                         break;
1848                     }
1849                 }
1850             }
1851             else
1852                 tty_printf(_("Key not changed so no update needed.\n"));
1853
1854             if( update_trust )
1855               {
1856                 revalidation_mark ();
1857                 update_trust=0;
1858               }
1859             goto leave;
1860
1861           case cmdINVCMD:
1862           default:
1863             tty_printf("\n");
1864             tty_printf(_("Invalid command  (try \"help\")\n"));
1865             break;
1866         }
1867     } /* end main loop */
1868
1869   leave:
1870     release_kbnode( keyblock );
1871     release_kbnode( sec_keyblock );
1872     keydb_release (kdbhd);
1873     m_free(answer);
1874 }
1875
1876
1877 /****************
1878  * show preferences of a public keyblock.
1879  */
1880 static void
1881 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
1882 {
1883     const prefitem_t fake={0,0};
1884     const prefitem_t *prefs;
1885     int i;
1886
1887     if( !uid )
1888         return;
1889
1890     if( uid->prefs )
1891         prefs=uid->prefs;
1892     else if(verbose)
1893         prefs=&fake;
1894     else
1895       return;
1896
1897     if (verbose) {
1898         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1899
1900         tty_printf ("     ");
1901         tty_printf (_("Cipher: "));
1902         for(i=any=0; prefs[i].type; i++ ) {
1903             if( prefs[i].type == PREFTYPE_SYM ) {
1904                 const char *s = cipher_algo_to_string (prefs[i].value);
1905                 
1906                 if (any)
1907                     tty_printf (", ");
1908                 any = 1;
1909                 /* We don't want to display strings for experimental algos */
1910                 if (s && prefs[i].value < 100 )
1911                     tty_printf ("%s", s );
1912                 else
1913                     tty_printf ("[%d]", prefs[i].value);
1914                 if (prefs[i].value == CIPHER_ALGO_3DES )
1915                     des_seen = 1;
1916             }    
1917         }
1918         if (!des_seen) {
1919             if (any)
1920                 tty_printf (", ");
1921             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
1922         }
1923         tty_printf ("\n     ");
1924         tty_printf (_("Digest: "));
1925         for(i=any=0; prefs[i].type; i++ ) {
1926             if( prefs[i].type == PREFTYPE_HASH ) {
1927                 const char *s = digest_algo_to_string (prefs[i].value);
1928                 
1929                 if (any)
1930                     tty_printf (", ");
1931                 any = 1;
1932                 /* We don't want to display strings for experimental algos */
1933                 if (s && prefs[i].value < 100 )
1934                     tty_printf ("%s", s );
1935                 else
1936                     tty_printf ("[%d]", prefs[i].value);
1937                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
1938                     sha1_seen = 1;
1939             }
1940         }
1941         if (!sha1_seen) {
1942             if (any)
1943                 tty_printf (", ");
1944             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
1945         }
1946         tty_printf ("\n     ");
1947         tty_printf (_("Compression: "));
1948         for(i=any=0; prefs[i].type; i++ ) {
1949             if( prefs[i].type == PREFTYPE_ZIP ) {
1950                 const char *s=compress_algo_to_string(prefs[i].value);
1951                 
1952                 if (any)
1953                     tty_printf (", ");
1954                 any = 1;
1955                 /* We don't want to display strings for experimental algos */
1956                 if (s && prefs[i].value < 100 )
1957                     tty_printf ("%s", s );
1958                 else
1959                     tty_printf ("[%d]", prefs[i].value);
1960                 if (prefs[i].value == COMPRESS_ALGO_NONE )
1961                     uncomp_seen = 1;
1962             }
1963         }
1964         if (!uncomp_seen) {
1965             if (any)
1966                 tty_printf (", ");
1967             else {
1968               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
1969               tty_printf (", ");
1970             }
1971             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
1972         }
1973         if(uid->mdc_feature || !uid->ks_modify)
1974           {
1975             tty_printf ("\n     ");
1976             tty_printf (_("Features: "));
1977             any=0;
1978             if(uid->mdc_feature)
1979               {
1980                 tty_printf ("MDC");
1981                 any=1;
1982               }
1983             if(!uid->ks_modify)
1984               {
1985                 if(any)
1986                   tty_printf (", ");
1987                 tty_printf (_("Keyserver no-modify"));
1988               }
1989           }
1990         tty_printf("\n");
1991
1992         if(selfsig)
1993           {
1994             const byte *pref_ks;
1995             size_t pref_ks_len;
1996
1997             pref_ks=parse_sig_subpkt(selfsig->hashed,
1998                                      SIGSUBPKT_PREF_KS,&pref_ks_len);
1999             if(pref_ks && pref_ks_len)
2000               {
2001                 tty_printf ("     ");
2002                 tty_printf(_("Preferred keyserver: "));
2003                 tty_print_utf8_string(pref_ks,pref_ks_len);
2004                 tty_printf("\n");
2005               }
2006           }
2007     }
2008     else {
2009         tty_printf("    ");
2010         for(i=0; prefs[i].type; i++ ) {
2011             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
2012                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
2013                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2014                                  prefs[i].value);
2015         }
2016         if (uid->mdc_feature)
2017             tty_printf (" [mdc]");
2018         if (!uid->ks_modify)
2019             tty_printf (" [no-ks-modify]");
2020         tty_printf("\n");
2021     }
2022 }
2023
2024
2025 /* This is the version of show_key_with_all_names used when
2026    opt.with_colons is used.  It prints all available data in a easy to
2027    parse format and does not translate utf8 */
2028 static void
2029 show_key_with_all_names_colon (KBNODE keyblock)
2030 {
2031   KBNODE node;
2032   int i, j, ulti_hack=0;
2033   byte pk_version=0;
2034   PKT_public_key *primary=NULL;
2035
2036   /* the keys */
2037   for ( node = keyblock; node; node = node->next )
2038     {
2039       if (node->pkt->pkttype == PKT_PUBLIC_KEY
2040           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2041         {
2042           PKT_public_key *pk = node->pkt->pkt.public_key;
2043           u32 keyid[2];
2044
2045           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2046             {
2047               pk_version = pk->version;
2048               primary=pk;
2049             }
2050
2051           keyid_from_pk (pk, keyid);
2052
2053           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2054           if (!pk->is_valid)
2055             putchar ('i');
2056           else if (pk->is_revoked)
2057             putchar ('r');
2058           else if (pk->has_expired)
2059             putchar ('e');
2060           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2061             {
2062               int trust = get_validity_info (pk, NULL);
2063               if(trust=='u')
2064                 ulti_hack=1;
2065               putchar (trust);
2066             }
2067
2068           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2069                   nbits_from_pk (pk),
2070                   pk->pubkey_algo,
2071                   (ulong)keyid[0], (ulong)keyid[1],
2072                   (ulong)pk->timestamp,
2073                   (ulong)pk->expiredate );
2074           if (node->pkt->pkttype==PKT_PUBLIC_KEY
2075               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2076             putchar(get_ownertrust_info (pk));
2077           putchar(':');
2078           putchar('\n');
2079           
2080           print_fingerprint (pk, NULL, 0);
2081
2082           /* print the revoker record */
2083           if( !pk->revkey && pk->numrevkeys )
2084             BUG();
2085           else
2086             {
2087               for (i=0; i < pk->numrevkeys; i++)
2088                 {
2089                   byte *p;
2090
2091                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
2092                   p = pk->revkey[i].fpr;
2093                   for (j=0; j < 20; j++, p++ )
2094                     printf ("%02X", *p);
2095                   printf (":%02x%s:\n", pk->revkey[i].class,
2096                           (pk->revkey[i].class&0x40)?"s":"");
2097                 }
2098             }
2099         }
2100     }
2101   
2102     /* the user ids */
2103     i = 0;
2104     for (node = keyblock; node; node = node->next) 
2105       {
2106         if ( node->pkt->pkttype == PKT_USER_ID )
2107           {
2108             PKT_user_id *uid = node->pkt->pkt.user_id;
2109
2110             ++i;
2111
2112             if(uid->attrib_data)
2113               printf("uat:");
2114             else
2115               printf("uid:");
2116
2117             if ( uid->is_revoked )
2118               printf("r::::::::");
2119             else if ( uid->is_expired )
2120               printf("e::::::::");
2121             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2122               printf("::::::::");
2123             else
2124               {
2125                 int uid_validity;
2126
2127                 if( primary && !ulti_hack )
2128                   uid_validity = get_validity_info( primary, uid );
2129                 else
2130                   uid_validity = 'u';
2131                 printf("%c::::::::",uid_validity);
2132               }
2133
2134             if(uid->attrib_data)
2135               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2136             else
2137               print_string (stdout, uid->name, uid->len, ':');
2138
2139             putchar (':');
2140             /* signature class */
2141             putchar (':');
2142             /* capabilities */
2143             putchar (':');
2144             /* preferences */
2145             if (pk_version>3 || uid->selfsigversion>3)
2146               {
2147                 const prefitem_t *prefs = uid->prefs;
2148                 
2149                 for (j=0; prefs && prefs[j].type; j++)
2150                   {
2151                     if (j)
2152                       putchar (' ');
2153                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2154                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2155                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2156                             prefs[j].value);
2157                   } 
2158                 if (uid->mdc_feature)
2159                   printf (",mdc");
2160                 if (!uid->ks_modify)
2161                   printf (",no-ks-modify");
2162               } 
2163             putchar (':');
2164             /* flags */
2165             printf ("%d,", i);
2166             if (uid->is_primary)
2167               putchar ('p');
2168             if (uid->is_revoked)
2169               putchar ('r');
2170             if (uid->is_expired)
2171               putchar ('e');
2172             if ((node->flag & NODFLG_SELUID))
2173               putchar ('s');
2174             if ((node->flag & NODFLG_MARK_A))
2175               putchar ('m');
2176             putchar (':');
2177             putchar('\n');
2178           }
2179       }
2180 }
2181
2182
2183 /****************
2184  * Display the key a the user ids, if only_marked is true, do only
2185  * so for user ids with mark A flag set and dont display the index number
2186  */
2187 static void
2188 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2189                          int with_fpr, int with_subkeys, int with_prefs )
2190 {
2191     KBNODE node;
2192     int i;
2193     int do_warn = 0;
2194     byte pk_version=0;
2195     PKT_public_key *primary=NULL;
2196
2197     if (opt.with_colons)
2198       {
2199         show_key_with_all_names_colon (keyblock);
2200         return;
2201       }
2202
2203     /* the keys */
2204     for( node = keyblock; node; node = node->next ) {
2205         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2206             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
2207             PKT_public_key *pk = node->pkt->pkt.public_key;
2208             const char *otrust="err",*trust="err";
2209
2210             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2211                 /* do it here, so that debug messages don't clutter the
2212                  * output */
2213                 static int did_warn = 0;
2214
2215                 trust = get_validity_string (pk, NULL);
2216                 otrust = get_ownertrust_string (pk);
2217
2218                 /* Show a warning once */
2219                 if (!did_warn
2220                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2221                     did_warn = 1;
2222                     do_warn = 1;
2223                 }
2224
2225                 pk_version=pk->version;
2226                 primary=pk;
2227             }
2228
2229             if(with_revoker) {
2230                 if( !pk->revkey && pk->numrevkeys )
2231                     BUG();
2232                 else
2233                     for(i=0;i<pk->numrevkeys;i++) {
2234                         u32 r_keyid[2];
2235                         char *user;
2236                         const char *algo=
2237                           pubkey_algo_to_string(pk->revkey[i].algid);
2238
2239                         keyid_from_fingerprint(pk->revkey[i].fpr,
2240                                                MAX_FINGERPRINT_LEN,r_keyid);
2241                         
2242                         user=get_user_id_string (r_keyid);
2243                         tty_printf (_("This key may be revoked by %s key "),
2244                                     algo?algo:"?");
2245                         tty_print_utf8_string (user, strlen (user));
2246                         if ((pk->revkey[i].class&0x40))
2247                           tty_printf (_(" (sensitive)"));
2248                         tty_printf ("\n");
2249                         m_free(user);
2250                       }
2251             }
2252
2253             keyid_from_pk(pk,NULL);
2254             tty_printf("%s%c %4u%c/%s  ",
2255                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2256                        (node->flag & NODFLG_SELKEY)? '*':' ',
2257                        nbits_from_pk( pk ),
2258                        pubkey_letter( pk->pubkey_algo ),
2259                        keystr(pk->keyid));
2260
2261             tty_printf(_("created: %s"),datestr_from_pk(pk));
2262             tty_printf("  ");
2263             if(pk->is_revoked)
2264               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2265             else if(pk->has_expired)
2266               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2267             else
2268               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2269             tty_printf("  ");
2270             tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2271             tty_printf("\n");
2272
2273             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2274               {
2275                 if(opt.trust_model!=TM_ALWAYS)
2276                   {
2277                     tty_printf("%*s",keystrlen()+13,"");
2278                     /* Ownertrust is only meaningful for the PGP or
2279                        classic trust models */
2280                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2281                       {
2282                         int width=14-strlen(otrust);
2283                         if(width<=0)
2284                           width=1;
2285                         tty_printf(_("trust: %s"), otrust);
2286                         tty_printf("%*s",width,"");
2287                       }
2288                     
2289                     tty_printf(_("validity: %s"), trust );
2290                     tty_printf("\n");
2291                   }
2292                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2293                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2294                   {
2295                     tty_printf("*** ");
2296                     tty_printf(_("This key has been disabled"));
2297                     tty_printf("\n");
2298                   }
2299               }
2300
2301             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2302               {
2303                 print_fingerprint ( pk, NULL, 2 );
2304                 tty_printf("\n");
2305               }
2306         }
2307         else if( node->pkt->pkttype == PKT_SECRET_KEY
2308             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2309           {
2310             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2311             tty_printf("%s%c %4u%c/%s  ",
2312                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2313                        (node->flag & NODFLG_SELKEY)? '*':' ',
2314                        nbits_from_sk( sk ),
2315                        pubkey_letter( sk->pubkey_algo ),
2316                        keystr_from_sk(sk));
2317             tty_printf(_("created: %s"),datestr_from_sk(sk));
2318             tty_printf("  ");
2319             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2320             tty_printf("\n");
2321             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2322               {
2323                 tty_printf("                     ");
2324                 tty_printf(_("card-no: ")); 
2325                 if (sk->protect.ivlen == 16
2326                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2327                   { /* This is an OpenPGP card. */
2328                     for (i=8; i < 14; i++)
2329                       {
2330                         if (i == 10)
2331                           tty_printf (" ");
2332                         tty_printf ("%02X", sk->protect.iv[i]);
2333                       }
2334                   }
2335                 else
2336                   { /* Something is wrong: Print all. */
2337                     for (i=0; i < sk->protect.ivlen; i++)
2338                       tty_printf ("%02X", sk->protect.iv[i]);
2339                   }
2340                 tty_printf ("\n");
2341               }
2342           }
2343     }
2344     
2345     /* the user ids */
2346
2347     i = 0;
2348     for( node = keyblock; node; node = node->next )
2349       {
2350         if( node->pkt->pkttype == PKT_USER_ID )
2351           {
2352             PKT_user_id *uid = node->pkt->pkt.user_id;
2353             ++i;
2354             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A)))
2355               {
2356                 if(!only_marked)
2357                   {
2358                     if(uid->is_revoked)
2359                       tty_printf(_("[%8.8s] "),_("revoked"));
2360                     else if(uid->is_expired)
2361                       tty_printf(_("[%8.8s] "),_("expired"));
2362                     else if(primary)
2363                       tty_printf(_("[%8.8s] "),
2364                                  trust_value_to_string(get_validity(primary,
2365                                                                     uid)));
2366                   }
2367
2368                 if( only_marked )
2369                   tty_printf("     ");
2370                 else if( node->flag & NODFLG_SELUID )
2371                   tty_printf("(%d)* ", i);
2372                 else if( uid->is_primary )
2373                   tty_printf("(%d). ", i);
2374                 else
2375                   tty_printf("(%d)  ", i);
2376                 tty_print_utf8_string( uid->name, uid->len );
2377                 tty_printf("\n");
2378                 if( with_prefs )
2379                   {
2380                     if(pk_version>3 || uid->selfsigversion>3)
2381                       {
2382                         PKT_signature *selfsig=NULL;
2383                         KBNODE signode;
2384
2385                         for(signode=node->next;
2386                             signode && signode->pkt->pkttype==PKT_SIGNATURE;
2387                             signode=signode->next)
2388                           {
2389                             if(signode->pkt->pkt.signature->
2390                                flags.chosen_selfsig)
2391                               {
2392                                 selfsig=signode->pkt->pkt.signature;
2393                                 break;
2394                               }
2395                           }
2396
2397                         show_prefs (uid, selfsig, with_prefs == 2);
2398                       }
2399                     else
2400                       tty_printf(_("There are no preferences on a "
2401                                    "PGP 2.x-style user ID.\n"));
2402                   }
2403               }
2404           }
2405       }
2406
2407     if (do_warn)
2408         tty_printf (_("Please note that the shown key validity "
2409                       "is not necessarily correct\n"
2410                       "unless you restart the program.\n")); 
2411 }
2412
2413
2414 /* Display basic key information.  This fucntion is suitable to show
2415    information on the key without any dependencies on the trustdb or
2416    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2417    a secret key.*/
2418 void
2419 show_basic_key_info ( KBNODE keyblock )
2420 {
2421   KBNODE node;
2422   int i;
2423
2424   /* The primary key */
2425   for (node = keyblock; node; node = node->next)
2426     {
2427       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2428         {
2429           PKT_public_key *pk = node->pkt->pkt.public_key;
2430           
2431           /* Note, we use the same format string as in other show
2432              functions to make the translation job easier. */
2433           tty_printf ("%s  %4u%c/%s  ",
2434                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2435                       nbits_from_pk( pk ),
2436                       pubkey_letter( pk->pubkey_algo ),
2437                       keystr_from_pk(pk));
2438           tty_printf(_("created: %s"),datestr_from_pk(pk));
2439           tty_printf("  ");
2440           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2441           tty_printf("\n");
2442           print_fingerprint ( pk, NULL, 3 );
2443           tty_printf("\n");
2444         }
2445       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2446         {
2447           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2448           tty_printf("%s  %4u%c/%s",
2449                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2450                      nbits_from_sk( sk ),
2451                      pubkey_letter( sk->pubkey_algo ),
2452                      keystr_from_sk(sk));
2453           tty_printf(_("created: %s"),datestr_from_sk(sk));
2454           tty_printf("  ");
2455           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2456           tty_printf("\n");
2457           print_fingerprint (NULL, sk, 3 );
2458           tty_printf("\n");
2459         }
2460     }
2461
2462   /* The user IDs. */
2463   for (i=0, node = keyblock; node; node = node->next)
2464     {
2465       if (node->pkt->pkttype == PKT_USER_ID)
2466         {
2467           PKT_user_id *uid = node->pkt->pkt.user_id;
2468           ++i;
2469      
2470           tty_printf ("     ");
2471           if (uid->is_revoked)
2472             tty_printf("[%s] ",_("revoked"));
2473           else if ( uid->is_expired )
2474             tty_printf("[%s] ",_("expired"));
2475           tty_print_utf8_string (uid->name, uid->len);
2476           tty_printf ("\n");
2477         }
2478     }
2479 }
2480
2481 static void
2482 show_key_and_fingerprint( KBNODE keyblock )
2483 {
2484   KBNODE node;
2485   PKT_public_key *pk = NULL;
2486
2487   for( node = keyblock; node; node = node->next )
2488     {
2489       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2490         {
2491           pk = node->pkt->pkt.public_key;
2492           tty_printf("pub   %4u%c/%s %s ",
2493                      nbits_from_pk( pk ),
2494                      pubkey_letter( pk->pubkey_algo ),
2495                      keystr_from_pk(pk),
2496                      datestr_from_pk(pk) );
2497         }
2498       else if( node->pkt->pkttype == PKT_USER_ID )
2499         {
2500           PKT_user_id *uid = node->pkt->pkt.user_id;
2501           tty_print_utf8_string( uid->name, uid->len );
2502           break;
2503         }
2504     }
2505   tty_printf("\n");
2506   if( pk )
2507     print_fingerprint( pk, NULL, 2 );
2508 }
2509
2510
2511 /* Show a warning if no uids on the key have the primary uid flag
2512    set. */
2513 static void
2514 no_primary_warning(KBNODE keyblock)
2515 {
2516   KBNODE node;
2517   int have_primary=0,uid_count=0;
2518
2519   /* TODO: if we ever start behaving differently with a primary or
2520      non-primary attribute ID, we will need to check for attributes
2521      here as well. */
2522
2523   for(node=keyblock; node; node = node->next)
2524     {
2525       if(node->pkt->pkttype==PKT_USER_ID
2526          && node->pkt->pkt.user_id->attrib_data==NULL)
2527         {
2528           uid_count++;
2529
2530           if(node->pkt->pkt.user_id->is_primary==2)
2531             {
2532               have_primary=1;
2533               break;
2534             }
2535         }
2536     }
2537
2538   if(uid_count>1 && !have_primary)
2539     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2540                " may\n              cause a different user ID to become"
2541                " the assumed primary.\n"));
2542 }
2543
2544 /****************
2545  * Ask for a new user id, do the selfsignature and put it into
2546  * both keyblocks.
2547  * Return true if there is a new user id
2548  */
2549 static int
2550 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2551 {
2552     PKT_user_id *uid;
2553     PKT_public_key *pk=NULL;
2554     PKT_secret_key *sk=NULL;
2555     PKT_signature *sig=NULL;
2556     PACKET *pkt;
2557     KBNODE node;
2558     KBNODE pub_where=NULL, sec_where=NULL;
2559     int rc;
2560
2561     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2562         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2563             pk = node->pkt->pkt.public_key;
2564         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2565             break;
2566     }
2567     if( !node ) /* no subkey */
2568         pub_where = NULL;
2569     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2570         if( node->pkt->pkttype == PKT_SECRET_KEY )
2571             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2572         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2573             break;
2574     }
2575     if( !node ) /* no subkey */
2576         sec_where = NULL;
2577     assert(pk && sk);
2578
2579     if(photo) {
2580       int hasattrib=0;
2581
2582       for( node = pub_keyblock; node; node = node->next )
2583         if( node->pkt->pkttype == PKT_USER_ID &&
2584             node->pkt->pkt.user_id->attrib_data!=NULL)
2585           {
2586             hasattrib=1;
2587             break;
2588           }
2589
2590       /* It is legal but bad for compatibility to add a photo ID to a
2591          v3 key as it means that PGP2 will not be able to use that key
2592          anymore.  Also, PGP may not expect a photo on a v3 key.
2593          Don't bother to ask this if the key already has a photo - any
2594          damage has already been done at that point. -dms */
2595       if(pk->version==3 && !hasattrib)
2596         {
2597           if(opt.expert)
2598             {
2599               tty_printf(_("WARNING: This is a PGP2-style key.  "
2600                            "Adding a photo ID may cause some versions\n"
2601                            "         of PGP to reject this key.\n"));
2602
2603               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2604                                         _("Are you sure you still want "
2605                                           "to add it? (y/N) ")))
2606                 return 0;
2607             }
2608           else
2609             {
2610               tty_printf(_("You may not add a photo ID to "
2611                            "a PGP2-style key.\n"));
2612               return 0;
2613             }
2614         }
2615
2616       uid = generate_photo_id(pk);
2617     } else
2618       uid = generate_user_id();
2619     if( !uid )
2620         return 0;
2621
2622     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2623                              keygen_add_std_prefs, pk );
2624     free_secret_key( sk );
2625     if( rc ) {
2626         log_error("signing failed: %s\n", g10_errstr(rc) );
2627         free_user_id(uid);
2628         return 0;
2629     }
2630
2631     /* insert/append to secret keyblock */
2632     pkt = m_alloc_clear( sizeof *pkt );
2633     pkt->pkttype = PKT_USER_ID;
2634     pkt->pkt.user_id = scopy_user_id(uid);
2635     node = new_kbnode(pkt);
2636     if( sec_where )
2637         insert_kbnode( sec_where, node, 0 );
2638     else
2639         add_kbnode( sec_keyblock, node );
2640     pkt = m_alloc_clear( sizeof *pkt );
2641     pkt->pkttype = PKT_SIGNATURE;
2642     pkt->pkt.signature = copy_signature(NULL, sig);
2643     if( sec_where )
2644         insert_kbnode( node, new_kbnode(pkt), 0 );
2645     else
2646         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2647     /* insert/append to public keyblock */
2648     pkt = m_alloc_clear( sizeof *pkt );
2649     pkt->pkttype = PKT_USER_ID;
2650     pkt->pkt.user_id = uid;
2651     node = new_kbnode(pkt);
2652     if( pub_where )
2653         insert_kbnode( pub_where, node, 0 );
2654     else
2655         add_kbnode( pub_keyblock, node );
2656     pkt = m_alloc_clear( sizeof *pkt );
2657     pkt->pkttype = PKT_SIGNATURE;
2658     pkt->pkt.signature = copy_signature(NULL, sig);
2659     if( pub_where )
2660         insert_kbnode( node, new_kbnode(pkt), 0 );
2661     else
2662         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2663     return 1;
2664 }
2665
2666
2667 /****************
2668  * Remove all selected userids from the keyrings
2669  */
2670 static void
2671 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2672 {
2673     KBNODE node;
2674     int selected=0;
2675
2676     for( node = pub_keyblock; node; node = node->next ) {
2677         if( node->pkt->pkttype == PKT_USER_ID ) {
2678             selected = node->flag & NODFLG_SELUID;
2679             if( selected ) {
2680                 /* Only cause a trust update if we delete a
2681                    non-revoked user id */
2682                 if(!node->pkt->pkt.user_id->is_revoked)
2683                   update_trust=1;
2684                 delete_kbnode( node );
2685                 if( sec_keyblock ) {
2686                     KBNODE snode;
2687                     int s_selected = 0;
2688                     PKT_user_id *uid = node->pkt->pkt.user_id;
2689                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2690                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2691                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2692
2693                             s_selected =
2694                                 (uid->len == suid->len
2695                                  && !memcmp( uid->name, suid->name, uid->len));
2696                             if( s_selected )
2697                                 delete_kbnode( snode );
2698                         }
2699                         else if( s_selected
2700                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2701                             delete_kbnode( snode );
2702                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2703                             s_selected = 0;
2704                     }
2705                 }
2706             }
2707         }
2708         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2709             delete_kbnode( node );
2710         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2711             selected = 0;
2712     }
2713     commit_kbnode( &pub_keyblock );
2714     if( sec_keyblock )
2715         commit_kbnode( &sec_keyblock );
2716 }
2717
2718
2719 static int
2720 menu_delsig( KBNODE pub_keyblock )
2721 {
2722     KBNODE node;
2723     PKT_user_id *uid = NULL;
2724     int changed=0;
2725
2726     for( node = pub_keyblock; node; node = node->next ) {
2727         if( node->pkt->pkttype == PKT_USER_ID ) {
2728             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2729         }
2730         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2731            int okay, valid, selfsig, inv_sig, no_key, other_err;
2732
2733             tty_printf("uid  ");
2734             tty_print_utf8_string( uid->name, uid->len );
2735             tty_printf("\n");
2736
2737             okay = inv_sig = no_key = other_err = 0;
2738             if(opt.with_colons)
2739               valid = print_and_check_one_sig_colon( pub_keyblock, node,
2740                                                &inv_sig, &no_key, &other_err,
2741                                                &selfsig, 1 );
2742             else
2743               valid = print_and_check_one_sig( pub_keyblock, node,
2744                                                &inv_sig, &no_key, &other_err,
2745                                                &selfsig, 1 );
2746
2747            if( valid ) {
2748                okay = cpr_get_answer_yes_no_quit(
2749                    "keyedit.delsig.valid",
2750                    _("Delete this good signature? (y/N/q)"));
2751
2752                /* Only update trust if we delete a good signature.
2753                   The other two cases do not affect trust. */
2754                if(okay)
2755                  update_trust=1;
2756            }
2757            else if( inv_sig || other_err )
2758                okay = cpr_get_answer_yes_no_quit(
2759                    "keyedit.delsig.invalid",
2760                    _("Delete this invalid signature? (y/N/q)"));
2761            else if( no_key )
2762                okay = cpr_get_answer_yes_no_quit(
2763                    "keyedit.delsig.unknown",
2764                    _("Delete this unknown signature? (y/N/q)"));
2765
2766             if( okay == -1 )
2767                 break;
2768            if( okay && selfsig && !cpr_get_answer_is_yes(
2769                                "keyedit.delsig.selfsig",
2770                               _("Really delete this self-signature? (y/N)") ))
2771                 okay = 0;
2772             if( okay ) {
2773                 delete_kbnode( node );
2774                 changed++;
2775             }
2776
2777         }
2778         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2779             uid = NULL;
2780     }
2781
2782     if( changed ) {
2783         commit_kbnode( &pub_keyblock );
2784         tty_printf( changed == 1? _("Deleted %d signature.\n")
2785                                 : _("Deleted %d signatures.\n"), changed );
2786     }
2787     else
2788         tty_printf( _("Nothing deleted.\n") );
2789
2790     return changed;
2791 }
2792
2793
2794 /****************
2795  * Remove some of the secondary keys
2796  */
2797 static void
2798 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2799 {
2800     KBNODE node;
2801     int selected=0;
2802
2803     for( node = pub_keyblock; node; node = node->next ) {
2804         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2805             selected = node->flag & NODFLG_SELKEY;
2806             if( selected ) {
2807                 delete_kbnode( node );
2808                 if( sec_keyblock ) {
2809                     KBNODE snode;
2810                     int s_selected = 0;
2811                     u32 ki[2];
2812
2813                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2814                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2815                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2816                             u32 ki2[2];
2817
2818                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2819                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2820                             if( s_selected )
2821                                 delete_kbnode( snode );
2822                         }
2823                         else if( s_selected
2824                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2825                             delete_kbnode( snode );
2826                         else
2827                             s_selected = 0;
2828                     }
2829                 }
2830             }
2831         }
2832         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2833             delete_kbnode( node );
2834         else
2835             selected = 0;
2836     }
2837     commit_kbnode( &pub_keyblock );
2838     if( sec_keyblock )
2839         commit_kbnode( &sec_keyblock );
2840
2841     /* No need to set update_trust here since signing keys are no
2842        longer used to certify other keys, so there is no change in
2843        trust when revoking/removing them */
2844 }
2845
2846
2847 /****************
2848  * Ask for a new revoker, do the selfsignature and put it into
2849  * both keyblocks.
2850  * Return true if there is a new revoker
2851  */
2852 static int
2853 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2854 {
2855   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2856   PKT_secret_key *sk=NULL;
2857   PKT_signature *sig=NULL;
2858   PACKET *pkt;
2859   struct revocation_key revkey;
2860   size_t fprlen;
2861   int rc;
2862
2863   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2864   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2865
2866   pk=pub_keyblock->pkt->pkt.public_key;
2867
2868   if(pk->numrevkeys==0 && pk->version==3)
2869     {
2870       /* It is legal but bad for compatibility to add a revoker to a
2871          v3 key as it means that PGP2 will not be able to use that key
2872          anymore.  Also, PGP may not expect a revoker on a v3 key.
2873          Don't bother to ask this if the key already has a revoker -
2874          any damage has already been done at that point. -dms */
2875       if(opt.expert)
2876         {
2877           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2878                        "Adding a designated revoker may cause\n"
2879                        "         some versions of PGP to reject this key.\n"));
2880
2881           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2882                                     _("Are you sure you still want "
2883                                       "to add it? (y/N) ")))
2884             return 0;
2885         }
2886       else
2887         {
2888           tty_printf(_("You may not add a designated revoker to "
2889                        "a PGP 2.x-style key.\n"));
2890           return 0;
2891         }
2892     }
2893
2894   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2895
2896   for(;;)
2897     {
2898       char *answer;
2899
2900       if(revoker_pk)
2901         free_public_key(revoker_pk);
2902
2903       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2904
2905       tty_printf("\n");
2906
2907       answer=cpr_get_utf8("keyedit.add_revoker",
2908                           _("Enter the user ID of the designated revoker: "));
2909       if(answer[0]=='\0' || answer[0]=='\004')
2910         {
2911           m_free(answer);
2912           goto fail;
2913         }
2914
2915       /* Note that I'm requesting SIG here and not CERT.  We're making
2916          a certification, but it is okay to be a subkey. */
2917       revoker_pk->req_usage=PUBKEY_USAGE_SIG;
2918       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2919       if(rc)
2920         {
2921           log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
2922           m_free(answer);
2923           continue;
2924         }
2925
2926       m_free(answer);
2927
2928       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2929       if(fprlen!=20)
2930         {
2931           log_error(_("cannot appoint a PGP 2.x style key as a "
2932                       "designated revoker\n"));
2933           continue;
2934         }
2935
2936       revkey.class=0x80;
2937       if(sensitive)
2938         revkey.class|=0x40;
2939       revkey.algid=revoker_pk->pubkey_algo;
2940
2941       if(cmp_public_keys(revoker_pk,pk)==0)
2942         {
2943           /* This actually causes no harm (after all, a key that
2944              designates itself as a revoker is the same as a
2945              regular key), but it's easy enough to check. */
2946           log_error(_("you cannot appoint a key as its own "
2947                       "designated revoker\n"));
2948
2949           continue;
2950         }
2951
2952       keyid_from_pk(pk,NULL);
2953
2954       /* Does this revkey already exist? */
2955       if(!pk->revkey && pk->numrevkeys)
2956         BUG();
2957       else
2958         {
2959           int i;
2960
2961           for(i=0;i<pk->numrevkeys;i++)
2962             {
2963               if(memcmp(&pk->revkey[i],&revkey,
2964                         sizeof(struct revocation_key))==0)
2965                 {
2966                   char buf[50];
2967
2968                   log_error(_("this key has already been designated "
2969                               "as a revoker\n"));
2970
2971                   sprintf(buf,"%08lX%08lX",
2972                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2973                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2974
2975                   break;
2976                 }
2977             }
2978
2979           if(i<pk->numrevkeys)
2980             continue;
2981         }
2982
2983       print_pubkey_info(NULL,revoker_pk);
2984       print_fingerprint(revoker_pk,NULL,2);
2985       tty_printf("\n");
2986
2987       tty_printf(_("WARNING: appointing a key as a designated revoker "
2988                    "cannot be undone!\n"));
2989
2990       tty_printf("\n");
2991
2992       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2993                                 _("Are you sure you want to appoint this "
2994                                   "key as a designated revoker? (y/N) ")))
2995         continue;
2996
2997       free_public_key(revoker_pk);
2998       revoker_pk=NULL;
2999       break;
3000     }
3001
3002   /* The 1F signature must be at least v4 to carry the revocation key
3003      subpacket. */
3004   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3005                            keygen_add_revkey,&revkey );
3006   if( rc )
3007     {
3008       log_error("signing failed: %s\n", g10_errstr(rc) );
3009       goto fail;
3010     }
3011
3012   free_secret_key(sk);
3013   sk=NULL;
3014
3015   /* insert into secret keyblock */
3016   pkt = m_alloc_clear( sizeof *pkt );
3017   pkt->pkttype = PKT_SIGNATURE;
3018   pkt->pkt.signature = copy_signature(NULL, sig);
3019   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3020
3021   /* insert into public keyblock */
3022   pkt = m_alloc_clear( sizeof *pkt );
3023   pkt->pkttype = PKT_SIGNATURE;
3024   pkt->pkt.signature = sig;
3025   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3026
3027   return 1;
3028
3029  fail:
3030   if(sk)
3031     free_secret_key(sk);
3032   if(sig)
3033     free_seckey_enc(sig);
3034   if(revoker_pk)
3035     free_public_key(revoker_pk);
3036
3037   return 0;
3038 }
3039
3040
3041 static int
3042 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3043 {
3044     int n1, signumber, rc;
3045     u32 expiredate;
3046     int mainkey=0;
3047     PKT_secret_key *sk;    /* copy of the main sk */
3048     PKT_public_key *main_pk, *sub_pk;
3049     PKT_user_id *uid;
3050     KBNODE node;
3051     u32 keyid[2];
3052
3053     if( count_selected_keys( sec_keyblock ) ) {
3054         tty_printf(_("Please remove selections from the secret keys.\n"));
3055         return 0;
3056     }
3057
3058     n1 = count_selected_keys( pub_keyblock );
3059     if( n1 > 1 ) {
3060         tty_printf(_("Please select at most one secondary key.\n"));
3061         return 0;
3062     }
3063     else if( n1 )
3064         tty_printf(_("Changing expiration time for a secondary key.\n"));
3065     else
3066       {
3067         tty_printf(_("Changing expiration time for the primary key.\n"));
3068         mainkey=1;
3069         no_primary_warning(pub_keyblock);
3070       }
3071
3072     expiredate = ask_expiredate();
3073     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3074     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3075
3076     /* Now we can actually change the self signature(s) */
3077     main_pk = sub_pk = NULL;
3078     uid = NULL;
3079     signumber = 0;
3080     for( node=pub_keyblock; node; node = node->next ) {
3081         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3082             main_pk = node->pkt->pkt.public_key;
3083             keyid_from_pk( main_pk, keyid );
3084             main_pk->expiredate = expiredate;
3085         }
3086         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3087                  && (node->flag & NODFLG_SELKEY ) ) {
3088             sub_pk = node->pkt->pkt.public_key;
3089             sub_pk->expiredate = expiredate;
3090         }
3091         else if( node->pkt->pkttype == PKT_USER_ID )
3092             uid = node->pkt->pkt.user_id;
3093         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3094                  && ( mainkey || sub_pk ) ) {
3095             PKT_signature *sig = node->pkt->pkt.signature;
3096             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3097                 && ( (mainkey && uid
3098                       && uid->created && (sig->sig_class&~3) == 0x10)
3099                      || (!mainkey && sig->sig_class == 0x18)  )
3100                 && sig->flags.chosen_selfsig )
3101               {
3102                 /* this is a selfsignature which is to be replaced */
3103                 PKT_signature *newsig;
3104                 PACKET *newpkt;
3105                 KBNODE sn;
3106                 int signumber2 = 0;
3107
3108                 signumber++;
3109
3110                 if( (mainkey && main_pk->version < 4)
3111                     || (!mainkey && sub_pk->version < 4 ) ) {
3112                     log_info(_(
3113                         "You can't change the expiration date of a v3 key\n"));
3114                     free_secret_key( sk );
3115                     return 0;
3116                 }
3117
3118                 /* find the corresponding secret self-signature */
3119                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3120                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3121                         PKT_signature *b = sn->pkt->pkt.signature;
3122                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3123                             && sig->sig_class == b->sig_class
3124                             && ++signumber2 == signumber )
3125                             break;
3126                     }
3127                 }
3128                 if( !sn )
3129                     log_info(_("No corresponding signature in secret ring\n"));
3130
3131                 if( mainkey )
3132                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3133                                             sk, keygen_add_key_expire, main_pk);
3134                 else
3135                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3136                                             sk, keygen_add_key_expire, sub_pk );
3137                 if( rc ) {
3138                     log_error("make_keysig_packet failed: %s\n",
3139                                                     g10_errstr(rc));
3140                     free_secret_key( sk );
3141                     return 0;
3142                 }
3143                 /* replace the packet */
3144                 newpkt = m_alloc_clear( sizeof *newpkt );
3145                 newpkt->pkttype = PKT_SIGNATURE;
3146                 newpkt->pkt.signature = newsig;
3147                 free_packet( node->pkt );
3148                 m_free( node->pkt );
3149                 node->pkt = newpkt;
3150                 if( sn ) {
3151                     newpkt = m_alloc_clear( sizeof *newpkt );
3152                     newpkt->pkttype = PKT_SIGNATURE;
3153                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3154                     free_packet( sn->pkt );
3155                     m_free( sn->pkt );
3156                     sn->pkt = newpkt;
3157                 }
3158                 sub_pk = NULL;
3159             }
3160         }
3161     }
3162
3163     free_secret_key( sk );
3164     update_trust=1;
3165     return 1;
3166 }
3167
3168 static int
3169 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3170 {
3171     byte buf[1];
3172
3173     /* first clear all primary uid flags so that we are sure none are
3174      * lingering around */
3175     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
3176     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3177
3178     /* if opaque is set,we want to set the primary id */
3179     if (opaque) { 
3180         buf[0] = 1;
3181         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3182     }
3183
3184     return 0;
3185 }
3186
3187
3188 /*
3189  * Set the primary uid flag for the selected UID.  We will also reset
3190  * all other primary uid flags.  For this to work with have to update
3191  * all the signature timestamps.  If we would do this with the current
3192  * time, we lose quite a lot of information, so we use a a kludge to
3193  * do this: Just increment the timestamp by one second which is
3194  * sufficient to updated a signature during import.
3195  */
3196 static int
3197 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3198 {
3199     PKT_secret_key *sk;    /* copy of the main sk */
3200     PKT_public_key *main_pk;
3201     PKT_user_id *uid;
3202     KBNODE node;
3203     u32 keyid[2];
3204     int selected;
3205     int attribute = 0;
3206     int modified = 0;
3207
3208     if ( count_selected_uids (pub_keyblock) != 1 ) {
3209         tty_printf(_("Please select exactly one user ID.\n"));
3210         return 0;
3211     }
3212
3213     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3214     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3215
3216     /* Now we can actually change the self signature(s) */
3217     main_pk = NULL;
3218     uid = NULL;
3219     selected = 0;
3220
3221     /* Is our selected uid an attribute packet? */
3222     for ( node=pub_keyblock; node; node = node->next )
3223       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3224         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3225
3226     for ( node=pub_keyblock; node; node = node->next ) {
3227         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3228             break; /* ready */
3229
3230         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3231             main_pk = node->pkt->pkt.public_key;
3232             keyid_from_pk( main_pk, keyid );
3233         }
3234         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3235             uid = node->pkt->pkt.user_id;
3236             selected = node->flag & NODFLG_SELUID;
3237         }
3238         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3239             PKT_signature *sig = node->pkt->pkt.signature;
3240             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3241                  && (uid && (sig->sig_class&~3) == 0x10)
3242                  && attribute == (uid->attrib_data!=NULL)
3243                  && sig->flags.chosen_selfsig )
3244               {
3245               if(sig->version < 4) {
3246                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3247
3248                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3249                          user);
3250                 m_free(user);
3251               }
3252               else {
3253                 /* This is a selfsignature which is to be replaced.
3254                    We can just ignore v3 signatures because they are
3255                    not able to carry the primary ID flag.  We also
3256                    ignore self-sigs on user IDs that are not of the
3257                    same type that we are making primary.  That is, if
3258                    we are making a user ID primary, we alter user IDs.
3259                    If we are making an attribute packet primary, we
3260                    alter attribute packets. */
3261
3262                 /* FIXME: We must make sure that we only have one
3263                    self-signature per user ID here (not counting
3264                    revocations) */
3265                 PKT_signature *newsig;
3266                 PACKET *newpkt;
3267                 const byte *p;
3268                 int action;
3269
3270                 /* see whether this signature has the primary UID flag */
3271                 p = parse_sig_subpkt (sig->hashed,
3272                                       SIGSUBPKT_PRIMARY_UID, NULL );
3273                 if ( !p )
3274                     p = parse_sig_subpkt (sig->unhashed,
3275                                           SIGSUBPKT_PRIMARY_UID, NULL );
3276                 if ( p && *p ) /* yes */
3277                     action = selected? 0 : -1;
3278                 else /* no */
3279                     action = selected? 1 : 0;
3280
3281                 if (action) {
3282                     int rc = update_keysig_packet (&newsig, sig,
3283                                                main_pk, uid, NULL,
3284                                                sk,
3285                                                change_primary_uid_cb,
3286                                                action > 0? "x":NULL );
3287                     if( rc ) {
3288                         log_error ("update_keysig_packet failed: %s\n",
3289                                    g10_errstr(rc));
3290                         free_secret_key( sk );
3291                         return 0;
3292                     }
3293                     /* replace the packet */
3294                     newpkt = m_alloc_clear( sizeof *newpkt );
3295                     newpkt->pkttype = PKT_SIGNATURE;
3296                     newpkt->pkt.signature = newsig;
3297                     free_packet( node->pkt );
3298                     m_free( node->pkt );
3299                     node->pkt = newpkt;
3300                     modified = 1;
3301                 }
3302               }
3303             }
3304         }
3305     }
3306
3307     free_secret_key( sk );
3308     return modified;
3309 }
3310
3311
3312 /* 
3313  * Set preferences to new values for the selected user IDs
3314  */
3315 static int
3316 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3317 {
3318     PKT_secret_key *sk;    /* copy of the main sk */
3319     PKT_public_key *main_pk;
3320     PKT_user_id *uid;
3321     KBNODE node;
3322     u32 keyid[2];
3323     int selected, select_all;
3324     int modified = 0;
3325
3326     no_primary_warning(pub_keyblock);
3327
3328     select_all = !count_selected_uids (pub_keyblock);
3329
3330     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3331     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3332
3333     /* Now we can actually change the self signature(s) */
3334     main_pk = NULL;
3335     uid = NULL;
3336     selected = 0;
3337     for ( node=pub_keyblock; node; node = node->next ) {
3338         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3339             break; /* ready */
3340
3341         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3342             main_pk = node->pkt->pkt.public_key;
3343             keyid_from_pk( main_pk, keyid );
3344         }
3345         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3346             uid = node->pkt->pkt.user_id;
3347             selected = select_all || (node->flag & NODFLG_SELUID);
3348         }
3349         else if ( main_pk && uid && selected
3350                   && node->pkt->pkttype == PKT_SIGNATURE ) {
3351             PKT_signature *sig = node->pkt->pkt.signature;
3352             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3353                  && (uid && (sig->sig_class&~3) == 0x10)
3354                  && sig->flags.chosen_selfsig ) {
3355               if( sig->version < 4 ) {
3356                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3357
3358                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3359                          user);
3360                 m_free(user);
3361               }
3362               else {
3363                 /* This is a selfsignature which is to be replaced 
3364                  * We have to ignore v3 signatures because they are
3365                  * not able to carry the preferences */
3366                 PKT_signature *newsig;
3367                 PACKET *newpkt;
3368                 int rc;
3369
3370                 rc = update_keysig_packet (&newsig, sig,
3371                                            main_pk, uid, NULL,
3372                                            sk,
3373                                            keygen_upd_std_prefs,
3374                                            NULL );
3375                 if( rc ) {
3376                     log_error ("update_keysig_packet failed: %s\n",
3377                                g10_errstr(rc));
3378                     free_secret_key( sk );
3379                     return 0;
3380                 }
3381                 /* replace the packet */
3382                 newpkt = m_alloc_clear( sizeof *newpkt );
3383                 newpkt->pkttype = PKT_SIGNATURE;
3384                 newpkt->pkt.signature = newsig;
3385                 free_packet( node->pkt );
3386                 m_free( node->pkt );
3387                 node->pkt = newpkt;
3388                 modified = 1;
3389               }
3390             }
3391         }
3392     }
3393     
3394     free_secret_key( sk );
3395     return modified;
3396 }
3397
3398
3399 static int
3400 menu_set_keyserver_url (const char *url,
3401                         KBNODE pub_keyblock, KBNODE sec_keyblock )
3402 {
3403   PKT_secret_key *sk;    /* copy of the main sk */
3404   PKT_public_key *main_pk;
3405   PKT_user_id *uid;
3406   KBNODE node;
3407   u32 keyid[2];
3408   int selected, select_all;
3409   int modified = 0;
3410   char *answer,*uri;
3411
3412   no_primary_warning(pub_keyblock);
3413
3414   if(url)
3415     answer=m_strdup(url);
3416   else
3417     {
3418       answer=cpr_get_utf8("keyedit.add_keyserver",
3419                           _("Enter your preferred keyserver URL: "));
3420       if(answer[0]=='\0' || answer[0]=='\004')
3421         {
3422           m_free(answer);
3423           return 0;
3424         }
3425     }
3426
3427   if(ascii_strcasecmp(answer,"none")==0)
3428     uri=NULL;
3429   else
3430     {
3431       struct keyserver_spec *keyserver=NULL;
3432       /* Sanity check the format */
3433       keyserver=parse_keyserver_uri(answer,1,NULL,0);
3434       m_free(answer);
3435       if(!keyserver)
3436         {
3437           log_info(_("could not parse keyserver URL\n"));
3438           return 0;
3439         }
3440       uri=m_strdup(keyserver->uri);
3441       free_keyserver_spec(keyserver);
3442     }
3443
3444   select_all = !count_selected_uids (pub_keyblock);
3445
3446   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3447   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3448
3449   /* Now we can actually change the self signature(s) */
3450   main_pk = NULL;
3451   uid = NULL;
3452   selected = 0;
3453   for ( node=pub_keyblock; node; node = node->next )
3454     {
3455       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3456         break; /* ready */
3457
3458       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
3459         {
3460           main_pk = node->pkt->pkt.public_key;
3461           keyid_from_pk( main_pk, keyid );
3462         }
3463       else if ( node->pkt->pkttype == PKT_USER_ID )
3464         {
3465           uid = node->pkt->pkt.user_id;
3466           selected = select_all || (node->flag & NODFLG_SELUID);
3467         }
3468       else if ( main_pk && uid && selected
3469                 && node->pkt->pkttype == PKT_SIGNATURE )
3470         {
3471           PKT_signature *sig = node->pkt->pkt.signature;
3472           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3473                && (uid && (sig->sig_class&~3) == 0x10) )
3474             {
3475               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3476               if( sig->version < 4 )
3477                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3478                          user);
3479               else
3480                 {
3481                   /* This is a selfsignature which is to be replaced
3482                    * We have to ignore v3 signatures because they are
3483                    * not able to carry the subpacket. */
3484                   PKT_signature *newsig;
3485                   PACKET *newpkt;
3486                   int rc;
3487                   const byte *p;
3488                   size_t plen;
3489
3490                   p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
3491                   if(p && plen)
3492                     {
3493                       tty_printf("Current preferred keyserver for user"
3494                                  " ID \"%s\": ",user);
3495                       tty_print_utf8_string(p,plen);
3496                       tty_printf("\n");
3497                       if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
3498                          uri?_("Are you sure you want to replace it? (y/N) "):
3499                              _("Are you sure you want to delete it? (y/N) ")))
3500                         continue;
3501                     }
3502                   else if(uri==NULL)
3503                     {
3504                       /* There is no current keyserver URL, so there
3505                          is no point in trying to un-set it. */
3506                       continue;
3507                     }
3508
3509                   rc = update_keysig_packet (&newsig, sig,
3510                                              main_pk, uid, NULL,
3511                                              sk,
3512                                              keygen_add_keyserver_url, uri );
3513                   if( rc )
3514                     {
3515                       log_error ("update_keysig_packet failed: %s\n",
3516                                  g10_errstr(rc));
3517                       free_secret_key( sk );
3518                       m_free(uri);
3519                       return 0;
3520                     }
3521                   /* replace the packet */
3522                   newpkt = m_alloc_clear( sizeof *newpkt );
3523                   newpkt->pkttype = PKT_SIGNATURE;
3524                   newpkt->pkt.signature = newsig;
3525                   free_packet( node->pkt );
3526                   m_free( node->pkt );
3527                   node->pkt = newpkt;
3528                   modified = 1;
3529                 }
3530
3531               m_free(user);
3532             }
3533         }
3534     }
3535
3536   m_free(uri);
3537   free_secret_key( sk );
3538   return modified;
3539 }
3540
3541
3542 /****************
3543  * Select one user id or remove all selection if index is 0.
3544  * Returns: True if the selection changed;
3545  */
3546 static int
3547 menu_select_uid( KBNODE keyblock, int idx )
3548 {
3549     KBNODE node;
3550     int i;
3551
3552     /* first check that the index is valid */
3553     if( idx ) {
3554         for( i=0, node = keyblock; node; node = node->next ) {
3555             if( node->pkt->pkttype == PKT_USER_ID ) {
3556                 if( ++i == idx )
3557                     break;
3558             }
3559         }
3560         if( !node ) {
3561             tty_printf(_("No user ID with index %d\n"), idx );
3562             return 0;
3563         }
3564     }
3565     else { /* reset all */
3566         for( i=0, node = keyblock; node; node = node->next ) {
3567             if( node->pkt->pkttype == PKT_USER_ID )
3568                 node->flag &= ~NODFLG_SELUID;
3569         }
3570         return 1;
3571     }
3572     /* and toggle the new index */
3573     for( i=0, node = keyblock; node; node = node->next ) {
3574         if( node->pkt->pkttype == PKT_USER_ID ) {
3575             if( ++i == idx ) {
3576                 if( (node->flag & NODFLG_SELUID) )
3577                     node->flag &= ~NODFLG_SELUID;
3578                 else
3579                     node->flag |= NODFLG_SELUID;
3580             }
3581         }
3582     }
3583
3584     return 1;
3585 }
3586
3587 /****************
3588  * Select secondary keys
3589  * Returns: True if the selection changed;
3590  */
3591 static int
3592 menu_select_key( KBNODE keyblock, int idx )
3593 {
3594     KBNODE node;
3595     int i;
3596
3597     /* first check that the index is valid */
3598     if( idx ) {
3599         for( i=0, node = keyblock; node; node = node->next ) {
3600             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3601                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3602                 if( ++i == idx )
3603                     break;
3604             }
3605         }
3606         if( !node ) {
3607             tty_printf(_("No secondary key with index %d\n"), idx );
3608             return 0;
3609         }
3610     }
3611     else { /* reset all */
3612         for( i=0, node = keyblock; node; node = node->next ) {
3613             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3614                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3615                 node->flag &= ~NODFLG_SELKEY;
3616         }
3617         return 1;
3618     }
3619     /* and set the new index */
3620     for( i=0, node = keyblock; node; node = node->next ) {
3621         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3622             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3623             if( ++i == idx ) {
3624                 if( (node->flag & NODFLG_SELKEY) )
3625                     node->flag &= ~NODFLG_SELKEY;
3626                 else
3627                     node->flag |= NODFLG_SELKEY;
3628             }
3629         }
3630     }
3631
3632     return 1;
3633 }
3634
3635
3636 static int
3637 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3638 {
3639     KBNODE node;
3640     int i=0;
3641
3642     for( node = keyblock; node; node = node->next )
3643         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3644             i++;
3645     return i;
3646 }
3647
3648 static int
3649 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3650 {
3651     KBNODE node;
3652     int i=0;
3653
3654     for( node = keyblock; node; node = node->next )
3655         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3656               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3657             && (node->flag & flag) )
3658             i++;
3659     return i;
3660 }
3661
3662 static int
3663 count_uids( KBNODE keyblock )
3664 {
3665     KBNODE node;
3666     int i=0;
3667
3668     for( node = keyblock; node; node = node->next )
3669         if( node->pkt->pkttype == PKT_USER_ID )
3670             i++;
3671     return i;
3672 }
3673
3674
3675 /****************
3676  * Returns true if there is at least one selected user id
3677  */
3678 static int
3679 count_selected_uids( KBNODE keyblock )
3680 {
3681     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3682 }
3683
3684 static int
3685 count_selected_keys( KBNODE keyblock )
3686 {
3687     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3688 }
3689
3690 /* returns how many real (i.e. not attribute) uids are unmarked */
3691 static int
3692 real_uids_left( KBNODE keyblock )
3693 {
3694   KBNODE node;
3695   int real=0;
3696
3697   for(node=keyblock;node;node=node->next)
3698     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3699        !node->pkt->pkt.user_id->attrib_data)
3700       real++;
3701
3702   return real;
3703 }
3704
3705 /*
3706  * Ask whether the signature should be revoked.  If the user commits this,
3707  * flag bit MARK_A is set on the signature and the user ID.
3708  */
3709 static void
3710 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3711 {
3712     int doit=0;
3713     char *p;
3714     PKT_signature *sig = node->pkt->pkt.signature;
3715     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3716
3717     if( !unode ) {
3718         log_error("Oops: no user ID for signature\n");
3719         return;
3720     }
3721
3722     p=utf8_to_native(unode->pkt->pkt.user_id->name,
3723                      unode->pkt->pkt.user_id->len,0);
3724     tty_printf(_("user ID: \"%s\"\n"),p);
3725     m_free(p);
3726
3727     tty_printf(_("signed by your key %s on %s%s%s\n"),
3728                keystr(sig->keyid),datestr_from_sig(sig),
3729                sig->flags.exportable?"":_(" (non-exportable)"),"");
3730
3731     if(sig->flags.expired)
3732       {
3733         tty_printf(_("This signature expired on %s.\n"),
3734                    expirestr_from_sig(sig));
3735         /* Use a different question so we can have different help text */
3736         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3737                         _("Are you sure you still want to revoke it? (y/N) "));
3738       }
3739     else
3740       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3741               _("Create a revocation certificate for this signature? (y/N) "));
3742
3743     if(doit) {
3744       node->flag |= NODFLG_MARK_A;
3745       unode->flag |= NODFLG_MARK_A;
3746     }
3747 }
3748
3749 /****************
3750  * Display all user ids of the current public key together with signatures
3751  * done by one of our keys.  Then walk over all this sigs and ask the user
3752  * whether he wants to revoke this signature.
3753  * Return: True when the keyblock has changed.
3754  */
3755 static int
3756 menu_revsig( KBNODE keyblock )
3757 {
3758     PKT_signature *sig;
3759     PKT_public_key *primary_pk;
3760     KBNODE node;
3761     int changed = 0;
3762     int rc, any, skip=1, all=!count_selected_uids(keyblock);
3763     struct revocation_reason_info *reason = NULL;
3764
3765     assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3766
3767     /* FIXME: detect duplicates here  */
3768     tty_printf(_("You have signed these user IDs on key %s:\n"),
3769                keystr_from_pk(keyblock->pkt->pkt.public_key));
3770     for( node = keyblock; node; node = node->next ) {
3771         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
3772         if( node->pkt->pkttype == PKT_USER_ID ) {
3773             if( node->flag&NODFLG_SE