Fix last change
[gnupg.git] / agent / call-scd.c
blobd09812e575c16ebdf477965af7dca20b6846a077
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 (void)m;
140 log_printf ("unknown under W32");
141 #else
142 if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
143 log_printf ("not_initialized");
144 else if (!(m->mx_state & PTH_MUTEX_LOCKED))
145 log_printf ("not_locked");
146 else
147 log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
148 #endif
152 /* This function may be called to print infromation pertaining to the
153 current state of this module to the log. */
154 void
155 agent_scd_dump_state (void)
157 log_info ("agent_scd_dump_state: scd_lock=");
158 dump_mutex_state (&start_scd_lock);
159 log_printf ("\n");
160 log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
161 primary_scd_ctx,
162 (long)assuan_get_pid (primary_scd_ctx),
163 primary_scd_ctx_reusable);
164 if (socket_name)
165 log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name);
169 /* The unlock_scd function shall be called after having accessed the
170 SCD. It is currently not very useful but gives an opportunity to
171 keep track of connections currently calling SCD. Note that the
172 "lock" operation is done by the start_scd() function which must be
173 called and error checked before any SCD operation. CTRL is the
174 usual connection context and RC the error code to be passed trhough
175 the function. */
176 static int
177 unlock_scd (ctrl_t ctrl, int rc)
179 if (ctrl->scd_local->locked != 1)
181 log_error ("unlock_scd: invalid lock count (%d)\n",
182 ctrl->scd_local->locked);
183 if (!rc)
184 rc = gpg_error (GPG_ERR_INTERNAL);
186 ctrl->scd_local->locked = 0;
187 return rc;
190 /* To make sure we leave no secrets in our image after forking of the
191 scdaemon, we use this callback. */
192 static void
193 atfork_cb (void *opaque, int where)
195 (void)opaque;
197 if (!where)
198 gcry_control (GCRYCTL_TERM_SECMEM);
202 /* Fork off the SCdaemon if this has not already been done. Lock the
203 daemon and make sure that a proper context has been setup in CTRL.
204 This function might also lock the daemon, which means that the
205 caller must call unlock_scd after this fucntion has returned
206 success and the actual Assuan transaction been done. */
207 static int
208 start_scd (ctrl_t ctrl)
210 gpg_error_t err = 0;
211 const char *pgmname;
212 assuan_context_t ctx;
213 const char *argv[3];
214 int no_close_list[3];
215 int i;
216 int rc;
218 if (opt.disable_scdaemon)
219 return gpg_error (GPG_ERR_NOT_SUPPORTED);
221 /* If this is the first call for this session, setup the local data
222 structure. */
223 if (!ctrl->scd_local)
225 ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
226 if (!ctrl->scd_local)
227 return gpg_error_from_syserror ();
228 ctrl->scd_local->ctrl_backlink = ctrl;
229 ctrl->scd_local->next_local = scd_local_list;
230 scd_local_list = ctrl->scd_local;
234 /* Assert that the lock count is as expected. */
235 if (ctrl->scd_local->locked)
237 log_error ("start_scd: invalid lock count (%d)\n",
238 ctrl->scd_local->locked);
239 return gpg_error (GPG_ERR_INTERNAL);
241 ctrl->scd_local->locked++;
243 if (ctrl->scd_local->ctx)
244 return 0; /* Okay, the context is fine. We used to test for an
245 alive context here and do an disconnect. Now that we
246 have a ticker function to check for it, it is easier
247 not to check here but to let the connection run on an
248 error instead. */
251 /* We need to protect the following code. */
252 if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
254 log_error ("failed to acquire the start_scd lock: %s\n",
255 strerror (errno));
256 return gpg_error (GPG_ERR_INTERNAL);
259 /* Check whether the pipe server has already been started and in
260 this case either reuse a lingering pipe connection or establish a
261 new socket based one. */
262 if (primary_scd_ctx && primary_scd_ctx_reusable)
264 ctx = primary_scd_ctx;
265 primary_scd_ctx_reusable = 0;
266 if (opt.verbose)
267 log_info ("new connection to SCdaemon established (reusing)\n");
268 goto leave;
271 if (socket_name)
273 rc = assuan_socket_connect (&ctx, socket_name, 0);
274 if (rc)
276 log_error ("can't connect to socket `%s': %s\n",
277 socket_name, gpg_strerror (rc));
278 err = gpg_error (GPG_ERR_NO_SCDAEMON);
279 goto leave;
282 if (opt.verbose)
283 log_info ("new connection to SCdaemon established\n");
284 goto leave;
287 if (primary_scd_ctx)
289 log_info ("SCdaemon is running but won't accept further connections\n");
290 err = gpg_error (GPG_ERR_NO_SCDAEMON);
291 goto leave;
294 /* Nope, it has not been started. Fire it up now. */
295 if (opt.verbose)
296 log_info ("no running SCdaemon - starting it\n");
298 if (fflush (NULL))
300 #ifndef HAVE_W32_SYSTEM
301 err = gpg_error_from_syserror ();
302 #endif
303 log_error ("error flushing pending output: %s\n", strerror (errno));
304 /* At least Windows XP fails here with EBADF. According to docs
305 and Wine an fflush(NULL) is the same as _flushall. However
306 the Wime implementaion does not flush stdin,stdout and stderr
307 - see above. Lets try to ignore the error. */
308 #ifndef HAVE_W32_SYSTEM
309 goto leave;
310 #endif
313 if (!opt.scdaemon_program || !*opt.scdaemon_program)
314 opt.scdaemon_program = gnupg_module_name (GNUPG_MODULE_NAME_SCDAEMON);
315 if ( !(pgmname = strrchr (opt.scdaemon_program, '/')))
316 pgmname = opt.scdaemon_program;
317 else
318 pgmname++;
320 argv[0] = pgmname;
321 argv[1] = "--multi-server";
322 argv[2] = NULL;
324 i=0;
325 if (!opt.running_detached)
327 if (log_get_fd () != -1)
328 no_close_list[i++] = log_get_fd ();
329 no_close_list[i++] = fileno (stderr);
331 no_close_list[i] = -1;
333 /* Connect to the pinentry and perform initial handshaking. Use
334 detached flag (128) so that under W32 SCDAEMON does not show up a
335 new window. */
336 rc = assuan_pipe_connect_ext (&ctx, opt.scdaemon_program, argv,
337 no_close_list, atfork_cb, NULL, 128);
338 if (rc)
340 log_error ("can't connect to the SCdaemon: %s\n",
341 gpg_strerror (rc));
342 err = gpg_error (GPG_ERR_NO_SCDAEMON);
343 goto leave;
346 if (opt.verbose)
347 log_debug ("first connection to SCdaemon established\n");
349 if (DBG_ASSUAN)
350 assuan_set_log_stream (ctx, log_get_stream ());
352 /* Get the name of the additional socket opened by scdaemon. */
354 membuf_t data;
355 unsigned char *databuf;
356 size_t datalen;
358 xfree (socket_name);
359 socket_name = NULL;
360 init_membuf (&data, 256);
361 assuan_transact (ctx, "GETINFO socket_name",
362 membuf_data_cb, &data, NULL, NULL, NULL, NULL);
364 databuf = get_membuf (&data, &datalen);
365 if (databuf && datalen)
367 socket_name = xtrymalloc (datalen + 1);
368 if (!socket_name)
369 log_error ("warning: can't store socket name: %s\n",
370 strerror (errno));
371 else
373 memcpy (socket_name, databuf, datalen);
374 socket_name[datalen] = 0;
375 if (DBG_ASSUAN)
376 log_debug ("additional connections at `%s'\n", socket_name);
379 xfree (databuf);
382 /* Tell the scdaemon we want him to send us an event signal. */
384 char buf[100];
386 #ifdef HAVE_W32_SYSTEM
387 snprintf (buf, sizeof buf, "OPTION event-signal=%lx",
388 (unsigned long)get_agent_scd_notify_event ());
389 #else
390 snprintf (buf, sizeof buf, "OPTION event-signal=%d", SIGUSR2);
391 #endif
392 assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
395 primary_scd_ctx = ctx;
396 primary_scd_ctx_reusable = 0;
398 leave:
399 if (err)
401 unlock_scd (ctrl, err);
403 else
405 ctrl->scd_local->ctx = ctx;
407 if (!pth_mutex_release (&start_scd_lock))
408 log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
409 return err;
413 /* Check whether the SCdaemon is active. This is a fast check without
414 any locking and might give a wrong result if another thread is about
415 to start the daemon or the daemon is about to be stopped.. */
417 agent_scd_check_running (void)
419 return !!primary_scd_ctx;
423 /* Check whether the Scdaemon is still alive and clean it up if not. */
424 void
425 agent_scd_check_aliveness (void)
427 pth_event_t evt;
428 pid_t pid;
429 #ifdef HAVE_W32_SYSTEM
430 DWORD rc;
431 #else
432 int rc;
433 #endif
435 if (!primary_scd_ctx)
436 return; /* No scdaemon running. */
438 /* This is not a critical function so we use a short timeout while
439 acquiring the lock. */
440 evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
441 if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
443 if (pth_event_occurred (evt))
445 if (opt.verbose > 1)
446 log_info ("failed to acquire the start_scd lock while"
447 " doing an aliveness check: %s\n", "timeout");
449 else
450 log_error ("failed to acquire the start_scd lock while"
451 " doing an aliveness check: %s\n", strerror (errno));
452 pth_event_free (evt, PTH_FREE_THIS);
453 return;
455 pth_event_free (evt, PTH_FREE_THIS);
457 if (primary_scd_ctx)
459 pid = assuan_get_pid (primary_scd_ctx);
460 #ifdef HAVE_W32_SYSTEM
461 /* If we have a PID we disconnect if either GetExitProcessCode
462 fails or if ir returns the exit code of the scdaemon. 259 is
463 the error code for STILL_ALIVE. */
464 if (pid != (pid_t)(void*)(-1) && pid
465 && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259))
466 #else
467 if (pid != (pid_t)(-1) && pid
468 && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
469 #endif
471 /* Okay, scdaemon died. Disconnect the primary connection
472 now but take care that it won't do another wait. Also
473 cleanup all other connections and release their
474 resources. The next use will start a new daemon then.
475 Due to the use of the START_SCD_LOCAL we are sure that
476 none of these context are actually in use. */
477 struct scd_local_s *sl;
479 assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
480 assuan_disconnect (primary_scd_ctx);
482 for (sl=scd_local_list; sl; sl = sl->next_local)
484 if (sl->ctx)
486 if (sl->ctx != primary_scd_ctx)
487 assuan_disconnect (sl->ctx);
488 sl->ctx = NULL;
492 primary_scd_ctx = NULL;
493 primary_scd_ctx_reusable = 0;
495 xfree (socket_name);
496 socket_name = NULL;
500 if (!pth_mutex_release (&start_scd_lock))
501 log_error ("failed to release the start_scd lock while"
502 " doing the aliveness check: %s\n", strerror (errno));
507 /* Reset the SCD if it has been used. Actually it is not a reset but
508 a cleanup of resources used by the current connection. */
510 agent_reset_scd (ctrl_t ctrl)
512 if (ctrl->scd_local)
514 if (ctrl->scd_local->ctx)
516 /* We can't disconnect the primary context because libassuan
517 does a waitpid on it and thus the system would hang.
518 Instead we send a reset and keep that connection for
519 reuse. */
520 if (ctrl->scd_local->ctx == primary_scd_ctx)
522 /* Send a RESTART to the SCD. This is required for the
523 primary connection as a kind of virtual EOF; we don't
524 have another way to tell it that the next command
525 should be viewed as if a new connection has been
526 made. For the non-primary connections this is not
527 needed as we simply close the socket. We don't check
528 for an error here because the RESTART may fail for
529 example if the scdaemon has already been terminated.
530 Anyway, we need to set the reusable flag to make sure
531 that the aliveness check can clean it up. */
532 assuan_transact (primary_scd_ctx, "RESTART",
533 NULL, NULL, NULL, NULL, NULL, NULL);
534 primary_scd_ctx_reusable = 1;
536 else
537 assuan_disconnect (ctrl->scd_local->ctx);
538 ctrl->scd_local->ctx = NULL;
541 /* Remove the local context from our list and release it. */
542 if (!scd_local_list)
543 BUG ();
544 else if (scd_local_list == ctrl->scd_local)
545 scd_local_list = ctrl->scd_local->next_local;
546 else
548 struct scd_local_s *sl;
550 for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
551 if (sl->next_local == ctrl->scd_local)
552 break;
553 if (!sl->next_local)
554 BUG ();
555 sl->next_local = ctrl->scd_local->next_local;
557 xfree (ctrl->scd_local);
558 ctrl->scd_local = NULL;
561 return 0;
566 static int
567 learn_status_cb (void *opaque, const char *line)
569 struct learn_parm_s *parm = opaque;
570 const char *keyword = line;
571 int keywordlen;
573 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
575 while (spacep (line))
576 line++;
577 if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
579 parm->certinfo_cb (parm->certinfo_cb_arg, line);
581 else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
583 parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
585 else if (keywordlen && *line)
587 parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
590 return 0;
593 /* Perform the LEARN command and return a list of all private keys
594 stored on the card. */
596 agent_card_learn (ctrl_t ctrl,
597 void (*kpinfo_cb)(void*, const char *),
598 void *kpinfo_cb_arg,
599 void (*certinfo_cb)(void*, const char *),
600 void *certinfo_cb_arg,
601 void (*sinfo_cb)(void*, const char *, size_t, const char *),
602 void *sinfo_cb_arg)
604 int rc;
605 struct learn_parm_s parm;
607 rc = start_scd (ctrl);
608 if (rc)
609 return rc;
611 memset (&parm, 0, sizeof parm);
612 parm.kpinfo_cb = kpinfo_cb;
613 parm.kpinfo_cb_arg = kpinfo_cb_arg;
614 parm.certinfo_cb = certinfo_cb;
615 parm.certinfo_cb_arg = certinfo_cb_arg;
616 parm.sinfo_cb = sinfo_cb;
617 parm.sinfo_cb_arg = sinfo_cb_arg;
618 rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
619 NULL, NULL, NULL, NULL,
620 learn_status_cb, &parm);
621 if (rc)
622 return unlock_scd (ctrl, rc);
624 return unlock_scd (ctrl, 0);
629 static int
630 get_serialno_cb (void *opaque, const char *line)
632 char **serialno = opaque;
633 const char *keyword = line;
634 const char *s;
635 int keywordlen, n;
637 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
639 while (spacep (line))
640 line++;
642 if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
644 if (*serialno)
645 return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
646 for (n=0,s=line; hexdigitp (s); s++, n++)
648 if (!n || (n&1)|| !(spacep (s) || !*s) )
649 return gpg_error (GPG_ERR_ASS_PARAMETER);
650 *serialno = xtrymalloc (n+1);
651 if (!*serialno)
652 return out_of_core ();
653 memcpy (*serialno, line, n);
654 (*serialno)[n] = 0;
657 return 0;
660 /* Return the serial number of the card or an appropriate error. The
661 serial number is returned as a hexstring. */
663 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
665 int rc;
666 char *serialno = NULL;
668 rc = start_scd (ctrl);
669 if (rc)
670 return rc;
672 rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
673 NULL, NULL, NULL, NULL,
674 get_serialno_cb, &serialno);
675 if (rc)
677 xfree (serialno);
678 return unlock_scd (ctrl, rc);
680 *r_serialno = serialno;
681 return unlock_scd (ctrl, 0);
687 static assuan_error_t
688 membuf_data_cb (void *opaque, const void *buffer, size_t length)
690 membuf_t *data = opaque;
692 if (buffer)
693 put_membuf (data, buffer, length);
694 return 0;
697 /* Handle the NEEDPIN inquiry. */
698 static int
699 inq_needpin (void *opaque, const char *line)
701 struct inq_needpin_s *parm = opaque;
702 char *pin;
703 size_t pinlen;
704 int rc;
706 if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
708 line += 7;
709 while (*line == ' ')
710 line++;
712 pinlen = 90;
713 pin = gcry_malloc_secure (pinlen);
714 if (!pin)
715 return out_of_core ();
717 rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
718 if (!rc)
719 rc = assuan_send_data (parm->ctx, pin, pinlen);
720 xfree (pin);
722 else if (!strncmp (line, "POPUPKEYPADPROMPT", 17)
723 && (line[17] == ' ' || !line[17]))
725 line += 17;
726 while (*line == ' ')
727 line++;
729 rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
731 else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19)
732 && (line[19] == ' ' || !line[19]))
734 rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
736 else if (parm->passthru)
738 unsigned char *value;
739 size_t valuelen;
740 int rest;
741 int needrest = !strncmp (line, "KEYDATA", 8);
743 /* Pass the inquiry up to our caller. We limit the maximum
744 amount to an arbitrary value. As we know that the KEYDATA
745 enquiry is pretty sensitive we disable logging then */
746 if ((rest = (needrest
747 && !assuan_get_flag (parm->passthru, ASSUAN_CONFIDENTIAL))))
748 assuan_begin_confidential (parm->passthru);
749 rc = assuan_inquire (parm->passthru, line, &value, &valuelen, 8096);
750 if (rest)
751 assuan_end_confidential (parm->passthru);
752 if (!rc)
754 if ((rest = (needrest
755 && !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL))))
756 assuan_begin_confidential (parm->ctx);
757 rc = assuan_send_data (parm->ctx, value, valuelen);
758 if (rest)
759 assuan_end_confidential (parm->ctx);
760 xfree (value);
762 else
763 log_error ("error forwarding inquiry `%s': %s\n",
764 line, gpg_strerror (rc));
766 else
768 log_error ("unsupported inquiry `%s'\n", line);
769 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
772 return rc;
777 /* Create a signature using the current card */
779 agent_card_pksign (ctrl_t ctrl,
780 const char *keyid,
781 int (*getpin_cb)(void *, const char *, char*, size_t),
782 void *getpin_cb_arg,
783 const unsigned char *indata, size_t indatalen,
784 unsigned char **r_buf, size_t *r_buflen)
786 int rc, i;
787 char *p, line[ASSUAN_LINELENGTH];
788 membuf_t data;
789 struct inq_needpin_s inqparm;
790 size_t len;
791 unsigned char *sigbuf;
792 size_t sigbuflen;
794 *r_buf = NULL;
795 rc = start_scd (ctrl);
796 if (rc)
797 return rc;
799 if (indatalen*2 + 50 > DIM(line))
800 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
802 sprintf (line, "SETDATA ");
803 p = line + strlen (line);
804 for (i=0; i < indatalen ; i++, p += 2 )
805 sprintf (p, "%02X", indata[i]);
806 rc = assuan_transact (ctrl->scd_local->ctx, line,
807 NULL, NULL, NULL, NULL, NULL, NULL);
808 if (rc)
809 return unlock_scd (ctrl, rc);
811 init_membuf (&data, 1024);
812 inqparm.ctx = ctrl->scd_local->ctx;
813 inqparm.getpin_cb = getpin_cb;
814 inqparm.getpin_cb_arg = getpin_cb_arg;
815 inqparm.passthru = 0;
816 snprintf (line, DIM(line)-1,
817 ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
818 line[DIM(line)-1] = 0;
819 rc = assuan_transact (ctrl->scd_local->ctx, line,
820 membuf_data_cb, &data,
821 inq_needpin, &inqparm,
822 NULL, NULL);
823 if (rc)
825 xfree (get_membuf (&data, &len));
826 return unlock_scd (ctrl, rc);
828 sigbuf = get_membuf (&data, &sigbuflen);
830 /* Create an S-expression from it which is formatted like this:
831 "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
832 *r_buflen = 21 + 11 + sigbuflen + 4;
833 p = xtrymalloc (*r_buflen);
834 *r_buf = (unsigned char*)p;
835 if (!p)
836 return unlock_scd (ctrl, out_of_core ());
837 p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
838 sprintf (p, "%u:", (unsigned int)sigbuflen);
839 p += strlen (p);
840 memcpy (p, sigbuf, sigbuflen);
841 p += sigbuflen;
842 strcpy (p, ")))");
843 xfree (sigbuf);
845 assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
846 return unlock_scd (ctrl, 0);
849 /* Decipher INDATA using the current card. Note that the returned value is */
851 agent_card_pkdecrypt (ctrl_t ctrl,
852 const char *keyid,
853 int (*getpin_cb)(void *, const char *, char*, size_t),
854 void *getpin_cb_arg,
855 const unsigned char *indata, size_t indatalen,
856 char **r_buf, size_t *r_buflen)
858 int rc, i;
859 char *p, line[ASSUAN_LINELENGTH];
860 membuf_t data;
861 struct inq_needpin_s inqparm;
862 size_t len;
864 *r_buf = NULL;
865 rc = start_scd (ctrl);
866 if (rc)
867 return rc;
869 /* FIXME: use secure memory where appropriate */
870 if (indatalen*2 + 50 > DIM(line))
871 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
873 sprintf (line, "SETDATA ");
874 p = line + strlen (line);
875 for (i=0; i < indatalen ; i++, p += 2 )
876 sprintf (p, "%02X", indata[i]);
877 rc = assuan_transact (ctrl->scd_local->ctx, line,
878 NULL, NULL, NULL, NULL, NULL, NULL);
879 if (rc)
880 return unlock_scd (ctrl, rc);
882 init_membuf (&data, 1024);
883 inqparm.ctx = ctrl->scd_local->ctx;
884 inqparm.getpin_cb = getpin_cb;
885 inqparm.getpin_cb_arg = getpin_cb_arg;
886 inqparm.passthru = 0;
887 snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
888 line[DIM(line)-1] = 0;
889 rc = assuan_transact (ctrl->scd_local->ctx, line,
890 membuf_data_cb, &data,
891 inq_needpin, &inqparm,
892 NULL, NULL);
893 if (rc)
895 xfree (get_membuf (&data, &len));
896 return unlock_scd (ctrl, rc);
898 *r_buf = get_membuf (&data, r_buflen);
899 if (!*r_buf)
900 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
902 return unlock_scd (ctrl, 0);
907 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
909 agent_card_readcert (ctrl_t ctrl,
910 const char *id, char **r_buf, size_t *r_buflen)
912 int rc;
913 char line[ASSUAN_LINELENGTH];
914 membuf_t data;
915 size_t len;
917 *r_buf = NULL;
918 rc = start_scd (ctrl);
919 if (rc)
920 return rc;
922 init_membuf (&data, 1024);
923 snprintf (line, DIM(line)-1, "READCERT %s", id);
924 line[DIM(line)-1] = 0;
925 rc = assuan_transact (ctrl->scd_local->ctx, line,
926 membuf_data_cb, &data,
927 NULL, NULL,
928 NULL, NULL);
929 if (rc)
931 xfree (get_membuf (&data, &len));
932 return unlock_scd (ctrl, rc);
934 *r_buf = get_membuf (&data, r_buflen);
935 if (!*r_buf)
936 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
938 return unlock_scd (ctrl, 0);
943 /* Read a key with ID and return it in an allocate buffer pointed to
944 by r_BUF as a valid S-expression. */
946 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
948 int rc;
949 char line[ASSUAN_LINELENGTH];
950 membuf_t data;
951 size_t len, buflen;
953 *r_buf = NULL;
954 rc = start_scd (ctrl);
955 if (rc)
956 return rc;
958 init_membuf (&data, 1024);
959 snprintf (line, DIM(line)-1, "READKEY %s", id);
960 line[DIM(line)-1] = 0;
961 rc = assuan_transact (ctrl->scd_local->ctx, line,
962 membuf_data_cb, &data,
963 NULL, NULL,
964 NULL, NULL);
965 if (rc)
967 xfree (get_membuf (&data, &len));
968 return unlock_scd (ctrl, rc);
970 *r_buf = get_membuf (&data, &buflen);
971 if (!*r_buf)
972 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
974 if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
976 xfree (*r_buf); *r_buf = NULL;
977 return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
980 return unlock_scd (ctrl, 0);
985 /* Type used with the card_getattr_cb. */
986 struct card_getattr_parm_s {
987 const char *keyword; /* Keyword to look for. */
988 size_t keywordlen; /* strlen of KEYWORD. */
989 char *data; /* Malloced and unescaped data. */
990 int error; /* ERRNO value or 0 on success. */
993 /* Callback function for agent_card_getattr. */
994 static assuan_error_t
995 card_getattr_cb (void *opaque, const char *line)
997 struct card_getattr_parm_s *parm = opaque;
998 const char *keyword = line;
999 int keywordlen;
1001 if (parm->data)
1002 return 0; /* We want only the first occurrence. */
1004 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1006 while (spacep (line))
1007 line++;
1009 if (keywordlen == parm->keywordlen
1010 && !memcmp (keyword, parm->keyword, keywordlen))
1012 parm->data = percent_plus_unescape ((const unsigned char*)line, 0xff);
1013 if (!parm->data)
1014 parm->error = errno;
1017 return 0;
1021 /* Call the agent to retrieve a single line data object. On success
1022 the object is malloced and stored at RESULT; it is guaranteed that
1023 NULL is never stored in this case. On error an error code is
1024 returned and NULL stored at RESULT. */
1025 gpg_error_t
1026 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
1028 int err;
1029 struct card_getattr_parm_s parm;
1030 char line[ASSUAN_LINELENGTH];
1032 *result = NULL;
1034 if (!*name)
1035 return gpg_error (GPG_ERR_INV_VALUE);
1037 memset (&parm, 0, sizeof parm);
1038 parm.keyword = name;
1039 parm.keywordlen = strlen (name);
1041 /* We assume that NAME does not need escaping. */
1042 if (8 + strlen (name) > DIM(line)-1)
1043 return gpg_error (GPG_ERR_TOO_LARGE);
1044 stpcpy (stpcpy (line, "GETATTR "), name);
1046 err = start_scd (ctrl);
1047 if (err)
1048 return err;
1050 err = assuan_transact (ctrl->scd_local->ctx, line,
1051 NULL, NULL, NULL, NULL,
1052 card_getattr_cb, &parm);
1053 if (!err && parm.error)
1054 err = gpg_error_from_errno (parm.error);
1056 if (!err && !parm.data)
1057 err = gpg_error (GPG_ERR_NO_DATA);
1059 if (!err)
1060 *result = parm.data;
1061 else
1062 xfree (parm.data);
1064 return unlock_scd (ctrl, err);
1070 static int
1071 pass_status_thru (void *opaque, const char *line)
1073 assuan_context_t ctx = opaque;
1074 char keyword[200];
1075 int i;
1077 for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
1078 keyword[i] = *line;
1079 keyword[i] = 0;
1080 /* truncate any remaining keyword stuff. */
1081 for (; *line && !spacep (line); line++)
1083 while (spacep (line))
1084 line++;
1086 assuan_write_status (ctx, keyword, line);
1087 return 0;
1090 static int
1091 pass_data_thru (void *opaque, const void *buffer, size_t length)
1093 assuan_context_t ctx = opaque;
1095 assuan_send_data (ctx, buffer, length);
1096 return 0;
1100 /* Send the line CMDLINE with command for the SCDdaemon to it and send
1101 all status messages back. This command is used as a general quoting
1102 mechanism to pass everything verbatim to SCDAEMON. The PIN
1103 inquiry is handled inside gpg-agent. */
1105 agent_card_scd (ctrl_t ctrl, const char *cmdline,
1106 int (*getpin_cb)(void *, const char *, char*, size_t),
1107 void *getpin_cb_arg, void *assuan_context)
1109 int rc;
1110 struct inq_needpin_s inqparm;
1112 rc = start_scd (ctrl);
1113 if (rc)
1114 return rc;
1116 inqparm.ctx = ctrl->scd_local->ctx;
1117 inqparm.getpin_cb = getpin_cb;
1118 inqparm.getpin_cb_arg = getpin_cb_arg;
1119 inqparm.passthru = assuan_context;
1120 rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1121 pass_data_thru, assuan_context,
1122 inq_needpin, &inqparm,
1123 pass_status_thru, assuan_context);
1124 if (rc)
1126 return unlock_scd (ctrl, rc);
1129 return unlock_scd (ctrl, 0);