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