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