* call-scd.c (inq_needpin): Skip leading spaces in of PIN
[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   while (*line == ' ')
605     line++;
606
607   pinlen = 90;
608   pin = gcry_malloc_secure (pinlen);
609   if (!pin)
610     return ASSUAN_Out_Of_Core;
611
612   rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
613   if (rc)
614     rc = ASSUAN_Canceled;
615   if (!rc)
616     rc = assuan_send_data (parm->ctx, pin, pinlen);
617   xfree (pin);
618
619   return rc;
620 }
621
622
623
624 /* Create a signature using the current card */
625 int
626 agent_card_pksign (ctrl_t ctrl,
627                    const char *keyid,
628                    int (*getpin_cb)(void *, const char *, char*, size_t),
629                    void *getpin_cb_arg,
630                    const unsigned char *indata, size_t indatalen,
631                    char **r_buf, size_t *r_buflen)
632 {
633   int rc, i;
634   char *p, line[ASSUAN_LINELENGTH];
635   membuf_t data;
636   struct inq_needpin_s inqparm;
637   size_t len;
638   unsigned char *sigbuf;
639   size_t sigbuflen;
640
641   *r_buf = NULL;
642   rc = start_scd (ctrl);
643   if (rc)
644     return rc;
645
646   if (indatalen*2 + 50 > DIM(line))
647     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
648
649   sprintf (line, "SETDATA ");
650   p = line + strlen (line);
651   for (i=0; i < indatalen ; i++, p += 2 )
652     sprintf (p, "%02X", indata[i]);
653   rc = assuan_transact (ctrl->scd_local->ctx, line,
654                         NULL, NULL, NULL, NULL, NULL, NULL);
655   if (rc)
656     return unlock_scd (ctrl, map_assuan_err (rc));
657
658   init_membuf (&data, 1024);
659   inqparm.ctx = ctrl->scd_local->ctx;
660   inqparm.getpin_cb = getpin_cb;
661   inqparm.getpin_cb_arg = getpin_cb_arg;
662   snprintf (line, DIM(line)-1, 
663             ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
664   line[DIM(line)-1] = 0;
665   rc = assuan_transact (ctrl->scd_local->ctx, line,
666                         membuf_data_cb, &data,
667                         inq_needpin, &inqparm,
668                         NULL, NULL);
669   if (rc)
670     {
671       xfree (get_membuf (&data, &len));
672       return unlock_scd (ctrl, map_assuan_err (rc));
673     }
674   sigbuf = get_membuf (&data, &sigbuflen);
675
676   /* Create an S-expression from it which is formatted like this:
677      "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
678   *r_buflen = 21 + 11 + sigbuflen + 4;
679   *r_buf = xtrymalloc (*r_buflen);
680   if (!*r_buf)
681     {
682       gpg_error_t tmperr = out_of_core ();
683       xfree (*r_buf);
684       return unlock_scd (ctrl, tmperr);
685     }
686   p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" );
687   sprintf (p, "%u:", (unsigned int)sigbuflen);
688   p += strlen (p);
689   memcpy (p, sigbuf, sigbuflen);
690   p += sigbuflen;
691   strcpy (p, ")))");
692   xfree (sigbuf);
693
694   assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
695   return unlock_scd (ctrl, 0);
696 }
697
698 /* Decipher INDATA using the current card. Note that the returned value is */
699 int
700 agent_card_pkdecrypt (ctrl_t ctrl,
701                       const char *keyid,
702                       int (*getpin_cb)(void *, const char *, char*, size_t),
703                       void *getpin_cb_arg,
704                       const unsigned char *indata, size_t indatalen,
705                       char **r_buf, size_t *r_buflen)
706 {
707   int rc, i;
708   char *p, line[ASSUAN_LINELENGTH];
709   membuf_t data;
710   struct inq_needpin_s inqparm;
711   size_t len;
712
713   *r_buf = NULL;
714   rc = start_scd (ctrl);
715   if (rc)
716     return rc;
717
718   /* FIXME: use secure memory where appropriate */
719   if (indatalen*2 + 50 > DIM(line))
720     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
721
722   sprintf (line, "SETDATA ");
723   p = line + strlen (line);
724   for (i=0; i < indatalen ; i++, p += 2 )
725     sprintf (p, "%02X", indata[i]);
726   rc = assuan_transact (ctrl->scd_local->ctx, line,
727                         NULL, NULL, NULL, NULL, NULL, NULL);
728   if (rc)
729     return unlock_scd (ctrl, map_assuan_err (rc));
730
731   init_membuf (&data, 1024);
732   inqparm.ctx = ctrl->scd_local->ctx;
733   inqparm.getpin_cb = getpin_cb;
734   inqparm.getpin_cb_arg = getpin_cb_arg;
735   snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
736   line[DIM(line)-1] = 0;
737   rc = assuan_transact (ctrl->scd_local->ctx, line,
738                         membuf_data_cb, &data,
739                         inq_needpin, &inqparm,
740                         NULL, NULL);
741   if (rc)
742     {
743       xfree (get_membuf (&data, &len));
744       return unlock_scd (ctrl, map_assuan_err (rc));
745     }
746   *r_buf = get_membuf (&data, r_buflen);
747   if (!*r_buf)
748     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
749
750   return unlock_scd (ctrl, 0);
751 }
752
753
754 \f
755 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
756 int
757 agent_card_readcert (ctrl_t ctrl,
758                      const char *id, char **r_buf, size_t *r_buflen)
759 {
760   int rc;
761   char line[ASSUAN_LINELENGTH];
762   membuf_t data;
763   size_t len;
764
765   *r_buf = NULL;
766   rc = start_scd (ctrl);
767   if (rc)
768     return rc;
769
770   init_membuf (&data, 1024);
771   snprintf (line, DIM(line)-1, "READCERT %s", id);
772   line[DIM(line)-1] = 0;
773   rc = assuan_transact (ctrl->scd_local->ctx, line,
774                         membuf_data_cb, &data,
775                         NULL, NULL,
776                         NULL, NULL);
777   if (rc)
778     {
779       xfree (get_membuf (&data, &len));
780       return unlock_scd (ctrl, map_assuan_err (rc));
781     }
782   *r_buf = get_membuf (&data, r_buflen);
783   if (!*r_buf)
784     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
785
786   return unlock_scd (ctrl, 0);
787 }
788
789
790 \f
791 /* Read a key with ID and return it in an allocate buffer pointed to
792    by r_BUF as a valid S-expression. */
793 int
794 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
795 {
796   int rc;
797   char line[ASSUAN_LINELENGTH];
798   membuf_t data;
799   size_t len, buflen;
800
801   *r_buf = NULL;
802   rc = start_scd (ctrl);
803   if (rc)
804     return rc;
805
806   init_membuf (&data, 1024);
807   snprintf (line, DIM(line)-1, "READKEY %s", id);
808   line[DIM(line)-1] = 0;
809   rc = assuan_transact (ctrl->scd_local->ctx, line,
810                         membuf_data_cb, &data,
811                         NULL, NULL,
812                         NULL, NULL);
813   if (rc)
814     {
815       xfree (get_membuf (&data, &len));
816       return unlock_scd (ctrl, map_assuan_err (rc));
817     }
818   *r_buf = get_membuf (&data, &buflen);
819   if (!*r_buf)
820     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
821
822   if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
823     {
824       xfree (*r_buf); *r_buf = NULL;
825       return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
826     }
827
828   return unlock_scd (ctrl, 0);
829 }
830
831
832 \f
833 /* Type used with the card_getattr_cb.  */
834 struct card_getattr_parm_s {
835   const char *keyword;  /* Keyword to look for.  */
836   size_t keywordlen;    /* strlen of KEYWORD.  */
837   char *data;           /* Malloced and unescaped data.  */
838   int error;            /* ERRNO value or 0 on success. */
839 };
840
841 /* Callback function for agent_card_getattr.  */
842 static assuan_error_t
843 card_getattr_cb (void *opaque, const char *line)
844 {
845   struct card_getattr_parm_s *parm = opaque;
846   const char *keyword = line;
847   int keywordlen;
848
849   if (parm->data)
850     return 0; /* We want only the first occurrence.  */
851
852   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
853     ;
854   while (spacep (line))
855     line++;
856
857   if (keywordlen == parm->keywordlen
858       && !memcmp (keyword, parm->keyword, keywordlen))
859     {
860       parm->data = unescape_status_string (line);
861       if (!parm->data)
862         parm->error = errno;
863     }
864   
865   return 0;
866 }
867
868
869 /* Call the agent to retrieve a single line data object. On success
870    the object is malloced and stored at RESULT; it is guaranteed that
871    NULL is never stored in this case.  On error an error code is
872    returned and NULL stored at RESULT. */
873 gpg_error_t
874 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
875 {
876   int err;
877   struct card_getattr_parm_s parm;
878   char line[ASSUAN_LINELENGTH];
879
880   *result = NULL;
881
882   if (!*name)
883     return gpg_error (GPG_ERR_INV_VALUE);
884
885   memset (&parm, 0, sizeof parm);
886   parm.keyword = name;
887   parm.keywordlen = strlen (name);
888
889   /* We assume that NAME does not need escaping. */
890   if (8 + strlen (name) > DIM(line)-1)
891     return gpg_error (GPG_ERR_TOO_LARGE);
892   stpcpy (stpcpy (line, "GETATTR "), name); 
893
894   err = start_scd (ctrl);
895   if (err)
896     return err;
897
898   err = map_assuan_err (assuan_transact (ctrl->scd_local->ctx, line,
899                                          NULL, NULL, NULL, NULL,
900                                          card_getattr_cb, &parm));
901   if (!err && parm.error)
902     err = gpg_error_from_errno (parm.error);
903   
904   if (!err && !parm.data)
905     err = gpg_error (GPG_ERR_NO_DATA);
906   
907   if (!err)
908     *result = parm.data;
909   else
910     xfree (parm.data);
911
912   return unlock_scd (ctrl, err);
913 }
914
915
916
917 \f
918 static AssuanError
919 pass_status_thru (void *opaque, const char *line)
920 {
921   ASSUAN_CONTEXT ctx = opaque;
922   char keyword[200];
923   int i;
924
925   for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
926     keyword[i] = *line;
927   keyword[i] = 0;
928   /* truncate any remaining keyword stuff. */
929   for (; *line && !spacep (line); line++)
930     ;
931   while (spacep (line))
932     line++;
933
934   assuan_write_status (ctx, keyword, line);
935   return 0;
936 }
937
938 static AssuanError
939 pass_data_thru (void *opaque, const void *buffer, size_t length)
940 {
941   ASSUAN_CONTEXT ctx = opaque;
942
943   assuan_send_data (ctx, buffer, length);
944   return 0;
945 }
946
947
948 /* Send the line CMDLINE with command for the SCDdaemon to it and send
949    all status messages back.  This command is used as a general quoting
950    mechanism to pass everything verbatim to SCDAEMOPN.  The PIN
951    inquirey is handled inside gpg-agent. */
952 int
953 agent_card_scd (ctrl_t ctrl, const char *cmdline,
954                 int (*getpin_cb)(void *, const char *, char*, size_t),
955                 void *getpin_cb_arg, void *assuan_context)
956 {
957   int rc;
958   struct inq_needpin_s inqparm;
959
960   rc = start_scd (ctrl);
961   if (rc)
962     return rc;
963
964   inqparm.ctx = ctrl->scd_local->ctx;
965   inqparm.getpin_cb = getpin_cb;
966   inqparm.getpin_cb_arg = getpin_cb_arg;
967   rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
968                         pass_data_thru, assuan_context,
969                         inq_needpin, &inqparm,
970                         pass_status_thru, assuan_context);
971   if (rc)
972     {
973       return unlock_scd (ctrl, map_assuan_err (rc));
974     }
975
976   return unlock_scd (ctrl, 0);
977 }
978
979