2006-10-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / agent / call-scd.c
blob2f91e1e840a8b20baad3527f327ea14d6d38a04f
1 /* call-scd.c - fork of the scdaemon to do SC operations
2 * Copyright (C) 2001, 2002, 2005 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 2 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 #include <config.h>
23 #include <errno.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <ctype.h>
28 #include <assert.h>
29 #include <unistd.h>
30 #include <signal.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #ifndef HAVE_W32_SYSTEM
34 #include <sys/wait.h>
35 #endif
36 #include <pth.h>
38 #include "agent.h"
39 #include <assuan.h>
41 #ifdef _POSIX_OPEN_MAX
42 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
43 #else
44 #define MAX_OPEN_FDS 20
45 #endif
47 /* Definition of module local data of the CTRL structure. */
48 struct scd_local_s
50 /* We keep a list of all allocated context with a an achnor at
51 SCD_LOCAL_LIST (see below). */
52 struct scd_local_s *next_local;
54 /* We need to get back to the ctrl object actually referencing this
55 structure. This is really an awkward way of enumerint the lcoal
56 contects. A much cleaner way would be to keep a global list of
57 ctrl objects to enumerate them. */
58 ctrl_t ctrl_backlink;
60 assuan_context_t ctx; /* NULL or session context for the SCdaemon
61 used with this connection. */
62 int locked; /* This flag is used to assert proper use of
63 start_scd and unlock_scd. */
68 /* Callback parameter for learn card */
69 struct learn_parm_s
71 void (*kpinfo_cb)(void*, const char *);
72 void *kpinfo_cb_arg;
73 void (*certinfo_cb)(void*, const char *);
74 void *certinfo_cb_arg;
75 void (*sinfo_cb)(void*, const char *, size_t, const char *);
76 void *sinfo_cb_arg;
79 struct inq_needpin_s
81 assuan_context_t ctx;
82 int (*getpin_cb)(void *, const char *, char*, size_t);
83 void *getpin_cb_arg;
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 if (!(m->mx_state & PTH_MUTEX_INITIALIZED))
139 log_printf ("not_initialized");
140 else if (!(m->mx_state & PTH_MUTEX_LOCKED))
141 log_printf ("not_locked");
142 else
143 log_printf ("locked tid=0x%lx count=%lu", (long)m->mx_owner, m->mx_count);
147 /* This function may be called to print infromation pertaining to the
148 current state of this module to the log. */
149 void
150 agent_scd_dump_state (void)
152 log_info ("agent_scd_dump_state: scd_lock=");
153 dump_mutex_state (&start_scd_lock);
154 log_printf ("\n");
155 log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
156 primary_scd_ctx,
157 (long)assuan_get_pid (primary_scd_ctx),
158 primary_scd_ctx_reusable);
159 if (socket_name)
160 log_info ("agent_scd_dump_state: socket=`%s'\n", socket_name);
164 /* The unlock_scd function shall be called after having accessed the
165 SCD. It is currently not very useful but gives an opportunity to
166 keep track of connections currently calling SCD. Note that the
167 "lock" operation is done by the start_scd() function which must be
168 called and error checked before any SCD operation. CTRL is the
169 usual connection context and RC the error code to be passed trhough
170 the function. */
171 static int
172 unlock_scd (ctrl_t ctrl, int rc)
174 if (ctrl->scd_local->locked != 1)
176 log_error ("unlock_scd: invalid lock count (%d)\n",
177 ctrl->scd_local->locked);
178 if (!rc)
179 rc = gpg_error (GPG_ERR_INTERNAL);
181 ctrl->scd_local->locked = 0;
182 return rc;
185 /* To make sure we leave no secrets in our image after forking of the
186 scdaemon, we use this callback. */
187 static void
188 atfork_cb (void *opaque, int where)
190 if (!where)
191 gcry_control (GCRYCTL_TERM_SECMEM);
195 /* Fork off the SCdaemon if this has not already been done. Lock the
196 daemon and make sure that a proper context has been setup in CTRL.
197 This function might also lock the daemon, which means that the
198 caller must call unlock_scd after this fucntion has returned
199 success and the actual Assuan transaction been done. */
200 static int
201 start_scd (ctrl_t ctrl)
203 gpg_error_t err = 0;
204 const char *pgmname;
205 assuan_context_t ctx;
206 const char *argv[3];
207 int no_close_list[3];
208 int i;
209 int rc;
211 if (opt.disable_scdaemon)
212 return gpg_error (GPG_ERR_NOT_SUPPORTED);
214 /* If this is the first call for this session, setup the local data
215 structure. */
216 if (!ctrl->scd_local)
218 ctrl->scd_local = xtrycalloc (1, sizeof *ctrl->scd_local);
219 if (!ctrl->scd_local)
220 return gpg_error_from_syserror ();
221 ctrl->scd_local->ctrl_backlink = ctrl;
222 ctrl->scd_local->next_local = scd_local_list;
223 scd_local_list = ctrl->scd_local;
227 /* Assert that the lock count is as expected. */
228 if (ctrl->scd_local->locked)
230 log_error ("start_scd: invalid lock count (%d)\n",
231 ctrl->scd_local->locked);
232 return gpg_error (GPG_ERR_INTERNAL);
234 ctrl->scd_local->locked++;
236 if (ctrl->scd_local->ctx)
237 return 0; /* Okay, the context is fine. We used to test for an
238 alive context here and do an disconnect. Now that we
239 have a ticker function to check for it, it is easier
240 not to check here but to let the connection run on an
241 error instead. */
244 /* We need to protect the following code. */
245 if (!pth_mutex_acquire (&start_scd_lock, 0, NULL))
247 log_error ("failed to acquire the start_scd lock: %s\n",
248 strerror (errno));
249 return gpg_error (GPG_ERR_INTERNAL);
252 /* Check whether the pipe server has already been started and in
253 this case either reuse a lingering pipe connection or establish a
254 new socket based one. */
255 if (primary_scd_ctx && primary_scd_ctx_reusable)
257 ctx = primary_scd_ctx;
258 primary_scd_ctx_reusable = 0;
259 if (opt.verbose)
260 log_info ("new connection to SCdaemon established (reusing)\n");
261 goto leave;
264 if (socket_name)
266 rc = assuan_socket_connect (&ctx, socket_name, 0);
267 if (rc)
269 log_error ("can't connect to socket `%s': %s\n",
270 socket_name, gpg_strerror (rc));
271 err = gpg_error (GPG_ERR_NO_SCDAEMON);
272 goto leave;
275 if (opt.verbose)
276 log_info ("new connection to SCdaemon established\n");
277 goto leave;
280 if (primary_scd_ctx)
282 log_info ("SCdaemon is running but won't accept further connections\n");
283 err = gpg_error (GPG_ERR_NO_SCDAEMON);
284 goto leave;
287 /* Nope, it has not been started. Fire it up now. */
288 if (opt.verbose)
289 log_info ("no running SCdaemon - starting it\n");
291 if (fflush (NULL))
293 err = gpg_error (gpg_err_code_from_errno (errno));
294 log_error ("error flushing pending output: %s\n", strerror (errno));
295 goto leave;
298 if (!opt.scdaemon_program || !*opt.scdaemon_program)
299 opt.scdaemon_program = GNUPG_DEFAULT_SCDAEMON;
300 if ( !(pgmname = strrchr (opt.scdaemon_program, '/')))
301 pgmname = opt.scdaemon_program;
302 else
303 pgmname++;
305 argv[0] = pgmname;
306 argv[1] = "--multi-server";
307 argv[2] = NULL;
309 i=0;
310 if (!opt.running_detached)
312 if (log_get_fd () != -1)
313 no_close_list[i++] = log_get_fd ();
314 no_close_list[i++] = fileno (stderr);
316 no_close_list[i] = -1;
318 /* Connect to the pinentry and perform initial handshaking */
319 rc = assuan_pipe_connect_ext (&ctx, opt.scdaemon_program, argv,
320 no_close_list, atfork_cb, NULL, 0);
321 if (rc)
323 log_error ("can't connect to the SCdaemon: %s\n",
324 gpg_strerror (rc));
325 err = gpg_error (GPG_ERR_NO_SCDAEMON);
326 goto leave;
329 if (opt.verbose)
330 log_debug ("first connection to SCdaemon established\n");
332 /* Get the name of the additional socket opened by scdaemon. */
334 membuf_t data;
335 unsigned char *databuf;
336 size_t datalen;
338 xfree (socket_name);
339 socket_name = NULL;
340 init_membuf (&data, 256);
341 assuan_transact (ctx, "GETINFO socket_name",
342 membuf_data_cb, &data, NULL, NULL, NULL, NULL);
344 databuf = get_membuf (&data, &datalen);
345 if (databuf && datalen)
347 socket_name = xtrymalloc (datalen + 1);
348 if (!socket_name)
349 log_error ("warning: can't store socket name: %s\n",
350 strerror (errno));
351 else
353 memcpy (socket_name, databuf, datalen);
354 socket_name[datalen] = 0;
355 if (DBG_ASSUAN)
356 log_debug ("additional connections at `%s'\n", socket_name);
359 xfree (databuf);
362 /* Tell the scdaemon we want him to send us an event signal. */
363 #ifndef HAVE_W32_SYSTEM
365 char buf[100];
367 sprintf (buf, "OPTION event-signal=%d", SIGUSR2);
368 assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
370 #endif
372 primary_scd_ctx = ctx;
373 primary_scd_ctx_reusable = 0;
375 leave:
376 if (err)
378 unlock_scd (ctrl, err);
380 else
382 ctrl->scd_local->ctx = ctx;
384 if (!pth_mutex_release (&start_scd_lock))
385 log_error ("failed to release the start_scd lock: %s\n", strerror (errno));
386 return err;
390 /* Check whether the Scdaemon is still alive and clean it up if not. */
391 void
392 agent_scd_check_aliveness (void)
394 pth_event_t evt;
395 pid_t pid;
396 int rc;
398 if (!primary_scd_ctx)
399 return; /* No scdaemon running. */
401 /* This is not a critical function so we use a short timeout while
402 acquiring the lock. */
403 evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
404 if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
406 if (pth_event_occurred (evt))
408 if (opt.verbose > 1)
409 log_info ("failed to acquire the start_scd lock while"
410 " doing an aliveness check: %s\n", "timeout");
412 else
413 log_error ("failed to acquire the start_scd lock while"
414 " doing an aliveness check: %s\n", strerror (errno));
415 pth_event_free (evt, PTH_FREE_THIS);
416 return;
418 pth_event_free (evt, PTH_FREE_THIS);
420 if (primary_scd_ctx)
422 pid = assuan_get_pid (primary_scd_ctx);
423 if (pid != (pid_t)(-1) && pid
424 && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
426 /* Okay, scdaemon died. Disconnect the primary connection
427 now but take care that it won't do another wait. Also
428 cleanup all other connections and release their
429 resources. The next use will start a new daemon then.
430 Due to the use of the START_SCD_LOCAL we are sure that
431 none of these context are actually in use. */
432 struct scd_local_s *sl;
434 assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
435 assuan_disconnect (primary_scd_ctx);
437 for (sl=scd_local_list; sl; sl = sl->next_local)
439 if (sl->ctx)
441 if (sl->ctx != primary_scd_ctx)
442 assuan_disconnect (sl->ctx);
443 sl->ctx = NULL;
447 primary_scd_ctx = NULL;
448 primary_scd_ctx_reusable = 0;
450 xfree (socket_name);
451 socket_name = NULL;
455 if (!pth_mutex_release (&start_scd_lock))
456 log_error ("failed to release the start_scd lock while"
457 " doing the aliveness check: %s\n", strerror (errno));
462 /* Reset the SCD if it has been used. Actually it is not a reset but
463 a cleanup of resources used by the current connection. */
465 agent_reset_scd (ctrl_t ctrl)
467 if (ctrl->scd_local)
469 if (ctrl->scd_local->ctx)
471 /* We can't disconnect the primary context because libassuan
472 does a waitpid on it and thus the system would hang.
473 Instead we send a reset and keep that connection for
474 reuse. */
475 if (ctrl->scd_local->ctx == primary_scd_ctx)
477 /* Send a RESTART to the SCD. This is required for the
478 primary connection as a kind of virtual EOF; we don't
479 have another way to tell it that the next command
480 should be viewed as if a new connection has been
481 made. For the non-primary connections this is not
482 needed as we simply close the socket. We don't check
483 for an error here because the RESTART may fail for
484 example if the scdaemon has already been terminated.
485 Anyway, we need to set the reusable flag to make sure
486 that the aliveness check can clean it up. */
487 assuan_transact (primary_scd_ctx, "RESTART",
488 NULL, NULL, NULL, NULL, NULL, NULL);
489 primary_scd_ctx_reusable = 1;
491 else
492 assuan_disconnect (ctrl->scd_local->ctx);
493 ctrl->scd_local->ctx = NULL;
496 /* Remove the local context from our list and release it. */
497 if (!scd_local_list)
498 BUG ();
499 else if (scd_local_list == ctrl->scd_local)
500 scd_local_list = ctrl->scd_local->next_local;
501 else
503 struct scd_local_s *sl;
505 for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
506 if (sl->next_local == ctrl->scd_local)
507 break;
508 if (!sl->next_local)
509 BUG ();
510 sl->next_local = ctrl->scd_local->next_local;
512 xfree (ctrl->scd_local);
513 ctrl->scd_local = NULL;
516 return 0;
521 /* Return a new malloced string by unescaping the string S. Escaping
522 is percent escaping and '+'/space mapping. A binary Nul will
523 silently be replaced by a 0xFF. Function returns NULL to indicate
524 an out of memory status. */
525 static char *
526 unescape_status_string (const unsigned char *s)
528 char *buffer, *d;
530 buffer = d = xtrymalloc (strlen ((const char*)s)+1);
531 if (!buffer)
532 return NULL;
533 while (*s)
535 if (*s == '%' && s[1] && s[2])
537 s++;
538 *d = xtoi_2 (s);
539 if (!*d)
540 *d = '\xff';
541 d++;
542 s += 2;
544 else if (*s == '+')
546 *d++ = ' ';
547 s++;
549 else
550 *d++ = *s++;
552 *d = 0;
553 return buffer;
558 static int
559 learn_status_cb (void *opaque, const char *line)
561 struct learn_parm_s *parm = opaque;
562 const char *keyword = line;
563 int keywordlen;
565 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
567 while (spacep (line))
568 line++;
569 if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
571 parm->certinfo_cb (parm->certinfo_cb_arg, line);
573 else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
575 parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
577 else if (keywordlen && *line)
579 parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
582 return 0;
585 /* Perform the LEARN command and return a list of all private keys
586 stored on the card. */
588 agent_card_learn (ctrl_t ctrl,
589 void (*kpinfo_cb)(void*, const char *),
590 void *kpinfo_cb_arg,
591 void (*certinfo_cb)(void*, const char *),
592 void *certinfo_cb_arg,
593 void (*sinfo_cb)(void*, const char *, size_t, const char *),
594 void *sinfo_cb_arg)
596 int rc;
597 struct learn_parm_s parm;
599 rc = start_scd (ctrl);
600 if (rc)
601 return rc;
603 memset (&parm, 0, sizeof parm);
604 parm.kpinfo_cb = kpinfo_cb;
605 parm.kpinfo_cb_arg = kpinfo_cb_arg;
606 parm.certinfo_cb = certinfo_cb;
607 parm.certinfo_cb_arg = certinfo_cb_arg;
608 parm.sinfo_cb = sinfo_cb;
609 parm.sinfo_cb_arg = sinfo_cb_arg;
610 rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
611 NULL, NULL, NULL, NULL,
612 learn_status_cb, &parm);
613 if (rc)
614 return unlock_scd (ctrl, rc);
616 return unlock_scd (ctrl, 0);
621 static int
622 get_serialno_cb (void *opaque, const char *line)
624 char **serialno = opaque;
625 const char *keyword = line;
626 const char *s;
627 int keywordlen, n;
629 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
631 while (spacep (line))
632 line++;
634 if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
636 if (*serialno)
637 return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
638 for (n=0,s=line; hexdigitp (s); s++, n++)
640 if (!n || (n&1)|| !(spacep (s) || !*s) )
641 return gpg_error (GPG_ERR_ASS_PARAMETER);
642 *serialno = xtrymalloc (n+1);
643 if (!*serialno)
644 return out_of_core ();
645 memcpy (*serialno, line, n);
646 (*serialno)[n] = 0;
649 return 0;
652 /* Return the serial number of the card or an appropriate error. The
653 serial number is returned as a hexstring. */
655 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
657 int rc;
658 char *serialno = NULL;
660 rc = start_scd (ctrl);
661 if (rc)
662 return rc;
664 rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
665 NULL, NULL, NULL, NULL,
666 get_serialno_cb, &serialno);
667 if (rc)
669 xfree (serialno);
670 return unlock_scd (ctrl, rc);
672 *r_serialno = serialno;
673 return unlock_scd (ctrl, 0);
679 static int
680 membuf_data_cb (void *opaque, const void *buffer, size_t length)
682 membuf_t *data = opaque;
684 if (buffer)
685 put_membuf (data, buffer, length);
686 return 0;
689 /* Handle the NEEDPIN inquiry. */
690 static int
691 inq_needpin (void *opaque, const char *line)
693 struct inq_needpin_s *parm = opaque;
694 char *pin;
695 size_t pinlen;
696 int rc;
698 if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
700 line += 7;
701 while (*line == ' ')
702 line++;
704 pinlen = 90;
705 pin = gcry_malloc_secure (pinlen);
706 if (!pin)
707 return out_of_core ();
709 rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
710 if (!rc)
711 rc = assuan_send_data (parm->ctx, pin, pinlen);
712 xfree (pin);
714 else if (!strncmp (line, "KEYPADINFO", 10) && (line[10] == ' ' || !line[10]))
716 size_t code;
717 char *endp;
719 code = strtoul (line+10, &endp, 10);
720 line = endp;
721 while (*line == ' ')
722 line++;
724 rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, code);
726 else
728 log_error ("unsupported inquiry `%s'\n", line);
729 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
732 return rc;
737 /* Create a signature using the current card */
739 agent_card_pksign (ctrl_t ctrl,
740 const char *keyid,
741 int (*getpin_cb)(void *, const char *, char*, size_t),
742 void *getpin_cb_arg,
743 const unsigned char *indata, size_t indatalen,
744 unsigned char **r_buf, size_t *r_buflen)
746 int rc, i;
747 char *p, line[ASSUAN_LINELENGTH];
748 membuf_t data;
749 struct inq_needpin_s inqparm;
750 size_t len;
751 unsigned char *sigbuf;
752 size_t sigbuflen;
754 *r_buf = NULL;
755 rc = start_scd (ctrl);
756 if (rc)
757 return rc;
759 if (indatalen*2 + 50 > DIM(line))
760 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
762 sprintf (line, "SETDATA ");
763 p = line + strlen (line);
764 for (i=0; i < indatalen ; i++, p += 2 )
765 sprintf (p, "%02X", indata[i]);
766 rc = assuan_transact (ctrl->scd_local->ctx, line,
767 NULL, NULL, NULL, NULL, NULL, NULL);
768 if (rc)
769 return unlock_scd (ctrl, rc);
771 init_membuf (&data, 1024);
772 inqparm.ctx = ctrl->scd_local->ctx;
773 inqparm.getpin_cb = getpin_cb;
774 inqparm.getpin_cb_arg = getpin_cb_arg;
775 snprintf (line, DIM(line)-1,
776 ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
777 line[DIM(line)-1] = 0;
778 rc = assuan_transact (ctrl->scd_local->ctx, line,
779 membuf_data_cb, &data,
780 inq_needpin, &inqparm,
781 NULL, NULL);
782 if (rc)
784 xfree (get_membuf (&data, &len));
785 return unlock_scd (ctrl, rc);
787 sigbuf = get_membuf (&data, &sigbuflen);
789 /* Create an S-expression from it which is formatted like this:
790 "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
791 *r_buflen = 21 + 11 + sigbuflen + 4;
792 p = xtrymalloc (*r_buflen);
793 *r_buf = (unsigned char*)p;
794 if (!p)
795 return unlock_scd (ctrl, out_of_core ());
796 p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
797 sprintf (p, "%u:", (unsigned int)sigbuflen);
798 p += strlen (p);
799 memcpy (p, sigbuf, sigbuflen);
800 p += sigbuflen;
801 strcpy (p, ")))");
802 xfree (sigbuf);
804 assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
805 return unlock_scd (ctrl, 0);
808 /* Decipher INDATA using the current card. Note that the returned value is */
810 agent_card_pkdecrypt (ctrl_t ctrl,
811 const char *keyid,
812 int (*getpin_cb)(void *, const char *, char*, size_t),
813 void *getpin_cb_arg,
814 const unsigned char *indata, size_t indatalen,
815 char **r_buf, size_t *r_buflen)
817 int rc, i;
818 char *p, line[ASSUAN_LINELENGTH];
819 membuf_t data;
820 struct inq_needpin_s inqparm;
821 size_t len;
823 *r_buf = NULL;
824 rc = start_scd (ctrl);
825 if (rc)
826 return rc;
828 /* FIXME: use secure memory where appropriate */
829 if (indatalen*2 + 50 > DIM(line))
830 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
832 sprintf (line, "SETDATA ");
833 p = line + strlen (line);
834 for (i=0; i < indatalen ; i++, p += 2 )
835 sprintf (p, "%02X", indata[i]);
836 rc = assuan_transact (ctrl->scd_local->ctx, line,
837 NULL, NULL, NULL, NULL, NULL, NULL);
838 if (rc)
839 return unlock_scd (ctrl, rc);
841 init_membuf (&data, 1024);
842 inqparm.ctx = ctrl->scd_local->ctx;
843 inqparm.getpin_cb = getpin_cb;
844 inqparm.getpin_cb_arg = getpin_cb_arg;
845 snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
846 line[DIM(line)-1] = 0;
847 rc = assuan_transact (ctrl->scd_local->ctx, line,
848 membuf_data_cb, &data,
849 inq_needpin, &inqparm,
850 NULL, NULL);
851 if (rc)
853 xfree (get_membuf (&data, &len));
854 return unlock_scd (ctrl, rc);
856 *r_buf = get_membuf (&data, r_buflen);
857 if (!*r_buf)
858 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
860 return unlock_scd (ctrl, 0);
865 /* Read a certificate with ID into R_BUF and R_BUFLEN. */
867 agent_card_readcert (ctrl_t ctrl,
868 const char *id, char **r_buf, size_t *r_buflen)
870 int rc;
871 char line[ASSUAN_LINELENGTH];
872 membuf_t data;
873 size_t len;
875 *r_buf = NULL;
876 rc = start_scd (ctrl);
877 if (rc)
878 return rc;
880 init_membuf (&data, 1024);
881 snprintf (line, DIM(line)-1, "READCERT %s", id);
882 line[DIM(line)-1] = 0;
883 rc = assuan_transact (ctrl->scd_local->ctx, line,
884 membuf_data_cb, &data,
885 NULL, NULL,
886 NULL, NULL);
887 if (rc)
889 xfree (get_membuf (&data, &len));
890 return unlock_scd (ctrl, rc);
892 *r_buf = get_membuf (&data, r_buflen);
893 if (!*r_buf)
894 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
896 return unlock_scd (ctrl, 0);
901 /* Read a key with ID and return it in an allocate buffer pointed to
902 by r_BUF as a valid S-expression. */
904 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
906 int rc;
907 char line[ASSUAN_LINELENGTH];
908 membuf_t data;
909 size_t len, buflen;
911 *r_buf = NULL;
912 rc = start_scd (ctrl);
913 if (rc)
914 return rc;
916 init_membuf (&data, 1024);
917 snprintf (line, DIM(line)-1, "READKEY %s", id);
918 line[DIM(line)-1] = 0;
919 rc = assuan_transact (ctrl->scd_local->ctx, line,
920 membuf_data_cb, &data,
921 NULL, NULL,
922 NULL, NULL);
923 if (rc)
925 xfree (get_membuf (&data, &len));
926 return unlock_scd (ctrl, rc);
928 *r_buf = get_membuf (&data, &buflen);
929 if (!*r_buf)
930 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
932 if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
934 xfree (*r_buf); *r_buf = NULL;
935 return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
938 return unlock_scd (ctrl, 0);
943 /* Type used with the card_getattr_cb. */
944 struct card_getattr_parm_s {
945 const char *keyword; /* Keyword to look for. */
946 size_t keywordlen; /* strlen of KEYWORD. */
947 char *data; /* Malloced and unescaped data. */
948 int error; /* ERRNO value or 0 on success. */
951 /* Callback function for agent_card_getattr. */
952 static assuan_error_t
953 card_getattr_cb (void *opaque, const char *line)
955 struct card_getattr_parm_s *parm = opaque;
956 const char *keyword = line;
957 int keywordlen;
959 if (parm->data)
960 return 0; /* We want only the first occurrence. */
962 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
964 while (spacep (line))
965 line++;
967 if (keywordlen == parm->keywordlen
968 && !memcmp (keyword, parm->keyword, keywordlen))
970 parm->data = unescape_status_string ((const unsigned char*)line);
971 if (!parm->data)
972 parm->error = errno;
975 return 0;
979 /* Call the agent to retrieve a single line data object. On success
980 the object is malloced and stored at RESULT; it is guaranteed that
981 NULL is never stored in this case. On error an error code is
982 returned and NULL stored at RESULT. */
983 gpg_error_t
984 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
986 int err;
987 struct card_getattr_parm_s parm;
988 char line[ASSUAN_LINELENGTH];
990 *result = NULL;
992 if (!*name)
993 return gpg_error (GPG_ERR_INV_VALUE);
995 memset (&parm, 0, sizeof parm);
996 parm.keyword = name;
997 parm.keywordlen = strlen (name);
999 /* We assume that NAME does not need escaping. */
1000 if (8 + strlen (name) > DIM(line)-1)
1001 return gpg_error (GPG_ERR_TOO_LARGE);
1002 stpcpy (stpcpy (line, "GETATTR "), name);
1004 err = start_scd (ctrl);
1005 if (err)
1006 return err;
1008 err = assuan_transact (ctrl->scd_local->ctx, line,
1009 NULL, NULL, NULL, NULL,
1010 card_getattr_cb, &parm);
1011 if (!err && parm.error)
1012 err = gpg_error_from_errno (parm.error);
1014 if (!err && !parm.data)
1015 err = gpg_error (GPG_ERR_NO_DATA);
1017 if (!err)
1018 *result = parm.data;
1019 else
1020 xfree (parm.data);
1022 return unlock_scd (ctrl, err);
1028 static int
1029 pass_status_thru (void *opaque, const char *line)
1031 assuan_context_t ctx = opaque;
1032 char keyword[200];
1033 int i;
1035 for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
1036 keyword[i] = *line;
1037 keyword[i] = 0;
1038 /* truncate any remaining keyword stuff. */
1039 for (; *line && !spacep (line); line++)
1041 while (spacep (line))
1042 line++;
1044 assuan_write_status (ctx, keyword, line);
1045 return 0;
1048 static int
1049 pass_data_thru (void *opaque, const void *buffer, size_t length)
1051 assuan_context_t ctx = opaque;
1053 assuan_send_data (ctx, buffer, length);
1054 return 0;
1058 /* Send the line CMDLINE with command for the SCDdaemon to it and send
1059 all status messages back. This command is used as a general quoting
1060 mechanism to pass everything verbatim to SCDAEMOPN. The PIN
1061 inquirey is handled inside gpg-agent. */
1063 agent_card_scd (ctrl_t ctrl, const char *cmdline,
1064 int (*getpin_cb)(void *, const char *, char*, size_t),
1065 void *getpin_cb_arg, void *assuan_context)
1067 int rc;
1068 struct inq_needpin_s inqparm;
1070 rc = start_scd (ctrl);
1071 if (rc)
1072 return rc;
1074 inqparm.ctx = ctrl->scd_local->ctx;
1075 inqparm.getpin_cb = getpin_cb;
1076 inqparm.getpin_cb_arg = getpin_cb_arg;
1077 rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1078 pass_data_thru, assuan_context,
1079 inq_needpin, &inqparm,
1080 pass_status_thru, assuan_context);
1081 if (rc)
1083 return unlock_scd (ctrl, rc);
1086 return unlock_scd (ctrl, 0);