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