* keylist.c, keyedit.c, keyserver.c, sign.c: Some TODOs and comments.
[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 key.\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.  Don't bother to ask this if the key already has a
1996          photo - any damage has already been done at that point. -dms */
1997       if(pk->version==3 && !hasattrib)
1998         {
1999           if(opt.expert)
2000             {
2001               tty_printf(_("WARNING: This is a PGP2-style key.  "
2002                            "Adding a photo ID may cause some versions\n"
2003                            "         of PGP to reject this key.\n"));
2004
2005               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2006                                         _("Are you sure you still want "
2007                                           "to add it? (y/N) ")))
2008                 return 0;
2009             }
2010           else
2011             {
2012               tty_printf(_("You may not add a photo ID to "
2013                            "a PGP2-style key.\n"));
2014               return 0;
2015             }
2016         }
2017
2018       uid = generate_photo_id(pk);
2019     } else
2020       uid = generate_user_id();
2021     if( !uid )
2022         return 0;
2023
2024     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2025                              keygen_add_std_prefs, pk );
2026     free_secret_key( sk );
2027     if( rc ) {
2028         log_error("signing failed: %s\n", g10_errstr(rc) );
2029         free_user_id(uid);
2030         return 0;
2031     }
2032
2033     /* insert/append to secret keyblock */
2034     pkt = m_alloc_clear( sizeof *pkt );
2035     pkt->pkttype = PKT_USER_ID;
2036     pkt->pkt.user_id = scopy_user_id(uid);
2037     node = new_kbnode(pkt);
2038     if( sec_where )
2039         insert_kbnode( sec_where, node, 0 );
2040     else
2041         add_kbnode( sec_keyblock, node );
2042     pkt = m_alloc_clear( sizeof *pkt );
2043     pkt->pkttype = PKT_SIGNATURE;
2044     pkt->pkt.signature = copy_signature(NULL, sig);
2045     if( sec_where )
2046         insert_kbnode( node, new_kbnode(pkt), 0 );
2047     else
2048         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2049     /* insert/append to public keyblock */
2050     pkt = m_alloc_clear( sizeof *pkt );
2051     pkt->pkttype = PKT_USER_ID;
2052     pkt->pkt.user_id = uid;
2053     node = new_kbnode(pkt);
2054     if( pub_where )
2055         insert_kbnode( pub_where, node, 0 );
2056     else
2057         add_kbnode( pub_keyblock, node );
2058     pkt = m_alloc_clear( sizeof *pkt );
2059     pkt->pkttype = PKT_SIGNATURE;
2060     pkt->pkt.signature = copy_signature(NULL, sig);
2061     if( pub_where )
2062         insert_kbnode( node, new_kbnode(pkt), 0 );
2063     else
2064         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2065     return 1;
2066 }
2067
2068
2069 /****************
2070  * Remove all selceted userids from the keyrings
2071  */
2072 static void
2073 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2074 {
2075     KBNODE node;
2076     int selected=0;
2077
2078     for( node = pub_keyblock; node; node = node->next ) {
2079         if( node->pkt->pkttype == PKT_USER_ID ) {
2080             selected = node->flag & NODFLG_SELUID;
2081             if( selected ) {
2082                 /* Only cause a trust update if we delete a
2083                    non-revoked user id */
2084                 if(!node->pkt->pkt.user_id->is_revoked)
2085                   update_trust=1;
2086                 delete_kbnode( node );
2087                 if( sec_keyblock ) {
2088                     KBNODE snode;
2089                     int s_selected = 0;
2090                     PKT_user_id *uid = node->pkt->pkt.user_id;
2091                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2092                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2093                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2094
2095                             s_selected =
2096                                 (uid->len == suid->len
2097                                  && !memcmp( uid->name, suid->name, uid->len));
2098                             if( s_selected )
2099                                 delete_kbnode( snode );
2100                         }
2101                         else if( s_selected
2102                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2103                             delete_kbnode( snode );
2104                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2105                             s_selected = 0;
2106                     }
2107                 }
2108             }
2109         }
2110         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2111             delete_kbnode( node );
2112         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2113             selected = 0;
2114     }
2115     commit_kbnode( &pub_keyblock );
2116     if( sec_keyblock )
2117         commit_kbnode( &sec_keyblock );
2118 }
2119
2120
2121 static int
2122 menu_delsig( KBNODE pub_keyblock )
2123 {
2124     KBNODE node;
2125     PKT_user_id *uid = NULL;
2126     int changed=0;
2127
2128     for( node = pub_keyblock; node; node = node->next ) {
2129         if( node->pkt->pkttype == PKT_USER_ID ) {
2130             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2131         }
2132         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2133            int okay, valid, selfsig, inv_sig, no_key, other_err;
2134
2135             tty_printf("uid  ");
2136             tty_print_utf8_string( uid->name, uid->len );
2137             tty_printf("\n");
2138
2139            okay = inv_sig = no_key = other_err = 0;
2140             valid = print_and_check_one_sig( pub_keyblock, node,
2141                                             &inv_sig, &no_key, &other_err,
2142                                             &selfsig, 1 );
2143
2144            if( valid ) {
2145                okay = cpr_get_answer_yes_no_quit(
2146                    "keyedit.delsig.valid",
2147                    _("Delete this good signature? (y/N/q)"));
2148
2149                /* Only update trust if we delete a good signature.
2150                   The other two cases do not affect trust. */
2151                if(okay)
2152                  update_trust=1;
2153            }
2154            else if( inv_sig || other_err )
2155                okay = cpr_get_answer_yes_no_quit(
2156                    "keyedit.delsig.invalid",
2157                    _("Delete this invalid signature? (y/N/q)"));
2158            else if( no_key )
2159                okay = cpr_get_answer_yes_no_quit(
2160                    "keyedit.delsig.unknown",
2161                    _("Delete this unknown signature? (y/N/q)"));
2162
2163             if( okay == -1 )
2164                 break;
2165            if( okay && selfsig && !cpr_get_answer_is_yes(
2166                                "keyedit.delsig.selfsig",
2167                               _("Really delete this self-signature? (y/N)") ))
2168                 okay = 0;
2169             if( okay ) {
2170                 delete_kbnode( node );
2171                 changed++;
2172             }
2173
2174         }
2175         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2176             uid = NULL;
2177     }
2178
2179     if( changed ) {
2180         commit_kbnode( &pub_keyblock );
2181         tty_printf( changed == 1? _("Deleted %d signature.\n")
2182                                 : _("Deleted %d signatures.\n"), changed );
2183     }
2184     else
2185         tty_printf( _("Nothing deleted.\n") );
2186
2187     return changed;
2188 }
2189
2190
2191 /****************
2192  * Remove some of the secondary keys
2193  */
2194 static void
2195 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2196 {
2197     KBNODE node;
2198     int selected=0;
2199
2200     for( node = pub_keyblock; node; node = node->next ) {
2201         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2202             selected = node->flag & NODFLG_SELKEY;
2203             if( selected ) {
2204                 delete_kbnode( node );
2205                 if( sec_keyblock ) {
2206                     KBNODE snode;
2207                     int s_selected = 0;
2208                     u32 ki[2];
2209
2210                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2211                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2212                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2213                             u32 ki2[2];
2214
2215                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2216                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2217                             if( s_selected )
2218                                 delete_kbnode( snode );
2219                         }
2220                         else if( s_selected
2221                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2222                             delete_kbnode( snode );
2223                         else
2224                             s_selected = 0;
2225                     }
2226                 }
2227             }
2228         }
2229         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2230             delete_kbnode( node );
2231         else
2232             selected = 0;
2233     }
2234     commit_kbnode( &pub_keyblock );
2235     if( sec_keyblock )
2236         commit_kbnode( &sec_keyblock );
2237
2238     /* No need to set update_trust here since signing keys no longer
2239        are used to certify other keys, so there is no change in trust
2240        when revoking/removing them */
2241 }
2242
2243
2244 /****************
2245  * Ask for a new revoker, do the selfsignature and put it into
2246  * both keyblocks.
2247  * Return true if there is a new revoker
2248  */
2249 static int
2250 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2251 {
2252   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2253   PKT_secret_key *sk=NULL;
2254   PKT_signature *sig=NULL;
2255   PACKET *pkt;
2256   struct revocation_key revkey;
2257   size_t fprlen;
2258   int rc;
2259
2260   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2261   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2262
2263   pk=pub_keyblock->pkt->pkt.public_key;
2264   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2265
2266   for(;;)
2267     {
2268       char *answer;
2269       u32 keyid[2];
2270       char *p;
2271       size_t n;
2272
2273       if(revoker_pk)
2274         free_public_key(revoker_pk);
2275
2276       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2277
2278       tty_printf("\n");
2279
2280       answer=cpr_get_utf8("keyedit.add_revoker",
2281                           _("Enter the user ID of the designated revoker: "));
2282       if(answer[0]=='\0' || answer[0]=='\004')
2283         goto fail;
2284
2285       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL);
2286
2287       if(rc)
2288         {
2289           log_error (_("key `%s' not found: %s\n"),answer,g10_errstr(rc));
2290           continue;
2291         }
2292
2293       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2294       if(fprlen!=20)
2295         {
2296           log_error(_("cannot appoint a PGP 2.x style key as a "
2297                       "designated revoker\n"));
2298           continue;
2299         }
2300
2301       if(cmp_public_keys(revoker_pk,pk)==0)
2302         {
2303           /* This actually causes no harm (after all, a key that
2304              designates itself as a revoker is the same as a
2305              regular key), but it's easy enough to check. */
2306           log_error(_("you cannot appoint a key as its own "
2307                       "designated revoker\n"));
2308           continue;
2309         }
2310
2311       keyid_from_pk(revoker_pk,keyid);
2312
2313       tty_printf("\npub  %4u%c/%08lX %s   ",
2314                  nbits_from_pk( revoker_pk ),
2315                  pubkey_letter( revoker_pk->pubkey_algo ),
2316                  (ulong)keyid[1], datestr_from_pk(pk) );
2317
2318       p = get_user_id( keyid, &n );
2319       tty_print_utf8_string( p, n );
2320       m_free(p);
2321       tty_printf("\n");
2322       print_fingerprint(revoker_pk,NULL,2);
2323       tty_printf("\n");
2324
2325       tty_printf("WARNING: appointing a key as a designated revoker "
2326                  "cannot be undone!\n");
2327
2328       tty_printf("\n");
2329
2330       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2331                                 "Are you sure you want to appoint this "
2332                                 "key as a designated revoker? (y/N): "))
2333         continue;
2334
2335       revkey.class=0x80;
2336       if(sensitive)
2337         revkey.class|=0x40;
2338       revkey.algid=revoker_pk->pubkey_algo;
2339       free_public_key(revoker_pk);
2340       break;
2341     }
2342
2343   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 0, 0, 0,
2344                            keygen_add_revkey,&revkey );
2345   if( rc )
2346     {
2347       log_error("signing failed: %s\n", g10_errstr(rc) );
2348       goto fail;
2349     }
2350
2351   free_secret_key(sk);
2352   sk=NULL;
2353
2354   /* insert into secret keyblock */
2355   pkt = m_alloc_clear( sizeof *pkt );
2356   pkt->pkttype = PKT_SIGNATURE;
2357   pkt->pkt.signature = copy_signature(NULL, sig);
2358   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2359
2360   /* insert into public keyblock */
2361   pkt = m_alloc_clear( sizeof *pkt );
2362   pkt->pkttype = PKT_SIGNATURE;
2363   pkt->pkt.signature = sig;
2364   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2365
2366   return 1;
2367
2368  fail:
2369   if(sk)
2370     free_secret_key(sk);
2371   if(sig)
2372     free_seckey_enc(sig);
2373   if(revoker_pk)
2374     free_public_key(revoker_pk);
2375
2376   return 0;
2377 }
2378
2379
2380 static int
2381 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
2382 {
2383     int n1, signumber, rc;
2384     u32 expiredate;
2385     int mainkey=0;
2386     PKT_secret_key *sk;    /* copy of the main sk */
2387     PKT_public_key *main_pk, *sub_pk;
2388     PKT_user_id *uid;
2389     KBNODE node;
2390     u32 keyid[2];
2391
2392     if( count_selected_keys( sec_keyblock ) ) {
2393         tty_printf(_("Please remove selections from the secret keys.\n"));
2394         return 0;
2395     }
2396
2397     n1 = count_selected_keys( pub_keyblock );
2398     if( n1 > 1 ) {
2399         tty_printf(_("Please select at most one secondary key.\n"));
2400         return 0;
2401     }
2402     else if( n1 )
2403         tty_printf(_("Changing expiration time for a secondary key.\n"));
2404     else {
2405         tty_printf(_("Changing expiration time for the primary key.\n"));
2406         mainkey=1;
2407     }
2408
2409     expiredate = ask_expiredate();
2410     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2411     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2412
2413     /* Now we can actually change the self signature(s) */
2414     main_pk = sub_pk = NULL;
2415     uid = NULL;
2416     signumber = 0;
2417     for( node=pub_keyblock; node; node = node->next ) {
2418         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2419             main_pk = node->pkt->pkt.public_key;
2420             keyid_from_pk( main_pk, keyid );
2421             main_pk->expiredate = expiredate;
2422         }
2423         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2424                  && (node->flag & NODFLG_SELKEY ) ) {
2425             sub_pk = node->pkt->pkt.public_key;
2426             sub_pk->expiredate = expiredate;
2427         }
2428         else if( node->pkt->pkttype == PKT_USER_ID )
2429             uid = node->pkt->pkt.user_id;
2430         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
2431                  && ( mainkey || sub_pk ) ) {
2432             PKT_signature *sig = node->pkt->pkt.signature;
2433             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2434                 && (    (mainkey && uid && (sig->sig_class&~3) == 0x10)
2435                      || (!mainkey && sig->sig_class == 0x18)  ) ) {
2436                 /* this is a selfsignature which is to be replaced */
2437                 PKT_signature *newsig;
2438                 PACKET *newpkt;
2439                 KBNODE sn;
2440                 int signumber2 = 0;
2441
2442                 signumber++;
2443
2444                 if( (mainkey && main_pk->version < 4)
2445                     || (!mainkey && sub_pk->version < 4 ) ) {
2446                     log_info(_(
2447                         "You can't change the expiration date of a v3 key\n"));
2448                     free_secret_key( sk );
2449                     return 0;
2450                 }
2451
2452                 /* find the corresponding secret self-signature */
2453                 for( sn=sec_keyblock; sn; sn = sn->next ) {
2454                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
2455                         PKT_signature *b = sn->pkt->pkt.signature;
2456                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
2457                             && sig->sig_class == b->sig_class
2458                             && ++signumber2 == signumber )
2459                             break;
2460                     }
2461                 }
2462                 if( !sn )
2463                     log_info(_("No corresponding signature in secret ring\n"));
2464
2465                 /* create new self signature */
2466                 if( mainkey )
2467                     rc = make_keysig_packet( &newsig, main_pk, uid, NULL,
2468                                              sk, 0x13, 0, 0, 0, 0,
2469                                              keygen_add_std_prefs, main_pk );
2470                 else
2471                     rc = make_keysig_packet( &newsig, main_pk, NULL, sub_pk,
2472                                              sk, 0x18, 0, 0, 0, 0,
2473                                              keygen_add_key_expire, sub_pk );
2474                 if( rc ) {
2475                     log_error("make_keysig_packet failed: %s\n",
2476                                                     g10_errstr(rc));
2477                     free_secret_key( sk );
2478                     return 0;
2479                 }
2480                 /* replace the packet */
2481                 newpkt = m_alloc_clear( sizeof *newpkt );
2482                 newpkt->pkttype = PKT_SIGNATURE;
2483                 newpkt->pkt.signature = newsig;
2484                 free_packet( node->pkt );
2485                 m_free( node->pkt );
2486                 node->pkt = newpkt;
2487                 if( sn ) {
2488                     newpkt = m_alloc_clear( sizeof *newpkt );
2489                     newpkt->pkttype = PKT_SIGNATURE;
2490                     newpkt->pkt.signature = copy_signature( NULL, newsig );
2491                     free_packet( sn->pkt );
2492                     m_free( sn->pkt );
2493                     sn->pkt = newpkt;
2494                 }
2495                 sub_pk = NULL;
2496             }
2497         }
2498     }
2499
2500     free_secret_key( sk );
2501     update_trust=1;
2502     return 1;
2503 }
2504
2505 static int
2506 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
2507 {
2508     byte buf[1];
2509
2510     /* first clear all primary uid flags so that we are sure none are
2511      * lingering around */
2512     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
2513     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
2514
2515     /* if opaque is set,we want to set the primary id */
2516     if (opaque) { 
2517         buf[0] = 1;
2518         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
2519     }
2520
2521     return 0;
2522 }
2523
2524
2525 /*
2526  * Set the primary uid flag for the selected UID.  We will also reset
2527  * all other primary uid flags.  For this to work with have to update
2528  * all the signature timestamps.  If we would do this with the current
2529  * time, we lose quite a lot of information, so we use a a kludge to
2530  * do this: Just increment the timestamp by one second which is
2531  * sufficient to updated a signature during import.
2532  */
2533 static int
2534 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
2535 {
2536     PKT_secret_key *sk;    /* copy of the main sk */
2537     PKT_public_key *main_pk;
2538     PKT_user_id *uid;
2539     KBNODE node;
2540     u32 keyid[2];
2541     int selected;
2542     int attribute = 0;
2543     int modified = 0;
2544
2545     if ( count_selected_uids (pub_keyblock) != 1 ) {
2546         tty_printf(_("Please select exactly one user ID.\n"));
2547         return 0;
2548     }
2549
2550     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2551     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2552
2553     /* Now we can actually change the self signature(s) */
2554     main_pk = NULL;
2555     uid = NULL;
2556     selected = 0;
2557
2558     /* Is our selected uid an attribute packet? */
2559     for ( node=pub_keyblock; node; node = node->next )
2560       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
2561         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
2562
2563     for ( node=pub_keyblock; node; node = node->next ) {
2564         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2565             break; /* ready */
2566
2567         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2568             main_pk = node->pkt->pkt.public_key;
2569             keyid_from_pk( main_pk, keyid );
2570         }
2571         else if ( node->pkt->pkttype == PKT_USER_ID ) {
2572             uid = node->pkt->pkt.user_id;
2573             selected = node->flag & NODFLG_SELUID;
2574         }
2575         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2576             PKT_signature *sig = node->pkt->pkt.signature;
2577             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2578                 && (uid && (sig->sig_class&~3) == 0x10)
2579                 && attribute == (uid->attrib_data!=NULL)) {
2580               if(sig->version < 4) {
2581                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
2582
2583                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
2584                          user);
2585                 m_free(user);
2586               }
2587               else {
2588                 /* This is a selfsignature which is to be replaced.
2589                    We can just ignore v3 signatures because they are
2590                    not able to carry the primary ID flag.  We also
2591                    ignore self-sigs on user IDs that are not of the
2592                    same type that we are making primary.  That is, if
2593                    we are making a user ID primary, we alter user IDs.
2594                    If we are making an attribute packet primary, we
2595                    alter attribute packets. */
2596
2597                 /* FIXME: We must make sure that we only have one
2598                    self-signature per user ID here (not counting
2599                    revocations) */
2600                 PKT_signature *newsig;
2601                 PACKET *newpkt;
2602                 const byte *p;
2603                 int action;
2604
2605                 /* see whether this signature has the primary UID flag */
2606                 p = parse_sig_subpkt (sig->hashed,
2607                                       SIGSUBPKT_PRIMARY_UID, NULL );
2608                 if ( !p )
2609                     p = parse_sig_subpkt (sig->unhashed,
2610                                           SIGSUBPKT_PRIMARY_UID, NULL );
2611                 if ( p && *p ) /* yes */
2612                     action = selected? 0 : -1;
2613                 else /* no */
2614                     action = selected? 1 : 0;
2615
2616                 if (action) {
2617                     int rc = update_keysig_packet (&newsig, sig,
2618                                                main_pk, uid, 
2619                                                sk,
2620                                                change_primary_uid_cb,
2621                                                action > 0? "x":NULL );
2622                     if( rc ) {
2623                         log_error ("update_keysig_packet failed: %s\n",
2624                                    g10_errstr(rc));
2625                         free_secret_key( sk );
2626                         return 0;
2627                     }
2628                     /* replace the packet */
2629                     newpkt = m_alloc_clear( sizeof *newpkt );
2630                     newpkt->pkttype = PKT_SIGNATURE;
2631                     newpkt->pkt.signature = newsig;
2632                     free_packet( node->pkt );
2633                     m_free( node->pkt );
2634                     node->pkt = newpkt;
2635                     modified = 1;
2636                 }
2637               }
2638             }
2639         }
2640     }
2641
2642     free_secret_key( sk );
2643     return modified;
2644 }
2645
2646
2647 /* 
2648  * Set preferences to new values for the selected user IDs
2649  */
2650 static int
2651 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
2652 {
2653     PKT_secret_key *sk;    /* copy of the main sk */
2654     PKT_public_key *main_pk;
2655     PKT_user_id *uid;
2656     KBNODE node;
2657     u32 keyid[2];
2658     int selected, select_all;
2659     int modified = 0;
2660
2661     select_all = !count_selected_uids (pub_keyblock);
2662
2663     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2664     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2665
2666     /* Now we can actually change the self signature(s) */
2667     main_pk = NULL;
2668     uid = NULL;
2669     selected = 0;
2670     for ( node=pub_keyblock; node; node = node->next ) {
2671         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2672             break; /* ready */
2673
2674         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2675             main_pk = node->pkt->pkt.public_key;
2676             keyid_from_pk( main_pk, keyid );
2677         }
2678         else if ( node->pkt->pkttype == PKT_USER_ID ) {
2679             uid = node->pkt->pkt.user_id;
2680             selected = select_all || (node->flag & NODFLG_SELUID);
2681         }
2682         else if ( main_pk && uid && selected
2683                   && node->pkt->pkttype == PKT_SIGNATURE ) {
2684             PKT_signature *sig = node->pkt->pkt.signature;
2685             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2686                  && (uid && (sig->sig_class&~3) == 0x10) ) {
2687               if( sig->version < 4 ) {
2688                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
2689
2690                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
2691                          user);
2692                 m_free(user);
2693               }
2694               else {
2695                 /* This is a selfsignature which is to be replaced 
2696                  * We have to ignore v3 signatures because they are
2697                  * not able to carry the preferences */
2698                 PKT_signature *newsig;
2699                 PACKET *newpkt;
2700                 int rc;
2701
2702                 rc = update_keysig_packet (&newsig, sig,
2703                                            main_pk, uid, 
2704                                            sk,
2705                                            keygen_upd_std_prefs,
2706                                            NULL );
2707                 if( rc ) {
2708                     log_error ("update_keysig_packet failed: %s\n",
2709                                g10_errstr(rc));
2710                     free_secret_key( sk );
2711                     return 0;
2712                 }
2713                 /* replace the packet */
2714                 newpkt = m_alloc_clear( sizeof *newpkt );
2715                 newpkt->pkttype = PKT_SIGNATURE;
2716                 newpkt->pkt.signature = newsig;
2717                 free_packet( node->pkt );
2718                 m_free( node->pkt );
2719                 node->pkt = newpkt;
2720                 modified = 1;
2721               }
2722             }
2723         }
2724     }
2725     
2726     free_secret_key( sk );
2727     return modified;
2728 }
2729
2730
2731 /****************
2732  * Select one user id or remove all selection if index is 0.
2733  * Returns: True if the selection changed;
2734  */
2735 static int
2736 menu_select_uid( KBNODE keyblock, int idx )
2737 {
2738     KBNODE node;
2739     int i;
2740
2741     /* first check that the index is valid */
2742     if( idx ) {
2743         for( i=0, node = keyblock; node; node = node->next ) {
2744             if( node->pkt->pkttype == PKT_USER_ID ) {
2745                 if( ++i == idx )
2746                     break;
2747             }
2748         }
2749         if( !node ) {
2750             tty_printf(_("No user ID with index %d\n"), idx );
2751             return 0;
2752         }
2753     }
2754     else { /* reset all */
2755         for( i=0, node = keyblock; node; node = node->next ) {
2756             if( node->pkt->pkttype == PKT_USER_ID )
2757                 node->flag &= ~NODFLG_SELUID;
2758         }
2759         return 1;
2760     }
2761     /* and toggle the new index */
2762     for( i=0, node = keyblock; node; node = node->next ) {
2763         if( node->pkt->pkttype == PKT_USER_ID ) {
2764             if( ++i == idx ) {
2765                 if( (node->flag & NODFLG_SELUID) )
2766                     node->flag &= ~NODFLG_SELUID;
2767                 else
2768                     node->flag |= NODFLG_SELUID;
2769             }
2770         }
2771     }
2772
2773     return 1;
2774 }
2775
2776 /****************
2777  * Select secondary keys
2778  * Returns: True if the selection changed;
2779  */
2780 static int
2781 menu_select_key( KBNODE keyblock, int idx )
2782 {
2783     KBNODE node;
2784     int i;
2785
2786     /* first check that the index is valid */
2787     if( idx ) {
2788         for( i=0, node = keyblock; node; node = node->next ) {
2789             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2790                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2791                 if( ++i == idx )
2792                     break;
2793             }
2794         }
2795         if( !node ) {
2796             tty_printf(_("No secondary key with index %d\n"), idx );
2797             return 0;
2798         }
2799     }
2800     else { /* reset all */
2801         for( i=0, node = keyblock; node; node = node->next ) {
2802             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2803                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
2804                 node->flag &= ~NODFLG_SELKEY;
2805         }
2806         return 1;
2807     }
2808     /* and set the new index */
2809     for( i=0, node = keyblock; node; node = node->next ) {
2810         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2811             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2812             if( ++i == idx ) {
2813                 if( (node->flag & NODFLG_SELKEY) )
2814                     node->flag &= ~NODFLG_SELKEY;
2815                 else
2816                     node->flag |= NODFLG_SELKEY;
2817             }
2818         }
2819     }
2820
2821     return 1;
2822 }
2823
2824
2825 static int
2826 count_uids_with_flag( KBNODE keyblock, unsigned flag )
2827 {
2828     KBNODE node;
2829     int i=0;
2830
2831     for( node = keyblock; node; node = node->next )
2832         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
2833             i++;
2834     return i;
2835 }
2836
2837 static int
2838 count_keys_with_flag( KBNODE keyblock, unsigned flag )
2839 {
2840     KBNODE node;
2841     int i=0;
2842
2843     for( node = keyblock; node; node = node->next )
2844         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2845               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
2846             && (node->flag & flag) )
2847             i++;
2848     return i;
2849 }
2850
2851 static int
2852 count_uids( KBNODE keyblock )
2853 {
2854     KBNODE node;
2855     int i=0;
2856
2857     for( node = keyblock; node; node = node->next )
2858         if( node->pkt->pkttype == PKT_USER_ID )
2859             i++;
2860     return i;
2861 }
2862
2863
2864 /****************
2865  * Returns true if there is at least one selected user id
2866  */
2867 static int
2868 count_selected_uids( KBNODE keyblock )
2869 {
2870     return count_uids_with_flag( keyblock, NODFLG_SELUID);
2871 }
2872
2873 static int
2874 count_selected_keys( KBNODE keyblock )
2875 {
2876     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
2877 }
2878
2879 /* returns how many real (i.e. not attribute) uids are unmarked */
2880 static int
2881 real_uids_left( KBNODE keyblock )
2882 {
2883   KBNODE node;
2884   int real=0;
2885
2886   for(node=keyblock;node;node=node->next)
2887     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
2888        !node->pkt->pkt.user_id->attrib_data)
2889       real++;
2890
2891   return real;
2892 }
2893
2894 /*
2895  * Ask whether the signature should be revoked.  If the user commits this,
2896  * flag bit MARK_A is set on the signature and the user ID.
2897  */
2898 static void
2899 ask_revoke_sig( KBNODE keyblock, KBNODE node )
2900 {
2901     int doit=0;
2902     PKT_signature *sig = node->pkt->pkt.signature;
2903     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
2904
2905     if( !unode ) {
2906         log_error("Oops: no user ID for signature\n");
2907         return;
2908     }
2909
2910     tty_printf(_("user ID: \""));
2911     tty_print_utf8_string( unode->pkt->pkt.user_id->name,
2912                            unode->pkt->pkt.user_id->len );
2913
2914     if(sig->flags.exportable)
2915       tty_printf(_("\"\nsigned with your key %08lX at %s\n"),
2916                  (ulong)sig->keyid[1], datestr_from_sig(sig) );
2917     else
2918       tty_printf(_("\"\nlocally signed with your key %08lX at %s\n"),
2919                  (ulong)sig->keyid[1], datestr_from_sig(sig) );
2920
2921     if(sig->flags.expired)
2922       {
2923         tty_printf(_("This signature expired on %s.\n"),
2924                    expirestr_from_sig(sig));
2925         /* Use a different question so we can have different help text */
2926         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
2927                         _("Are you sure you still want to revoke it? (y/N) "));
2928       }
2929     else
2930       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
2931               _("Create a revocation certificate for this signature? (y/N) "));
2932
2933     if(doit) {
2934       node->flag |= NODFLG_MARK_A;
2935       unode->flag |= NODFLG_MARK_A;
2936     }
2937 }
2938
2939 /****************
2940  * Display all user ids of the current public key together with signatures
2941  * done by one of our keys.  Then walk over all this sigs and ask the user
2942  * whether he wants to revoke this signature.
2943  * Return: True when the keyblock has changed.
2944  */
2945 static int
2946 menu_revsig( KBNODE keyblock )
2947 {
2948     PKT_signature *sig;
2949     PKT_public_key *primary_pk;
2950     KBNODE node;
2951     int changed = 0;
2952     int rc, any, skip=1, all=!count_selected_uids(keyblock);
2953     struct revocation_reason_info *reason = NULL;
2954
2955     /* FIXME: detect duplicates here  */
2956     tty_printf(_("You have signed these user IDs:\n"));
2957     for( node = keyblock; node; node = node->next ) {
2958         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
2959         if( node->pkt->pkttype == PKT_USER_ID ) {
2960             if( node->flag&NODFLG_SELUID || all ) {
2961               PKT_user_id *uid = node->pkt->pkt.user_id;
2962               /* Hmmm: Should we show only UIDs with a signature? */
2963               tty_printf("     ");
2964               tty_print_utf8_string( uid->name, uid->len );
2965               tty_printf("\n");
2966               skip=0;
2967             }
2968             else
2969               skip=1;
2970         }
2971         else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
2972                 && ((sig = node->pkt->pkt.signature),
2973                      !seckey_available(sig->keyid)  ) ) {
2974             if( (sig->sig_class&~3) == 0x10 ) {
2975                 tty_printf(_("   signed by %08lX at %s%s%s\n"),
2976                            (ulong)sig->keyid[1], datestr_from_sig(sig),
2977                            sig->flags.exportable?"":" (non-exportable)",
2978                            sig->flags.revocable?"":" (non-revocable)");
2979                 if(sig->flags.revocable)
2980                   node->flag |= NODFLG_SELSIG;
2981             }
2982             else if( sig->sig_class == 0x30 ) {
2983                 tty_printf(_("   revoked by %08lX at %s\n"),
2984                             (ulong)sig->keyid[1], datestr_from_sig(sig) );
2985             }
2986         }
2987     }
2988
2989     /* ask */
2990     for( node = keyblock; node; node = node->next ) {
2991         if( !(node->flag & NODFLG_SELSIG) )
2992             continue;
2993         ask_revoke_sig( keyblock, node );
2994     }
2995
2996     /* present selected */
2997     any = 0;
2998     for( node = keyblock; node; node = node->next ) {
2999         if( !(node->flag & NODFLG_MARK_A) )
3000             continue;
3001         if( !any ) {
3002             any = 1;
3003             tty_printf(_("You are about to revoke these signatures:\n"));
3004         }
3005         if( node->pkt->pkttype == PKT_USER_ID ) {
3006             PKT_user_id *uid = node->pkt->pkt.user_id;
3007             tty_printf("     ");
3008             tty_print_utf8_string( uid->name, uid->len );
3009             tty_printf("\n");
3010         }
3011         else if( node->pkt->pkttype == PKT_SIGNATURE ) {
3012             sig = node->pkt->pkt.signature;
3013             tty_printf(_("   signed by %08lX at %s%s\n"),
3014                        (ulong)sig->keyid[1], datestr_from_sig(sig),
3015                        sig->flags.exportable?"":_(" (non-exportable)") );
3016         }
3017     }
3018     if( !any )
3019         return 0; /* none selected */
3020
3021     if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
3022          _("Really create the revocation certificates? (y/N) ")) )
3023         return 0; /* forget it */
3024
3025     reason = ask_revocation_reason( 0, 1, 0 );
3026     if( !reason ) { /* user decided to cancel */
3027         return 0;
3028     }
3029
3030     /* now we can sign the user ids */
3031   reloop: /* (must use this, because we are modifing the list) */
3032     primary_pk = keyblock->pkt->pkt.public_key;
3033     for( node=keyblock; node; node = node->next ) {
3034         KBNODE unode;
3035         PACKET *pkt;
3036         struct sign_attrib attrib;
3037         PKT_secret_key *sk;
3038
3039         if( !(node->flag & NODFLG_MARK_A)
3040             || node->pkt->pkttype != PKT_SIGNATURE )
3041             continue;
3042         unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3043         assert( unode ); /* we already checked this */
3044
3045         memset( &attrib, 0, sizeof attrib );
3046         attrib.reason = reason;
3047         attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
3048
3049         node->flag &= ~NODFLG_MARK_A;
3050         sk = m_alloc_secure_clear( sizeof *sk );
3051         if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
3052             log_info(_("no secret key\n"));
3053             continue;
3054         }
3055         rc = make_keysig_packet( &sig, primary_pk,
3056                                        unode->pkt->pkt.user_id,
3057                                        NULL,
3058                                        sk,
3059                                        0x30, 0, 0, 0, 0,
3060                                        sign_mk_attrib,
3061                                        &attrib );
3062         free_secret_key(sk);
3063         if( rc ) {
3064             log_error(_("signing failed: %s\n"), g10_errstr(rc));
3065             release_revocation_reason_info( reason );
3066             return changed;
3067         }
3068         changed = 1; /* we changed the keyblock */
3069         update_trust = 1;
3070         /* Are we revoking our own uid? */
3071         if(primary_pk->keyid[0]==sig->keyid[0] &&
3072            primary_pk->keyid[1]==sig->keyid[1])
3073           unode->pkt->pkt.user_id->is_revoked=1;
3074         pkt = m_alloc_clear( sizeof *pkt );
3075         pkt->pkttype = PKT_SIGNATURE;
3076         pkt->pkt.signature = sig;
3077         insert_kbnode( unode, new_kbnode(pkt), 0 );
3078         goto reloop;
3079     }
3080
3081     release_revocation_reason_info( reason );
3082     return changed;
3083 }
3084
3085 /****************
3086  * Revoke some of the secondary keys.
3087  * Hmmm: Should we add a revocation to the secret keyring too?
3088  *       Does its all make sense to duplicate most of the information?
3089  */
3090 static int
3091 menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3092 {
3093     PKT_public_key *mainpk;
3094     KBNODE node;
3095     int changed = 0;
3096     int rc;
3097     struct revocation_reason_info *reason = NULL;
3098
3099     reason = ask_revocation_reason( 1, 0, 0 );
3100     if( !reason ) { /* user decided to cancel */
3101         return 0;
3102     }
3103
3104
3105   reloop: /* (better this way because we are modifing the keyring) */
3106     mainpk = pub_keyblock->pkt->pkt.public_key;
3107     for( node = pub_keyblock; node; node = node->next ) {
3108         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3109             && (node->flag & NODFLG_SELKEY) ) {
3110             PACKET *pkt;
3111             PKT_signature *sig;
3112             PKT_secret_key *sk;
3113             PKT_public_key *subpk = node->pkt->pkt.public_key;
3114             struct sign_attrib attrib;
3115
3116             memset( &attrib, 0, sizeof attrib );
3117             attrib.reason = reason;
3118
3119             node->flag &= ~NODFLG_SELKEY;
3120             sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
3121             rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
3122                                      0x28, 0, 0, 0, 0,
3123                                      sign_mk_attrib, &attrib );
3124             free_secret_key(sk);
3125             if( rc ) {
3126                 log_error(_("signing failed: %s\n"), g10_errstr(rc));
3127                 release_revocation_reason_info( reason );
3128                 return changed;
3129             }
3130             changed = 1; /* we changed the keyblock */
3131
3132             pkt = m_alloc_clear( sizeof *pkt );
3133             pkt->pkttype = PKT_SIGNATURE;
3134             pkt->pkt.signature = sig;
3135             insert_kbnode( node, new_kbnode(pkt), 0 );
3136             goto reloop;
3137         }
3138     }
3139     commit_kbnode( &pub_keyblock );
3140     /*commit_kbnode( &sec_keyblock );*/
3141
3142     /* No need to set update_trust here since signing keys no longer
3143        are used to certify other keys, so there is no change in trust
3144        when revoking/removing them */
3145
3146     release_revocation_reason_info( reason );
3147     return changed;
3148 }
3149
3150
3151 static int
3152 enable_disable_key( KBNODE keyblock, int disable )
3153 {
3154     PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
3155                             ->pkt->pkt.public_key;
3156     unsigned int trust, newtrust;
3157
3158     trust = newtrust = get_ownertrust (pk);
3159     newtrust &= ~TRUST_FLAG_DISABLED;
3160     if( disable )
3161         newtrust |= TRUST_FLAG_DISABLED;
3162     if( trust == newtrust )
3163         return 0; /* already in that state */
3164     update_ownertrust(pk, newtrust );
3165     return 0;
3166 }
3167
3168
3169 static void
3170 menu_showphoto( KBNODE keyblock )
3171 {
3172   KBNODE node;
3173   int select_all = !count_selected_uids(keyblock);
3174   int count=0;
3175   PKT_public_key *pk=NULL;
3176   u32 keyid[2];
3177
3178   /* Look for the public key first.  We have to be really, really,
3179      explicit as to which photo this is, and what key it is a UID on
3180      since people may want to sign it. */
3181
3182   for( node = keyblock; node; node = node->next )
3183     {
3184       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
3185         {
3186           pk = node->pkt->pkt.public_key;
3187           keyid_from_pk(pk, keyid);
3188         }
3189       else if( node->pkt->pkttype == PKT_USER_ID )
3190         {
3191           PKT_user_id *uid = node->pkt->pkt.user_id;
3192           count++;
3193
3194           if((select_all || (node->flag & NODFLG_SELUID)) &&
3195              uid->attribs!=NULL)
3196             {
3197               int i;
3198
3199               for(i=0;i<uid->numattribs;i++)
3200                 {
3201                   byte type;
3202                   u32 size;
3203
3204                   if(uid->attribs[i].type==ATTRIB_IMAGE &&
3205                      parse_image_header(&uid->attribs[i],&type,&size))
3206                     {
3207                       tty_printf(_("Displaying %s photo ID of size %ld for "
3208                                    "key 0x%08lX (uid %d)\n"),
3209                                  image_type_to_string(type,1),
3210                                  (ulong)size,(ulong)keyid[1],count);
3211                       show_photos(&uid->attribs[i],1,pk,NULL);
3212                     }
3213                 }
3214             }
3215         }
3216     }
3217 }