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