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