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