Note: I have not fully tested the new key creation due to a pc/sc
[gnupg.git] / g10 / card-util.c
1 /* card-util.c - Utility functions for the OpenPGP card.
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #if GNUPG_MAJOR_VERSION != 1
29 #include "gpg.h"
30 #endif
31 #include "util.h"
32 #include "i18n.h"
33 #include "ttyio.h"
34 #include "status.h"
35 #include "options.h"
36 #include "main.h"
37 #include "keyserver-internal.h"
38 #if GNUPG_MAJOR_VERSION == 1
39 #include "cardglue.h"
40 #else
41 #include "call-agent.h"
42 #endif
43
44 #define CONTROL_D ('D' - 'A' + 1)
45
46
47 /* Change the PIN of a an OpenPGP card.  This is an interactive
48    function. */
49 void
50 change_pin (int chvno)
51 {
52   struct agent_card_info_s info;
53   int rc;
54
55   rc = agent_learn (&info);
56   if (rc)
57     {
58       log_error (_("OpenPGP card not available: %s\n"),
59                   gpg_strerror (rc));
60       return;
61     }
62   
63   log_info (_("OpenPGP card no. %s detected\n"),
64               info.serialno? info.serialno : "[none]");
65
66   agent_release_card_info (&info);
67
68   if (opt.batch)
69     {
70       log_error (_("sorry, can't do this in batch mode\n"));
71       return;
72     }
73
74   for (;;)
75     {
76       char *answer;
77
78       tty_printf ("\n");
79       tty_printf ("1 - change PIN\n"
80                   "2 - unblock PIN\n"
81                   "3 - change Admin PIN\n"
82                   "Q - quit\n");
83       tty_printf ("\n");
84
85       answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
86       cpr_kill_prompt();
87       if (strlen (answer) != 1)
88         continue;
89
90       rc = 0;
91       if (*answer == '1')
92         {
93           rc = agent_scd_change_pin (1);
94           if (rc)
95             tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
96           else
97             tty_printf ("PIN changed.\n");
98         }
99       else if (*answer == '2')
100         {
101           rc = agent_scd_change_pin (101);
102           if (rc)
103             tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
104           else
105             tty_printf ("PIN unblocked and new PIN set.\n");
106         }
107       else if (*answer == '3')
108         {
109           rc = agent_scd_change_pin (3);
110           if (rc)
111             tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
112           else
113             tty_printf ("PIN changed.\n");
114         }
115       else if (*answer == 'q' || *answer == 'Q')
116         {
117           break;
118         }
119     }
120 }
121
122 static const char *
123 get_manufacturer (unsigned int no)
124 {
125   /* Note:  Make sure that there is no colon or linefeed in the string. */
126   switch (no)
127     {
128     case 0:
129     case 0xffff: return "test card";
130     case 0x0001: return "PPC Card Systems";
131     default: return "unknown";
132     }
133 }
134
135
136 static void
137 print_sha1_fpr (FILE *fp, const unsigned char *fpr)
138 {
139   int i;
140
141   if (fpr)
142     {
143       for (i=0; i < 20 ; i+=2, fpr += 2 )
144         {
145           if (i == 10 )
146             tty_fprintf (fp, " ");
147           tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]);
148         }
149     }
150   else
151     tty_fprintf (fp, " [none]");
152   tty_fprintf (fp, "\n");
153 }
154
155
156 static void
157 print_sha1_fpr_colon (FILE *fp, const unsigned char *fpr)
158 {
159   int i;
160
161   if (fpr)
162     {
163       for (i=0; i < 20 ; i++, fpr++)
164         fprintf (fp, "%02X", *fpr);
165     }
166   putc (':', fp);
167 }
168
169
170 static void
171 print_name (FILE *fp, const char *text, const char *name)
172 {
173   tty_fprintf (fp, "%s", text);
174
175   /* FIXME: tty_printf_utf8_string2 eats everything after and
176      including an @ - e.g. when printing an url. */
177   if (name && *name)
178     {
179       if (fp)
180         print_utf8_string2 (fp, name, strlen (name), '\n');
181       else
182         tty_print_utf8_string2 (name, strlen (name), 0);
183     }
184   else
185     tty_fprintf (fp, _("[not set]"));
186   tty_fprintf (fp, "\n");
187 }
188
189 static void
190 print_isoname (FILE *fp, const char *text, const char *tag, const char *name)
191 {
192   if (opt.with_colons)
193     fprintf (fp, "%s:", tag);
194   else
195     tty_fprintf (fp, "%s", text);
196
197   if (name && *name)
198     {
199       char *p, *given, *buf = xstrdup (name);
200
201       given = strstr (buf, "<<");
202       for (p=buf; *p; p++)
203         if (*p == '<')
204           *p = ' ';
205       if (given && given[2])
206         {
207           *given = 0;
208           given += 2;
209           if (opt.with_colons)
210             print_string (fp, given, strlen (given), ':');
211           else if (fp)
212             print_utf8_string2 (fp, given, strlen (given), '\n');
213           else
214             tty_print_utf8_string2 (given, strlen (given), 0);
215
216           if (opt.with_colons)
217             putc (':', fp);
218           else if (*buf)
219             tty_fprintf (fp, " ");
220         }
221
222       if (opt.with_colons)
223         print_string (fp, buf, strlen (buf), ':');
224       else if (fp)
225         print_utf8_string2 (fp, buf, strlen (buf), '\n');
226       else
227         tty_print_utf8_string2 (buf, strlen (buf), 0);
228       xfree (buf);
229     }
230   else
231     {
232       if (opt.with_colons)
233         putc (':', fp);
234       else
235         tty_fprintf (fp, _("[not set]"));
236     }
237
238   if (opt.with_colons)
239     fputs (":\n", fp);
240   else
241     tty_fprintf (fp, "\n");
242 }
243
244 /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
245 static int
246 fpr_is_zero (const char *fpr)
247 {
248   int i;
249
250   for (i=0; i < 20 && !fpr[i]; i++)
251     ;
252   return (i == 20);
253 }
254
255
256 /* Print all available information about the current card. */
257 void
258 card_status (FILE *fp, char *serialno, size_t serialnobuflen)
259 {
260   struct agent_card_info_s info;
261   PKT_public_key *pk = xcalloc (1, sizeof *pk);
262   int rc;
263   unsigned int uval;
264
265   if (serialno && serialnobuflen)
266     *serialno = 0;
267
268   rc = agent_learn (&info);
269   if (rc)
270     {
271       if (opt.with_colons)
272         fputs ("AID:::\n", fp);
273       log_error (_("OpenPGP card not available: %s\n"),
274                   gpg_strerror (rc));
275       xfree (pk);
276       return;
277     }
278
279   if (opt.with_colons)
280     fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
281   else
282     tty_fprintf (fp, "Application ID ...: %s\n",
283                  info.serialno? info.serialno : "[none]");
284   if (!info.serialno || strncmp (info.serialno, "D27600012401", 12) 
285       || strlen (info.serialno) != 32 )
286     {
287       if (opt.with_colons)
288         fputs ("unknown:\n", fp);
289       log_info ("not an OpenPGP card\n");
290       agent_release_card_info (&info);
291       xfree (pk);
292       return;
293     }
294
295   if (!serialno)
296     ;
297   else if (strlen (serialno)+1 > serialnobuflen)
298     log_error ("serial number longer than expected\n");
299   else 
300     strcpy (serialno, info.serialno);
301
302   if (opt.with_colons)
303     fputs ("openpgp-card:\n", fp);
304
305
306   if (opt.with_colons)
307     {
308       fprintf (fp, "version:%.4s:\n", info.serialno+12);
309       uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
310       fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
311       fprintf (fp, "serial:%.8s:\n", info.serialno+20);
312       
313       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
314
315       fputs ("lang:", fp);
316       if (info.disp_lang)
317         print_string (fp, info.disp_lang, strlen (info.disp_lang), ':');
318       fputs (":\n", fp);
319
320       fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
321                                  info.disp_sex == 2? 'f' : 'u'));
322
323       fputs ("url:", fp);
324       if (info.pubkey_url)
325         print_string (fp, info.pubkey_url, strlen (info.pubkey_url), ':');
326       fputs (":\n", fp);
327
328       fputs ("login:", fp);
329       if (info.login_data)
330         print_string (fp, info.login_data, strlen (info.login_data), ':');
331       fputs (":\n", fp);
332
333       fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
334       fprintf (fp, "maxpinlen:%d:%d:%d:\n",
335                    info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
336       fprintf (fp, "pinretry:%d:%d:%d:\n",
337                    info.chvretry[0], info.chvretry[1], info.chvretry[2]);
338       fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
339
340       fputs ("cafpr:", fp);
341       print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
342       print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
343       print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
344       putc ('\n', fp);
345       fputs ("fpr:", fp);
346       print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
347       print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
348       print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
349       putc ('\n', fp);
350
351     }
352   else 
353     {
354       tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
355                    info.serialno[12] == '0'?"":info.serialno+12,
356                    info.serialno[13],
357                    info.serialno[14] == '0'?"":info.serialno+14,
358                    info.serialno[15]);
359       tty_fprintf (fp, "Manufacturer .....: %s\n", 
360                    get_manufacturer (xtoi_2(info.serialno+16)*256
361                                      + xtoi_2 (info.serialno+18)));
362       tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
363       
364       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
365       print_name (fp, "Language prefs ...: ", info.disp_lang);
366       tty_fprintf (fp,    "Sex ..............: %s\n",
367                    info.disp_sex == 1? _("male"):
368                    info.disp_sex == 2? _("female") : _("unspecified"));
369       print_name (fp, "URL of public key : ", info.pubkey_url);
370       print_name (fp, "Login data .......: ", info.login_data);
371       if (info.cafpr1valid)
372         {
373           tty_fprintf (fp, "CA fingerprint %d .:", 1);
374           print_sha1_fpr (fp, info.cafpr1);
375         }
376       if (info.cafpr2valid)
377         {
378           tty_fprintf (fp, "CA fingerprint %d .:", 2);
379           print_sha1_fpr (fp, info.cafpr2);
380         }
381       if (info.cafpr3valid)
382         {
383           tty_fprintf (fp, "CA fingerprint %d .:", 3);
384           print_sha1_fpr (fp, info.cafpr3);
385         }
386       tty_fprintf (fp,    "Signature PIN ....: %s\n",
387                    info.chv1_cached? _("not forced"): _("forced"));
388       tty_fprintf (fp,    "Max. PIN lengths .: %d %d %d\n",
389                    info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
390       tty_fprintf (fp,    "PIN retry counter : %d %d %d\n",
391                    info.chvretry[0], info.chvretry[1], info.chvretry[2]);
392       tty_fprintf (fp,    "Signature counter : %lu\n", info.sig_counter);
393       tty_fprintf (fp, "Signature key ....:");
394       print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
395       tty_fprintf (fp, "Encryption key....:");
396       print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
397       tty_fprintf (fp, "Authentication key:");
398       print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
399       tty_fprintf (fp, "General key info..: "); 
400       if (info.fpr1valid && !get_pubkey_byfprint (pk, info.fpr1, 20))
401         print_pubkey_info (fp, pk);
402       else
403         tty_fprintf (fp, "[none]\n");
404     }
405       
406   free_public_key (pk);
407   agent_release_card_info (&info);
408 }
409
410
411 static char *
412 get_one_name (const char *prompt1, const char *prompt2)
413 {
414   char *name;
415   int i;
416
417   for (;;)
418     {
419       name = cpr_get (prompt1, prompt2);
420       if (!name)
421         return NULL;
422       trim_spaces (name);
423       cpr_kill_prompt ();
424       for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
425         ;
426
427       /* The name must be in Latin-1 and not UTF-8 - lacking the code
428          to ensure this we restrict it to ASCII. */
429       if (name[i])
430         tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
431       else if (strchr (name, '<'))
432         tty_printf (_("Error: The \"<\" character may not be used.\n"));
433       else if (strstr (name, "  "))
434         tty_printf (_("Error: Double spaces are not allowed.\n"));    
435       else
436         return name;
437       xfree (name);
438     }
439 }
440
441
442
443 static int
444 change_name (void)
445 {
446   char *surname = NULL, *givenname = NULL;
447   char *isoname, *p;
448   int rc;
449
450   surname = get_one_name ("keygen.smartcard.surname",
451                                     _("Cardholder's surname: "));
452   givenname = get_one_name ("keygen.smartcard.givenname",
453                                        _("Cardholder's given name: "));
454   if (!surname || !givenname || (!*surname && !*givenname))
455     {
456       xfree (surname);
457       xfree (givenname);
458       return -1; /*canceled*/
459     }
460
461   isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
462   strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
463   xfree (surname);
464   xfree (givenname);
465   for (p=isoname; *p; p++)
466     if (*p == ' ')
467       *p = '<';
468
469   if (strlen (isoname) > 39 )
470     {
471       tty_printf (_("Error: Combined name too long "
472                     "(limit is %d characters).\n"), 39);    
473       xfree (isoname);
474       return -1;
475     }
476
477   log_debug ("setting Name to `%s'\n", isoname);
478   rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname) );
479   if (rc)
480     log_error ("error setting Name: %s\n", gpg_strerror (rc));
481
482   xfree (isoname);
483   return rc;
484 }
485
486
487 static int
488 change_url (void)
489 {
490   char *url;
491   int rc;
492
493   url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
494   if (!url)
495     return -1;
496   trim_spaces (url);
497   cpr_kill_prompt ();
498
499   if (strlen (url) > 254 )
500     {
501       tty_printf (_("Error: URL too long "
502                     "(limit is %d characters).\n"), 254);    
503       xfree (url);
504       return -1;
505     }
506
507   rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url) );
508   if (rc)
509     log_error ("error setting URL: %s\n", gpg_strerror (rc));
510   xfree (url);
511   return rc;
512 }
513
514 static int
515 fetch_url(void)
516 {
517   int rc;
518   struct agent_card_info_s info;
519
520   memset(&info,0,sizeof(info));
521
522   rc=agent_scd_getattr("PUBKEY-URL",&info);
523   if(rc)
524     log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
525   else if(info.pubkey_url)
526     {
527       struct keyserver_spec *spec=NULL;
528
529       rc=agent_scd_getattr("KEY-FPR",&info);
530       if(rc)
531         log_error("error retrieving key fingerprint from card: %s\n",
532                   gpg_strerror(rc));
533       else
534         {
535           spec=parse_keyserver_uri(info.pubkey_url,0,NULL,0);
536           if(spec && info.fpr1valid)
537             {
538               /* This is not perfectly right.  Currently, all card
539                  fingerprints are 20 digits, but what about
540                  fingerprints for a future v5 key?  We should get the
541                  length from somewhere lower in the code.  In any
542                  event, the fpr/keyid is not meaningful for straight
543                  HTTP fetches, but using it allows the card to point
544                  to HKP and LDAP servers as well. */
545               rc=keyserver_import_fprint(info.fpr1,20,spec);
546               free_keyserver_spec(spec);
547             }
548         }
549     }
550   else
551     log_error("no URL set on card\n");
552
553   return rc;
554 }
555
556
557 static int
558 change_login (const char *args)
559 {
560   char *data;
561   int n;
562   int rc;
563
564   if (args && *args == '<')  /* Read it from a file */
565     {
566       FILE *fp;
567
568       for (args++; spacep (args); args++)
569         ;
570       fp = fopen (args, "rb");
571       if (!fp)
572         {
573           tty_printf ("can't open `%s': %s\n", args, strerror (errno));
574           return -1;
575         }
576       data = xmalloc (254);
577       n = fread (data, 1, 254, fp);
578       fclose (fp);
579       if (n < 0)
580         {
581           tty_printf ("error reading `%s': %s\n", args, strerror (errno));
582           xfree (data);
583           return -1;
584         }
585     }
586   else
587     {
588       data = cpr_get ("cardedit.change_login",
589                       _("Login data (account name): "));
590       if (!data)
591         return -1;
592       trim_spaces (data);
593       cpr_kill_prompt ();
594       n = strlen (data);
595     }
596
597   if (n > 254 )
598     {
599       tty_printf (_("Error: Login data too long "
600                     "(limit is %d characters).\n"), 254);    
601       xfree (data);
602       return -1;
603     }
604
605   rc = agent_scd_setattr ("LOGIN-DATA", data, n );
606   if (rc)
607     log_error ("error setting login data: %s\n", gpg_strerror (rc));
608   xfree (data);
609   return rc;
610 }
611
612 static int
613 change_lang (void)
614 {
615   char *data, *p;
616   int rc;
617
618   data = cpr_get ("cardedit.change_lang",
619                   _("Language preferences: "));
620   if (!data)
621     return -1;
622   trim_spaces (data);
623   cpr_kill_prompt ();
624
625   if (strlen (data) > 8 || (strlen (data) & 1))
626     {
627       tty_printf (_("Error: invalid length of preference string.\n"));
628       xfree (data);
629       return -1;
630     }
631
632   for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
633     ;
634   if (*p)
635     {
636       tty_printf (_("Error: invalid characters in preference string.\n"));
637       xfree (data);
638       return -1;
639     }
640
641   rc = agent_scd_setattr ("DISP-LANG", data, strlen (data) );
642   if (rc)
643     log_error ("error setting lang: %s\n", gpg_strerror (rc));
644   xfree (data);
645   return rc;
646 }
647
648
649 static int
650 change_sex (void)
651 {
652   char *data;
653   const char *str;
654   int rc;
655
656   data = cpr_get ("cardedit.change_sex",
657                   _("Sex ((M)ale, (F)emale or space): "));
658   if (!data)
659     return -1;
660   trim_spaces (data);
661   cpr_kill_prompt ();
662
663   if (!*data)
664     str = "9";
665   else if ((*data == 'M' || *data == 'm') && !data[1])
666     str = "1";
667   else if ((*data == 'F' || *data == 'f') && !data[1])
668     str = "2";
669   else 
670     {
671       tty_printf (_("Error: invalid response.\n"));
672       xfree (data);
673       return -1;
674     }
675      
676   rc = agent_scd_setattr ("DISP-SEX", str, 1 );
677   if (rc)
678     log_error ("error setting sex: %s\n", gpg_strerror (rc));
679   xfree (data);
680   return rc;
681 }
682
683
684 static int
685 change_cafpr (int fprno)
686 {
687   char *data;
688   const char *s;
689   int i, c, rc;
690   unsigned char fpr[20];
691
692   data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
693   if (!data)
694     return -1;
695   trim_spaces (data);
696   cpr_kill_prompt ();
697
698   for (i=0, s=data; i < 20 && *s; )
699     {
700       while (spacep(s))
701         s++;
702       if (*s == ':')
703         s++;
704       while (spacep(s))
705         s++;
706       c = hextobyte (s);
707       if (c == -1)
708         break;
709       fpr[i++] = c;
710       s += 2;
711     }
712   xfree (data);
713   if (i != 20 || *s)
714     {
715       tty_printf (_("Error: invalid formatted fingerprint.\n"));
716       return -1;
717     }
718
719   rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
720                           fprno==2?"CA-FPR-2":
721                           fprno==3?"CA-FPR-3":"x", fpr, 20 );
722   if (rc)
723     log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
724   return rc;
725 }
726
727
728
729 static void
730 toggle_forcesig (void)
731 {
732   struct agent_card_info_s info;
733   int rc;
734   int newstate;
735
736   memset (&info, 0, sizeof info);
737   rc = agent_scd_getattr ("CHV-STATUS", &info);
738   if (rc)
739     {
740       log_error ("error getting current status: %s\n", gpg_strerror (rc));
741       return;
742     }
743   newstate = !info.chv1_cached;
744   agent_release_card_info (&info);
745
746   rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1);
747   if (rc)
748     log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
749 }
750
751
752 /* Helper for the key generation/edit functions.  */
753 static int
754 get_info_for_key_operation (struct agent_card_info_s *info)
755 {
756   int rc;
757
758   memset (info, 0, sizeof *info);
759   rc = agent_scd_getattr ("SERIALNO", info);
760   if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12) 
761       || strlen (info->serialno) != 32 )
762     {
763       log_error (_("key operation not possible: %s\n"),
764                  rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
765       return rc? rc: -1;
766     }
767   rc = agent_scd_getattr ("KEY-FPR", info);
768   if (!rc)
769     rc = agent_scd_getattr ("CHV-STATUS", info);
770   if (!rc)
771     rc = agent_scd_getattr ("DISP-NAME", info);
772   if (rc)
773     log_error (_("error getting current key info: %s\n"), gpg_strerror (rc));
774   return rc;
775 }
776
777
778 /* Helper for the key generation/edit functions.  */
779 static int
780 check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
781 {     
782   int rc = 0;
783
784   *forced_chv1 = !info->chv1_cached;
785   if (*forced_chv1)
786     { /* Switch of the forced mode so that during key generation we
787          don't get bothered with PIN queries for each
788          self-signature. */
789       rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
790       if (rc)
791         {
792           log_error ("error clearing forced signature PIN flag: %s\n",
793                      gpg_strerror (rc));
794           *forced_chv1 = 0;
795         }
796     }
797
798   if (!rc)
799     {
800       /* Check the PIN now, so that we won't get asked later for each
801          binding signature. */
802       rc = agent_scd_checkpin (info->serialno);
803       if (rc)
804         log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
805     }
806   return rc;
807 }
808
809 /* Helper for the key generation/edit functions.  */
810 static void 
811 restore_forced_chv1 (int *forced_chv1)
812 {
813   int rc;
814
815   if (*forced_chv1)
816     { /* Switch back to forced state. */
817       rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
818       if (rc)
819         {
820           log_error ("error setting forced signature PIN flag: %s\n",
821                      gpg_strerror (rc));
822         }
823     }
824 }
825
826 /* Helper for the key generation/edit functions.  */
827 static void
828 show_card_key_info (struct agent_card_info_s *info)
829 {
830   tty_fprintf (NULL, "Signature key ....:");
831   print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL);
832   tty_fprintf (NULL, "Encryption key....:");
833   print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL);
834   tty_fprintf (NULL, "Authentication key:");
835   print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
836   tty_printf ("\n");
837 }
838
839
840 /* Helper for the key generation/edit functions.  */
841 static int
842 replace_existing_key_p (struct agent_card_info_s *info, int keyno)
843 {
844   assert (keyno >= 0 && keyno <= 3);
845
846   if ((keyno == 1 && info->fpr1valid)
847       || (keyno == 2 && info->fpr2valid)
848       || (keyno == 3 && info->fpr3valid))
849     {
850       tty_printf ("\n");
851       log_info ("WARNING: such a key has already been stored on the card!\n");
852       tty_printf ("\n");
853       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
854                                   _("Replace existing key? ")))
855         return -1;
856     }
857   return 0;
858 }
859
860
861
862 static void
863 generate_card_keys (const char *serialno)
864 {
865   struct agent_card_info_s info;
866   int forced_chv1;
867   int want_backup;
868
869   if (get_info_for_key_operation (&info))
870     return;
871
872   want_backup = !(cpr_get_answer_is_yes 
873                   ( "cardedit.genkeys.backup_enc",
874                     _("Inhibit creation of encryption key backup? ")));
875
876   if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
877        || (info.fpr2valid && !fpr_is_zero (info.fpr2))
878        || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
879     {
880       tty_printf ("\n");
881       log_info ("NOTE: keys are already stored on the card!\n");
882       tty_printf ("\n");
883       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
884                                   _("Replace existing keys? ")))
885         {
886           agent_release_card_info (&info);
887           return;
888         }
889     }
890   else if (!info.disp_name || !*info.disp_name)
891     {
892       tty_printf ("\n");
893       tty_printf (_("Please note that the factory settings of the PINs are\n"
894                     "   PIN = \"%s\"     Admin PIN = \"%s\"\n"
895                     "You should change them using the command --change-pin\n"),
896                   "123456", "12345678");
897       tty_printf ("\n");
898     }
899
900   if (check_pin_for_key_operation (&info, &forced_chv1))
901     goto leave;
902   
903   generate_keypair (NULL, info.serialno,
904                     want_backup? opt.homedir:NULL);
905
906  leave:
907   agent_release_card_info (&info);
908   restore_forced_chv1 (&forced_chv1);
909 }
910
911
912 /* This fucntion is used by the key edit menu to generate an arbitrary
913    subkey. */
914 int
915 card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
916 {
917   struct agent_card_info_s info;
918   int okay = 0;
919   int forced_chv1 = 0;
920   int keyno;
921
922   if (get_info_for_key_operation (&info))
923     return 0;
924
925   show_card_key_info (&info);
926
927   tty_printf (_("Please select the type of key to generate:\n"));
928
929   tty_printf (_("   (1) Signature key\n"));
930   tty_printf (_("   (2) Encryption key\n"));
931   tty_printf (_("   (3) Authentication key\n"));
932
933   for (;;) 
934     {
935       char *answer = cpr_get ("cardedit.genkeys.subkeytype",
936                               _("Your selection? "));
937       cpr_kill_prompt();
938       if (*answer == CONTROL_D)
939         {
940           xfree (answer);
941           goto leave;
942         }
943       keyno = *answer? atoi(answer): 0;
944       xfree(answer);
945       if (keyno >= 1 && keyno <= 3)
946         break; /* Okay. */
947       tty_printf(_("Invalid selection.\n"));
948     }
949
950   if (replace_existing_key_p (&info, keyno))
951     goto leave;
952
953   if (check_pin_for_key_operation (&info, &forced_chv1))
954     goto leave;
955
956   okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
957                                    keyno, info.serialno);
958
959  leave:
960   agent_release_card_info (&info);
961   restore_forced_chv1 (&forced_chv1);
962   return okay;
963 }
964
965
966 /* Store the subkey at NODE into the smartcard and modify NODE to
967    carry the serrialno stuff instead of the actual secret key
968    parameters. */
969 int 
970 card_store_subkey (KBNODE node, int use)
971 {
972   struct agent_card_info_s info;
973   int okay = 0;
974   int rc;
975   int keyno, i;
976   PKT_secret_key *copied_sk = NULL;
977   PKT_secret_key *sk;
978   size_t n;
979   const char *s;
980   int allow_keyno[3];
981
982   assert (node->pkt->pkttype == PKT_SECRET_KEY
983           || node->pkt->pkttype == PKT_SECRET_SUBKEY);
984   sk = node->pkt->pkt.secret_key;
985
986   if (get_info_for_key_operation (&info))
987     return 0;
988
989   show_card_key_info (&info);
990
991   if (!is_RSA (sk->pubkey_algo) || nbits_from_sk (sk) != 1024 )
992     {
993       tty_printf ("You may only store a 1024 bit RSA key on the card\n");
994       tty_printf ("\n");
995       goto leave;
996     }
997
998   allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG)));
999   allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
1000   allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
1001
1002   tty_printf (_("Please select where to store the key:\n"));
1003
1004   if (allow_keyno[0])
1005     tty_printf (_("   (1) Signature key\n"));
1006   if (allow_keyno[1])
1007     tty_printf (_("   (2) Encryption key\n"));
1008   if (allow_keyno[2])
1009     tty_printf (_("   (3) Authentication key\n"));
1010
1011   for (;;) 
1012     {
1013       char *answer = cpr_get ("cardedit.genkeys.storekeytype",
1014                               _("Your selection? "));
1015       cpr_kill_prompt();
1016       if (*answer == CONTROL_D || !*answer)
1017         {
1018           xfree (answer);
1019           goto leave;
1020         }
1021       keyno = *answer? atoi(answer): 0;
1022       xfree(answer);
1023       if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
1024         break; /* Okay. */
1025       tty_printf(_("Invalid selection.\n"));
1026     }
1027
1028   if (replace_existing_key_p (&info, keyno))
1029     goto leave;
1030
1031   /* Unprotect key.  */
1032   switch (is_secret_key_protected (sk) )
1033     {
1034     case 0: /* Not protected. */
1035       break;
1036     case -1:
1037       log_error (_("unknown key protection algorithm\n"));
1038       goto leave;
1039     default:
1040       if (sk->protect.s2k.mode == 1001)
1041         {
1042           log_error (_("secret parts of key are not available\n"));
1043           goto leave;
1044         }
1045       if (sk->protect.s2k.mode == 1002)
1046         {
1047           log_error (_("secret key already stored on a card\n"));
1048           goto leave;
1049         }
1050       /* We better copy the key before we unprotect it.  */
1051       copied_sk = sk = copy_secret_key (NULL, sk);
1052       rc = check_secret_key (sk, 0);
1053       if (rc)
1054         goto leave;
1055     }
1056
1057   rc = save_unprotected_key_to_card (sk, keyno);
1058   if (rc)
1059     goto leave;
1060
1061   /* Get back to the maybe protected original secret key.  */
1062   if (copied_sk)
1063     {
1064       free_secret_key (copied_sk);
1065       copied_sk = NULL; 
1066     }
1067   sk = node->pkt->pkt.secret_key;
1068
1069   /* Get rid of the secret key parameters and store the serial numer. */
1070   n = pubkey_get_nskey (sk->pubkey_algo);
1071   for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; i++)
1072     {
1073       mpi_free (sk->skey[i]);
1074       sk->skey[i] = NULL;
1075     }
1076   i = pubkey_get_npkey (sk->pubkey_algo);
1077   sk->skey[i] = mpi_set_opaque (NULL, xstrdup ("dummydata"), 10);
1078   sk->is_protected = 1;
1079   sk->protect.s2k.mode = 1002;
1080   s = info.serialno;
1081   for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
1082        sk->protect.ivlen++, s += 2)
1083     sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
1084
1085   okay = 1;
1086
1087  leave:
1088   if (copied_sk)
1089     free_secret_key (copied_sk);
1090   agent_release_card_info (&info);
1091   return okay;
1092 }
1093
1094
1095
1096 /* Menu to edit all user changeable values on an OpenPGP card.  Only
1097    Key creation is not handled here. */
1098 void
1099 card_edit (STRLIST commands)
1100 {
1101   enum cmdids {
1102     cmdNOP = 0,
1103     cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
1104     cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
1105     cmdFORCESIG, cmdGENERATE, cmdPASSWD,
1106     cmdINVCMD
1107   };
1108
1109   static struct {
1110     const char *name;
1111     enum cmdids id;
1112     const char *desc;
1113   } cmds[] = {
1114     { N_("quit")  , cmdQUIT  , N_("quit this menu") },
1115     { N_("q")     , cmdQUIT  , NULL   },
1116     { N_("help")  , cmdHELP  , N_("show this help") },
1117     {    "?"      , cmdHELP  , NULL   },
1118     { N_("list")  , cmdLIST  , N_("list all available data") },
1119     { N_("l")     , cmdLIST  , NULL   },
1120     { N_("debug") , cmdDEBUG , NULL },
1121     { N_("name")  , cmdNAME  , N_("change card holder's name") },
1122     { N_("url")   , cmdURL   , N_("change URL to retrieve key") },
1123     { N_("fetch") , cmdFETCH , N_("fetch the key specified in the card URL") },
1124     { N_("login") , cmdLOGIN , N_("change the login name") },
1125     { N_("lang")  , cmdLANG  , N_("change the language preferences") },
1126     { N_("sex")   , cmdSEX   , N_("change card holder's sex") },
1127     { N_("cafpr"),  cmdCAFPR,  N_("change a CA fingerprint") },
1128     { N_("forcesig"),
1129                   cmdFORCESIG, N_("toggle the signature force PIN flag") },
1130     { N_("generate"),
1131                   cmdGENERATE, N_("generate new keys") },
1132     { N_("passwd"), cmdPASSWD, N_("menu to change or unblock the PIN") },
1133     { NULL, cmdINVCMD } 
1134   };
1135  
1136   enum cmdids cmd = cmdNOP;
1137   int have_commands = !!commands;
1138   int redisplay = 1;
1139   char *answer = NULL;
1140   int did_checkpin = 0;
1141   char serialnobuf[50];
1142
1143
1144   if (opt.command_fd != -1)
1145     ;
1146   else if (opt.batch && !have_commands)
1147     {
1148       log_error(_("can't do that in batchmode\n"));
1149       goto leave;
1150     }
1151
1152   for (;;)
1153     {
1154       int arg_number;
1155       const char *arg_string = "";
1156       char *p;
1157       int i;
1158       
1159       tty_printf("\n");
1160       if (redisplay )
1161         {
1162           if (opt.with_colons)
1163             {
1164               card_status (stdout, serialnobuf, DIM (serialnobuf));
1165               fflush (stdout);
1166             }
1167           else
1168             {
1169               card_status (NULL, serialnobuf, DIM (serialnobuf));
1170               tty_printf("\n");
1171             }
1172           redisplay = 0;
1173         }
1174
1175       do
1176         {
1177           xfree (answer);
1178           if (have_commands)
1179             {
1180               if (commands)
1181                 {
1182                   answer = xstrdup (commands->d);
1183                   commands = commands->next;
1184                 }
1185               else if (opt.batch)
1186                 {
1187                   answer = xstrdup ("quit");
1188                 }
1189               else
1190                 have_commands = 0;
1191             }
1192
1193             if (!have_commands)
1194               {
1195                 answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
1196                 cpr_kill_prompt();
1197             }
1198             trim_spaces(answer);
1199         }
1200       while( *answer == '#' );
1201
1202       arg_number = 0; /* Yes, here is the init which egcc complains about */
1203       if (!*answer)
1204         cmd = cmdLIST; /* Default to the list command */
1205       else if (*answer == CONTROL_D)
1206         cmd = cmdQUIT;
1207       else {
1208         if ((p=strchr (answer,' ')))
1209           {
1210             *p++ = 0;
1211             trim_spaces (answer);
1212             trim_spaces (p);
1213             arg_number = atoi(p);
1214             arg_string = p;
1215           }
1216
1217         for (i=0; cmds[i].name; i++ )
1218           if (!ascii_strcasecmp (answer, cmds[i].name ))
1219             break;
1220
1221         cmd = cmds[i].id;
1222       }
1223       
1224
1225       switch (cmd)
1226         {
1227         case cmdHELP:
1228           for (i=0; cmds[i].name; i++ )
1229             if (cmds[i].desc)
1230               tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1231           break;
1232
1233         case cmdLIST:
1234           redisplay = 1;
1235           break;
1236
1237         case cmdNAME:
1238           change_name ();
1239           break;
1240
1241         case cmdURL:
1242           change_url ();
1243           break;
1244
1245         case cmdFETCH:
1246           fetch_url();
1247           break;
1248
1249         case cmdLOGIN:
1250           change_login (arg_string);
1251           break;
1252
1253         case cmdLANG:
1254           change_lang ();
1255           break;
1256
1257         case cmdSEX:
1258           change_sex ();
1259           break;
1260
1261         case cmdCAFPR:
1262           if ( arg_number < 1 || arg_number > 3 )
1263             tty_printf ("usage: cafpr N\n"
1264                         "       1 <= N <= 3\n");
1265           else
1266             change_cafpr (arg_number);
1267           break;
1268
1269         case cmdFORCESIG:
1270           toggle_forcesig ();
1271           break;
1272
1273         case cmdGENERATE:
1274           generate_card_keys (serialnobuf);
1275           break;
1276
1277         case cmdPASSWD:
1278           change_pin (0);
1279           did_checkpin = 0; /* Need to reset it of course. */
1280           break;
1281
1282         case cmdQUIT:
1283           goto leave;
1284
1285         case cmdNOP:
1286           break;
1287
1288         case cmdINVCMD:
1289         default:
1290           tty_printf ("\n");
1291           tty_printf (_("Invalid command  (try \"help\")\n"));
1292           break;
1293         } /* End command switch. */
1294     } /* End of main menu loop. */
1295
1296  leave:
1297   xfree (answer);
1298 }
1299