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