8ab2276be5186bed4096c21ea9200a2f03706e84
[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
1171     { NULL, cmdNONE } };
1172     enum cmdids cmd = 0;
1173     int rc = 0;
1174     KBNODE keyblock = NULL;
1175     KEYDB_HANDLE kdbhd = NULL;
1176     KBNODE sec_keyblock = NULL;
1177     KEYDB_HANDLE sec_kdbhd = NULL;
1178     KBNODE cur_keyblock;
1179     char *answer = NULL;
1180     int redisplay = 1;
1181     int modified = 0;
1182     int sec_modified = 0;
1183     int toggle;
1184     int have_commands = !!commands;
1185
1186     if ( opt.command_fd != -1 )
1187         ;
1188     else if( opt.batch && !have_commands  ) {
1189         log_error(_("can't do that in batchmode\n"));
1190         goto leave;
1191     }
1192
1193     /* get the public key */
1194     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1195     if( rc )
1196         goto leave;
1197     if( fix_keyblock( keyblock ) )
1198         modified++;
1199     if( collapse_uids( &keyblock ) )
1200         modified++;
1201     reorder_keyblock(keyblock);
1202
1203     if(seckey_check)
1204       {/* see whether we have a matching secret key */
1205         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1206
1207         sec_kdbhd = keydb_new (1);
1208         {
1209             byte afp[MAX_FINGERPRINT_LEN];
1210             size_t an;
1211
1212             fingerprint_from_pk (pk, afp, &an);
1213             while (an < MAX_FINGERPRINT_LEN) 
1214                 afp[an++] = 0;
1215             rc = keydb_search_fpr (sec_kdbhd, afp);
1216         }
1217         if (!rc) {
1218             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1219             if (rc) {
1220                 log_error (_("error reading secret keyblock `%s': %s\n"),
1221                                                 username, g10_errstr(rc));
1222             }
1223             else {
1224                 merge_keys_and_selfsig( sec_keyblock );
1225                 if( fix_keyblock( sec_keyblock ) )
1226                     sec_modified++;
1227             }
1228         }
1229
1230         if (rc) {
1231             sec_keyblock = NULL;
1232             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1233             rc = 0;
1234         }
1235
1236         if( sec_keyblock && !quiet )
1237           tty_printf(_("Secret key is available.\n"));
1238     }
1239
1240     toggle = 0;
1241     cur_keyblock = keyblock;
1242     for(;;) { /* main loop */
1243         int i, arg_number, photo;
1244         const char *arg_string = "";
1245         char *p;
1246         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1247
1248         tty_printf("\n");
1249         if( redisplay && !quiet )
1250           {
1251             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1252             tty_printf("\n");
1253             redisplay = 0;
1254           }
1255         do {
1256             m_free(answer);
1257             if( have_commands ) {
1258                 if( commands ) {
1259                     answer = m_strdup( commands->d );
1260                     commands = commands->next;
1261                 }
1262                 else if( opt.batch ) {
1263                     answer = m_strdup("quit");
1264                 }
1265                 else
1266                     have_commands = 0;
1267             }
1268             if( !have_commands ) {
1269                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1270                 cpr_kill_prompt();
1271             }
1272             trim_spaces(answer);
1273         } while( *answer == '#' );
1274
1275         arg_number = 0; /* Yes, here is the init which egcc complains about */
1276         photo = 0; /* This too */
1277         if( !*answer )
1278             cmd = cmdLIST;
1279         else if( *answer == CONTROL_D )
1280             cmd = cmdQUIT;
1281         else if( digitp(answer ) ) {
1282             cmd = cmdSELUID;
1283             arg_number = atoi(answer);
1284         }
1285         else {
1286             if( (p=strchr(answer,' ')) ) {
1287                 *p++ = 0;
1288                 trim_spaces(answer);
1289                 trim_spaces(p);
1290                 arg_number = atoi(p);
1291                 arg_string = p;
1292             }
1293
1294             for(i=0; cmds[i].name; i++ ) {
1295                 if( !ascii_strcasecmp( answer, cmds[i].name ) )
1296                     break;
1297             }
1298             if( cmds[i].need_sk && !sec_keyblock ) {
1299                 tty_printf(_("Need the secret key to do this.\n"));
1300                 cmd = cmdNOP;
1301             }
1302             else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
1303                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1304                 cmd = cmdNOP;
1305             }
1306             else
1307                 cmd = cmds[i].id;
1308         }
1309         switch( cmd )  {
1310           case cmdHELP:
1311             for(i=0; cmds[i].name; i++ ) {
1312               if( cmds[i].need_sk && !sec_keyblock )
1313                 ; /* skip if we do not have the secret key */
1314               else if( cmds[i].desc )
1315                 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1316             }
1317             break;
1318
1319           case cmdLIST:
1320             redisplay = 1;
1321             break;
1322
1323           case cmdFPR:
1324             show_key_and_fingerprint( keyblock );
1325             break;
1326
1327           case cmdSELUID:
1328             if( menu_select_uid( cur_keyblock, arg_number ) )
1329                 redisplay = 1;
1330             break;
1331
1332           case cmdSELKEY:
1333             if( menu_select_key( cur_keyblock, arg_number ) )
1334                 redisplay = 1;
1335             break;
1336
1337           case cmdCHECK:
1338             /* we can only do this with the public key becuase the
1339              * check functions can't cope with secret keys and it
1340              * is questionable whether this would make sense at all */
1341             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1342             break;
1343
1344           case cmdSIGN: /* sign (only the public key) */
1345           case cmdLSIGN: /* sign (only the public key) */
1346           case cmdNRSIGN: /* sign (only the public key) */
1347           case cmdNRLSIGN: /* sign (only the public key) */
1348           case cmdTSIGN:
1349             if( pk->is_revoked )
1350               {
1351                 tty_printf(_("Key is revoked."));
1352
1353                 if(opt.expert)
1354                   {
1355                     tty_printf("  ");
1356                     if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1357                                               _("Are you sure you still want "
1358                                                 "to sign it? (y/N) ")))
1359                       break;
1360                   }
1361                 else
1362                   {
1363                     tty_printf(_("  Unable to sign.\n"));
1364                     break;
1365                   }
1366               }
1367
1368             if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) {
1369                 if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1370                                            _("Really sign all user IDs? ")) ) {
1371                     tty_printf(_("Hint: Select the user IDs to sign\n"));
1372                     break;
1373                 }
1374             }
1375
1376             sign_uids( keyblock, locusr, &modified,
1377                        (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
1378                        (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
1379                        (cmd == cmdTSIGN));
1380             break;
1381
1382           case cmdDEBUG:
1383             dump_kbnode( cur_keyblock );
1384             break;
1385
1386           case cmdTOGGLE:
1387             toggle = !toggle;
1388             cur_keyblock = toggle? sec_keyblock : keyblock;
1389             redisplay = 1;
1390             break;
1391
1392           case cmdADDPHOTO:
1393             if (RFC2440 || RFC1991 || PGP2)
1394               {
1395                 tty_printf(
1396                    _("This command is not allowed while in %s mode.\n"),
1397                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1398                 break;
1399               }
1400             photo=1;
1401             /* fall through */
1402
1403           case cmdADDUID:
1404             if( menu_adduid( keyblock, sec_keyblock, photo ) )
1405               {
1406                 update_trust = 1;
1407                 redisplay = 1;
1408                 sec_modified = modified = 1;
1409                 merge_keys_and_selfsig( sec_keyblock );
1410                 merge_keys_and_selfsig( keyblock );
1411               }
1412             break;
1413
1414           case cmdDELUID: {
1415                 int n1;
1416
1417                 if( !(n1=count_selected_uids(keyblock)) )
1418                     tty_printf(_("You must select at least one user ID.\n"));
1419                 else if( real_uids_left(keyblock) < 1 )
1420                     tty_printf(_("You can't delete the last user ID!\n"));
1421                 else if( cpr_get_answer_is_yes(
1422                             "keyedit.remove.uid.okay",
1423                         n1 > 1? _("Really remove all selected user IDs? ")
1424                               : _("Really remove this user ID? ")
1425                        ) ) {
1426                     menu_deluid( keyblock, sec_keyblock );
1427                     redisplay = 1;
1428                     modified = 1;
1429                     if( sec_keyblock )
1430                        sec_modified = 1;
1431                 }
1432             }
1433             break;
1434
1435           case cmdDELSIG: {
1436                 int n1;
1437
1438                 if( !(n1=count_selected_uids(keyblock)) )
1439                     tty_printf(_("You must select at least one user ID.\n"));
1440                 else if( menu_delsig( keyblock ) ) {
1441                     /* no redisplay here, because it may scroll away some
1442                      * status output of delsig */
1443                     modified = 1;
1444                 }
1445             }
1446             break;
1447
1448           case cmdADDKEY:
1449             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1450                 redisplay = 1;
1451                 sec_modified = modified = 1;
1452                 merge_keys_and_selfsig( sec_keyblock );
1453                 merge_keys_and_selfsig( keyblock );
1454             }
1455             break;
1456
1457
1458           case cmdDELKEY: {
1459                 int n1;
1460
1461                 if( !(n1=count_selected_keys( keyblock )) )
1462                     tty_printf(_("You must select at least one key.\n"));
1463                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1464                        n1 > 1?
1465                         _("Do you really want to delete the selected keys? "):
1466                         _("Do you really want to delete this key? ")
1467                        ))
1468                     ;
1469                 else {
1470                     menu_delkey( keyblock, sec_keyblock );
1471                     redisplay = 1;
1472                     modified = 1;
1473                     if( sec_keyblock )
1474                        sec_modified = 1;
1475                 }
1476             }
1477             break;
1478
1479           case cmdADDREVOKER:
1480             {
1481               int sensitive=0;
1482
1483               if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1484                 sensitive=1;
1485               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1486                 redisplay = 1;
1487                 sec_modified = modified = 1;
1488                 merge_keys_and_selfsig( sec_keyblock );
1489                 merge_keys_and_selfsig( keyblock );
1490               }
1491             }
1492             break;
1493
1494           case cmdREVUID: {
1495                 int n1;
1496
1497                 if( !(n1=count_selected_uids(keyblock)) )
1498                     tty_printf(_("You must select at least one user ID.\n"));
1499                 else if( cpr_get_answer_is_yes(
1500                             "keyedit.revoke.uid.okay",
1501                         n1 > 1? _("Really revoke all selected user IDs? ")
1502                               : _("Really revoke this user ID? ")
1503                        ) ) {
1504                   if(menu_revuid(keyblock,sec_keyblock))
1505                     {
1506                       modified=1;
1507                       redisplay=1;
1508                     }
1509                 }
1510             }
1511             break;
1512
1513           case cmdREVKEY: {
1514                 int n1;
1515
1516                 if( !(n1=count_selected_keys( keyblock )) )
1517                     tty_printf(_("You must select at least one key.\n"));
1518                 else if( sec_keyblock && !cpr_get_answer_is_yes(
1519                             "keyedit.revoke.subkey.okay",
1520                        n1 > 1?
1521                         _("Do you really want to revoke the selected keys? "):
1522                         _("Do you really want to revoke this key? ")
1523                        ))
1524                     ;
1525                 else {
1526                     if( menu_revkey( keyblock, sec_keyblock ) ) {
1527                         modified = 1;
1528                         /*sec_modified = 1;*/
1529                     }
1530                     redisplay = 1;
1531                 }
1532             }
1533             break;
1534
1535           case cmdEXPIRE:
1536             if( menu_expire( keyblock, sec_keyblock ) ) {
1537                 merge_keys_and_selfsig( sec_keyblock );
1538                 merge_keys_and_selfsig( keyblock );
1539                 sec_modified = 1;
1540                 modified = 1;
1541                 redisplay = 1;
1542             }
1543             break;
1544
1545           case cmdPRIMARY:
1546             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1547                 merge_keys_and_selfsig( keyblock );
1548                 modified = 1;
1549                 redisplay = 1;
1550             }
1551             break;
1552
1553           case cmdPASSWD:
1554             if( change_passphrase( sec_keyblock ) )
1555                 sec_modified = 1;
1556             break;
1557
1558           case cmdTRUST:
1559             if(opt.trust_model==TM_EXTERNAL)
1560               {
1561                 tty_printf(_("Owner trust may not be set while "
1562                              "using an user provided trust database\n"));
1563                 break;
1564               }
1565
1566             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1567             tty_printf("\n");
1568             if( edit_ownertrust( find_kbnode( keyblock,
1569                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1570                 redisplay = 1;
1571                 /* No real need to set update_trust here as
1572                    edit_ownertrust() calls revalidation_mark()
1573                    anyway. */
1574                 update_trust=1;
1575             }
1576             break;
1577
1578           case cmdPREF:
1579             show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1580             break;
1581
1582           case cmdSHOWPREF:
1583             show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1584             break;
1585
1586           case cmdSETPREF:
1587             keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
1588             break;
1589
1590           case cmdUPDPREF: 
1591             {
1592               PKT_user_id *temp=keygen_get_std_prefs();
1593               tty_printf(_("Set preference list to:\n"));
1594               show_prefs(temp,1);
1595               m_free(temp);
1596             }
1597             if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
1598                                         count_selected_uids (keyblock)?
1599                                         _("Really update the preferences"
1600                                           " for the selected user IDs? "):
1601                                        _("Really update the preferences? "))){
1602
1603                 if ( menu_set_preferences (keyblock, sec_keyblock) ) {
1604                     merge_keys_and_selfsig (keyblock);
1605                     modified = 1;
1606                     redisplay = 1;
1607                 }
1608             }
1609             break;
1610
1611           case cmdPREFKS:
1612             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
1613                                          keyblock, sec_keyblock ) )
1614               {
1615                 merge_keys_and_selfsig( keyblock );
1616                 modified = 1;
1617                 redisplay = 1;
1618               }
1619             break;
1620
1621           case cmdNOP:
1622             break;
1623
1624           case cmdREVSIG:
1625             if( menu_revsig( keyblock ) ) {
1626                 redisplay = 1;
1627                 modified = 1;
1628             }
1629             break;
1630
1631           case cmdENABLEKEY:
1632           case cmdDISABLEKEY:
1633             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1634                 redisplay = 1;
1635                 modified = 1;
1636             }
1637             break;
1638
1639          case cmdSHOWPHOTO:
1640            menu_showphoto(keyblock);
1641            break;
1642
1643           case cmdQUIT:
1644             if( have_commands )
1645                 goto leave;
1646             if( !modified && !sec_modified )
1647                 goto leave;
1648             if( !cpr_get_answer_is_yes("keyedit.save.okay",
1649                                         _("Save changes? ")) ) {
1650                 if( cpr_enabled()
1651                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
1652                                              _("Quit without saving? ")) )
1653                     goto leave;
1654                 break;
1655             }
1656             /* fall thru */
1657           case cmdSAVE:
1658             if( modified || sec_modified  ) {
1659                 if( modified ) {
1660                     rc = keydb_update_keyblock (kdbhd, keyblock);
1661                     if( rc ) {
1662                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
1663                         break;
1664                     }
1665                 }
1666                 if( sec_modified ) {
1667                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1668                     if( rc ) {
1669                         log_error( _("update secret failed: %s\n"),
1670                                    g10_errstr(rc) );
1671                         break;
1672                     }
1673                 }
1674             }
1675             else
1676                 tty_printf(_("Key not changed so no update needed.\n"));
1677
1678             if( update_trust )
1679               {
1680                 revalidation_mark ();
1681                 update_trust=0;
1682               }
1683             goto leave;
1684
1685           case cmdINVCMD:
1686           default:
1687             tty_printf("\n");
1688             tty_printf(_("Invalid command  (try \"help\")\n"));
1689             break;
1690         }
1691     } /* end main loop */
1692
1693   leave:
1694     release_kbnode( keyblock );
1695     release_kbnode( sec_keyblock );
1696     keydb_release (kdbhd);
1697     m_free(answer);
1698 }
1699
1700
1701 /****************
1702  * show preferences of a public keyblock.
1703  */
1704 static void
1705 show_prefs (PKT_user_id *uid, int verbose)
1706 {
1707     const prefitem_t fake={0,0};
1708     const prefitem_t *prefs;
1709     int i;
1710
1711     if( !uid )
1712         return;
1713
1714     if( uid->prefs )
1715         prefs=uid->prefs;
1716     else if(verbose)
1717         prefs=&fake;
1718     else
1719       return;
1720
1721     if (verbose) {
1722         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1723         tty_printf ("     ");
1724         tty_printf (_("Cipher: "));
1725         for(i=any=0; prefs[i].type; i++ ) {
1726             if( prefs[i].type == PREFTYPE_SYM ) {
1727                 const char *s = cipher_algo_to_string (prefs[i].value);
1728                 
1729                 if (any)
1730                     tty_printf (", ");
1731                 any = 1;
1732                 /* We don't want to display strings for experimental algos */
1733                 if (s && prefs[i].value < 100 )
1734                     tty_printf ("%s", s );
1735                 else
1736                     tty_printf ("[%d]", prefs[i].value);
1737                 if (prefs[i].value == CIPHER_ALGO_3DES )
1738                     des_seen = 1;
1739             }    
1740         }
1741         if (!des_seen) {
1742             if (any)
1743                 tty_printf (", ");
1744             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
1745         }
1746         tty_printf ("\n     ");
1747         tty_printf (_("Digest: "));
1748         for(i=any=0; prefs[i].type; i++ ) {
1749             if( prefs[i].type == PREFTYPE_HASH ) {
1750                 const char *s = digest_algo_to_string (prefs[i].value);
1751                 
1752                 if (any)
1753                     tty_printf (", ");
1754                 any = 1;
1755                 /* We don't want to display strings for experimental algos */
1756                 if (s && prefs[i].value < 100 )
1757                     tty_printf ("%s", s );
1758                 else
1759                     tty_printf ("[%d]", prefs[i].value);
1760                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
1761                     sha1_seen = 1;
1762             }
1763         }
1764         if (!sha1_seen) {
1765             if (any)
1766                 tty_printf (", ");
1767             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
1768         }
1769         tty_printf ("\n     ");
1770         tty_printf (_("Compression: "));
1771         for(i=any=0; prefs[i].type; i++ ) {
1772             if( prefs[i].type == PREFTYPE_ZIP ) {
1773                 const char *s=compress_algo_to_string(prefs[i].value);
1774                 
1775                 if (any)
1776                     tty_printf (", ");
1777                 any = 1;
1778                 /* We don't want to display strings for experimental algos */
1779                 if (s && prefs[i].value < 100 )
1780                     tty_printf ("%s", s );
1781                 else
1782                     tty_printf ("[%d]", prefs[i].value);
1783                 if (prefs[i].value == COMPRESS_ALGO_NONE )
1784                     uncomp_seen = 1;
1785             }
1786         }
1787         if (!uncomp_seen) {
1788             if (any)
1789                 tty_printf (", ");
1790             else {
1791               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
1792               tty_printf (", ");
1793             }
1794             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
1795         }
1796         if(uid->mdc_feature || !uid->ks_modify)
1797           {
1798             tty_printf ("\n     ");
1799             tty_printf (_("Features: "));
1800             any=0;
1801             if(uid->mdc_feature)
1802               {
1803                 tty_printf ("MDC");
1804                 any=1;
1805               }
1806             if(!uid->ks_modify)
1807               {
1808                 if(any)
1809                   tty_printf (", ");
1810                 tty_printf (_("Keyserver no-modify"));
1811               }
1812           }
1813         tty_printf("\n");
1814     }
1815     else {
1816         tty_printf("    ");
1817         for(i=0; prefs[i].type; i++ ) {
1818             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
1819                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
1820                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
1821                                  prefs[i].value);
1822         }
1823         if (uid->mdc_feature)
1824             tty_printf (" [mdc]");
1825         if (!uid->ks_modify)
1826             tty_printf (" [no-ks-modify]");
1827         tty_printf("\n");
1828     }
1829 }
1830
1831
1832 /* This is the version of show_key_with_all_names used when
1833    opt.with_colons is used.  It prints all available data in a easy to
1834    parse format and does not translate utf8 */
1835 static void
1836 show_key_with_all_names_colon (KBNODE keyblock)
1837 {
1838   KBNODE node;
1839   int i, j, ulti_hack=0;
1840   byte pk_version=0;
1841   PKT_public_key *primary=NULL;
1842
1843   /* the keys */
1844   for ( node = keyblock; node; node = node->next )
1845     {
1846       if (node->pkt->pkttype == PKT_PUBLIC_KEY
1847           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
1848         {
1849           PKT_public_key *pk = node->pkt->pkt.public_key;
1850           u32 keyid[2];
1851
1852           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1853             {
1854               pk_version = pk->version;
1855               primary=pk;
1856             }
1857
1858           keyid_from_pk (pk, keyid);
1859
1860           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
1861           if (!pk->is_valid)
1862             putchar ('i');
1863           else if (pk->is_revoked)
1864             putchar ('r');
1865           else if (pk->has_expired)
1866             putchar ('e');
1867           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1868             {
1869               int trust = get_validity_info (pk, NULL);
1870               if(trust=='u')
1871                 ulti_hack=1;
1872               putchar (trust);
1873             }
1874
1875           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
1876                   nbits_from_pk (pk),
1877                   pk->pubkey_algo,
1878                   (ulong)keyid[0], (ulong)keyid[1],
1879                   (ulong)pk->timestamp,
1880                   (ulong)pk->expiredate );
1881           if (node->pkt->pkttype==PKT_PUBLIC_KEY
1882               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1883             putchar(get_ownertrust_info (pk));
1884           putchar(':');
1885           putchar('\n');
1886           
1887           print_fingerprint (pk, NULL, 0);
1888
1889           /* print the revoker record */
1890           if( !pk->revkey && pk->numrevkeys )
1891             BUG();
1892           else
1893             {
1894               for (i=0; i < pk->numrevkeys; i++)
1895                 {
1896                   byte *p;
1897
1898                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
1899                   p = pk->revkey[i].fpr;
1900                   for (j=0; j < 20; j++, p++ )
1901                     printf ("%02X", *p);
1902                   printf (":%02x%s:\n", pk->revkey[i].class,
1903                           (pk->revkey[i].class&0x40)?"s":"");
1904                 }
1905             }
1906         }
1907     }
1908   
1909     /* the user ids */
1910     i = 0;
1911     for (node = keyblock; node; node = node->next) 
1912       {
1913         if ( node->pkt->pkttype == PKT_USER_ID )
1914           {
1915             PKT_user_id *uid = node->pkt->pkt.user_id;
1916
1917             ++i;
1918
1919             if(uid->attrib_data)
1920               printf("uat:");
1921             else
1922               printf("uid:");
1923
1924             if ( uid->is_revoked )
1925               printf("r::::::::");
1926             else if ( uid->is_expired )
1927               printf("e::::::::");
1928             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
1929               printf("::::::::");
1930             else
1931               {
1932                 int uid_validity;
1933
1934                 if( primary && !ulti_hack )
1935                   uid_validity = get_validity_info( primary, uid );
1936                 else
1937                   uid_validity = 'u';
1938                 printf("%c::::::::",uid_validity);
1939               }
1940
1941             if(uid->attrib_data)
1942               printf ("%u %lu",uid->numattribs,uid->attrib_len);
1943             else
1944               print_string (stdout, uid->name, uid->len, ':');
1945
1946             putchar (':');
1947             /* signature class */
1948             putchar (':');
1949             /* capabilities */
1950             putchar (':');
1951             /* preferences */
1952             if (pk_version>3 || uid->selfsigversion>3)
1953               {
1954                 const prefitem_t *prefs = uid->prefs;
1955                 
1956                 for (j=0; prefs && prefs[j].type; j++)
1957                   {
1958                     if (j)
1959                       putchar (' ');
1960                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
1961                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
1962                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
1963                             prefs[j].value);
1964                   } 
1965                 if (uid->mdc_feature)
1966                   printf (",mdc");
1967                 if (!uid->ks_modify)
1968                   printf (",no-ks-modify");
1969               } 
1970             putchar (':');
1971             /* flags */
1972             printf ("%d,", i);
1973             if (uid->is_primary)
1974               putchar ('p');
1975             if (uid->is_revoked)
1976               putchar ('r');
1977             if (uid->is_expired)
1978               putchar ('e');
1979             if ((node->flag & NODFLG_SELUID))
1980               putchar ('s');
1981             if ((node->flag & NODFLG_MARK_A))
1982               putchar ('m');
1983             putchar (':');
1984             putchar('\n');
1985           }
1986       }
1987 }
1988
1989
1990 /****************
1991  * Display the key a the user ids, if only_marked is true, do only
1992  * so for user ids with mark A flag set and dont display the index number
1993  */
1994 static void
1995 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
1996                          int with_fpr, int with_subkeys, int with_prefs )
1997 {
1998     KBNODE node;
1999     int i, rc;
2000     int do_warn = 0, indent=0;
2001     byte pk_version=0;
2002     PKT_public_key *primary=NULL;
2003
2004     if (opt.with_colons)
2005       {
2006         show_key_with_all_names_colon (keyblock);
2007         return;
2008       }
2009
2010     /* the keys */
2011     for( node = keyblock; node; node = node->next ) {
2012         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2013             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
2014             PKT_public_key *pk = node->pkt->pkt.public_key;
2015             const char *otrust="err",*trust="err";
2016
2017             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2018                 /* do it here, so that debug messages don't clutter the
2019                  * output */
2020                 static int did_warn = 0;
2021
2022                 trust = get_validity_string (pk, NULL);
2023                 otrust = get_ownertrust_string (pk);
2024
2025                 /* Show a warning once */
2026                 if (!did_warn
2027                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2028                     did_warn = 1;
2029                     do_warn = 1;
2030                 }
2031
2032                 pk_version=pk->version;
2033                 primary=pk;
2034             }
2035
2036             if(with_revoker) {
2037                 if( !pk->revkey && pk->numrevkeys )
2038                     BUG();
2039                 else
2040                     for(i=0;i<pk->numrevkeys;i++) {
2041                         u32 r_keyid[2];
2042                         char *user;
2043                         const char *algo=
2044                           pubkey_algo_to_string(pk->revkey[i].algid);
2045
2046                         keyid_from_fingerprint(pk->revkey[i].fpr,
2047                                                MAX_FINGERPRINT_LEN,r_keyid);
2048                         
2049                         user=get_user_id_string (r_keyid);
2050                         tty_printf (_("This key may be revoked by %s key "),
2051                                     algo?algo:"?");
2052                         tty_print_utf8_string (user, strlen (user));
2053                         if ((pk->revkey[i].class&0x40))
2054                           tty_printf (_(" (sensitive)"));
2055                         tty_printf ("\n");
2056                         m_free(user);
2057                       }
2058             }
2059
2060             keyid_from_pk(pk,NULL);
2061             tty_printf("%s%c %4u%c/%s  ",
2062                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2063                        (node->flag & NODFLG_SELKEY)? '*':' ',
2064                        nbits_from_pk( pk ),
2065                        pubkey_letter( pk->pubkey_algo ),
2066                        keystr(pk->keyid));
2067
2068             tty_printf(_("created: %s"),datestr_from_pk(pk));
2069             tty_printf("  ");
2070             if(pk->is_revoked)
2071               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2072             else if(pk->has_expired)
2073               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2074             else
2075               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2076             tty_printf("\n");
2077
2078             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2079               {
2080                 if(opt.trust_model!=TM_ALWAYS)
2081                   {
2082                     tty_printf("%*s",keystrlen()+13,"");
2083                     /* Ownertrust is only meaningful for the PGP or
2084                        classic trust models */
2085                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2086                       {
2087                         int width=14-strlen(otrust);
2088                         if(width<=0)
2089                           width=1;
2090                         tty_printf(_("trust: %s"), otrust);
2091                         tty_printf("%*s",width,"");
2092                       }
2093                     
2094                     tty_printf(_("validity: %s"), trust );
2095                     tty_printf("\n");
2096                   }
2097                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2098                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2099                   {
2100                     tty_printf("*** ");
2101                     tty_printf(_("This key has been disabled"));
2102                     tty_printf("\n");
2103                   }
2104               }
2105
2106             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2107               {
2108                 print_fingerprint ( pk, NULL, 2 );
2109                 tty_printf("\n");
2110               }
2111         }
2112         else if( node->pkt->pkttype == PKT_SECRET_KEY
2113             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
2114             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2115             tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2116                           node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2117                           (node->flag & NODFLG_SELKEY)? '*':' ',
2118                           nbits_from_sk( sk ),
2119                           pubkey_letter( sk->pubkey_algo ),
2120                           (ulong)keyid_from_sk(sk,NULL),
2121                           datestr_from_sk(sk),
2122                           expirestr_from_sk(sk) );
2123             tty_printf("\n");
2124         }
2125         else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
2126                  && node->pkt->pkt.signature->sig_class == 0x28       ) {
2127             PKT_signature *sig = node->pkt->pkt.signature;
2128
2129             rc = check_key_signature( keyblock, node, NULL );
2130             if( !rc )
2131                 tty_printf( _("rev! subkey has been revoked: %s\n"),
2132                             datestr_from_sig( sig ) );
2133             else if( rc == G10ERR_BAD_SIGN )
2134                 tty_printf( _("rev- faked revocation found\n") );
2135             else if( rc )
2136                 tty_printf( _("rev? problem checking revocation: %s\n"),
2137                                                          g10_errstr(rc) );
2138         }
2139     }
2140     
2141     /* the user ids */
2142
2143     for( node = keyblock; node; node = node->next )
2144       {
2145         if(node->pkt->pkttype == PKT_USER_ID
2146            && (node->pkt->pkt.user_id->is_revoked
2147                || node->pkt->pkt.user_id->is_expired))
2148           {
2149             indent=1;
2150             break;
2151           }
2152       }
2153
2154     i = 0;
2155     for( node = keyblock; node; node = node->next ) {
2156         if( node->pkt->pkttype == PKT_USER_ID ) {
2157             PKT_user_id *uid = node->pkt->pkt.user_id;
2158             ++i;
2159             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
2160                 if(uid->is_revoked)
2161                   tty_printf("[%8.8s] ",_("revoked"));
2162                 else if(uid->is_expired)
2163                   tty_printf("[%8.8s] ",_("expired"));
2164                 else if(opt.list_options&LIST_SHOW_VALIDITY && primary)
2165                   tty_printf("[%8.8s] ",
2166                              trust_value_to_string(get_validity(primary,uid)));
2167                 else if(indent)
2168                   tty_printf("           ");
2169                 if( only_marked )
2170                    tty_printf("     ");
2171                 else if( node->flag & NODFLG_SELUID )
2172                    tty_printf("(%d)* ", i);
2173                 else if( uid->is_primary )
2174                    tty_printf("(%d). ", i);
2175                 else
2176                    tty_printf("(%d)  ", i);
2177                 tty_print_utf8_string( uid->name, uid->len );
2178                 tty_printf("\n");
2179                 if( with_prefs )
2180                   {
2181                     if(pk_version>3 || uid->selfsigversion>3)
2182                       show_prefs (uid, with_prefs == 2);
2183                     else
2184                       tty_printf(_("There are no preferences on a "
2185                                    "PGP 2.x-style user ID.\n"));
2186                   }
2187             }
2188         }
2189     }
2190
2191     if (do_warn)
2192         tty_printf (_("Please note that the shown key validity "
2193                       "is not necessarily correct\n"
2194                       "unless you restart the program.\n")); 
2195
2196 }
2197
2198
2199 /* Display basic key information.  This fucntion is suitable to show
2200    information on the key without any dependencies on the trustdb or
2201    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2202    a secret key.*/
2203 void
2204 show_basic_key_info ( KBNODE keyblock )
2205 {
2206   KBNODE node;
2207   int i;
2208
2209   /* The primary key */
2210   for (node = keyblock; node; node = node->next)
2211     {
2212       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2213         {
2214           PKT_public_key *pk = node->pkt->pkt.public_key;
2215           
2216           /* Note, we use the same format string as in other show
2217              functions to make the translation job easier. */
2218           tty_printf (_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2219                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2220                       ' ',
2221                       nbits_from_pk( pk ),
2222                       pubkey_letter( pk->pubkey_algo ),
2223                       (ulong)keyid_from_pk(pk,NULL),
2224                       datestr_from_pk(pk),
2225                       expirestr_from_pk(pk) );
2226           tty_printf("\n");
2227           print_fingerprint ( pk, NULL, 3 );
2228           tty_printf("\n");
2229         }
2230       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2231         {
2232           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2233           tty_printf(_("%s%c %4u%c/%08lX  created: %s expires: %s"),
2234                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2235                      ' ',
2236                      nbits_from_sk( sk ),
2237                      pubkey_letter( sk->pubkey_algo ),
2238                      (ulong)keyid_from_sk(sk,NULL),
2239                      datestr_from_sk(sk),
2240                      expirestr_from_sk(sk) );
2241           tty_printf("\n");
2242           print_fingerprint (NULL, sk, 3 );
2243           tty_printf("\n");
2244         }
2245     }
2246
2247   /* The user IDs. */
2248   for (i=0, node = keyblock; node; node = node->next)
2249     {
2250       if (node->pkt->pkttype == PKT_USER_ID)
2251         {
2252           PKT_user_id *uid = node->pkt->pkt.user_id;
2253           ++i;
2254      
2255           tty_printf ("     ");
2256           if (uid->is_revoked)
2257             tty_printf (_("[revoked] "));
2258           else if ( uid->is_expired )
2259             tty_printf (_("[expired] "));
2260           tty_print_utf8_string (uid->name, uid->len);
2261           tty_printf ("\n");
2262         }
2263     }
2264 }
2265
2266 static void
2267 show_key_and_fingerprint( KBNODE keyblock )
2268 {
2269   KBNODE node;
2270   PKT_public_key *pk = NULL;
2271
2272   for( node = keyblock; node; node = node->next )
2273     {
2274       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2275         {
2276           pk = node->pkt->pkt.public_key;
2277           tty_printf("pub   %4u%c/%s %s ",
2278                      nbits_from_pk( pk ),
2279                      pubkey_letter( pk->pubkey_algo ),
2280                      keystr_from_pk(pk),
2281                      datestr_from_pk(pk) );
2282         }
2283       else if( node->pkt->pkttype == PKT_USER_ID )
2284         {
2285           PKT_user_id *uid = node->pkt->pkt.user_id;
2286           tty_print_utf8_string( uid->name, uid->len );
2287           break;
2288         }
2289     }
2290   tty_printf("\n");
2291   if( pk )
2292     print_fingerprint( pk, NULL, 2 );
2293 }
2294
2295
2296 /* Show a warning if no uids on the key have the primary uid flag
2297    set. */
2298 static void
2299 no_primary_warning(KBNODE keyblock)
2300 {
2301   KBNODE node;
2302   int have_primary=0,uid_count=0;
2303
2304   /* TODO: if we ever start behaving differently with a primary or
2305      non-primary attribute ID, we will need to check for attributes
2306      here as well. */
2307
2308   for(node=keyblock; node; node = node->next)
2309     {
2310       if(node->pkt->pkttype==PKT_USER_ID
2311          && node->pkt->pkt.user_id->attrib_data==NULL)
2312         {
2313           uid_count++;
2314
2315           if(node->pkt->pkt.user_id->is_primary==2)
2316             {
2317               have_primary=1;
2318               break;
2319             }
2320         }
2321     }
2322
2323   if(uid_count>1 && !have_primary)
2324     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2325                " may\n              cause a different user ID to become"
2326                " the assumed primary.\n"));
2327 }
2328
2329 /****************
2330  * Ask for a new user id, do the selfsignature and put it into
2331  * both keyblocks.
2332  * Return true if there is a new user id
2333  */
2334 static int
2335 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2336 {
2337     PKT_user_id *uid;
2338     PKT_public_key *pk=NULL;
2339     PKT_secret_key *sk=NULL;
2340     PKT_signature *sig=NULL;
2341     PACKET *pkt;
2342     KBNODE node;
2343     KBNODE pub_where=NULL, sec_where=NULL;
2344     int rc;
2345
2346     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2347         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2348             pk = node->pkt->pkt.public_key;
2349         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2350             break;
2351     }
2352     if( !node ) /* no subkey */
2353         pub_where = NULL;
2354     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2355         if( node->pkt->pkttype == PKT_SECRET_KEY )
2356             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2357         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2358             break;
2359     }
2360     if( !node ) /* no subkey */
2361         sec_where = NULL;
2362     assert(pk && sk);
2363
2364     if(photo) {
2365       int hasattrib=0;
2366
2367       for( node = pub_keyblock; node; node = node->next )
2368         if( node->pkt->pkttype == PKT_USER_ID &&
2369             node->pkt->pkt.user_id->attrib_data!=NULL)
2370           {
2371             hasattrib=1;
2372             break;
2373           }
2374
2375       /* It is legal but bad for compatibility to add a photo ID to a
2376          v3 key as it means that PGP2 will not be able to use that key
2377          anymore.  Also, PGP may not expect a photo on a v3 key.
2378          Don't bother to ask this if the key already has a photo - any
2379          damage has already been done at that point. -dms */
2380       if(pk->version==3 && !hasattrib)
2381         {
2382           if(opt.expert)
2383             {
2384               tty_printf(_("WARNING: This is a PGP2-style key.  "
2385                            "Adding a photo ID may cause some versions\n"
2386                            "         of PGP to reject this key.\n"));
2387
2388               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2389                                         _("Are you sure you still want "
2390                                           "to add it? (y/N) ")))
2391                 return 0;
2392             }
2393           else
2394             {
2395               tty_printf(_("You may not add a photo ID to "
2396                            "a PGP2-style key.\n"));
2397               return 0;
2398             }
2399         }
2400
2401       uid = generate_photo_id(pk);
2402     } else
2403       uid = generate_user_id();
2404     if( !uid )
2405         return 0;
2406
2407     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2408                              keygen_add_std_prefs, pk );
2409     free_secret_key( sk );
2410     if( rc ) {
2411         log_error("signing failed: %s\n", g10_errstr(rc) );
2412         free_user_id(uid);
2413         return 0;
2414     }
2415
2416     /* insert/append to secret keyblock */
2417     pkt = m_alloc_clear( sizeof *pkt );
2418     pkt->pkttype = PKT_USER_ID;
2419     pkt->pkt.user_id = scopy_user_id(uid);
2420     node = new_kbnode(pkt);
2421     if( sec_where )
2422         insert_kbnode( sec_where, node, 0 );
2423     else
2424         add_kbnode( sec_keyblock, node );
2425     pkt = m_alloc_clear( sizeof *pkt );
2426     pkt->pkttype = PKT_SIGNATURE;
2427     pkt->pkt.signature = copy_signature(NULL, sig);
2428     if( sec_where )
2429         insert_kbnode( node, new_kbnode(pkt), 0 );
2430     else
2431         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2432     /* insert/append to public keyblock */
2433     pkt = m_alloc_clear( sizeof *pkt );
2434     pkt->pkttype = PKT_USER_ID;
2435     pkt->pkt.user_id = uid;
2436     node = new_kbnode(pkt);
2437     if( pub_where )
2438         insert_kbnode( pub_where, node, 0 );
2439     else
2440         add_kbnode( pub_keyblock, node );
2441     pkt = m_alloc_clear( sizeof *pkt );
2442     pkt->pkttype = PKT_SIGNATURE;
2443     pkt->pkt.signature = copy_signature(NULL, sig);
2444     if( pub_where )
2445         insert_kbnode( node, new_kbnode(pkt), 0 );
2446     else
2447         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2448     return 1;
2449 }
2450
2451
2452 /****************
2453  * Remove all selceted userids from the keyrings
2454  */
2455 static void
2456 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2457 {
2458     KBNODE node;
2459     int selected=0;
2460
2461     for( node = pub_keyblock; node; node = node->next ) {
2462         if( node->pkt->pkttype == PKT_USER_ID ) {
2463             selected = node->flag & NODFLG_SELUID;
2464             if( selected ) {
2465                 /* Only cause a trust update if we delete a
2466                    non-revoked user id */
2467                 if(!node->pkt->pkt.user_id->is_revoked)
2468                   update_trust=1;
2469                 delete_kbnode( node );
2470                 if( sec_keyblock ) {
2471                     KBNODE snode;
2472                     int s_selected = 0;
2473                     PKT_user_id *uid = node->pkt->pkt.user_id;
2474                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2475                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2476                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2477
2478                             s_selected =
2479                                 (uid->len == suid->len
2480                                  && !memcmp( uid->name, suid->name, uid->len));
2481                             if( s_selected )
2482                                 delete_kbnode( snode );
2483                         }
2484                         else if( s_selected
2485                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2486                             delete_kbnode( snode );
2487                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2488                             s_selected = 0;
2489                     }
2490                 }
2491             }
2492         }
2493         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2494             delete_kbnode( node );
2495         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2496             selected = 0;
2497     }
2498     commit_kbnode( &pub_keyblock );
2499     if( sec_keyblock )
2500         commit_kbnode( &sec_keyblock );
2501 }
2502
2503
2504 static int
2505 menu_delsig( KBNODE pub_keyblock )
2506 {
2507     KBNODE node;
2508     PKT_user_id *uid = NULL;
2509     int changed=0;
2510
2511     for( node = pub_keyblock; node; node = node->next ) {
2512         if( node->pkt->pkttype == PKT_USER_ID ) {
2513             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2514         }
2515         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2516            int okay, valid, selfsig, inv_sig, no_key, other_err;
2517
2518             tty_printf("uid  ");
2519             tty_print_utf8_string( uid->name, uid->len );
2520             tty_printf("\n");
2521
2522            okay = inv_sig = no_key = other_err = 0;
2523             valid = print_and_check_one_sig( pub_keyblock, node,
2524                                             &inv_sig, &no_key, &other_err,
2525                                             &selfsig, 1 );
2526
2527            if( valid ) {
2528                okay = cpr_get_answer_yes_no_quit(
2529                    "keyedit.delsig.valid",
2530                    _("Delete this good signature? (y/N/q)"));
2531
2532                /* Only update trust if we delete a good signature.
2533                   The other two cases do not affect trust. */
2534                if(okay)
2535                  update_trust=1;
2536            }
2537            else if( inv_sig || other_err )
2538                okay = cpr_get_answer_yes_no_quit(
2539                    "keyedit.delsig.invalid",
2540                    _("Delete this invalid signature? (y/N/q)"));
2541            else if( no_key )
2542                okay = cpr_get_answer_yes_no_quit(
2543                    "keyedit.delsig.unknown",
2544                    _("Delete this unknown signature? (y/N/q)"));
2545
2546             if( okay == -1 )
2547                 break;
2548            if( okay && selfsig && !cpr_get_answer_is_yes(
2549                                "keyedit.delsig.selfsig",
2550                               _("Really delete this self-signature? (y/N)") ))
2551                 okay = 0;
2552             if( okay ) {
2553                 delete_kbnode( node );
2554                 changed++;
2555             }
2556
2557         }
2558         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2559             uid = NULL;
2560     }
2561
2562     if( changed ) {
2563         commit_kbnode( &pub_keyblock );
2564         tty_printf( changed == 1? _("Deleted %d signature.\n")
2565                                 : _("Deleted %d signatures.\n"), changed );
2566     }
2567     else
2568         tty_printf( _("Nothing deleted.\n") );
2569
2570     return changed;
2571 }
2572
2573
2574 /****************
2575  * Remove some of the secondary keys
2576  */
2577 static void
2578 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2579 {
2580     KBNODE node;
2581     int selected=0;
2582
2583     for( node = pub_keyblock; node; node = node->next ) {
2584         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2585             selected = node->flag & NODFLG_SELKEY;
2586             if( selected ) {
2587                 delete_kbnode( node );
2588                 if( sec_keyblock ) {
2589                     KBNODE snode;
2590                     int s_selected = 0;
2591                     u32 ki[2];
2592
2593                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2594                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2595                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2596                             u32 ki2[2];
2597
2598                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2599                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2600                             if( s_selected )
2601                                 delete_kbnode( snode );
2602                         }
2603                         else if( s_selected
2604                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2605                             delete_kbnode( snode );
2606                         else
2607                             s_selected = 0;
2608                     }
2609                 }
2610             }
2611         }
2612         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2613             delete_kbnode( node );
2614         else
2615             selected = 0;
2616     }
2617     commit_kbnode( &pub_keyblock );
2618     if( sec_keyblock )
2619         commit_kbnode( &sec_keyblock );
2620
2621     /* No need to set update_trust here since signing keys are no
2622        longer used to certify other keys, so there is no change in
2623        trust when revoking/removing them */
2624 }
2625
2626
2627 /****************
2628  * Ask for a new revoker, do the selfsignature and put it into
2629  * both keyblocks.
2630  * Return true if there is a new revoker
2631  */
2632 static int
2633 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2634 {
2635   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2636   PKT_secret_key *sk=NULL;
2637   PKT_signature *sig=NULL;
2638   PACKET *pkt;
2639   struct revocation_key revkey;
2640   size_t fprlen;
2641   int rc;
2642
2643   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2644   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2645
2646   pk=pub_keyblock->pkt->pkt.public_key;
2647
2648   if(pk->numrevkeys==0 && pk->version==3)
2649     {
2650       /* It is legal but bad for compatibility to add a revoker to a
2651          v3 key as it means that PGP2 will not be able to use that key
2652          anymore.  Also, PGP may not expect a revoker on a v3 key.
2653          Don't bother to ask this if the key already has a revoker -
2654          any damage has already been done at that point. -dms */
2655       if(opt.expert)
2656         {
2657           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2658                        "Adding a designated revoker may cause\n"
2659                        "         some versions of PGP to reject this key.\n"));
2660
2661           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2662                                     _("Are you sure you still want "
2663                                       "to add it? (y/N) ")))
2664             return 0;
2665         }
2666       else
2667         {
2668           tty_printf(_("You may not add a designated revoker to "
2669                        "a PGP 2.x-style key.\n"));
2670           return 0;
2671         }
2672     }
2673
2674   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2675
2676   for(;;)
2677     {
2678       char *answer;
2679
2680       if(revoker_pk)
2681         free_public_key(revoker_pk);
2682
2683       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2684
2685       tty_printf("\n");
2686
2687       answer=cpr_get_utf8("keyedit.add_revoker",
2688                           _("Enter the user ID of the designated revoker: "));
2689       if(answer[0]=='\0' || answer[0]=='\004')
2690         {
2691           m_free(answer);
2692           goto fail;
2693         }
2694
2695       /* Note that I'm requesting SIG here and not CERT.  We're making
2696          a certification, but it is okay to be a subkey. */
2697       revoker_pk->req_usage=PUBKEY_USAGE_SIG;
2698       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2699       if(rc)
2700         {
2701           log_error (_("key `%s' not found: %s\n"),answer,g10_errstr(rc));
2702           m_free(answer);
2703           continue;
2704         }
2705
2706       m_free(answer);
2707
2708       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2709       if(fprlen!=20)
2710         {
2711           log_error(_("cannot appoint a PGP 2.x style key as a "
2712                       "designated revoker\n"));
2713           continue;
2714         }
2715
2716       revkey.class=0x80;
2717       if(sensitive)
2718         revkey.class|=0x40;
2719       revkey.algid=revoker_pk->pubkey_algo;
2720
2721       if(cmp_public_keys(revoker_pk,pk)==0)
2722         {
2723           /* This actually causes no harm (after all, a key that
2724              designates itself as a revoker is the same as a
2725              regular key), but it's easy enough to check. */
2726           log_error(_("you cannot appoint a key as its own "
2727                       "designated revoker\n"));
2728
2729           continue;
2730         }
2731
2732       keyid_from_pk(pk,NULL);
2733
2734       /* Does this revkey already exist? */
2735       if(!pk->revkey && pk->numrevkeys)
2736         BUG();
2737       else
2738         {
2739           int i;
2740
2741           for(i=0;i<pk->numrevkeys;i++)
2742             {
2743               if(memcmp(&pk->revkey[i],&revkey,
2744                         sizeof(struct revocation_key))==0)
2745                 {
2746                   char buf[50];
2747
2748                   log_error(_("this key has already been designated "
2749                               "as a revoker\n"));
2750
2751                   sprintf(buf,"%08lX%08lX",
2752                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2753                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2754
2755                   break;
2756                 }
2757             }
2758
2759           if(i<pk->numrevkeys)
2760             continue;
2761         }
2762
2763       print_pubkey_info(NULL,revoker_pk);
2764       print_fingerprint(revoker_pk,NULL,2);
2765       tty_printf("\n");
2766
2767       tty_printf(_("WARNING: appointing a key as a designated revoker "
2768                    "cannot be undone!\n"));
2769
2770       tty_printf("\n");
2771
2772       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2773                                 _("Are you sure you want to appoint this "
2774                                   "key as a designated revoker? (y/N): ")))
2775         continue;
2776
2777       free_public_key(revoker_pk);
2778       revoker_pk=NULL;
2779       break;
2780     }
2781
2782   /* The 1F signature must be at least v4 to carry the revocation key
2783      subpacket. */
2784   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
2785                            keygen_add_revkey,&revkey );
2786   if( rc )
2787     {
2788       log_error("signing failed: %s\n", g10_errstr(rc) );
2789       goto fail;
2790     }
2791
2792   free_secret_key(sk);
2793   sk=NULL;
2794
2795   /* insert into secret keyblock */
2796   pkt = m_alloc_clear( sizeof *pkt );
2797   pkt->pkttype = PKT_SIGNATURE;
2798   pkt->pkt.signature = copy_signature(NULL, sig);
2799   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2800
2801   /* insert into public keyblock */
2802   pkt = m_alloc_clear( sizeof *pkt );
2803   pkt->pkttype = PKT_SIGNATURE;
2804   pkt->pkt.signature = sig;
2805   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2806
2807   return 1;
2808
2809  fail:
2810   if(sk)
2811     free_secret_key(sk);
2812   if(sig)
2813     free_seckey_enc(sig);
2814   if(revoker_pk)
2815     free_public_key(revoker_pk);
2816
2817   return 0;
2818 }
2819
2820
2821 static int
2822 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
2823 {
2824     int n1, signumber, rc;
2825     u32 expiredate;
2826     int mainkey=0;
2827     PKT_secret_key *sk;    /* copy of the main sk */
2828     PKT_public_key *main_pk, *sub_pk;
2829     PKT_user_id *uid;
2830     KBNODE node;
2831     u32 keyid[2];
2832
2833     if( count_selected_keys( sec_keyblock ) ) {
2834         tty_printf(_("Please remove selections from the secret keys.\n"));
2835         return 0;
2836     }
2837
2838     n1 = count_selected_keys( pub_keyblock );
2839     if( n1 > 1 ) {
2840         tty_printf(_("Please select at most one secondary key.\n"));
2841         return 0;
2842     }
2843     else if( n1 )
2844         tty_printf(_("Changing expiration time for a secondary key.\n"));
2845     else
2846       {
2847         tty_printf(_("Changing expiration time for the primary key.\n"));
2848         mainkey=1;
2849         no_primary_warning(pub_keyblock);
2850       }
2851
2852     expiredate = ask_expiredate();
2853     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2854     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2855
2856     /* Now we can actually change the self signature(s) */
2857     main_pk = sub_pk = NULL;
2858     uid = NULL;
2859     signumber = 0;
2860     for( node=pub_keyblock; node; node = node->next ) {
2861         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2862             main_pk = node->pkt->pkt.public_key;
2863             keyid_from_pk( main_pk, keyid );
2864             main_pk->expiredate = expiredate;
2865         }
2866         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2867                  && (node->flag & NODFLG_SELKEY ) ) {
2868             sub_pk = node->pkt->pkt.public_key;
2869             sub_pk->expiredate = expiredate;
2870         }
2871         else if( node->pkt->pkttype == PKT_USER_ID )
2872             uid = node->pkt->pkt.user_id;
2873         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
2874                  && ( mainkey || sub_pk ) ) {
2875             PKT_signature *sig = node->pkt->pkt.signature;
2876             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
2877                 && ( (mainkey && uid
2878                       && uid->created && (sig->sig_class&~3) == 0x10)
2879                      || (!mainkey && sig->sig_class == 0x18)  )
2880                 && sig->flags.chosen_selfsig )
2881               {
2882                 /* this is a selfsignature which is to be replaced */
2883                 PKT_signature *newsig;
2884                 PACKET *newpkt;
2885                 KBNODE sn;
2886                 int signumber2 = 0;
2887
2888                 signumber++;
2889
2890                 if( (mainkey && main_pk->version < 4)
2891                     || (!mainkey && sub_pk->version < 4 ) ) {
2892                     log_info(_(
2893                         "You can't change the expiration date of a v3 key\n"));
2894                     free_secret_key( sk );
2895                     return 0;
2896                 }
2897
2898                 /* find the corresponding secret self-signature */
2899                 for( sn=sec_keyblock; sn; sn = sn->next ) {
2900                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
2901                         PKT_signature *b = sn->pkt->pkt.signature;
2902                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
2903                             && sig->sig_class == b->sig_class
2904                             && ++signumber2 == signumber )
2905                             break;
2906                     }
2907                 }
2908                 if( !sn )
2909                     log_info(_("No corresponding signature in secret ring\n"));
2910
2911                 if( mainkey )
2912                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
2913                                             sk, keygen_add_key_expire, main_pk);
2914                 else
2915                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
2916                                             sk, keygen_add_key_expire, sub_pk );
2917                 if( rc ) {
2918                     log_error("make_keysig_packet failed: %s\n",
2919                                                     g10_errstr(rc));
2920                     free_secret_key( sk );
2921                     return 0;
2922                 }
2923                 /* replace the packet */
2924                 newpkt = m_alloc_clear( sizeof *newpkt );
2925                 newpkt->pkttype = PKT_SIGNATURE;
2926                 newpkt->pkt.signature = newsig;
2927                 free_packet( node->pkt );
2928                 m_free( node->pkt );
2929                 node->pkt = newpkt;
2930                 if( sn ) {
2931                     newpkt = m_alloc_clear( sizeof *newpkt );
2932                     newpkt->pkttype = PKT_SIGNATURE;
2933                     newpkt->pkt.signature = copy_signature( NULL, newsig );
2934                     free_packet( sn->pkt );
2935                     m_free( sn->pkt );
2936                     sn->pkt = newpkt;
2937                 }
2938                 sub_pk = NULL;
2939             }
2940         }
2941     }
2942
2943     free_secret_key( sk );
2944     update_trust=1;
2945     return 1;
2946 }
2947
2948 static int
2949 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
2950 {
2951     byte buf[1];
2952
2953     /* first clear all primary uid flags so that we are sure none are
2954      * lingering around */
2955     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
2956     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
2957
2958     /* if opaque is set,we want to set the primary id */
2959     if (opaque) { 
2960         buf[0] = 1;
2961         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
2962     }
2963
2964     return 0;
2965 }
2966
2967
2968 /*
2969  * Set the primary uid flag for the selected UID.  We will also reset
2970  * all other primary uid flags.  For this to work with have to update
2971  * all the signature timestamps.  If we would do this with the current
2972  * time, we lose quite a lot of information, so we use a a kludge to
2973  * do this: Just increment the timestamp by one second which is
2974  * sufficient to updated a signature during import.
2975  */
2976 static int
2977 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
2978 {
2979     PKT_secret_key *sk;    /* copy of the main sk */
2980     PKT_public_key *main_pk;
2981     PKT_user_id *uid;
2982     KBNODE node;
2983     u32 keyid[2];
2984     int selected;
2985     int attribute = 0;
2986     int modified = 0;
2987
2988     if ( count_selected_uids (pub_keyblock) != 1 ) {
2989         tty_printf(_("Please select exactly one user ID.\n"));
2990         return 0;
2991     }
2992
2993     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2994     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2995
2996     /* Now we can actually change the self signature(s) */
2997     main_pk = NULL;
2998     uid = NULL;
2999     selected = 0;
3000
3001     /* Is our selected uid an attribute packet? */
3002     for ( node=pub_keyblock; node; node = node->next )
3003       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3004         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3005
3006     for ( node=pub_keyblock; node; node = node->next ) {
3007         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3008             break; /* ready */
3009
3010         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3011             main_pk = node->pkt->pkt.public_key;
3012             keyid_from_pk( main_pk, keyid );
3013         }
3014         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3015             uid = node->pkt->pkt.user_id;
3016             selected = node->flag & NODFLG_SELUID;
3017         }
3018         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3019             PKT_signature *sig = node->pkt->pkt.signature;
3020             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3021                  && (uid && (sig->sig_class&~3) == 0x10)
3022                  && attribute == (uid->attrib_data!=NULL)
3023                  && sig->flags.chosen_selfsig )
3024               {
3025               if(sig->version < 4) {
3026                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3027
3028                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3029                          user);
3030                 m_free(user);
3031               }
3032               else {
3033                 /* This is a selfsignature which is to be replaced.
3034                    We can just ignore v3 signatures because they are
3035                    not able to carry the primary ID flag.  We also
3036                    ignore self-sigs on user IDs that are not of the
3037                    same type that we are making primary.  That is, if
3038                    we are making a user ID primary, we alter user IDs.
3039                    If we are making an attribute packet primary, we
3040                    alter attribute packets. */
3041
3042                 /* FIXME: We must make sure that we only have one
3043                    self-signature per user ID here (not counting
3044                    revocations) */
3045                 PKT_signature *newsig;
3046                 PACKET *newpkt;
3047                 const byte *p;
3048                 int action;
3049
3050                 /* see whether this signature has the primary UID flag */
3051                 p = parse_sig_subpkt (sig->hashed,
3052                                       SIGSUBPKT_PRIMARY_UID, NULL );
3053                 if ( !p )
3054                     p = parse_sig_subpkt (sig->unhashed,
3055                                           SIGSUBPKT_PRIMARY_UID, NULL );
3056                 if ( p && *p ) /* yes */
3057                     action = selected? 0 : -1;
3058                 else /* no */
3059                     action = selected? 1 : 0;
3060
3061                 if (action) {
3062                     int rc = update_keysig_packet (&newsig, sig,
3063                                                main_pk, uid, NULL,
3064                                                sk,
3065                                                change_primary_uid_cb,
3066                                                action > 0? "x":NULL );
3067                     if( rc ) {
3068                         log_error ("update_keysig_packet failed: %s\n",
3069                                    g10_errstr(rc));
3070                         free_secret_key( sk );
3071                         return 0;
3072                     }
3073                     /* replace the packet */
3074                     newpkt = m_alloc_clear( sizeof *newpkt );
3075                     newpkt->pkttype = PKT_SIGNATURE;
3076                     newpkt->pkt.signature = newsig;
3077                     free_packet( node->pkt );
3078                     m_free( node->pkt );
3079                     node->pkt = newpkt;
3080                     modified = 1;
3081                 }
3082               }
3083             }
3084         }
3085     }
3086
3087     free_secret_key( sk );
3088     return modified;
3089 }
3090
3091
3092 /* 
3093  * Set preferences to new values for the selected user IDs
3094  */
3095 static int
3096 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3097 {
3098     PKT_secret_key *sk;    /* copy of the main sk */
3099     PKT_public_key *main_pk;
3100     PKT_user_id *uid;
3101     KBNODE node;
3102     u32 keyid[2];
3103     int selected, select_all;
3104     int modified = 0;
3105
3106     no_primary_warning(pub_keyblock);
3107
3108     select_all = !count_selected_uids (pub_keyblock);
3109
3110     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3111     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3112
3113     /* Now we can actually change the self signature(s) */
3114     main_pk = NULL;
3115     uid = NULL;
3116     selected = 0;
3117     for ( node=pub_keyblock; node; node = node->next ) {
3118         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3119             break; /* ready */
3120
3121         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3122             main_pk = node->pkt->pkt.public_key;
3123             keyid_from_pk( main_pk, keyid );
3124         }
3125         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3126             uid = node->pkt->pkt.user_id;
3127             selected = select_all || (node->flag & NODFLG_SELUID);
3128         }
3129         else if ( main_pk && uid && selected
3130                   && node->pkt->pkttype == PKT_SIGNATURE ) {
3131             PKT_signature *sig = node->pkt->pkt.signature;
3132             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3133                  && (uid && (sig->sig_class&~3) == 0x10)
3134                  && sig->flags.chosen_selfsig ) {
3135               if( sig->version < 4 ) {
3136                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3137
3138                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3139                          user);
3140                 m_free(user);
3141               }
3142               else {
3143                 /* This is a selfsignature which is to be replaced 
3144                  * We have to ignore v3 signatures because they are
3145                  * not able to carry the preferences */
3146                 PKT_signature *newsig;
3147                 PACKET *newpkt;
3148                 int rc;
3149
3150                 rc = update_keysig_packet (&newsig, sig,
3151                                            main_pk, uid, NULL,
3152                                            sk,
3153                                            keygen_upd_std_prefs,
3154                                            NULL );
3155                 if( rc ) {
3156                     log_error ("update_keysig_packet failed: %s\n",
3157                                g10_errstr(rc));
3158                     free_secret_key( sk );
3159                     return 0;
3160                 }
3161                 /* replace the packet */
3162                 newpkt = m_alloc_clear( sizeof *newpkt );
3163                 newpkt->pkttype = PKT_SIGNATURE;
3164                 newpkt->pkt.signature = newsig;
3165                 free_packet( node->pkt );
3166                 m_free( node->pkt );
3167                 node->pkt = newpkt;
3168                 modified = 1;
3169               }
3170             }
3171         }
3172     }
3173     
3174     free_secret_key( sk );
3175     return modified;
3176 }
3177
3178
3179 static int
3180 menu_set_keyserver_url (const char *url,
3181                         KBNODE pub_keyblock, KBNODE sec_keyblock )
3182 {
3183   PKT_secret_key *sk;    /* copy of the main sk */
3184   PKT_public_key *main_pk;
3185   PKT_user_id *uid;
3186   KBNODE node;
3187   u32 keyid[2];
3188   int selected, select_all;
3189   int modified = 0;
3190   char *answer;
3191   struct keyserver_spec *keyserver;
3192
3193   no_primary_warning(pub_keyblock);
3194
3195   if(url)
3196     answer=m_strdup(url);
3197   else
3198     {
3199       answer=cpr_get_utf8("keyedit.add_keyserver",
3200                           _("Enter your preferred keyserver URL: "));
3201       if(answer[0]=='\0' || answer[0]=='\004')
3202         {
3203           m_free(answer);
3204           return 0;
3205         }
3206     }
3207
3208   /* Sanity check the format */
3209   keyserver=parse_keyserver_uri(answer,1,NULL,0);
3210   m_free(answer);
3211   if(!keyserver)
3212     {
3213       log_info(_("could not parse keyserver URL\n"));
3214       return 0;
3215     }
3216
3217   select_all = !count_selected_uids (pub_keyblock);
3218
3219   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3220   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3221
3222   /* Now we can actually change the self signature(s) */
3223   main_pk = NULL;
3224   uid = NULL;
3225   selected = 0;
3226   for ( node=pub_keyblock; node; node = node->next )
3227     {
3228       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3229         break; /* ready */
3230
3231       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
3232         {
3233           main_pk = node->pkt->pkt.public_key;
3234           keyid_from_pk( main_pk, keyid );
3235         }
3236       else if ( node->pkt->pkttype == PKT_USER_ID )
3237         {
3238           uid = node->pkt->pkt.user_id;
3239           selected = select_all || (node->flag & NODFLG_SELUID);
3240         }
3241       else if ( main_pk && uid && selected
3242                 && node->pkt->pkttype == PKT_SIGNATURE )
3243         {
3244           PKT_signature *sig = node->pkt->pkt.signature;
3245           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3246                && (uid && (sig->sig_class&~3) == 0x10) )
3247             {
3248               if( sig->version < 4 )
3249                 {