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