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