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