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