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