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