New debugging optionhs, updates to the manual.
[gnupg.git] / agent / call-scd.c
1 /* call-scd.c - fork of the scdaemon to do SC operations
2  *      Copyright (C) 2001, 2002, 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 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #ifndef HAVE_W32_SYSTEM
32 #include <sys/wait.h>
33 #endif
34 #include <pth.h>
35
36 #include "agent.h"
37 #include <assuan.h>
38
39 #ifdef _POSIX_OPEN_MAX
40 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
41 #else
42 #define MAX_OPEN_FDS 20
43 #endif
44
45 /* Definition of module local data of the CTRL structure.  */
46 struct scd_local_s
47 {
48   assuan_context_t ctx; /* NULL or session context for the SCdaemon
49                            used with this connection. */
50   int locked;           /* This flag is used to assert proper use of
51                            start_scd and unlock_scd. */
52
53 };
54
55
56 /* Callback parameter for learn card */
57 struct learn_parm_s
58 {
59   void (*kpinfo_cb)(void*, const char *);
60   void *kpinfo_cb_arg;
61   void (*certinfo_cb)(void*, const char *);
62   void *certinfo_cb_arg;
63   void (*sinfo_cb)(void*, const char *, size_t, const char *);
64   void *sinfo_cb_arg;
65 };
66
67 struct inq_needpin_s 
68 {
69   assuan_context_t ctx;
70   int (*getpin_cb)(void *, const char *, char*, size_t);
71   void *getpin_cb_arg;
72 };
73
74
75 /* A Mutex used inside the start_scd function. */
76 static pth_mutex_t start_scd_lock;
77
78 /* A malloced string with the name of the socket to be used for
79    additional connections.  May be NULL if not provided by
80    SCdaemon. */
81 static char *socket_name;
82
83 /* The context of the primary connection.  This is also used as a flag
84    to indicate whether the scdaemon has been started. */
85 static assuan_context_t primary_scd_ctx;
86
87 /* To allow reuse of the primary connection, the following flag is set
88    to true if the primary context has been reset and is not in use by
89    any connection. */
90 static int primary_scd_ctx_reusable;
91
92
93
94 /* Local prototypes.  */
95 static assuan_error_t membuf_data_cb (void *opaque,
96                                       const void *buffer, size_t length);
97
98
99
100 \f
101 /* This function must be called once to initialize this module.  This
102    has to be done before a second thread is spawned.  We can't do the
103    static initialization because Pth emulation code might not be able
104    to do a static init; in particular, it is not possible for W32. */
105 void
106 initialize_module_call_scd (void)
107 {
108   static int initialized;
109
110   if (!initialized)
111     {
112       if (!pth_mutex_init (&start_scd_lock))
113         log_fatal ("error initializing mutex: %s\n", strerror (errno));
114       initialized = 1;
115     }
116 }
117
118
119 static void
120 dump_mutex_state (pth_mutex_t *m)
121 {
122   if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
123     log_printf ("not_initialized");
124   else if (!(m->mx_state & PTH_MUTEX_LOCKED))
125     log_printf ("not_locked");
126   else
127     log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
128 }
129
130
131 /* This function may be called to print infromation pertaining to the
132    current state of this module to the log. */
133 void
134 agent_scd_dump_state (void)
135 {
136   log_info ("agent_scd_dump_state: scd_lock=");
137   dump_mutex_state (&start_scd_lock);
138   log_printf ("\n");
139   log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
140             primary_scd_ctx, 
141             (long)assuan_get_pid (primary_scd_ctx),
142             primary_scd_ctx_reusable);
143   if (socket_name)
144     log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name);
145 }
146
147
148 /* The unlock_scd function shall be called after having accessed the
149    SCD.  It is currently not very useful but gives an opportunity to
150    keep track of connections currently calling SCD.  Note that the
151    "lock" operation is done by the start_scd() function which must be
152    called and error checked before any SCD operation.  CTRL is the
153    usual connection context and RC the error code to be passed trhough
154    the function. */
155 static int 
156 unlock_scd (ctrl_t ctrl, int rc)
157 {
158   if (ctrl->scd_local->locked != 1)
159     {
160       log_error ("unlock_scd: invalid lock count (%d)\n",
161                  ctrl->scd_local->locked);
162       if (!rc)
163         rc = gpg_error (GPG_ERR_INTERNAL);
164     }
165   ctrl->scd_local->locked = 0;
166   return rc;
167 }
168
169 /* To make sure we leave no secrets in our image after forking of the
170    scdaemon, we use this callback. */
171 static void
172 atfork_cb (void *opaque, int where)
173 {
174   if (!where)
175     gcry_control (GCRYCTL_TERM_SECMEM);
176 }
177
178
179 /* Fork off the SCdaemon if this has not already been done.  Lock the
180    daemon and make sure that a proper context has been setup in CTRL.
181    Thsi fucntion might also lock the daemon, which means that the
182    caller must call unlock_scd after this fucntion has returned
183    success and the actual Assuan transaction been done. */
184 static int
185 start_scd (ctrl_t ctrl)
186 {
187   gpg_error_t err = 0;
188   const char *pgmname;
189   assuan_context_t ctx;
190   const char *argv[3];
191   int no_close_list[3];
192   int i;
193   int rc;
194
195   if (opt.disable_scdaemon)
196     return gpg_error (GPG_ERR_NOT_SUPPORTED);
197
198   /* If this is the first call for this session, setup the local data
199      structure. */
200   if (!ctrl->scd_local)
201     {
202       ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
203       if (!ctrl->scd_local)
204         return gpg_error_from_errno (errno);
205     }
206
207
208   /* Assert that the lock count is as expected. */
209   if (ctrl->scd_local->locked)
210     {
211       log_error ("start_scd: invalid lock count (%d)\n",
212                  ctrl->scd_local->locked);
213       return gpg_error (GPG_ERR_INTERNAL);
214     }
215   ctrl->scd_local->locked++;
216
217   if (ctrl->scd_local->ctx)
218     return 0; /* Okay, the context is fine.  We used to test for an
219                  alive context here and do an disconnect.  How that we
220                  have a ticker function to check for it, it is easier
221                  not to check here but to let the connection run on an
222                  error instead. */
223
224
225   /* We need to protect the following code. */
226   if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
227     {
228       log_error ("failed to acquire the start_scd lock: %s\n",
229                  strerror (errno));
230       return gpg_error (GPG_ERR_INTERNAL);
231     }
232
233   /* Check whether the pipe server has already been started and in
234      this case either reuse a lingering pipe connection or establish a
235      new socket based one. */
236   if (primary_scd_ctx && primary_scd_ctx_reusable)
237     {
238       ctx = primary_scd_ctx;
239       primary_scd_ctx_reusable = 0;
240       if (opt.verbose)
241         log_info ("new connection to SCdaemon established (reusing)\n");
242       goto leave;
243     }
244
245   if (socket_name)
246     {
247       rc = assuan_socket_connect (&ctx, socket_name, 0);
248       if (rc)
249         {
250           log_error ("can't connect to socket `%s': %s\n",
251                      socket_name, assuan_strerror (rc));
252           err = gpg_error (GPG_ERR_NO_SCDAEMON);
253           goto leave;
254         }
255
256       if (opt.verbose)
257         log_info ("new connection to SCdaemon established\n");
258       goto leave;
259     }
260
261   if (primary_scd_ctx)
262     {
263       log_info ("SCdaemon is running but won't accept further connections\n");
264       err = gpg_error (GPG_ERR_NO_SCDAEMON);
265       goto leave;
266     }
267
268   /* Nope, it has not been started.  Fire it up now. */
269   if (opt.verbose)
270     log_info ("no running SCdaemon - starting it\n");
271       
272   if (fflush (NULL))
273     {
274       err = gpg_error (gpg_err_code_from_errno (errno));
275       log_error ("error flushing pending output: %s\n", strerror (errno));
276       goto leave;
277     }
278
279   if (!opt.scdaemon_program || !*opt.scdaemon_program)
280     opt.scdaemon_program = GNUPG_DEFAULT_SCDAEMON;
281   if ( !(pgmname = strrchr (opt.scdaemon_program, '/')))
282     pgmname = opt.scdaemon_program;
283   else
284     pgmname++;
285
286   argv[0] = pgmname;
287   argv[1] = "--multi-server";
288   argv[2] = NULL;
289
290   i=0;
291   if (!opt.running_detached)
292     {
293       if (log_get_fd () != -1)
294         no_close_list[i++] = log_get_fd ();
295       no_close_list[i++] = fileno (stderr);
296     }
297   no_close_list[i] = -1;
298
299   /* Connect to the pinentry and perform initial handshaking */
300   rc = assuan_pipe_connect2 (&ctx, opt.scdaemon_program, (char**)argv,
301                              no_close_list, atfork_cb, NULL);
302   if (rc)
303     {
304       log_error ("can't connect to the SCdaemon: %s\n",
305                  assuan_strerror (rc));
306       err = gpg_error (GPG_ERR_NO_SCDAEMON);
307       goto leave;
308     }
309
310   if (opt.verbose)
311     log_debug ("first connection to SCdaemon established\n");
312
313   /* Get the name of the additional socket opened by scdaemon. */
314   {
315     membuf_t data;
316     unsigned char *databuf;
317     size_t datalen;
318
319     xfree (socket_name);
320     socket_name = NULL;
321     init_membuf (&data, 256);
322     assuan_transact (ctx, "GETINFO socket_name",
323                      membuf_data_cb, &data, NULL, NULL, NULL, NULL);
324
325     databuf = get_membuf (&data, &datalen);
326     if (databuf && datalen)
327       {
328         socket_name = xtrymalloc (datalen + 1);
329         if (!socket_name)
330           log_error ("warning: can't store socket name: %s\n",
331                      strerror (errno));
332         else
333           {
334             memcpy (socket_name, databuf, datalen);
335             socket_name[datalen] = 0;
336             if (DBG_ASSUAN)
337               log_debug ("additional connections at `%s'\n", socket_name);
338           }
339       }
340     xfree (databuf);
341   }
342
343   /* Tell the scdaemon we want him to send us an event signal. */
344 #ifndef HAVE_W32_SYSTEM
345   {
346     char buf[100];
347
348     sprintf (buf, "OPTION event-signal=%d", SIGUSR2);
349     assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
350   }
351 #endif
352
353   primary_scd_ctx = ctx;
354   primary_scd_ctx_reusable = 0;
355
356  leave:
357   if (err)
358     {
359       unlock_scd (ctrl, err);
360     } 
361   else
362     {
363       ctrl->scd_local->ctx = ctx;
364     }
365   if (!pth_mutex_release (&start_scd_lock))
366     log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
367   return err;
368 }
369
370
371 /* Check whether the Scdaemon is still alive and clean it up if not. */
372 void
373 agent_scd_check_aliveness (void)
374 {
375   pth_event_t evt;
376   pid_t pid;
377   int rc;
378
379   if (!primary_scd_ctx)
380     return; /* No scdaemon running. */
381
382   /* This is not a critical function so we use a short timeout while
383      acquiring the lock.  */
384   evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
385   if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
386     {
387       if (pth_event_occurred (evt))
388         {
389           if (opt.verbose > 1)
390             log_info ("failed to acquire the start_scd lock while"
391                       " doing an aliveness check: %s\n", "timeout");
392         }
393       else
394         log_error ("failed to acquire the start_scd lock while"
395                    " doing an aliveness check: %s\n", strerror (errno));
396       pth_event_free (evt, PTH_FREE_THIS);
397       return;
398     }
399   pth_event_free (evt, PTH_FREE_THIS);
400
401   if (primary_scd_ctx)
402     {
403       pid = assuan_get_pid (primary_scd_ctx);
404       if (pid != (pid_t)(-1) && pid
405           && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
406         {
407           /* Okay, scdaemon died.  Disconnect the primary connection now
408              but take care that it won't do another wait. */
409           assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
410           assuan_disconnect (primary_scd_ctx);
411           primary_scd_ctx = NULL;
412           primary_scd_ctx_reusable = 0;
413           xfree (socket_name);
414           socket_name = NULL;
415         }
416     }
417
418   if (!pth_mutex_release (&start_scd_lock))
419     log_error ("failed to release the start_scd lock while"
420                " doing the aliveness check: %s\n", strerror (errno));
421 }
422
423
424
425 /* Reset the SCD if it has been used. */
426 int
427 agent_reset_scd (ctrl_t ctrl)
428 {
429   if (ctrl->scd_local)
430     {
431       if (ctrl->scd_local->ctx)
432         {
433           /* We can't disconnect the primary context because libassuan
434              does a waitpid on it and thus the system would hang.
435              Instead we send a reset and keep that connection for
436              reuse. */
437           if (ctrl->scd_local->ctx == primary_scd_ctx)
438             {
439               /* The RESET may fail for example if the scdaemon has
440                  already been terminated.  We need to set the reusable
441                  flag anyway to make sure that the aliveness check can
442                  clean it up. */
443               assuan_transact (primary_scd_ctx, "RESET",
444                                NULL, NULL, NULL, NULL, NULL, NULL);
445               primary_scd_ctx_reusable = 1;
446             }
447           else
448             assuan_disconnect (ctrl->scd_local->ctx);
449         }
450       xfree (ctrl->scd_local);
451       ctrl->scd_local = NULL;
452     }
453
454   return 0;
455 }
456
457
458 \f
459 /* Return a new malloced string by unescaping the string S.  Escaping
460    is percent escaping and '+'/space mapping.  A binary Nul will
461    silently be replaced by a 0xFF.  Function returns NULL to indicate
462    an out of memory status. */
463 static char *
464 unescape_status_string (const unsigned char *s)
465 {
466   char *buffer, *d;
467
468   buffer = d = xtrymalloc (strlen (s)+1);
469   if (!buffer)
470     return NULL;
471   while (*s)
472     {
473       if (*s == '%' && s[1] && s[2])
474         { 
475           s++;
476           *d = xtoi_2 (s);
477           if (!*d)
478             *d = '\xff';
479           d++;
480           s += 2;
481         }
482       else if (*s == '+')
483         {
484           *d++ = ' ';
485           s++;
486         }
487       else
488         *d++ = *s++;
489     }
490   *d = 0; 
491   return buffer;
492 }
493
494
495 \f
496 static AssuanError
497 learn_status_cb (void *opaque, const char *line)
498 {
499   struct learn_parm_s *parm = opaque;
500   const char *keyword = line;
501   int keywordlen;
502
503   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
504     ;
505   while (spacep (line))
506     line++;
507   if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
508     {
509       parm->certinfo_cb (parm->certinfo_cb_arg, line);
510     }
511   else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
512     {
513       parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
514     }
515   else if (keywordlen && *line)
516     {
517       parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
518     }
519   
520   return 0;
521 }
522
523 /* Perform the LEARN command and return a list of all private keys
524    stored on the card. */
525 int
526 agent_card_learn (ctrl_t ctrl,
527                   void (*kpinfo_cb)(void*, const char *),
528                   void *kpinfo_cb_arg,
529                   void (*certinfo_cb)(void*, const char *),
530                   void *certinfo_cb_arg,
531                   void (*sinfo_cb)(void*, const char *, size_t, const char *),
532                   void *sinfo_cb_arg)
533 {
534   int rc;
535   struct learn_parm_s parm;
536
537   rc = start_scd (ctrl);
538   if (rc)
539     return rc;
540
541   memset (&parm, 0, sizeof parm);
542   parm.kpinfo_cb = kpinfo_cb;
543   parm.kpinfo_cb_arg = kpinfo_cb_arg;
544   parm.certinfo_cb = certinfo_cb;
545   parm.certinfo_cb_arg = certinfo_cb_arg;
546   parm.sinfo_cb = sinfo_cb;
547   parm.sinfo_cb_arg = sinfo_cb_arg;
548   rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
549                         NULL, NULL, NULL, NULL,
550                         learn_status_cb, &parm);
551   if (rc)
552     return unlock_scd (ctrl, map_assuan_err (rc));
553
554   return unlock_scd (ctrl, 0);
555 }
556
557
558 \f
559 static AssuanError
560 get_serialno_cb (void *opaque, const char *line)
561 {
562   char **serialno = opaque;
563   const char *keyword = line;
564   const char *s;
565   int keywordlen, n;
566
567   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
568     ;
569   while (spacep (line))
570     line++;
571
572   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
573     {
574       if (*serialno)
575         return ASSUAN_Unexpected_Status;
576       for (n=0,s=line; hexdigitp (s); s++, n++)
577         ;
578       if (!n || (n&1)|| !(spacep (s) || !*s) )
579         return ASSUAN_Invalid_Status;
580       *serialno = xtrymalloc (n+1);
581       if (!*serialno)
582         return ASSUAN_Out_Of_Core;
583       memcpy (*serialno, line, n);
584       (*serialno)[n] = 0;
585     }
586   
587   return 0;
588 }
589
590 /* Return the serial number of the card or an appropriate error.  The
591    serial number is returned as a hexstring. */
592 int
593 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
594 {
595   int rc;
596   char *serialno = NULL;
597
598   rc = start_scd (ctrl);
599   if (rc)
600     return rc;
601
602   rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
603                         NULL, NULL, NULL, NULL,
604                         get_serialno_cb, &serialno);
605   if (rc)
606     {
607       xfree (serialno);
608       return unlock_scd (ctrl, map_assuan_err (rc));
609     }
610   *r_serialno = serialno;
611   return unlock_scd (ctrl, 0);
612 }
613
614
615
616 \f
617 static AssuanError
618 membuf_data_cb (void *opaque, const void *buffer, size_t length)
619 {
620   membuf_t *data = opaque;
621
622   if (buffer)
623     put_membuf (data, buffer, length);
624   return 0;
625 }
626   
627 /* Handle the NEEDPIN inquiry. */
628 static AssuanError
629 inq_needpin (void *opaque, const char *line)
630 {
631   struct inq_needpin_s *parm = opaque;
632   char *pin;
633   size_t pinlen;
634   int rc;
635
636   if (!(!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7])))
637     {
638       log_error ("unsupported inquiry `%s'\n", line);
639       return ASSUAN_Inquire_Unknown;
640     }
641   line += 7;
642   while (*line == ' ')
643     line++;
644
645   pinlen = 90;
646   pin = gcry_malloc_secure (pinlen);
647   if (!pin)
648     return ASSUAN_Out_Of_Core;
649
650   rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
651   if (rc)
652     rc = ASSUAN_Canceled;
653   if (!rc)
654     rc = assuan_send_data (parm->ctx, pin, pinlen);
655   xfree (pin);
656
657   return rc;
658 }
659
660
661
662 /* Create a signature using the current card */
663 int
664 agent_card_pksign (ctrl_t ctrl,
665                    const char *keyid,
666                    int (*getpin_cb)(void *, const char *, char*, size_t),
667                    void *getpin_cb_arg,
668                    const unsigned char *indata, size_t indatalen,
669                    char **r_buf, size_t *r_buflen)
670 {
671   int rc, i;
672   char *p, line[ASSUAN_LINELENGTH];
673   membuf_t data;
674   struct inq_needpin_s inqparm;
675   size_t len;
676   unsigned char *sigbuf;
677   size_t sigbuflen;
678
679   *r_buf = NULL;
680   rc = start_scd (ctrl);
681   if (rc)
682     return rc;
683
684   if (indatalen*2 + 50 > DIM(line))
685     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
686
687   sprintf (line, "SETDATA ");
688   p = line + strlen (line);
689   for (i=0; i < indatalen ; i++, p += 2 )
690     sprintf (p, "%02X", indata[i]);
691   rc = assuan_transact (ctrl->scd_local->ctx, line,
692                         NULL, NULL, NULL, NULL, NULL, NULL);
693   if (rc)
694     return unlock_scd (ctrl, map_assuan_err (rc));
695
696   init_membuf (&data, 1024);
697   inqparm.ctx = ctrl->scd_local->ctx;
698   inqparm.getpin_cb = getpin_cb;
699   inqparm.getpin_cb_arg = getpin_cb_arg;
700   snprintf (line, DIM(line)-1, 
701             ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
702   line[DIM(line)-1] = 0;
703   rc = assuan_transact (ctrl->scd_local->ctx, line,
704                         membuf_data_cb, &data,
705                         inq_needpin, &inqparm,
706                         NULL, NULL);
707   if (rc)
708     {
709       xfree (get_membuf (&data, &len));
710       return unlock_scd (ctrl, map_assuan_err (rc));
711     }
712   sigbuf = get_membuf (&data, &sigbuflen);
713
714   /* Create an S-expression from it which is formatted like this:
715      "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
716   *r_buflen = 21 + 11 + sigbuflen + 4;
717   *r_buf = xtrymalloc (*r_buflen);
718   if (!*r_buf)
719     {
720       gpg_error_t tmperr = out_of_core ();
721       xfree (*r_buf);
722       return unlock_scd (ctrl, tmperr);
723     }
724   p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" );
725   sprintf (p, "%u:", (unsigned int)sigbuflen);
726   p += strlen (p);
727   memcpy (p, sigbuf, sigbuflen);
728   p += sigbuflen;
729   strcpy (p, ")))");
730   xfree (sigbuf);
731
732   assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
733   return unlock_scd (ctrl, 0);
734 }
735
736 /* Decipher INDATA using the current card. Note that the returned value is */
737 int
738 agent_card_pkdecrypt (ctrl_t ctrl,
739                       const char *keyid,
740                       int (*getpin_cb)(void *, const char *, char*, size_t),
741                       void *getpin_cb_arg,
742                       const unsigned char *indata, size_t indatalen,
743                       char **r_buf, size_t *r_buflen)
744 {
745   int rc, i;
746   char *p, line[ASSUAN_LINELENGTH];
747   membuf_t data;
748   struct inq_needpin_s inqparm;
749   size_t len;
750
751   *r_buf = NULL;
752   rc = start_scd (ctrl);
753   if (rc)
754     return rc;
755
756   /* FIXME: use secure memory where appropriate */
757   if (indatalen*2 + 50 > DIM(line))
758     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
759
760   sprintf (line, "SETDATA ");
761   p = line + strlen (line);
762   for (i=0; i < indatalen ; i++, p += 2 )
763     sprintf (p, "%02X", indata[i]);
764   rc = assuan_transact (ctrl->scd_local->ctx, line,
765                         NULL, NULL, NULL, NULL, NULL, NULL);
766   if (rc)
767     return unlock_scd (ctrl, map_assuan_err (rc));
768
769   init_membuf (&data, 1024);
770   inqparm.ctx = ctrl->scd_local->ctx;
771   inqparm.getpin_cb = getpin_cb;
772   inqparm.getpin_cb_arg = getpin_cb_arg;
773   snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
774   line[DIM(line)-1] = 0;
775   rc = assuan_transact (ctrl->scd_local->ctx, line,
776                         membuf_data_cb, &data,
777                         inq_needpin, &inqparm,
778                         NULL, NULL);
779   if (rc)
780     {
781       xfree (get_membuf (&data, &len));
782       return unlock_scd (ctrl, map_assuan_err (rc));
783     }
784   *r_buf = get_membuf (&data, r_buflen);
785   if (!*r_buf)
786     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
787
788   return unlock_scd (ctrl, 0);
789 }
790
791
792 \f
793 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
794 int
795 agent_card_readcert (ctrl_t ctrl,
796                      const char *id, char **r_buf, size_t *r_buflen)
797 {
798   int rc;
799   char line[ASSUAN_LINELENGTH];
800   membuf_t data;
801   size_t len;
802
803   *r_buf = NULL;
804   rc = start_scd (ctrl);
805   if (rc)
806     return rc;
807
808   init_membuf (&data, 1024);
809   snprintf (line, DIM(line)-1, "READCERT %s", id);
810   line[DIM(line)-1] = 0;
811   rc = assuan_transact (ctrl->scd_local->ctx, line,
812                         membuf_data_cb, &data,
813                         NULL, NULL,
814                         NULL, NULL);
815   if (rc)
816     {
817       xfree (get_membuf (&data, &len));
818       return unlock_scd (ctrl, map_assuan_err (rc));
819     }
820   *r_buf = get_membuf (&data, r_buflen);
821   if (!*r_buf)
822     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
823
824   return unlock_scd (ctrl, 0);
825 }
826
827
828 \f
829 /* Read a key with ID and return it in an allocate buffer pointed to
830    by r_BUF as a valid S-expression. */
831 int
832 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
833 {
834   int rc;
835   char line[ASSUAN_LINELENGTH];
836   membuf_t data;
837   size_t len, buflen;
838
839   *r_buf = NULL;
840   rc = start_scd (ctrl);
841   if (rc)
842     return rc;
843
844   init_membuf (&data, 1024);
845   snprintf (line, DIM(line)-1, "READKEY %s", id);
846   line[DIM(line)-1] = 0;
847   rc = assuan_transact (ctrl->scd_local->ctx, line,
848                         membuf_data_cb, &data,
849                         NULL, NULL,
850                         NULL, NULL);
851   if (rc)
852     {
853       xfree (get_membuf (&data, &len));
854       return unlock_scd (ctrl, map_assuan_err (rc));
855     }
856   *r_buf = get_membuf (&data, &buflen);
857   if (!*r_buf)
858     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
859
860   if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
861     {
862       xfree (*r_buf); *r_buf = NULL;
863       return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
864     }
865
866   return unlock_scd (ctrl, 0);
867 }
868
869
870 \f
871 /* Type used with the card_getattr_cb.  */
872 struct card_getattr_parm_s {
873   const char *keyword;  /* Keyword to look for.  */
874   size_t keywordlen;    /* strlen of KEYWORD.  */
875   char *data;           /* Malloced and unescaped data.  */
876   int error;            /* ERRNO value or 0 on success. */
877 };
878
879 /* Callback function for agent_card_getattr.  */
880 static assuan_error_t
881 card_getattr_cb (void *opaque, const char *line)
882 {
883   struct card_getattr_parm_s *parm = opaque;
884   const char *keyword = line;
885   int keywordlen;
886
887   if (parm->data)
888     return 0; /* We want only the first occurrence.  */
889
890   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
891     ;
892   while (spacep (line))
893     line++;
894
895   if (keywordlen == parm->keywordlen
896       && !memcmp (keyword, parm->keyword, keywordlen))
897     {
898       parm->data = unescape_status_string (line);
899       if (!parm->data)
900         parm->error = errno;
901     }
902   
903   return 0;
904 }
905
906
907 /* Call the agent to retrieve a single line data object. On success
908    the object is malloced and stored at RESULT; it is guaranteed that
909    NULL is never stored in this case.  On error an error code is
910    returned and NULL stored at RESULT. */
911 gpg_error_t
912 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
913 {
914   int err;
915   struct card_getattr_parm_s parm;
916   char line[ASSUAN_LINELENGTH];
917
918   *result = NULL;
919
920   if (!*name)
921     return gpg_error (GPG_ERR_INV_VALUE);
922
923   memset (&parm, 0, sizeof parm);
924   parm.keyword = name;
925   parm.keywordlen = strlen (name);
926
927   /* We assume that NAME does not need escaping. */
928   if (8 + strlen (name) > DIM(line)-1)
929     return gpg_error (GPG_ERR_TOO_LARGE);
930   stpcpy (stpcpy (line, "GETATTR "), name); 
931
932   err = start_scd (ctrl);
933   if (err)
934     return err;
935
936   err = map_assuan_err (assuan_transact (ctrl->scd_local->ctx, line,
937                                          NULL, NULL, NULL, NULL,
938                                          card_getattr_cb, &parm));
939   if (!err && parm.error)
940     err = gpg_error_from_errno (parm.error);
941   
942   if (!err && !parm.data)
943     err = gpg_error (GPG_ERR_NO_DATA);
944   
945   if (!err)
946     *result = parm.data;
947   else
948     xfree (parm.data);
949
950   return unlock_scd (ctrl, err);
951 }
952
953
954
955 \f
956 static AssuanError
957 pass_status_thru (void *opaque, const char *line)
958 {
959   ASSUAN_CONTEXT ctx = opaque;
960   char keyword[200];
961   int i;
962
963   for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
964     keyword[i] = *line;
965   keyword[i] = 0;
966   /* truncate any remaining keyword stuff. */
967   for (; *line && !spacep (line); line++)
968     ;
969   while (spacep (line))
970     line++;
971
972   assuan_write_status (ctx, keyword, line);
973   return 0;
974 }
975
976 static AssuanError
977 pass_data_thru (void *opaque, const void *buffer, size_t length)
978 {
979   ASSUAN_CONTEXT ctx = opaque;
980
981   assuan_send_data (ctx, buffer, length);
982   return 0;
983 }
984
985
986 /* Send the line CMDLINE with command for the SCDdaemon to it and send
987    all status messages back.  This command is used as a general quoting
988    mechanism to pass everything verbatim to SCDAEMOPN.  The PIN
989    inquirey is handled inside gpg-agent. */
990 int
991 agent_card_scd (ctrl_t ctrl, const char *cmdline,
992                 int (*getpin_cb)(void *, const char *, char*, size_t),
993                 void *getpin_cb_arg, void *assuan_context)
994 {
995   int rc;
996   struct inq_needpin_s inqparm;
997
998   rc = start_scd (ctrl);
999   if (rc)
1000     return rc;
1001
1002   inqparm.ctx = ctrl->scd_local->ctx;
1003   inqparm.getpin_cb = getpin_cb;
1004   inqparm.getpin_cb_arg = getpin_cb_arg;
1005   rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1006                         pass_data_thru, assuan_context,
1007                         inq_needpin, &inqparm,
1008                         pass_status_thru, assuan_context);
1009   if (rc)
1010     {
1011       return unlock_scd (ctrl, map_assuan_err (rc));
1012     }
1013
1014   return unlock_scd (ctrl, 0);
1015 }
1016
1017