194bd83e20fcd5acf1201171c74b2bfcaf77138b
[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 static void
753 generate_card_keys (const char *serialno)
754 {
755   struct agent_card_info_s info;
756   int rc;
757   int forced_chv1;
758
759   memset (&info, 0, sizeof info);
760   rc = agent_scd_getattr ("KEY-FPR", &info);
761   if (!rc)
762     rc = agent_scd_getattr ("SERIALNO", &info);
763   if (!rc)
764     rc = agent_scd_getattr ("CHV-STATUS", &info);
765   if (!rc)
766     rc = agent_scd_getattr ("DISP-NAME", &info);
767   if (rc)
768     {
769       log_error ("error getting current key info: %s\n", gpg_strerror (rc));
770       return;
771     }
772   if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
773        || (info.fpr2valid && !fpr_is_zero (info.fpr2))
774        || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
775     {
776       tty_printf ("\n");
777       log_info ("NOTE: keys are already stored on the card!\n");
778       tty_printf ("\n");
779       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_keys",
780                                   _("Replace existing keys? ")))
781         {
782           agent_release_card_info (&info);
783           return;
784         }
785     }
786   else if (!info.disp_name || !*info.disp_name)
787     {
788       tty_printf ("\n");
789       tty_printf (_("Please note that the factory settings of the PINs are\n"
790                     "   PIN = \"%s\"     Admin PIN = \"%s\"\n"
791                     "You should change them using the command --change-pin\n"),
792                   "123456", "12345678");
793       tty_printf ("\n");
794     }
795
796   forced_chv1 = !info.chv1_cached;
797   if (forced_chv1)
798     { /* Switch of the forced mode so that during key generation we
799          don't get bothered with PIN queries for each
800          self-signature. */
801       rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
802       if (rc)
803         {
804           log_error ("error clearing forced signature PIN flag: %s\n",
805                      gpg_strerror (rc));
806           return;
807         }
808     }
809
810   /* Check the PIN now, so that we won't get asked later for each
811      binding signature. */
812   rc = agent_scd_checkpin (serialno);
813   if (rc)
814     log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
815   else
816     generate_keypair (NULL, info.serialno);
817
818   agent_release_card_info (&info);
819   if (forced_chv1)
820     { /* Switch back to forced state. */
821       rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
822       if (rc)
823         {
824           log_error ("error setting forced signature PIN flag: %s\n",
825                      gpg_strerror (rc));
826           return;
827         }
828     }
829 }
830
831
832 /* This fucntion is used by the key edit menu to generate an arbitrary
833    subkey. */
834 int
835 card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
836 {
837   struct agent_card_info_s info;
838   int okay = 0;
839   int forced_chv1 = 0;
840   int rc;
841   int keyno;
842
843   memset (&info, 0, sizeof info);
844   rc = agent_scd_getattr ("SERIALNO", &info);
845   if (rc || !info.serialno || strncmp (info.serialno, "D27600012401", 12) 
846       || strlen (info.serialno) != 32 )
847     {
848       log_error (_("cannot generate key: %s\n"),
849                  rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
850       goto leave;
851     }
852   rc = agent_scd_getattr ("KEY-FPR", &info);
853   if (!rc)
854     rc = agent_scd_getattr ("CHV-STATUS", &info);
855   if (rc)
856     {
857       log_error ("error getting current key info: %s\n", gpg_strerror (rc));
858       goto leave;
859     }
860   
861   tty_fprintf (NULL, "Signature key ....:");
862   print_sha1_fpr (NULL, info.fpr1valid? info.fpr1:NULL);
863   tty_fprintf (NULL, "Encryption key....:");
864   print_sha1_fpr (NULL, info.fpr2valid? info.fpr2:NULL);
865   tty_fprintf (NULL, "Authentication key:");
866   print_sha1_fpr (NULL, info.fpr3valid? info.fpr3:NULL);
867   tty_printf ("\n");
868
869   tty_printf (_("Please select the type of key to generate:\n"));
870
871   tty_printf (_("   (1) Signature key\n"));
872   tty_printf (_("   (2) Encryption key\n"));
873   tty_printf (_("   (3) Authentication key\n"));
874
875   for (;;) 
876     {
877       char *answer = cpr_get ("cardedit.genkeys.subkeytype",
878                               _("Your selection? "));
879       cpr_kill_prompt();
880       if (*answer == CONTROL_D)
881         {
882           xfree (answer);
883           goto leave;
884         }
885       keyno = *answer? atoi(answer): 0;
886       xfree(answer);
887       if (keyno >= 1 && keyno <= 3)
888         break; /* Okay. */
889       tty_printf(_("Invalid selection.\n"));
890     }
891
892   if ((keyno == 1 && info.fpr1valid)
893       || (keyno == 2 && info.fpr2valid)
894       || (keyno == 3 && info.fpr3valid))
895     {
896       tty_printf ("\n");
897       log_info ("WARNING: such a key has already been stored on the card!\n");
898       tty_printf ("\n");
899       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
900                                   _("Replace existing key? ")))
901         goto leave;
902     }
903
904   forced_chv1 = !info.chv1_cached;
905   if (forced_chv1)
906     { /* Switch of the forced mode so that during key generation we
907          don't get bothered with PIN queries for each
908          self-signature. */
909       rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1);
910       if (rc)
911         {
912           log_error ("error clearing forced signature PIN flag: %s\n",
913                      gpg_strerror (rc));
914           forced_chv1 = 0;
915           goto leave;
916         }
917     }
918
919   /* Check the PIN now, so that we won't get asked later for each
920      binding signature. */
921   rc = agent_scd_checkpin (info.serialno);
922   if (rc)
923     log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
924   else
925     okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
926                                      keyno, info.serialno);
927
928  leave:
929   agent_release_card_info (&info);
930   if (forced_chv1)
931     { /* Switch back to forced state. */
932       rc = agent_scd_setattr ("CHV-STATUS-1", "", 1);
933       if (rc)
934         {
935           log_error ("error setting forced signature PIN flag: %s\n",
936                      gpg_strerror (rc));
937           return okay;
938         }
939     }
940   return okay;
941 }
942
943
944
945 /* Menu to edit all user changeable values on an OpenPGP card.  Only
946    Key creation is not handled here. */
947 void
948 card_edit (STRLIST commands)
949 {
950   enum cmdids {
951     cmdNOP = 0,
952     cmdQUIT, cmdHELP, cmdLIST, cmdDEBUG,
953     cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
954     cmdFORCESIG, cmdGENERATE, cmdPASSWD,
955     cmdINVCMD
956   };
957
958   static struct {
959     const char *name;
960     enum cmdids id;
961     const char *desc;
962   } cmds[] = {
963     { N_("quit")  , cmdQUIT  , N_("quit this menu") },
964     { N_("q")     , cmdQUIT  , NULL   },
965     { N_("help")  , cmdHELP  , N_("show this help") },
966     {    "?"      , cmdHELP  , NULL   },
967     { N_("list")  , cmdLIST  , N_("list all available data") },
968     { N_("l")     , cmdLIST  , NULL   },
969     { N_("debug") , cmdDEBUG , NULL },
970     { N_("name")  , cmdNAME  , N_("change card holder's name") },
971     { N_("url")   , cmdURL   , N_("change URL to retrieve key") },
972     { N_("fetch") , cmdFETCH , N_("fetch the key specified in the card URL") },
973     { N_("login") , cmdLOGIN , N_("change the login name") },
974     { N_("lang")  , cmdLANG  , N_("change the language preferences") },
975     { N_("sex")   , cmdSEX   , N_("change card holder's sex") },
976     { N_("cafpr"),  cmdCAFPR,  N_("change a CA fingerprint") },
977     { N_("forcesig"),
978                   cmdFORCESIG, N_("toggle the signature force PIN flag") },
979     { N_("generate"),
980                   cmdGENERATE, N_("generate new keys") },
981     { N_("passwd"), cmdPASSWD, N_("menu to change or unblock the PIN") },
982     { NULL, cmdINVCMD } 
983   };
984  
985   enum cmdids cmd = cmdNOP;
986   int have_commands = !!commands;
987   int redisplay = 1;
988   char *answer = NULL;
989   int did_checkpin = 0;
990   char serialnobuf[50];
991
992
993   if (opt.command_fd != -1)
994     ;
995   else if (opt.batch && !have_commands)
996     {
997       log_error(_("can't do that in batchmode\n"));
998       goto leave;
999     }
1000
1001   for (;;)
1002     {
1003       int arg_number;
1004       const char *arg_string = "";
1005       char *p;
1006       int i;
1007       
1008       tty_printf("\n");
1009       if (redisplay )
1010         {
1011           if (opt.with_colons)
1012             {
1013               card_status (stdout, serialnobuf, DIM (serialnobuf));
1014               fflush (stdout);
1015             }
1016           else
1017             {
1018               card_status (NULL, serialnobuf, DIM (serialnobuf));
1019               tty_printf("\n");
1020             }
1021           redisplay = 0;
1022         }
1023
1024       do
1025         {
1026           xfree (answer);
1027           if (have_commands)
1028             {
1029               if (commands)
1030                 {
1031                   answer = xstrdup (commands->d);
1032                   commands = commands->next;
1033                 }
1034               else if (opt.batch)
1035                 {
1036                   answer = xstrdup ("quit");
1037                 }
1038               else
1039                 have_commands = 0;
1040             }
1041
1042             if (!have_commands)
1043               {
1044                 answer = cpr_get_no_help("cardedit.prompt", _("Command> "));
1045                 cpr_kill_prompt();
1046             }
1047             trim_spaces(answer);
1048         }
1049       while( *answer == '#' );
1050
1051       arg_number = 0; /* Yes, here is the init which egcc complains about */
1052       if (!*answer)
1053         cmd = cmdLIST; /* Default to the list command */
1054       else if (*answer == CONTROL_D)
1055         cmd = cmdQUIT;
1056       else {
1057         if ((p=strchr (answer,' ')))
1058           {
1059             *p++ = 0;
1060             trim_spaces (answer);
1061             trim_spaces (p);
1062             arg_number = atoi(p);
1063             arg_string = p;
1064           }
1065
1066         for (i=0; cmds[i].name; i++ )
1067           if (!ascii_strcasecmp (answer, cmds[i].name ))
1068             break;
1069
1070         cmd = cmds[i].id;
1071       }
1072       
1073
1074       switch (cmd)
1075         {
1076         case cmdHELP:
1077           for (i=0; cmds[i].name; i++ )
1078             if (cmds[i].desc)
1079               tty_printf("%-10s %s\n", cmds[i].name, _(cmds[i].desc) );
1080           break;
1081
1082         case cmdLIST:
1083           redisplay = 1;
1084           break;
1085
1086         case cmdNAME:
1087           change_name ();
1088           break;
1089
1090         case cmdURL:
1091           change_url ();
1092           break;
1093
1094         case cmdFETCH:
1095           fetch_url();
1096           break;
1097
1098         case cmdLOGIN:
1099           change_login (arg_string);
1100           break;
1101
1102         case cmdLANG:
1103           change_lang ();
1104           break;
1105
1106         case cmdSEX:
1107           change_sex ();
1108           break;
1109
1110         case cmdCAFPR:
1111           if ( arg_number < 1 || arg_number > 3 )
1112             tty_printf ("usage: cafpr N\n"
1113                         "       1 <= N <= 3\n");
1114           else
1115             change_cafpr (arg_number);
1116           break;
1117
1118         case cmdFORCESIG:
1119           toggle_forcesig ();
1120           break;
1121
1122         case cmdGENERATE:
1123           generate_card_keys (serialnobuf);
1124           break;
1125
1126         case cmdPASSWD:
1127           change_pin (0);
1128           did_checkpin = 0; /* Need to reset it of course. */
1129           break;
1130
1131         case cmdQUIT:
1132           goto leave;
1133
1134         case cmdNOP:
1135           break;
1136
1137         case cmdINVCMD:
1138         default:
1139           tty_printf ("\n");
1140           tty_printf (_("Invalid command  (try \"help\")\n"));
1141           break;
1142         } /* End command switch. */
1143     } /* End of main menu loop. */
1144
1145  leave:
1146   xfree (answer);
1147 }
1148