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