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