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