Imported Upstream version 2.0.26
[platform/upstream/gpg2.git] / g10 / keyedit.c
1 /* keyedit.c - keyedit stuff
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3  *               2008, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <ctype.h>
28 #ifdef HAVE_LIBREADLINE
29 #define GNUPG_LIBREADLINE_H_INCLUDED
30 #include <readline/readline.h>
31 #endif
32
33 #include "gpg.h"
34 #include "options.h"
35 #include "packet.h"
36 #include "status.h"
37 #include "iobuf.h"
38 #include "keydb.h"
39 #include "photoid.h"
40 #include "util.h"
41 #include "main.h"
42 #include "trustdb.h"
43 #include "filter.h"
44 #include "ttyio.h"
45 #include "status.h"
46 #include "i18n.h"
47 #include "keyserver-internal.h"
48
49 static void show_prefs( PKT_user_id *uid, PKT_signature *selfsig, int verbose);
50 static void show_names(KBNODE keyblock,PKT_public_key *pk,
51                        unsigned int flag,int with_prefs);
52 static void show_key_with_all_names( KBNODE keyblock, int only_marked,
53             int with_revoker, int with_fpr, int with_subkeys, int with_prefs );
54 static void show_key_and_fingerprint( KBNODE keyblock );
55 static int menu_adduid( KBNODE keyblock, KBNODE sec_keyblock,
56                         int photo, const char *photo_name );
57 static void menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock );
58 static int menu_delsig( KBNODE pub_keyblock );
59 static int menu_clean(KBNODE keyblock,int self_only);
60 static void menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock );
61 static int menu_addrevoker( KBNODE pub_keyblock,
62                             KBNODE sec_keyblock, int sensitive );
63 static int menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock );
64 static int menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock);
65 static int menu_set_primary_uid( KBNODE pub_keyblock, KBNODE sec_keyblock );
66 static int menu_set_preferences( KBNODE pub_keyblock, KBNODE sec_keyblock );
67 static int menu_set_keyserver_url (const char *url,
68                                    KBNODE pub_keyblock, KBNODE sec_keyblock );
69 static int menu_set_notation(const char *string,
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_t 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_notations)
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, int *r_err)
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             u32 keyid[2];
1155
1156             tty_printf(_("Key is protected.\n"));
1157
1158             /* Clear the passphrase cache so that the user is required
1159                to enter the old passphrase.  */
1160             keyid_from_sk (sk, keyid);
1161             passphrase_clear_cache (keyid, NULL, 0);
1162
1163             rc = check_secret_key( sk, 0 );
1164             if( !rc )
1165                 passphrase = get_last_passphrase();
1166         }
1167         break;
1168     }
1169
1170     /* Unprotect all subkeys (use the supplied passphrase or ask)*/
1171     for(node=keyblock; !rc && node; node = node->next ) {
1172         if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1173             PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1174             if ( !(subsk->is_protected
1175                    && (subsk->protect.s2k.mode == 1001
1176                        || subsk->protect.s2k.mode == 1002))) {
1177                 set_next_passphrase( passphrase );
1178                 rc = check_secret_key( subsk, 0 );
1179                 if( !rc && !passphrase )
1180                     passphrase = get_last_passphrase();
1181             }
1182         }
1183     }
1184
1185     if( rc )
1186         tty_printf(_("Can't edit this key: %s\n"), g10_errstr(rc));
1187     else {
1188         DEK *dek = NULL;
1189         STRING2KEY *s2k = xmalloc_secure( sizeof *s2k );
1190         const char *errtext = NULL;
1191
1192         tty_printf(_("Enter the new passphrase for this secret key.\n\n") );
1193
1194         set_next_passphrase( NULL );
1195         for(;;) {
1196             int canceled;
1197
1198             s2k->mode = opt.s2k_mode;
1199             s2k->hash_algo = S2K_DIGEST_ALGO;
1200             dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo,
1201                                      s2k, 2, errtext, &canceled);
1202             if (!dek && canceled) {
1203                 rc = GPG_ERR_CANCELED;
1204                 break;
1205             }
1206             else if( !dek ) {
1207                 errtext = N_("passphrase not correctly repeated; try again");
1208                 tty_printf ("%s.\n", _(errtext));
1209             }
1210             else if( !dek->keylen ) {
1211                 rc = 0;
1212                 tty_printf(_( "You don't want a passphrase -"
1213                             " this is probably a *bad* idea!\n\n"));
1214                 if( cpr_get_answer_is_yes("change_passwd.empty.okay",
1215                                _("Do you really want to do this? (y/N) ")))
1216                   {
1217                     changed++;
1218                     break;
1219                   }
1220             }
1221             else { /* okay */
1222                 rc = 0;
1223                 if( !no_primary_secrets ) {
1224                     sk->protect.algo = dek->algo;
1225                     sk->protect.s2k = *s2k;
1226                     rc = protect_secret_key( sk, dek );
1227                 }
1228                 for(node=keyblock; !rc && node; node = node->next ) {
1229                     if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1230                         PKT_secret_key *subsk = node->pkt->pkt.secret_key;
1231                         if ( !(subsk->is_protected
1232                                && (subsk->protect.s2k.mode == 1001
1233                                    || subsk->protect.s2k.mode == 1002))) {
1234                             subsk->protect.algo = dek->algo;
1235                             subsk->protect.s2k = *s2k;
1236                             rc = protect_secret_key( subsk, dek );
1237                         }
1238                     }
1239                 }
1240                 if( rc )
1241                     log_error("protect_secret_key failed: %s\n",
1242                               g10_errstr(rc) );
1243                 else
1244                   {
1245                     u32 keyid[2];
1246
1247                     /* Clear the cahce again so that the user is
1248                        required to enter the new passphrase at the
1249                        next operation.  */
1250                     keyid_from_sk (sk, keyid);
1251                     passphrase_clear_cache (keyid, NULL, 0);
1252
1253                     changed++;
1254                   }
1255                 break;
1256             }
1257         }
1258         xfree(s2k);
1259         xfree(dek);
1260     }
1261
1262   leave:
1263     xfree( passphrase );
1264     set_next_passphrase( NULL );
1265     if (r_err)
1266       *r_err = rc;
1267     return changed && !rc;
1268 }
1269
1270
1271 /****************
1272  * There are some keys out (due to a bug in gnupg), where the sequence
1273  * of the packets is wrong.  This function fixes that.
1274  * Returns: true if the keyblock has been fixed.
1275  *
1276  * Note:  This function does not work if there is more than one user ID.
1277  */
1278 static int
1279 fix_keyblock( KBNODE keyblock )
1280 {
1281     KBNODE node, last, subkey;
1282     int fixed=0;
1283
1284     /* locate key signatures of class 0x10..0x13 behind sub key packets */
1285     for( subkey=last=NULL, node = keyblock; node;
1286                                             last=node, node = node->next ) {
1287         switch( node->pkt->pkttype ) {
1288           case PKT_PUBLIC_SUBKEY:
1289           case PKT_SECRET_SUBKEY:
1290             if( !subkey )
1291                 subkey = last; /* actually it is the one before the subkey */
1292             break;
1293           case PKT_SIGNATURE:
1294             if( subkey ) {
1295                 PKT_signature *sig = node->pkt->pkt.signature;
1296                 if( sig->sig_class >= 0x10 && sig->sig_class <= 0x13 ) {
1297                     log_info(_(
1298                         "moving a key signature to the correct place\n"));
1299                     last->next = node->next;
1300                     node->next = subkey->next;
1301                     subkey->next = node;
1302                     node = last;
1303                     fixed=1;
1304                 }
1305             }
1306             break;
1307           default: break;
1308         }
1309     }
1310
1311     return fixed;
1312 }
1313
1314 static int
1315 parse_sign_type(const char *str,int *localsig,int *nonrevokesig,int *trustsig)
1316 {
1317   const char *p=str;
1318
1319   while(*p)
1320     {
1321       if(ascii_strncasecmp(p,"l",1)==0)
1322         {
1323           *localsig=1;
1324           p++;
1325         }
1326       else if(ascii_strncasecmp(p,"nr",2)==0)
1327         {
1328           *nonrevokesig=1;
1329           p+=2;
1330         }
1331       else if(ascii_strncasecmp(p,"t",1)==0)
1332         {
1333           *trustsig=1;
1334           p++;
1335         }
1336       else
1337         return 0;
1338     }
1339
1340   return 1;
1341 }
1342
1343 \f
1344 /****************
1345  * Menu driven key editor.  If seckey_check is true, then a secret key
1346  * that matches username will be looked for.  If it is false, not all
1347  * commands will be available.
1348  *
1349  * Note: to keep track of some selection we use node->mark MARKBIT_xxxx.
1350  */
1351
1352 /* Need an SK for this command */
1353 #define KEYEDIT_NEED_SK 1
1354 /* Cannot be viewing the SK for this command */
1355 #define KEYEDIT_NOT_SK  2
1356 /* Must be viewing the SK for this command */
1357 #define KEYEDIT_ONLY_SK 4
1358 /* Match the tail of the string */
1359 #define KEYEDIT_TAIL_MATCH 8
1360
1361 enum cmdids
1362   {
1363     cmdNONE = 0,
1364     cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
1365     cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
1366     cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
1367     cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
1368     cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
1369     cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
1370     cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCLEAN,
1371     cmdMINIMIZE, cmdNOP
1372   };
1373
1374 static struct
1375 {
1376   const char *name;
1377   enum cmdids id;
1378   int flags;
1379   const char *desc;
1380 } cmds[] =
1381   {
1382     { "quit"    , cmdQUIT      , 0, N_("quit this menu") },
1383     { "q"       , cmdQUIT      , 0, NULL   },
1384     { "save"    , cmdSAVE      , 0, N_("save and quit") },
1385     { "help"    , cmdHELP      , 0, N_("show this help") },
1386     { "?"       , cmdHELP      , 0, NULL   },
1387     { "fpr"     , cmdFPR       , 0, N_("show key fingerprint") },
1388     { "list"    , cmdLIST      , 0, N_("list key and user IDs") },
1389     { "l"       , cmdLIST      , 0, NULL   },
1390     { "uid"     , cmdSELUID    , 0, N_("select user ID N") },
1391     { "key"     , cmdSELKEY    , 0, N_("select subkey N") },
1392     { "check"   , cmdCHECK     , 0, N_("check signatures") },
1393     { "c"       , cmdCHECK     , 0, NULL },
1394     { "cross-certify", cmdBACKSIGN  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1395     { "backsign", cmdBACKSIGN  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1396     { "sign"    , cmdSIGN      , KEYEDIT_NOT_SK|KEYEDIT_TAIL_MATCH,
1397       N_("sign selected user IDs [* see below for related commands]") },
1398     { "s"       , cmdSIGN      , KEYEDIT_NOT_SK, NULL },
1399     /* "lsign" and friends will never match since "sign" comes first
1400        and it is a tail match.  They are just here so they show up in
1401        the help menu. */
1402     { "lsign"   , cmdNOP       , 0, N_("sign selected user IDs locally") },
1403     { "tsign"   , cmdNOP       , 0,
1404       N_("sign selected user IDs with a trust signature") },
1405     { "nrsign"  , cmdNOP       , 0,
1406       N_("sign selected user IDs with a non-revocable signature") },
1407
1408     { "debug"   , cmdDEBUG     , 0, NULL },
1409     { "adduid"  , cmdADDUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1410       N_("add a user ID") },
1411     { "addphoto", cmdADDPHOTO  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1412       N_("add a photo ID") },
1413     { "deluid"  , cmdDELUID    , KEYEDIT_NOT_SK,
1414       N_("delete selected user IDs") },
1415     /* delphoto is really deluid in disguise */
1416     { "delphoto", cmdDELUID    , KEYEDIT_NOT_SK, NULL },
1417
1418     { "addkey"  , cmdADDKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1419       N_("add a subkey") },
1420
1421 #ifdef ENABLE_CARD_SUPPORT
1422     { "addcardkey", cmdADDCARDKEY , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1423       N_("add a key to a smartcard") },
1424     { "keytocard", cmdKEYTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1425       N_("move a key to a smartcard")},
1426     { "bkuptocard", cmdBKUPTOCARD , KEYEDIT_NEED_SK|KEYEDIT_ONLY_SK,
1427       N_("move a backup key to a smartcard")},
1428 #endif /*ENABLE_CARD_SUPPORT*/
1429
1430     { "delkey"  , cmdDELKEY    , KEYEDIT_NOT_SK,
1431       N_("delete selected subkeys") },
1432     { "addrevoker",cmdADDREVOKER,KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1433       N_("add a revocation key") },
1434     { "delsig"  , cmdDELSIG    , KEYEDIT_NOT_SK,
1435       N_("delete signatures from the selected user IDs") },
1436     { "expire"  , cmdEXPIRE    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1437       N_("change the expiration date for the key or selected subkeys") },
1438     { "primary" , cmdPRIMARY   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1439       N_("flag the selected user ID as primary")},
1440     { "toggle"  , cmdTOGGLE    , KEYEDIT_NEED_SK,
1441       N_("toggle between the secret and public key listings") },
1442     { "t"       , cmdTOGGLE    , KEYEDIT_NEED_SK, NULL },
1443     { "pref"    , cmdPREF      , KEYEDIT_NOT_SK,
1444       N_("list preferences (expert)")},
1445     { "showpref", cmdSHOWPREF  , KEYEDIT_NOT_SK,
1446       N_("list preferences (verbose)") },
1447     { "setpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1448       N_("set preference list for the selected user IDs") },
1449     /* Alias */
1450     { "updpref" , cmdSETPREF   , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1451
1452     { "keyserver",cmdPREFKS    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1453       N_("set the preferred keyserver URL for the selected user IDs")},
1454     { "notation", cmdNOTATION  , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1455       N_("set a notation for the selected user IDs")},
1456     { "passwd"  , cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1457       N_("change the passphrase") },
1458     /* Alias */
1459     { "password", cmdPASSWD    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1460
1461     { "trust"   , cmdTRUST     , KEYEDIT_NOT_SK, N_("change the ownertrust") },
1462     { "revsig"  , cmdREVSIG    , KEYEDIT_NOT_SK,
1463       N_("revoke signatures on the selected user IDs") },
1464     { "revuid"  , cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1465       N_("revoke selected user IDs") },
1466     /* Alias */
1467     { "revphoto", cmdREVUID    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK, NULL },
1468
1469     { "revkey"  , cmdREVKEY    , KEYEDIT_NOT_SK|KEYEDIT_NEED_SK,
1470       N_("revoke key or selected subkeys") },
1471     { "enable"  , cmdENABLEKEY , KEYEDIT_NOT_SK, N_("enable key") },
1472     { "disable" , cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key") },
1473     { "showphoto",cmdSHOWPHOTO , 0, N_("show selected photo IDs") },
1474     { "clean",    cmdCLEAN     , KEYEDIT_NOT_SK,
1475       N_("compact unusable user IDs and remove unusable signatures from key")},
1476     { "minimize", cmdMINIMIZE  , KEYEDIT_NOT_SK,
1477       N_("compact unusable user IDs and remove all signatures from key") },
1478     { NULL, cmdNONE, 0, NULL }
1479   };
1480
1481 #ifdef HAVE_LIBREADLINE
1482
1483 /* These two functions are used by readline for command completion. */
1484
1485 static char *
1486 command_generator(const char *text,int state)
1487 {
1488   static int list_index,len;
1489   const char *name;
1490
1491   /* If this is a new word to complete, initialize now.  This includes
1492      saving the length of TEXT for efficiency, and initializing the
1493      index variable to 0. */
1494   if(!state)
1495     {
1496       list_index=0;
1497       len=strlen(text);
1498     }
1499
1500   /* Return the next partial match */
1501   while((name=cmds[list_index].name))
1502     {
1503       /* Only complete commands that have help text */
1504       if(cmds[list_index++].desc && strncmp(name,text,len)==0)
1505         return strdup(name);
1506     }
1507
1508   return NULL;
1509 }
1510
1511 static char **
1512 keyedit_completion(const char *text, int start, int end)
1513 {
1514   /* If we are at the start of a line, we try and command-complete.
1515      If not, just do nothing for now. */
1516
1517   (void)end;
1518
1519   if(start==0)
1520     return rl_completion_matches(text,command_generator);
1521
1522   rl_attempted_completion_over=1;
1523
1524   return NULL;
1525 }
1526 #endif /* HAVE_LIBREADLINE */
1527
1528
1529 void
1530 keyedit_menu( const char *username, strlist_t locusr,
1531               strlist_t commands, int quiet, int seckey_check )
1532 {
1533     enum cmdids cmd = 0;
1534     int rc = 0;
1535     KBNODE keyblock = NULL;
1536     KEYDB_HANDLE kdbhd = NULL;
1537     KBNODE sec_keyblock = NULL;
1538     KEYDB_HANDLE sec_kdbhd = NULL;
1539     KBNODE cur_keyblock;
1540     char *answer = NULL;
1541     int redisplay = 1;
1542     int modified = 0;
1543     int sec_modified = 0;
1544     int toggle;
1545     int have_commands = !!commands;
1546
1547     if ( opt.command_fd != -1 )
1548         ;
1549     else if( opt.batch && !have_commands )
1550       {
1551         log_error(_("can't do this in batch mode\n"));
1552         goto leave;
1553       }
1554
1555 #ifdef HAVE_W32_SYSTEM
1556     /* Due to Windows peculiarities we need to make sure that the
1557        trustdb stale check is done before we open another file
1558        (i.e. by searching for a key).  In theory we could make sure
1559        that the files are closed after use but the open/close caches
1560        inhibits that and flushing the cache right before the stale
1561        check is not easy to implement.  Thus we take the easy way out
1562        and run the stale check as early as possible.  Note, that for
1563        non- W32 platforms it is run indirectly trough a call to
1564        get_validity ().  */
1565     check_trustdb_stale ();
1566 #endif
1567
1568     /* Get the public key */
1569     rc = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
1570     if( rc )
1571       {
1572         log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
1573         goto leave;
1574       }
1575
1576     if( fix_keyblock( keyblock ) )
1577         modified++;
1578     if( collapse_uids( &keyblock ) )
1579         modified++;
1580     reorder_keyblock(keyblock);
1581     /* We modified the keyblock, so let's make sure the flags are
1582        right. */
1583     if (modified)
1584       merge_keys_and_selfsig (keyblock);
1585
1586     if(seckey_check)
1587       {/* see whether we have a matching secret key */
1588         PKT_public_key *pk = keyblock->pkt->pkt.public_key;
1589
1590         sec_kdbhd = keydb_new (1);
1591         {
1592             byte afp[MAX_FINGERPRINT_LEN];
1593             size_t an;
1594
1595             fingerprint_from_pk (pk, afp, &an);
1596             while (an < MAX_FINGERPRINT_LEN)
1597                 afp[an++] = 0;
1598             rc = keydb_search_fpr (sec_kdbhd, afp);
1599         }
1600         if (!rc)
1601           {
1602             rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
1603             if (rc)
1604               {
1605                 log_error (_("error reading secret keyblock \"%s\": %s\n"),
1606                            username, g10_errstr(rc));
1607               }
1608             else
1609               {
1610                 merge_keys_and_selfsig( sec_keyblock );
1611                 if( fix_keyblock( sec_keyblock ) )
1612                   sec_modified++;
1613               }
1614           }
1615
1616         if (rc) {
1617             sec_keyblock = NULL;
1618             keydb_release (sec_kdbhd); sec_kdbhd = NULL;
1619             rc = 0;
1620         }
1621
1622         if( sec_keyblock && !quiet )
1623           tty_printf(_("Secret key is available.\n"));
1624     }
1625
1626     toggle = 0;
1627     cur_keyblock = keyblock;
1628     for(;;) { /* main loop */
1629         int i, arg_number, photo;
1630         const char *arg_string = "";
1631         char *p;
1632         PKT_public_key *pk=keyblock->pkt->pkt.public_key;
1633
1634         tty_printf("\n");
1635
1636         if( redisplay && !quiet )
1637           {
1638             show_key_with_all_names( cur_keyblock, 0, 1, 0, 1, 0 );
1639             tty_printf("\n");
1640             redisplay = 0;
1641           }
1642         do {
1643             xfree(answer);
1644             if( have_commands ) {
1645                 if( commands ) {
1646                     answer = xstrdup( commands->d );
1647                     commands = commands->next;
1648                 }
1649                 else if( opt.batch ) {
1650                     answer = xstrdup("quit");
1651                 }
1652                 else
1653                     have_commands = 0;
1654             }
1655             if( !have_commands )
1656               {
1657 #ifdef HAVE_LIBREADLINE
1658                 tty_enable_completion(keyedit_completion);
1659 #endif
1660                 answer = cpr_get_no_help("keyedit.prompt", "gpg> ");
1661                 cpr_kill_prompt();
1662                 tty_disable_completion();
1663               }
1664             trim_spaces(answer);
1665         } while( *answer == '#' );
1666
1667         arg_number = 0; /* Yes, here is the init which egcc complains about */
1668         photo = 0; /* This too */
1669         if( !*answer )
1670             cmd = cmdLIST;
1671         else if( *answer == CONTROL_D )
1672             cmd = cmdQUIT;
1673         else if( digitp(answer ) ) {
1674             cmd = cmdSELUID;
1675             arg_number = atoi(answer);
1676         }
1677         else {
1678             if( (p=strchr(answer,' ')) ) {
1679                 *p++ = 0;
1680                 trim_spaces(answer);
1681                 trim_spaces(p);
1682                 arg_number = atoi(p);
1683                 arg_string = p;
1684             }
1685
1686             for(i=0; cmds[i].name; i++ )
1687               {
1688                 if(cmds[i].flags & KEYEDIT_TAIL_MATCH)
1689                   {
1690                     size_t l=strlen(cmds[i].name);
1691                     size_t a=strlen(answer);
1692                     if(a>=l)
1693                       {
1694                         if(ascii_strcasecmp(&answer[a-l],cmds[i].name)==0)
1695                           {
1696                             answer[a-l]='\0';
1697                             break;
1698                           }
1699                       }
1700                   }
1701                 else if( !ascii_strcasecmp( answer, cmds[i].name ) )
1702                   break;
1703               }
1704             if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1705               {
1706                 tty_printf(_("Need the secret key to do this.\n"));
1707                 cmd = cmdNOP;
1708               }
1709             else if(((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
1710                      && toggle)
1711                     ||((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
1712                        && !toggle))
1713               {
1714                 tty_printf(_("Please use the command \"toggle\" first.\n"));
1715                 cmd = cmdNOP;
1716               }
1717             else
1718               cmd = cmds[i].id;
1719         }
1720         switch( cmd )
1721           {
1722           case cmdHELP:
1723             for(i=0; cmds[i].name; i++ )
1724               {
1725                 if((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock )
1726                   ; /* skip if we do not have the secret key */
1727                 else if( cmds[i].desc )
1728                   tty_printf("%-11s %s\n", cmds[i].name, _(cmds[i].desc) );
1729               }
1730
1731             tty_printf("\n");
1732             tty_printf(_(
1733 "* The `sign' command may be prefixed with an `l' for local "
1734 "signatures (lsign),\n"
1735 "  a `t' for trust signatures (tsign), an `nr' for non-revocable signatures\n"
1736 "  (nrsign), or any combination thereof (ltsign, tnrsign, etc.).\n"));
1737
1738             break;
1739
1740           case cmdLIST:
1741             redisplay = 1;
1742             break;
1743
1744           case cmdFPR:
1745             show_key_and_fingerprint( keyblock );
1746             break;
1747
1748           case cmdSELUID:
1749             if(strlen(arg_string)==NAMEHASH_LEN*2)
1750               redisplay=menu_select_uid_namehash(cur_keyblock,arg_string);
1751             else
1752               {
1753                 if (*arg_string == '*'
1754                     && (!arg_string[1] || spacep (arg_string+1)))
1755                   arg_number = -1; /* Select all. */
1756                 redisplay = menu_select_uid (cur_keyblock, arg_number);
1757               }
1758             break;
1759
1760           case cmdSELKEY:
1761             {
1762               if (*arg_string == '*'
1763                   && (!arg_string[1] || spacep (arg_string+1)))
1764                 arg_number = -1; /* Select all. */
1765               if (menu_select_key( cur_keyblock, arg_number))
1766                 redisplay = 1;
1767             }
1768             break;
1769
1770           case cmdCHECK:
1771             /* we can only do this with the public key becuase the
1772              * check functions can't cope with secret keys and it
1773              * is questionable whether this would make sense at all */
1774             check_all_keysigs( keyblock, count_selected_uids(keyblock) );
1775             break;
1776
1777           case cmdSIGN: /* sign (only the public key) */
1778             {
1779               int localsig=0,nonrevokesig=0,trustsig=0,interactive=0;
1780
1781               if( pk->is_revoked )
1782                 {
1783                   tty_printf(_("Key is revoked."));
1784
1785                   if(opt.expert)
1786                     {
1787                       tty_printf("  ");
1788                       if(!cpr_get_answer_is_yes("keyedit.sign_revoked.okay",
1789                                                 _("Are you sure you still want"
1790                                                   " to sign it? (y/N) ")))
1791                         break;
1792                     }
1793                   else
1794                     {
1795                       tty_printf(_("  Unable to sign.\n"));
1796                       break;
1797                     }
1798                 }
1799
1800               if(count_uids(keyblock) > 1 && !count_selected_uids(keyblock)
1801                  && !cpr_get_answer_is_yes("keyedit.sign_all.okay",
1802                                            _("Really sign all user IDs?"
1803                                              " (y/N) ")))
1804                 {
1805                   if(opt.interactive)
1806                     interactive=1;
1807                   else
1808                     {
1809                       tty_printf(_("Hint: Select the user IDs to sign\n"));
1810                       have_commands = 0;
1811                       break;
1812                     }
1813
1814                 }
1815               /* What sort of signing are we doing? */
1816               if(!parse_sign_type(answer,&localsig,&nonrevokesig,&trustsig))
1817                 {
1818                   tty_printf(_("Unknown signature type `%s'\n"),answer);
1819                   break;
1820                 }
1821
1822               sign_uids(keyblock, locusr, &modified,
1823                         localsig, nonrevokesig, trustsig, interactive);
1824             }
1825             break;
1826
1827           case cmdDEBUG:
1828             dump_kbnode( cur_keyblock );
1829             break;
1830
1831           case cmdTOGGLE:
1832             toggle = !toggle;
1833             cur_keyblock = toggle? sec_keyblock : keyblock;
1834             redisplay = 1;
1835             break;
1836
1837           case cmdADDPHOTO:
1838             if (RFC2440 || RFC1991 || PGP2)
1839               {
1840                 tty_printf(
1841                    _("This command is not allowed while in %s mode.\n"),
1842                    compliance_option_string());
1843                 break;
1844               }
1845             photo=1;
1846             /* fall through */
1847
1848           case cmdADDUID:
1849             if( menu_adduid( keyblock, sec_keyblock, photo, arg_string ) )
1850               {
1851                 update_trust = 1;
1852                 redisplay = 1;
1853                 sec_modified = modified = 1;
1854                 merge_keys_and_selfsig( sec_keyblock );
1855                 merge_keys_and_selfsig( keyblock );
1856               }
1857             break;
1858
1859           case cmdDELUID: {
1860                 int n1;
1861
1862                 if( !(n1=count_selected_uids(keyblock)) )
1863                     tty_printf(_("You must select at least one user ID.\n"));
1864                 else if( real_uids_left(keyblock) < 1 )
1865                     tty_printf(_("You can't delete the last user ID!\n"));
1866                 else if( cpr_get_answer_is_yes("keyedit.remove.uid.okay",
1867                 n1 > 1? _("Really remove all selected user IDs? (y/N) ")
1868                             : _("Really remove this user ID? (y/N) ")
1869                        ) ) {
1870                     menu_deluid( keyblock, sec_keyblock );
1871                     redisplay = 1;
1872                     modified = 1;
1873                     if( sec_keyblock )
1874                        sec_modified = 1;
1875                 }
1876             }
1877             break;
1878
1879           case cmdDELSIG: {
1880                 int n1;
1881
1882                 if( !(n1=count_selected_uids(keyblock)) )
1883                     tty_printf(_("You must select at least one user ID.\n"));
1884                 else if( menu_delsig( keyblock ) ) {
1885                     /* no redisplay here, because it may scroll away some
1886                      * status output of delsig */
1887                     modified = 1;
1888                 }
1889             }
1890             break;
1891
1892           case cmdADDKEY:
1893             if( generate_subkeypair( keyblock, sec_keyblock ) ) {
1894                 redisplay = 1;
1895                 sec_modified = modified = 1;
1896                 merge_keys_and_selfsig( sec_keyblock );
1897                 merge_keys_and_selfsig( keyblock );
1898             }
1899             break;
1900
1901 #ifdef ENABLE_CARD_SUPPORT
1902           case cmdADDCARDKEY:
1903             if (card_generate_subkey (keyblock, sec_keyblock)) {
1904                 redisplay = 1;
1905                 sec_modified = modified = 1;
1906                 merge_keys_and_selfsig( sec_keyblock );
1907                 merge_keys_and_selfsig( keyblock );
1908             }
1909             break;
1910
1911         case cmdKEYTOCARD:
1912           {
1913             KBNODE node=NULL;
1914             switch ( count_selected_keys (sec_keyblock) )
1915               {
1916               case 0:
1917                 if (cpr_get_answer_is_yes
1918                     ("keyedit.keytocard.use_primary",
1919                      /* TRANSLATORS: Please take care: This is about
1920                         moving the key and not about removing it.  */
1921                      _("Really move the primary key? (y/N) ")))
1922                   node = sec_keyblock;
1923                 break;
1924               case 1:
1925                 for (node = sec_keyblock; node; node = node->next )
1926                   {
1927                     if (node->pkt->pkttype == PKT_SECRET_SUBKEY
1928                         && node->flag & NODFLG_SELKEY)
1929                       break;
1930                   }
1931                 break;
1932               default:
1933                 tty_printf(_("You must select exactly one key.\n"));
1934                 break;
1935               }
1936             if (node)
1937               {
1938                 PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
1939                 if (card_store_subkey (node, xxpk?xxpk->pubkey_usage:0))
1940                   {
1941                     redisplay = 1;
1942                     sec_modified = 1;
1943                   }
1944               }
1945           }
1946           break;
1947
1948         case cmdBKUPTOCARD:
1949           {
1950             /* Ask for a filename, check whether this is really a
1951                backup key as generated by the card generation, parse
1952                that key and store it on card. */
1953             KBNODE node;
1954             const char *fname;
1955             PACKET *pkt;
1956             IOBUF a;
1957
1958             fname = arg_string;
1959             if (!*fname)
1960               {
1961                 tty_printf (_("Command expects a filename argument\n"));
1962                 break;
1963               }
1964
1965             /* Open that file.  */
1966             a = iobuf_open (fname);
1967             if (a && is_secured_file (iobuf_get_fd (a)))
1968               {
1969                 iobuf_close (a);
1970                 a = NULL;
1971                 errno = EPERM;
1972               }
1973             if (!a)
1974               {
1975                 tty_printf (_("Can't open `%s': %s\n"),
1976                             fname, strerror(errno));
1977                 break;
1978               }
1979
1980             /* Parse and check that file.  */
1981             pkt = xmalloc (sizeof *pkt);
1982             init_packet (pkt);
1983             rc = parse_packet (a, pkt);
1984             iobuf_close (a);
1985             iobuf_ioctl (NULL, 2, 0, (char*)fname); /* (invalidate cache).  */
1986             if (!rc
1987                 && pkt->pkttype != PKT_SECRET_KEY
1988                 && pkt->pkttype != PKT_SECRET_SUBKEY)
1989               rc = G10ERR_NO_SECKEY;
1990             if (rc)
1991               {
1992                 tty_printf(_("Error reading backup key from `%s': %s\n"),
1993                            fname, g10_errstr (rc));
1994                 free_packet (pkt);
1995                 xfree (pkt);
1996                 break;
1997               }
1998             node = new_kbnode (pkt);
1999
2000             /* Store it.  */
2001             if (card_store_subkey (node, 0))
2002               {
2003                 redisplay = 1;
2004                 sec_modified = 1;
2005               }
2006             release_kbnode (node);
2007           }
2008           break;
2009
2010 #endif /* ENABLE_CARD_SUPPORT */
2011
2012           case cmdDELKEY: {
2013                 int n1;
2014
2015                 if( !(n1=count_selected_keys( keyblock )) )
2016                     tty_printf(_("You must select at least one key.\n"));
2017                 else if( !cpr_get_answer_is_yes( "keyedit.remove.subkey.okay",
2018                        n1 > 1?
2019                    _("Do you really want to delete the selected keys? (y/N) "):
2020                         _("Do you really want to delete this key? (y/N) ")
2021                        ))
2022                     ;
2023                 else {
2024                     menu_delkey( keyblock, sec_keyblock );
2025                     redisplay = 1;
2026                     modified = 1;
2027                     if( sec_keyblock )
2028                        sec_modified = 1;
2029                 }
2030             }
2031             break;
2032
2033           case cmdADDREVOKER:
2034             {
2035               int sensitive=0;
2036
2037               if(ascii_strcasecmp(arg_string,"sensitive")==0)
2038                 sensitive=1;
2039               if( menu_addrevoker( keyblock, sec_keyblock, sensitive ) ) {
2040                 redisplay = 1;
2041                 sec_modified = modified = 1;
2042                 merge_keys_and_selfsig( sec_keyblock );
2043                 merge_keys_and_selfsig( keyblock );
2044               }
2045             }
2046             break;
2047
2048           case cmdREVUID: {
2049                 int n1;
2050
2051                 if( !(n1=count_selected_uids(keyblock)) )
2052                     tty_printf(_("You must select at least one user ID.\n"));
2053                 else if( cpr_get_answer_is_yes(
2054                             "keyedit.revoke.uid.okay",
2055                        n1 > 1? _("Really revoke all selected user IDs? (y/N) ")
2056                              : _("Really revoke this user ID? (y/N) ")
2057                        ) ) {
2058                   if(menu_revuid(keyblock,sec_keyblock))
2059                     {
2060                       modified=1;
2061                       redisplay=1;
2062                     }
2063                 }
2064             }
2065             break;
2066
2067           case cmdREVKEY:
2068             {
2069               int n1;
2070
2071               if( !(n1=count_selected_keys( keyblock )) )
2072                 {
2073                   if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2074                                            _("Do you really want to revoke"
2075                                              " the entire key? (y/N) ")))
2076                     {
2077                       if(menu_revkey(keyblock,sec_keyblock))
2078                         modified=1;
2079
2080                       redisplay=1;
2081                     }
2082                 }
2083               else if(cpr_get_answer_is_yes("keyedit.revoke.subkey.okay",
2084                                             n1 > 1?
2085                                             _("Do you really want to revoke"
2086                                               " the selected subkeys? (y/N) "):
2087                                             _("Do you really want to revoke"
2088                                               " this subkey? (y/N) ")))
2089                 {
2090                   if( menu_revsubkey( keyblock, sec_keyblock ) )
2091                     modified = 1;
2092
2093                   redisplay = 1;
2094                 }
2095
2096               if(modified)
2097                 merge_keys_and_selfsig( keyblock );
2098             }
2099             break;
2100
2101           case cmdEXPIRE:
2102             if( menu_expire( keyblock, sec_keyblock ) )
2103               {
2104                 merge_keys_and_selfsig( sec_keyblock );
2105                 merge_keys_and_selfsig( keyblock );
2106                 sec_modified = 1;
2107                 modified = 1;
2108                 redisplay = 1;
2109               }
2110             break;
2111
2112           case cmdBACKSIGN:
2113             if(menu_backsign(keyblock,sec_keyblock))
2114               {
2115                 sec_modified = 1;
2116                 modified = 1;
2117                 redisplay = 1;
2118               }
2119             break;
2120
2121           case cmdPRIMARY:
2122             if( menu_set_primary_uid ( keyblock, sec_keyblock ) ) {
2123                 merge_keys_and_selfsig( keyblock );
2124                 modified = 1;
2125                 redisplay = 1;
2126             }
2127             break;
2128
2129           case cmdPASSWD:
2130             if (change_passphrase (sec_keyblock, NULL))
2131                 sec_modified = 1;
2132             break;
2133
2134           case cmdTRUST:
2135             if(opt.trust_model==TM_EXTERNAL)
2136               {
2137                 tty_printf (_("Owner trust may not be set while "
2138                               "using a user provided trust database\n"));
2139                 break;
2140               }
2141
2142             show_key_with_all_names( keyblock, 0, 0, 0, 1, 0 );
2143             tty_printf("\n");
2144             if( edit_ownertrust( find_kbnode( keyblock,
2145                                  PKT_PUBLIC_KEY )->pkt->pkt.public_key, 1 ) ) {
2146                 redisplay = 1;
2147                 /* No real need to set update_trust here as
2148                    edit_ownertrust() calls revalidation_mark()
2149                    anyway. */
2150                 update_trust=1;
2151             }
2152             break;
2153
2154           case cmdPREF:
2155             {
2156               int count=count_selected_uids(keyblock);
2157               assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2158               show_names(keyblock,keyblock->pkt->pkt.public_key,
2159                          count?NODFLG_SELUID:0,1);
2160             }
2161             break;
2162
2163           case cmdSHOWPREF:
2164             {
2165               int count=count_selected_uids(keyblock);
2166               assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
2167               show_names(keyblock,keyblock->pkt->pkt.public_key,
2168                          count?NODFLG_SELUID:0,2);
2169             }
2170             break;
2171
2172           case cmdSETPREF:
2173             {
2174               PKT_user_id *tempuid;
2175
2176               keygen_set_std_prefs(!*arg_string?"default" : arg_string, 0);
2177
2178               tempuid=keygen_get_std_prefs();
2179               tty_printf(_("Set preference list to:\n"));
2180               show_prefs(tempuid,NULL,1);
2181               free_user_id(tempuid);
2182
2183               if(cpr_get_answer_is_yes("keyedit.setpref.okay",
2184                                        count_selected_uids (keyblock)?
2185                                        _("Really update the preferences"
2186                                          " for the selected user IDs? (y/N) "):
2187                                        _("Really update the preferences? (y/N) ")))
2188                 {
2189                   if ( menu_set_preferences (keyblock, sec_keyblock) )
2190                     {
2191                       merge_keys_and_selfsig (keyblock);
2192                       modified = 1;
2193                       redisplay = 1;
2194                     }
2195                 }
2196             }
2197             break;
2198
2199           case cmdPREFKS:
2200             if( menu_set_keyserver_url ( *arg_string?arg_string:NULL,
2201                                          keyblock, sec_keyblock ) )
2202               {
2203                 merge_keys_and_selfsig( keyblock );
2204                 modified = 1;
2205                 redisplay = 1;
2206               }
2207             break;
2208
2209           case cmdNOTATION:
2210             if( menu_set_notation ( *arg_string?arg_string:NULL,
2211                                     keyblock, sec_keyblock ) )
2212               {
2213                 merge_keys_and_selfsig( keyblock );
2214                 modified = 1;
2215                 redisplay = 1;
2216               }
2217             break;
2218
2219           case cmdNOP:
2220             break;
2221
2222           case cmdREVSIG:
2223             if( menu_revsig( keyblock ) ) {
2224                 redisplay = 1;
2225                 modified = 1;
2226             }
2227             break;
2228
2229           case cmdENABLEKEY:
2230           case cmdDISABLEKEY:
2231             if( enable_disable_key( keyblock, cmd == cmdDISABLEKEY ) ) {
2232                 redisplay = 1;
2233                 modified = 1;
2234             }
2235             break;
2236
2237           case cmdSHOWPHOTO:
2238             menu_showphoto(keyblock);
2239             break;
2240
2241           case cmdCLEAN:
2242             if(menu_clean(keyblock,0))
2243               redisplay=modified=1;
2244             break;
2245
2246           case cmdMINIMIZE:
2247             if(menu_clean(keyblock,1))
2248               redisplay=modified=1;
2249             break;
2250
2251           case cmdQUIT:
2252             if( have_commands )
2253                 goto leave;
2254             if( !modified && !sec_modified )
2255                 goto leave;
2256             if( !cpr_get_answer_is_yes("keyedit.save.okay",
2257                                         _("Save changes? (y/N) ")) ) {
2258                 if( cpr_enabled()
2259                     || cpr_get_answer_is_yes("keyedit.cancel.okay",
2260                                              _("Quit without saving? (y/N) ")))
2261                     goto leave;
2262                 break;
2263             }
2264             /* fall thru */
2265           case cmdSAVE:
2266             if( modified || sec_modified  ) {
2267                 if( modified ) {
2268                     rc = keydb_update_keyblock (kdbhd, keyblock);
2269                     if( rc ) {
2270                         log_error(_("update failed: %s\n"), g10_errstr(rc) );
2271                         break;
2272                     }
2273                 }
2274                 if( sec_modified ) {
2275                     rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock );
2276                     if( rc ) {
2277                         log_error( _("update secret failed: %s\n"),
2278                                    g10_errstr(rc) );
2279                         break;
2280                     }
2281                 }
2282             }
2283             else
2284                 tty_printf(_("Key not changed so no update needed.\n"));
2285
2286             if( update_trust )
2287               {
2288                 revalidation_mark ();
2289                 update_trust=0;
2290               }
2291             goto leave;
2292
2293           case cmdINVCMD:
2294           default:
2295             tty_printf("\n");
2296             tty_printf(_("Invalid command  (try \"help\")\n"));
2297             break;
2298         }
2299     } /* end main loop */
2300
2301   leave:
2302     release_kbnode( keyblock );
2303     release_kbnode( sec_keyblock );
2304     keydb_release (kdbhd);
2305     xfree(answer);
2306 }
2307
2308
2309 /* Change the passphrase of the secret key identified by USERNAME.  */
2310 void
2311 keyedit_passwd (const char *username)
2312 {
2313   gpg_error_t err;
2314   PKT_public_key *pk;
2315   unsigned char fpr[MAX_FINGERPRINT_LEN];
2316   size_t fprlen;
2317   KEYDB_HANDLE kdh = NULL;
2318   KBNODE keyblock = NULL;
2319
2320   pk = xtrycalloc (1, sizeof *pk);
2321   if (!pk)
2322     {
2323       err = gpg_error_from_syserror ();
2324       goto leave;
2325     }
2326   err = get_pubkey_byname (NULL, pk, username, NULL, NULL, 1, 1);
2327   if (err)
2328     goto leave;
2329   fingerprint_from_pk (pk, fpr, &fprlen);
2330   while (fprlen < MAX_FINGERPRINT_LEN)
2331     fpr[fprlen++] = 0;
2332
2333   kdh = keydb_new (1);
2334   if (!kdh)
2335     {
2336       err = gpg_error (GPG_ERR_GENERAL);
2337       goto leave;
2338     }
2339
2340   err = keydb_search_fpr (kdh, fpr);
2341   if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
2342     err = gpg_error (GPG_ERR_NO_SECKEY);
2343   if (err)
2344     goto leave;
2345
2346   err = keydb_get_keyblock (kdh, &keyblock);
2347   if (err)
2348     goto leave;
2349
2350   if (!change_passphrase (keyblock, &err))
2351     goto leave;
2352
2353   err = keydb_update_keyblock (kdh, keyblock);
2354   if (err)
2355     log_error( _("update secret failed: %s\n"), gpg_strerror (err));
2356
2357  leave:
2358   release_kbnode (keyblock);
2359   if (pk)
2360     free_public_key (pk);
2361   keydb_release (kdh);
2362   if (err)
2363     {
2364       log_info ("error changing the passphrase for `%s': %s\n",
2365                 username, gpg_strerror (err));
2366       write_status_error ("keyedit.passwd", gpg_err_code (err));
2367     }
2368   else
2369     write_status_text (STATUS_SUCCESS, "keyedit.passwd");
2370 }
2371
2372
2373 static void
2374 tty_print_notations(int indent,PKT_signature *sig)
2375 {
2376   int first=1;
2377   struct notation *notation,*nd;
2378
2379   if(indent<0)
2380     {
2381       first=0;
2382       indent=-indent;
2383     }
2384
2385   notation=sig_to_notation(sig);
2386
2387   for(nd=notation;nd;nd=nd->next)
2388     {
2389       if(!first)
2390         tty_printf("%*s",indent,"");
2391       else
2392         first=0;
2393
2394       tty_print_utf8_string(nd->name,strlen(nd->name));
2395       tty_printf("=");
2396       tty_print_utf8_string(nd->value,strlen(nd->value));
2397       tty_printf("\n");
2398     }
2399
2400   free_notation(notation);
2401 }
2402
2403 /****************
2404  * show preferences of a public keyblock.
2405  */
2406 static void
2407 show_prefs (PKT_user_id *uid, PKT_signature *selfsig, int verbose)
2408 {
2409     const prefitem_t fake={0,0};
2410     const prefitem_t *prefs;
2411     int i;
2412
2413     if( !uid )
2414         return;
2415
2416     if( uid->prefs )
2417         prefs=uid->prefs;
2418     else if(verbose)
2419         prefs=&fake;
2420     else
2421       return;
2422
2423     if (verbose) {
2424         int any, des_seen=0, sha1_seen=0, uncomp_seen=0;
2425
2426         tty_printf ("     ");
2427         tty_printf (_("Cipher: "));
2428         for(i=any=0; prefs[i].type; i++ ) {
2429             if( prefs[i].type == PREFTYPE_SYM ) {
2430                 if (any)
2431                     tty_printf (", ");
2432                 any = 1;
2433                 /* We don't want to display strings for experimental algos */
2434                 if (!openpgp_cipher_test_algo (prefs[i].value)
2435                     && prefs[i].value < 100 )
2436                     tty_printf ("%s",
2437                                 openpgp_cipher_algo_name (prefs[i].value));
2438                 else
2439                     tty_printf ("[%d]", prefs[i].value);
2440                 if (prefs[i].value == CIPHER_ALGO_3DES )
2441                     des_seen = 1;
2442             }
2443         }
2444         if (!des_seen) {
2445             if (any)
2446                 tty_printf (", ");
2447             tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
2448         }
2449         tty_printf ("\n     ");
2450         tty_printf (_("Digest: "));
2451         for(i=any=0; prefs[i].type; i++ ) {
2452             if( prefs[i].type == PREFTYPE_HASH ) {
2453                 if (any)
2454                     tty_printf (", ");
2455                 any = 1;
2456                 /* We don't want to display strings for experimental algos */
2457                 if (!gcry_md_test_algo (prefs[i].value)
2458                     && prefs[i].value < 100 )
2459                     tty_printf ("%s", gcry_md_algo_name (prefs[i].value) );
2460                 else
2461                     tty_printf ("[%d]", prefs[i].value);
2462                 if (prefs[i].value == DIGEST_ALGO_SHA1 )
2463                     sha1_seen = 1;
2464             }
2465         }
2466         if (!sha1_seen) {
2467             if (any)
2468                 tty_printf (", ");
2469             tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
2470         }
2471         tty_printf ("\n     ");
2472         tty_printf (_("Compression: "));
2473         for(i=any=0; prefs[i].type; i++ ) {
2474             if( prefs[i].type == PREFTYPE_ZIP ) {
2475                 const char *s=compress_algo_to_string(prefs[i].value);
2476
2477                 if (any)
2478                     tty_printf (", ");
2479                 any = 1;
2480                 /* We don't want to display strings for experimental algos */
2481                 if (s && prefs[i].value < 100 )
2482                     tty_printf ("%s", s );
2483                 else
2484                     tty_printf ("[%d]", prefs[i].value);
2485                 if (prefs[i].value == COMPRESS_ALGO_NONE )
2486                     uncomp_seen = 1;
2487             }
2488         }
2489         if (!uncomp_seen) {
2490             if (any)
2491                 tty_printf (", ");
2492             else {
2493               tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_ZIP));
2494               tty_printf (", ");
2495             }
2496             tty_printf ("%s",compress_algo_to_string(COMPRESS_ALGO_NONE));
2497         }
2498         if(uid->flags.mdc || !uid->flags.ks_modify)
2499           {
2500             tty_printf ("\n     ");
2501             tty_printf (_("Features: "));
2502             any=0;
2503             if(uid->flags.mdc)
2504               {
2505                 tty_printf ("MDC");
2506                 any=1;
2507               }
2508             if(!uid->flags.ks_modify)
2509               {
2510                 if(any)
2511                   tty_printf (", ");
2512                 tty_printf (_("Keyserver no-modify"));
2513               }
2514           }
2515         tty_printf("\n");
2516
2517         if(selfsig)
2518           {
2519             const byte *pref_ks;
2520             size_t pref_ks_len;
2521
2522             pref_ks=parse_sig_subpkt(selfsig->hashed,
2523                                      SIGSUBPKT_PREF_KS,&pref_ks_len);
2524             if(pref_ks && pref_ks_len)
2525               {
2526                 tty_printf ("     ");
2527                 tty_printf(_("Preferred keyserver: "));
2528                 tty_print_utf8_string(pref_ks,pref_ks_len);
2529                 tty_printf("\n");
2530               }
2531
2532             if(selfsig->flags.notation)
2533               {
2534                 tty_printf ("     ");
2535                 tty_printf(_("Notations: "));
2536                 tty_print_notations(5+strlen(_("Notations: ")),selfsig);
2537               }
2538           }
2539     }
2540     else {
2541         tty_printf("    ");
2542         for(i=0; prefs[i].type; i++ ) {
2543             tty_printf( " %c%d", prefs[i].type == PREFTYPE_SYM   ? 'S' :
2544                                  prefs[i].type == PREFTYPE_HASH  ? 'H' :
2545                                  prefs[i].type == PREFTYPE_ZIP ? 'Z':'?',
2546                                  prefs[i].value);
2547         }
2548         if (uid->flags.mdc)
2549             tty_printf (" [mdc]");
2550         if (!uid->flags.ks_modify)
2551             tty_printf (" [no-ks-modify]");
2552         tty_printf("\n");
2553     }
2554 }
2555
2556 /* This is the version of show_key_with_all_names used when
2557    opt.with_colons is used.  It prints all available data in a easy to
2558    parse format and does not translate utf8 */
2559 static void
2560 show_key_with_all_names_colon (KBNODE keyblock)
2561 {
2562   KBNODE node;
2563   int i, j, ulti_hack=0;
2564   byte pk_version=0;
2565   PKT_public_key *primary=NULL;
2566
2567   /* the keys */
2568   for ( node = keyblock; node; node = node->next )
2569     {
2570       if (node->pkt->pkttype == PKT_PUBLIC_KEY
2571           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) )
2572         {
2573           PKT_public_key *pk = node->pkt->pkt.public_key;
2574           u32 keyid[2];
2575
2576           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2577             {
2578               pk_version = pk->version;
2579               primary=pk;
2580             }
2581
2582           keyid_from_pk (pk, keyid);
2583
2584           fputs (node->pkt->pkttype == PKT_PUBLIC_KEY?"pub:":"sub:", stdout);
2585           if (!pk->is_valid)
2586             putchar ('i');
2587           else if (pk->is_revoked)
2588             putchar ('r');
2589           else if (pk->has_expired)
2590             putchar ('e');
2591           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2592             {
2593               int trust = get_validity_info (pk, NULL);
2594               if(trust=='u')
2595                 ulti_hack=1;
2596               putchar (trust);
2597             }
2598
2599           printf (":%u:%d:%08lX%08lX:%lu:%lu::",
2600                   nbits_from_pk (pk),
2601                   pk->pubkey_algo,
2602                   (ulong)keyid[0], (ulong)keyid[1],
2603                   (ulong)pk->timestamp,
2604                   (ulong)pk->expiredate );
2605           if (node->pkt->pkttype==PKT_PUBLIC_KEY
2606               && !(opt.fast_list_mode || opt.no_expensive_trust_checks ))
2607             putchar(get_ownertrust_info (pk));
2608           putchar(':');
2609           putchar (':');
2610           putchar (':');
2611           /* Print capabilities.  */
2612           if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) )
2613             putchar ('e');
2614           if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) )
2615             putchar ('s');
2616           if ( (pk->pubkey_usage & PUBKEY_USAGE_CERT) )
2617             putchar ('c');
2618           if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
2619             putchar ('a');
2620           putchar('\n');
2621
2622           print_fingerprint (pk, NULL, 0);
2623           print_revokers(pk);
2624         }
2625     }
2626
2627     /* the user ids */
2628     i = 0;
2629     for (node = keyblock; node; node = node->next)
2630       {
2631         if ( node->pkt->pkttype == PKT_USER_ID )
2632           {
2633             PKT_user_id *uid = node->pkt->pkt.user_id;
2634
2635             ++i;
2636
2637             if(uid->attrib_data)
2638               printf("uat:");
2639             else
2640               printf("uid:");
2641
2642             if ( uid->is_revoked )
2643               printf("r::::::::");
2644             else if ( uid->is_expired )
2645               printf("e::::::::");
2646             else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
2647               printf("::::::::");
2648             else
2649               {
2650                 int uid_validity;
2651
2652                 if( primary && !ulti_hack )
2653                   uid_validity = get_validity_info( primary, uid );
2654                 else
2655                   uid_validity = 'u';
2656                 printf("%c::::::::",uid_validity);
2657               }
2658
2659             if(uid->attrib_data)
2660               printf ("%u %lu",uid->numattribs,uid->attrib_len);
2661             else
2662               print_string (stdout, uid->name, uid->len, ':');
2663
2664             putchar (':');
2665             /* signature class */
2666             putchar (':');
2667             /* capabilities */
2668             putchar (':');
2669             /* preferences */
2670             if (pk_version>3 || uid->selfsigversion>3)
2671               {
2672                 const prefitem_t *prefs = uid->prefs;
2673
2674                 for (j=0; prefs && prefs[j].type; j++)
2675                   {
2676                     if (j)
2677                       putchar (' ');
2678                     printf ("%c%d", prefs[j].type == PREFTYPE_SYM   ? 'S' :
2679                             prefs[j].type == PREFTYPE_HASH  ? 'H' :
2680                             prefs[j].type == PREFTYPE_ZIP ? 'Z':'?',
2681                             prefs[j].value);
2682                   }
2683                 if (uid->flags.mdc)
2684                   printf (",mdc");
2685                 if (!uid->flags.ks_modify)
2686                   printf (",no-ks-modify");
2687               }
2688             putchar (':');
2689             /* flags */
2690             printf ("%d,", i);
2691             if (uid->is_primary)
2692               putchar ('p');
2693             if (uid->is_revoked)
2694               putchar ('r');
2695             if (uid->is_expired)
2696               putchar ('e');
2697             if ((node->flag & NODFLG_SELUID))
2698               putchar ('s');
2699             if ((node->flag & NODFLG_MARK_A))
2700               putchar ('m');
2701             putchar (':');
2702             putchar('\n');
2703           }
2704       }
2705 }
2706
2707 static void
2708 show_names(KBNODE keyblock,PKT_public_key *pk,unsigned int flag,int with_prefs)
2709 {
2710   KBNODE node;
2711   int i=0;
2712
2713   for( node = keyblock; node; node = node->next )
2714     {
2715       if( node->pkt->pkttype == PKT_USER_ID
2716           && !is_deleted_kbnode(node))
2717         {
2718           PKT_user_id *uid = node->pkt->pkt.user_id;
2719           ++i;
2720           if(!flag || (flag && (node->flag & flag)))
2721             {
2722               if(!(flag&NODFLG_MARK_A) && pk)
2723                 tty_printf("%s ",uid_trust_string_fixed(pk,uid));
2724
2725               if( flag & NODFLG_MARK_A )
2726                 tty_printf("     ");
2727               else if( node->flag & NODFLG_SELUID )
2728                 tty_printf("(%d)* ", i);
2729               else if( uid->is_primary )
2730                 tty_printf("(%d). ", i);
2731               else
2732                 tty_printf("(%d)  ", i);
2733               tty_print_utf8_string( uid->name, uid->len );
2734               tty_printf("\n");
2735               if(with_prefs && pk)
2736                 {
2737                   if(pk->version>3 || uid->selfsigversion>3)
2738                     {
2739                       PKT_signature *selfsig=NULL;
2740                       KBNODE signode;
2741
2742                       for(signode=node->next;
2743                           signode && signode->pkt->pkttype==PKT_SIGNATURE;
2744                           signode=signode->next)
2745                         {
2746                           if(signode->pkt->pkt.signature->
2747                              flags.chosen_selfsig)
2748                             {
2749                               selfsig=signode->pkt->pkt.signature;
2750                               break;
2751                             }
2752                         }
2753
2754                       show_prefs (uid, selfsig, with_prefs == 2);
2755                     }
2756                   else
2757                     tty_printf(_("There are no preferences on a"
2758                                  " PGP 2.x-style user ID.\n"));
2759                 }
2760             }
2761         }
2762     }
2763 }
2764
2765 /****************
2766  * Display the key a the user ids, if only_marked is true, do only
2767  * so for user ids with mark A flag set and dont display the index number
2768  */
2769 static void
2770 show_key_with_all_names( KBNODE keyblock, int only_marked, int with_revoker,
2771                          int with_fpr, int with_subkeys, int with_prefs )
2772 {
2773     KBNODE node;
2774     int i;
2775     int do_warn = 0;
2776     PKT_public_key *primary=NULL;
2777
2778     if (opt.with_colons)
2779       {
2780         show_key_with_all_names_colon (keyblock);
2781         return;
2782       }
2783
2784     /* the keys */
2785     for( node = keyblock; node; node = node->next ) {
2786         if( node->pkt->pkttype == PKT_PUBLIC_KEY
2787             || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2788                 && !is_deleted_kbnode(node)) ) {
2789             PKT_public_key *pk = node->pkt->pkt.public_key;
2790             const char *otrust="err",*trust="err";
2791
2792             if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
2793                 /* do it here, so that debug messages don't clutter the
2794                  * output */
2795                 static int did_warn = 0;
2796
2797                 trust = get_validity_string (pk, NULL);
2798                 otrust = get_ownertrust_string (pk);
2799
2800                 /* Show a warning once */
2801                 if (!did_warn
2802                     && (get_validity (pk, NULL) & TRUST_FLAG_PENDING_CHECK)) {
2803                     did_warn = 1;
2804                     do_warn = 1;
2805                 }
2806
2807                 primary=pk;
2808             }
2809
2810             if(pk->is_revoked)
2811               {
2812                 char *user=get_user_id_string_native(pk->revoked.keyid);
2813                 const char *algo = openpgp_pk_algo_name (pk->revoked.algo);
2814                 tty_printf (_("The following key was revoked on"
2815                               " %s by %s key %s\n"),
2816                            revokestr_from_pk(pk),algo?algo:"?",user);
2817                 xfree(user);
2818               }
2819
2820             if(with_revoker)
2821               {
2822                 if( !pk->revkey && pk->numrevkeys )
2823                   BUG();
2824                 else
2825                   for(i=0;i<pk->numrevkeys;i++)
2826                     {
2827                       u32 r_keyid[2];
2828                       char *user;
2829                       const char *algo;
2830
2831                       algo = openpgp_pk_algo_name (pk->revkey[i].algid);
2832                       keyid_from_fingerprint(pk->revkey[i].fpr,
2833                                              MAX_FINGERPRINT_LEN,r_keyid);
2834
2835                       user=get_user_id_string_native(r_keyid);
2836                       tty_printf(_("This key may be revoked by %s key %s"),
2837                                  algo?algo:"?",user);
2838
2839                       if(pk->revkey[i].class&0x40)
2840                         {
2841                           tty_printf(" ");
2842                           tty_printf(_("(sensitive)"));
2843                         }
2844
2845                       tty_printf ("\n");
2846                       xfree(user);
2847                     }
2848               }
2849
2850             keyid_from_pk(pk,NULL);
2851             tty_printf("%s%c %4u%c/%s  ",
2852                        node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2853                        (node->flag & NODFLG_SELKEY)? '*':' ',
2854                        nbits_from_pk( pk ),
2855                        pubkey_letter( pk->pubkey_algo ),
2856                        keystr(pk->keyid));
2857
2858             tty_printf(_("created: %s"),datestr_from_pk(pk));
2859             tty_printf("  ");
2860             if(pk->is_revoked)
2861               tty_printf(_("revoked: %s"),revokestr_from_pk(pk));
2862             else if(pk->has_expired)
2863               tty_printf(_("expired: %s"),expirestr_from_pk(pk));
2864             else
2865               tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2866             tty_printf("  ");
2867             tty_printf(_("usage: %s"),usagestr_from_pk(pk));
2868             tty_printf("\n");
2869
2870             if( node->pkt->pkttype == PKT_PUBLIC_KEY )
2871               {
2872                 if(opt.trust_model!=TM_ALWAYS)
2873                   {
2874                     tty_printf("%*s", (int)keystrlen()+13,"");
2875                     /* Ownertrust is only meaningful for the PGP or
2876                        classic trust models */
2877                     if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
2878                       {
2879                         int width=14-strlen(otrust);
2880                         if(width<=0)
2881                           width=1;
2882                         tty_printf(_("trust: %s"), otrust);
2883                         tty_printf("%*s",width,"");
2884                       }
2885
2886                     tty_printf(_("validity: %s"), trust );
2887                     tty_printf("\n");
2888                   }
2889                 if( node->pkt->pkttype == PKT_PUBLIC_KEY
2890                     && (get_ownertrust (pk)&TRUST_FLAG_DISABLED))
2891                   {
2892                     tty_printf("*** ");
2893                     tty_printf(_("This key has been disabled"));
2894                     tty_printf("\n");
2895                   }
2896               }
2897
2898             if( node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr )
2899               {
2900                 print_fingerprint ( pk, NULL, 2 );
2901                 tty_printf("\n");
2902               }
2903         }
2904         else if( node->pkt->pkttype == PKT_SECRET_KEY
2905             || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY) )
2906           {
2907             PKT_secret_key *sk = node->pkt->pkt.secret_key;
2908             tty_printf("%s%c %4u%c/%s  ",
2909                        node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2910                        (node->flag & NODFLG_SELKEY)? '*':' ',
2911                        nbits_from_sk( sk ),
2912                        pubkey_letter( sk->pubkey_algo ),
2913                        keystr_from_sk(sk));
2914             tty_printf(_("created: %s"),datestr_from_sk(sk));
2915             tty_printf("  ");
2916             tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2917             tty_printf("\n");
2918             if (sk->is_protected && sk->protect.s2k.mode == 1002)
2919               {
2920                 tty_printf("                     ");
2921                 tty_printf(_("card-no: "));
2922                 if (sk->protect.ivlen == 16
2923                     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
2924                   { /* This is an OpenPGP card. */
2925                     for (i=8; i < 14; i++)
2926                       {
2927                         if (i == 10)
2928                           tty_printf (" ");
2929                         tty_printf ("%02X", sk->protect.iv[i]);
2930                       }
2931                   }
2932                 else
2933                   { /* Something is wrong: Print all. */
2934                     for (i=0; i < sk->protect.ivlen; i++)
2935                       tty_printf ("%02X", sk->protect.iv[i]);
2936                   }
2937                 tty_printf ("\n");
2938               }
2939           }
2940     }
2941
2942     show_names(keyblock,primary,only_marked?NODFLG_MARK_A:0,with_prefs);
2943
2944     if (do_warn)
2945         tty_printf (_("Please note that the shown key validity"
2946                       " is not necessarily correct\n"
2947                       "unless you restart the program.\n"));
2948 }
2949
2950
2951 /* Display basic key information.  This function is suitable to show
2952    information on the key without any dependencies on the trustdb or
2953    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
2954    a secret key.*/
2955 void
2956 show_basic_key_info ( KBNODE keyblock )
2957 {
2958   KBNODE node;
2959   int i;
2960
2961   /* The primary key */
2962   for (node = keyblock; node; node = node->next)
2963     {
2964       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
2965         {
2966           PKT_public_key *pk = node->pkt->pkt.public_key;
2967
2968           /* Note, we use the same format string as in other show
2969              functions to make the translation job easier. */
2970           tty_printf ("%s  %4u%c/%s  ",
2971                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
2972                       nbits_from_pk( pk ),
2973                       pubkey_letter( pk->pubkey_algo ),
2974                       keystr_from_pk(pk));
2975           tty_printf(_("created: %s"),datestr_from_pk(pk));
2976           tty_printf("  ");
2977           tty_printf(_("expires: %s"),expirestr_from_pk(pk));
2978           tty_printf("\n");
2979           print_fingerprint ( pk, NULL, 3 );
2980           tty_printf("\n");
2981         }
2982       else if (node->pkt->pkttype == PKT_SECRET_KEY)
2983         {
2984           PKT_secret_key *sk = node->pkt->pkt.secret_key;
2985           tty_printf("%s  %4u%c/%s",
2986                      node->pkt->pkttype == PKT_SECRET_KEY? "sec":"ssb",
2987                      nbits_from_sk( sk ),
2988                      pubkey_letter( sk->pubkey_algo ),
2989                      keystr_from_sk(sk));
2990           tty_printf(_("created: %s"),datestr_from_sk(sk));
2991           tty_printf("  ");
2992           tty_printf(_("expires: %s"),expirestr_from_sk(sk));
2993           tty_printf("\n");
2994           print_fingerprint (NULL, sk, 3 );
2995           tty_printf("\n");
2996         }
2997     }
2998
2999   /* The user IDs. */
3000   for (i=0, node = keyblock; node; node = node->next)
3001     {
3002       if (node->pkt->pkttype == PKT_USER_ID)
3003         {
3004           PKT_user_id *uid = node->pkt->pkt.user_id;
3005           ++i;
3006
3007           tty_printf ("     ");
3008           if (uid->is_revoked)
3009             tty_printf("[%s] ",_("revoked"));
3010           else if ( uid->is_expired )
3011             tty_printf("[%s] ",_("expired"));
3012           tty_print_utf8_string (uid->name, uid->len);
3013           tty_printf ("\n");
3014         }
3015     }
3016 }
3017
3018 static void
3019 show_key_and_fingerprint( KBNODE keyblock )
3020 {
3021   KBNODE node;
3022   PKT_public_key *pk = NULL;
3023
3024   for( node = keyblock; node; node = node->next )
3025     {
3026       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
3027         {
3028           pk = node->pkt->pkt.public_key;
3029           tty_printf("pub   %4u%c/%s %s ",
3030                      nbits_from_pk( pk ),
3031                      pubkey_letter( pk->pubkey_algo ),
3032                      keystr_from_pk(pk),
3033                      datestr_from_pk(pk) );
3034         }
3035       else if( node->pkt->pkttype == PKT_USER_ID )
3036         {
3037           PKT_user_id *uid = node->pkt->pkt.user_id;
3038           tty_print_utf8_string( uid->name, uid->len );
3039           break;
3040         }
3041     }
3042   tty_printf("\n");
3043   if( pk )
3044     print_fingerprint( pk, NULL, 2 );
3045 }
3046
3047
3048 /* Show a warning if no uids on the key have the primary uid flag
3049    set. */
3050 static void
3051 no_primary_warning(KBNODE keyblock)
3052 {
3053   KBNODE node;
3054   int have_primary=0,uid_count=0;
3055
3056   /* TODO: if we ever start behaving differently with a primary or
3057      non-primary attribute ID, we will need to check for attributes
3058      here as well. */
3059
3060   for(node=keyblock; node; node = node->next)
3061     {
3062       if(node->pkt->pkttype==PKT_USER_ID
3063          && node->pkt->pkt.user_id->attrib_data==NULL)
3064         {
3065           uid_count++;
3066
3067           if(node->pkt->pkt.user_id->is_primary==2)
3068             {
3069               have_primary=1;
3070               break;
3071             }
3072         }
3073     }
3074
3075   if(uid_count>1 && !have_primary)
3076     log_info(_("WARNING: no user ID has been marked as primary.  This command"
3077                " may\n              cause a different user ID to become"
3078                " the assumed primary.\n"));
3079 }
3080
3081 /****************
3082  * Ask for a new user id, do the selfsignature and put it into
3083  * both keyblocks.
3084  * Return true if there is a new user id
3085  */
3086 static int
3087 menu_adduid( KBNODE pub_keyblock, KBNODE sec_keyblock,
3088              int photo, const char *photo_name)
3089 {
3090     PKT_user_id *uid;
3091     PKT_public_key *pk=NULL;
3092     PKT_secret_key *sk=NULL;
3093     PKT_signature *sig=NULL;
3094     PACKET *pkt;
3095     KBNODE node;
3096     KBNODE pub_where=NULL, sec_where=NULL;
3097     int rc;
3098
3099     for( node = pub_keyblock; node; pub_where = node, node = node->next ) {
3100         if( node->pkt->pkttype == PKT_PUBLIC_KEY )
3101             pk = node->pkt->pkt.public_key;
3102         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3103             break;
3104     }
3105     if( !node ) /* no subkey */
3106         pub_where = NULL;
3107     for( node = sec_keyblock; node; sec_where = node, node = node->next ) {
3108         if( node->pkt->pkttype == PKT_SECRET_KEY )
3109             sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3110         else if( node->pkt->pkttype == PKT_SECRET_SUBKEY )
3111             break;
3112     }
3113     if( !node ) /* no subkey */
3114         sec_where = NULL;
3115     assert(pk && sk);
3116
3117     if(photo) {
3118       int hasattrib=0;
3119
3120       for( node = pub_keyblock; node; node = node->next )
3121         if( node->pkt->pkttype == PKT_USER_ID &&
3122             node->pkt->pkt.user_id->attrib_data!=NULL)
3123           {
3124             hasattrib=1;
3125             break;
3126           }
3127
3128       /* It is legal but bad for compatibility to add a photo ID to a
3129          v3 key as it means that PGP2 will not be able to use that key
3130          anymore.  Also, PGP may not expect a photo on a v3 key.
3131          Don't bother to ask this if the key already has a photo - any
3132          damage has already been done at that point. -dms */
3133       if(pk->version==3 && !hasattrib)
3134         {
3135           if(opt.expert)
3136             {
3137               tty_printf(_("WARNING: This is a PGP2-style key.  "
3138                            "Adding a photo ID may cause some versions\n"
3139                            "         of PGP to reject this key.\n"));
3140
3141               if(!cpr_get_answer_is_yes("keyedit.v3_photo.okay",
3142                                         _("Are you sure you still want "
3143                                           "to add it? (y/N) ")))
3144                 return 0;
3145             }
3146           else
3147             {
3148               tty_printf(_("You may not add a photo ID to "
3149                            "a PGP2-style key.\n"));
3150               return 0;
3151             }
3152         }
3153
3154       uid = generate_photo_id(pk,photo_name);
3155     } else
3156       uid = generate_user_id (pub_keyblock);
3157     if( !uid )
3158         return 0;
3159
3160     rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
3161                              keygen_add_std_prefs, pk );
3162     free_secret_key( sk );
3163     if( rc ) {
3164         log_error("signing failed: %s\n", g10_errstr(rc) );
3165         free_user_id(uid);
3166         return 0;
3167     }
3168
3169     /* insert/append to secret keyblock */
3170     pkt = xmalloc_clear( sizeof *pkt );
3171     pkt->pkttype = PKT_USER_ID;
3172     pkt->pkt.user_id = scopy_user_id(uid);
3173     node = new_kbnode(pkt);
3174     if( sec_where )
3175         insert_kbnode( sec_where, node, 0 );
3176     else
3177         add_kbnode( sec_keyblock, node );
3178     pkt = xmalloc_clear( sizeof *pkt );
3179     pkt->pkttype = PKT_SIGNATURE;
3180     pkt->pkt.signature = copy_signature(NULL, sig);
3181     if( sec_where )
3182         insert_kbnode( node, new_kbnode(pkt), 0 );
3183     else
3184         add_kbnode( sec_keyblock, new_kbnode(pkt) );
3185     /* insert/append to public keyblock */
3186     pkt = xmalloc_clear( sizeof *pkt );
3187     pkt->pkttype = PKT_USER_ID;
3188     pkt->pkt.user_id = uid;
3189     node = new_kbnode(pkt);
3190     if( pub_where )
3191         insert_kbnode( pub_where, node, 0 );
3192     else
3193         add_kbnode( pub_keyblock, node );
3194     pkt = xmalloc_clear( sizeof *pkt );
3195     pkt->pkttype = PKT_SIGNATURE;
3196     pkt->pkt.signature = copy_signature(NULL, sig);
3197     if( pub_where )
3198         insert_kbnode( node, new_kbnode(pkt), 0 );
3199     else
3200         add_kbnode( pub_keyblock, new_kbnode(pkt) );
3201     return 1;
3202 }
3203
3204
3205 /****************
3206  * Remove all selected userids from the keyrings
3207  */
3208 static void
3209 menu_deluid( KBNODE pub_keyblock, KBNODE sec_keyblock )
3210 {
3211     KBNODE node;
3212     int selected=0;
3213
3214     for( node = pub_keyblock; node; node = node->next ) {
3215         if( node->pkt->pkttype == PKT_USER_ID ) {
3216             selected = node->flag & NODFLG_SELUID;
3217             if( selected ) {
3218                 /* Only cause a trust update if we delete a
3219                    non-revoked user id */
3220                 if(!node->pkt->pkt.user_id->is_revoked)
3221                   update_trust=1;
3222                 delete_kbnode( node );
3223                 if( sec_keyblock ) {
3224                     KBNODE snode;
3225                     int s_selected = 0;
3226                     PKT_user_id *uid = node->pkt->pkt.user_id;
3227                     for( snode = sec_keyblock; snode; snode = snode->next ) {
3228                         if( snode->pkt->pkttype == PKT_USER_ID ) {
3229                             PKT_user_id *suid = snode->pkt->pkt.user_id;
3230
3231                             s_selected =
3232                                 (uid->len == suid->len
3233                                  && !memcmp( uid->name, suid->name, uid->len));
3234                             if( s_selected )
3235                                 delete_kbnode( snode );
3236                         }
3237                         else if( s_selected
3238                                  && snode->pkt->pkttype == PKT_SIGNATURE )
3239                             delete_kbnode( snode );
3240                         else if( snode->pkt->pkttype == PKT_SECRET_SUBKEY )
3241                             s_selected = 0;
3242                     }
3243                 }
3244             }
3245         }
3246         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3247             delete_kbnode( node );
3248         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3249             selected = 0;
3250     }
3251     commit_kbnode( &pub_keyblock );
3252     if( sec_keyblock )
3253         commit_kbnode( &sec_keyblock );
3254 }
3255
3256
3257 static int
3258 menu_delsig( KBNODE pub_keyblock )
3259 {
3260     KBNODE node;
3261     PKT_user_id *uid = NULL;
3262     int changed=0;
3263
3264     for( node = pub_keyblock; node; node = node->next ) {
3265         if( node->pkt->pkttype == PKT_USER_ID ) {
3266             uid = (node->flag & NODFLG_SELUID)? node->pkt->pkt.user_id : NULL;
3267         }
3268         else if( uid && node->pkt->pkttype == PKT_SIGNATURE ) {
3269            int okay, valid, selfsig, inv_sig, no_key, other_err;
3270
3271             tty_printf("uid  ");
3272             tty_print_utf8_string( uid->name, uid->len );
3273             tty_printf("\n");
3274
3275             okay = inv_sig = no_key = other_err = 0;
3276             if(opt.with_colons)
3277               valid = print_and_check_one_sig_colon( pub_keyblock, node,
3278                                                &inv_sig, &no_key, &other_err,
3279                                                &selfsig, 1 );
3280             else
3281               valid = print_and_check_one_sig( pub_keyblock, node,
3282                                                &inv_sig, &no_key, &other_err,
3283                                                &selfsig, 1 );
3284
3285            if( valid ) {
3286                okay = cpr_get_answer_yes_no_quit(
3287                    "keyedit.delsig.valid",
3288                    _("Delete this good signature? (y/N/q)"));
3289
3290                /* Only update trust if we delete a good signature.
3291                   The other two cases do not affect trust. */
3292                if(okay)
3293                  update_trust=1;
3294            }
3295            else if( inv_sig || other_err )
3296                okay = cpr_get_answer_yes_no_quit(
3297                    "keyedit.delsig.invalid",
3298                    _("Delete this invalid signature? (y/N/q)"));
3299            else if( no_key )
3300                okay = cpr_get_answer_yes_no_quit(
3301                    "keyedit.delsig.unknown",
3302                    _("Delete this unknown signature? (y/N/q)"));
3303
3304             if( okay == -1 )
3305                 break;
3306            if( okay && selfsig && !cpr_get_answer_is_yes(
3307                                "keyedit.delsig.selfsig",
3308                               _("Really delete this self-signature? (y/N)") ))
3309                 okay = 0;
3310             if( okay ) {
3311                 delete_kbnode( node );
3312                 changed++;
3313             }
3314
3315         }
3316         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3317             uid = NULL;
3318     }
3319
3320     if( changed ) {
3321         commit_kbnode( &pub_keyblock );
3322         tty_printf( changed == 1? _("Deleted %d signature.\n")
3323                                 : _("Deleted %d signatures.\n"), changed );
3324     }
3325     else
3326         tty_printf( _("Nothing deleted.\n") );
3327
3328     return changed;
3329 }
3330
3331 static int
3332 menu_clean(KBNODE keyblock,int self_only)
3333 {
3334   KBNODE uidnode;
3335   int modified=0,select_all=!count_selected_uids(keyblock);
3336
3337   for(uidnode=keyblock->next;
3338       uidnode && uidnode->pkt->pkttype!=PKT_PUBLIC_SUBKEY;
3339       uidnode=uidnode->next)
3340     {
3341       if(uidnode->pkt->pkttype==PKT_USER_ID
3342          && (uidnode->flag&NODFLG_SELUID || select_all))
3343         {
3344           int uids=0,sigs=0;
3345           char *user=utf8_to_native(uidnode->pkt->pkt.user_id->name,
3346                                     uidnode->pkt->pkt.user_id->len,
3347                                     0);
3348
3349           clean_one_uid(keyblock,uidnode,opt.verbose,self_only,&uids,&sigs);
3350           if(uids)
3351             {
3352               const char *reason;
3353
3354               if(uidnode->pkt->pkt.user_id->is_revoked)
3355                 reason=_("revoked");
3356               else if(uidnode->pkt->pkt.user_id->is_expired)
3357                 reason=_("expired");
3358               else
3359                 reason=_("invalid");
3360
3361               tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
3362
3363               modified=1;
3364             }
3365           else if(sigs)
3366             {
3367               tty_printf(sigs==1?
3368                          _("User ID \"%s\": %d signature removed\n") :
3369                          _("User ID \"%s\": %d signatures removed\n"),
3370                          user,sigs);
3371
3372               modified=1;
3373             }
3374           else
3375             {
3376               tty_printf (self_only==1?
3377                           _("User ID \"%s\": already minimized\n") :
3378                           _("User ID \"%s\": already clean\n"),
3379                           user);
3380             }
3381
3382           xfree(user);
3383         }
3384     }
3385
3386   return modified;
3387 }
3388
3389 /****************
3390  * Remove some of the secondary keys
3391  */
3392 static void
3393 menu_delkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
3394 {
3395     KBNODE node;
3396     int selected=0;
3397
3398     for( node = pub_keyblock; node; node = node->next ) {
3399         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
3400             selected = node->flag & NODFLG_SELKEY;
3401             if( selected ) {
3402                 delete_kbnode( node );
3403                 if( sec_keyblock ) {
3404                     KBNODE snode;
3405                     int s_selected = 0;
3406                     u32 ki[2];
3407
3408                     keyid_from_pk( node->pkt->pkt.public_key, ki );
3409                     for( snode = sec_keyblock; snode; snode = snode->next ) {
3410                         if( snode->pkt->pkttype == PKT_SECRET_SUBKEY ) {
3411                             u32 ki2[2];
3412
3413                             keyid_from_sk( snode->pkt->pkt.secret_key, ki2 );
3414                             s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
3415                             if( s_selected )
3416                                 delete_kbnode( snode );
3417                         }
3418                         else if( s_selected
3419                                  && snode->pkt->pkttype == PKT_SIGNATURE )
3420                             delete_kbnode( snode );
3421                         else
3422                             s_selected = 0;
3423                     }
3424                 }
3425             }
3426         }
3427         else if( selected && node->pkt->pkttype == PKT_SIGNATURE )
3428             delete_kbnode( node );
3429         else
3430             selected = 0;
3431     }
3432     commit_kbnode( &pub_keyblock );
3433     if( sec_keyblock )
3434         commit_kbnode( &sec_keyblock );
3435
3436     /* No need to set update_trust here since signing keys are no
3437        longer used to certify other keys, so there is no change in
3438        trust when revoking/removing them */
3439 }
3440
3441
3442 /****************
3443  * Ask for a new revoker, do the selfsignature and put it into
3444  * both keyblocks.
3445  * Return true if there is a new revoker
3446  */
3447 static int
3448 menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
3449 {
3450   PKT_public_key *pk=NULL,*revoker_pk=NULL;
3451   PKT_secret_key *sk=NULL;
3452   PKT_signature *sig=NULL;
3453   PACKET *pkt;
3454   struct revocation_key revkey;
3455   size_t fprlen;
3456   int rc;
3457
3458   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3459   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3460
3461   pk=pub_keyblock->pkt->pkt.public_key;
3462
3463   if(pk->numrevkeys==0 && pk->version==3)
3464     {
3465       /* It is legal but bad for compatibility to add a revoker to a
3466          v3 key as it means that PGP2 will not be able to use that key
3467          anymore.  Also, PGP may not expect a revoker on a v3 key.
3468          Don't bother to ask this if the key already has a revoker -
3469          any damage has already been done at that point. -dms */
3470       if(opt.expert)
3471         {
3472           tty_printf(_("WARNING: This is a PGP 2.x-style key.  "
3473                        "Adding a designated revoker may cause\n"
3474                        "         some versions of PGP to reject this key.\n"));
3475
3476           if(!cpr_get_answer_is_yes("keyedit.v3_revoker.okay",
3477                                     _("Are you sure you still want "
3478                                       "to add it? (y/N) ")))
3479             return 0;
3480         }
3481       else
3482         {
3483           tty_printf(_("You may not add a designated revoker to "
3484                        "a PGP 2.x-style key.\n"));
3485           return 0;
3486         }
3487     }
3488
3489   sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3490
3491   for(;;)
3492     {
3493       char *answer;
3494
3495       if(revoker_pk)
3496         free_public_key(revoker_pk);
3497
3498       revoker_pk=xmalloc_clear(sizeof(*revoker_pk));
3499
3500       tty_printf("\n");
3501
3502       answer=cpr_get_utf8("keyedit.add_revoker",
3503                           _("Enter the user ID of the designated revoker: "));
3504       if(answer[0]=='\0' || answer[0]=='\004')
3505         {
3506           xfree(answer);
3507           goto fail;
3508         }
3509
3510       /* Note that I'm requesting CERT here, which usually implies
3511          primary keys only, but some casual testing shows that PGP and
3512          GnuPG both can handle a designated revokation from a
3513          subkey. */
3514       revoker_pk->req_usage=PUBKEY_USAGE_CERT;
3515       rc=get_pubkey_byname (NULL, revoker_pk,answer,NULL,NULL,1, 1);
3516       if(rc)
3517         {
3518           log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));
3519           xfree(answer);
3520           continue;
3521         }
3522
3523       xfree(answer);
3524
3525       fingerprint_from_pk(revoker_pk,revkey.fpr,&fprlen);
3526       if(fprlen!=20)
3527         {
3528           log_error(_("cannot appoint a PGP 2.x style key as a "
3529                       "designated revoker\n"));
3530           continue;
3531         }
3532
3533       revkey.class=0x80;
3534       if(sensitive)
3535         revkey.class|=0x40;
3536       revkey.algid=revoker_pk->pubkey_algo;
3537
3538       if(cmp_public_keys(revoker_pk,pk)==0)
3539         {
3540           /* This actually causes no harm (after all, a key that
3541              designates itself as a revoker is the same as a
3542              regular key), but it's easy enough to check. */
3543           log_error(_("you cannot appoint a key as its own "
3544                       "designated revoker\n"));
3545
3546           continue;
3547         }
3548
3549       keyid_from_pk(pk,NULL);
3550
3551       /* Does this revkey already exist? */
3552       if(!pk->revkey && pk->numrevkeys)
3553         BUG();
3554       else
3555         {
3556           int i;
3557
3558           for(i=0;i<pk->numrevkeys;i++)
3559             {
3560               if(memcmp(&pk->revkey[i],&revkey,
3561                         sizeof(struct revocation_key))==0)
3562                 {
3563                   char buf[50];
3564
3565                   log_error(_("this key has already been designated "
3566                               "as a revoker\n"));
3567
3568                   sprintf(buf,"%08lX%08lX",
3569                           (ulong)pk->keyid[0],(ulong)pk->keyid[1]);
3570                   write_status_text(STATUS_ALREADY_SIGNED,buf);
3571
3572                   break;
3573                 }
3574             }
3575
3576           if(i<pk->numrevkeys)
3577             continue;
3578         }
3579
3580       print_pubkey_info(NULL,revoker_pk);
3581       print_fingerprint(revoker_pk,NULL,2);
3582       tty_printf("\n");
3583
3584       tty_printf(_("WARNING: appointing a key as a designated revoker "
3585                    "cannot be undone!\n"));
3586
3587       tty_printf("\n");
3588
3589       if(!cpr_get_answer_is_yes("keyedit.add_revoker.okay",
3590                                 _("Are you sure you want to appoint this "
3591                                   "key as a designated revoker? (y/N) ")))
3592         continue;
3593
3594       free_public_key(revoker_pk);
3595       revoker_pk=NULL;
3596       break;
3597     }
3598
3599   /* The 1F signature must be at least v4 to carry the revocation key
3600      subpacket. */
3601   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
3602                            keygen_add_revkey,&revkey );
3603   if( rc )
3604     {
3605       log_error("signing failed: %s\n", g10_errstr(rc) );
3606       goto fail;
3607     }
3608
3609   free_secret_key(sk);
3610   sk=NULL;
3611
3612   /* insert into secret keyblock */
3613   pkt = xmalloc_clear( sizeof *pkt );
3614   pkt->pkttype = PKT_SIGNATURE;
3615   pkt->pkt.signature = copy_signature(NULL, sig);
3616   insert_kbnode( sec_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3617
3618   /* insert into public keyblock */
3619   pkt = xmalloc_clear( sizeof *pkt );
3620   pkt->pkttype = PKT_SIGNATURE;
3621   pkt->pkt.signature = sig;
3622   insert_kbnode( pub_keyblock, new_kbnode(pkt), PKT_SIGNATURE );
3623
3624   return 1;
3625
3626  fail:
3627   if(sk)
3628     free_secret_key(sk);
3629   if(sig)
3630     free_seckey_enc(sig);
3631   if(revoker_pk)
3632     free_public_key(revoker_pk);
3633
3634   return 0;
3635 }
3636
3637
3638 static int
3639 menu_expire( KBNODE pub_keyblock, KBNODE sec_keyblock )
3640 {
3641     int n1, signumber, rc;
3642     u32 expiredate;
3643     int mainkey=0;
3644     PKT_secret_key *sk;    /* copy of the main sk */
3645     PKT_public_key *main_pk, *sub_pk;
3646     PKT_user_id *uid;
3647     KBNODE node;
3648     u32 keyid[2];
3649
3650     if( count_selected_keys( sec_keyblock ) ) {
3651         tty_printf(_("Please remove selections from the secret keys.\n"));
3652         return 0;
3653     }
3654
3655     n1 = count_selected_keys( pub_keyblock );
3656     if( n1 > 1 ) {
3657         tty_printf(_("Please select at most one subkey.\n"));
3658         return 0;
3659     }
3660     else if( n1 )
3661         tty_printf(_("Changing expiration time for a subkey.\n"));
3662     else
3663       {
3664         tty_printf(_("Changing expiration time for the primary key.\n"));
3665         mainkey=1;
3666         no_primary_warning(pub_keyblock);
3667       }
3668
3669     expiredate = ask_expiredate();
3670     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3671     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3672
3673     /* Now we can actually change the self signature(s) */
3674     main_pk = sub_pk = NULL;
3675     uid = NULL;
3676     signumber = 0;
3677     for( node=pub_keyblock; node; node = node->next ) {
3678         if( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3679             main_pk = node->pkt->pkt.public_key;
3680             keyid_from_pk( main_pk, keyid );
3681             main_pk->expiredate = expiredate;
3682         }
3683         else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
3684                  && (node->flag & NODFLG_SELKEY ) ) {
3685             sub_pk = node->pkt->pkt.public_key;
3686             sub_pk->expiredate = expiredate;
3687         }
3688         else if( node->pkt->pkttype == PKT_USER_ID )
3689             uid = node->pkt->pkt.user_id;
3690         else if( main_pk && node->pkt->pkttype == PKT_SIGNATURE
3691                  && ( mainkey || sub_pk ) ) {
3692             PKT_signature *sig = node->pkt->pkt.signature;
3693             if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
3694                 && ( (mainkey && uid
3695                       && uid->created && (sig->sig_class&~3) == 0x10)
3696                      || (!mainkey && sig->sig_class == 0x18)  )
3697                 && sig->flags.chosen_selfsig )
3698               {
3699                 /* this is a selfsignature which is to be replaced */
3700                 PKT_signature *newsig;
3701                 PACKET *newpkt;
3702                 KBNODE sn;
3703                 int signumber2 = 0;
3704
3705                 signumber++;
3706
3707                 if( (mainkey && main_pk->version < 4)
3708                     || (!mainkey && sub_pk->version < 4 ) ) {
3709                     log_info(_(
3710                         "You can't change the expiration date of a v3 key\n"));
3711                     free_secret_key( sk );
3712                     return 0;
3713                 }
3714
3715                 /* find the corresponding secret self-signature */
3716                 for( sn=sec_keyblock; sn; sn = sn->next ) {
3717                     if( sn->pkt->pkttype == PKT_SIGNATURE ) {
3718                         PKT_signature *b = sn->pkt->pkt.signature;
3719                         if( keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
3720                             && sig->sig_class == b->sig_class
3721                             && ++signumber2 == signumber )
3722                             break;
3723                     }
3724                 }
3725                 if( !sn )
3726                     log_info(_("No corresponding signature in secret ring\n"));
3727
3728                 if( mainkey )
3729                   rc = update_keysig_packet(&newsig, sig, main_pk, uid, NULL,
3730                                             sk, keygen_add_key_expire, main_pk);
3731                 else
3732                   rc = update_keysig_packet(&newsig, sig, main_pk, NULL, sub_pk,
3733                                             sk, keygen_add_key_expire, sub_pk );
3734                 if( rc ) {
3735                     log_error("make_keysig_packet failed: %s\n",
3736                                                     g10_errstr(rc));
3737                     free_secret_key( sk );
3738                     return 0;
3739                 }
3740                 /* replace the packet */
3741                 newpkt = xmalloc_clear( sizeof *newpkt );
3742                 newpkt->pkttype = PKT_SIGNATURE;
3743                 newpkt->pkt.signature = newsig;
3744                 free_packet( node->pkt );
3745                 xfree( node->pkt );
3746                 node->pkt = newpkt;
3747                 if( sn ) {
3748                     newpkt = xmalloc_clear( sizeof *newpkt );
3749                     newpkt->pkttype = PKT_SIGNATURE;
3750                     newpkt->pkt.signature = copy_signature( NULL, newsig );
3751                     free_packet( sn->pkt );
3752                     xfree( sn->pkt );
3753                     sn->pkt = newpkt;
3754                 }
3755                 sub_pk = NULL;
3756             }
3757         }
3758     }
3759
3760     free_secret_key( sk );
3761     update_trust=1;
3762     return 1;
3763 }
3764
3765 static int
3766 menu_backsign(KBNODE pub_keyblock,KBNODE sec_keyblock)
3767 {
3768   int rc,modified=0;
3769   PKT_public_key *main_pk;
3770   PKT_secret_key *main_sk,*sub_sk=NULL;
3771   KBNODE node;
3772   u32 timestamp;
3773
3774   assert(pub_keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
3775   assert(sec_keyblock->pkt->pkttype==PKT_SECRET_KEY);
3776
3777   merge_keys_and_selfsig(pub_keyblock);
3778   main_pk=pub_keyblock->pkt->pkt.public_key;
3779   main_sk=copy_secret_key(NULL,sec_keyblock->pkt->pkt.secret_key);
3780   keyid_from_pk(main_pk,NULL);
3781
3782   /* We use the same timestamp for all backsigs so that we don't
3783      reveal information about the used machine.  */
3784   timestamp = make_timestamp ();
3785
3786   for(node=pub_keyblock;node;node=node->next)
3787     {
3788       PKT_public_key *sub_pk=NULL;
3789       KBNODE node2,sig_pk=NULL,sig_sk=NULL;
3790       char *passphrase;
3791
3792       if(sub_sk)
3793         {
3794           free_secret_key(sub_sk);
3795           sub_sk=NULL;
3796         }
3797
3798       /* Find a signing subkey with no backsig */
3799       if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY)
3800         {
3801           if(node->pkt->pkt.public_key->pubkey_usage&PUBKEY_USAGE_SIG)
3802             {
3803               if(node->pkt->pkt.public_key->backsig)
3804                 tty_printf(_("signing subkey %s is already cross-certified\n"),
3805                            keystr_from_pk(node->pkt->pkt.public_key));
3806               else
3807                 sub_pk=node->pkt->pkt.public_key;
3808             }
3809           else
3810             tty_printf(_("subkey %s does not sign and so does"
3811                          " not need to be cross-certified\n"),
3812                        keystr_from_pk(node->pkt->pkt.public_key));
3813         }
3814
3815       if(!sub_pk)
3816         continue;
3817
3818       /* Find the selected selfsig on this subkey */
3819       for(node2=node->next;
3820           node2 && node2->pkt->pkttype==PKT_SIGNATURE;
3821           node2=node2->next)
3822         if(node2->pkt->pkt.signature->version>=4
3823            && node2->pkt->pkt.signature->flags.chosen_selfsig)
3824           {
3825             sig_pk=node2;
3826             break;
3827           }
3828
3829       if(!sig_pk)
3830         continue;
3831
3832       /* Find the secret subkey that matches the public subkey */
3833       for(node2=sec_keyblock;node2;node2=node2->next)
3834         if(node2->pkt->pkttype==PKT_SECRET_SUBKEY
3835            && !cmp_public_secret_key(sub_pk,node2->pkt->pkt.secret_key))
3836           {
3837             sub_sk=copy_secret_key(NULL,node2->pkt->pkt.secret_key);
3838             break;
3839           }
3840
3841       if(!sub_sk)
3842         {
3843           tty_printf(_("no secret subkey for public subkey %s - ignoring\n"),
3844                      keystr_from_pk(sub_pk));
3845           continue;
3846         }
3847
3848       /* Now finally find the matching selfsig on the secret subkey.
3849          We can't use chosen_selfsig here (it's not set for secret
3850          keys), so we just pick the selfsig with the right class.
3851          This is what menu_expire does as well. */
3852       for(node2=node2->next;
3853           node2 && node2->pkt->pkttype!=PKT_SECRET_SUBKEY;
3854           node2=node2->next)
3855         if(node2->pkt->pkttype==PKT_SIGNATURE
3856            && node2->pkt->pkt.signature->version>=4
3857            && node2->pkt->pkt.signature->keyid[0]==sig_pk->pkt->pkt.signature->keyid[0]
3858            && node2->pkt->pkt.signature->keyid[1]==sig_pk->pkt->pkt.signature->keyid[1]
3859            && node2->pkt->pkt.signature->sig_class==sig_pk->pkt->pkt.signature->sig_class)
3860           {
3861             sig_sk=node2;
3862             break;
3863           }
3864
3865       /* Now we can get to work.  We have a main key and secret part,
3866          a signing subkey with signature and secret part possibly with
3867          signature. */
3868
3869       passphrase=get_last_passphrase();
3870       set_next_passphrase(passphrase);
3871       xfree(passphrase);
3872
3873       rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk,
3874                          timestamp);
3875       if(rc==0)
3876         {
3877           PKT_signature *newsig;
3878           PACKET *newpkt;
3879
3880           passphrase=get_last_passphrase();
3881           set_next_passphrase(passphrase);
3882           xfree(passphrase);
3883
3884           rc=update_keysig_packet(&newsig,sig_pk->pkt->pkt.signature,main_pk,
3885                                   NULL,sub_pk,main_sk,NULL,NULL);
3886           if(rc==0)
3887             {
3888               /* Put the new sig into place on the pubkey */
3889               newpkt=xmalloc_clear(sizeof(*newpkt));
3890               newpkt->pkttype=PKT_SIGNATURE;
3891               newpkt->pkt.signature=newsig;
3892               free_packet(sig_pk->pkt);
3893               xfree(sig_pk->pkt);
3894               sig_pk->pkt=newpkt;
3895
3896               if(sig_sk)
3897                 {
3898                   /* Put the new sig into place on the seckey */
3899                   newpkt=xmalloc_clear(sizeof(*newpkt));
3900                   newpkt->pkttype=PKT_SIGNATURE;
3901                   newpkt->pkt.signature=copy_signature(NULL,newsig);
3902                   free_packet(sig_sk->pkt);
3903                   xfree(sig_sk->pkt);
3904                   sig_sk->pkt=newpkt;
3905                 }
3906
3907               modified=1;
3908             }
3909           else
3910             {
3911               log_error("update_keysig_packet failed: %s\n",g10_errstr(rc));
3912               break;
3913             }
3914         }
3915       else
3916         {
3917           log_error("make_backsig failed: %s\n",g10_errstr(rc));
3918           break;
3919         }
3920     }
3921
3922   set_next_passphrase(NULL);
3923
3924   free_secret_key(main_sk);
3925   if(sub_sk)
3926     free_secret_key(sub_sk);
3927
3928   return modified;
3929 }
3930
3931
3932 static int
3933 change_primary_uid_cb ( PKT_signature *sig, void *opaque )
3934 {
3935     byte buf[1];
3936
3937     /* first clear all primary uid flags so that we are sure none are
3938      * lingering around */
3939     delete_sig_subpkt (sig->hashed,   SIGSUBPKT_PRIMARY_UID);
3940     delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
3941
3942     /* if opaque is set,we want to set the primary id */
3943     if (opaque) {
3944         buf[0] = 1;
3945         build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1 );
3946     }
3947
3948     return 0;
3949 }
3950
3951
3952 /*
3953  * Set the primary uid flag for the selected UID.  We will also reset
3954  * all other primary uid flags.  For this to work with have to update
3955  * all the signature timestamps.  If we would do this with the current
3956  * time, we lose quite a lot of information, so we use a a kludge to
3957  * do this: Just increment the timestamp by one second which is
3958  * sufficient to updated a signature during import.
3959  */
3960 static int
3961 menu_set_primary_uid ( KBNODE pub_keyblock, KBNODE sec_keyblock )
3962 {
3963     PKT_secret_key *sk;    /* copy of the main sk */
3964     PKT_public_key *main_pk;
3965     PKT_user_id *uid;
3966     KBNODE node;
3967     u32 keyid[2];
3968     int selected;
3969     int attribute = 0;
3970     int modified = 0;
3971
3972     if ( count_selected_uids (pub_keyblock) != 1 ) {
3973         tty_printf(_("Please select exactly one user ID.\n"));
3974         return 0;
3975     }
3976
3977     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
3978     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
3979
3980     /* Now we can actually change the self signature(s) */
3981     main_pk = NULL;
3982     uid = NULL;
3983     selected = 0;
3984
3985     /* Is our selected uid an attribute packet? */
3986     for ( node=pub_keyblock; node; node = node->next )
3987       if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
3988         attribute = (node->pkt->pkt.user_id->attrib_data!=NULL);
3989
3990     for ( node=pub_keyblock; node; node = node->next ) {
3991         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
3992             break; /* ready */
3993
3994         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
3995             main_pk = node->pkt->pkt.public_key;
3996             keyid_from_pk( main_pk, keyid );
3997         }
3998         else if ( node->pkt->pkttype == PKT_USER_ID ) {
3999             uid = node->pkt->pkt.user_id;
4000             selected = node->flag & NODFLG_SELUID;
4001         }
4002         else if ( main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE ) {
4003             PKT_signature *sig = node->pkt->pkt.signature;
4004             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4005                  && (uid && (sig->sig_class&~3) == 0x10)
4006                  && attribute == (uid->attrib_data!=NULL)
4007                  && sig->flags.chosen_selfsig )
4008               {
4009               if(sig->version < 4) {
4010                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4011
4012                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4013                          user);
4014                 xfree(user);
4015               }
4016               else {
4017                 /* This is a selfsignature which is to be replaced.
4018                    We can just ignore v3 signatures because they are
4019                    not able to carry the primary ID flag.  We also
4020                    ignore self-sigs on user IDs that are not of the
4021                    same type that we are making primary.  That is, if
4022                    we are making a user ID primary, we alter user IDs.
4023                    If we are making an attribute packet primary, we
4024                    alter attribute packets. */
4025
4026                 /* FIXME: We must make sure that we only have one
4027                    self-signature per user ID here (not counting
4028                    revocations) */
4029                 PKT_signature *newsig;
4030                 PACKET *newpkt;
4031                 const byte *p;
4032                 int action;
4033
4034                 /* see whether this signature has the primary UID flag */
4035                 p = parse_sig_subpkt (sig->hashed,
4036                                       SIGSUBPKT_PRIMARY_UID, NULL );
4037                 if ( !p )
4038                     p = parse_sig_subpkt (sig->unhashed,
4039                                           SIGSUBPKT_PRIMARY_UID, NULL );
4040                 if ( p && *p ) /* yes */
4041                     action = selected? 0 : -1;
4042                 else /* no */
4043                     action = selected? 1 : 0;
4044
4045                 if (action) {
4046                     int rc = update_keysig_packet (&newsig, sig,
4047                                                main_pk, uid, NULL,
4048                                                sk,
4049                                                change_primary_uid_cb,
4050                                                action > 0? "x":NULL );
4051                     if( rc ) {
4052                         log_error ("update_keysig_packet failed: %s\n",
4053                                    g10_errstr(rc));
4054                         free_secret_key( sk );
4055                         return 0;
4056                     }
4057                     /* replace the packet */
4058                     newpkt = xmalloc_clear( sizeof *newpkt );
4059                     newpkt->pkttype = PKT_SIGNATURE;
4060                     newpkt->pkt.signature = newsig;
4061                     free_packet( node->pkt );
4062                     xfree( node->pkt );
4063                     node->pkt = newpkt;
4064                     modified = 1;
4065                 }
4066               }
4067             }
4068         }
4069     }
4070
4071     free_secret_key( sk );
4072     return modified;
4073 }
4074
4075
4076 /*
4077  * Set preferences to new values for the selected user IDs
4078  */
4079 static int
4080 menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock )
4081 {
4082     PKT_secret_key *sk;    /* copy of the main sk */
4083     PKT_public_key *main_pk;
4084     PKT_user_id *uid;
4085     KBNODE node;
4086     u32 keyid[2];
4087     int selected, select_all;
4088     int modified = 0;
4089
4090     no_primary_warning(pub_keyblock);
4091
4092     select_all = !count_selected_uids (pub_keyblock);
4093
4094     node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4095     sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4096
4097     /* Now we can actually change the self signature(s) */
4098     main_pk = NULL;
4099     uid = NULL;
4100     selected = 0;
4101     for ( node=pub_keyblock; node; node = node->next ) {
4102         if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4103             break; /* ready */
4104
4105         if ( node->pkt->pkttype == PKT_PUBLIC_KEY ) {
4106             main_pk = node->pkt->pkt.public_key;
4107             keyid_from_pk( main_pk, keyid );
4108         }
4109         else if ( node->pkt->pkttype == PKT_USER_ID ) {
4110             uid = node->pkt->pkt.user_id;
4111             selected = select_all || (node->flag & NODFLG_SELUID);
4112         }
4113         else if ( main_pk && uid && selected
4114                   && node->pkt->pkttype == PKT_SIGNATURE ) {
4115             PKT_signature *sig = node->pkt->pkt.signature;
4116             if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4117                  && (uid && (sig->sig_class&~3) == 0x10)
4118                  && sig->flags.chosen_selfsig ) {
4119               if( sig->version < 4 ) {
4120                 char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4121
4122                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4123                          user);
4124                 xfree(user);
4125               }
4126               else {
4127                 /* This is a selfsignature which is to be replaced
4128                  * We have to ignore v3 signatures because they are
4129                  * not able to carry the preferences */
4130                 PKT_signature *newsig;
4131                 PACKET *newpkt;
4132                 int rc;
4133
4134                 rc = update_keysig_packet (&newsig, sig,
4135                                            main_pk, uid, NULL,
4136                                            sk,
4137                                            keygen_upd_std_prefs,
4138                                            NULL );
4139                 if( rc ) {
4140                     log_error ("update_keysig_packet failed: %s\n",
4141                                g10_errstr(rc));
4142                     free_secret_key( sk );
4143                     return 0;
4144                 }
4145                 /* replace the packet */
4146                 newpkt = xmalloc_clear( sizeof *newpkt );
4147                 newpkt->pkttype = PKT_SIGNATURE;
4148                 newpkt->pkt.signature = newsig;
4149                 free_packet( node->pkt );
4150                 xfree( node->pkt );
4151                 node->pkt = newpkt;
4152                 modified = 1;
4153               }
4154             }
4155         }
4156     }
4157
4158     free_secret_key( sk );
4159     return modified;
4160 }
4161
4162
4163 static int
4164 menu_set_keyserver_url (const char *url,
4165                         KBNODE pub_keyblock, KBNODE sec_keyblock )
4166 {
4167   PKT_secret_key *sk;    /* copy of the main sk */
4168   PKT_public_key *main_pk;
4169   PKT_user_id *uid;
4170   KBNODE node;
4171   u32 keyid[2];
4172   int selected, select_all;
4173   int modified = 0;
4174   char *answer,*uri;
4175
4176   no_primary_warning(pub_keyblock);
4177
4178   if(url)
4179     answer=xstrdup(url);
4180   else
4181     {
4182       answer=cpr_get_utf8("keyedit.add_keyserver",
4183                           _("Enter your preferred keyserver URL: "));
4184       if(answer[0]=='\0' || answer[0]=='\004')
4185         {
4186           xfree(answer);
4187           return 0;
4188         }
4189     }
4190
4191   if(ascii_strcasecmp(answer,"none")==0)
4192     uri=NULL;
4193   else
4194     {
4195       struct keyserver_spec *keyserver=NULL;
4196       /* Sanity check the format */
4197       keyserver=parse_keyserver_uri(answer,1,NULL,0);
4198       xfree(answer);
4199       if(!keyserver)
4200         {
4201           log_info(_("could not parse keyserver URL\n"));
4202           return 0;
4203         }
4204       uri=xstrdup(keyserver->uri);
4205       free_keyserver_spec(keyserver);
4206     }
4207
4208   select_all = !count_selected_uids (pub_keyblock);
4209
4210   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4211   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4212
4213   /* Now we can actually change the self signature(s) */
4214   main_pk = NULL;
4215   uid = NULL;
4216   selected = 0;
4217   for ( node=pub_keyblock; node; node = node->next )
4218     {
4219       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4220         break; /* ready */
4221
4222       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4223         {
4224           main_pk = node->pkt->pkt.public_key;
4225           keyid_from_pk( main_pk, keyid );
4226         }
4227       else if ( node->pkt->pkttype == PKT_USER_ID )
4228         {
4229           uid = node->pkt->pkt.user_id;
4230           selected = select_all || (node->flag & NODFLG_SELUID);
4231         }
4232       else if ( main_pk && uid && selected
4233                 && node->pkt->pkttype == PKT_SIGNATURE )
4234         {
4235           PKT_signature *sig = node->pkt->pkt.signature;
4236           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4237                && (uid && (sig->sig_class&~3) == 0x10)
4238                && sig->flags.chosen_selfsig)
4239             {
4240               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4241               if( sig->version < 4 )
4242                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4243                          user);
4244               else
4245                 {
4246                   /* This is a selfsignature which is to be replaced
4247                    * We have to ignore v3 signatures because they are
4248                    * not able to carry the subpacket. */
4249                   PKT_signature *newsig;
4250                   PACKET *newpkt;
4251                   int rc;
4252                   const byte *p;
4253                   size_t plen;
4254
4255                   p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&plen);
4256                   if(p && plen)
4257                     {
4258                       tty_printf("Current preferred keyserver for user"
4259                                  " ID \"%s\": ",user);
4260                       tty_print_utf8_string(p,plen);
4261                       tty_printf("\n");
4262                       if(!cpr_get_answer_is_yes("keyedit.confirm_keyserver",
4263                          uri?_("Are you sure you want to replace it? (y/N) "):
4264                              _("Are you sure you want to delete it? (y/N) ")))
4265                         continue;
4266                     }
4267                   else if(uri==NULL)
4268                     {
4269                       /* There is no current keyserver URL, so there
4270                          is no point in trying to un-set it. */
4271                       continue;
4272                     }
4273
4274                   rc = update_keysig_packet (&newsig, sig,
4275                                              main_pk, uid, NULL,
4276                                              sk,
4277                                              keygen_add_keyserver_url, uri );
4278                   if( rc )
4279                     {
4280                       log_error ("update_keysig_packet failed: %s\n",
4281                                  g10_errstr(rc));
4282                       free_secret_key( sk );
4283                       xfree(uri);
4284                       return 0;
4285                     }
4286                   /* replace the packet */
4287                   newpkt = xmalloc_clear( sizeof *newpkt );
4288                   newpkt->pkttype = PKT_SIGNATURE;
4289                   newpkt->pkt.signature = newsig;
4290                   free_packet( node->pkt );
4291                   xfree( node->pkt );
4292                   node->pkt = newpkt;
4293                   modified = 1;
4294                 }
4295
4296               xfree(user);
4297             }
4298         }
4299     }
4300
4301   xfree(uri);
4302   free_secret_key( sk );
4303   return modified;
4304 }
4305
4306 static int
4307 menu_set_notation(const char *string,KBNODE pub_keyblock,KBNODE sec_keyblock)
4308 {
4309   PKT_secret_key *sk;    /* copy of the main sk */
4310   PKT_public_key *main_pk;
4311   PKT_user_id *uid;
4312   KBNODE node;
4313   u32 keyid[2];
4314   int selected, select_all;
4315   int modified = 0;
4316   char *answer;
4317   struct notation *notation;
4318
4319   no_primary_warning(pub_keyblock);
4320
4321   if(string)
4322     answer=xstrdup(string);
4323   else
4324     {
4325       answer=cpr_get_utf8("keyedit.add_notation",
4326                           _("Enter the notation: "));
4327       if(answer[0]=='\0' || answer[0]=='\004')
4328         {
4329           xfree(answer);
4330           return 0;
4331         }
4332     }
4333
4334   if(ascii_strcasecmp(answer,"none")==0
4335      || ascii_strcasecmp(answer,"-")==0)
4336     notation=NULL; /* delete them all */
4337   else
4338     {
4339       notation=string_to_notation(answer,0);
4340       if(!notation)
4341         {
4342           xfree(answer);
4343           return 0;
4344         }
4345     }
4346
4347   xfree(answer);
4348
4349   select_all = !count_selected_uids (pub_keyblock);
4350
4351   node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
4352   sk = copy_secret_key( NULL, node->pkt->pkt.secret_key);
4353
4354   /* Now we can actually change the self signature(s) */
4355   main_pk = NULL;
4356   uid = NULL;
4357   selected = 0;
4358   for ( node=pub_keyblock; node; node = node->next )
4359     {
4360       if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
4361         break; /* ready */
4362
4363       if ( node->pkt->pkttype == PKT_PUBLIC_KEY )
4364         {
4365           main_pk = node->pkt->pkt.public_key;
4366           keyid_from_pk( main_pk, keyid );
4367         }
4368       else if ( node->pkt->pkttype == PKT_USER_ID )
4369         {
4370           uid = node->pkt->pkt.user_id;
4371           selected = select_all || (node->flag & NODFLG_SELUID);
4372         }
4373       else if ( main_pk && uid && selected
4374                 && node->pkt->pkttype == PKT_SIGNATURE )
4375         {
4376           PKT_signature *sig = node->pkt->pkt.signature;
4377           if ( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
4378                && (uid && (sig->sig_class&~3) == 0x10)
4379                && sig->flags.chosen_selfsig)
4380             {
4381               char *user=utf8_to_native(uid->name,strlen(uid->name),0);
4382               if( sig->version < 4 )
4383                 log_info(_("skipping v3 self-signature on user ID \"%s\"\n"),
4384                          user);
4385               else
4386                 {
4387                   PKT_signature *newsig;
4388                   PACKET *newpkt;
4389                   int rc,skip=0,addonly=1;
4390
4391                   if(sig->flags.notation)
4392                     {
4393                       tty_printf("Current notations for user ID \"%s\":\n",
4394                                  user);
4395                       tty_print_notations(-9,sig);
4396                     }
4397                   else
4398                     {
4399                       tty_printf("No notations on user ID \"%s\"\n",user);
4400                       if(notation==NULL)
4401                         {
4402                           /* There are no current notations, so there
4403                              is no point in trying to un-set them. */
4404                           continue;
4405                         }
4406                     }
4407
4408                   if(notation)
4409                     {
4410                       struct notation *n;
4411                       int deleting=0;
4412
4413                       notation->next=sig_to_notation(sig);
4414
4415                       for(n=notation->next;n;n=n->next)
4416                         if(strcmp(n->name,notation->name)==0)
4417                           {
4418                             if(notation->value)
4419                               {
4420                                 if(strcmp(n->value,notation->value)==0)
4421                                   {
4422                                     if(notation->flags.ignore)
4423                                       {
4424                                         /* Value match with a delete
4425                                            flag. */
4426                                         n->flags.ignore=1;
4427                                         deleting=1;
4428                                       }
4429                                     else
4430                                       {
4431                                         /* Adding the same notation
4432                                            twice, so don't add it at
4433                                            all. */
4434                                         skip=1;
4435                                         tty_printf("Skipping notation:"
4436                                                    " %s=%s\n",
4437                                                    notation->name,
4438                                                    notation->value);
4439                                         break;
4440                                       }
4441                                   }
4442                               }
4443                             else
4444                               {
4445                                 /* No value, so it means delete. */
4446                                 n->flags.ignore=1;
4447                                 deleting=1;
4448                               }
4449
4450                             if(n->flags.ignore)
4451                               {
4452                                 tty_printf("Removing notation: %s=%s\n",
4453                                            n->name,n->value);
4454                                 addonly=0;
4455                               }
4456                           }
4457
4458                       if(!notation->flags.ignore && !skip)
4459                         tty_printf("Adding notation: %s=%s\n",
4460                                    notation->name,notation->value);
4461
4462                       /* We tried to delete, but had no matches */
4463                       if(notation->flags.ignore && !deleting)
4464                         continue;
4465                     }
4466                   else
4467                     {
4468                       tty_printf("Removing all notations\n");
4469                       addonly=0;
4470                     }
4471
4472                   if(skip
4473                      || (!addonly
4474                          && !cpr_get_answer_is_yes("keyedit.confirm_notation",
4475                                                    _("Proceed? (y/N) "))))
4476                     continue;
4477
4478                   rc = update_keysig_packet (&newsig, sig,
4479                                              main_pk, uid, NULL,
4480                                              sk,
4481                                              keygen_add_notations, notation );
4482                   if( rc )
4483                     {
4484                       log_error ("update_keysig_packet failed: %s\n",
4485                                  g10_errstr(rc));
4486                       free_secret_key( sk );
4487                       free_notation(notation);
4488                       xfree(user);
4489                       return 0;
4490                     }
4491
4492                   /* replace the packet */
4493                   newpkt = xmalloc_clear( sizeof *newpkt );
4494                   newpkt->pkttype = PKT_SIGNATURE;
4495                   newpkt->pkt.signature = newsig;
4496                   free_packet( node->pkt );
4497                   xfree( node->pkt );
4498                   node->pkt = newpkt;
4499                   modified = 1;
4500
4501                   if(notation)
4502                     {
4503                       /* Snip off the notation list from the sig */
4504                       free_notation(notation->next);
4505                       notation->next=NULL;
4506                     }
4507
4508                   xfree(user);
4509                 }
4510             }
4511         }
4512     }
4513
4514   free_notation(notation);
4515   free_secret_key( sk );
4516   return modified;
4517 }
4518
4519
4520 /*
4521  * Select one user id or remove all selection if IDX is 0 or select
4522  * all if IDX is -1.  Returns: True if the selection changed.
4523  */
4524 static int
4525 menu_select_uid (KBNODE keyblock, int idx)
4526 {
4527   KBNODE node;
4528   int i;
4529
4530   if (idx == -1) /* Select all. */
4531     {
4532       for (node = keyblock; node; node = node->next)
4533         if (node->pkt->pkttype == PKT_USER_ID)
4534           node->flag |= NODFLG_SELUID;
4535       return 1;
4536     }
4537   else if (idx) /* Toggle.  */
4538     {
4539       for (i=0, node = keyblock; node; node = node->next)
4540         {
4541           if (node->pkt->pkttype == PKT_USER_ID)
4542             if (++i == idx)
4543               break;
4544         }
4545       if (!node)
4546         {
4547           tty_printf (_("No user ID with index %d\n"), idx );
4548           return 0;
4549         }
4550
4551       for (i=0, node = keyblock; node; node = node->next)
4552         {
4553           if (node->pkt->pkttype == PKT_USER_ID)
4554             {
4555               if (++i == idx)
4556                 {
4557                   if ((node->flag & NODFLG_SELUID))
4558                     node->flag &= ~NODFLG_SELUID;
4559                   else
4560                     node->flag |= NODFLG_SELUID;
4561                 }
4562             }
4563         }
4564     }
4565   else /* Unselect all */
4566     {
4567       for (node = keyblock; node; node = node->next)
4568         if (node->pkt->pkttype == PKT_USER_ID)
4569           node->flag &= ~NODFLG_SELUID;
4570     }
4571
4572   return 1;
4573 }
4574
4575
4576 /* Search in the keyblock for a uid that matches namehash */
4577 static int
4578 menu_select_uid_namehash( KBNODE keyblock, const char *namehash )
4579 {
4580   byte hash[NAMEHASH_LEN];
4581   KBNODE node;
4582   int i;
4583
4584   assert(strlen(namehash)==NAMEHASH_LEN*2);
4585
4586   for(i=0;i<NAMEHASH_LEN;i++)
4587     hash[i]=hextobyte(&namehash[i*2]);
4588
4589   for(node=keyblock->next;node;node=node->next)
4590     {
4591       if(node->pkt->pkttype==PKT_USER_ID)
4592         {
4593           namehash_from_uid(node->pkt->pkt.user_id);
4594           if(memcmp(node->pkt->pkt.user_id->namehash,hash,NAMEHASH_LEN)==0)
4595             {
4596               if(node->flag&NODFLG_SELUID)
4597                 node->flag &= ~NODFLG_SELUID;
4598               else
4599                 node->flag |= NODFLG_SELUID;
4600
4601               break;
4602             }
4603         }
4604     }
4605
4606     if(!node)
4607       {
4608         tty_printf(_("No user ID with hash %s\n"),namehash);
4609         return 0;
4610       }
4611
4612   return 1;
4613 }
4614
4615 /****************
4616  * Select secondary keys
4617  * Returns: True if the selection changed.
4618  */
4619 static int
4620 menu_select_key (KBNODE keyblock, int idx)
4621 {
4622   KBNODE node;
4623   int i;
4624
4625   if (idx == -1) /* Select all.  */
4626     {
4627       for (node = keyblock; node; node = node->next)
4628         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4629             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4630           node->flag |= NODFLG_SELKEY;
4631     }
4632   else if (idx) /* Toggle selection.  */
4633     {
4634       for (i=0, node = keyblock; node; node = node->next)
4635         {
4636           if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4637               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4638             if (++i == idx)
4639               break;
4640         }
4641       if (!node)
4642         {
4643           tty_printf (_("No subkey with index %d\n"), idx );
4644           return 0;
4645         }
4646
4647       for (i=0, node = keyblock; node; node = node->next)
4648         {
4649           if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4650               || node->pkt->pkttype == PKT_SECRET_SUBKEY )
4651             if (++i == idx)
4652               {
4653                 if ((node->flag & NODFLG_SELKEY))
4654                   node->flag &= ~NODFLG_SELKEY;
4655                 else
4656                   node->flag |= NODFLG_SELKEY;
4657               }
4658         }
4659     }
4660   else /* Unselect all. */
4661     {
4662       for (node = keyblock; node; node = node->next)
4663         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4664             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4665           node->flag &= ~NODFLG_SELKEY;
4666     }
4667
4668   return 1;
4669 }
4670
4671
4672 static int
4673 count_uids_with_flag( KBNODE keyblock, unsigned flag )
4674 {
4675     KBNODE node;
4676     int i=0;
4677
4678     for( node = keyblock; node; node = node->next )
4679         if( node->pkt->pkttype == PKT_USER_ID && (node->flag & flag) )
4680             i++;
4681     return i;
4682 }
4683
4684 static int
4685 count_keys_with_flag( KBNODE keyblock, unsigned flag )
4686 {
4687     KBNODE node;
4688     int i=0;
4689
4690     for( node = keyblock; node; node = node->next )
4691         if( ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
4692               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
4693             && (node->flag & flag) )
4694             i++;
4695     return i;
4696 }
4697
4698 static int
4699 count_uids( KBNODE keyblock )
4700 {
4701     KBNODE node;
4702     int i=0;
4703
4704     for( node = keyblock; node; node = node->next )
4705         if( node->pkt->pkttype == PKT_USER_ID )
4706             i++;
4707     return i;
4708 }
4709
4710
4711 /****************
4712  * Returns true if there is at least one selected user id
4713  */
4714 static int
4715 count_selected_uids( KBNODE keyblock )
4716 {
4717     return count_uids_with_flag( keyblock, NODFLG_SELUID);
4718 }
4719
4720 static int
4721 count_selected_keys( KBNODE keyblock )
4722 {
4723     return count_keys_with_flag( keyblock, NODFLG_SELKEY);
4724 }
4725
4726 /* returns how many real (i.e. not attribute) uids are unmarked */
4727 static int
4728 real_uids_left( KBNODE keyblock )
4729 {
4730   KBNODE node;
4731   int real=0;
4732
4733   for(node=keyblock;node;node=node->next)
4734     if(node->pkt->pkttype==PKT_USER_ID && !(node->flag&NODFLG_SELUID) &&
4735        !node->pkt->pkt.user_id->attrib_data)
4736       real++;
4737
4738   return real;
4739 }
4740
4741 /*
4742  * Ask whether the signature should be revoked.  If the user commits this,
4743  * flag bit MARK_A is set on the signature and the user ID.
4744  */
4745 static void
4746 ask_revoke_sig( KBNODE keyblock, KBNODE node )
4747 {
4748     int doit=0;
4749     PKT_user_id *uid;
4750     PKT_signature *sig = node->pkt->pkt.signature;
4751     KBNODE unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4752
4753     if( !unode ) {
4754         log_error("Oops: no user ID for signature\n");
4755         return;
4756     }
4757
4758     uid=unode->pkt->pkt.user_id;
4759
4760     if(opt.with_colons)
4761       {
4762         if(uid->attrib_data)
4763           printf("uat:::::::::%u %lu",uid->numattribs,uid->attrib_len);
4764         else
4765           {
4766             printf("uid:::::::::");
4767             print_string (stdout, uid->name, uid->len, ':');
4768           }
4769
4770         printf("\n");
4771
4772         print_and_check_one_sig_colon(keyblock,node,NULL,NULL,NULL,NULL,1);
4773       }
4774     else
4775       {
4776         char *p=utf8_to_native(unode->pkt->pkt.user_id->name,
4777                          unode->pkt->pkt.user_id->len,0);
4778         tty_printf(_("user ID: \"%s\"\n"),p);
4779         xfree(p);
4780
4781         tty_printf(_("signed by your key %s on %s%s%s\n"),
4782                    keystr(sig->keyid),datestr_from_sig(sig),
4783                    sig->flags.exportable?"":_(" (non-exportable)"),"");
4784       }
4785     if(sig->flags.expired)
4786       {
4787         tty_printf(_("This signature expired on %s.\n"),
4788                    expirestr_from_sig(sig));
4789         /* Use a different question so we can have different help text */
4790         doit=cpr_get_answer_is_yes("ask_revoke_sig.expired",
4791                         _("Are you sure you still want to revoke it? (y/N) "));
4792       }
4793     else
4794       doit=cpr_get_answer_is_yes("ask_revoke_sig.one",
4795               _("Create a revocation certificate for this signature? (y/N) "));
4796
4797     if(doit) {
4798       node->flag |= NODFLG_MARK_A;
4799       unode->flag |= NODFLG_MARK_A;
4800     }
4801 }
4802
4803 /****************
4804  * Display all user ids of the current public key together with signatures
4805  * done by one of our keys.  Then walk over all this sigs and ask the user
4806  * whether he wants to revoke this signature.
4807  * Return: True when the keyblock has changed.
4808  */
4809 static int
4810 menu_revsig( KBNODE keyblock )
4811 {
4812     PKT_signature *sig;
4813     PKT_public_key *primary_pk;
4814     KBNODE node;
4815     int changed = 0;
4816     int rc, any, skip=1, all=!count_selected_uids(keyblock);
4817     struct revocation_reason_info *reason = NULL;
4818
4819     assert(keyblock->pkt->pkttype==PKT_PUBLIC_KEY);
4820
4821     /* First check whether we have any signatures at all.  */
4822     any = 0;
4823     for (node = keyblock; node; node = node->next )
4824       {
4825         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
4826         if (node->pkt->pkttype == PKT_USER_ID) {
4827           if (node->flag&NODFLG_SELUID || all)
4828             skip = 0;
4829           else
4830             skip = 1;
4831         }
4832         else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
4833                  && ((sig = node->pkt->pkt.signature),
4834                      !seckey_available(sig->keyid)     ))
4835           {
4836             if ((sig->sig_class&~3) == 0x10)
4837               {
4838                 any = 1;
4839                 break;
4840               }
4841           }
4842       }
4843
4844     if (!any)
4845       {
4846         tty_printf (_("Not signed by you.\n"));
4847         return 0;
4848       }
4849
4850
4851     /* FIXME: detect duplicates here  */
4852     tty_printf(_("You have signed these user IDs on key %s:\n"),
4853                keystr_from_pk(keyblock->pkt->pkt.public_key));
4854     for( node = keyblock; node; node = node->next ) {
4855         node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
4856         if( node->pkt->pkttype == PKT_USER_ID ) {
4857             if( node->flag&NODFLG_SELUID || all ) {
4858               PKT_user_id *uid = node->pkt->pkt.user_id;
4859               /* Hmmm: Should we show only UIDs with a signature? */
4860               tty_printf("     ");
4861               tty_print_utf8_string( uid->name, uid->len );
4862               tty_printf("\n");
4863               skip=0;
4864             }
4865             else
4866               skip=1;
4867         }
4868         else if( !skip && node->pkt->pkttype == PKT_SIGNATURE
4869                 && ((sig = node->pkt->pkt.signature),
4870                      !seckey_available(sig->keyid)  ) )
4871           {
4872             if( (sig->sig_class&~3) == 0x10 )
4873               {
4874                 tty_printf("   ");
4875                 tty_printf(_("signed by your key %s on %s%s%s\n"),
4876                            keystr(sig->keyid), datestr_from_sig(sig),
4877                            sig->flags.exportable?"":_(" (non-exportable)"),
4878                            sig->flags.revocable?"":_(" (non-revocable)"));
4879                 if(sig->flags.revocable)
4880                   node->flag |= NODFLG_SELSIG;
4881               }
4882             else if( sig->sig_class == 0x30 )
4883               {
4884                 tty_printf("   ");
4885                 tty_printf(_("revoked by your key %s on %s\n"),
4886                            keystr(sig->keyid),datestr_from_sig(sig));
4887               }
4888           }
4889     }
4890
4891     tty_printf("\n");
4892
4893     /* ask */
4894     for( node = keyblock; node; node = node->next ) {
4895         if( !(node->flag & NODFLG_SELSIG) )
4896             continue;
4897         ask_revoke_sig( keyblock, node );
4898     }
4899
4900     /* present selected */
4901     any = 0;
4902     for( node = keyblock; node; node = node->next ) {
4903         if( !(node->flag & NODFLG_MARK_A) )
4904             continue;
4905         if( !any ) {
4906             any = 1;
4907             tty_printf(_("You are about to revoke these signatures:\n"));
4908         }
4909         if( node->pkt->pkttype == PKT_USER_ID ) {
4910             PKT_user_id *uid = node->pkt->pkt.user_id;
4911             tty_printf("     ");
4912             tty_print_utf8_string( uid->name, uid->len );
4913             tty_printf("\n");
4914         }
4915         else if( node->pkt->pkttype == PKT_SIGNATURE ) {
4916             sig = node->pkt->pkt.signature;
4917             tty_printf("   ");
4918             tty_printf(_("signed by your key %s on %s%s%s\n"),
4919                        keystr(sig->keyid), datestr_from_sig(sig),"",
4920                        sig->flags.exportable?"":_(" (non-exportable)") );
4921         }
4922     }
4923     if( !any )
4924         return 0; /* none selected */
4925
4926     if( !cpr_get_answer_is_yes("ask_revoke_sig.okay",
4927          _("Really create the revocation certificates? (y/N) ")) )
4928         return 0; /* forget it */
4929
4930     reason = ask_revocation_reason( 0, 1, 0 );
4931     if( !reason ) { /* user decided to cancel */
4932         return 0;
4933     }
4934
4935     /* now we can sign the user ids */
4936   reloop: /* (must use this, because we are modifing the list) */
4937     primary_pk = keyblock->pkt->pkt.public_key;
4938     for( node=keyblock; node; node = node->next ) {
4939         KBNODE unode;
4940         PACKET *pkt;
4941         struct sign_attrib attrib;
4942         PKT_secret_key *sk;
4943
4944         if( !(node->flag & NODFLG_MARK_A)
4945             || node->pkt->pkttype != PKT_SIGNATURE )
4946             continue;
4947         unode = find_prev_kbnode( keyblock, node, PKT_USER_ID );
4948         assert( unode ); /* we already checked this */
4949
4950         memset( &attrib, 0, sizeof attrib );
4951         attrib.reason = reason;
4952         attrib.non_exportable=!node->pkt->pkt.signature->flags.exportable;
4953
4954         node->flag &= ~NODFLG_MARK_A;
4955         sk = xmalloc_secure_clear( sizeof *sk );
4956         if( get_seckey( sk, node->pkt->pkt.signature->keyid ) ) {
4957             log_info(_("no secret key\n"));
4958             continue;
4959         }
4960         rc = make_keysig_packet( &sig, primary_pk,
4961                                        unode->pkt->pkt.user_id,
4962                                        NULL,
4963                                        sk,
4964                                        0x30, 0, 0, 0, 0,
4965                                        sign_mk_attrib,
4966                                        &attrib );
4967         free_secret_key(sk);
4968         if( rc ) {
4969             log_error(_("signing failed: %s\n"), g10_errstr(rc));
4970             release_revocation_reason_info( reason );
4971             return changed;
4972         }
4973         changed = 1; /* we changed the keyblock */
4974         update_trust = 1;
4975         /* Are we revoking our own uid? */
4976         if(primary_pk->keyid[0]==sig->keyid[0] &&
4977            primary_pk->keyid[1]==sig->keyid[1])
4978           unode->pkt->pkt.user_id->is_revoked=1;
4979         pkt = xmalloc_clear( sizeof *pkt );
4980         pkt->pkttype = PKT_SIGNATURE;
4981         pkt->pkt.signature = sig;
4982         insert_kbnode( unode, new_kbnode(pkt), 0 );
4983         goto reloop;
4984     }
4985
4986     release_revocation_reason_info( reason );
4987     return changed;
4988 }
4989
4990 /* Revoke a user ID (i.e. revoke a user ID selfsig).  Return true if
4991    keyblock changed. */
4992 static int
4993 menu_revuid( KBNODE pub_keyblock, KBNODE sec_keyblock )
4994 {
4995   PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
4996   PKT_secret_key *sk = copy_secret_key( NULL,
4997                                         sec_keyblock->pkt->pkt.secret_key );
4998   KBNODE node;
4999   int changed = 0;
5000   int rc;
5001   struct revocation_reason_info *reason = NULL;
5002
5003   /* Note that this is correct as per the RFCs, but nevertheless
5004      somewhat meaningless in the real world.  1991 did define the 0x30
5005      sig class, but PGP 2.x did not actually implement it, so it would
5006      probably be safe to use v4 revocations everywhere. -ds */
5007
5008   for( node = pub_keyblock; node; node = node->next )
5009     if(pk->version>3 || (node->pkt->pkttype==PKT_USER_ID &&
5010                          node->pkt->pkt.user_id->selfsigversion>3))
5011       {
5012         if((reason = ask_revocation_reason( 0, 1, 4 )))
5013           break;
5014         else
5015           goto leave;
5016       }
5017
5018  reloop: /* (better this way because we are modifing the keyring) */
5019   for( node = pub_keyblock; node; node = node->next )
5020     if(node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
5021       {
5022         PKT_user_id *uid=node->pkt->pkt.user_id;
5023
5024         if(uid->is_revoked)
5025           {
5026             char *user=utf8_to_native(uid->name,uid->len,0);
5027             log_info(_("user ID \"%s\" is already revoked\n"),user);
5028             xfree(user);
5029           }
5030         else
5031           {
5032             PACKET *pkt;
5033             PKT_signature *sig;
5034             struct sign_attrib attrib;
5035             u32 timestamp=make_timestamp();
5036
5037             if(uid->created>=timestamp)
5038               {
5039                 /* Okay, this is a problem.  The user ID selfsig was
5040                    created in the future, so we need to warn the user and
5041                    set our revocation timestamp one second after that so
5042                    everything comes out clean. */
5043
5044                 log_info(_("WARNING: a user ID signature is dated %d"
5045                            " seconds in the future\n"),uid->created-timestamp);
5046
5047                 timestamp=uid->created+1;
5048               }
5049
5050             memset( &attrib, 0, sizeof attrib );
5051             attrib.reason = reason;
5052
5053             node->flag &= ~NODFLG_SELUID;
5054
5055             rc = make_keysig_packet( &sig, pk, uid, NULL, sk, 0x30, 0,
5056                                      (reason==NULL)?3:0, timestamp, 0,
5057                                      sign_mk_attrib, &attrib );
5058             if( rc )
5059               {
5060                 log_error(_("signing failed: %s\n"), g10_errstr(rc));
5061                 goto leave;
5062               }
5063             else
5064               {
5065                 pkt = xmalloc_clear( sizeof *pkt );
5066                 pkt->pkttype = PKT_SIGNATURE;
5067                 pkt->pkt.signature = sig;
5068                 insert_kbnode( node, new_kbnode(pkt), 0 );
5069
5070                 /* If the trustdb has an entry for this key+uid then the
5071                    trustdb needs an update. */
5072                 if(!update_trust
5073                    && (get_validity(pk,uid)&TRUST_MASK)>=TRUST_UNDEFINED)
5074                   update_trust=1;
5075
5076                 changed = 1;
5077                 node->pkt->pkt.user_id->is_revoked=1;
5078
5079                 goto reloop;
5080               }
5081           }
5082       }
5083
5084   if(changed)
5085     commit_kbnode( &pub_keyblock );
5086
5087  leave:
5088   free_secret_key(sk);
5089   release_revocation_reason_info( reason );
5090   return changed;
5091 }
5092
5093 /****************
5094  * Revoke the whole key.
5095  */
5096 static int
5097 menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
5098 {
5099   PKT_public_key *pk=pub_keyblock->pkt->pkt.public_key;
5100   PKT_secret_key *sk;
5101   int rc,changed = 0;
5102   struct revocation_reason_info *reason;
5103   PACKET *pkt;
5104   PKT_signature *sig;
5105
5106   if(pk->is_revoked)
5107     {
5108       tty_printf(_("Key %s is already revoked.\n"),keystr_from_pk(pk));
5109       return 0;
5110     }
5111
5112   reason = ask_revocation_reason( 1, 0, 0 );
5113   /* user decided to cancel */
5114   if( !reason )
5115     return 0;
5116
5117   sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
5118   rc = make_keysig_packet( &sig, pk, NULL, NULL, sk,
5119                            0x20, 0, opt.force_v4_certs?4:0, 0, 0,
5120                            revocation_reason_build_cb, reason );
5121   free_secret_key(sk);
5122   if( rc )
5123     {
5124       log_error(_("signing failed: %s\n"), g10_errstr(rc));
5125       goto scram;
5126     }
5127
5128   changed = 1; /* we changed the keyblock */
5129
5130   pkt = xmalloc_clear( sizeof *pkt );
5131   pkt->pkttype = PKT_SIGNATURE;
5132   pkt->pkt.signature = sig;
5133   insert_kbnode( pub_keyblock, new_kbnode(pkt), 0 );
5134   commit_kbnode( &pub_keyblock );
5135
5136   update_trust=1;
5137
5138  scram:
5139   release_revocation_reason_info( reason );
5140   return changed;
5141 }
5142
5143 static int
5144 menu_revsubkey( KBNODE pub_keyblock, KBNODE sec_keyblock )
5145 {
5146     PKT_public_key *mainpk;
5147     KBNODE node;
5148     int changed = 0;
5149     int rc;
5150     struct revocation_reason_info *reason = NULL;
5151
5152     reason = ask_revocation_reason( 1, 0, 0 );
5153     if( !reason ) { /* user decided to cancel */
5154         return 0;
5155     }
5156
5157   reloop: /* (better this way because we are modifing the keyring) */
5158     mainpk = pub_keyblock->pkt->pkt.public_key;
5159     for( node = pub_keyblock; node; node = node->next ) {
5160         if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
5161             && (node->flag & NODFLG_SELKEY) ) {
5162             PACKET *pkt;
5163             PKT_signature *sig;
5164             PKT_secret_key *sk;
5165             PKT_public_key *subpk = node->pkt->pkt.public_key;
5166             struct sign_attrib attrib;
5167
5168             if(subpk->is_revoked)
5169               {
5170                 tty_printf(_("Subkey %s is already revoked.\n"),
5171                            keystr_from_pk(subpk));
5172                 continue;
5173               }
5174
5175             memset( &attrib, 0, sizeof attrib );
5176             attrib.reason = reason;
5177
5178             node->flag &= ~NODFLG_SELKEY;
5179             sk = copy_secret_key( NULL, sec_keyblock->pkt->pkt.secret_key );
5180             rc = make_keysig_packet( &sig, mainpk, NULL, subpk, sk,
5181                                      0x28, 0, 0, 0, 0,
5182                                      sign_mk_attrib, &attrib );
5183             free_secret_key(sk);
5184             if( rc ) {
5185                 log_error(_("signing failed: %s\n"), g10_errstr(rc));
5186                 release_revocation_reason_info( reason );
5187                 return changed;
5188             }
5189             changed = 1; /* we changed the keyblock */
5190
5191             pkt = xmalloc_clear( sizeof *pkt );
5192             pkt->pkttype = PKT_SIGNATURE;
5193             pkt->pkt.signature = sig;
5194             insert_kbnode( node, new_kbnode(pkt), 0 );
5195             goto reloop;
5196         }
5197     }
5198     commit_kbnode( &pub_keyblock );
5199     /*commit_kbnode( &sec_keyblock );*/
5200
5201     /* No need to set update_trust here since signing keys no longer
5202        are used to certify other keys, so there is no change in trust
5203        when revoking/removing them */
5204
5205     release_revocation_reason_info( reason );
5206     return changed;
5207 }
5208
5209 /* Note that update_ownertrust is going to mark the trustdb dirty when
5210    enabling or disabling a key.  This is arguably sub-optimal as
5211    disabled keys are still counted in the web of trust, but perhaps
5212    not worth adding extra complexity to change. -ds */
5213 static int
5214 enable_disable_key( KBNODE keyblock, int disable )
5215 {
5216     PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY )
5217                             ->pkt->pkt.public_key;
5218     unsigned int trust, newtrust;
5219
5220     trust = newtrust = get_ownertrust (pk);
5221     newtrust &= ~TRUST_FLAG_DISABLED;
5222     if( disable )
5223         newtrust |= TRUST_FLAG_DISABLED;
5224     if( trust == newtrust )
5225         return 0; /* already in that state */
5226     update_ownertrust(pk, newtrust );
5227     return 0;
5228 }
5229
5230
5231 static void
5232 menu_showphoto( KBNODE keyblock )
5233 {
5234   KBNODE node;
5235   int select_all = !count_selected_uids(keyblock);
5236   int count=0;
5237   PKT_public_key *pk=NULL;
5238
5239   /* Look for the public key first.  We have to be really, really,
5240      explicit as to which photo this is, and what key it is a UID on
5241      since people may want to sign it. */
5242
5243   for( node = keyblock; node; node = node->next )
5244     {
5245       if( node->pkt->pkttype == PKT_PUBLIC_KEY )
5246         pk = node->pkt->pkt.public_key;
5247       else if( node->pkt->pkttype == PKT_USER_ID )
5248         {
5249           PKT_user_id *uid = node->pkt->pkt.user_id;
5250           count++;
5251
5252           if((select_all || (node->flag & NODFLG_SELUID)) &&
5253              uid->attribs!=NULL)
5254             {
5255               int i;
5256
5257               for(i=0;i<uid->numattribs;i++)
5258                 {
5259                   byte type;
5260                   u32 size;
5261
5262                   if(uid->attribs[i].type==ATTRIB_IMAGE &&
5263                      parse_image_header(&uid->attribs[i],&type,&size))
5264                     {
5265                       tty_printf(_("Displaying %s photo ID of size %ld for "
5266                                    "key %s (uid %d)\n"),
5267                                  image_type_to_string(type,1),
5268                                  (ulong)size,keystr_from_pk(pk),count);
5269                       show_photos(&uid->attribs[i],1,pk,NULL,uid);
5270                     }
5271                 }
5272             }
5273         }
5274     }
5275 }