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