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