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