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