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