b62ab97ea0094cfbb8931acd5956631783d4abe0
[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_module_name (GNUPG_MODULE_NAME_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 #ifdef HAVE_W32_SYSTEM
428 #warning Need to implement an alive test for scdaemon
429 #else
430       if (pid != (pid_t)(-1) && pid
431           && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
432         {
433           /* Okay, scdaemon died.  Disconnect the primary connection
434              now but take care that it won't do another wait. Also
435              cleanup all other connections and release their
436              resources.  The next use will start a new daemon then.
437              Due to the use of the START_SCD_LOCAL we are sure that
438              none of these context are actually in use. */
439           struct scd_local_s *sl;
440
441           assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
442           assuan_disconnect (primary_scd_ctx);
443
444           for (sl=scd_local_list; sl; sl = sl->next_local)
445             {
446               if (sl->ctx)
447                 {
448                   if (sl->ctx != primary_scd_ctx)
449                     assuan_disconnect (sl->ctx);
450                   sl->ctx = NULL;
451                 }
452             }
453           
454           primary_scd_ctx = NULL;
455           primary_scd_ctx_reusable = 0;
456
457           xfree (socket_name);
458           socket_name = NULL;
459         }
460 #endif
461     }
462
463   if (!pth_mutex_release (&start_scd_lock))
464     log_error ("failed to release the start_scd lock while"
465                " doing the aliveness check: %s\n", strerror (errno));
466 }
467
468
469
470 /* Reset the SCD if it has been used.  Actually it is not a reset but
471    a cleanup of resources used by the current connection. */
472 int
473 agent_reset_scd (ctrl_t ctrl)
474 {
475   if (ctrl->scd_local)
476     {
477       if (ctrl->scd_local->ctx)
478         {
479           /* We can't disconnect the primary context because libassuan
480              does a waitpid on it and thus the system would hang.
481              Instead we send a reset and keep that connection for
482              reuse. */
483           if (ctrl->scd_local->ctx == primary_scd_ctx)
484             {
485               /* Send a RESTART to the SCD.  This is required for the
486                  primary connection as a kind of virtual EOF; we don't
487                  have another way to tell it that the next command
488                  should be viewed as if a new connection has been
489                  made.  For the non-primary connections this is not
490                  needed as we simply close the socket.  We don't check
491                  for an error here because the RESTART may fail for
492                  example if the scdaemon has already been terminated.
493                  Anyway, we need to set the reusable flag to make sure
494                  that the aliveness check can clean it up. */
495               assuan_transact (primary_scd_ctx, "RESTART",
496                                NULL, NULL, NULL, NULL, NULL, NULL);
497               primary_scd_ctx_reusable = 1;
498             }
499           else
500             assuan_disconnect (ctrl->scd_local->ctx);
501           ctrl->scd_local->ctx = NULL;
502         }
503       
504       /* Remove the local context from our list and release it. */
505       if (!scd_local_list)
506         BUG ();
507       else if (scd_local_list == ctrl->scd_local)
508         scd_local_list = ctrl->scd_local->next_local;
509       else
510         {
511           struct scd_local_s *sl;
512       
513           for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
514             if (sl->next_local == ctrl->scd_local)
515               break;
516           if (!sl->next_local)
517             BUG ();
518           sl->next_local = ctrl->scd_local->next_local;
519         }
520       xfree (ctrl->scd_local);
521       ctrl->scd_local = NULL;
522     }
523
524   return 0;
525 }
526
527
528 \f
529 /* Return a new malloced string by unescaping the string S.  Escaping
530    is percent escaping and '+'/space mapping.  A binary Nul will
531    silently be replaced by a 0xFF.  Function returns NULL to indicate
532    an out of memory status. */
533 static char *
534 unescape_status_string (const unsigned char *s)
535 {
536   char *buffer, *d;
537
538   buffer = d = xtrymalloc (strlen ((const char*)s)+1);
539   if (!buffer)
540     return NULL;
541   while (*s)
542     {
543       if (*s == '%' && s[1] && s[2])
544         { 
545           s++;
546           *d = xtoi_2 (s);
547           if (!*d)
548             *d = '\xff';
549           d++;
550           s += 2;
551         }
552       else if (*s == '+')
553         {
554           *d++ = ' ';
555           s++;
556         }
557       else
558         *d++ = *s++;
559     }
560   *d = 0; 
561   return buffer;
562 }
563
564
565 \f
566 static int
567 learn_status_cb (void *opaque, const char *line)
568 {
569   struct learn_parm_s *parm = opaque;
570   const char *keyword = line;
571   int keywordlen;
572
573   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
574     ;
575   while (spacep (line))
576     line++;
577   if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
578     {
579       parm->certinfo_cb (parm->certinfo_cb_arg, line);
580     }
581   else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
582     {
583       parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
584     }
585   else if (keywordlen && *line)
586     {
587       parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
588     }
589   
590   return 0;
591 }
592
593 /* Perform the LEARN command and return a list of all private keys
594    stored on the card. */
595 int
596 agent_card_learn (ctrl_t ctrl,
597                   void (*kpinfo_cb)(void*, const char *),
598                   void *kpinfo_cb_arg,
599                   void (*certinfo_cb)(void*, const char *),
600                   void *certinfo_cb_arg,
601                   void (*sinfo_cb)(void*, const char *, size_t, const char *),
602                   void *sinfo_cb_arg)
603 {
604   int rc;
605   struct learn_parm_s parm;
606
607   rc = start_scd (ctrl);
608   if (rc)
609     return rc;
610
611   memset (&parm, 0, sizeof parm);
612   parm.kpinfo_cb = kpinfo_cb;
613   parm.kpinfo_cb_arg = kpinfo_cb_arg;
614   parm.certinfo_cb = certinfo_cb;
615   parm.certinfo_cb_arg = certinfo_cb_arg;
616   parm.sinfo_cb = sinfo_cb;
617   parm.sinfo_cb_arg = sinfo_cb_arg;
618   rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
619                         NULL, NULL, NULL, NULL,
620                         learn_status_cb, &parm);
621   if (rc)
622     return unlock_scd (ctrl, rc);
623
624   return unlock_scd (ctrl, 0);
625 }
626
627
628 \f
629 static int
630 get_serialno_cb (void *opaque, const char *line)
631 {
632   char **serialno = opaque;
633   const char *keyword = line;
634   const char *s;
635   int keywordlen, n;
636
637   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
638     ;
639   while (spacep (line))
640     line++;
641
642   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
643     {
644       if (*serialno)
645         return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
646       for (n=0,s=line; hexdigitp (s); s++, n++)
647         ;
648       if (!n || (n&1)|| !(spacep (s) || !*s) )
649         return gpg_error (GPG_ERR_ASS_PARAMETER);
650       *serialno = xtrymalloc (n+1);
651       if (!*serialno)
652         return out_of_core ();
653       memcpy (*serialno, line, n);
654       (*serialno)[n] = 0;
655     }
656   
657   return 0;
658 }
659
660 /* Return the serial number of the card or an appropriate error.  The
661    serial number is returned as a hexstring. */
662 int
663 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
664 {
665   int rc;
666   char *serialno = NULL;
667
668   rc = start_scd (ctrl);
669   if (rc)
670     return rc;
671
672   rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
673                         NULL, NULL, NULL, NULL,
674                         get_serialno_cb, &serialno);
675   if (rc)
676     {
677       xfree (serialno);
678       return unlock_scd (ctrl, rc);
679     }
680   *r_serialno = serialno;
681   return unlock_scd (ctrl, 0);
682 }
683
684
685
686 \f
687 static int
688 membuf_data_cb (void *opaque, const void *buffer, size_t length)
689 {
690   membuf_t *data = opaque;
691
692   if (buffer)
693     put_membuf (data, buffer, length);
694   return 0;
695 }
696   
697 /* Handle the NEEDPIN inquiry. */
698 static int
699 inq_needpin (void *opaque, const char *line)
700 {
701   struct inq_needpin_s *parm = opaque;
702   char *pin;
703   size_t pinlen;
704   int rc;
705
706   if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
707     {
708       line += 7;
709       while (*line == ' ')
710         line++;
711       
712       pinlen = 90;
713       pin = gcry_malloc_secure (pinlen);
714       if (!pin)
715         return out_of_core ();
716
717       rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
718       if (!rc)
719         rc = assuan_send_data (parm->ctx, pin, pinlen);
720       xfree (pin);
721     }
722   else if (!strncmp (line, "POPUPKEYPADPROMPT", 17)
723            && (line[17] == ' ' || !line[17]))
724     {
725       line += 17;
726       while (*line == ' ')
727         line++;
728       
729       rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
730     }
731   else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19)
732            && (line[19] == ' ' || !line[19]))
733     {
734       rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
735     }
736   else
737     {
738       log_error ("unsupported inquiry `%s'\n", line);
739       rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
740     }
741
742   return rc;
743 }
744
745
746
747 /* Create a signature using the current card */
748 int
749 agent_card_pksign (ctrl_t ctrl,
750                    const char *keyid,
751                    int (*getpin_cb)(void *, const char *, char*, size_t),
752                    void *getpin_cb_arg,
753                    const unsigned char *indata, size_t indatalen,
754                    unsigned char **r_buf, size_t *r_buflen)
755 {
756   int rc, i;
757   char *p, line[ASSUAN_LINELENGTH];
758   membuf_t data;
759   struct inq_needpin_s inqparm;
760   size_t len;
761   unsigned char *sigbuf;
762   size_t sigbuflen;
763
764   *r_buf = NULL;
765   rc = start_scd (ctrl);
766   if (rc)
767     return rc;
768
769   if (indatalen*2 + 50 > DIM(line))
770     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
771
772   sprintf (line, "SETDATA ");
773   p = line + strlen (line);
774   for (i=0; i < indatalen ; i++, p += 2 )
775     sprintf (p, "%02X", indata[i]);
776   rc = assuan_transact (ctrl->scd_local->ctx, line,
777                         NULL, NULL, NULL, NULL, NULL, NULL);
778   if (rc)
779     return unlock_scd (ctrl, rc);
780
781   init_membuf (&data, 1024);
782   inqparm.ctx = ctrl->scd_local->ctx;
783   inqparm.getpin_cb = getpin_cb;
784   inqparm.getpin_cb_arg = getpin_cb_arg;
785   snprintf (line, DIM(line)-1, 
786             ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
787   line[DIM(line)-1] = 0;
788   rc = assuan_transact (ctrl->scd_local->ctx, line,
789                         membuf_data_cb, &data,
790                         inq_needpin, &inqparm,
791                         NULL, NULL);
792   if (rc)
793     {
794       xfree (get_membuf (&data, &len));
795       return unlock_scd (ctrl, rc);
796     }
797   sigbuf = get_membuf (&data, &sigbuflen);
798
799   /* Create an S-expression from it which is formatted like this:
800      "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
801   *r_buflen = 21 + 11 + sigbuflen + 4;
802   p = xtrymalloc (*r_buflen);
803   *r_buf = (unsigned char*)p;
804   if (!p)
805     return unlock_scd (ctrl, out_of_core ());
806   p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
807   sprintf (p, "%u:", (unsigned int)sigbuflen);
808   p += strlen (p);
809   memcpy (p, sigbuf, sigbuflen);
810   p += sigbuflen;
811   strcpy (p, ")))");
812   xfree (sigbuf);
813
814   assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
815   return unlock_scd (ctrl, 0);
816 }
817
818 /* Decipher INDATA using the current card. Note that the returned value is */
819 int
820 agent_card_pkdecrypt (ctrl_t ctrl,
821                       const char *keyid,
822                       int (*getpin_cb)(void *, const char *, char*, size_t),
823                       void *getpin_cb_arg,
824                       const unsigned char *indata, size_t indatalen,
825                       char **r_buf, size_t *r_buflen)
826 {
827   int rc, i;
828   char *p, line[ASSUAN_LINELENGTH];
829   membuf_t data;
830   struct inq_needpin_s inqparm;
831   size_t len;
832
833   *r_buf = NULL;
834   rc = start_scd (ctrl);
835   if (rc)
836     return rc;
837
838   /* FIXME: use secure memory where appropriate */
839   if (indatalen*2 + 50 > DIM(line))
840     return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
841
842   sprintf (line, "SETDATA ");
843   p = line + strlen (line);
844   for (i=0; i < indatalen ; i++, p += 2 )
845     sprintf (p, "%02X", indata[i]);
846   rc = assuan_transact (ctrl->scd_local->ctx, line,
847                         NULL, NULL, NULL, NULL, NULL, NULL);
848   if (rc)
849     return unlock_scd (ctrl, rc);
850
851   init_membuf (&data, 1024);
852   inqparm.ctx = ctrl->scd_local->ctx;
853   inqparm.getpin_cb = getpin_cb;
854   inqparm.getpin_cb_arg = getpin_cb_arg;
855   snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
856   line[DIM(line)-1] = 0;
857   rc = assuan_transact (ctrl->scd_local->ctx, line,
858                         membuf_data_cb, &data,
859                         inq_needpin, &inqparm,
860                         NULL, NULL);
861   if (rc)
862     {
863       xfree (get_membuf (&data, &len));
864       return unlock_scd (ctrl, rc);
865     }
866   *r_buf = get_membuf (&data, r_buflen);
867   if (!*r_buf)
868     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
869
870   return unlock_scd (ctrl, 0);
871 }
872
873
874 \f
875 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
876 int
877 agent_card_readcert (ctrl_t ctrl,
878                      const char *id, char **r_buf, size_t *r_buflen)
879 {
880   int rc;
881   char line[ASSUAN_LINELENGTH];
882   membuf_t data;
883   size_t len;
884
885   *r_buf = NULL;
886   rc = start_scd (ctrl);
887   if (rc)
888     return rc;
889
890   init_membuf (&data, 1024);
891   snprintf (line, DIM(line)-1, "READCERT %s", id);
892   line[DIM(line)-1] = 0;
893   rc = assuan_transact (ctrl->scd_local->ctx, line,
894                         membuf_data_cb, &data,
895                         NULL, NULL,
896                         NULL, NULL);
897   if (rc)
898     {
899       xfree (get_membuf (&data, &len));
900       return unlock_scd (ctrl, rc);
901     }
902   *r_buf = get_membuf (&data, r_buflen);
903   if (!*r_buf)
904     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
905
906   return unlock_scd (ctrl, 0);
907 }
908
909
910 \f
911 /* Read a key with ID and return it in an allocate buffer pointed to
912    by r_BUF as a valid S-expression. */
913 int
914 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
915 {
916   int rc;
917   char line[ASSUAN_LINELENGTH];
918   membuf_t data;
919   size_t len, buflen;
920
921   *r_buf = NULL;
922   rc = start_scd (ctrl);
923   if (rc)
924     return rc;
925
926   init_membuf (&data, 1024);
927   snprintf (line, DIM(line)-1, "READKEY %s", id);
928   line[DIM(line)-1] = 0;
929   rc = assuan_transact (ctrl->scd_local->ctx, line,
930                         membuf_data_cb, &data,
931                         NULL, NULL,
932                         NULL, NULL);
933   if (rc)
934     {
935       xfree (get_membuf (&data, &len));
936       return unlock_scd (ctrl, rc);
937     }
938   *r_buf = get_membuf (&data, &buflen);
939   if (!*r_buf)
940     return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
941
942   if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
943     {
944       xfree (*r_buf); *r_buf = NULL;
945       return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
946     }
947
948   return unlock_scd (ctrl, 0);
949 }
950
951
952 \f
953 /* Type used with the card_getattr_cb.  */
954 struct card_getattr_parm_s {
955   const char *keyword;  /* Keyword to look for.  */
956   size_t keywordlen;    /* strlen of KEYWORD.  */
957   char *data;           /* Malloced and unescaped data.  */
958   int error;            /* ERRNO value or 0 on success. */
959 };
960
961 /* Callback function for agent_card_getattr.  */
962 static assuan_error_t
963 card_getattr_cb (void *opaque, const char *line)
964 {
965   struct card_getattr_parm_s *parm = opaque;
966   const char *keyword = line;
967   int keywordlen;
968
969   if (parm->data)
970     return 0; /* We want only the first occurrence.  */
971
972   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
973     ;
974   while (spacep (line))
975     line++;
976
977   if (keywordlen == parm->keywordlen
978       && !memcmp (keyword, parm->keyword, keywordlen))
979     {
980       parm->data = unescape_status_string ((const unsigned char*)line);
981       if (!parm->data)
982         parm->error = errno;
983     }
984   
985   return 0;
986 }
987
988
989 /* Call the agent to retrieve a single line data object. On success
990    the object is malloced and stored at RESULT; it is guaranteed that
991    NULL is never stored in this case.  On error an error code is
992    returned and NULL stored at RESULT. */
993 gpg_error_t
994 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
995 {
996   int err;
997   struct card_getattr_parm_s parm;
998   char line[ASSUAN_LINELENGTH];
999
1000   *result = NULL;
1001
1002   if (!*name)
1003     return gpg_error (GPG_ERR_INV_VALUE);
1004
1005   memset (&parm, 0, sizeof parm);
1006   parm.keyword = name;
1007   parm.keywordlen = strlen (name);
1008
1009   /* We assume that NAME does not need escaping. */
1010   if (8 + strlen (name) > DIM(line)-1)
1011     return gpg_error (GPG_ERR_TOO_LARGE);
1012   stpcpy (stpcpy (line, "GETATTR "), name); 
1013
1014   err = start_scd (ctrl);
1015   if (err)
1016     return err;
1017
1018   err = assuan_transact (ctrl->scd_local->ctx, line,
1019                          NULL, NULL, NULL, NULL,
1020                          card_getattr_cb, &parm);
1021   if (!err && parm.error)
1022     err = gpg_error_from_errno (parm.error);
1023   
1024   if (!err && !parm.data)
1025     err = gpg_error (GPG_ERR_NO_DATA);
1026   
1027   if (!err)
1028     *result = parm.data;
1029   else
1030     xfree (parm.data);
1031
1032   return unlock_scd (ctrl, err);
1033 }
1034
1035
1036
1037 \f
1038 static int
1039 pass_status_thru (void *opaque, const char *line)
1040 {
1041   assuan_context_t ctx = opaque;
1042   char keyword[200];
1043   int i;
1044
1045   for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
1046     keyword[i] = *line;
1047   keyword[i] = 0;
1048   /* truncate any remaining keyword stuff. */
1049   for (; *line && !spacep (line); line++)
1050     ;
1051   while (spacep (line))
1052     line++;
1053
1054   assuan_write_status (ctx, keyword, line);
1055   return 0;
1056 }
1057
1058 static int
1059 pass_data_thru (void *opaque, const void *buffer, size_t length)
1060 {
1061   assuan_context_t ctx = opaque;
1062
1063   assuan_send_data (ctx, buffer, length);
1064   return 0;
1065 }
1066
1067
1068 /* Send the line CMDLINE with command for the SCDdaemon to it and send
1069    all status messages back.  This command is used as a general quoting
1070    mechanism to pass everything verbatim to SCDAEMOPN.  The PIN
1071    inquirey is handled inside gpg-agent. */
1072 int
1073 agent_card_scd (ctrl_t ctrl, const char *cmdline,
1074                 int (*getpin_cb)(void *, const char *, char*, size_t),
1075                 void *getpin_cb_arg, void *assuan_context)
1076 {
1077   int rc;
1078   struct inq_needpin_s inqparm;
1079
1080   rc = start_scd (ctrl);
1081   if (rc)
1082     return rc;
1083
1084   inqparm.ctx = ctrl->scd_local->ctx;
1085   inqparm.getpin_cb = getpin_cb;
1086   inqparm.getpin_cb_arg = getpin_cb_arg;
1087   rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1088                         pass_data_thru, assuan_context,
1089                         inq_needpin, &inqparm,
1090                         pass_status_thru, assuan_context);
1091   if (rc)
1092     {
1093       return unlock_scd (ctrl, rc);
1094     }
1095
1096   return unlock_scd (ctrl, 0);
1097 }
1098
1099