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