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