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