* keygen.c (keygen_get_std_prefs): Set reference count when creating the
[gnupg.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
28 #include <ctype.h>
29
30 #include "options.h"
31 #include "packet.h"
32 #include "errors.h"
33 #include "iobuf.h"
34 #include "keydb.h"
35 #include "memory.h"
36 #include "photoid.h"
37 #include "util.h"
38 #include "main.h"
39 #include "trustdb.h"
40 #include "filter.h"
41 #include "ttyio.h"
42 #include "status.h"
43 #include "i18n.h"
44 #include "keyserver-internal.h"
45
46 static void show_prefs( PKT_user_id *uid, 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
1073     node = find_kbnode( keyblock, PKT_SECRET_KEY );
1074     if( !node ) {
1075         log_error("Oops; secret key not found anymore!\n");
1076         goto leave;
1077     }
1078     sk = node->pkt->pkt.secret_key;
1079
1080     switch( is_secret_key_protected( sk ) ) {
1081       case -1:
1082         rc = G10ERR_PUBKEY_ALGO;
1083         break;
1084       case 0:
1085         tty_printf(_("This key is not protected.\n"));
1086         break;
1087       default:
1088         if( sk->protect.s2k.mode == 1001 ) {
1089             tty_printf(_("Secret parts of primary key are not available.\n"));
1090             no_primary_secrets = 1;
1091         }
1092         else {
1093             tty_printf(_("Key is protected.\n"));
1094             rc = check_secret_key( sk, 0 );
1095             if( !rc )
1096                 passphrase = get_last_passphrase();
1097         }
1098         break;
1099     }
1100
1101     /* unprotect all subkeys (use the supplied passphrase or ask)*/
1102     for(node=keyblock; !rc && node; node = node->next ) {
1103         if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1104             PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1105             set_next_passphrase( passphrase );
1106             rc = check_secret_key( subsk, 0 );
1107             if( !rc && !passphrase )
1108                 passphrase = get_last_passphrase();
1109         }
1110     }
1111
1112     if( rc )
1113         tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
1114     else {
1115         DEK *dek = NULL;
1116         STRING2KEY *s2k = m_alloc_secure( sizeof *s2k );
1117         const char *errtext = NULL;
1118
1119         tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
1120
1121         set_next_passphrase( NULL );
1122         for(;;) {
1123             s2k->mode = opt.s2k_mode;
1124             s2k->hash_algo = S2K_DIGEST_ALGO;
1125             dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
1126                                      s2k, 2, errtext, NULL);
1127             if( !dek ) {
1128                 errtext = N_("passphrase not correctly repeated; try again");
1129                 tty_printf ("%s.\n", _(errtext));
1130             }
1131             else if( !dek->keylen ) {
1132                 rc = 0;
1133                 tty_printf(_( "You don't want a passphrase -"
1134                             " this is probably a *bad* idea!\n\n"));
1135                 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
1136                                _("Do you really want to do this? (y/N) ")))
1137                   {
1138                     changed++;
1139                     break;
1140                   }
1141             }
1142             else { /* okay */
1143                 rc = 0;
1144                 if( !no_primary_secrets ) {
1145                     sk->protect.algo = dek->algo;
1146                     sk->protect.s2k = *s2k;
1147                     rc = protect_secret_key( sk, dek );
1148                 }
1149                 for(node=keyblock; !rc && node; node = node->next ) {
1150                     if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1151                         PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1152                         subsk->protect.algo = dek->algo;
1153                         subsk->protect.s2k = *s2k;
1154                         rc = protect_secret_key( subsk, dek );
1155                     }
1156                 }
1157                 if( rc )
1158                     log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
1159                 else
1160                     changed++;
1161                 break;
1162             }
1163         }
1164         m_free(s2k);
1165         m_free(dek);
1166     }
1167
1168   leave:
1169     m_free( passphrase );
1170     set_next_passphrase( NULL );
1171     return changed && !rc;
1172 }
1173
1174
1175 /****************
1176  * There are some keys out (due to a bug in gnupg), where the sequence
1177  * of the packets is wrong.  This function fixes that.
1178  * Returns: true if the keyblock has been fixed.
1179  *
1180  * Note:  This function does not work if there is more than one user ID.
1181  */
1182 static int
1183 fix_keyblock( KBNODE keyblock )
1184 {
1185     KBNODE node, last, subkey;
1186     int fixed=0;
1187
1188     /* locate key signatures of class 0x10..0x13 behind sub key packets */
1189     for( subkey=last=NULL, node = keyblock; node;
1190                                             last=node, node = node->next ) {
1191         switch( node->pkt->pkttype ) {
1192           case PKT_PUBLIC_SUBKEY:
1193           case PKT_SECRET_SUBKEY:
1194             if( !subkey )
1195                 subkey = last; /* actually it is the one before the subkey */
1196             break;
1197           case PKT_SIGNATURE:
1198             if( subkey ) {
1199                 PKT_signature *sig = node->pkt->pkt.signature;
1200                 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1201                     log_info(_(
1202                         "moving a key signature to the correct place\n"));
1203                     last->next = node->next;
1204                     node->next = subkey->next;
1205                     subkey->next = node;
1206                     node = last;
1207                     fixed=1;
1208                 }
1209             }
1210             break;
1211           default: break;
1212         }
1213     }
1214
1215     return fixed;
1216 }
1217
1218 static int
1219 parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
1220 {
1221   const char *p=str;
1222
1223   while(*p)
1224     {
1225       if(ascii_strncasecmp(p,"l",1)==0)
1226         {
1227           *localsig=1;
1228           p++;
1229         }
1230       else if(ascii_strncasecmp(p,"nr",2)==0)
1231         {
1232           *nonrevokesig=1;
1233           p+=2;
1234         }
1235       else if(ascii_strncasecmp(p,"t",1)==0)
1236         {
1237           *trustsig=1;
1238           p++;
1239         }
1240       else
1241         return 0;
1242     }
1243
1244   return 1;
1245 }
1246
1247 /****************
1248  * Menu driven key editor.  If seckey_check is true, then a secret key
1249  * that matches username will be looked for.  If it is false, not all
1250  * commands will be available.
1251  *
1252  * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1253  */
1254
1255 /* Need an SK for this command */
1256 #define KEYEDIT_NEED_SK 1
1257 /* Cannot be viewing the SK for this command */
1258 #define KEYEDIT_NOT_SK  2
1259 /* Must be viewing the SK for this command */
1260 #define KEYEDIT_ONLY_SK 4
1261 /* Match the tail of the string */
1262 #define KEYEDIT_TAIL_MATCH 8
1263
1264 void
1265 keyedit_menu( const char *username, STRLIST locusr,
1266               STRLIST commands, int quiet, int seckey_check )
1267 {
1268   enum cmdids
1269     { cmdNONE = 0,
1270       cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1271       cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
1272       cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
1273       cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
1274       cmdEXPIRE, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF, cmdSETPREF,
1275       cmdPREFKS, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST, cmdCHKTRUST,
1276       cmdADDCARDKEY, cmdKEYTOCARD,
1277       cmdNOP };
1278   static struct
1279   {
1280     const char *name;
1281     enum cmdids id;
1282     int flags;
1283     const char *desc;
1284   } cmds[] =
1285     { 
1286       { "quit"    , cmdQUIT      , 0, N_("quit this menu") },
1287       { "q"       , cmdQUIT      , 0, NULL   },
1288       { "save"    , cmdSAVE      , 0, N_("save and quit") },
1289       { "help"    , cmdHELP      , 0, N_("show this help") },
1290       { "?"       , cmdHELP      , 0, NULL   },
1291       { "fpr"     , cmdFPR       , 0, N_("show fingerprint") },
1292       { "list"    , cmdLIST      , 0, N_("list key and user IDs") },
1293       { "l"       , cmdLIST      , 0, NULL   },
1294       { "uid"     , cmdSELUID    , 0, N_("select user ID N") },
1295       { "key"     , cmdSELKEY    , 0, N_("select secondary key N") },
1296       { "check"   , cmdCHECK     , 0, N_("list signatures") },
1297       { "c"       , cmdCHECK     , 0, NULL },
1298       { "sign"    , cmdSIGN      , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH, N_("sign the key") },
1299       { "s"       , cmdSIGN      , KEYEDIT_NOT_SK, NULL },
1300       /* "lsign" will never match since "sign" comes first and it is a
1301          tail match.  It is just here so it shows up in the help
1302          menu. */
1303       { "lsign"   , cmdNOP       , 0, N_("sign the key locally") },
1304       { "debug"   , cmdDEBUG     , 0, NULL },
1305       { "adduid"  , cmdADDUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("add a user ID") },
1306       { "addphoto", cmdADDPHOTO  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("add a photo ID") },
1307       { "deluid"  , cmdDELUID    , KEYEDIT_NOT_SK, N_("delete user ID") },
1308       /* delphoto is really deluid in disguise */
1309       { "delphoto", cmdDELUID    , KEYEDIT_NOT_SK, NULL },
1310       { "addkey"  , cmdADDKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("add a secondary key") },
1311 #ifdef ENABLE_CARD_SUPPORT
1312       { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("add a key to a smartcard") },
1313       { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK, N_("move a key to a smartcard")},
1314 #endif /*ENABLE_CARD_SUPPORT*/
1315       { "delkey"  , cmdDELKEY    , KEYEDIT_NOT_SK, N_("delete a secondary key") },
1316       { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("add a revocation key") },
1317       { "delsig"  , cmdDELSIG    , KEYEDIT_NOT_SK, N_("delete signatures") },
1318       { "expire"  , cmdEXPIRE    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("change the expire date") },
1319       { "primary" , cmdPRIMARY   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("flag user ID as primary")},
1320       { "toggle"  , cmdTOGGLE    , KEYEDIT_NEED_SK, N_("toggle between secret and public key listing") },
1321       { "t"       , cmdTOGGLE    , KEYEDIT_NEED_SK, NULL },
1322       { "pref"    , cmdPREF      , KEYEDIT_NOT_SK, N_("list preferences (expert)")},
1323       { "showpref", cmdSHOWPREF  , KEYEDIT_NOT_SK, N_("list preferences (verbose)") },
1324       { "setpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("set preference list") },
1325       /* Alias */
1326       { "updpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1327       { "keyserver",cmdPREFKS    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("set preferred keyserver URL")},
1328       { "passwd"  , cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("change the passphrase") },
1329       { "trust"   , cmdTRUST     , KEYEDIT_NOT_SK, N_("change the ownertrust") },
1330       { "revsig"  , cmdREVSIG    , KEYEDIT_NOT_SK, N_("revoke signatures") },
1331       { "revuid"  , cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("revoke a user ID") },
1332       /* Alias */
1333       { "revphoto", cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1334       { "revkey"  , cmdREVKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, N_("revoke a secondary key") },
1335       { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable a key") },
1336       { "enable"  , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable a key") },
1337       { "showphoto",cmdSHOWPHOTO , 0, N_("show photo ID") },
1338       { NULL, cmdNONE, 0, NULL }
1339     };
1340     enum cmdids cmd = 0;
1341     int rc = 0;
1342     KBNODE keyblock = NULL;
1343     KEYDB_HANDLE kdbhd = NULL;
1344     KBNODE sec_keyblock = NULL;
1345     KEYDB_HANDLE sec_kdbhd = NULL;
1346     KBNODE cur_keyblock;
1347     char *answer = NULL;
1348     int redisplay = 1;
1349     int modified = 0;
1350     int sec_modified = 0;
1351     int toggle;
1352     int have_commands = !!commands;
1353
1354     if ( opt.command_fd != -1 )
1355         ;
1356     else if( opt.batch && !have_commands )
1357       {
1358         log_error(_("can't do this in batch mode\n"));
1359         goto leave;
1360       }
1361
1362     /* get the public key */
1363     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1364     if( rc )
1365         goto leave;
1366     if( fix_keyblock( keyblock ) )
1367         modified++;
1368     if( collapse_uids( &keyblock ) )
1369         modified++;
1370     reorder_keyblock(keyblock);
1371
1372     if(seckey_check)
1373       {/* see whether we have a matching secret key */
1374         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1375
1376         sec_kdbhd = keydb_new (1);
1377         {
1378             byte afp[MAX_FINGERPRINT_LEN];
1379             size_t an;
1380
1381             fingerprint_from_pk (pk, afp, &an);
1382             while (an < MAX_FINGERPRINT_LEN) 
1383                 afp[an++] = 0;
1384             rc = keydb_search_fpr (sec_kdbhd, afp);
1385         }
1386         if (!rc)
1387           {
1388             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1389             if (rc)
1390               {
1391                 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1392                            username, g10_errstr(rc));
1393               }
1394             else
1395               {
1396                 merge_keys_and_selfsig( sec_keyblock );
1397                 if( fix_keyblock( sec_keyblock ) )
1398                   sec_modified++;
1399               }
1400           }
1401
1402         if (rc) {
1403             sec_keyblock = NULL;
1404             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1405             rc = 0;
1406         }
1407
1408         if( sec_keyblock && !quiet )
1409           tty_printf(_("Secret key is available.\n"));
1410     }
1411
1412     toggle = 0;
1413     cur_keyblock = keyblock;
1414     for(;;) { /* main loop */
1415         int i, arg_number, photo;
1416         const char *arg_string = "";
1417         char *p;
1418         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1419
1420         tty_printf("\n");
1421         if( redisplay && !quiet )
1422           {
1423             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1424             tty_printf("\n");
1425             redisplay = 0;
1426           }
1427         do {
1428             m_free(answer);
1429             if( have_commands ) {
1430                 if( commands ) {
1431                     answer = m_strdup( commands->d );
1432                     commands = commands->next;
1433                 }
1434                 else if( opt.batch ) {
1435                     answer = m_strdup("quit");
1436                 }
1437                 else
1438                     have_commands = 0;
1439             }
1440             if( !have_commands ) {
1441                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1442                 cpr_kill_prompt();
1443             }
1444             trim_spaces(answer);
1445         } while( *answer == '#' );
1446
1447         arg_number = 0; /* Yes, here is the init which egcc complains about */
1448         photo = 0; /* This too */
1449         if( !*answer )
1450             cmd = cmdLIST;
1451         else if( *answer == CONTROL_D )
1452             cmd = cmdQUIT;
1453         else if( digitp(answer ) ) {
1454             cmd = cmdSELUID;
1455             arg_number = atoi(answer);
1456         }
1457         else {
1458             if( (p=strchr(answer,' ')) ) {
1459                 *p++ = 0;
1460                 trim_spaces(answer);
1461                 trim_spaces(p);
1462                 arg_number = atoi(p);
1463                 arg_string = p;
1464             }
1465
1466             for(i=0; cmds[i].name; i++ )
1467               {
1468                 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1469                   {
1470                     size_t l=strlen(cmds[i].name);
1471                     size_t a=strlen(answer);
1472                     if(a>=l)
1473                       {
1474                         if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1475                           {
1476                             answer[a-l]='\0';
1477                             break;
1478                           }
1479                       }
1480                   }
1481                 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1482                   break;
1483               }
1484             if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1485               {
1486                 tty_printf(_("Need the secret key to do this.\n"));
1487                 cmd = cmdNOP;
1488               }
1489             else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1490                      && toggle)
1491                     ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1492                        && !toggle))
1493               {
1494                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1495                 cmd = cmdNOP;
1496               }
1497             else
1498               cmd = cmds[i].id;
1499         }
1500         switch( cmd )  {
1501           case cmdHELP:
1502             for(i=0; cmds[i].name; i++ )
1503               {
1504                 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1505                   ; /* skip if we do not have the secret key */
1506                 else if( cmds[i].desc )
1507                   tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1508               }
1509             break;
1510
1511           case cmdLIST:
1512             redisplay = 1;
1513             break;
1514
1515           case cmdFPR:
1516             show_key_and_fingerprint( keyblock );
1517             break;
1518
1519           case cmdSELUID:
1520             if( menu_select_uid( cur_keyblock, arg_number ) )
1521                 redisplay = 1;
1522             break;
1523
1524           case cmdSELKEY:
1525             if( menu_select_key( cur_keyblock, arg_number ) )
1526                 redisplay = 1;
1527             break;
1528
1529           case cmdCHECK:
1530             /* we can only do this with the public key becuase the
1531              * check functions can't cope with secret keys and it
1532              * is questionable whether this would make sense at all */
1533             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1534             break;
1535
1536           case cmdSIGN: /* sign (only the public key) */
1537             {
1538               int localsig=0,nonrevokesig=0,trustsig=0;
1539
1540               if( pk->is_revoked )
1541                 {
1542                   tty_printf(_("Key is revoked."));
1543
1544                   if(opt.expert)
1545                     {
1546                       tty_printf("  ");
1547                       if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1548                                                 _("Are you sure you still want"
1549                                                   " to sign it? (y/N) ")))
1550                         break;
1551                     }
1552                   else
1553                     {
1554                       tty_printf(_("  Unable to sign.\n"));
1555                       break;
1556                     }
1557                 }
1558
1559               if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) )
1560                 {
1561                   if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1562                                              _("Really sign all user IDs?"
1563                                                " (y/N) ")))
1564                     {
1565                       tty_printf(_("Hint: Select the user IDs to sign\n"));
1566                       break;
1567                     }
1568                 }
1569
1570               /* What sort of signing are we doing? */
1571               if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1572                 {
1573                   tty_printf(_("Unknown signature type `%s'\n"),answer);
1574                   break;
1575                 }
1576
1577               sign_uids(keyblock, locusr, &modified,
1578                         localsig, nonrevokesig, trustsig);
1579             }
1580             break;
1581
1582           case cmdDEBUG:
1583             dump_kbnode( cur_keyblock );
1584             break;
1585
1586           case cmdTOGGLE:
1587             toggle = !toggle;
1588             cur_keyblock = toggle? sec_keyblock : keyblock;
1589             redisplay = 1;
1590             break;
1591
1592           case cmdADDPHOTO:
1593             if (RFC2440 || RFC1991 || PGP2)
1594               {
1595                 tty_printf(
1596                    _("This command is not allowed while in %s mode.\n"),
1597                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1598                 break;
1599               }
1600             photo=1;
1601             /* fall through */
1602
1603           case cmdADDUID:
1604             if( menu_adduid( keyblock, sec_keyblock, photo ) )
1605               {
1606                 update_trust = 1;
1607                 redisplay = 1;
1608                 sec_modified = modified = 1;
1609                 merge_keys_and_selfsig( sec_keyblock );
1610                 merge_keys_and_selfsig( keyblock );
1611               }
1612             break;
1613
1614           case cmdDELUID: {
1615                 int n1;
1616
1617                 if( !(n1=count_selected_uids(keyblock)) )
1618                     tty_printf(_("You must select at least one user ID.\n"));
1619                 else if( real_uids_left(keyblock) < 1 )
1620                     tty_printf(_("You can't delete the last user ID!\n"));
1621                 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1622                 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1623                             : _("Really remove this user ID? (y/N) ")
1624                        ) ) {
1625                     menu_deluid( keyblock, sec_keyblock );
1626                     redisplay = 1;
1627                     modified = 1;
1628                     if( sec_keyblock )
1629                        sec_modified = 1;
1630                 }
1631             }
1632             break;
1633
1634           case cmdDELSIG: {
1635                 int n1;
1636
1637                 if( !(n1=count_selected_uids(keyblock)) )
1638                     tty_printf(_("You must select at least one user ID.\n"));
1639                 else if( menu_delsig( keyblock ) ) {
1640                     /* no redisplay here, because it may scroll away some
1641                      * status output of delsig */
1642                     modified = 1;
1643                 }
1644             }
1645             break;
1646
1647           case cmdADDKEY:
1648             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1649                 redisplay = 1;
1650                 sec_modified = modified = 1;
1651                 merge_keys_and_selfsig( sec_keyblock );
1652                 merge_keys_and_selfsig( keyblock );
1653             }
1654             break;
1655
1656 #ifdef ENABLE_CARD_SUPPORT
1657           case cmdADDCARDKEY:
1658             if (card_generate_subkey (keyblock, sec_keyblock)) {
1659                 redisplay = 1;
1660                 sec_modified = modified = 1;
1661                 merge_keys_and_selfsig( sec_keyblock );
1662                 merge_keys_and_selfsig( keyblock );
1663             }
1664             break;
1665
1666         case cmdKEYTOCARD:
1667           {
1668             KBNODE node=NULL;
1669             switch ( count_selected_keys (sec_keyblock) )
1670               {
1671               case 0:
1672                 if (cpr_get_answer_is_yes("keyedit.keytocard.use_primary",
1673                                      _("Really move the primary key? (y/N) ")))
1674                   node = sec_keyblock;
1675                 break;
1676               case 1:
1677                 for (node = sec_keyblock; node; node = node->next )
1678                   {
1679                     if (node->pkt->pkttype == PKT_SECRET_SUBKEY 
1680                         && node->flag & NODFLG_SELKEY)
1681                       break;
1682                   }
1683                 break;
1684               default:
1685                 tty_printf(_("You must select exactly one key.\n"));
1686                 break;
1687               }
1688             if (node)
1689               {
1690                 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1691                 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1692                   {
1693                     redisplay = 1;
1694                     sec_modified = 1;
1695                   }
1696               }
1697           }
1698           break;
1699 #endif /* ENABLE_CARD_SUPPORT */
1700
1701           case cmdDELKEY: {
1702                 int n1;
1703
1704                 if( !(n1=count_selected_keys( keyblock )) )
1705                     tty_printf(_("You must select at least one key.\n"));
1706                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1707                        n1 > 1?
1708                    _("Do you really want to delete the selected keys? (y/N) "):
1709                         _("Do you really want to delete this key? (y/N) ")
1710                        ))
1711                     ;
1712                 else {
1713                     menu_delkey( keyblock, sec_keyblock );
1714                     redisplay = 1;
1715                     modified = 1;
1716                     if( sec_keyblock )
1717                        sec_modified = 1;
1718                 }
1719             }
1720             break;
1721
1722           case cmdADDREVOKER:
1723             {
1724               int sensitive=0;
1725
1726               if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1727                 sensitive=1;
1728               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1729                 redisplay = 1;
1730                 sec_modified = modified = 1;
1731                 merge_keys_and_selfsig( sec_keyblock );
1732                 merge_keys_and_selfsig( keyblock );
1733               }
1734             }
1735             break;
1736
1737           case cmdREVUID: {
1738                 int n1;
1739
1740                 if( !(n1=count_selected_uids(keyblock)) )
1741                     tty_printf(_("You must select at least one user ID.\n"));
1742                 else if( cpr_get_answer_is_yes(
1743                             "keyedit.revoke.uid.okay",
1744                        n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
1745                              : _("Really revoke this user ID? (y/N) ")
1746                        ) ) {
1747                   if(menu_revuid(keyblock,sec_keyblock))
1748                     {
1749                       modified=1;
1750                       redisplay=1;
1751                     }
1752                 }
1753             }
1754             break;
1755
1756           case cmdREVKEY:
1757             {
1758               int n1;
1759
1760               if( !(n1=count_selected_keys( keyblock )) )
1761                 {
1762                   if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
1763                                            _("Do you really want to revoke"
1764                                              " the entire key? (y/N) ")))
1765                     {
1766                       if(menu_revkey(keyblock,sec_keyblock))
1767                         modified=1;
1768
1769                       redisplay=1;
1770                     }
1771                 }
1772               else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
1773                                             n1 > 1?
1774                                             _("Do you really want to revoke"
1775                                               " the selected subkeys? (y/N) "):
1776                                             _("Do you really want to revoke"
1777                                               " this subkey? (y/N) ")))
1778                 {
1779                   if( menu_revsubkey( keyblock, sec_keyblock ) )
1780                     modified = 1;
1781
1782                   redisplay = 1;
1783                 }
1784
1785               if(modified)
1786                 merge_keys_and_selfsig( keyblock );
1787             }
1788             break;
1789
1790           case cmdEXPIRE:
1791             if( menu_expire( keyblock, sec_keyblock ) )
1792               {
1793                 merge_keys_and_selfsig( sec_keyblock );
1794                 merge_keys_and_selfsig( keyblock );
1795                 sec_modified = 1;
1796                 modified = 1;
1797                 redisplay = 1;
1798               }
1799             break;
1800
1801           case cmdPRIMARY:
1802             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1803                 merge_keys_and_selfsig( keyblock );
1804                 modified = 1;
1805                 redisplay = 1;
1806             }
1807             break;
1808
1809           case cmdPASSWD:
1810             if( change_passphrase( sec_keyblock ) )
1811                 sec_modified = 1;
1812             break;
1813
1814           case cmdTRUST:
1815             if(opt.trust_model==TM_EXTERNAL)
1816               {
1817                 tty_printf(_("Owner trust may not be set while "
1818                              "using an user provided trust database\n"));
1819                 break;
1820               }
1821
1822             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1823             tty_printf("\n");
1824             if( edit_ownertrust( find_kbnode( keyblock,
1825                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1826                 redisplay = 1;
1827                 /* No real need to set update_trust here as
1828                    edit_ownertrust() calls revalidation_mark()
1829                    anyway. */
1830                 update_trust=1;
1831             }
1832             break;
1833
1834           case cmdPREF:
1835             show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1836             break;
1837
1838           case cmdSHOWPREF:
1839             show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1840             break;
1841
1842           case cmdSETPREF:
1843             {
1844               PKT_user_id *tempuid;
1845
1846               keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
1847
1848               tempuid=keygen_get_std_prefs();
1849               tty_printf(_("Set preference list to:\n"));
1850               show_prefs(tempuid,NULL,1);
1851               free_user_id(tempuid);
1852
1853               if(cpr_get_answer_is_yes("keyedit.setpref.okay",
1854                                        count_selected_uids (keyblock)?
1855                                        _("Really update the preferences"
1856                                          " for the selected user IDs? (y/N) "):
1857                                        _("Really update the preferences? (y/N) ")))
1858                 {
1859                   if ( menu_set_preferences (keyblock, sec_keyblock) )
1860                     {
1861                       merge_keys_and_selfsig (keyblock);
1862                       modified = 1;
1863                       redisplay = 1;
1864                     }
1865                 }
1866             }
1867             break;
1868
1869           case cmdPREFKS:
1870             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
1871                                          keyblock, sec_keyblock ) )
1872               {
1873                 merge_keys_and_selfsig( keyblock );
1874                 modified = 1;
1875                 redisplay = 1;
1876               }
1877             break;
1878
1879           case cmdNOP:
1880             break;
1881
1882           case cmdREVSIG:
1883             if( menu_revsig( keyblock ) ) {
1884                 redisplay = 1;
1885                 modified = 1;
1886             }
1887             break;
1888
1889           case cmdENABLEKEY:
1890           case cmdDISABLEKEY:
1891             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1892                 redisplay = 1;
1893                 modified = 1;
1894             }
1895             break;
1896
1897          case cmdSHOWPHOTO:
1898            menu_showphoto(keyblock);
1899            break;
1900
1901           case cmdQUIT:
1902             if( have_commands )
1903                 goto leave;
1904             if( !modified && !sec_modified )
1905                 goto leave;
1906             if( !cpr_get_answer_is_yes("keyedit.save.okay",
1907                                         _("Save changes? (y/N) ")) ) {
1908                 if( cpr_enabled()
1909                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
1910                                              _("Quit without saving? (y/N) ")))
1911                     goto leave;
1912                 break;
1913             }
1914             /* fall thru */
1915           case cmdSAVE:
1916             if( modified || sec_modified  ) {
1917                 if( modified ) {
1918                     rc = keydb_update_keyblock (kdbhd, keyblock);
1919                     if( rc ) {
1920                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
1921                         break;
1922                     }
1923                 }
1924                 if( sec_modified ) {
1925                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1926                     if( rc ) {
1927                         log_error( _("update secret failed: %s\n"),
1928                                    g10_errstr(rc) );
1929                         break;
1930                     }
1931                 }
1932             }
1933             else
1934                 tty_printf(_("Key not changed so no update needed.\n"));
1935
1936             if( update_trust )
1937               {
1938                 revalidation_mark ();
1939                 update_trust=0;
1940               }
1941             goto leave;
1942
1943           case cmdINVCMD:
1944           default:
1945             tty_printf("\n");
1946             tty_printf(_("Invalid command  (try \"help\")\n"));
1947             break;
1948         }
1949     } /* end main loop */
1950
1951   leave:
1952     release_kbnode( keyblock );
1953     release_kbnode( sec_keyblock );
1954     keydb_release (kdbhd);
1955     m_free(answer);
1956 }
1957
1958
1959 /****************
1960  * show preferences of a public keyblock.
1961  */
1962 static void
1963 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
1964 {
1965     const prefitem_t fake={0,0};
1966     const prefitem_t *prefs;
1967     int i;
1968
1969     if( !uid )
1970         return;
1971
1972     if( uid->prefs )
1973         prefs=uid->prefs;
1974     else if(verbose)
1975         prefs=&fake;
1976     else
1977       return;
1978
1979     if (verbose) {
1980         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1981
1982         tty_printf ("     ");
1983         tty_printf (_("Cipher: "));
1984         for(i=any=0; prefs[i].type; i++ ) {
1985             if( prefs[i].type == PREFTYPE_SYM ) {
1986                 const char *s = cipher_algo_to_string (prefs[i].value);
1987                 
1988                 if (any)
1989                     tty_printf (", ");
1990                 any = 1;
1991                 /* We don't want to display strings for experimental algos */
1992                 if (s && prefs[i].value < 100 )
1993                     tty_printf ("%s", s );
1994                 else
1995                     tty_printf ("[%d]", prefs[i].value);
1996                 if (prefs[i].value == CIPHER_ALGO_3DES )
1997                     des_seen = 1;
1998             }    
1999         }
2000         if (!des_seen) {
2001             if (any)
2002                 tty_printf (", ");
2003             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
2004         }
2005         tty_printf ("\n     ");
2006         tty_printf (_("Digest: "));
2007         for(i=any=0; prefs[i].type; i++ ) {
2008             if( prefs[i].type == PREFTYPE_HASH ) {
2009                 const char *s = digest_algo_to_string (prefs[i].value);
2010                 
2011                 if (any)
2012                     tty_printf (", ");
2013                 any = 1;
2014                 /* We don't want to display strings for experimental algos */
2015                 if (s && prefs[i].value < 100 )
2016                     tty_printf ("%s", s );
2017                 else
2018                     tty_printf ("[%d]", prefs[i].value);
2019                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2020                     sha1_seen = 1;
2021             }
2022         }
2023         if (!sha1_seen) {
2024             if (any)
2025                 tty_printf (", ");
2026             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
2027         }
2028         tty_printf ("\n     ");
2029         tty_printf (_("Compression: "));
2030         for(i=any=0; prefs[i].type; i++ ) {
2031             if( prefs[i].type == PREFTYPE_ZIP ) {
2032                 const char *s=compress_algo_to_string(prefs[i].value);
2033                 
2034                 if (any)
2035                     tty_printf (", ");
2036                 any = 1;
2037                 /* We don't want to display strings for experimental algos */
2038                 if (s && prefs[i].value < 100 )
2039                     tty_printf ("%s", s );
2040                 else
2041                     tty_printf ("[%d]", prefs[i].value);
2042                 if (prefs[i].value == COMPRESS_ALGO_NONE )
2043                     uncomp_seen = 1;
2044             }
2045         }
2046         if (!uncomp_seen) {
2047             if (any)
2048                 tty_printf (", ");
2049             else {
2050               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2051               tty_printf (", ");
2052             }
2053             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2054         }
2055         if(uid->mdc_feature || !uid->ks_modify)
2056           {
2057             tty_printf ("\n     ");
2058             tty_printf (_("Features: "));
2059             any=0;
2060             if(uid->mdc_feature)
2061               {
2062                 tty_printf ("MDC");
2063                 any=1;
2064               }
2065             if(!uid->ks_modify)
2066               {
2067                 if(any)
2068                   tty_printf (", ");
2069                 tty_printf (_("Keyserver no-modify"));
2070               }
2071           }
2072         tty_printf("\n");
2073
2074         if(selfsig)
2075           {
2076             const byte *pref_ks;
2077             size_t pref_ks_len;
2078
2079             pref_ks=parse_sig_subpkt(selfsig->hashed,
2080                                      SIGSUBPKT_PREF_KS,&pref_ks_len);
2081             if(pref_ks && pref_ks_len)
2082               {
2083                 tty_printf ("     ");
2084                 tty_printf(_("Preferred keyserver: "));
2085                 tty_print_utf8_string(pref_ks,pref_ks_len);
2086                 tty_printf("\n");
2087               }
2088           }
2089     }
2090     else {
2091         tty_printf("    ");
2092         for(i=0; prefs[i].type; i++ ) {
2093             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
2094                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
2095                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2096                                  prefs[i].value);
2097         }
2098         if (uid->mdc_feature)
2099             tty_printf (" [mdc]");
2100         if (!uid->ks_modify)
2101             tty_printf (" [no-ks-modify]");
2102         tty_printf("\n");
2103     }
2104 }
2105
2106
2107 /* This is the version of show_key_with_all_names used when
2108    opt.with_colons is used.  It prints all available data in a easy to
2109    parse format and does not translate utf8 */
2110 static void
2111 show_key_with_all_names_colon (KBNODE keyblock)
2112 {
2113   KBNODE node;
2114   int i, j, ulti_hack=0;
2115   byte pk_version=0;
2116   PKT_public_key *primary=NULL;
2117
2118   /* the keys */
2119   for ( node = keyblock; node; node = node->next )
2120     {
2121       if (node->pkt->pkttype == PKT_PUBLIC_KEY
2122           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2123         {
2124           PKT_public_key *pk = node->pkt->pkt.public_key;
2125           u32 keyid[2];
2126
2127           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2128             {
2129               pk_version = pk->version;
2130               primary=pk;
2131             }
2132
2133           keyid_from_pk (pk, keyid);
2134
2135           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2136           if (!pk->is_valid)
2137             putchar ('i');
2138           else if (pk->is_revoked)
2139             putchar ('r');
2140           else if (pk->has_expired)
2141             putchar ('e');
2142           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2143             {
2144               int trust = get_validity_info (pk, NULL);
2145               if(trust=='u')
2146                 ulti_hack=1;
2147               putchar (trust);
2148             }
2149
2150           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2151                   nbits_from_pk (pk),
2152                   pk->pubkey_algo,
2153                   (ulong)keyid[0], (ulong)keyid[1],
2154                   (ulong)pk->timestamp,
2155                   (ulong)pk->expiredate );
2156           if (node->pkt->pkttype==PKT_PUBLIC_KEY
2157               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2158             putchar(get_ownertrust_info (pk));
2159           putchar(':');
2160           putchar('\n');
2161           
2162           print_fingerprint (pk, NULL, 0);
2163
2164           /* print the revoker record */
2165           if( !pk->revkey && pk->numrevkeys )
2166             BUG();
2167           else
2168             {
2169               for (i=0; i < pk->numrevkeys; i++)
2170                 {
2171                   byte *p;
2172
2173                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
2174                   p = pk->revkey[i].fpr;
2175                   for (j=0; j < 20; j++, p++ )
2176                     printf ("%02X", *p);
2177                   printf (":%02x%s:\n", pk->revkey[i].class,
2178                           (pk->revkey[i].class&0x40)?"s":"");
2179                 }
2180             }
2181         }
2182     }
2183   
2184     /* the user ids */
2185     i = 0;
2186     for (node = keyblock; node; node = node->next) 
2187       {
2188         if ( node->pkt->pkttype == PKT_USER_ID )
2189           {
2190             PKT_user_id *uid = node->pkt->pkt.user_id;
2191
2192             ++i;
2193
2194             if(uid->attrib_data)
2195               printf("uat:");
2196             else
2197               printf("uid:");
2198
2199             if ( uid->is_revoked )
2200               printf("r::::::::");
2201             else if ( uid->is_expired )
2202               printf("e::::::::");
2203             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2204               printf("::::::::");
2205             else
2206               {
2207                 int uid_validity;
2208
2209                 if( primary && !ulti_hack )
2210                   uid_validity = get_validity_info( primary, uid );
2211                 else
2212                   uid_validity = 'u';
2213                 printf("%c::::::::",uid_validity);
2214               }
2215
2216             if(uid->attrib_data)
2217               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2218             else
2219               print_string (stdout, uid->name, uid->len, ':');
2220
2221             putchar (':');
2222             /* signature class */
2223             putchar (':');
2224             /* capabilities */
2225             putchar (':');
2226             /* preferences */
2227             if (pk_version>3 || uid->selfsigversion>3)
2228               {
2229                 const prefitem_t *prefs = uid->prefs;
2230                 
2231                 for (j=0; prefs && prefs[j].type; j++)
2232                   {
2233                     if (j)
2234                       putchar (' ');
2235                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2236                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2237                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2238                             prefs[j].value);
2239                   } 
2240                 if (uid->mdc_feature)
2241                   printf (",mdc");
2242                 if (!uid->ks_modify)
2243                   printf (",no-ks-modify");
2244               } 
2245             putchar (':');
2246             /* flags */
2247             printf ("%d,", i);
2248             if (uid->is_primary)
2249               putchar ('p');
2250             if (uid->is_revoked)
2251               putchar ('r');
2252             if (uid->is_expired)
2253               putchar ('e');
2254             if ((node->flag & NODFLG_SELUID))
2255               putchar ('s');
2256             if ((node->flag & NODFLG_MARK_A))
2257               putchar ('m');
2258             putchar (':');
2259             putchar('\n');
2260           }
2261       }
2262 }
2263
2264
2265 /****************
2266  * Display the key a the user ids, if only_marked is true, do only
2267  * so for user ids with mark A flag set and dont display the index number
2268  */
2269 static void
2270 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2271                          int with_fpr, int with_subkeys, int with_prefs )
2272 {
2273     KBNODE node;
2274     int i;
2275     int do_warn = 0;
2276     byte pk_version=0;
2277     PKT_public_key *primary=NULL;
2278
2279     if (opt.with_colons)
2280       {
2281         show_key_with_all_names_colon (keyblock);
2282         return;
2283       }
2284
2285     /* the keys */
2286     for( node = keyblock; node; node = node->next ) {
2287         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2288             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
2289             PKT_public_key *pk = node->pkt->pkt.public_key;
2290             const char *otrust="err",*trust="err";
2291
2292             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2293                 /* do it here, so that debug messages don't clutter the
2294                  * output */
2295                 static int did_warn = 0;
2296
2297                 trust = get_validity_string (pk, NULL);
2298                 otrust = get_ownertrust_string (pk);
2299
2300                 /* Show a warning once */
2301                 if (!did_warn
2302                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2303                     did_warn = 1;
2304                     do_warn = 1;
2305                 }
2306
2307                 pk_version=pk->version;
2308                 primary=pk;
2309             }
2310
2311             if(with_revoker)
2312               {
2313                 if( !pk->revkey && pk->numrevkeys )
2314                   BUG();
2315                 else
2316                   for(i=0;i<pk->numrevkeys;i++)
2317                     {
2318                       u32 r_keyid[2];
2319                       char *user;
2320                       const char *algo=
2321                         pubkey_algo_to_string(pk->revkey[i].algid);
2322
2323                       keyid_from_fingerprint(pk->revkey[i].fpr,
2324                                              MAX_FINGERPRINT_LEN,r_keyid);
2325
2326                       user=get_user_id_string_native(r_keyid);
2327                       tty_printf(_("This key may be revoked by %s key %s"),
2328                                  algo?algo:"?",user);
2329
2330                       if(pk->revkey[i].class&0x40)
2331                         {
2332                           tty_printf(" ");
2333                           tty_printf(_("(sensitive)"));
2334                         }
2335
2336                       tty_printf ("\n");
2337                       m_free(user);
2338                     }
2339               }
2340
2341             keyid_from_pk(pk,NULL);
2342             tty_printf("%s%c %4u%c/%s  ",
2343                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2344                        (node->flag & NODFLG_SELKEY)? '*':' ',
2345                        nbits_from_pk( pk ),
2346                        pubkey_letter( pk->pubkey_algo ),
2347                        keystr(pk->keyid));
2348
2349             tty_printf(_("created: %s"),datestr_from_pk(pk));
2350             tty_printf("  ");
2351             if(pk->is_revoked)
2352               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2353             else if(pk->has_expired)
2354               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2355             else
2356               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2357             tty_printf("  ");
2358             tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2359             tty_printf("\n");
2360
2361             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2362               {
2363                 if(opt.trust_model!=TM_ALWAYS)
2364                   {
2365                     tty_printf("%*s", (int)keystrlen()+13,"");
2366                     /* Ownertrust is only meaningful for the PGP or
2367                        classic trust models */
2368                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2369                       {
2370                         int width=14-strlen(otrust);
2371                         if(width<=0)
2372                           width=1;
2373                         tty_printf(_("trust: %s"), otrust);
2374                         tty_printf("%*s",width,"");
2375                       }
2376                     
2377                     tty_printf(_("validity: %s"), trust );
2378                     tty_printf("\n");
2379                   }
2380                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2381                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2382                   {
2383                     tty_printf("*** ");
2384                     tty_printf(_("This key has been disabled"));
2385                     tty_printf("\n");
2386                   }
2387               }
2388
2389             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2390               {
2391                 print_fingerprint ( pk, NULL, 2 );
2392                 tty_printf("\n");
2393               }
2394         }
2395         else if( node->pkt->pkttype == PKT_SECRET_KEY
2396             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2397           {
2398             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2399             tty_printf("%s%c %4u%c/%s  ",
2400                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2401                        (node->flag & NODFLG_SELKEY)? '*':' ',
2402                        nbits_from_sk( sk ),
2403                        pubkey_letter( sk->pubkey_algo ),
2404                        keystr_from_sk(sk));
2405             tty_printf(_("created: %s"),datestr_from_sk(sk));
2406             tty_printf("  ");
2407             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2408             tty_printf("\n");
2409             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2410               {
2411                 tty_printf("                     ");
2412                 tty_printf(_("card-no: ")); 
2413                 if (sk->protect.ivlen == 16
2414                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2415                   { /* This is an OpenPGP card. */
2416                     for (i=8; i < 14; i++)
2417                       {
2418                         if (i == 10)
2419                           tty_printf (" ");
2420                         tty_printf ("%02X", sk->protect.iv[i]);
2421                       }
2422                   }
2423                 else
2424                   { /* Something is wrong: Print all. */
2425                     for (i=0; i < sk->protect.ivlen; i++)
2426                       tty_printf ("%02X", sk->protect.iv[i]);
2427                   }
2428                 tty_printf ("\n");
2429               }
2430           }
2431     }
2432     
2433     /* the user ids */
2434
2435     i = 0;
2436     for( node = keyblock; node; node = node->next )
2437       {
2438         if( node->pkt->pkttype == PKT_USER_ID )
2439           {
2440             PKT_user_id *uid = node->pkt->pkt.user_id;
2441             ++i;
2442             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A)))
2443               {
2444                 if(!only_marked && primary)
2445                   tty_printf("%s ",uid_trust_string_fixed(primary,uid));
2446
2447                 if( only_marked )
2448                   tty_printf("     ");
2449                 else if( node->flag & NODFLG_SELUID )
2450                   tty_printf("(%d)* ", i);
2451                 else if( uid->is_primary )
2452                   tty_printf("(%d). ", i);
2453                 else
2454                   tty_printf("(%d)  ", i);
2455                 tty_print_utf8_string( uid->name, uid->len );
2456                 tty_printf("\n");
2457                 if( with_prefs )
2458                   {
2459                     if(pk_version>3 || uid->selfsigversion>3)
2460                       {
2461                         PKT_signature *selfsig=NULL;
2462                         KBNODE signode;
2463
2464                         for(signode=node->next;
2465                             signode && signode->pkt->pkttype==PKT_SIGNATURE;
2466                             signode=signode->next)
2467                           {
2468                             if(signode->pkt->pkt.signature->
2469                                flags.chosen_selfsig)
2470                               {
2471                                 selfsig=signode->pkt->pkt.signature;
2472                                 break;
2473                               }
2474                           }
2475
2476                         show_prefs (uid, selfsig, with_prefs == 2);
2477                       }
2478                     else
2479                       tty_printf(_("There are no preferences on a"
2480                                    " PGP 2.x-style user ID.\n"));
2481                   }
2482               }
2483           }
2484       }
2485
2486     if (do_warn)
2487         tty_printf (_("Please note that the shown key validity"
2488                       " is not necessarily correct\n"
2489                       "unless you restart the program.\n")); 
2490 }
2491
2492
2493 /* Display basic key information.  This fucntion is suitable to show
2494    information on the key without any dependencies on the trustdb or
2495    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2496    a secret key.*/
2497 void
2498 show_basic_key_info ( KBNODE keyblock )
2499 {
2500   KBNODE node;
2501   int i;
2502
2503   /* The primary key */
2504   for (node = keyblock; node; node = node->next)
2505     {
2506       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2507         {
2508           PKT_public_key *pk = node->pkt->pkt.public_key;
2509           
2510           /* Note, we use the same format string as in other show
2511              functions to make the translation job easier. */
2512           tty_printf ("%s  %4u%c/%s  ",
2513                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2514                       nbits_from_pk( pk ),
2515                       pubkey_letter( pk->pubkey_algo ),
2516                       keystr_from_pk(pk));
2517           tty_printf(_("created: %s"),datestr_from_pk(pk));
2518           tty_printf("  ");
2519           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2520           tty_printf("\n");
2521           print_fingerprint ( pk, NULL, 3 );
2522           tty_printf("\n");
2523         }
2524       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2525         {
2526           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2527           tty_printf("%s  %4u%c/%s",
2528                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2529                      nbits_from_sk( sk ),
2530                      pubkey_letter( sk->pubkey_algo ),
2531                      keystr_from_sk(sk));
2532           tty_printf(_("created: %s"),datestr_from_sk(sk));
2533           tty_printf("  ");
2534           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2535           tty_printf("\n");
2536           print_fingerprint (NULL, sk, 3 );
2537           tty_printf("\n");
2538         }
2539     }
2540
2541   /* The user IDs. */
2542   for (i=0, node = keyblock; node; node = node->next)
2543     {
2544       if (node->pkt->pkttype == PKT_USER_ID)
2545         {
2546           PKT_user_id *uid = node->pkt->pkt.user_id;
2547           ++i;
2548      
2549           tty_printf ("     ");
2550           if (uid->is_revoked)
2551             tty_printf("[%s] ",_("revoked"));
2552           else if ( uid->is_expired )
2553             tty_printf("[%s] ",_("expired"));
2554           tty_print_utf8_string (uid->name, uid->len);
2555           tty_printf ("\n");
2556         }
2557     }
2558 }
2559
2560 static void
2561 show_key_and_fingerprint( KBNODE keyblock )
2562 {
2563   KBNODE node;
2564   PKT_public_key *pk = NULL;
2565
2566   for( node = keyblock; node; node = node->next )
2567     {
2568       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2569         {
2570           pk = node->pkt->pkt.public_key;
2571           tty_printf("pub   %4u%c/%s %s ",
2572                      nbits_from_pk( pk ),
2573                      pubkey_letter( pk->pubkey_algo ),
2574                      keystr_from_pk(pk),
2575                      datestr_from_pk(pk) );
2576         }
2577       else if( node->pkt->pkttype == PKT_USER_ID )
2578         {
2579           PKT_user_id *uid = node->pkt->pkt.user_id;
2580           tty_print_utf8_string( uid->name, uid->len );
2581           break;
2582         }
2583     }
2584   tty_printf("\n");
2585   if( pk )
2586     print_fingerprint( pk, NULL, 2 );
2587 }
2588
2589
2590 /* Show a warning if no uids on the key have the primary uid flag
2591    set. */
2592 static void
2593 no_primary_warning(KBNODE keyblock)
2594 {
2595   KBNODE node;
2596   int have_primary=0,uid_count=0;
2597
2598   /* TODO: if we ever start behaving differently with a primary or
2599      non-primary attribute ID, we will need to check for attributes
2600      here as well. */
2601
2602   for(node=keyblock; node; node = node->next)
2603     {
2604       if(node->pkt->pkttype==PKT_USER_ID
2605          && node->pkt->pkt.user_id->attrib_data==NULL)
2606         {
2607           uid_count++;
2608
2609           if(node->pkt->pkt.user_id->is_primary==2)
2610             {
2611               have_primary=1;
2612               break;
2613             }
2614         }
2615     }
2616
2617   if(uid_count>1 && !have_primary)
2618     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2619                " may\n              cause a different user ID to become"
2620                " the assumed primary.\n"));
2621 }
2622
2623 /****************
2624  * Ask for a new user id, do the selfsignature and put it into
2625  * both keyblocks.
2626  * Return true if there is a new user id
2627  */
2628 static int
2629 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2630 {
2631     PKT_user_id *uid;
2632     PKT_public_key *pk=NULL;
2633     PKT_secret_key *sk=NULL;
2634     PKT_signature *sig=NULL;
2635     PACKET *pkt;
2636     KBNODE node;
2637     KBNODE pub_where=NULL, sec_where=NULL;
2638     int rc;
2639
2640     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2641         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2642             pk = node->pkt->pkt.public_key;
2643         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2644             break;
2645     }
2646     if( !node ) /* no subkey */
2647         pub_where = NULL;
2648     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2649         if( node->pkt->pkttype == PKT_SECRET_KEY )
2650             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2651         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2652             break;
2653     }
2654     if( !node ) /* no subkey */
2655         sec_where = NULL;
2656     assert(pk && sk);
2657
2658     if(photo) {
2659       int hasattrib=0;
2660
2661       for( node = pub_keyblock; node; node = node->next )
2662         if( node->pkt->pkttype == PKT_USER_ID &&
2663             node->pkt->pkt.user_id->attrib_data!=NULL)
2664           {
2665             hasattrib=1;
2666             break;
2667           }
2668
2669       /* It is legal but bad for compatibility to add a photo ID to a
2670          v3 key as it means that PGP2 will not be able to use that key
2671          anymore.  Also, PGP may not expect a photo on a v3 key.
2672          Don't bother to ask this if the key already has a photo - any
2673          damage has already been done at that point. -dms */
2674       if(pk->version==3 && !hasattrib)
2675         {
2676           if(opt.expert)
2677             {
2678               tty_printf(_("WARNING: This is a PGP2-style key.  "
2679                            "Adding a photo ID may cause some versions\n"
2680                            "         of PGP to reject this key.\n"));
2681
2682               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2683                                         _("Are you sure you still want "
2684                                           "to add it? (y/N) ")))
2685                 return 0;
2686             }
2687           else
2688             {
2689               tty_printf(_("You may not add a photo ID to "
2690                            "a PGP2-style key.\n"));
2691               return 0;
2692             }
2693         }
2694
2695       uid = generate_photo_id(pk);
2696     } else
2697       uid = generate_user_id();
2698     if( !uid )
2699         return 0;
2700
2701     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2702                              keygen_add_std_prefs, pk );
2703     free_secret_key( sk );
2704     if( rc ) {
2705         log_error("signing failed: %s\n", g10_errstr(rc) );
2706         free_user_id(uid);
2707         return 0;
2708     }
2709
2710     /* insert/append to secret keyblock */
2711     pkt = m_alloc_clear( sizeof *pkt );
2712     pkt->pkttype = PKT_USER_ID;
2713     pkt->pkt.user_id = scopy_user_id(uid);
2714     node = new_kbnode(pkt);
2715     if( sec_where )
2716         insert_kbnode( sec_where, node, 0 );
2717     else
2718         add_kbnode( sec_keyblock, node );
2719     pkt = m_alloc_clear( sizeof *pkt );
2720     pkt->pkttype = PKT_SIGNATURE;
2721     pkt->pkt.signature = copy_signature(NULL, sig);
2722     if( sec_where )
2723         insert_kbnode( node, new_kbnode(pkt), 0 );
2724     else
2725         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2726     /* insert/append to public keyblock */
2727     pkt = m_alloc_clear( sizeof *pkt );
2728     pkt->pkttype = PKT_USER_ID;
2729     pkt->pkt.user_id = uid;
2730     node = new_kbnode(pkt);
2731     if( pub_where )
2732         insert_kbnode( pub_where, node, 0 );
2733     else
2734         add_kbnode( pub_keyblock, node );
2735     pkt = m_alloc_clear( sizeof *pkt );
2736     pkt->pkttype = PKT_SIGNATURE;
2737     pkt->pkt.signature = copy_signature(NULL, sig);
2738     if( pub_where )
2739         insert_kbnode( node, new_kbnode(pkt), 0 );
2740     else
2741         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2742     return 1;
2743 }
2744
2745
2746 /****************
2747  * Remove all selected userids from the keyrings
2748  */
2749 static void
2750 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2751 {
2752     KBNODE node;
2753     int selected=0;
2754
2755     for( node = pub_keyblock; node; node = node->next ) {
2756         if( node->pkt->pkttype == PKT_USER_ID ) {
2757             selected = node->flag & NODFLG_SELUID;
2758             if( selected ) {
2759                 /* Only cause a trust update if we delete a
2760                    non-revoked user id */
2761                 if(!node->pkt->pkt.user_id->is_revoked)
2762                   update_trust=1;
2763                 delete_kbnode( node );
2764                 if( sec_keyblock ) {
2765                     KBNODE snode;
2766                     int s_selected = 0;
2767                     PKT_user_id *uid = node->pkt->pkt.user_id;
2768                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2769                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2770                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2771
2772                             s_selected =
2773                                 (uid->len == suid->len
2774                                  && !memcmp( uid->name, suid->name, uid->len));
2775                             if( s_selected )
2776                                 delete_kbnode( snode );
2777                         }
2778                         else if( s_selected
2779                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2780                             delete_kbnode( snode );
2781                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2782                             s_selected = 0;
2783                     }
2784                 }
2785             }
2786         }
2787         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2788             delete_kbnode( node );
2789         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2790             selected = 0;
2791     }
2792     commit_kbnode( &pub_keyblock );
2793     if( sec_keyblock )
2794         commit_kbnode( &sec_keyblock );
2795 }
2796
2797
2798 static int
2799 menu_delsig( KBNODE pub_keyblock )
2800 {
2801     KBNODE node;
2802     PKT_user_id *uid = NULL;
2803     int changed=0;
2804
2805     for( node = pub_keyblock; node; node = node->next ) {
2806         if( node->pkt->pkttype == PKT_USER_ID ) {
2807             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2808         }
2809         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2810            int okay, valid, selfsig, inv_sig, no_key, other_err;
2811
2812             tty_printf("uid  ");
2813             tty_print_utf8_string( uid->name, uid->len );
2814             tty_printf("\n");
2815
2816             okay = inv_sig = no_key = other_err = 0;
2817             if(opt.with_colons)
2818               valid = print_and_check_one_sig_colon( pub_keyblock, node,
2819                                                &inv_sig, &no_key, &other_err,
2820                                                &selfsig, 1 );
2821             else
2822               valid = print_and_check_one_sig( pub_keyblock, node,
2823                                                &inv_sig, &no_key, &other_err,
2824                                                &selfsig, 1 );
2825
2826            if( valid ) {
2827                okay = cpr_get_answer_yes_no_quit(
2828                    "keyedit.delsig.valid",
2829                    _("Delete this good signature? (y/N/q)"));
2830
2831                /* Only update trust if we delete a good signature.
2832                   The other two cases do not affect trust. */
2833                if(okay)
2834                  update_trust=1;
2835            }
2836            else if( inv_sig || other_err )
2837                okay = cpr_get_answer_yes_no_quit(
2838                    "keyedit.delsig.invalid",
2839                    _("Delete this invalid signature? (y/N/q)"));
2840            else if( no_key )
2841                okay = cpr_get_answer_yes_no_quit(
2842                    "keyedit.delsig.unknown",
2843                    _("Delete this unknown signature? (y/N/q)"));
2844
2845             if( okay == -1 )
2846                 break;
2847            if( okay && selfsig && !cpr_get_answer_is_yes(
2848                                "keyedit.delsig.selfsig",
2849                               _("Really delete this self-signature? (y/N)") ))
2850                 okay = 0;
2851             if( okay ) {
2852                 delete_kbnode( node );
2853                 changed++;
2854             }
2855
2856         }
2857         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2858             uid = NULL;
2859     }
2860
2861     if( changed ) {
2862         commit_kbnode( &pub_keyblock );
2863         tty_printf( changed == 1? _("Deleted %d signature.\n")
2864                                 : _("Deleted %d signatures.\n"), changed );
2865     }
2866     else
2867         tty_printf( _("Nothing deleted.\n") );
2868
2869     return changed;
2870 }
2871
2872
2873 /****************
2874  * Remove some of the secondary keys
2875  */
2876 static void
2877 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2878 {
2879     KBNODE node;
2880     int selected=0;
2881
2882     for( node = pub_keyblock; node; node = node->next ) {
2883         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2884             selected = node->flag & NODFLG_SELKEY;
2885             if( selected ) {
2886                 delete_kbnode( node );
2887                 if( sec_keyblock ) {
2888                     KBNODE snode;
2889                     int s_selected = 0;
2890                     u32 ki[2];
2891
2892                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2893                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2894                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2895                             u32 ki2[2];
2896
2897                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2898                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2899                             if( s_selected )
2900                                 delete_kbnode( snode );
2901                         }
2902                         else if( s_selected
2903                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2904                             delete_kbnode( snode );
2905                         else
2906                             s_selected = 0;
2907                     }
2908                 }
2909             }
2910         }
2911         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2912             delete_kbnode( node );
2913         else
2914             selected = 0;
2915     }
2916     commit_kbnode( &pub_keyblock );
2917     if( sec_keyblock )
2918         commit_kbnode( &sec_keyblock );
2919
2920     /* No need to set update_trust here since signing keys are no
2921        longer used to certify other keys, so there is no change in
2922        trust when revoking/removing them */
2923 }
2924
2925
2926 /****************
2927  * Ask for a new revoker, do the selfsignature and put it into
2928  * both keyblocks.
2929  * Return true if there is a new revoker
2930  */
2931 static int
2932 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2933 {
2934   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2935   PKT_secret_key *sk=NULL;
2936   PKT_signature *sig=NULL;
2937   PACKET *pkt;
2938   struct revocation_key revkey;
2939   size_t fprlen;
2940   int rc;
2941
2942   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2943   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2944
2945   pk=pub_keyblock->pkt->pkt.public_key;
2946
2947   if(pk->numrevkeys==0 && pk->version==3)
2948     {
2949       /* It is legal but bad for compatibility to add a revoker to a
2950          v3 key as it means that PGP2 will not be able to use that key
2951          anymore.  Also, PGP may not expect a revoker on a v3 key.
2952          Don't bother to ask this if the key already has a revoker -
2953          any damage has already been done at that point. -dms */
2954       if(opt.expert)
2955         {
2956           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2957                        "Adding a designated revoker may cause\n"
2958                        "         some versions of PGP to reject this key.\n"));
2959
2960           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2961                                     _("Are you sure you still want "
2962                                       "to add it? (y/N) ")))
2963             return 0;
2964         }
2965       else
2966         {
2967           tty_printf(_("You may not add a designated revoker to "
2968                        "a PGP 2.x-style key.\n"));
2969           return 0;
2970         }
2971     }
2972
2973   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2974
2975   for(;;)
2976     {
2977       char *answer;
2978
2979       if(revoker_pk)
2980         free_public_key(revoker_pk);
2981
2982       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2983
2984       tty_printf("\n");
2985
2986       answer=cpr_get_utf8("keyedit.add_revoker",
2987                           _("Enter the user ID of the designated revoker: "));
2988       if(answer[0]=='\0' || answer[0]=='\004')
2989         {
2990           m_free(answer);
2991           goto fail;
2992         }
2993
2994       /* Note that I'm requesting SIG here and not CERT.  We're making
2995          a certification, but it is okay to be a subkey. */
2996       revoker_pk->req_usage=PUBKEY_USAGE_SIG;
2997       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2998       if(rc)
2999         {
3000           log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
3001           m_free(answer);
3002           continue;
3003         }
3004
3005       m_free(answer);
3006
3007       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
3008       if(fprlen!=20)
3009         {
3010           log_error(_("cannot appoint a PGP 2.x style key as a "
3011                       "designated revoker\n"));
3012           continue;
3013         }
3014
3015       revkey.class=0x80;
3016       if(sensitive)
3017         revkey.class|=0x40;
3018       revkey.algid=revoker_pk->pubkey_algo;
3019
3020       if(cmp_public_keys(revoker_pk,pk)==0)
3021         {
3022           /* This actually causes no harm (after all, a key that
3023              designates itself as a revoker is the same as a
3024              regular key), but it's easy enough to check. */
3025           log_error(_("you cannot appoint a key as its own "
3026                       "designated revoker\n"));
3027
3028           continue;
3029         }
3030
3031       keyid_from_pk(pk,NULL);
3032
3033       /* Does this revkey already exist? */
3034       if(!pk->revkey && pk->numrevkeys)
3035         BUG();
3036       else
3037         {
3038           int i;
3039
3040           for(i=0;i<pk->numrevkeys;i++)
3041             {
3042               if(memcmp(&pk->revkey[i],&revkey,
3043                         sizeof(struct revocation_key))==0)
3044                 {
3045                   char buf[50];
3046
3047                   log_error(_("this key has already been designated "
3048                               "as a revoker\n"));
3049
3050                   sprintf(buf,"%08lX%08lX",
3051                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
3052                   write_status_text(STATUS_ALREADY_SIGNED,buf);
3053
3054                   break;
3055                 }
3056             }
3057
3058           if(i<pk->numrevkeys)
3059             continue;
3060         }
3061
3062       print_pubkey_info(NULL,revoker_pk);
3063       print_fingerprint(revoker_pk,NULL,2);
3064       tty_printf("\n");
3065
3066       tty_printf(_("WARNING: appointing a key as a designated revoker "
3067                    "cannot be undone!\n"));
3068
3069       tty_printf("\n");
3070
3071       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
3072                                 _("Are you sure you want to appoint this "
3073                                   "key as a designated revoker? (y/N) ")))
3074         continue;
3075
3076       free_public_key(revoker_pk);
3077       revoker_pk=NULL;
3078       break;
3079     }
3080
3081   /* The 1F signature must be at least v4 to carry the revocation key
3082      subpacket. */
3083   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3084                            keygen_add_revkey,&revkey );
3085   if( rc )
3086     {
3087       log_error("signing failed: %s\n", g10_errstr(rc) );
3088       goto fail;
3089     }
3090
3091   free_secret_key(sk);
3092   sk=NULL;
3093
3094   /* insert into secret keyblock */
3095   pkt = m_alloc_clear( sizeof *pkt );
3096   pkt->pkttype = PKT_SIGNATURE;
3097   pkt->pkt.signature = copy_signature(NULL, sig);
3098   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3099
3100   /* insert into public keyblock */
3101   pkt = m_alloc_clear( sizeof *pkt );
3102   pkt->pkttype = PKT_SIGNATURE;
3103   pkt->pkt.signature = sig;
3104   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3105
3106   return 1;
3107
3108  fail:
3109   if(sk)
3110     free_secret_key(sk);
3111   if(sig)
3112     free_seckey_enc(sig);
3113   if(revoker_pk)
3114     free_public_key(revoker_pk);
3115
3116   return 0;
3117 }
3118
3119
3120 static int
3121 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3122 {
3123     int n1, signumber, rc;
3124     u32 expiredate;
3125     int mainkey=0;
3126     PKT_secret_key *sk;    /* copy of the main sk */
3127     PKT_public_key *main_pk, *sub_pk;
3128     PKT_user_id *uid;
3129     KBNODE node;
3130     u32 keyid[2];
3131
3132     if( count_selected_keys( sec_keyblock ) ) {
3133         tty_printf(_("Please remove selections from the secret keys.\n"));
3134         return 0;
3135     }
3136
3137     n1 = count_selected_keys( pub_keyblock );
3138     if( n1 > 1 ) {
3139         tty_printf(_("Please select at most one secondary key.\n"));
3140         return 0;
3141     }
3142     else if( n1 )
3143         tty_printf(_("Changing expiration time for a secondary key.\n"));
3144     else
3145       {
3146         tty_printf(_("Changing expiration time for the primary key.\n"));
3147         mainkey=1;
3148         no_primary_warning(pub_keyblock);
3149       }
3150
3151     expiredate = ask_expiredate();
3152     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3153     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3154
3155     /* Now we can actually change the self signature(s) */
3156     main_pk = sub_pk = NULL;
3157     uid = NULL;
3158     signumber = 0;
3159     for( node=pub_keyblock; node; node = node->next ) {
3160         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3161             main_pk = node->pkt->pkt.public_key;
3162             keyid_from_pk( main_pk, keyid );
3163             main_pk->expiredate = expiredate;
3164         }
3165         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3166                  && (node->flag & NODFLG_SELKEY ) ) {
3167             sub_pk = node->pkt->pkt.public_key;
3168             sub_pk->expiredate = expiredate;
3169         }
3170         else if( node->pkt->pkttype == PKT_USER_ID )
3171             uid = node->pkt->pkt.user_id;
3172         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3173                  && ( mainkey || sub_pk ) ) {
3174             PKT_signature *sig = node->pkt->pkt.signature;
3175             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3176                 && ( (mainkey && uid
3177                       && uid->created && (sig->sig_class&~3) == 0x10)
3178                      || (!mainkey && sig->sig_class == 0x18)  )
3179                 && sig->flags.chosen_selfsig )
3180               {
3181                 /* this is a selfsignature which is to be replaced */
3182                 PKT_signature *newsig;
3183                 PACKET *newpkt;
3184                 KBNODE sn;
3185                 int signumber2 = 0;
3186
3187                 signumber++;
3188
3189                 if( (mainkey && main_pk->version < 4)
3190                     || (!mainkey && sub_pk->version < 4 ) ) {
3191                     log_info(_(
3192                         "You can't change the expiration date of a v3 key\n"));
3193                     free_secret_key( sk );
3194                     return 0;
3195                 }
3196
3197                 /* find the corresponding secret self-signature */
3198                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3199                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3200                         PKT_signature *b = sn->pkt->pkt.signature;
3201                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3202                             && sig->sig_class == b->sig_class
3203                             && ++signumber2 == signumber )
3204                             break;
3205                     }
3206                 }
3207                 if( !sn )
3208                     log_info(_("No corresponding signature in secret ring\n"));
3209
3210                 if( mainkey )
3211                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3212                                             sk, keygen_add_key_expire, main_pk);
3213                 else
3214                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3215                                             sk, keygen_add_key_expire, sub_pk );
3216                 if( rc ) {
3217                     log_error("make_keysig_packet failed: %s\n",
3218                                                     g10_errstr(rc));
3219                     free_secret_key( sk );
3220                     return 0;
3221                 }
3222                 /* replace the packet */
3223                 newpkt = m_alloc_clear( sizeof *newpkt );
3224                 newpkt->pkttype = PKT_SIGNATURE;
3225                 newpkt->pkt.signature = newsig;
3226                 free_packet( node->pkt );
3227                 m_free( node->pkt );
3228                 node->pkt = newpkt;
3229                 if( sn ) {
3230                     newpkt = m_alloc_clear( sizeof *newpkt );
3231                     newpkt->pkttype = PKT_SIGNATURE;
3232                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3233                     free_packet( sn->pkt );
3234                     m_free( sn->pkt );
3235                     sn->pkt = newpkt;
3236                 }
3237                 sub_pk = NULL;
3238             }
3239         }
3240     }
3241
3242     free_secret_key( sk );
3243     update_trust=1;
3244     return 1;
3245 }
3246
3247 static int
3248 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3249 {
3250     byte buf[1];
3251
3252     /* first clear all primary uid flags so that we are sure none are
3253      * lingering around */
3254     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
3255     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3256
3257     /* if opaque is set,we want to set the primary id */
3258     if (opaque) { 
3259         buf[0] = 1;
3260         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3261     }
3262
3263     return 0;
3264 }
3265
3266
3267 /*
3268  * Set the primary uid flag for the selected UID.  We will also reset
3269  * all other primary uid flags.  For this to work with have to update
3270  * all the signature timestamps.  If we would do this with the current
3271  * time, we lose quite a lot of information, so we use a a kludge to
3272  * do this: Just increment the timestamp by one second which is
3273  * sufficient to updated a signature during import.
3274  */
3275 static int
3276 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3277 {
3278     PKT_secret_key *sk;    /* copy of the main sk */
3279     PKT_public_key *main_pk;
3280     PKT_user_id *uid;
3281     KBNODE node;
3282     u32 keyid[2];
3283     int selected;
3284     int attribute = 0;
3285     int modified = 0;
3286
3287     if ( count_selected_uids (pub_keyblock) != 1 ) {
3288         tty_printf(_("Please select exactly one user ID.\n"));
3289         return 0;
3290     }
3291
3292     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3293     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3294
3295     /* Now we can actually change the self signature(s) */
3296     main_pk = NULL;
3297     uid = NULL;
3298     selected = 0;
3299
3300     /* Is our selected uid an attribute packet? */
3301     for ( node=pub_keyblock; node; node = node->next )
3302       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3303         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3304
3305     for ( node=pub_keyblock; node; node = node->next ) {
3306         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3307             break; /* ready */
3308
3309         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3310             main_pk = node->pkt->pkt.public_key;
3311             keyid_from_pk( main_pk, keyid );
3312         }
3313         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3314             uid = node->pkt->pkt.user_id;
3315             selected = node->flag & NODFLG_SELUID;
3316         }
3317         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3318             PKT_signature *sig = node->pkt->pkt.signature;
3319             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3320                  && (uid && (sig->sig_class&~3) == 0x10)
3321                  && attribute == (uid->attrib_data!=NULL)
3322                  && sig->flags.chosen_selfsig )
3323               {
3324               if(sig->version < 4) {
3325                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3326
3327                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3328                          user);
3329                 m_free(user);
3330               }
3331               else {
3332                 /* This is a selfsignature which is to be replaced.
3333                    We can just ignore v3 signatures because they are
3334                    not able to carry the primary ID flag.  We also
3335                    ignore self-sigs on user IDs that are not of the
3336                    same type that we are making primary.  That is, if
3337                    we are making a user ID primary, we alter user IDs.
3338                    If we are making an attribute packet primary, we
3339                    alter attribute packets. */
3340
3341                 /* FIXME: We must make sure that we only have one
3342                    self-signature per user ID here (not counting
3343                    revocations) */
3344                 PKT_signature *newsig;
3345                 PACKET *newpkt;
3346                 const byte *p;
3347                 int action;
3348
3349                 /* see whether this signature has the primary UID flag */
3350                 p = parse_sig_subpkt (sig->hashed,
3351                                       SIGSUBPKT_PRIMARY_UID, NULL );
3352                 if ( !p )
3353                     p = parse_sig_subpkt (sig->unhashed,
3354                                           SIGSUBPKT_PRIMARY_UID, NULL );
3355                 if ( p && *p ) /* yes */
3356                     action = selected? 0 : -1;
3357                 else /* no */
3358                     action = selected? 1 : 0;
3359
3360                 if (action) {
3361                     int rc = update_keysig_packet (&newsig, sig,
3362                                                main_pk, uid, NULL,
3363                                                sk,
3364                                                change_primary_uid_cb,
3365                                                action > 0? "x":NULL );
3366                     if( rc ) {
3367                         log_error ("update_keysig_packet failed: %s\n",
3368                                    g10_errstr(rc));
3369                         free_secret_key( sk );
3370                         return 0;
3371                     }
3372                     /* replace the packet */
3373                     newpkt = m_alloc_clear( sizeof *newpkt );
3374                     newpkt->pkttype = PKT_SIGNATURE;
3375                     newpkt->pkt.signature = newsig;
3376                     free_packet( node->pkt );
3377                     m_free( node->pkt );
3378                     node->pkt = newpkt;
3379                     modified = 1;
3380                 }
3381               }
3382             }
3383         }
3384     }
3385
3386     free_secret_key( sk );
3387     return modified;
3388 }
3389
3390
3391 /* 
3392  * Set preferences to new values for the selected user IDs
3393  */
3394 static int
3395 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3396 {
3397     PKT_secret_key *sk;    /* copy of the main sk */
3398     PKT_public_key *main_pk;
3399     PKT_user_id *uid;
3400     KBNODE node;
3401     u32 keyid[2];
3402     int selected, select_all;
3403     int modified = 0;
3404
3405     no_primary_warning(pub_keyblock);
3406
3407     select_all = !count_selected_uids (pub_keyblock);
3408
3409     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3410     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3411
3412     /* Now we can actually change the self signature(s) */
3413     main_pk = NULL;
3414     uid = NULL;
3415     selected = 0;
3416     for ( node=pub_keyblock; node; node = node->next ) {
3417         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3418             break; /* ready */
3419
3420         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3421             main_pk = node->pkt->pkt.public_key;
3422             keyid_from_pk( main_pk, keyid );
3423         }
3424         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3425             uid = node->pkt->pkt.user_id;
3426             selected = select_all || (node->flag & NODFLG_SELUID);
3427         }
3428         else if ( main_pk && uid && selected
3429                   && node->pkt->pkttype == PKT_SIGNATURE ) {
3430             PKT_signature *sig = node->pkt->pkt.signature;
3431             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3432                  && (uid && (sig->sig_class&~3) == 0x10)
3433                  && sig->flags.chosen_selfsig ) {
3434               if( sig->version < 4 ) {
3435                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3436
3437                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3438                          user);
3439                 m_free(user);
3440               }
3441               else {
3442                 /* This is a selfsignature which is to be replaced 
3443                  * We have to ignore v3 signatures because they are
3444                  * not able to carry the preferences */
3445                 PKT_signature *newsig;
3446                 PACKET *newpkt;
3447                 int rc;
3448
3449                 rc = update_keysig_packet (&newsig, sig,
3450                                            main_pk, uid, NULL,
3451                                            sk,
3452                                            keygen_upd_std_prefs,
3453                                            NULL );
3454                 if( rc ) {
3455                     log_error ("update_keysig_packet failed: %s\n",
3456                                g10_errstr(rc));
3457                     free_secret_key( sk );
3458                     return 0;
3459                 }
3460                 /* replace the packet */
3461                 newpkt = m_alloc_clear( sizeof *newpkt );
3462                 newpkt->pkttype = PKT_SIGNATURE;
3463                 newpkt->pkt.signature = newsig;
3464                 free_packet( node->pkt );
3465                 m_free( node->pkt );
3466                 node->pkt = newpkt;
3467                 modified = 1;
3468               }
3469             }
3470         }
3471     }
3472     
3473     free_secret_key( sk );
3474     return modified;
3475 }
3476
3477
3478 static int
3479 menu_set_keyserver_url (const char *url,
3480                         KBNODE pub_keyblock, KBNODE sec_keyblock )
3481 {
3482   PKT_secret_key *sk;    /* copy of the main sk */
3483   PKT_public_key *main_pk;
3484   PKT_user_id *uid;
3485   KBNODE node;
3486   u32 keyid[2];
3487   int selected, select_all;
3488   int modified = 0;
3489   char *answer,*uri;
3490
3491   no_primary_warning(pub_keyblock);
3492
3493   if(url)
3494     answer=m_strdup(url);
3495   else
3496     {
3497       answer=cpr_get_utf8("keyedit.add_keyserver",
3498                           _("Enter your preferred keyserver URL: "));
3499       if(answer[0]=='\0' || answer[0]=='\004')
3500         {
3501           m_free(answer);
3502           return 0;
3503         }
3504     }
3505
3506   if(ascii_strcasecmp(answer,"none")==0)
3507     uri=NULL;
3508   else
3509     {
3510       struct keyserver_spec *keyserver=NULL;
3511       /* Sanity check the format */
3512       keyserver=parse_keyserver_uri(answer,1,NULL,0);
3513       m_free(answer);
3514       if(!keyserver)
3515         {
3516           log_info(_("could not parse keyserver URL\n"));
3517           return 0;
3518         }
3519       uri=m_strdup(keyserver->uri);
3520       free_keyserver_spec(keyserver);
3521     }
3522
3523   select_all = !count_selected_uids (pub_keyblock);
3524
3525   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3526   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3527
3528   /* Now we can actually change the self signature(s) */
3529   main_pk = NULL;
3530   uid = NULL;
3531   selected = 0;
3532   for ( node=pub_keyblock; node; node = node->next )
3533     {
3534       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3535         break; /* ready */
3536
3537       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
3538         {
3539           main_pk = node->pkt->pkt.public_key;
3540           keyid_from_pk( main_pk, keyid );
3541         }
3542       else if ( node->pkt->pkttype == PKT_USER_ID )
3543         {
3544           uid = node->pkt->pkt.user_id;
3545           selected = select_all || (node->flag & NODFLG_SELUID);
3546         }
3547       else if ( main_pk && uid && selected
3548                 && node->pkt->pkttype == PKT_SIGNATURE )
3549         {
3550           PKT_signature *sig = node->pkt->pkt.signature;
3551           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3552                && (uid && (sig->sig_class&~3) == 0x10) )
3553             {
3554               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3555               if( sig->version < 4 )
3556                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
3557                          user);
3558               else
3559                 {
3560                   /* This is a selfsignature which is to be replaced
3561                    * We have to ignore v3 signatures because they are
3562                    * not able to carry the subpacket. */
3563                   PKT_signature *newsig;
3564                   PACKET *newpkt;
3565                   int rc;
3566                   const byte *p;
3567                   size_t plen;
3568
3569                   p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
3570                   if(p && plen)
3571                     {
3572                       tty_printf("Current preferred keyserver for user"
3573                                  " ID \"%s\": ",user);
3574                       tty_print_utf8_string(p,plen);
3575                       tty_printf("\n");
3576                       if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
3577                          uri?_("Are you sure you want to replace it? (y/N) "):
3578                              _("Are you sure you want to delete it? (y/N) ")))
3579                         continue;
3580                     }
3581                   else if(uri==NULL)
3582                     {
3583                       /* There is no current keyserver URL, so there
3584                          is no point in trying to un-set it. */
3585                       continue;
3586                     }
3587
3588                   rc = update_keysig_packet (&newsig, sig,
3589                                              main_pk, uid, NULL,
3590                                              sk,
3591                                              keygen_add_keyserver_url, uri );
3592                   if( rc )
3593                     {
3594                       log_error ("update_keysig_packet failed: %s\n",
3595                                  g10_errstr(rc));
3596                       free_secret_key( sk );
3597                       m_free(uri);
3598                       return 0;
3599                     }
3600                   /* replace the packet */
3601                   newpkt = m_alloc_clear( sizeof *newpkt );
3602                   newpkt->pkttype = PKT_SIGNATURE;
3603                   newpkt->pkt.signature = newsig;
3604                   free_packet( node->pkt );
3605                   m_free( node->pkt );
3606                   node->pkt = newpkt;
3607                   modified = 1;
3608                 }
3609
3610               m_free(user);
3611             }
3612         }
3613     }
3614
3615   m_free(uri);
3616   free_secret_key( sk );
3617   return modified;
3618 }
3619
3620
3621 /****************
3622  * Select one user id or remove all selection if index is 0.
3623  * Returns: True if the selection changed;
3624  */
3625 static int
3626 menu_select_uid( KBNODE keyblock, int idx )
3627 {
3628     KBNODE node;
3629     int i;
3630
3631     /* first check that the index is valid */
3632     if( idx ) {
3633         for( i=0, node = keyblock; node; node = node->next ) {
3634             if( node->pkt->pkttype == PKT_USER_ID ) {
3635                 if( ++i == idx )
3636                     break;
3637             }
3638         }
3639         if( !node ) {
3640             tty_printf(_("No user ID with index %d\n"), idx );
3641             return 0;
3642         }
3643     }
3644     else { /* reset all */
3645         for( i=0, node = keyblock; node; node = node->next ) {
3646             if( node->pkt->pkttype == PKT_USER_ID )
3647                 node->flag &= ~NODFLG_SELUID;
3648         }
3649         return 1;
3650     }
3651     /* and toggle the new index */
3652     for( i=0, node = keyblock; node; node = node->next ) {
3653         if( node->pkt->pkttype == PKT_USER_ID ) {
3654             if( ++i == idx ) {
3655                 if( (node->flag & NODFLG_SELUID) )
3656                     node->flag &= ~NODFLG_SELUID;
3657                 else
3658                     node->flag |= NODFLG_SELUID;
3659             }
3660         }
3661     }
3662
3663     return 1;
3664 }
3665
3666 /****************
3667  * Select secondary keys
3668  * Returns: True if the selection changed;
3669  */
3670 static int
3671 menu_select_key( KBNODE keyblock, int idx )
3672 {
3673     KBNODE node;
3674     int i;
3675
3676     /* first check that the index is valid */
3677     if( idx ) {
3678         for( i=0, node = keyblock; node; node = node->next ) {
3679             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3680                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3681                 if( ++i == idx )
3682                     break;
3683             }
3684         }
3685         if( !node ) {
3686             tty_printf(_("No secondary key with index %d\n"), idx );
3687             return 0;
3688         }
3689     }
3690     else { /* reset all */
3691         for( i=0, node = keyblock; node; node = node->next ) {
3692             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3693                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3694                 node->flag &= ~NODFLG_SELKEY;
3695         }
3696         return 1;
3697     }
3698     /* and set the new index */
3699     for( i=0, node = keyblock; node; node = node->next ) {
3700         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3701             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3702             if( ++i == idx ) {
3703                 if( (node->flag & NODFLG_SELKEY) )
3704                     node->flag &= ~NODFLG_SELKEY;
3705                 else
3706                     node->flag |= NODFLG_SELKEY;
3707             }
3708         }
3709     }
3710
3711     return 1;
3712 }
3713
3714
3715 static int
3716 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3717 {
3718     KBNODE node;
3719     int i=0;
3720
3721     for( node = keyblock; node; node = node->next )
3722         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3723             i++;
3724     return i;
3725 }
3726
3727 static int
3728 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3729 {
3730     KBNODE node;
3731     int i=0;
3732
3733     for( node = keyblock; node; node = node->next )
3734         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3735               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3736             && (node->flag & flag) )
3737             i++;
3738     return i;
3739 }
3740
3741 static int
3742 count_uids( KBNODE keyblock )
3743 {
3744     KBNODE node;
3745     int i=0;
3746
3747     for( node = keyblock; node; node = node->next )
3748         if( node->pkt->pkttype == PKT_USER_ID )
3749             i++;
3750     return i;
3751 }
3752
3753
3754 /****************
3755  * Returns true if there is at least one selected user id
3756  */
3757 static int
3758 count_selected_uids( KBNODE keyblock )
3759 {
3760     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3761 }
3762
3763 static int
3764 count_selected_keys( KBNODE keyblock )
3765 {
3766     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3767 }
3768
3769 /* returns how many real (i.e. not attribute) uids are unmarked */
3770 static int
3771 real_uids_left( KBNODE keyblock )
3772 {
3773   KBNODE node;
3774   int real=0;
3775
3776   for(node=keyblock;node;node=node->next)
3777     if(node->pkt->pkttype==PKT_USER_ID &&