* gpg.sgml: Document -K.
[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            cmdADDCARDKEY,
1195            cmdNOP };
1196     static struct { const char *name;
1197                     enum cmdids id;
1198                     int need_sk;
1199                     int not_with_sk;
1200                     const char *desc;
1201                   } cmds[] = {
1202         { N_("quit")    , cmdQUIT      , 0,0, N_("quit this menu") },
1203         { N_("q")       , cmdQUIT      , 0,0, NULL   },
1204         { N_("save")    , cmdSAVE      , 0,0, N_("save and quit") },
1205         { N_("help")    , cmdHELP      , 0,0, N_("show this help") },
1206         {    "?"        , cmdHELP      , 0,0, NULL   },
1207         { N_("fpr")     , cmdFPR       , 0,0, N_("show fingerprint") },
1208         { N_("list")    , cmdLIST      , 0,0, N_("list key and user IDs") },
1209         { N_("l")       , cmdLIST      , 0,0, NULL   },
1210         { N_("uid")     , cmdSELUID    , 0,0, N_("select user ID N") },
1211         { N_("key")     , cmdSELKEY    , 0,0, N_("select secondary key N") },
1212         { N_("check")   , cmdCHECK     , 0,0, N_("list signatures") },
1213         { N_("c")       , cmdCHECK     , 0,0, NULL },
1214         { N_("sign")    , cmdSIGN      , 0,1, N_("sign the key") },
1215         { N_("s")       , cmdSIGN      , 0,1, NULL },
1216         { N_("tsign")   , cmdTSIGN     , 0,1, N_("make a trust signature")},
1217         { N_("lsign")   , cmdLSIGN     , 0,1, N_("sign the key locally") },
1218         { N_("nrsign")  , cmdNRSIGN    , 0,1, N_("sign the key non-revocably") },
1219         { N_("nrlsign") , cmdNRLSIGN   , 0,1, N_("sign the key locally and non-revocably") },
1220         { N_("debug")   , cmdDEBUG     , 0,0, NULL },
1221         { N_("adduid")  , cmdADDUID    , 1,1, N_("add a user ID") },
1222         { N_("addphoto"), cmdADDPHOTO  , 1,1, N_("add a photo ID") },
1223         { N_("deluid")  , cmdDELUID    , 0,1, N_("delete user ID") },
1224         /* delphoto is really deluid in disguise */
1225         { N_("delphoto"), cmdDELUID    , 0,1, NULL },
1226         { N_("addkey")  , cmdADDKEY    , 1,1, N_("add a secondary key") },
1227         { N_("addcardkey"), cmdADDCARDKEY , 1,1, N_("add a key to a smartcard") },
1228         { N_("delkey")  , cmdDELKEY    , 0,1, N_("delete a secondary key") },
1229         { N_("addrevoker"),cmdADDREVOKER,1,1, N_("add a revocation key") },
1230         { N_("delsig")  , cmdDELSIG    , 0,1, N_("delete signatures") },
1231         { N_("expire")  , cmdEXPIRE    , 1,1, N_("change the expire date") },
1232         { N_("primary") , cmdPRIMARY   , 1,1, N_("flag user ID as primary")},
1233         { N_("toggle")  , cmdTOGGLE    , 1,0, N_("toggle between secret "
1234                                                  "and public key listing") },
1235         { N_("t"     )  , cmdTOGGLE    , 1,0, NULL },
1236         { N_("pref")    , cmdPREF      , 0,1, N_("list preferences (expert)")},
1237         { N_("showpref"), cmdSHOWPREF  , 0,1, N_("list preferences (verbose)") },
1238         { N_("setpref") , cmdSETPREF   , 1,1, N_("set preference list") },
1239         { N_("updpref") , cmdUPDPREF   , 1,1, N_("updated preferences") },
1240         { N_("keyserver"),cmdPREFKS    , 1,1, N_("set preferred keyserver URL")},
1241         { N_("passwd")  , cmdPASSWD    , 1,1, N_("change the passphrase") },
1242         { N_("trust")   , cmdTRUST     , 0,1, N_("change the ownertrust") },
1243         { N_("revsig")  , cmdREVSIG    , 0,1, N_("revoke signatures") },
1244         { N_("revuid")  , cmdREVUID    , 1,1, N_("revoke a user ID") },
1245         { N_("revkey")  , cmdREVKEY    , 1,1, N_("revoke a secondary key") },
1246         { N_("disable") , cmdDISABLEKEY, 0,1, N_("disable a key") },
1247         { N_("enable")  , cmdENABLEKEY , 0,1, N_("enable a key") },
1248         { N_("showphoto"),cmdSHOWPHOTO , 0,0, N_("show photo ID") },
1249         { NULL, cmdNONE, 0, 0, NULL } };
1250     enum cmdids cmd = 0;
1251     int rc = 0;
1252     KBNODE keyblock = NULL;
1253     KEYDB_HANDLE kdbhd = NULL;
1254     KBNODE sec_keyblock = NULL;
1255     KEYDB_HANDLE sec_kdbhd = NULL;
1256     KBNODE cur_keyblock;
1257     char *answer = NULL;
1258     int redisplay = 1;
1259     int modified = 0;
1260     int sec_modified = 0;
1261     int toggle;
1262     int have_commands = !!commands;
1263
1264     if ( opt.command_fd != -1 )
1265         ;
1266     else if( opt.batch && !have_commands  ) {
1267         log_error(_("can't do that in batchmode\n"));
1268         goto leave;
1269     }
1270
1271     /* get the public key */
1272     rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1);
1273     if( rc )
1274         goto leave;
1275     if( fix_keyblock( keyblock ) )
1276         modified++;
1277     if( collapse_uids( &keyblock ) )
1278         modified++;
1279     reorder_keyblock(keyblock);
1280
1281     if(seckey_check)
1282       {/* see whether we have a matching secret key */
1283         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1284
1285         sec_kdbhd = keydb_new (1);
1286         {
1287             byte afp[MAX_FINGERPRINT_LEN];
1288             size_t an;
1289
1290             fingerprint_from_pk (pk, afp, &an);
1291             while (an < MAX_FINGERPRINT_LEN) 
1292                 afp[an++] = 0;
1293             rc = keydb_search_fpr (sec_kdbhd, afp);
1294         }
1295         if (!rc) {
1296             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1297             if (rc) {
1298                 log_error (_("error reading secret keyblock `%s': %s\n"),
1299                                                 username, g10_errstr(rc));
1300             }
1301             else {
1302                 merge_keys_and_selfsig( sec_keyblock );
1303                 if( fix_keyblock( sec_keyblock ) )
1304                     sec_modified++;
1305             }
1306         }
1307
1308         if (rc) {
1309             sec_keyblock = NULL;
1310             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1311             rc = 0;
1312         }
1313
1314         if( sec_keyblock && !quiet )
1315           tty_printf(_("Secret key is available.\n"));
1316     }
1317
1318     toggle = 0;
1319     cur_keyblock = keyblock;
1320     for(;;) { /* main loop */
1321         int i, arg_number, photo;
1322         const char *arg_string = "";
1323         char *p;
1324         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1325
1326         tty_printf("\n");
1327         if( redisplay && !quiet )
1328           {
1329             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1330             tty_printf("\n");
1331             redisplay = 0;
1332           }
1333         do {
1334             m_free(answer);
1335             if( have_commands ) {
1336                 if( commands ) {
1337                     answer = m_strdup( commands->d );
1338                     commands = commands->next;
1339                 }
1340                 else if( opt.batch ) {
1341                     answer = m_strdup("quit");
1342                 }
1343                 else
1344                     have_commands = 0;
1345             }
1346             if( !have_commands ) {
1347                 answer = cpr_get_no_help("keyedit.prompt", _("Command> "));
1348                 cpr_kill_prompt();
1349             }
1350             trim_spaces(answer);
1351         } while( *answer == '#' );
1352
1353         arg_number = 0; /* Yes, here is the init which egcc complains about */
1354         photo = 0; /* This too */
1355         if( !*answer )
1356             cmd = cmdLIST;
1357         else if( *answer == CONTROL_D )
1358             cmd = cmdQUIT;
1359         else if( digitp(answer ) ) {
1360             cmd = cmdSELUID;
1361             arg_number = atoi(answer);
1362         }
1363         else {
1364             if( (p=strchr(answer,' ')) ) {
1365                 *p++ = 0;
1366                 trim_spaces(answer);
1367                 trim_spaces(p);
1368                 arg_number = atoi(p);
1369                 arg_string = p;
1370             }
1371
1372             for(i=0; cmds[i].name; i++ ) {
1373                 if( !ascii_strcasecmp( answer, cmds[i].name ) )
1374                     break;
1375             }
1376             if( cmds[i].need_sk && !sec_keyblock ) {
1377                 tty_printf(_("Need the secret key to do this.\n"));
1378                 cmd = cmdNOP;
1379             }
1380             else if( cmds[i].not_with_sk && sec_keyblock && toggle ) {
1381                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1382                 cmd = cmdNOP;
1383             }
1384             else
1385                 cmd = cmds[i].id;
1386         }
1387         switch( cmd )  {
1388           case cmdHELP:
1389             for(i=0; cmds[i].name; i++ ) {
1390               if( cmds[i].need_sk && !sec_keyblock )
1391                 ; /* skip if we do not have the secret key */
1392               else if( cmds[i].desc )
1393                 tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1394             }
1395             break;
1396
1397           case cmdLIST:
1398             redisplay = 1;
1399             break;
1400
1401           case cmdFPR:
1402             show_key_and_fingerprint( keyblock );
1403             break;
1404
1405           case cmdSELUID:
1406             if( menu_select_uid( cur_keyblock, arg_number ) )
1407                 redisplay = 1;
1408             break;
1409
1410           case cmdSELKEY:
1411             if( menu_select_key( cur_keyblock, arg_number ) )
1412                 redisplay = 1;
1413             break;
1414
1415           case cmdCHECK:
1416             /* we can only do this with the public key becuase the
1417              * check functions can't cope with secret keys and it
1418              * is questionable whether this would make sense at all */
1419             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1420             break;
1421
1422           case cmdSIGN: /* sign (only the public key) */
1423           case cmdLSIGN: /* sign (only the public key) */
1424           case cmdNRSIGN: /* sign (only the public key) */
1425           case cmdNRLSIGN: /* sign (only the public key) */
1426           case cmdTSIGN:
1427             if( pk->is_revoked )
1428               {
1429                 tty_printf(_("Key is revoked."));
1430
1431                 if(opt.expert)
1432                   {
1433                     tty_printf("  ");
1434                     if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1435                                               _("Are you sure you still want "
1436                                                 "to sign it? (y/N) ")))
1437                       break;
1438                   }
1439                 else
1440                   {
1441                     tty_printf(_("  Unable to sign.\n"));
1442                     break;
1443                   }
1444               }
1445
1446             if( count_uids(keyblock) > 1 && !count_selected_uids(keyblock) ) {
1447                 if( !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1448                                            _("Really sign all user IDs? ")) ) {
1449                     tty_printf(_("Hint: Select the user IDs to sign\n"));
1450                     break;
1451                 }
1452             }
1453
1454             sign_uids( keyblock, locusr, &modified,
1455                        (cmd == cmdLSIGN) || (cmd == cmdNRLSIGN),
1456                        (cmd == cmdNRSIGN) || (cmd==cmdNRLSIGN),
1457                        (cmd == cmdTSIGN));
1458             break;
1459
1460           case cmdDEBUG:
1461             dump_kbnode( cur_keyblock );
1462             break;
1463
1464           case cmdTOGGLE:
1465             toggle = !toggle;
1466             cur_keyblock = toggle? sec_keyblock : keyblock;
1467             redisplay = 1;
1468             break;
1469
1470           case cmdADDPHOTO:
1471             if (RFC2440 || RFC1991 || PGP2)
1472               {
1473                 tty_printf(
1474                    _("This command is not allowed while in %s mode.\n"),
1475                    RFC2440?"OpenPGP":PGP2?"PGP2":"RFC-1991");
1476                 break;
1477               }
1478             photo=1;
1479             /* fall through */
1480
1481           case cmdADDUID:
1482             if( menu_adduid( keyblock, sec_keyblock, photo ) )
1483               {
1484                 update_trust = 1;
1485                 redisplay = 1;
1486                 sec_modified = modified = 1;
1487                 merge_keys_and_selfsig( sec_keyblock );
1488                 merge_keys_and_selfsig( keyblock );
1489               }
1490             break;
1491
1492           case cmdDELUID: {
1493                 int n1;
1494
1495                 if( !(n1=count_selected_uids(keyblock)) )
1496                     tty_printf(_("You must select at least one user ID.\n"));
1497                 else if( real_uids_left(keyblock) < 1 )
1498                     tty_printf(_("You can't delete the last user ID!\n"));
1499                 else if( cpr_get_answer_is_yes(
1500                             "keyedit.remove.uid.okay",
1501                         n1 > 1? _("Really remove all selected user IDs? ")
1502                               : _("Really remove this user ID? ")
1503                        ) ) {
1504                     menu_deluid( keyblock, sec_keyblock );
1505                     redisplay = 1;
1506                     modified = 1;
1507                     if( sec_keyblock )
1508                        sec_modified = 1;
1509                 }
1510             }
1511             break;
1512
1513           case cmdDELSIG: {
1514                 int n1;
1515
1516                 if( !(n1=count_selected_uids(keyblock)) )
1517                     tty_printf(_("You must select at least one user ID.\n"));
1518                 else if( menu_delsig( keyblock ) ) {
1519                     /* no redisplay here, because it may scroll away some
1520                      * status output of delsig */
1521                     modified = 1;
1522                 }
1523             }
1524             break;
1525
1526           case cmdADDKEY:
1527             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1528                 redisplay = 1;
1529                 sec_modified = modified = 1;
1530                 merge_keys_and_selfsig( sec_keyblock );
1531                 merge_keys_and_selfsig( keyblock );
1532             }
1533             break;
1534
1535 #ifdef ENABLE_CARD_SUPPORT
1536           case cmdADDCARDKEY:
1537             if (card_generate_subkey (keyblock, sec_keyblock)) {
1538                 redisplay = 1;
1539                 sec_modified = modified = 1;
1540                 merge_keys_and_selfsig( sec_keyblock );
1541                 merge_keys_and_selfsig( keyblock );
1542             }
1543             break;
1544 #endif /* ENABLE_CARD_SUPPORT */
1545
1546           case cmdDELKEY: {
1547                 int n1;
1548
1549                 if( !(n1=count_selected_keys( keyblock )) )
1550                     tty_printf(_("You must select at least one key.\n"));
1551                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
1552                        n1 > 1?
1553                         _("Do you really want to delete the selected keys? "):
1554                         _("Do you really want to delete this key? ")
1555                        ))
1556                     ;
1557                 else {
1558                     menu_delkey( keyblock, sec_keyblock );
1559                     redisplay = 1;
1560                     modified = 1;
1561                     if( sec_keyblock )
1562                        sec_modified = 1;
1563                 }
1564             }
1565             break;
1566
1567           case cmdADDREVOKER:
1568             {
1569               int sensitive=0;
1570
1571               if(arg_string && ascii_strcasecmp(arg_string,"sensitive")==0)
1572                 sensitive=1;
1573               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
1574                 redisplay = 1;
1575                 sec_modified = modified = 1;
1576                 merge_keys_and_selfsig( sec_keyblock );
1577                 merge_keys_and_selfsig( keyblock );
1578               }
1579             }
1580             break;
1581
1582           case cmdREVUID: {
1583                 int n1;
1584
1585                 if( !(n1=count_selected_uids(keyblock)) )
1586                     tty_printf(_("You must select at least one user ID.\n"));
1587                 else if( cpr_get_answer_is_yes(
1588                             "keyedit.revoke.uid.okay",
1589                         n1 > 1? _("Really revoke all selected user IDs? ")
1590                               : _("Really revoke this user ID? ")
1591                        ) ) {
1592                   if(menu_revuid(keyblock,sec_keyblock))
1593                     {
1594                       modified=1;
1595                       redisplay=1;
1596                     }
1597                 }
1598             }
1599             break;
1600
1601           case cmdREVKEY: {
1602                 int n1;
1603
1604                 if( !(n1=count_selected_keys( keyblock )) )
1605                     tty_printf(_("You must select at least one key.\n"));
1606                 else if( sec_keyblock && !cpr_get_answer_is_yes(
1607                             "keyedit.revoke.subkey.okay",
1608                        n1 > 1?
1609                         _("Do you really want to revoke the selected keys? "):
1610                         _("Do you really want to revoke this key? ")
1611                        ))
1612                     ;
1613                 else {
1614                     if( menu_revkey( keyblock, sec_keyblock ) ) {
1615                         modified = 1;
1616                         /*sec_modified = 1;*/
1617                     }
1618                     redisplay = 1;
1619                 }
1620             }
1621             break;
1622
1623           case cmdEXPIRE:
1624             if( menu_expire( keyblock, sec_keyblock ) ) {
1625                 merge_keys_and_selfsig( sec_keyblock );
1626                 merge_keys_and_selfsig( keyblock );
1627                 sec_modified = 1;
1628                 modified = 1;
1629                 redisplay = 1;
1630             }
1631             break;
1632
1633           case cmdPRIMARY:
1634             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
1635                 merge_keys_and_selfsig( keyblock );
1636                 modified = 1;
1637                 redisplay = 1;
1638             }
1639             break;
1640
1641           case cmdPASSWD:
1642             if( change_passphrase( sec_keyblock ) )
1643                 sec_modified = 1;
1644             break;
1645
1646           case cmdTRUST:
1647             if(opt.trust_model==TM_EXTERNAL)
1648               {
1649                 tty_printf(_("Owner trust may not be set while "
1650                              "using an user provided trust database\n"));
1651                 break;
1652               }
1653
1654             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
1655             tty_printf("\n");
1656             if( edit_ownertrust( find_kbnode( keyblock,
1657                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
1658                 redisplay = 1;
1659                 /* No real need to set update_trust here as
1660                    edit_ownertrust() calls revalidation_mark()
1661                    anyway. */
1662                 update_trust=1;
1663             }
1664             break;
1665
1666           case cmdPREF:
1667             show_key_with_all_names( keyblock, 0, 0, 0, 0, 1 );
1668             break;
1669
1670           case cmdSHOWPREF:
1671             show_key_with_all_names( keyblock, 0, 0, 0, 0, 2 );
1672             break;
1673
1674           case cmdSETPREF:
1675             keygen_set_std_prefs ( !*arg_string? "default" : arg_string, 0);
1676             break;
1677
1678           case cmdUPDPREF: 
1679             {
1680               PKT_user_id *temp=keygen_get_std_prefs();
1681               tty_printf(_("Set preference list to:\n"));
1682               show_prefs(temp,NULL,1);
1683               m_free(temp);
1684             }
1685             if (cpr_get_answer_is_yes ("keyedit.updpref.okay",
1686                                         count_selected_uids (keyblock)?
1687                                         _("Really update the preferences"
1688                                           " for the selected user IDs? "):
1689                                        _("Really update the preferences? "))){
1690
1691                 if ( menu_set_preferences (keyblock, sec_keyblock) ) {
1692                     merge_keys_and_selfsig (keyblock);
1693                     modified = 1;
1694                     redisplay = 1;
1695                 }
1696             }
1697             break;
1698
1699           case cmdPREFKS:
1700             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
1701                                          keyblock, sec_keyblock ) )
1702               {
1703                 merge_keys_and_selfsig( keyblock );
1704                 modified = 1;
1705                 redisplay = 1;
1706               }
1707             break;
1708
1709           case cmdNOP:
1710             break;
1711
1712           case cmdREVSIG:
1713             if( menu_revsig( keyblock ) ) {
1714                 redisplay = 1;
1715                 modified = 1;
1716             }
1717             break;
1718
1719           case cmdENABLEKEY:
1720           case cmdDISABLEKEY:
1721             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
1722                 redisplay = 1;
1723                 modified = 1;
1724             }
1725             break;
1726
1727          case cmdSHOWPHOTO:
1728            menu_showphoto(keyblock);
1729            break;
1730
1731           case cmdQUIT:
1732             if( have_commands )
1733                 goto leave;
1734             if( !modified && !sec_modified )
1735                 goto leave;
1736             if( !cpr_get_answer_is_yes("keyedit.save.okay",
1737                                         _("Save changes? ")) ) {
1738                 if( cpr_enabled()
1739                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
1740                                              _("Quit without saving? ")) )
1741                     goto leave;
1742                 break;
1743             }
1744             /* fall thru */
1745           case cmdSAVE:
1746             if( modified || sec_modified  ) {
1747                 if( modified ) {
1748                     rc = keydb_update_keyblock (kdbhd, keyblock);
1749                     if( rc ) {
1750                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
1751                         break;
1752                     }
1753                 }
1754                 if( sec_modified ) {
1755                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
1756                     if( rc ) {
1757                         log_error( _("update secret failed: %s\n"),
1758                                    g10_errstr(rc) );
1759                         break;
1760                     }
1761                 }
1762             }
1763             else
1764                 tty_printf(_("Key not changed so no update needed.\n"));
1765
1766             if( update_trust )
1767               {
1768                 revalidation_mark ();
1769                 update_trust=0;
1770               }
1771             goto leave;
1772
1773           case cmdINVCMD:
1774           default:
1775             tty_printf("\n");
1776             tty_printf(_("Invalid command  (try \"help\")\n"));
1777             break;
1778         }
1779     } /* end main loop */
1780
1781   leave:
1782     release_kbnode( keyblock );
1783     release_kbnode( sec_keyblock );
1784     keydb_release (kdbhd);
1785     m_free(answer);
1786 }
1787
1788
1789 /****************
1790  * show preferences of a public keyblock.
1791  */
1792 static void
1793 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
1794 {
1795     const prefitem_t fake={0,0};
1796     const prefitem_t *prefs;
1797     int i;
1798
1799     if( !uid )
1800         return;
1801
1802     if( uid->prefs )
1803         prefs=uid->prefs;
1804     else if(verbose)
1805         prefs=&fake;
1806     else
1807       return;
1808
1809     if (verbose) {
1810         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
1811         const byte *pref_ks;
1812         size_t pref_ks_len;
1813
1814         tty_printf ("     ");
1815         tty_printf (_("Cipher: "));
1816         for(i=any=0; prefs[i].type; i++ ) {
1817             if( prefs[i].type == PREFTYPE_SYM ) {
1818                 const char *s = cipher_algo_to_string (prefs[i].value);
1819                 
1820                 if (any)
1821                     tty_printf (", ");
1822                 any = 1;
1823                 /* We don't want to display strings for experimental algos */
1824                 if (s && prefs[i].value < 100 )
1825                     tty_printf ("%s", s );
1826                 else
1827                     tty_printf ("[%d]", prefs[i].value);
1828                 if (prefs[i].value == CIPHER_ALGO_3DES )
1829                     des_seen = 1;
1830             }    
1831         }
1832         if (!des_seen) {
1833             if (any)
1834                 tty_printf (", ");
1835             tty_printf ("%s",cipher_algo_to_string(CIPHER_ALGO_3DES));
1836         }
1837         tty_printf ("\n     ");
1838         tty_printf (_("Digest: "));
1839         for(i=any=0; prefs[i].type; i++ ) {
1840             if( prefs[i].type == PREFTYPE_HASH ) {
1841                 const char *s = digest_algo_to_string (prefs[i].value);
1842                 
1843                 if (any)
1844                     tty_printf (", ");
1845                 any = 1;
1846                 /* We don't want to display strings for experimental algos */
1847                 if (s && prefs[i].value < 100 )
1848                     tty_printf ("%s", s );
1849                 else
1850                     tty_printf ("[%d]", prefs[i].value);
1851                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
1852                     sha1_seen = 1;
1853             }
1854         }
1855         if (!sha1_seen) {
1856             if (any)
1857                 tty_printf (", ");
1858             tty_printf ("%s",digest_algo_to_string(DIGEST_ALGO_SHA1));
1859         }
1860         tty_printf ("\n     ");
1861         tty_printf (_("Compression: "));
1862         for(i=any=0; prefs[i].type; i++ ) {
1863             if( prefs[i].type == PREFTYPE_ZIP ) {
1864                 const char *s=compress_algo_to_string(prefs[i].value);
1865                 
1866                 if (any)
1867                     tty_printf (", ");
1868                 any = 1;
1869                 /* We don't want to display strings for experimental algos */
1870                 if (s && prefs[i].value < 100 )
1871                     tty_printf ("%s", s );
1872                 else
1873                     tty_printf ("[%d]", prefs[i].value);
1874                 if (prefs[i].value == COMPRESS_ALGO_NONE )
1875                     uncomp_seen = 1;
1876             }
1877         }
1878         if (!uncomp_seen) {
1879             if (any)
1880                 tty_printf (", ");
1881             else {
1882               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
1883               tty_printf (", ");
1884             }
1885             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
1886         }
1887         if(uid->mdc_feature || !uid->ks_modify)
1888           {
1889             tty_printf ("\n     ");
1890             tty_printf (_("Features: "));
1891             any=0;
1892             if(uid->mdc_feature)
1893               {
1894                 tty_printf ("MDC");
1895                 any=1;
1896               }
1897             if(!uid->ks_modify)
1898               {
1899                 if(any)
1900                   tty_printf (", ");
1901                 tty_printf (_("Keyserver no-modify"));
1902               }
1903           }
1904         tty_printf("\n");
1905
1906         pref_ks=parse_sig_subpkt(selfsig->hashed,
1907                                  SIGSUBPKT_PREF_KS,&pref_ks_len);
1908         if(pref_ks && pref_ks_len)
1909           {
1910             tty_printf ("     ");
1911             tty_printf("Preferred keyserver: %.*s\n",pref_ks_len,pref_ks);
1912           }
1913     }
1914     else {
1915         tty_printf("    ");
1916         for(i=0; prefs[i].type; i++ ) {
1917             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
1918                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
1919                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
1920                                  prefs[i].value);
1921         }
1922         if (uid->mdc_feature)
1923             tty_printf (" [mdc]");
1924         if (!uid->ks_modify)
1925             tty_printf (" [no-ks-modify]");
1926         tty_printf("\n");
1927     }
1928 }
1929
1930
1931 /* This is the version of show_key_with_all_names used when
1932    opt.with_colons is used.  It prints all available data in a easy to
1933    parse format and does not translate utf8 */
1934 static void
1935 show_key_with_all_names_colon (KBNODE keyblock)
1936 {
1937   KBNODE node;
1938   int i, j, ulti_hack=0;
1939   byte pk_version=0;
1940   PKT_public_key *primary=NULL;
1941
1942   /* the keys */
1943   for ( node = keyblock; node; node = node->next )
1944     {
1945       if (node->pkt->pkttype == PKT_PUBLIC_KEY
1946           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
1947         {
1948           PKT_public_key *pk = node->pkt->pkt.public_key;
1949           u32 keyid[2];
1950
1951           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
1952             {
1953               pk_version = pk->version;
1954               primary=pk;
1955             }
1956
1957           keyid_from_pk (pk, keyid);
1958
1959           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
1960           if (!pk->is_valid)
1961             putchar ('i');
1962           else if (pk->is_revoked)
1963             putchar ('r');
1964           else if (pk->has_expired)
1965             putchar ('e');
1966           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1967             {
1968               int trust = get_validity_info (pk, NULL);
1969               if(trust=='u')
1970                 ulti_hack=1;
1971               putchar (trust);
1972             }
1973
1974           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
1975                   nbits_from_pk (pk),
1976                   pk->pubkey_algo,
1977                   (ulong)keyid[0], (ulong)keyid[1],
1978                   (ulong)pk->timestamp,
1979                   (ulong)pk->expiredate );
1980           if (node->pkt->pkttype==PKT_PUBLIC_KEY
1981               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
1982             putchar(get_ownertrust_info (pk));
1983           putchar(':');
1984           putchar('\n');
1985           
1986           print_fingerprint (pk, NULL, 0);
1987
1988           /* print the revoker record */
1989           if( !pk->revkey && pk->numrevkeys )
1990             BUG();
1991           else
1992             {
1993               for (i=0; i < pk->numrevkeys; i++)
1994                 {
1995                   byte *p;
1996
1997                   printf ("rvk:::%d::::::", pk->revkey[i].algid);
1998                   p = pk->revkey[i].fpr;
1999                   for (j=0; j < 20; j++, p++ )
2000                     printf ("%02X", *p);
2001                   printf (":%02x%s:\n", pk->revkey[i].class,
2002                           (pk->revkey[i].class&0x40)?"s":"");
2003                 }
2004             }
2005         }
2006     }
2007   
2008     /* the user ids */
2009     i = 0;
2010     for (node = keyblock; node; node = node->next) 
2011       {
2012         if ( node->pkt->pkttype == PKT_USER_ID )
2013           {
2014             PKT_user_id *uid = node->pkt->pkt.user_id;
2015
2016             ++i;
2017
2018             if(uid->attrib_data)
2019               printf("uat:");
2020             else
2021               printf("uid:");
2022
2023             if ( uid->is_revoked )
2024               printf("r::::::::");
2025             else if ( uid->is_expired )
2026               printf("e::::::::");
2027             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2028               printf("::::::::");
2029             else
2030               {
2031                 int uid_validity;
2032
2033                 if( primary && !ulti_hack )
2034                   uid_validity = get_validity_info( primary, uid );
2035                 else
2036                   uid_validity = 'u';
2037                 printf("%c::::::::",uid_validity);
2038               }
2039
2040             if(uid->attrib_data)
2041               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2042             else
2043               print_string (stdout, uid->name, uid->len, ':');
2044
2045             putchar (':');
2046             /* signature class */
2047             putchar (':');
2048             /* capabilities */
2049             putchar (':');
2050             /* preferences */
2051             if (pk_version>3 || uid->selfsigversion>3)
2052               {
2053                 const prefitem_t *prefs = uid->prefs;
2054                 
2055                 for (j=0; prefs && prefs[j].type; j++)
2056                   {
2057                     if (j)
2058                       putchar (' ');
2059                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2060                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2061                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2062                             prefs[j].value);
2063                   } 
2064                 if (uid->mdc_feature)
2065                   printf (",mdc");
2066                 if (!uid->ks_modify)
2067                   printf (",no-ks-modify");
2068               } 
2069             putchar (':');
2070             /* flags */
2071             printf ("%d,", i);
2072             if (uid->is_primary)
2073               putchar ('p');
2074             if (uid->is_revoked)
2075               putchar ('r');
2076             if (uid->is_expired)
2077               putchar ('e');
2078             if ((node->flag & NODFLG_SELUID))
2079               putchar ('s');
2080             if ((node->flag & NODFLG_MARK_A))
2081               putchar ('m');
2082             putchar (':');
2083             putchar('\n');
2084           }
2085       }
2086 }
2087
2088
2089 /****************
2090  * Display the key a the user ids, if only_marked is true, do only
2091  * so for user ids with mark A flag set and dont display the index number
2092  */
2093 static void
2094 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2095                          int with_fpr, int with_subkeys, int with_prefs )
2096 {
2097     KBNODE node;
2098     int i, rc;
2099     int do_warn = 0, indent=0;
2100     byte pk_version=0;
2101     PKT_public_key *primary=NULL;
2102
2103     if (opt.with_colons)
2104       {
2105         show_key_with_all_names_colon (keyblock);
2106         return;
2107       }
2108
2109     /* the keys */
2110     for( node = keyblock; node; node = node->next ) {
2111         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2112             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY) ) {
2113             PKT_public_key *pk = node->pkt->pkt.public_key;
2114             const char *otrust="err",*trust="err";
2115
2116             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2117                 /* do it here, so that debug messages don't clutter the
2118                  * output */
2119                 static int did_warn = 0;
2120
2121                 trust = get_validity_string (pk, NULL);
2122                 otrust = get_ownertrust_string (pk);
2123
2124                 /* Show a warning once */
2125                 if (!did_warn
2126                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2127                     did_warn = 1;
2128                     do_warn = 1;
2129                 }
2130
2131                 pk_version=pk->version;
2132                 primary=pk;
2133             }
2134
2135             if(with_revoker) {
2136                 if( !pk->revkey && pk->numrevkeys )
2137                     BUG();
2138                 else
2139                     for(i=0;i<pk->numrevkeys;i++) {
2140                         u32 r_keyid[2];
2141                         char *user;
2142                         const char *algo=
2143                           pubkey_algo_to_string(pk->revkey[i].algid);
2144
2145                         keyid_from_fingerprint(pk->revkey[i].fpr,
2146                                                MAX_FINGERPRINT_LEN,r_keyid);
2147                         
2148                         user=get_user_id_string (r_keyid);
2149                         tty_printf (_("This key may be revoked by %s key "),
2150                                     algo?algo:"?");
2151                         tty_print_utf8_string (user, strlen (user));
2152                         if ((pk->revkey[i].class&0x40))
2153                           tty_printf (_(" (sensitive)"));
2154                         tty_printf ("\n");
2155                         m_free(user);
2156                       }
2157             }
2158
2159             keyid_from_pk(pk,NULL);
2160             tty_printf("%s%c %4u%c/%s  ",
2161                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2162                        (node->flag & NODFLG_SELKEY)? '*':' ',
2163                        nbits_from_pk( pk ),
2164                        pubkey_letter( pk->pubkey_algo ),
2165                        keystr(pk->keyid));
2166
2167             tty_printf(_("created: %s"),datestr_from_pk(pk));
2168             tty_printf("  ");
2169             if(pk->is_revoked)
2170               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2171             else if(pk->has_expired)
2172               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2173             else
2174               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2175             tty_printf("\n");
2176
2177             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2178               {
2179                 if(opt.trust_model!=TM_ALWAYS)
2180                   {
2181                     tty_printf("%*s",keystrlen()+13,"");
2182                     /* Ownertrust is only meaningful for the PGP or
2183                        classic trust models */
2184                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2185                       {
2186                         int width=14-strlen(otrust);
2187                         if(width<=0)
2188                           width=1;
2189                         tty_printf(_("trust: %s"), otrust);
2190                         tty_printf("%*s",width,"");
2191                       }
2192                     
2193                     tty_printf(_("validity: %s"), trust );
2194                     tty_printf("\n");
2195                   }
2196                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2197                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2198                   {
2199                     tty_printf("*** ");
2200                     tty_printf(_("This key has been disabled"));
2201                     tty_printf("\n");
2202                   }
2203               }
2204
2205             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2206               {
2207                 print_fingerprint ( pk, NULL, 2 );
2208                 tty_printf("\n");
2209               }
2210         }
2211         else if( node->pkt->pkttype == PKT_SECRET_KEY
2212             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2213           {
2214             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2215             tty_printf("%s%c %4u%c/%s  ",
2216                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2217                        (node->flag & NODFLG_SELKEY)? '*':' ',
2218                        nbits_from_sk( sk ),
2219                        pubkey_letter( sk->pubkey_algo ),
2220                        keystr_from_sk(sk));
2221             tty_printf(_("created: %s"),datestr_from_sk(sk));
2222             tty_printf("  ");
2223             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2224             tty_printf("\n");
2225             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2226               {
2227                 tty_printf("                     ");
2228                 tty_printf(_("card-no: ")); 
2229                 if (sk->protect.ivlen == 16
2230                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2231                   { /* This is an OpenPGP card. */
2232                     for (i=8; i < 14; i++)
2233                       {
2234                         if (i == 10)
2235                           tty_printf (" ");
2236                         tty_printf ("%02X", sk->protect.iv[i]);
2237                       }
2238                   }
2239                 else
2240                   { /* Something is wrong: Print all. */
2241                     for (i=0; i < sk->protect.ivlen; i++)
2242                       tty_printf ("%02X", sk->protect.iv[i]);
2243                   }
2244                 tty_printf ("\n");
2245               }
2246           }
2247         else if( with_subkeys && node->pkt->pkttype == PKT_SIGNATURE
2248                  && node->pkt->pkt.signature->sig_class == 0x28       ) {
2249             PKT_signature *sig = node->pkt->pkt.signature;
2250
2251             rc = check_key_signature( keyblock, node, NULL );
2252             if( !rc )
2253                 tty_printf( _("rev! subkey has been revoked: %s\n"),
2254                             datestr_from_sig( sig ) );
2255             else if( rc == G10ERR_BAD_SIGN )
2256                 tty_printf( _("rev- faked revocation found\n") );
2257             else if( rc )
2258                 tty_printf( _("rev? problem checking revocation: %s\n"),
2259                                                          g10_errstr(rc) );
2260         }
2261     }
2262     
2263     /* the user ids */
2264
2265     for( node = keyblock; node; node = node->next )
2266       {
2267         if(node->pkt->pkttype == PKT_USER_ID
2268            && (node->pkt->pkt.user_id->is_revoked
2269                || node->pkt->pkt.user_id->is_expired))
2270           {
2271             indent=1;
2272             break;
2273           }
2274       }
2275
2276     i = 0;
2277     for( node = keyblock; node; node = node->next ) {
2278         if( node->pkt->pkttype == PKT_USER_ID ) {
2279             PKT_user_id *uid = node->pkt->pkt.user_id;
2280             ++i;
2281             if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))){
2282                 if(uid->is_revoked)
2283                   tty_printf("[%8.8s] ",_("revoked"));
2284                 else if(uid->is_expired)
2285                   tty_printf("[%8.8s] ",_("expired"));
2286                 else if(opt.list_options&LIST_SHOW_UID_VALIDITY && primary)
2287                   tty_printf("[%8.8s] ",
2288                              trust_value_to_string(get_validity(primary,uid)));
2289                 else if(indent)
2290                   tty_printf("           ");
2291                 if( only_marked )
2292                    tty_printf("     ");
2293                 else if( node->flag & NODFLG_SELUID )
2294                    tty_printf("(%d)* ", i);
2295                 else if( uid->is_primary )
2296                    tty_printf("(%d). ", i);
2297                 else
2298                    tty_printf("(%d)  ", i);
2299                 tty_print_utf8_string( uid->name, uid->len );
2300                 tty_printf("\n");
2301                 if( with_prefs )
2302                   {
2303                     if(pk_version>3 || uid->selfsigversion>3)
2304                       {
2305                         PKT_signature *selfsig=NULL;
2306                         KBNODE signode;
2307
2308                         for(signode=node->next;
2309                             signode && signode->pkt->pkttype==PKT_SIGNATURE;
2310                             signode=signode->next)
2311                           {
2312                             if(signode->pkt->pkt.signature->
2313                                flags.chosen_selfsig)
2314                               {
2315                                 selfsig=signode->pkt->pkt.signature;
2316                                 break;
2317                               }
2318                           }
2319
2320                         show_prefs (uid, selfsig, with_prefs == 2);
2321                       }
2322                     else
2323                       tty_printf(_("There are no preferences on a "
2324                                    "PGP 2.x-style user ID.\n"));
2325                   }
2326             }
2327         }
2328     }
2329
2330     if (do_warn)
2331         tty_printf (_("Please note that the shown key validity "
2332                       "is not necessarily correct\n"
2333                       "unless you restart the program.\n")); 
2334 }
2335
2336
2337 /* Display basic key information.  This fucntion is suitable to show
2338    information on the key without any dependencies on the trustdb or
2339    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2340    a secret key.*/
2341 void
2342 show_basic_key_info ( KBNODE keyblock )
2343 {
2344   KBNODE node;
2345   int i;
2346
2347   /* The primary key */
2348   for (node = keyblock; node; node = node->next)
2349     {
2350       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2351         {
2352           PKT_public_key *pk = node->pkt->pkt.public_key;
2353           
2354           /* Note, we use the same format string as in other show
2355              functions to make the translation job easier. */
2356           tty_printf ("%s  %4u%c/%s  ",
2357                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2358                       nbits_from_pk( pk ),
2359                       pubkey_letter( pk->pubkey_algo ),
2360                       keystr_from_pk(pk));
2361           tty_printf(_("created: %s"),datestr_from_pk(pk));
2362           tty_printf("  ");
2363           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2364           tty_printf("\n");
2365           print_fingerprint ( pk, NULL, 3 );
2366           tty_printf("\n");
2367         }
2368       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2369         {
2370           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2371           tty_printf("%s  %4u%c/%s",
2372                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2373                      nbits_from_sk( sk ),
2374                      pubkey_letter( sk->pubkey_algo ),
2375                      keystr_from_sk(sk));
2376           tty_printf(_("created: %s"),datestr_from_sk(sk));
2377           tty_printf("  ");
2378           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2379           tty_printf("\n");
2380           print_fingerprint (NULL, sk, 3 );
2381           tty_printf("\n");
2382         }
2383     }
2384
2385   /* The user IDs. */
2386   for (i=0, node = keyblock; node; node = node->next)
2387     {
2388       if (node->pkt->pkttype == PKT_USER_ID)
2389         {
2390           PKT_user_id *uid = node->pkt->pkt.user_id;
2391           ++i;
2392      
2393           tty_printf ("     ");
2394           if (uid->is_revoked)
2395             tty_printf (_("[revoked] "));
2396           else if ( uid->is_expired )
2397             tty_printf (_("[expired] "));
2398           tty_print_utf8_string (uid->name, uid->len);
2399           tty_printf ("\n");
2400         }
2401     }
2402 }
2403
2404 static void
2405 show_key_and_fingerprint( KBNODE keyblock )
2406 {
2407   KBNODE node;
2408   PKT_public_key *pk = NULL;
2409
2410   for( node = keyblock; node; node = node->next )
2411     {
2412       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2413         {
2414           pk = node->pkt->pkt.public_key;
2415           tty_printf("pub   %4u%c/%s %s ",
2416                      nbits_from_pk( pk ),
2417                      pubkey_letter( pk->pubkey_algo ),
2418                      keystr_from_pk(pk),
2419                      datestr_from_pk(pk) );
2420         }
2421       else if( node->pkt->pkttype == PKT_USER_ID )
2422         {
2423           PKT_user_id *uid = node->pkt->pkt.user_id;
2424           tty_print_utf8_string( uid->name, uid->len );
2425           break;
2426         }
2427     }
2428   tty_printf("\n");
2429   if( pk )
2430     print_fingerprint( pk, NULL, 2 );
2431 }
2432
2433
2434 /* Show a warning if no uids on the key have the primary uid flag
2435    set. */
2436 static void
2437 no_primary_warning(KBNODE keyblock)
2438 {
2439   KBNODE node;
2440   int have_primary=0,uid_count=0;
2441
2442   /* TODO: if we ever start behaving differently with a primary or
2443      non-primary attribute ID, we will need to check for attributes
2444      here as well. */
2445
2446   for(node=keyblock; node; node = node->next)
2447     {
2448       if(node->pkt->pkttype==PKT_USER_ID
2449          && node->pkt->pkt.user_id->attrib_data==NULL)
2450         {
2451           uid_count++;
2452
2453           if(node->pkt->pkt.user_id->is_primary==2)
2454             {
2455               have_primary=1;
2456               break;
2457             }
2458         }
2459     }
2460
2461   if(uid_count>1 && !have_primary)
2462     log_info(_("WARNING: no user ID has been marked as primary.  This command"
2463                " may\n              cause a different user ID to become"
2464                " the assumed primary.\n"));
2465 }
2466
2467 /****************
2468  * Ask for a new user id, do the selfsignature and put it into
2469  * both keyblocks.
2470  * Return true if there is a new user id
2471  */
2472 static int
2473 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock, int photo)
2474 {
2475     PKT_user_id *uid;
2476     PKT_public_key *pk=NULL;
2477     PKT_secret_key *sk=NULL;
2478     PKT_signature *sig=NULL;
2479     PACKET *pkt;
2480     KBNODE node;
2481     KBNODE pub_where=NULL, sec_where=NULL;
2482     int rc;
2483
2484     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
2485         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2486             pk = node->pkt->pkt.public_key;
2487         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2488             break;
2489     }
2490     if( !node ) /* no subkey */
2491         pub_where = NULL;
2492     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
2493         if( node->pkt->pkttype == PKT_SECRET_KEY )
2494             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2495         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
2496             break;
2497     }
2498     if( !node ) /* no subkey */
2499         sec_where = NULL;
2500     assert(pk && sk);
2501
2502     if(photo) {
2503       int hasattrib=0;
2504
2505       for( node = pub_keyblock; node; node = node->next )
2506         if( node->pkt->pkttype == PKT_USER_ID &&
2507             node->pkt->pkt.user_id->attrib_data!=NULL)
2508           {
2509             hasattrib=1;
2510             break;
2511           }
2512
2513       /* It is legal but bad for compatibility to add a photo ID to a
2514          v3 key as it means that PGP2 will not be able to use that key
2515          anymore.  Also, PGP may not expect a photo on a v3 key.
2516          Don't bother to ask this if the key already has a photo - any
2517          damage has already been done at that point. -dms */
2518       if(pk->version==3 && !hasattrib)
2519         {
2520           if(opt.expert)
2521             {
2522               tty_printf(_("WARNING: This is a PGP2-style key.  "
2523                            "Adding a photo ID may cause some versions\n"
2524                            "         of PGP to reject this key.\n"));
2525
2526               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
2527                                         _("Are you sure you still want "
2528                                           "to add it? (y/N) ")))
2529                 return 0;
2530             }
2531           else
2532             {
2533               tty_printf(_("You may not add a photo ID to "
2534                            "a PGP2-style key.\n"));
2535               return 0;
2536             }
2537         }
2538
2539       uid = generate_photo_id(pk);
2540     } else
2541       uid = generate_user_id();
2542     if( !uid )
2543         return 0;
2544
2545     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
2546                              keygen_add_std_prefs, pk );
2547     free_secret_key( sk );
2548     if( rc ) {
2549         log_error("signing failed: %s\n", g10_errstr(rc) );
2550         free_user_id(uid);
2551         return 0;
2552     }
2553
2554     /* insert/append to secret keyblock */
2555     pkt = m_alloc_clear( sizeof *pkt );
2556     pkt->pkttype = PKT_USER_ID;
2557     pkt->pkt.user_id = scopy_user_id(uid);
2558     node = new_kbnode(pkt);
2559     if( sec_where )
2560         insert_kbnode( sec_where, node, 0 );
2561     else
2562         add_kbnode( sec_keyblock, node );
2563     pkt = m_alloc_clear( sizeof *pkt );
2564     pkt->pkttype = PKT_SIGNATURE;
2565     pkt->pkt.signature = copy_signature(NULL, sig);
2566     if( sec_where )
2567         insert_kbnode( node, new_kbnode(pkt), 0 );
2568     else
2569         add_kbnode( sec_keyblock, new_kbnode(pkt) );
2570     /* insert/append to public keyblock */
2571     pkt = m_alloc_clear( sizeof *pkt );
2572     pkt->pkttype = PKT_USER_ID;
2573     pkt->pkt.user_id = uid;
2574     node = new_kbnode(pkt);
2575     if( pub_where )
2576         insert_kbnode( pub_where, node, 0 );
2577     else
2578         add_kbnode( pub_keyblock, node );
2579     pkt = m_alloc_clear( sizeof *pkt );
2580     pkt->pkttype = PKT_SIGNATURE;
2581     pkt->pkt.signature = copy_signature(NULL, sig);
2582     if( pub_where )
2583         insert_kbnode( node, new_kbnode(pkt), 0 );
2584     else
2585         add_kbnode( pub_keyblock, new_kbnode(pkt) );
2586     return 1;
2587 }
2588
2589
2590 /****************
2591  * Remove all selected userids from the keyrings
2592  */
2593 static void
2594 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
2595 {
2596     KBNODE node;
2597     int selected=0;
2598
2599     for( node = pub_keyblock; node; node = node->next ) {
2600         if( node->pkt->pkttype == PKT_USER_ID ) {
2601             selected = node->flag & NODFLG_SELUID;
2602             if( selected ) {
2603                 /* Only cause a trust update if we delete a
2604                    non-revoked user id */
2605                 if(!node->pkt->pkt.user_id->is_revoked)
2606                   update_trust=1;
2607                 delete_kbnode( node );
2608                 if( sec_keyblock ) {
2609                     KBNODE snode;
2610                     int s_selected = 0;
2611                     PKT_user_id *uid = node->pkt->pkt.user_id;
2612                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2613                         if( snode->pkt->pkttype == PKT_USER_ID ) {
2614                             PKT_user_id *suid = snode->pkt->pkt.user_id;
2615
2616                             s_selected =
2617                                 (uid->len == suid->len
2618                                  && !memcmp( uid->name, suid->name, uid->len));
2619                             if( s_selected )
2620                                 delete_kbnode( snode );
2621                         }
2622                         else if( s_selected
2623                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2624                             delete_kbnode( snode );
2625                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
2626                             s_selected = 0;
2627                     }
2628                 }
2629             }
2630         }
2631         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2632             delete_kbnode( node );
2633         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2634             selected = 0;
2635     }
2636     commit_kbnode( &pub_keyblock );
2637     if( sec_keyblock )
2638         commit_kbnode( &sec_keyblock );
2639 }
2640
2641
2642 static int
2643 menu_delsig( KBNODE pub_keyblock )
2644 {
2645     KBNODE node;
2646     PKT_user_id *uid = NULL;
2647     int changed=0;
2648
2649     for( node = pub_keyblock; node; node = node->next ) {
2650         if( node->pkt->pkttype == PKT_USER_ID ) {
2651             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
2652         }
2653         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
2654            int okay, valid, selfsig, inv_sig, no_key, other_err;
2655
2656             tty_printf("uid  ");
2657             tty_print_utf8_string( uid->name, uid->len );
2658             tty_printf("\n");
2659
2660             okay = inv_sig = no_key = other_err = 0;
2661             if(opt.with_colons)
2662               valid = print_and_check_one_sig_colon( pub_keyblock, node,
2663                                                &inv_sig, &no_key, &other_err,
2664                                                &selfsig, 1 );
2665             else
2666               valid = print_and_check_one_sig( pub_keyblock, node,
2667                                                &inv_sig, &no_key, &other_err,
2668                                                &selfsig, 1 );
2669
2670            if( valid ) {
2671                okay = cpr_get_answer_yes_no_quit(
2672                    "keyedit.delsig.valid",
2673                    _("Delete this good signature? (y/N/q)"));
2674
2675                /* Only update trust if we delete a good signature.
2676                   The other two cases do not affect trust. */
2677                if(okay)
2678                  update_trust=1;
2679            }
2680            else if( inv_sig || other_err )
2681                okay = cpr_get_answer_yes_no_quit(
2682                    "keyedit.delsig.invalid",
2683                    _("Delete this invalid signature? (y/N/q)"));
2684            else if( no_key )
2685                okay = cpr_get_answer_yes_no_quit(
2686                    "keyedit.delsig.unknown",
2687                    _("Delete this unknown signature? (y/N/q)"));
2688
2689             if( okay == -1 )
2690                 break;
2691            if( okay && selfsig && !cpr_get_answer_is_yes(
2692                                "keyedit.delsig.selfsig",
2693                               _("Really delete this self-signature? (y/N)") ))
2694                 okay = 0;
2695             if( okay ) {
2696                 delete_kbnode( node );
2697                 changed++;
2698             }
2699
2700         }
2701         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
2702             uid = NULL;
2703     }
2704
2705     if( changed ) {
2706         commit_kbnode( &pub_keyblock );
2707         tty_printf( changed == 1? _("Deleted %d signature.\n")
2708                                 : _("Deleted %d signatures.\n"), changed );
2709     }
2710     else
2711         tty_printf( _("Nothing deleted.\n") );
2712
2713     return changed;
2714 }
2715
2716
2717 /****************
2718  * Remove some of the secondary keys
2719  */
2720 static void
2721 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
2722 {
2723     KBNODE node;
2724     int selected=0;
2725
2726     for( node = pub_keyblock; node; node = node->next ) {
2727         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
2728             selected = node->flag & NODFLG_SELKEY;
2729             if( selected ) {
2730                 delete_kbnode( node );
2731                 if( sec_keyblock ) {
2732                     KBNODE snode;
2733                     int s_selected = 0;
2734                     u32 ki[2];
2735
2736                     keyid_from_pk( node->pkt->pkt.public_key, ki );
2737                     for( snode = sec_keyblock; snode; snode = snode->next ) {
2738                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
2739                             u32 ki2[2];
2740
2741                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
2742                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
2743                             if( s_selected )
2744                                 delete_kbnode( snode );
2745                         }
2746                         else if( s_selected
2747                                  && snode->pkt->pkttype == PKT_SIGNATURE )
2748                             delete_kbnode( snode );
2749                         else
2750                             s_selected = 0;
2751                     }
2752                 }
2753             }
2754         }
2755         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
2756             delete_kbnode( node );
2757         else
2758             selected = 0;
2759     }
2760     commit_kbnode( &pub_keyblock );
2761     if( sec_keyblock )
2762         commit_kbnode( &sec_keyblock );
2763
2764     /* No need to set update_trust here since signing keys are no
2765        longer used to certify other keys, so there is no change in
2766        trust when revoking/removing them */
2767 }
2768
2769
2770 /****************
2771  * Ask for a new revoker, do the selfsignature and put it into
2772  * both keyblocks.
2773  * Return true if there is a new revoker
2774  */
2775 static int
2776 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
2777 {
2778   PKT_public_key *pk=NULL,*revoker_pk=NULL;
2779   PKT_secret_key *sk=NULL;
2780   PKT_signature *sig=NULL;
2781   PACKET *pkt;
2782   struct revocation_key revkey;
2783   size_t fprlen;
2784   int rc;
2785
2786   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2787   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
2788
2789   pk=pub_keyblock->pkt->pkt.public_key;
2790
2791   if(pk->numrevkeys==0 && pk->version==3)
2792     {
2793       /* It is legal but bad for compatibility to add a revoker to a
2794          v3 key as it means that PGP2 will not be able to use that key
2795          anymore.  Also, PGP may not expect a revoker on a v3 key.
2796          Don't bother to ask this if the key already has a revoker -
2797          any damage has already been done at that point. -dms */
2798       if(opt.expert)
2799         {
2800           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
2801                        "Adding a designated revoker may cause\n"
2802                        "         some versions of PGP to reject this key.\n"));
2803
2804           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
2805                                     _("Are you sure you still want "
2806                                       "to add it? (y/N) ")))
2807             return 0;
2808         }
2809       else
2810         {
2811           tty_printf(_("You may not add a designated revoker to "
2812                        "a PGP 2.x-style key.\n"));
2813           return 0;
2814         }
2815     }
2816
2817   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
2818
2819   for(;;)
2820     {
2821       char *answer;
2822
2823       if(revoker_pk)
2824         free_public_key(revoker_pk);
2825
2826       revoker_pk=m_alloc_clear(sizeof(*revoker_pk));
2827
2828       tty_printf("\n");
2829
2830       answer=cpr_get_utf8("keyedit.add_revoker",
2831                           _("Enter the user ID of the designated revoker: "));
2832       if(answer[0]=='\0' || answer[0]=='\004')
2833         {
2834           m_free(answer);
2835           goto fail;
2836         }
2837
2838       /* Note that I'm requesting SIG here and not CERT.  We're making
2839          a certification, but it is okay to be a subkey. */
2840       revoker_pk->req_usage=PUBKEY_USAGE_SIG;
2841       rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1);
2842       if(rc)
2843         {
2844           log_error (_("key `%s' not found: %s\n"),answer,g10_errstr(rc));
2845           m_free(answer);
2846           continue;
2847         }
2848
2849       m_free(answer);
2850
2851       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
2852       if(fprlen!=20)
2853         {
2854           log_error(_("cannot appoint a PGP 2.x style key as a "
2855                       "designated revoker\n"));
2856           continue;
2857         }
2858
2859       revkey.class=0x80;
2860       if(sensitive)
2861         revkey.class|=0x40;
2862       revkey.algid=revoker_pk->pubkey_algo;
2863
2864       if(cmp_public_keys(revoker_pk,pk)==0)
2865         {
2866           /* This actually causes no harm (after all, a key that
2867              designates itself as a revoker is the same as a
2868              regular key), but it's easy enough to check. */
2869           log_error(_("you cannot appoint a key as its own "
2870                       "designated revoker\n"));
2871
2872           continue;
2873         }
2874
2875       keyid_from_pk(pk,NULL);
2876
2877       /* Does this revkey already exist? */
2878       if(!pk->revkey && pk->numrevkeys)
2879         BUG();
2880       else
2881         {
2882           int i;
2883
2884           for(i=0;i<pk->numrevkeys;i++)
2885             {
2886               if(memcmp(&pk->revkey[i],&revkey,
2887                         sizeof(struct revocation_key))==0)
2888                 {
2889                   char buf[50];
2890
2891                   log_error(_("this key has already been designated "
2892                               "as a revoker\n"));
2893
2894                   sprintf(buf,"%08lX%08lX",
2895                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
2896                   write_status_text(STATUS_ALREADY_SIGNED,buf);
2897
2898                   break;
2899                 }
2900             }
2901
2902           if(i<pk->numrevkeys)
2903             continue;
2904         }
2905
2906       print_pubkey_info(NULL,revoker_pk);
2907       print_fingerprint(revoker_pk,NULL,2);
2908       tty_printf("\n");
2909
2910       tty_printf(_("WARNING: appointing a key as a designated revoker "
2911                    "cannot be undone!\n"));
2912
2913       tty_printf("\n");
2914
2915       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
2916                                 _("Are you sure you want to appoint this "
2917                                   "key as a designated revoker? (y/N): ")))
2918         continue;
2919
2920       free_public_key(revoker_pk);
2921       revoker_pk=NULL;
2922       break;
2923     }
2924
2925   /* The 1F signature must be at least v4 to carry the revocation key
2926      subpacket. */
2927   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
2928                            keygen_add_revkey,&revkey );
2929   if( rc )
2930     {
2931       log_error("signing failed: %s\n", g10_errstr(rc) );
2932       goto fail;
2933     }
2934
2935   free_secret_key(sk);
2936   sk=NULL;
2937
2938   /* insert into secret keyblock */
2939   pkt = m_alloc_clear( sizeof *pkt );
2940   pkt->pkttype = PKT_SIGNATURE;
2941   pkt->pkt.signature = copy_signature(NULL, sig);
2942   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2943
2944   /* insert into public keyblock */
2945   pkt = m_alloc_clear( sizeof *pkt );
2946   pkt->pkttype = PKT_SIGNATURE;
2947   pkt->pkt.signature = sig;
2948   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
2949
2950   return 1;
2951
2952  fail:
2953   if(sk)
2954     free_secret_key(sk);
2955   if(sig)
2956     free_seckey_enc(sig);
2957   if(revoker_pk)
2958     free_public_key(revoker_pk);
2959
2960   return 0;
2961 }
2962
2963
2964 static int
2965 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
2966 {
2967     int n1, signumber, rc;
2968     u32 expiredate;
2969     int mainkey=0;
2970     PKT_secret_key *sk;    /* copy of the main sk */
2971     PKT_public_key *main_pk, *sub_pk;
2972     PKT_user_id *uid;
2973     KBNODE node;
2974     u32 keyid[2];
2975
2976     if( count_selected_keys( sec_keyblock ) ) {
2977         tty_printf(_("Please remove selections from the secret keys.\n"));
2978         return 0;
2979     }
2980
2981     n1 = count_selected_keys( pub_keyblock );
2982     if( n1 > 1 ) {
2983         tty_printf(_("Please select at most one secondary key.\n"));
2984         return 0;
2985     }
2986     else if( n1 )
2987         tty_printf(_("Changing expiration time for a secondary key.\n"));
2988     else
2989       {
2990         tty_printf(_("Changing expiration time for the primary key.\n"));
2991         mainkey=1;
2992         no_primary_warning(pub_keyblock);
2993       }
2994
2995     expiredate = ask_expiredate();
2996     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
2997     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
2998
2999     /* Now we can actually change the self signature(s) */
3000     main_pk = sub_pk = NULL;
3001     uid = NULL;
3002     signumber = 0;
3003     for( node=pub_keyblock; node; node = node->next ) {
3004         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3005             main_pk = node->pkt->pkt.public_key;
3006             keyid_from_pk( main_pk, keyid );
3007             main_pk->expiredate = expiredate;
3008         }
3009         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3010                  && (node->flag & NODFLG_SELKEY ) ) {
3011             sub_pk = node->pkt->pkt.public_key;
3012             sub_pk->expiredate = expiredate;
3013         }
3014         else if( node->pkt->pkttype == PKT_USER_ID )
3015             uid = node->pkt->pkt.user_id;
3016         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3017                  && ( mainkey || sub_pk ) ) {
3018             PKT_signature *sig = node->pkt->pkt.signature;
3019             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3020                 && ( (mainkey && uid
3021                       && uid->created && (sig->sig_class&~3) == 0x10)
3022                      || (!mainkey && sig->sig_class == 0x18)  )
3023                 && sig->flags.chosen_selfsig )
3024               {
3025                 /* this is a selfsignature which is to be replaced */
3026                 PKT_signature *newsig;
3027                 PACKET *newpkt;
3028                 KBNODE sn;
3029                 int signumber2 = 0;
3030
3031                 signumber++;
3032
3033                 if( (mainkey && main_pk->version < 4)
3034                     || (!mainkey && sub_pk->version < 4 ) ) {
3035                     log_info(_(
3036                         "You can't change the expiration date of a v3 key\n"));
3037                     free_secret_key( sk );
3038                     return 0;
3039                 }
3040
3041                 /* find the corresponding secret self-signature */
3042                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3043                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3044                         PKT_signature *b = sn->pkt->pkt.signature;
3045                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3046                             && sig->sig_class == b->sig_class
3047                             && ++signumber2 == signumber )
3048                             break;
3049                     }
3050                 }
3051                 if( !sn )
3052                     log_info(_("No corresponding signature in secret ring\n"));
3053
3054                 if( mainkey )
3055                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3056                                             sk, keygen_add_key_expire, main_pk);
3057                 else
3058                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3059                                             sk, keygen_add_key_expire, sub_pk );
3060                 if( rc ) {
3061                     log_error("make_keysig_packet failed: %s\n",
3062                                                     g10_errstr(rc));
3063                     free_secret_key( sk );
3064                     return 0;
3065                 }
3066                 /* replace the packet */
3067                 newpkt = m_alloc_clear( sizeof *newpkt );
3068                 newpkt->pkttype = PKT_SIGNATURE;
3069                 newpkt->pkt.signature = newsig;
3070                 free_packet( node->pkt );
3071                 m_free( node->pkt );
3072                 node->pkt = newpkt;
3073                 if( sn ) {
3074                     newpkt = m_alloc_clear( sizeof *newpkt );
3075                     newpkt->pkttype = PKT_SIGNATURE;
3076                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3077                     free_packet( sn->pkt );
3078                     m_free( sn->pkt );
3079                     sn->pkt = newpkt;
3080                 }
3081                 sub_pk = NULL;
3082             }
3083         }
3084     }
3085
3086     free_secret_key( sk );
3087     update_trust=1;
3088     return 1;
3089 }
3090
3091 static int
3092 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3093 {
3094     byte buf[1];
3095
3096     /* first clear all primary uid flags so that we are sure none are
3097      * lingering around */
3098     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
3099     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3100
3101     /* if opaque is set,we want to set the primary id */
3102     if (opaque) { 
3103         buf[0] = 1;
3104         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3105     }
3106
3107     return 0;
3108 }
3109
3110
3111 /*
3112  * Set the primary uid flag for the selected UID.  We will also reset
3113  * all other primary uid flags.  For this to work with have to update
3114  * all the signature timestamps.  If we would do this with the current
3115  * time, we lose quite a lot of information, so we use a a kludge to
3116  * do this: Just increment the timestamp by one second which is
3117  * sufficient to updated a signature during import.
3118  */
3119 static int
3120 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3121 {
3122     PKT_secret_key *sk;    /* copy of the main sk */
3123     PKT_public_key *main_pk;
3124     PKT_user_id *uid;
3125     KBNODE node;
3126     u32 keyid[2];
3127     int selected;
3128     int attribute = 0;
3129     int modified = 0;
3130
3131     if ( count_selected_uids (pub_keyblock) != 1 ) {
3132         tty_printf(_("Please select exactly one user ID.\n"));
3133         return 0;
3134     }
3135
3136     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3137     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3138
3139     /* Now we can actually change the self signature(s) */
3140     main_pk = NULL;
3141     uid = NULL;
3142     selected = 0;
3143
3144     /* Is our selected uid an attribute packet? */
3145     for ( node=pub_keyblock; node; node = node->next )
3146       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3147         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3148
3149     for ( node=pub_keyblock; node; node = node->next ) {
3150         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3151             break; /* ready */
3152
3153         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3154             main_pk = node->pkt->pkt.public_key;
3155             keyid_from_pk( main_pk, keyid );
3156         }
3157         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3158             uid = node->pkt->pkt.user_id;
3159             selected = node->flag & NODFLG_SELUID;
3160         }
3161         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3162             PKT_signature *sig = node->pkt->pkt.signature;
3163             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3164                  && (uid && (sig->sig_class&~3) == 0x10)
3165                  && attribute == (uid->attrib_data!=NULL)
3166                  && sig->flags.chosen_selfsig )
3167               {
3168               if(sig->version < 4) {
3169                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3170
3171                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3172                          user);
3173                 m_free(user);
3174               }
3175               else {
3176                 /* This is a selfsignature which is to be replaced.
3177                    We can just ignore v3 signatures because they are
3178                    not able to carry the primary ID flag.  We also
3179                    ignore self-sigs on user IDs that are not of the
3180                    same type that we are making primary.  That is, if
3181                    we are making a user ID primary, we alter user IDs.
3182                    If we are making an attribute packet primary, we
3183                    alter attribute packets. */
3184
3185                 /* FIXME: We must make sure that we only have one
3186                    self-signature per user ID here (not counting
3187                    revocations) */
3188                 PKT_signature *newsig;
3189                 PACKET *newpkt;
3190                 const byte *p;
3191                 int action;
3192
3193                 /* see whether this signature has the primary UID flag */
3194                 p = parse_sig_subpkt (sig->hashed,
3195                                       SIGSUBPKT_PRIMARY_UID, NULL );
3196                 if ( !p )
3197                     p = parse_sig_subpkt (sig->unhashed,
3198                                           SIGSUBPKT_PRIMARY_UID, NULL );
3199                 if ( p && *p ) /* yes */
3200                     action = selected? 0 : -1;
3201                 else /* no */
3202                     action = selected? 1 : 0;
3203
3204                 if (action) {
3205                     int rc = update_keysig_packet (&newsig, sig,
3206                                                main_pk, uid, NULL,
3207                                                sk,
3208                                                change_primary_uid_cb,
3209                                                action > 0? "x":NULL );
3210                     if( rc ) {
3211                         log_error ("update_keysig_packet failed: %s\n",
3212                                    g10_errstr(rc));
3213                         free_secret_key( sk );
3214                         return 0;
3215                     }
3216                     /* replace the packet */
3217                     newpkt = m_alloc_clear( sizeof *newpkt );
3218                     newpkt->pkttype = PKT_SIGNATURE;
3219                     newpkt->pkt.signature = newsig;
3220                     free_packet( node->pkt );
3221                     m_free( node->pkt );
3222                     node->pkt = newpkt;
3223                     modified = 1;
3224                 }
3225               }
3226             }
3227         }
3228     }
3229
3230     free_secret_key( sk );
3231     return modified;
3232 }
3233
3234
3235 /* 
3236  * Set preferences to new values for the selected user IDs
3237  */
3238 static int
3239 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
3240 {
3241     PKT_secret_key *sk;    /* copy of the main sk */
3242     PKT_public_key *main_pk;
3243     PKT_user_id *uid;
3244     KBNODE node;
3245     u32 keyid[2];
3246     int selected, select_all;
3247     int modified = 0;
3248
3249     no_primary_warning(pub_keyblock);
3250
3251     select_all = !count_selected_uids (pub_keyblock);
3252
3253     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3254     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3255
3256     /* Now we can actually change the self signature(s) */
3257     main_pk = NULL;
3258     uid = NULL;
3259     selected = 0;
3260     for ( node=pub_keyblock; node; node = node->next ) {
3261         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3262             break; /* ready */
3263
3264         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3265             main_pk = node->pkt->pkt.public_key;
3266             keyid_from_pk( main_pk, keyid );
3267         }
3268         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3269             uid = node->pkt->pkt.user_id;
3270             selected = select_all || (node->flag & NODFLG_SELUID);
3271         }
3272         else if ( main_pk && uid && selected
3273                   && node->pkt->pkttype == PKT_SIGNATURE ) {
3274             PKT_signature *sig = node->pkt->pkt.signature;
3275             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3276                  && (uid && (sig->sig_class&~3) == 0x10)
3277                  && sig->flags.chosen_selfsig ) {
3278               if( sig->version < 4 ) {
3279                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3280
3281                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3282                          user);
3283                 m_free(user);
3284               }
3285               else {
3286                 /* This is a selfsignature which is to be replaced 
3287                  * We have to ignore v3 signatures because they are
3288                  * not able to carry the preferences */
3289                 PKT_signature *newsig;
3290                 PACKET *newpkt;
3291                 int rc;
3292
3293                 rc = update_keysig_packet (&newsig, sig,
3294                                            main_pk, uid, NULL,
3295                                            sk,
3296                                            keygen_upd_std_prefs,
3297                                            NULL );
3298                 if( rc ) {
3299                     log_error ("update_keysig_packet failed: %s\n",
3300                                g10_errstr(rc));
3301                     free_secret_key( sk );
3302                     return 0;
3303                 }
3304                 /* replace the packet */
3305                 newpkt = m_alloc_clear( sizeof *newpkt );
3306                 newpkt->pkttype = PKT_SIGNATURE;
3307                 newpkt->pkt.signature = newsig;
3308                 free_packet( node->pkt );
3309                 m_free( node->pkt );
3310                 node->pkt = newpkt;
3311                 modified = 1;
3312               }
3313             }
3314         }
3315     }
3316     
3317     free_secret_key( sk );
3318     return modified;
3319 }
3320
3321
3322 static int
3323 menu_set_keyserver_url (const char *url,
3324                         KBNODE pub_keyblock, KBNODE sec_keyblock )
3325 {
3326   PKT_secret_key *sk;    /* copy of the main sk */
3327   PKT_public_key *main_pk;
3328   PKT_user_id *uid;
3329   KBNODE node;
3330   u32 keyid[2];
3331   int selected, select_all;
3332   int modified = 0;
3333   char *answer,*uri;
3334
3335   no_primary_warning(pub_keyblock);
3336
3337   if(url)
3338     answer=m_strdup(url);
3339   else
3340     {
3341       answer=cpr_get_utf8("keyedit.add_keyserver",
3342                           _("Enter your preferred keyserver URL: "));
3343       if(answer[0]=='\0' || answer[0]=='\004')
3344         {
3345           m_free(answer);
3346           return 0;
3347         }
3348     }
3349
3350   if(ascii_strcasecmp(answer,"none")==0)
3351     uri=NULL;
3352   else
3353     {
3354       struct keyserver_spec *keyserver=NULL;
3355       /* Sanity check the format */
3356       keyserver=parse_keyserver_uri(answer,1,NULL,0);
3357       m_free(answer);
3358       if(!keyserver)
3359         {
3360           log_info(_("could not parse keyserver URL\n"));
3361           return 0;
3362         }
3363       uri=m_strdup(keyserver->uri);
3364       free_keyserver_spec(keyserver);
3365     }
3366
3367   select_all = !count_selected_uids (pub_keyblock);
3368
3369   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3370   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3371
3372   /* Now we can actually change the self signature(s) */
3373   main_pk = NULL;
3374   uid = NULL;
3375   selected = 0;
3376   for ( node=pub_keyblock; node; node = node->next )
3377     {
3378       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3379         break; /* ready */
3380
3381       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
3382         {
3383           main_pk = node->pkt->pkt.public_key;
3384           keyid_from_pk( main_pk, keyid );
3385         }
3386       else if ( node->pkt->pkttype == PKT_USER_ID )
3387         {
3388           uid = node->pkt->pkt.user_id;
3389           selected = select_all || (node->flag & NODFLG_SELUID);
3390         }
3391       else if ( main_pk && uid && selected
3392                 && node->pkt->pkttype == PKT_SIGNATURE )
3393         {
3394           PKT_signature *sig = node->pkt->pkt.signature;
3395           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3396                && (uid && (sig->sig_class&~3) == 0x10) )
3397             {
3398               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
3399               if( sig->version < 4 )
3400                 log_info(_("skipping v3 self-signature on user id \"%s\"\n"),
3401                          user);
3402               else
3403                 {
3404                   /* This is a selfsignature which is to be replaced
3405                    * We have to ignore v3 signatures because they are
3406                    * not able to carry the subpacket. */
3407                   PKT_signature *newsig;
3408                   PACKET *newpkt;
3409                   int rc;
3410                   const byte *p;
3411                   size_t plen;
3412
3413                   p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
3414                   if(p && plen)
3415                     {
3416                       tty_printf("Current preferred keyserver for user"
3417                                  " ID \"%s\": %.*s\n",user,plen,p);
3418                       if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
3419                          uri?_("Are you sure you want to replace it? (y/N) "):
3420                              _("Are you sure you want to delete it? (y/N) ")))
3421                         continue;
3422                     }
3423                   else if(uri==NULL)
3424                     {
3425                       /* There is no current keyserver URL, so there
3426                          is no point in trying to un-set it. */
3427                       continue;
3428                     }
3429
3430                   rc = update_keysig_packet (&newsig, sig,
3431                                              main_pk, uid, NULL,
3432                                              sk,
3433                                              keygen_add_keyserver_url, uri );
3434                   if( rc )
3435                     {
3436                       log_error ("update_keysig_packet failed: %s\n",
3437                                  g10_errstr(rc));
3438                       free_secret_key( sk );
3439                       m_free(uri);
3440                       return 0;
3441                     }
3442                   /* replace the packet */
3443                   newpkt = m_alloc_clear( sizeof *newpkt );
3444                   newpkt->pkttype = PKT_SIGNATURE;
3445                   newpkt->pkt.signature = newsig;
3446                   free_packet( node->pkt );
3447                   m_free( node->pkt );
3448                   node->pkt = newpkt;
3449                   modified = 1;
3450                 }
3451
3452               m_free(user);
3453             }
3454         }
3455     }
3456
3457   m_free(uri);
3458   free_secret_key( sk );
3459   return modified;
3460 }
3461
3462
3463 /****************
3464  * Select one user id or remove all selection if index is 0.
3465  * Returns: True if the selection changed;
3466  */
3467 static int
3468 menu_select_uid( KBNODE keyblock, int idx )
3469 {
3470     KBNODE node;
3471     int i;
3472
3473     /* first check that the index is valid */
3474     if( idx ) {
3475         for( i=0, node = keyblock; node; node = node->next ) {
3476             if( node->pkt->pkttype == PKT_USER_ID ) {
3477                 if( ++i == idx )
3478                     break;
3479             }
3480         }
3481         if( !node ) {
3482             tty_printf(_("No user ID with index %d\n"), idx );
3483             return 0;
3484         }
3485     }
3486     else { /* reset all */
3487         for( i=0, node = keyblock; node; node = node->next ) {
3488             if( node->pkt->pkttype == PKT_USER_ID )
3489                 node->flag &= ~NODFLG_SELUID;
3490         }
3491         return 1;
3492     }
3493     /* and toggle the new index */
3494     for( i=0, node = keyblock; node; node = node->next ) {
3495         if( node->pkt->pkttype == PKT_USER_ID ) {
3496             if( ++i == idx ) {
3497                 if( (node->flag & NODFLG_SELUID) )
3498                     node->flag &= ~NODFLG_SELUID;
3499                 else
3500                     node->flag |= NODFLG_SELUID;
3501             }
3502         }
3503     }
3504
3505     return 1;
3506 }
3507
3508 /****************
3509  * Select secondary keys
3510  * Returns: True if the selection changed;
3511  */
3512 static int
3513 menu_select_key( KBNODE keyblock, int idx )
3514 {
3515     KBNODE node;
3516     int i;
3517
3518     /* first check that the index is valid */
3519     if( idx ) {
3520         for( i=0, node = keyblock; node; node = node->next ) {
3521             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3522                 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3523                 if( ++i == idx )
3524                     break;
3525             }
3526         }
3527         if( !node ) {
3528             tty_printf(_("No secondary key with index %d\n"), idx );
3529             return 0;
3530         }
3531     }
3532     else { /* reset all */
3533         for( i=0, node = keyblock; node; node = node->next ) {
3534             if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3535                 || node->pkt->pkttype == PKT_SECRET_SUBKEY )
3536                 node->flag &= ~NODFLG_SELKEY;
3537         }
3538         return 1;
3539     }
3540     /* and set the new index */
3541     for( i=0, node = keyblock; node; node = node->next ) {
3542         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3543             || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3544             if( ++i == idx ) {
3545                 if( (node->flag & NODFLG_SELKEY) )
3546                     node->flag &= ~NODFLG_SELKEY;
3547                 else
3548                     node->flag |= NODFLG_SELKEY;
3549             }
3550         }
3551     }
3552
3553     return 1;
3554 }
3555
3556
3557 static int
3558 count_uids_with_flag( KBNODE keyblock, unsigned flag )
3559 {
3560     KBNODE node;
3561     int i=0;
3562
3563     for( node = keyblock; node; node = node->next )
3564         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
3565             i++;
3566     return i;
3567 }
3568
3569 static int
3570 count_keys_with_flag( KBNODE keyblock, unsigned flag )
3571 {
3572     KBNODE node;
3573     int i=0;
3574
3575     for( node = keyblock; node; node = node->next )
3576         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3577               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
3578             && (node->flag & flag) )
3579             i++;
3580     return i;
3581 }
3582
3583 static int
3584 count_uids( KBNODE keyblock )
3585 {
3586     KBNODE node;
3587     int i=0;
3588
3589     for( node = keyblock; node; node = node->next )
3590         if( node->pkt->pkttype == PKT_USER_ID )
3591             i++;
3592     return i;
3593 }
3594
3595
3596 /****************
3597  * Returns true if there is at least one selected user id
3598  */
3599 static int
3600 count_selected_uids( KBNODE keyblock )
3601 {
3602     return count_uids_with_flag( keyblock, NODFLG_SELUID);
3603 }
3604
3605 static int
3606 count_selected_keys( KBNODE keyblock )
3607 {
3608     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
3609 }
3610
3611 /* returns how many real (i.e. not attribute) uids are unmarked */
3612 static int
3613 real_uids_left( KBNODE keyblock )
3614 {
3615   KBNODE node;
3616   int real=0;
3617
3618   for(node=keyblock;node;node=node->next)
3619     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
3620        !node->pkt->pkt.user_id->attrib_data)
3621       real++;
3622
3623   return real;
3624 }
3625
3626 /*
3627  * Ask whether the signature should be revoked.  If the user commits this,
3628  * flag bit MARK_A is set on the signature and the user ID.
3629  */
3630 static void
3631 ask_revoke_sig( KBNODE keyblock, KBNODE node )
3632 {
3633     int doit=0;
3634     PKT_signature *sig = node->pkt->pkt.signature;
3635     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
3636
3637     if( !unode ) {
3638         log_error("Oops: no user ID for signature\n");
3639         return;
3640     }
3641
3642     tty_printf(_("user ID: \""));
3643     tty_print_utf8_string( unode->pkt->pkt.user_id->name,
3644                            unode->pkt->pkt.user_id->len );
3645
3646     if(sig->flags.exportable)
3647       tty_printf(_("\"\nsigned with your key %s at %s\n"),
3648                  keystr(sig->keyid), datestr_from_sig(sig) );
3649     else
3650       tty_printf(_("\"\nlocally signed with your key %s at %s\n"),
3651                  keystr(sig->keyid), datestr_from_sig(sig) );
3652
3653     if(sig->flags.expired)
3654       {
3655         tty_printf(_("This signature expired on %s.\n"),
3656                    expirestr_from_sig(sig));
3657         /* Use a different question so we can have different help text */
3658         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
3659                         _("Are you sure you still want to revoke it? (y/N) "));
3660       }
3661     else
3662       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
3663               _("Create a revocation certificate for this signature? (y/N) "));
3664
3665     if(doit) {
3666       node->flag |= NODFLG_MARK_A;
3667       unode->flag |= NODFLG_MARK_A;
3668     }
3669 }
3670
3671 /****************
3672  * Display all user ids of the current public key together with signatures
3673  * done by one of our keys.  Then walk over all this sigs and ask the user
3674  * whether he wants to revoke this signature.
3675  * Return: True when the keyblock has changed.
3676  */
3677 static int
3678 menu_revsig( KBNODE keyblock )
3679 {
3680     PKT_signature *sig;
3681     PKT_public_key *primary_pk;
3682     KBNODE node;
3683     int changed = 0;
3684     int rc, any, skip=1, all=!count_selected_uids(keyblock);
3685     struct revocation_reason_info *reason = NULL;
3686
3687     /* FIXME: detect duplicates here  */
3688     tty_printf(_("You have signed these user IDs:\n"));
3689     for( node = keyblock; node; node = node->next ) {
3690         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
3691         if( node->pkt->pkttype == PKT_USER_ID ) {
3692             if( node->flag&NODFLG_SELUID || all ) {
3693               PKT_user_id *uid = node->pkt->pkt.user_id;
3694               /* Hmmm: Should we show only UIDs with a signature? */
3695               tty_printf("     ");
3696               tty_print_utf8_string( uid->name, uid->len );
3697               tty_printf("\n");
3698               skip=0;
3699             }
3700             else
3701               skip=1;
3702         }
3703         else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
3704                 && ((sig = node->pkt->pkt.signature),
3705                      !seckey_available(sig->keyid)  ) )
3706           {
3707             if( (sig->sig_class&~3) == 0x10 )
3708               {
3709                 tty_printf(_("   signed by %s on %s%s%s\n"),
3710                            keystr(sig->keyid), datestr_from_sig(sig),
3711                            sig->flags.exportable?"":" (non-exportable)",
3712                            sig->flags.revocable?"":" (non-revocable)");
3713                 if(sig->flags.revocable)
3714                   node->flag |= NODFLG_SELSIG;
3715               }
3716             else if( sig->sig_class == 0x30 )
3717               {
3718                 tty_printf(_("   revoked by %s on %s\n"),
3719                            keystr(sig->keyid), datestr_from_sig(sig) );
3720               }
3721           }
3722     }
3723
3724     /* ask */
3725     for( node = keyblock; node; node = node->next ) {
3726         if( !(node->flag & NODFLG_SELSIG) )
3727             continue;
3728         ask_revoke_sig( keyblock, node );
3729     }
3730
3731     /* present selected */
3732     any = 0;
3733     for( node = keyblock; node; node = node->next ) {
3734         if( !(node->flag & NODFLG_MARK_A) )
3735             continue;
3736         if( !any ) {
3737             any = 1;
3738             tty_printf(_("You are about to revoke these signatures:\n"));
3739         }
3740         if( node->pkt->pkttype == PKT_USER_ID ) {
3741             PKT_user_id *uid = node->pkt->pkt.user_id;
3742             tty_printf("     ");
3743             tty_print_utf8_string( uid->name, uid->len );
3744             tty_printf("\n");
3745         }
3746         else if( node->pkt->pkttype == PKT_SIGNATURE ) {
3747             sig = node->pkt->pkt.signature;
3748             tty_printf(_("   signed by %s on %s%s\n"),
3749                        keystr(sig->keyid), datestr_from_sig(sig),
3750                        sig->flags.exportable?"":_(" (non-exportable)") );
3751         }
3752     }
3753     if( !any )
3754         return 0; /* none selected */
3755
3756     if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
3757          _("Really create the revocation certificates? (y/N) ")) )
3758         return 0; /* forget it */
3759
3760     reason = ask_revocation_reason( 0, 1, 0 );
3761     if( !reason ) { /* user decided to cancel */
3762         return 0;
3763     }
3764
3765     /* now we can sign the user ids */
3766   reloop: /* (must use this, because we are modifing the list) */
3767     primary_pk = keyblock->pkt->pkt.public_key;
3768     for( node=keyblock; node; node = node->next ) {
3769         KBNODE&nb