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