* g10.c (main): Default {export|import}-unusable-sigs to off until the
[gnupg.git] / g10 / cardglue.c
1 /* cardglue.c - mainly dispatcher for card related functions.
2  * Copyright (C) 2003, 2004, 2005 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 #ifndef ENABLE_CARD_SUPPORT
23 #error  not configured for card support.
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <assert.h>
31
32 #include "options.h"
33 #include "packet.h"
34 #include "errors.h"
35 #include "memory.h"
36 #include "util.h"
37 #include "main.h"
38 #include "status.h"
39 #include "ttyio.h"
40 #include "i18n.h"
41
42 #include "cardglue.h"
43 #include "apdu.h"
44 #include "app-common.h"
45
46 /* If we build w/o agent support, assuan.h won't be included and thus
47    we need to define a repalcement for the assuan error type. */
48 #ifndef ENABLE_AGENT_SUPPORT
49 typedef int assuan_error_t;
50 #endif
51
52
53 struct ctrl_ctx_s 
54 {
55   assuan_error_t (*status_cb)(void *opaque, const char *line);
56   void *status_cb_arg;
57 };
58
59
60 struct pincb_parm_s
61 {
62   const char *sn;
63 };
64
65
66 struct writekey_parm_s
67 {
68   assuan_context_t ctx;
69   const unsigned char *keydata;
70   size_t keydatalen;
71 };
72
73
74
75 static char *default_reader_port;
76 static app_t current_app;
77
78
79 /* Local prototypes. */
80 static assuan_error_t learn_status_cb (void *opaque, const char *line);
81
82
83 \f
84 /* Create a serialno/fpr string from the serial number and the secret
85    key.  caller must free the returned string.  There is no error
86    return. [Taken from 1.9's keyid.c]*/
87 char *
88 serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
89                           PKT_secret_key *sk)
90 {
91   unsigned char fpr[MAX_FINGERPRINT_LEN];
92   size_t fprlen;
93   char *buffer, *p;
94   int i;
95   
96   fingerprint_from_sk (sk, fpr, &fprlen);
97   buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
98   for (i=0; i < snlen; i++, p+=2)
99     sprintf (p, "%02X", sn[i]);
100   *p++ = '/';
101   for (i=0; i < fprlen; i++, p+=2)
102     sprintf (p, "%02X", fpr[i]);
103   *p = 0;
104   return buffer;
105 }
106
107
108 /* Send a line with status information via assuan and escape all given
109    buffers. The variable elements are pairs of (char *, size_t),
110    terminated with a (NULL, 0). */
111 void
112 send_status_info (ctrl_t ctrl, const char *keyword, ...)
113 {
114   va_list arg_ptr;
115   const unsigned char *value;
116   size_t valuelen;
117   char buf[950], *p;
118   size_t n;
119   
120   va_start (arg_ptr, keyword);
121
122   p = buf; 
123   n = 0;
124   valuelen = strlen (keyword);
125   for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, keyword++)
126     *p++ = *keyword;
127
128   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
129     {
130       valuelen = va_arg (arg_ptr, size_t);
131       if (!valuelen)
132         continue; /* empty buffer */
133       if (n)
134         {
135           *p++ = ' ';
136           n++;
137         }
138       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
139         {
140           if (*value < ' ' || *value == '+')
141             {
142               sprintf (p, "%%%02X", *value);
143               p += 3;
144             }
145           else if (*value == ' ')
146             *p++ = '+';
147           else
148             *p++ = *value;
149         }
150     }
151   *p = 0;
152   if (ctrl && ctrl->status_cb)
153     ctrl->status_cb (ctrl->status_cb_arg, buf);
154
155   va_end (arg_ptr);
156 }
157
158
159 /* Replacement function of the Libgcrypt onewhich is used in gnupg
160    1.9.  Thus function computes the digest of ALGO from the data in
161    BUFFER of LENGTH.  ALGO must be supported. */
162 void 
163 gcry_md_hash_buffer (int algo, void *digest,
164                      const void *buffer, size_t length)
165 {
166   MD_HANDLE h = md_open (algo, 0);
167   if (!h)
168     BUG();
169   md_write (h, (byte *) buffer, length);
170   md_final (h);
171   memcpy (digest, md_read (h, algo), md_digest_length (algo));
172   md_close (h);
173 }
174
175
176 /* This is a limited version of the one in 1.9 but it should be
177    sufficient here. */
178 void
179 log_printf (const char *fmt, ...)
180 {
181   va_list arg_ptr;
182
183   va_start (arg_ptr, fmt);
184   vfprintf (log_stream (), fmt, arg_ptr);
185   va_end (arg_ptr);
186 }
187
188
189
190 /* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
191    dump, with TEXT just an empty string, print a trailing linefeed,
192    otherwise print an entire debug line. */
193 void
194 log_printhex (const char *text, const void *buffer, size_t length)
195 {
196   if (text && *text)
197     log_debug ("%s ", text);
198   if (length)
199     {
200       const unsigned char *p = buffer;
201       log_printf ("%02X", *p);
202       for (length--, p++; length--; p++)
203         log_printf (" %02X", *p);
204     }
205   if (text)
206     log_printf ("\n");
207 }
208
209
210
211 void
212 app_set_default_reader_port (const char *portstr)
213 {
214   xfree (default_reader_port);
215   default_reader_port = portstr? xstrdup (portstr): NULL;
216 }
217
218
219 void
220 card_set_reader_port (const char *portstr)
221 {
222   app_set_default_reader_port (portstr);
223 }
224
225
226 /* Retrieve the serial number and the time of the last update of the
227    card.  The serial number is returned as a malloced string (hex
228    encoded) in SERIAL and the time of update is returned in STAMP.  If
229    no update time is available the returned value is 0.  Caller must
230    free SERIAL unless the function returns an error. */
231 int 
232 app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
233 {
234   unsigned char *buf, *p;
235   int i;
236
237   if (!app || !serial || !stamp)
238     return gpg_error (GPG_ERR_INV_VALUE);
239
240   *serial = NULL;
241   *stamp = 0; /* not available */
242
243   buf = xtrymalloc (app->serialnolen * 2 + 1);
244   if (!buf)
245     return gpg_error_from_errno (errno);
246   for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
247     sprintf (p, "%02X", app->serialno[i]);
248   *p = 0;
249   *serial = buf;
250   return 0;
251 }
252
253
254
255
256
257
258 /* Release the card info structure. */
259 void 
260 agent_release_card_info (struct agent_card_info_s *info)
261 {
262   int i;
263
264   if (!info)
265     return;
266
267   xfree (info->serialno); info->serialno = NULL;
268   xfree (info->disp_name); info->disp_name = NULL;
269   xfree (info->disp_lang); info->disp_lang = NULL;
270   xfree (info->pubkey_url); info->pubkey_url = NULL;
271   xfree (info->login_data); info->login_data = NULL;
272   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
273   info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
274   for (i=0; i < 4; i++)
275     {
276       xfree (info->private_do[i]);
277       info->private_do[i] = NULL;
278     }
279 }
280
281
282 /* Print an error message for a failed assuan-Transact and return a
283    gpg error code. No error is printed if RC is 0. */
284 static gpg_error_t
285 test_transact (int rc, const char *command)
286 {
287   if (!rc)
288     return 0;
289   log_error ("sending command `%s' to agent failed: %s\n",
290              command, assuan_strerror (rc));
291   return gpg_error (GPG_ERR_CARD);
292 }
293
294
295 /* Try to open a card using an already running agent.  Prepare a
296    proper application context and return it. */
297 static app_t
298 open_card_via_agent (int *scd_available)
299 {
300   assuan_context_t ctx;
301   app_t app;
302   struct agent_card_info_s info;
303   int rc;
304
305   *scd_available = 0;
306   ctx = agent_open (1);
307   if (!ctx)
308     return NULL;
309
310   /* Request the serialbnumber of the card.  If we get
311      NOT_SUPPORTED or NO_SCDAEMON back, the gpg-agent either has
312      disabled scdaemon or it can't be used.  We close the connection
313      in this case and use our own code.  This may happen if just the
314      gpg-agent has been installed for the sake of passphrase
315      caching. */
316   memset (&info, 0, sizeof info);
317   rc = assuan_transact (ctx, "SCD SERIALNO openpgp",
318                         NULL, NULL, NULL, NULL,
319                         learn_status_cb, &info);
320   if (rc)
321     {
322       if ((rc & 0xffff) == 60 || (rc & 0xffff) == 119)
323         ;  /* No scdaemon available to gpg-agent. */
324       else
325         {
326           write_status_text (STATUS_CARDCTRL, "4");
327           log_info ("selecting openpgp failed: %s\n", assuan_strerror (rc));
328           *scd_available = 1;
329         }
330       agent_release_card_info (&info);
331       agent_close (ctx);
332       return NULL;
333     }
334   
335   app = xcalloc (1, sizeof *app);
336   app->assuan_ctx = ctx;
337
338   return app;
339 }
340
341
342
343 /* Open the current card and select the openpgp application.  Return
344    an APP context handle to be used for further procesing or NULL on
345    error or if no OpenPGP application exists.*/
346 static app_t
347 open_card (void)
348 {
349   int slot = -1;
350   int rc;
351   app_t app;
352   int did_shutdown = 0;
353
354   /* First check whether we can contact a gpg-agent and divert all
355      operation to it. This is required because gpg as well as the
356      agent require exclusive access to the reader. */
357   if (opt.use_agent)
358     {
359       int scd_available;
360
361       app = open_card_via_agent (&scd_available);
362       if (app)
363         goto ready; /* Yes, there is a agent with a usable card, go that way. */
364       if (scd_available)
365         return NULL; /* agent avilabale but card problem. */
366     }
367
368
369   /* No agent or usable agent, thus we do it on our own. */
370   card_close ();
371   
372  retry:
373   if (did_shutdown)
374     apdu_reset (slot);
375   else
376     {
377       slot = apdu_open_reader (default_reader_port);
378       if (slot == -1)
379         {
380           log_error ("card reader not available\n");
381           return NULL;
382         }
383     }
384
385   app = xcalloc (1, sizeof *app);
386   app->slot = slot;
387   rc = app_select_openpgp (app);
388   if (rc && !opt.batch)
389     {
390       write_status_text (STATUS_CARDCTRL, "1");
391       
392       did_shutdown = !!apdu_shutdown_reader (slot);
393
394       if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay",
395            _("Please insert the card and hit return or enter 'c' to cancel: "),
396                                        1) )
397         {
398           if (!did_shutdown)
399             apdu_close_reader (slot);
400           xfree (app);
401           goto retry;
402         }
403     }
404   if (rc)
405     {
406       write_status_text (STATUS_CARDCTRL, "4");
407       log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
408       apdu_close_reader (slot);
409       xfree (app);
410       return NULL;
411     }
412
413  ready:
414   app->initialized = 1;
415   current_app = app;
416   if (is_status_enabled () )
417     {
418       int i;
419       char *p, *buf;
420
421       buf = xmalloc (5 + app->serialnolen * 2 + 1);
422       p = stpcpy (buf, "3 ");
423       for (i=0; i < app->serialnolen; p +=2, i++)
424         sprintf (p, "%02X", app->serialno[i]);
425       write_status_text (STATUS_CARDCTRL, buf);
426       xfree (buf);
427     }
428
429   return app;
430 }
431
432
433 void
434 card_close (void)
435 {
436   if (current_app)
437     {
438       app_t app = current_app;
439       current_app = NULL;
440
441       if (app->assuan_ctx)
442         agent_close (app->assuan_ctx);
443       else
444         apdu_close_reader (app->slot);
445       xfree (app);
446     }
447 }
448
449
450 /* Format a cache ID from the serialnumber in SN and return it as an
451    allocated string.  In case of an error NULL is returned. */
452 static char *
453 format_cacheid (const char *sn)
454 {
455   const char *s;
456   size_t snlen;
457   char *cacheid = NULL;
458
459   /* The serialnumber we use for a card is "CARDSN:serialno".  Where
460      serialno is the BCD string (i.e. hex string) with the full
461      number.  The serial number expect here constsis of hexdigits
462      followed by other characters, we cut off these other
463      characters. */
464   if (sn)
465     {
466       for (s=sn,snlen=0; hexdigitp (s); s++, snlen++)
467         ;
468       if (snlen == 32)
469         {
470           /* Yes, this looks indeed like an OpenPGP card S/N. */
471           cacheid = xtrymalloc (7+snlen+1);
472           if (cacheid)
473             {
474               memcpy (cacheid, "CARDSN:", 7);
475               memcpy (cacheid+7, sn, snlen);
476               cacheid[7+snlen] = 0;
477             }
478         }
479     }
480   return cacheid;
481 }
482
483 /* Check that the serial number of the current card (as described by
484    APP) matches SERIALNO.  If there is no match and we are not in
485    batch mode, present a prompt to insert the desired card.  The
486    function return 0 is the present card is okay, -1 if the user
487    selected to insert a new card or an error value.  Note that the
488    card context will be closed in all cases except for 0 as return
489    value and if it was possible to merely shutdown the reader. */
490 static int
491 check_card_serialno (app_t app, const char *serialno)
492 {
493   const char *s;
494   int ask = 0;
495   int n;
496   
497   for (s = serialno, n=0; *s != '/' && hexdigitp (s); s++, n++)
498     ;
499   if (n != 32)
500     {
501       log_error ("invalid serial number in keyring detected\n");
502       return gpg_error (GPG_ERR_INV_ID);
503     }
504   if (app->serialnolen != 16)
505     ask = 1;
506   for (s = serialno, n=0; !ask && n < 16; s += 2, n++)
507     if (app->serialno[n] != xtoi_2 (s))
508       ask = 1;
509   if (ask)
510     {
511       char buf[5+32+1];
512       int did_shutdown = 0;
513
514       if (current_app && !apdu_shutdown_reader (current_app->slot))
515         did_shutdown = 1;
516       else
517         card_close ();
518       tty_printf (_("Please remove the current card and "
519                     "insert the one with serial number:\n"
520                     "   %.*s\n"), 32, serialno);
521
522       sprintf (buf, "1 %.32s", serialno);
523       write_status_text (STATUS_CARDCTRL, buf);
524
525       if ( cpr_get_answer_okay_cancel ("cardctrl.change_card.okay",
526                           _("Hit return when ready "
527                             "or enter 'c' to cancel: "),
528                                        1) )
529         {
530           card_close ();
531           return -1;
532         }
533       if (did_shutdown)
534         apdu_reset (current_app->slot);
535       else
536         card_close ();
537       return gpg_error (GPG_ERR_INV_ID);
538     }
539   return 0;
540 }
541
542
543 /* Take a 20 byte hexencoded string and put it into the the provided
544    20 byte buffer FPR in binary format. */
545 static int
546 unhexify_fpr (const char *hexstr, unsigned char *fpr)
547 {
548   const char *s;
549   int n;
550
551   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
552     ;
553   if (*s || (n != 40))
554     return 0; /* no fingerprint (invalid or wrong length). */
555   n /= 2;
556   for (s=hexstr, n=0; *s; s += 2, n++)
557     fpr[n] = xtoi_2 (s);
558   return 1; /* okay */
559 }
560
561 /* Take the serial number from LINE and return it verbatim in a newly
562    allocated string.  We make sure that only hex characters are
563    returned. */
564 static char *
565 store_serialno (const char *line)
566 {
567   const char *s;
568   char *p;
569
570   for (s=line; hexdigitp (s); s++)
571     ;
572   p = xmalloc (s + 1 - line);
573   memcpy (p, line, s-line);
574   p[s-line] = 0;
575   return p;
576 }
577
578
579
580 static assuan_error_t
581 learn_status_cb (void *opaque, const char *line)
582 {
583   struct agent_card_info_s *parm = opaque;
584   const char *keyword = line;
585   int keywordlen;
586   int i;
587
588 /*   log_debug ("got status line `%s'\n", line); */
589   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
590     ;
591   while (spacep (line))
592     line++;
593
594   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
595     {
596       xfree (parm->serialno);
597       parm->serialno = store_serialno (line);
598     }
599   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
600     {
601       xfree (parm->disp_name);
602       parm->disp_name = unescape_percent_string (line);
603     }
604   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
605     {
606       xfree (parm->disp_lang);
607       parm->disp_lang = unescape_percent_string (line);
608     }
609   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
610     {
611       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
612     }
613   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
614     {
615       xfree (parm->pubkey_url);
616       parm->pubkey_url = unescape_percent_string (line);
617     }
618   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
619     {
620       xfree (parm->login_data);
621       parm->login_data = unescape_percent_string (line);
622     }
623   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
624     {
625       parm->sig_counter = strtoul (line, NULL, 0);
626     }
627   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
628     {
629       char *p, *buf;
630
631       buf = p = unescape_percent_string (line);
632       if (buf)
633         {
634           while (spacep (p))
635             p++;
636           parm->chv1_cached = atoi (p);
637           while (*p && !spacep (p))
638             p++;
639           while (spacep (p))
640             p++;
641           for (i=0; *p && i < 3; i++)
642             {
643               parm->chvmaxlen[i] = atoi (p);
644               while (*p && !spacep (p))
645                 p++;
646               while (spacep (p))
647                 p++;
648             }
649           for (i=0; *p && i < 3; i++)
650             {
651               parm->chvretry[i] = atoi (p);
652               while (*p && !spacep (p))
653                 p++;
654               while (spacep (p))
655                 p++;
656             }
657           xfree (buf);
658         }
659     }
660   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
661     {
662       int no = atoi (line);
663       while (* line && !spacep (line))
664         line++;
665       while (spacep (line))
666         line++;
667       if (no == 1)
668         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
669       else if (no == 2)
670         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
671       else if (no == 3)
672         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
673     }
674   else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
675     {
676       int no = atoi (line);
677       while (* line && !spacep (line))
678         line++;
679       while (spacep (line))
680         line++;
681       if (no == 1)
682         parm->fpr1time = strtoul (line, NULL, 10);
683       else if (no == 2)
684         parm->fpr2time = strtoul (line, NULL, 10);
685       else if (no == 3)
686         parm->fpr3time = strtoul (line, NULL, 10);
687     }
688   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
689     {
690       int no = atoi (line);
691       while (*line && !spacep (line))
692         line++;
693       while (spacep (line))
694         line++;
695       if (no == 1)
696         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
697       else if (no == 2)
698         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
699       else if (no == 3)
700         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
701     }
702   else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
703            && strchr ("1234", keyword[11]))
704     {
705       int no = keyword[11] - '1';
706       assert (no >= 0 && no <= 3);
707       xfree (parm->private_do[no]);
708       parm->private_do[no] = unescape_percent_string (line);
709     }
710  
711   return 0;
712 }
713
714
715 /* Return card info. */
716 int 
717 agent_learn (struct agent_card_info_s *info)
718 {
719   app_t app;
720   int rc;
721   struct ctrl_ctx_s ctrl;
722   time_t stamp;
723   char *serial;
724   
725   app = current_app? current_app : open_card ();
726   if (!app)
727     return gpg_error (GPG_ERR_CARD);
728
729   memset (info, 0, sizeof *info);
730
731   if (app->assuan_ctx)
732     {
733       rc = assuan_transact (app->assuan_ctx, "SCD LEARN --force",
734                             NULL, NULL, NULL, NULL,
735                             learn_status_cb, info);
736       rc = test_transact (rc, "SCD LEARN");
737     }
738   else
739     {
740       memset (&ctrl, 0, sizeof ctrl);
741       ctrl.status_cb = learn_status_cb;
742       ctrl.status_cb_arg = info;
743
744       rc = app_get_serial_and_stamp (app, &serial, &stamp);
745       if (!rc)
746         {
747           send_status_info (&ctrl, "SERIALNO",
748                             serial, strlen(serial), NULL, 0);
749           xfree (serial);
750           rc = app->fnc.learn_status (app, &ctrl);
751         }
752     }
753
754   return rc;
755 }
756
757
758 /* Get an attribute from the card. Make sure info is initialized. */
759 int 
760 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
761 {
762   int rc;
763   app_t app;
764   struct ctrl_ctx_s ctrl;
765
766   app = current_app? current_app : open_card ();
767   if (!app)
768     return gpg_error (GPG_ERR_CARD);
769
770   if (app->assuan_ctx)
771     {
772       char line[ASSUAN_LINELENGTH];
773
774       /* We assume that NAME does not need escaping. */
775       if (12 + strlen (name) > DIM(line)-1)
776         return gpg_error (GPG_ERR_CARD);
777       stpcpy (stpcpy (line, "SCD GETATTR "), name); 
778
779       rc = test_transact (assuan_transact (app->assuan_ctx, line,
780                                            NULL, NULL, NULL, NULL,
781                                            learn_status_cb, info),
782                           "SCD GETATTR");
783     }
784   else
785     {
786       ctrl.status_cb = learn_status_cb;
787       ctrl.status_cb_arg = info;
788       rc = app->fnc.getattr (app, &ctrl, name);
789     }
790
791   return rc;
792 }
793
794
795
796 static int 
797 pin_cb (void *opaque, const char *info, char **retstr)
798 {
799   struct pincb_parm_s *parm = opaque;
800   char *value;
801   int canceled;
802   int isadmin = 0;
803   int newpin = 0;
804   const char *again_text = NULL;
805   const char *ends, *s;
806   char *cacheid = NULL;
807
808   *retstr = NULL;
809   /*   log_debug ("asking for PIN '%s'\n", info); */
810
811   /* We use a special prefix to check whether the Admin PIN has been
812      requested. */
813   if (info && *info =='|' && (ends=strchr (info+1, '|')))
814     {
815       for (s=info+1; s < ends; s++)
816         {
817           if (*s == 'A')
818             isadmin = 1;
819           else if (*s == 'N')
820             newpin = 1;
821         }
822       info = ends+1;
823     }
824   else if (info && *info == '|')
825     log_debug ("pin_cb called without proper PIN info hack\n");
826
827   /* If we are not requesting a new PIN and we are not requesting an
828      AdminPIN, compute a string to be used as the cacheID for
829      gpg-agent. */
830   if (!newpin && !isadmin && parm)
831     {
832       cacheid = format_cacheid (parm->sn);
833     }
834   else if (newpin && parm)
835     {
836       /* Make really sure that it is not cached anymore. */
837       agent_clear_pin_cache (parm->sn);
838     }
839
840
841  again:
842   if (is_status_enabled())
843     write_status_text (STATUS_NEED_PASSPHRASE_PIN,
844                        isadmin? "OPENPGP 3" : "OPENPGP 1");
845
846   value = ask_passphrase (info, again_text,
847                           newpin && isadmin? "passphrase.adminpin.new.ask" :
848                           newpin?  "passphrase.pin.new.ask" :
849                           isadmin? "passphrase.adminpin.ask" :
850                                    "passphrase.pin.ask", 
851                           newpin && isadmin? _("Enter New Admin PIN: ") :
852                           newpin?  _("Enter New PIN: ") :
853                           isadmin? _("Enter Admin PIN: ")
854                                  : _("Enter PIN: "),
855                           cacheid,
856                           &canceled);
857   xfree (cacheid);
858   cacheid = NULL;
859   again_text = NULL;
860   if (!value && canceled)
861     return -1;
862   else if (!value)
863     return G10ERR_GENERAL;
864
865   if (newpin)
866     {
867       char *value2;
868
869       value2 = ask_passphrase (info, NULL, NULL,
870                                "passphrase.pin.repeat", 
871                                _("Repeat this PIN: "),
872                               &canceled);
873       if (!value && canceled)
874         {
875           xfree (value);
876           return -1;
877         }
878       else if (!value)
879         {
880           xfree (value);
881           return G10ERR_GENERAL;
882         }
883       if (strcmp (value, value2))
884         {
885           again_text = N_("PIN not correctly repeated; try again");
886           xfree (value2);
887           xfree (value);
888           value = NULL;
889           goto again;
890         }
891       xfree (value2);
892     }
893
894   *retstr = value;
895   return 0;
896 }
897
898
899
900 /* Send a SETATTR command to the SCdaemon. */
901 int 
902 agent_scd_setattr (const char *name,
903                    const unsigned char *value, size_t valuelen)
904 {
905   app_t app;
906   int rc;
907
908   app = current_app? current_app : open_card ();
909   if (!app)
910     return gpg_error (GPG_ERR_CARD);
911
912   if (app->assuan_ctx)
913     {
914       char line[ASSUAN_LINELENGTH];
915       char *p;
916
917       /* We assume that NAME does not need escaping. */
918       if (12 + strlen (name) > DIM(line)-1)
919         return gpg_error (GPG_ERR_CARD);
920       p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
921       *p++ = ' ';
922       for (; valuelen; value++, valuelen--)
923         {
924           if (p >= line + DIM(line)-5 )
925             return gpg_error (GPG_ERR_CARD);
926           if (*value < ' ' || *value == '+' || *value == '%')
927             {
928               sprintf (p, "%%%02X", *value);
929               p += 3;
930             }
931           else if (*value == ' ')
932             *p++ = '+';
933           else
934             *p++ = *value;
935         }
936       *p = 0;
937
938       rc = test_transact (assuan_transact (app->assuan_ctx, line,
939                                            NULL, NULL, NULL, NULL, NULL, NULL),
940                           "SCD SETATTR");
941     }
942   else
943     {
944       rc = app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
945     }
946
947   if (rc)
948     write_status (STATUS_SC_OP_FAILURE);
949   return rc;
950 }
951
952
953 /* Handle a KEYDATA inquiry.  Note, we only send the data,
954    assuan_transact takes care of flushing and writing the end */
955 static assuan_error_t
956 inq_writekey_parms (void *opaque, const char *keyword)
957 {
958   struct writekey_parm_s *parm = opaque; 
959
960   return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
961 }
962
963
964 /* Send a WRITEKEY command to the SCdaemon. */
965 int 
966 agent_scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen)
967 {
968   app_t app;
969   int rc;
970   char line[ASSUAN_LINELENGTH];
971   app = current_app? current_app : open_card ();
972   if (!app)
973     return gpg_error (GPG_ERR_CARD);
974
975   if (app->assuan_ctx)
976     {
977       struct writekey_parm_s parms;
978
979       snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
980       line[DIM(line)-1] = 0;
981       parms.ctx = app->assuan_ctx;
982       parms.keydata = keydata;
983       parms.keydatalen = keydatalen;
984       rc = test_transact (assuan_transact (app->assuan_ctx, line,
985                                            NULL, NULL,
986                                            inq_writekey_parms, &parms,
987                                            NULL, NULL),
988                           "SCD WRITEKEY");
989     }
990   else
991     {
992       snprintf (line, DIM(line)-1, "OPENPGP.%d", keyno);
993       line[DIM(line)-1] = 0;
994       rc = app->fnc.writekey (app, NULL, line, 0x0001,
995                               pin_cb, NULL,
996                               keydata, keydatalen);
997     }
998
999   if (rc)
1000     write_status (STATUS_SC_OP_FAILURE);
1001   return rc;
1002 }
1003
1004
1005
1006 static assuan_error_t
1007 genkey_status_cb (void *opaque, const char *line)
1008 {
1009   struct agent_card_genkey_s *parm = opaque;
1010   const char *keyword = line;
1011   int keywordlen;
1012
1013 /*   log_debug ("got status line `%s'\n", line); */
1014   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1015     ;
1016   while (spacep (line))
1017     line++;
1018
1019   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
1020     {
1021       parm->fprvalid = unhexify_fpr (line, parm->fpr);
1022     }
1023   if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
1024     {
1025       MPI a;
1026       const char *name = line;
1027       char *buf;
1028
1029       while (*line && !spacep (line))
1030         line++;
1031       while (spacep (line))
1032         line++;
1033
1034       buf = xmalloc ( 2 + strlen (line) + 1);
1035       strcpy (stpcpy (buf, "0x"), line);
1036       a = mpi_alloc (300);
1037       if( mpi_fromstr (a, buf) )
1038         log_error ("error parsing received key data\n");
1039       else if (*name == 'n' && spacep (name+1))
1040         parm->n = a;
1041       else if (*name == 'e' && spacep (name+1))
1042         parm->e = a;
1043       else
1044         {
1045           log_info ("unknown parameter name in received key data\n");
1046           mpi_free (a);
1047         }
1048       xfree (buf);
1049     }
1050   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
1051     {
1052       parm->created_at = (u32)strtoul (line, NULL, 10);
1053     }
1054
1055   return 0;
1056 }
1057
1058 /* Send a GENKEY command to the SCdaemon. */
1059 int 
1060 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
1061 {
1062   app_t app;
1063   char line[ASSUAN_LINELENGTH];
1064   struct ctrl_ctx_s ctrl;
1065   int rc;
1066
1067   app = current_app? current_app : open_card ();
1068   if (!app)
1069     return gpg_error (GPG_ERR_CARD);
1070
1071   memset (info, 0, sizeof *info);
1072
1073   if (app->assuan_ctx)
1074     {
1075       snprintf (line, DIM(line)-1, "SCD GENKEY %s%d",
1076                 force? "--force ":"", keyno);
1077       line[DIM(line)-1] = 0;
1078       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1079                                            NULL, NULL, NULL, NULL,
1080                                            genkey_status_cb, info),
1081                           "SCD GENKEY");
1082     }
1083   else
1084     {
1085       snprintf (line, DIM(line)-1, "%d", keyno);
1086       ctrl.status_cb = genkey_status_cb;
1087       ctrl.status_cb_arg = info;
1088       rc = app->fnc.genkey (app, &ctrl, line,
1089                             force? 1:0,
1090                             pin_cb, NULL);
1091     }
1092
1093   if (rc)
1094     write_status (STATUS_SC_OP_FAILURE);
1095   return rc;
1096 }
1097
1098
1099 static assuan_error_t
1100 membuf_data_cb (void *opaque, const void *buffer, size_t length)
1101 {
1102   membuf_t *data = opaque;
1103
1104   if (buffer)
1105     put_membuf (data, buffer, length);
1106   return 0;
1107 }
1108   
1109
1110 /* Send a PKSIGN command to the SCdaemon. */
1111 int 
1112 agent_scd_pksign (const char *serialno, int hashalgo,
1113                   const unsigned char *indata, size_t indatalen,
1114                   unsigned char **r_buf, size_t *r_buflen)
1115 {
1116   struct pincb_parm_s parm;
1117   app_t app;
1118   int rc;
1119
1120   *r_buf = NULL;
1121   *r_buflen = 0;
1122   memset (&parm, 0, sizeof parm);
1123   parm.sn = serialno;
1124  retry:
1125   app = current_app? current_app : open_card ();
1126   if (!app)
1127     return gpg_error (GPG_ERR_CARD);
1128
1129   if (app->assuan_ctx)
1130     {
1131       char *p, line[ASSUAN_LINELENGTH];
1132       membuf_t data;
1133       size_t len;
1134       int i;
1135
1136       if (indatalen*2 + 50 > DIM(line))
1137         return gpg_error (GPG_ERR_GENERAL);
1138
1139       p = stpcpy (line, "SCD SETDATA ");
1140       for (i=0; i < indatalen ; i++, p += 2 )
1141         sprintf (p, "%02X", indata[i]);
1142       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1143                                            NULL, NULL, NULL, NULL, NULL, NULL),
1144                           "SCD SETDATA");
1145       if (!rc)
1146         {
1147           init_membuf (&data, 1024);
1148           snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno);
1149           line[DIM(line)-1] = 0;
1150           rc = test_transact (assuan_transact (app->assuan_ctx, line,
1151                                                membuf_data_cb, &data,
1152                                                NULL, NULL, NULL, NULL),
1153                               "SCD PKSIGN");
1154           if (rc)
1155             xfree (get_membuf (&data, &len));
1156           else
1157             *r_buf = get_membuf (&data, r_buflen);
1158         }
1159     }
1160   else
1161     {
1162       /* Check that the card's serialnumber is as required.*/
1163       rc = check_card_serialno (app, serialno);
1164       if (rc == -1)
1165         goto retry;
1166
1167       if (!rc)
1168         rc = app->fnc.sign (app, serialno, hashalgo,
1169                             pin_cb, &parm,
1170                             indata, indatalen,
1171                             r_buf, r_buflen);
1172     }
1173
1174   if (rc)
1175     {
1176       write_status (STATUS_SC_OP_FAILURE);
1177       if (!app->assuan_ctx)
1178         agent_clear_pin_cache (serialno);
1179     }
1180   return rc;
1181 }
1182
1183
1184 /* Send a PKDECRYPT command to the SCdaemon. */
1185 int 
1186 agent_scd_pkdecrypt (const char *serialno,
1187                      const unsigned char *indata, size_t indatalen,
1188                      unsigned char **r_buf, size_t *r_buflen)
1189 {
1190   struct pincb_parm_s parm;
1191   app_t app;
1192   int rc;
1193
1194   *r_buf = NULL;
1195   *r_buflen = 0;
1196   memset (&parm, 0, sizeof parm);
1197   parm.sn = serialno;
1198  retry:
1199   app = current_app? current_app : open_card ();
1200   if (!app)
1201     return gpg_error (GPG_ERR_CARD);
1202
1203   if (app->assuan_ctx)
1204     {
1205       char *p, line[ASSUAN_LINELENGTH];
1206       membuf_t data;
1207       size_t len;
1208       int i;
1209
1210       if (indatalen*2 + 50 > DIM(line))
1211         return gpg_error (GPG_ERR_GENERAL);
1212
1213       p = stpcpy (line, "SCD SETDATA ");
1214       for (i=0; i < indatalen ; i++, p += 2 )
1215         sprintf (p, "%02X", indata[i]);
1216       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1217                                            NULL, NULL, NULL, NULL, NULL, NULL),
1218                           "SCD SETDATA");
1219       if (!rc)
1220         {
1221           init_membuf (&data, 1024);
1222           snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1223           line[DIM(line)-1] = 0;
1224           rc = test_transact (assuan_transact (app->assuan_ctx, line,
1225                                                membuf_data_cb, &data,
1226                                                NULL, NULL, NULL, NULL),
1227                               "SCD PKDECRYPT");
1228           if (rc)
1229             xfree (get_membuf (&data, &len));
1230           else
1231             *r_buf = get_membuf (&data, r_buflen);
1232         }
1233     }
1234   else
1235     {
1236       /* Check that the card's serialnumber is as required.*/
1237       rc = check_card_serialno (app, serialno);
1238       if (rc == -1)
1239         goto retry;
1240       
1241       if (!rc)
1242         rc = app->fnc.decipher (app, serialno, 
1243                                 pin_cb, &parm,
1244                                 indata, indatalen,
1245                                 r_buf, r_buflen);
1246     }
1247
1248   if (rc)
1249     {
1250       write_status (STATUS_SC_OP_FAILURE);
1251       if (!app->assuan_ctx)
1252         agent_clear_pin_cache (serialno);
1253     }
1254   return rc;
1255 }
1256
1257 /* Change the PIN of an OpenPGP card or reset the retry counter. */
1258 int 
1259 agent_scd_change_pin (int chvno)
1260 {
1261   app_t app;
1262   int reset = 0;
1263   int rc;
1264
1265   reset = (chvno >= 100);
1266   chvno %= 100;
1267
1268   app = current_app? current_app : open_card ();
1269   if (!app)
1270     return gpg_error (GPG_ERR_CARD);
1271
1272   if (app->assuan_ctx)
1273     {
1274       char line[ASSUAN_LINELENGTH];
1275
1276       snprintf (line, DIM(line)-1, "SCD PASSWD%s %d",
1277                 reset? " --reset":"", chvno);
1278       line[DIM(line)-1] = 0;
1279       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1280                                            NULL, NULL, NULL, NULL, NULL, NULL),
1281                           "SCD PASSWD");
1282     }
1283   else
1284     {
1285       char chvnostr[50];
1286
1287       sprintf (chvnostr, "%d", chvno);
1288       rc = app->fnc.change_pin (app, NULL, chvnostr, reset,
1289                                 pin_cb, NULL);
1290     }
1291
1292   if (rc)
1293     write_status (STATUS_SC_OP_FAILURE);
1294   return rc;
1295 }
1296
1297 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1298    number of the card - optionally followed by the fingerprint;
1299    however the fingerprint is ignored here. */
1300 int
1301 agent_scd_checkpin (const char *serialnobuf)
1302 {
1303   app_t app;
1304   int rc;
1305
1306   app = current_app? current_app : open_card ();
1307   if (!app)
1308     return gpg_error (GPG_ERR_CARD);
1309
1310   if (app->assuan_ctx)
1311     {
1312       char line[ASSUAN_LINELENGTH];
1313
1314       if (15 + strlen (serialnobuf) > DIM(line)-1)
1315         return gpg_error (GPG_ERR_CARD);
1316       stpcpy (stpcpy (line, "SCD CHECKPIN "), serialnobuf); 
1317       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1318                                            NULL, NULL, NULL, NULL, NULL, NULL),
1319                           "SCD CHECKPIN");
1320     }
1321   else
1322     {
1323       rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
1324     }
1325
1326   if (rc)
1327     write_status (STATUS_SC_OP_FAILURE);
1328   return rc;
1329 }
1330
1331
1332
1333 void
1334 agent_clear_pin_cache (const char *sn)
1335 {
1336   char *cacheid = format_cacheid (sn);
1337   if (cacheid)
1338     {
1339       passphrase_clear_cache (NULL, cacheid, 0);
1340       xfree (cacheid);
1341     }
1342 }