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