Fix signal handling race condition.
[gnupg.git] / agent / call-scd.c
blobc162ad14c1c86b708311d44a83cad0547ff223b8
1 /* call-scd.c - fork of the scdaemon to do SC operations
2 * Copyright (C) 2001, 2002, 2005, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
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>
36 #include "agent.h"
37 #include <assuan.h>
39 #ifdef _POSIX_OPEN_MAX
40 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
41 #else
42 #define MAX_OPEN_FDS 20
43 #endif
45 /* Definition of module local data of the CTRL structure. */
46 struct scd_local_s
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;
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;
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. */
66 /* Callback parameter for learn card */
67 struct learn_parm_s
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;
77 struct inq_needpin_s
79 assuan_context_t ctx;
80 int (*getpin_cb)(void *, const char *, char*, size_t);
81 void *getpin_cb_arg;
82 assuan_context_t passthru; /* If not NULL, pass unknown inquiries
83 up to the caller. */
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;
91 /* A Mutex used inside the start_scd function. */
92 static pth_mutex_t start_scd_lock;
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;
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;
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;
110 /* Local prototypes. */
111 static assuan_error_t membuf_data_cb (void *opaque,
112 const void *buffer, size_t length);
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)
124 static int initialized;
126 if (!initialized)
128 if (!pth_mutex_init (&start_scd_lock))
129 log_fatal ("error initializing mutex: %s\n", strerror (errno));
130 initialized = 1;
135 static void
136 dump_mutex_state (pth_mutex_t *m)
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
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)
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);
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)
178 if (ctrl->scd_local->locked != 1)
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);
185 ctrl->scd_local->locked = 0;
186 return rc;
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)
194 (void)opaque;
196 if (!where)
197 gcry_control (GCRYCTL_TERM_SECMEM);
201 /* Fork off the SCdaemon if this has not already been done. Lock the
202 daemon and make sure that a proper context has been setup in CTRL.
203 This function might also lock the daemon, which means that the
204 caller must call unlock_scd after this fucntion has returned
205 success and the actual Assuan transaction been done. */
206 static int
207 start_scd (ctrl_t ctrl)
209 gpg_error_t err = 0;
210 const char *pgmname;
211 assuan_context_t ctx;
212 const char *argv[3];
213 int no_close_list[3];
214 int i;
215 int rc;
217 if (opt.disable_scdaemon)
218 return gpg_error (GPG_ERR_NOT_SUPPORTED);
220 /* If this is the first call for this session, setup the local data
221 structure. */
222 if (!ctrl->scd_local)
224 ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
225 if (!ctrl->scd_local)
226 return gpg_error_from_syserror ();
227 ctrl->scd_local->ctrl_backlink = ctrl;
228 ctrl->scd_local->next_local = scd_local_list;
229 scd_local_list = ctrl->scd_local;
233 /* Assert that the lock count is as expected. */
234 if (ctrl->scd_local->locked)
236 log_error ("start_scd: invalid lock count (%d)\n",
237 ctrl->scd_local->locked);
238 return gpg_error (GPG_ERR_INTERNAL);
240 ctrl->scd_local->locked++;
242 if (ctrl->scd_local->ctx)
243 return 0; /* Okay, the context is fine. We used to test for an
244 alive context here and do an disconnect. Now that we
245 have a ticker function to check for it, it is easier
246 not to check here but to let the connection run on an
247 error instead. */
250 /* We need to protect the following code. */
251 if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
253 log_error ("failed to acquire the start_scd lock: %s\n",
254 strerror (errno));
255 return gpg_error (GPG_ERR_INTERNAL);
258 /* Check whether the pipe server has already been started and in
259 this case either reuse a lingering pipe connection or establish a
260 new socket based one. */
261 if (primary_scd_ctx && primary_scd_ctx_reusable)
263 ctx = primary_scd_ctx;
264 primary_scd_ctx_reusable = 0;
265 if (opt.verbose)
266 log_info ("new connection to SCdaemon established (reusing)\n");
267 goto leave;
270 if (socket_name)
272 rc = assuan_socket_connect (&ctx, socket_name, 0);
273 if (rc)
275 log_error ("can't connect to socket `%s': %s\n",
276 socket_name, gpg_strerror (rc));
277 err = gpg_error (GPG_ERR_NO_SCDAEMON);
278 goto leave;
281 if (opt.verbose)
282 log_info ("new connection to SCdaemon established\n");
283 goto leave;
286 if (primary_scd_ctx)
288 log_info ("SCdaemon is running but won't accept further connections\n");
289 err = gpg_error (GPG_ERR_NO_SCDAEMON);
290 goto leave;
293 /* Nope, it has not been started. Fire it up now. */
294 if (opt.verbose)
295 log_info ("no running SCdaemon - starting it\n");
297 if (fflush (NULL))
299 #ifndef HAVE_W32_SYSTEM
300 err = gpg_error_from_syserror ();
301 #endif
302 log_error ("error flushing pending output: %s\n", strerror (errno));
303 /* At least Windows XP fails here with EBADF. According to docs
304 and Wine an fflush(NULL) is the same as _flushall. However
305 the Wime implementaion does not flush stdin,stdout and stderr
306 - see above. Lets try to ignore the error. */
307 #ifndef HAVE_W32_SYSTEM
308 goto leave;
309 #endif
312 if (!opt.scdaemon_program || !*opt.scdaemon_program)
313 opt.scdaemon_program = gnupg_module_name (GNUPG_MODULE_NAME_SCDAEMON);
314 if ( !(pgmname = strrchr (opt.scdaemon_program, '/')))
315 pgmname = opt.scdaemon_program;
316 else
317 pgmname++;
319 argv[0] = pgmname;
320 argv[1] = "--multi-server";
321 argv[2] = NULL;
323 i=0;
324 if (!opt.running_detached)
326 if (log_get_fd () != -1)
327 no_close_list[i++] = log_get_fd ();
328 no_close_list[i++] = fileno (stderr);
330 no_close_list[i] = -1;
332 /* Connect to the pinentry and perform initial handshaking. Use
333 detached flag (128) so that under W32 SCDAEMON does not show up a
334 new window. */
335 rc = assuan_pipe_connect_ext (&ctx, opt.scdaemon_program, argv,
336 no_close_list, atfork_cb, NULL, 128);
337 if (rc)
339 log_error ("can't connect to the SCdaemon: %s\n",
340 gpg_strerror (rc));
341 err = gpg_error (GPG_ERR_NO_SCDAEMON);
342 goto leave;
345 if (opt.verbose)
346 log_debug ("first connection to SCdaemon established\n");
348 if (DBG_ASSUAN)
349 assuan_set_log_stream (ctx, log_get_stream ());
351 /* Get the name of the additional socket opened by scdaemon. */
353 membuf_t data;
354 unsigned char *databuf;
355 size_t datalen;
357 xfree (socket_name);
358 socket_name = NULL;
359 init_membuf (&data, 256);
360 assuan_transact (ctx, "GETINFO socket_name",
361 membuf_data_cb, &data, NULL, NULL, NULL, NULL);
363 databuf = get_membuf (&data, &datalen);
364 if (databuf && datalen)
366 socket_name = xtrymalloc (datalen + 1);
367 if (!socket_name)
368 log_error ("warning: can't store socket name: %s\n",
369 strerror (errno));
370 else
372 memcpy (socket_name, databuf, datalen);
373 socket_name[datalen] = 0;
374 if (DBG_ASSUAN)
375 log_debug ("additional connections at `%s'\n", socket_name);
378 xfree (databuf);
381 /* Tell the scdaemon we want him to send us an event signal. */
383 char buf[100];
385 #ifdef HAVE_W32_SYSTEM
386 snprintf (buf, sizeof buf, "OPTION event-signal=%lx",
387 (unsigned long)get_agent_scd_notify_event ());
388 #else
389 snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
390 #endif
391 assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
394 primary_scd_ctx = ctx;
395 primary_scd_ctx_reusable = 0;
397 leave:
398 if (err)
400 unlock_scd (ctrl, err);
402 else
404 ctrl->scd_local->ctx = ctx;
406 if (!pth_mutex_release (&start_scd_lock))
407 log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
408 return err;
412 /* Check whether the Scdaemon is still alive and clean it up if not. */
413 void
414 agent_scd_check_aliveness (void)
416 pth_event_t evt;
417 pid_t pid;
418 #ifdef HAVE_W32_SYSTEM
419 DWORD rc;
420 #else
421 int rc;
422 #endif
424 if (!primary_scd_ctx)
425 return; /* No scdaemon running. */
427 /* This is not a critical function so we use a short timeout while
428 acquiring the lock. */
429 evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
430 if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
432 if (pth_event_occurred (evt))
434 if (opt.verbose > 1)
435 log_info ("failed to acquire the start_scd lock while"
436 " doing an aliveness check: %s\n", "timeout");
438 else
439 log_error ("failed to acquire the start_scd lock while"
440 " doing an aliveness check: %s\n", strerror (errno));
441 pth_event_free (evt, PTH_FREE_THIS);
442 return;
444 pth_event_free (evt, PTH_FREE_THIS);
446 if (primary_scd_ctx)
448 pid = assuan_get_pid (primary_scd_ctx);
449 #ifdef HAVE_W32_SYSTEM
450 /* If we have a PID we disconnect if either GetExitProcessCode
451 fails or if ir returns the exit code of the scdaemon. 259 is
452 the error code for STILL_ALIVE. */
453 if (pid != (pid_t)(void*)(-1) && pid
454 && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259))
455 #else
456 if (pid != (pid_t)(-1) && pid
457 && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
458 #endif
460 /* Okay, scdaemon died. Disconnect the primary connection
461 now but take care that it won't do another wait. Also
462 cleanup all other connections and release their
463 resources. The next use will start a new daemon then.
464 Due to the use of the START_SCD_LOCAL we are sure that
465 none of these context are actually in use. */
466 struct scd_local_s *sl;
468 assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
469 assuan_disconnect (primary_scd_ctx);
471 for (sl=scd_local_list; sl; sl = sl->next_local)
473 if (sl->ctx)
475 if (sl->ctx != primary_scd_ctx)
476 assuan_disconnect (sl->ctx);
477 sl->ctx = NULL;
481 primary_scd_ctx = NULL;
482 primary_scd_ctx_reusable = 0;
484 xfree (socket_name);
485 socket_name = NULL;
489 if (!pth_mutex_release (&start_scd_lock))
490 log_error ("failed to release the start_scd lock while"
491 " doing the aliveness check: %s\n", strerror (errno));
496 /* Reset the SCD if it has been used. Actually it is not a reset but
497 a cleanup of resources used by the current connection. */
499 agent_reset_scd (ctrl_t ctrl)
501 if (ctrl->scd_local)
503 if (ctrl->scd_local->ctx)
505 /* We can't disconnect the primary context because libassuan
506 does a waitpid on it and thus the system would hang.
507 Instead we send a reset and keep that connection for
508 reuse. */
509 if (ctrl->scd_local->ctx == primary_scd_ctx)
511 /* Send a RESTART to the SCD. This is required for the
512 primary connection as a kind of virtual EOF; we don't
513 have another way to tell it that the next command
514 should be viewed as if a new connection has been
515 made. For the non-primary connections this is not
516 needed as we simply close the socket. We don't check
517 for an error here because the RESTART may fail for
518 example if the scdaemon has already been terminated.
519 Anyway, we need to set the reusable flag to make sure
520 that the aliveness check can clean it up. */
521 assuan_transact (primary_scd_ctx, "RESTART",
522 NULL, NULL, NULL, NULL, NULL, NULL);
523 primary_scd_ctx_reusable = 1;
525 else
526 assuan_disconnect (ctrl->scd_local->ctx);
527 ctrl->scd_local->ctx = NULL;
530 /* Remove the local context from our list and release it. */
531 if (!scd_local_list)
532 BUG ();
533 else if (scd_local_list == ctrl->scd_local)
534 scd_local_list = ctrl->scd_local->next_local;
535 else
537 struct scd_local_s *sl;
539 for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
540 if (sl->next_local == ctrl->scd_local)
541 break;
542 if (!sl->next_local)
543 BUG ();
544 sl->next_local = ctrl->scd_local->next_local;
546 xfree (ctrl->scd_local);
547 ctrl->scd_local = NULL;
550 return 0;
555 /* Return a new malloced string by unescaping the string S. Escaping
556 is percent escaping and '+'/space mapping. A binary Nul will
557 silently be replaced by a 0xFF. Function returns NULL to indicate
558 an out of memory status. */
559 static char *
560 unescape_status_string (const unsigned char *s)
562 char *buffer, *d;
564 buffer = d = xtrymalloc (strlen ((const char*)s)+1);
565 if (!buffer)
566 return NULL;
567 while (*s)
569 if (*s == '%' && s[1] && s[2])
571 s++;
572 *d = xtoi_2 (s);
573 if (!*d)
574 *d = '\xff';
575 d++;
576 s += 2;
578 else if (*s == '+')
580 *d++ = ' ';
581 s++;
583 else
584 *d++ = *s++;
586 *d = 0;
587 return buffer;
592 static int
593 learn_status_cb (void *opaque, const char *line)
595 struct learn_parm_s *parm = opaque;
596 const char *keyword = line;
597 int keywordlen;
599 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
601 while (spacep (line))
602 line++;
603 if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
605 parm->certinfo_cb (parm->certinfo_cb_arg, line);
607 else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
609 parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
611 else if (keywordlen && *line)
613 parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
616 return 0;
619 /* Perform the LEARN command and return a list of all private keys
620 stored on the card. */
622 agent_card_learn (ctrl_t ctrl,
623 void (*kpinfo_cb)(void*, const char *),
624 void *kpinfo_cb_arg,
625 void (*certinfo_cb)(void*, const char *),
626 void *certinfo_cb_arg,
627 void (*sinfo_cb)(void*, const char *, size_t, const char *),
628 void *sinfo_cb_arg)
630 int rc;
631 struct learn_parm_s parm;
633 rc = start_scd (ctrl);
634 if (rc)
635 return rc;
637 memset (&parm, 0, sizeof parm);
638 parm.kpinfo_cb = kpinfo_cb;
639 parm.kpinfo_cb_arg = kpinfo_cb_arg;
640 parm.certinfo_cb = certinfo_cb;
641 parm.certinfo_cb_arg = certinfo_cb_arg;
642 parm.sinfo_cb = sinfo_cb;
643 parm.sinfo_cb_arg = sinfo_cb_arg;
644 rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
645 NULL, NULL, NULL, NULL,
646 learn_status_cb, &parm);
647 if (rc)
648 return unlock_scd (ctrl, rc);
650 return unlock_scd (ctrl, 0);
655 static int
656 get_serialno_cb (void *opaque, const char *line)
658 char **serialno = opaque;
659 const char *keyword = line;
660 const char *s;
661 int keywordlen, n;
663 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
665 while (spacep (line))
666 line++;
668 if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
670 if (*serialno)
671 return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
672 for (n=0,s=line; hexdigitp (s); s++, n++)
674 if (!n || (n&1)|| !(spacep (s) || !*s) )
675 return gpg_error (GPG_ERR_ASS_PARAMETER);
676 *serialno = xtrymalloc (n+1);
677 if (!*serialno)
678 return out_of_core ();
679 memcpy (*serialno, line, n);
680 (*serialno)[n] = 0;
683 return 0;
686 /* Return the serial number of the card or an appropriate error. The
687 serial number is returned as a hexstring. */
689 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
691 int rc;
692 char *serialno = NULL;
694 rc = start_scd (ctrl);
695 if (rc)
696 return rc;
698 rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
699 NULL, NULL, NULL, NULL,
700 get_serialno_cb, &serialno);
701 if (rc)
703 xfree (serialno);
704 return unlock_scd (ctrl, rc);
706 *r_serialno = serialno;
707 return unlock_scd (ctrl, 0);
713 static assuan_error_t
714 membuf_data_cb (void *opaque, const void *buffer, size_t length)
716 membuf_t *data = opaque;
718 if (buffer)
719 put_membuf (data, buffer, length);
720 return 0;
723 /* Handle the NEEDPIN inquiry. */
724 static int
725 inq_needpin (void *opaque, const char *line)
727 struct inq_needpin_s *parm = opaque;
728 char *pin;
729 size_t pinlen;
730 int rc;
732 if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
734 line += 7;
735 while (*line == ' ')
736 line++;
738 pinlen = 90;
739 pin = gcry_malloc_secure (pinlen);
740 if (!pin)
741 return out_of_core ();
743 rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
744 if (!rc)
745 rc = assuan_send_data (parm->ctx, pin, pinlen);
746 xfree (pin);
748 else if (!strncmp (line, "POPUPKEYPADPROMPT", 17)
749 && (line[17] == ' ' || !line[17]))
751 line += 17;
752 while (*line == ' ')
753 line++;
755 rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
757 else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19)
758 && (line[19] == ' ' || !line[19]))
760 rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
762 else if (parm->passthru)
764 unsigned char *value;
765 size_t valuelen;
766 int rest;
767 int needrest = !strncmp (line, "KEYDATA", 8);
769 /* Pass the inquiry up to our caller. We limit the maximum
770 amount to an arbitrary value. As we know that the KEYDATA
771 enquiry is pretty sensitive we disable logging then */
772 if ((rest = (needrest
773 && !assuan_get_flag (parm->passthru, ASSUAN_CONFIDENTIAL))))
774 assuan_begin_confidential (parm->passthru);
775 rc = assuan_inquire (parm->passthru, line, &value, &valuelen, 8096);
776 if (rest)
777 assuan_end_confidential (parm->passthru);
778 if (!rc)
780 if ((rest = (needrest
781 && !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL))))
782 assuan_begin_confidential (parm->ctx);
783 rc = assuan_send_data (parm->ctx, value, valuelen);
784 if (rest)
785 assuan_end_confidential (parm->ctx);
786 xfree (value);
788 else
789 log_error ("error forwarding inquiry `%s': %s\n",
790 line, gpg_strerror (rc));
792 else
794 log_error ("unsupported inquiry `%s'\n", line);
795 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
798 return rc;
803 /* Create a signature using the current card */
805 agent_card_pksign (ctrl_t ctrl,
806 const char *keyid,
807 int (*getpin_cb)(void *, const char *, char*, size_t),
808 void *getpin_cb_arg,
809 const unsigned char *indata, size_t indatalen,
810 unsigned char **r_buf, size_t *r_buflen)
812 int rc, i;
813 char *p, line[ASSUAN_LINELENGTH];
814 membuf_t data;
815 struct inq_needpin_s inqparm;
816 size_t len;
817 unsigned char *sigbuf;
818 size_t sigbuflen;
820 *r_buf = NULL;
821 rc = start_scd (ctrl);
822 if (rc)
823 return rc;
825 if (indatalen*2 + 50 > DIM(line))
826 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
828 sprintf (line, "SETDATA ");
829 p = line + strlen (line);
830 for (i=0; i < indatalen ; i++, p += 2 )
831 sprintf (p, "%02X", indata[i]);
832 rc = assuan_transact (ctrl->scd_local->ctx, line,
833 NULL, NULL, NULL, NULL, NULL, NULL);
834 if (rc)
835 return unlock_scd (ctrl, rc);
837 init_membuf (&data, 1024);
838 inqparm.ctx = ctrl->scd_local->ctx;
839 inqparm.getpin_cb = getpin_cb;
840 inqparm.getpin_cb_arg = getpin_cb_arg;
841 inqparm.passthru = 0;
842 snprintf (line, DIM(line)-1,
843 ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
844 line[DIM(line)-1] = 0;
845 rc = assuan_transact (ctrl->scd_local->ctx, line,
846 membuf_data_cb, &data,
847 inq_needpin, &inqparm,
848 NULL, NULL);
849 if (rc)
851 xfree (get_membuf (&data, &len));
852 return unlock_scd (ctrl, rc);
854 sigbuf = get_membuf (&data, &sigbuflen);
856 /* Create an S-expression from it which is formatted like this:
857 "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
858 *r_buflen = 21 + 11 + sigbuflen + 4;
859 p = xtrymalloc (*r_buflen);
860 *r_buf = (unsigned char*)p;
861 if (!p)
862 return unlock_scd (ctrl, out_of_core ());
863 p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
864 sprintf (p, "%u:", (unsigned int)sigbuflen);
865 p += strlen (p);
866 memcpy (p, sigbuf, sigbuflen);
867 p += sigbuflen;
868 strcpy (p, ")))");
869 xfree (sigbuf);
871 assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
872 return unlock_scd (ctrl, 0);
875 /* Decipher INDATA using the current card. Note that the returned value is */
877 agent_card_pkdecrypt (ctrl_t ctrl,
878 const char *keyid,
879 int (*getpin_cb)(void *, const char *, char*, size_t),
880 void *getpin_cb_arg,
881 const unsigned char *indata, size_t indatalen,
882 char **r_buf, size_t *r_buflen)
884 int rc, i;
885 char *p, line[ASSUAN_LINELENGTH];
886 membuf_t data;
887 struct inq_needpin_s inqparm;
888 size_t len;
890 *r_buf = NULL;
891 rc = start_scd (ctrl);
892 if (rc)
893 return rc;
895 /* FIXME: use secure memory where appropriate */
896 if (indatalen*2 + 50 > DIM(line))
897 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
899 sprintf (line, "SETDATA ");
900 p = line + strlen (line);
901 for (i=0; i < indatalen ; i++, p += 2 )
902 sprintf (p, "%02X", indata[i]);
903 rc = assuan_transact (ctrl->scd_local->ctx, line,
904 NULL, NULL, NULL, NULL, NULL, NULL);
905 if (rc)
906 return unlock_scd (ctrl, rc);
908 init_membuf (&data, 1024);
909 inqparm.ctx = ctrl->scd_local->ctx;
910 inqparm.getpin_cb = getpin_cb;
911 inqparm.getpin_cb_arg = getpin_cb_arg;
912 inqparm.passthru = 0;
913 snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
914 line[DIM(line)-1] = 0;
915 rc = assuan_transact (ctrl->scd_local->ctx, line,
916 membuf_data_cb, &data,
917 inq_needpin, &inqparm,
918 NULL, NULL);
919 if (rc)
921 xfree (get_membuf (&data, &len));
922 return unlock_scd (ctrl, rc);
924 *r_buf = get_membuf (&data, r_buflen);
925 if (!*r_buf)
926 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
928 return unlock_scd (ctrl, 0);
933 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
935 agent_card_readcert (ctrl_t ctrl,
936 const char *id, char **r_buf, size_t *r_buflen)
938 int rc;
939 char line[ASSUAN_LINELENGTH];
940 membuf_t data;
941 size_t len;
943 *r_buf = NULL;
944 rc = start_scd (ctrl);
945 if (rc)
946 return rc;
948 init_membuf (&data, 1024);
949 snprintf (line, DIM(line)-1, "READCERT %s", id);
950 line[DIM(line)-1] = 0;
951 rc = assuan_transact (ctrl->scd_local->ctx, line,
952 membuf_data_cb, &data,
953 NULL, NULL,
954 NULL, NULL);
955 if (rc)
957 xfree (get_membuf (&data, &len));
958 return unlock_scd (ctrl, rc);
960 *r_buf = get_membuf (&data, r_buflen);
961 if (!*r_buf)
962 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
964 return unlock_scd (ctrl, 0);
969 /* Read a key with ID and return it in an allocate buffer pointed to
970 by r_BUF as a valid S-expression. */
972 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
974 int rc;
975 char line[ASSUAN_LINELENGTH];
976 membuf_t data;
977 size_t len, buflen;
979 *r_buf = NULL;
980 rc = start_scd (ctrl);
981 if (rc)
982 return rc;
984 init_membuf (&data, 1024);
985 snprintf (line, DIM(line)-1, "READKEY %s", id);
986 line[DIM(line)-1] = 0;
987 rc = assuan_transact (ctrl->scd_local->ctx, line,
988 membuf_data_cb, &data,
989 NULL, NULL,
990 NULL, NULL);
991 if (rc)
993 xfree (get_membuf (&data, &len));
994 return unlock_scd (ctrl, rc);
996 *r_buf = get_membuf (&data, &buflen);
997 if (!*r_buf)
998 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
1000 if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
1002 xfree (*r_buf); *r_buf = NULL;
1003 return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
1006 return unlock_scd (ctrl, 0);
1011 /* Type used with the card_getattr_cb. */
1012 struct card_getattr_parm_s {
1013 const char *keyword; /* Keyword to look for. */
1014 size_t keywordlen; /* strlen of KEYWORD. */
1015 char *data; /* Malloced and unescaped data. */
1016 int error; /* ERRNO value or 0 on success. */
1019 /* Callback function for agent_card_getattr. */
1020 static assuan_error_t
1021 card_getattr_cb (void *opaque, const char *line)
1023 struct card_getattr_parm_s *parm = opaque;
1024 const char *keyword = line;
1025 int keywordlen;
1027 if (parm->data)
1028 return 0; /* We want only the first occurrence. */
1030 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1032 while (spacep (line))
1033 line++;
1035 if (keywordlen == parm->keywordlen
1036 && !memcmp (keyword, parm->keyword, keywordlen))
1038 parm->data = unescape_status_string ((const unsigned char*)line);
1039 if (!parm->data)
1040 parm->error = errno;
1043 return 0;
1047 /* Call the agent to retrieve a single line data object. On success
1048 the object is malloced and stored at RESULT; it is guaranteed that
1049 NULL is never stored in this case. On error an error code is
1050 returned and NULL stored at RESULT. */
1051 gpg_error_t
1052 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
1054 int err;
1055 struct card_getattr_parm_s parm;
1056 char line[ASSUAN_LINELENGTH];
1058 *result = NULL;
1060 if (!*name)
1061 return gpg_error (GPG_ERR_INV_VALUE);
1063 memset (&parm, 0, sizeof parm);
1064 parm.keyword = name;
1065 parm.keywordlen = strlen (name);
1067 /* We assume that NAME does not need escaping. */
1068 if (8 + strlen (name) > DIM(line)-1)
1069 return gpg_error (GPG_ERR_TOO_LARGE);
1070 stpcpy (stpcpy (line, "GETATTR "), name);
1072 err = start_scd (ctrl);
1073 if (err)
1074 return err;
1076 err = assuan_transact (ctrl->scd_local->ctx, line,
1077 NULL, NULL, NULL, NULL,
1078 card_getattr_cb, &parm);
1079 if (!err && parm.error)
1080 err = gpg_error_from_errno (parm.error);
1082 if (!err && !parm.data)
1083 err = gpg_error (GPG_ERR_NO_DATA);
1085 if (!err)
1086 *result = parm.data;
1087 else
1088 xfree (parm.data);
1090 return unlock_scd (ctrl, err);
1096 static int
1097 pass_status_thru (void *opaque, const char *line)
1099 assuan_context_t ctx = opaque;
1100 char keyword[200];
1101 int i;
1103 for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
1104 keyword[i] = *line;
1105 keyword[i] = 0;
1106 /* truncate any remaining keyword stuff. */
1107 for (; *line && !spacep (line); line++)
1109 while (spacep (line))
1110 line++;
1112 assuan_write_status (ctx, keyword, line);
1113 return 0;
1116 static int
1117 pass_data_thru (void *opaque, const void *buffer, size_t length)
1119 assuan_context_t ctx = opaque;
1121 assuan_send_data (ctx, buffer, length);
1122 return 0;
1126 /* Send the line CMDLINE with command for the SCDdaemon to it and send
1127 all status messages back. This command is used as a general quoting
1128 mechanism to pass everything verbatim to SCDAEMON. The PIN
1129 inquiry is handled inside gpg-agent. */
1131 agent_card_scd (ctrl_t ctrl, const char *cmdline,
1132 int (*getpin_cb)(void *, const char *, char*, size_t),
1133 void *getpin_cb_arg, void *assuan_context)
1135 int rc;
1136 struct inq_needpin_s inqparm;
1138 rc = start_scd (ctrl);
1139 if (rc)
1140 return rc;
1142 inqparm.ctx = ctrl->scd_local->ctx;
1143 inqparm.getpin_cb = getpin_cb;
1144 inqparm.getpin_cb_arg = getpin_cb_arg;
1145 inqparm.passthru = assuan_context;
1146 rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1147 pass_data_thru, assuan_context,
1148 inq_needpin, &inqparm,
1149 pass_status_thru, assuan_context);
1150 if (rc)
1152 return unlock_scd (ctrl, rc);
1155 return unlock_scd (ctrl, 0);