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