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