Move password repetition from gpg to gpg-agent.
[gnupg.git] / agent / call-scd.c
blobf45e94097240570f44d3cde23e603787c9181b8b
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 active. This is a fast check without
413 any locking and might give a wrong result if another thread is about
414 to start the daemon or the daemon is about to be stopped.. */
416 agent_scd_check_running (void)
418 return !!primary_scd_ctx;
422 /* Check whether the Scdaemon is still alive and clean it up if not. */
423 void
424 agent_scd_check_aliveness (void)
426 pth_event_t evt;
427 pid_t pid;
428 #ifdef HAVE_W32_SYSTEM
429 DWORD rc;
430 #else
431 int rc;
432 #endif
434 if (!primary_scd_ctx)
435 return; /* No scdaemon running. */
437 /* This is not a critical function so we use a short timeout while
438 acquiring the lock. */
439 evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0));
440 if (!pth_mutex_acquire (&start_scd_lock, 0, evt))
442 if (pth_event_occurred (evt))
444 if (opt.verbose > 1)
445 log_info ("failed to acquire the start_scd lock while"
446 " doing an aliveness check: %s\n", "timeout");
448 else
449 log_error ("failed to acquire the start_scd lock while"
450 " doing an aliveness check: %s\n", strerror (errno));
451 pth_event_free (evt, PTH_FREE_THIS);
452 return;
454 pth_event_free (evt, PTH_FREE_THIS);
456 if (primary_scd_ctx)
458 pid = assuan_get_pid (primary_scd_ctx);
459 #ifdef HAVE_W32_SYSTEM
460 /* If we have a PID we disconnect if either GetExitProcessCode
461 fails or if ir returns the exit code of the scdaemon. 259 is
462 the error code for STILL_ALIVE. */
463 if (pid != (pid_t)(void*)(-1) && pid
464 && (!GetExitCodeProcess ((HANDLE)pid, &rc) || rc != 259))
465 #else
466 if (pid != (pid_t)(-1) && pid
467 && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
468 #endif
470 /* Okay, scdaemon died. Disconnect the primary connection
471 now but take care that it won't do another wait. Also
472 cleanup all other connections and release their
473 resources. The next use will start a new daemon then.
474 Due to the use of the START_SCD_LOCAL we are sure that
475 none of these context are actually in use. */
476 struct scd_local_s *sl;
478 assuan_set_flag (primary_scd_ctx, ASSUAN_NO_WAITPID, 1);
479 assuan_disconnect (primary_scd_ctx);
481 for (sl=scd_local_list; sl; sl = sl->next_local)
483 if (sl->ctx)
485 if (sl->ctx != primary_scd_ctx)
486 assuan_disconnect (sl->ctx);
487 sl->ctx = NULL;
491 primary_scd_ctx = NULL;
492 primary_scd_ctx_reusable = 0;
494 xfree (socket_name);
495 socket_name = NULL;
499 if (!pth_mutex_release (&start_scd_lock))
500 log_error ("failed to release the start_scd lock while"
501 " doing the aliveness check: %s\n", strerror (errno));
506 /* Reset the SCD if it has been used. Actually it is not a reset but
507 a cleanup of resources used by the current connection. */
509 agent_reset_scd (ctrl_t ctrl)
511 if (ctrl->scd_local)
513 if (ctrl->scd_local->ctx)
515 /* We can't disconnect the primary context because libassuan
516 does a waitpid on it and thus the system would hang.
517 Instead we send a reset and keep that connection for
518 reuse. */
519 if (ctrl->scd_local->ctx == primary_scd_ctx)
521 /* Send a RESTART to the SCD. This is required for the
522 primary connection as a kind of virtual EOF; we don't
523 have another way to tell it that the next command
524 should be viewed as if a new connection has been
525 made. For the non-primary connections this is not
526 needed as we simply close the socket. We don't check
527 for an error here because the RESTART may fail for
528 example if the scdaemon has already been terminated.
529 Anyway, we need to set the reusable flag to make sure
530 that the aliveness check can clean it up. */
531 assuan_transact (primary_scd_ctx, "RESTART",
532 NULL, NULL, NULL, NULL, NULL, NULL);
533 primary_scd_ctx_reusable = 1;
535 else
536 assuan_disconnect (ctrl->scd_local->ctx);
537 ctrl->scd_local->ctx = NULL;
540 /* Remove the local context from our list and release it. */
541 if (!scd_local_list)
542 BUG ();
543 else if (scd_local_list == ctrl->scd_local)
544 scd_local_list = ctrl->scd_local->next_local;
545 else
547 struct scd_local_s *sl;
549 for (sl=scd_local_list; sl->next_local; sl = sl->next_local)
550 if (sl->next_local == ctrl->scd_local)
551 break;
552 if (!sl->next_local)
553 BUG ();
554 sl->next_local = ctrl->scd_local->next_local;
556 xfree (ctrl->scd_local);
557 ctrl->scd_local = NULL;
560 return 0;
565 /* Return a new malloced string by unescaping the string S. Escaping
566 is percent escaping and '+'/space mapping. A binary Nul will
567 silently be replaced by a 0xFF. Function returns NULL to indicate
568 an out of memory status. */
569 static char *
570 unescape_status_string (const unsigned char *s)
572 char *buffer, *d;
574 buffer = d = xtrymalloc (strlen ((const char*)s)+1);
575 if (!buffer)
576 return NULL;
577 while (*s)
579 if (*s == '%' && s[1] && s[2])
581 s++;
582 *d = xtoi_2 (s);
583 if (!*d)
584 *d = '\xff';
585 d++;
586 s += 2;
588 else if (*s == '+')
590 *d++ = ' ';
591 s++;
593 else
594 *d++ = *s++;
596 *d = 0;
597 return buffer;
602 static int
603 learn_status_cb (void *opaque, const char *line)
605 struct learn_parm_s *parm = opaque;
606 const char *keyword = line;
607 int keywordlen;
609 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
611 while (spacep (line))
612 line++;
613 if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
615 parm->certinfo_cb (parm->certinfo_cb_arg, line);
617 else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
619 parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
621 else if (keywordlen && *line)
623 parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
626 return 0;
629 /* Perform the LEARN command and return a list of all private keys
630 stored on the card. */
632 agent_card_learn (ctrl_t ctrl,
633 void (*kpinfo_cb)(void*, const char *),
634 void *kpinfo_cb_arg,
635 void (*certinfo_cb)(void*, const char *),
636 void *certinfo_cb_arg,
637 void (*sinfo_cb)(void*, const char *, size_t, const char *),
638 void *sinfo_cb_arg)
640 int rc;
641 struct learn_parm_s parm;
643 rc = start_scd (ctrl);
644 if (rc)
645 return rc;
647 memset (&parm, 0, sizeof parm);
648 parm.kpinfo_cb = kpinfo_cb;
649 parm.kpinfo_cb_arg = kpinfo_cb_arg;
650 parm.certinfo_cb = certinfo_cb;
651 parm.certinfo_cb_arg = certinfo_cb_arg;
652 parm.sinfo_cb = sinfo_cb;
653 parm.sinfo_cb_arg = sinfo_cb_arg;
654 rc = assuan_transact (ctrl->scd_local->ctx, "LEARN --force",
655 NULL, NULL, NULL, NULL,
656 learn_status_cb, &parm);
657 if (rc)
658 return unlock_scd (ctrl, rc);
660 return unlock_scd (ctrl, 0);
665 static int
666 get_serialno_cb (void *opaque, const char *line)
668 char **serialno = opaque;
669 const char *keyword = line;
670 const char *s;
671 int keywordlen, n;
673 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
675 while (spacep (line))
676 line++;
678 if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
680 if (*serialno)
681 return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
682 for (n=0,s=line; hexdigitp (s); s++, n++)
684 if (!n || (n&1)|| !(spacep (s) || !*s) )
685 return gpg_error (GPG_ERR_ASS_PARAMETER);
686 *serialno = xtrymalloc (n+1);
687 if (!*serialno)
688 return out_of_core ();
689 memcpy (*serialno, line, n);
690 (*serialno)[n] = 0;
693 return 0;
696 /* Return the serial number of the card or an appropriate error. The
697 serial number is returned as a hexstring. */
699 agent_card_serialno (ctrl_t ctrl, char **r_serialno)
701 int rc;
702 char *serialno = NULL;
704 rc = start_scd (ctrl);
705 if (rc)
706 return rc;
708 rc = assuan_transact (ctrl->scd_local->ctx, "SERIALNO",
709 NULL, NULL, NULL, NULL,
710 get_serialno_cb, &serialno);
711 if (rc)
713 xfree (serialno);
714 return unlock_scd (ctrl, rc);
716 *r_serialno = serialno;
717 return unlock_scd (ctrl, 0);
723 static assuan_error_t
724 membuf_data_cb (void *opaque, const void *buffer, size_t length)
726 membuf_t *data = opaque;
728 if (buffer)
729 put_membuf (data, buffer, length);
730 return 0;
733 /* Handle the NEEDPIN inquiry. */
734 static int
735 inq_needpin (void *opaque, const char *line)
737 struct inq_needpin_s *parm = opaque;
738 char *pin;
739 size_t pinlen;
740 int rc;
742 if (!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7]))
744 line += 7;
745 while (*line == ' ')
746 line++;
748 pinlen = 90;
749 pin = gcry_malloc_secure (pinlen);
750 if (!pin)
751 return out_of_core ();
753 rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
754 if (!rc)
755 rc = assuan_send_data (parm->ctx, pin, pinlen);
756 xfree (pin);
758 else if (!strncmp (line, "POPUPKEYPADPROMPT", 17)
759 && (line[17] == ' ' || !line[17]))
761 line += 17;
762 while (*line == ' ')
763 line++;
765 rc = parm->getpin_cb (parm->getpin_cb_arg, line, NULL, 1);
767 else if (!strncmp (line, "DISMISSKEYPADPROMPT", 19)
768 && (line[19] == ' ' || !line[19]))
770 rc = parm->getpin_cb (parm->getpin_cb_arg, "", NULL, 0);
772 else if (parm->passthru)
774 unsigned char *value;
775 size_t valuelen;
776 int rest;
777 int needrest = !strncmp (line, "KEYDATA", 8);
779 /* Pass the inquiry up to our caller. We limit the maximum
780 amount to an arbitrary value. As we know that the KEYDATA
781 enquiry is pretty sensitive we disable logging then */
782 if ((rest = (needrest
783 && !assuan_get_flag (parm->passthru, ASSUAN_CONFIDENTIAL))))
784 assuan_begin_confidential (parm->passthru);
785 rc = assuan_inquire (parm->passthru, line, &value, &valuelen, 8096);
786 if (rest)
787 assuan_end_confidential (parm->passthru);
788 if (!rc)
790 if ((rest = (needrest
791 && !assuan_get_flag (parm->ctx, ASSUAN_CONFIDENTIAL))))
792 assuan_begin_confidential (parm->ctx);
793 rc = assuan_send_data (parm->ctx, value, valuelen);
794 if (rest)
795 assuan_end_confidential (parm->ctx);
796 xfree (value);
798 else
799 log_error ("error forwarding inquiry `%s': %s\n",
800 line, gpg_strerror (rc));
802 else
804 log_error ("unsupported inquiry `%s'\n", line);
805 rc = gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE);
808 return rc;
813 /* Create a signature using the current card */
815 agent_card_pksign (ctrl_t ctrl,
816 const char *keyid,
817 int (*getpin_cb)(void *, const char *, char*, size_t),
818 void *getpin_cb_arg,
819 const unsigned char *indata, size_t indatalen,
820 unsigned char **r_buf, size_t *r_buflen)
822 int rc, i;
823 char *p, line[ASSUAN_LINELENGTH];
824 membuf_t data;
825 struct inq_needpin_s inqparm;
826 size_t len;
827 unsigned char *sigbuf;
828 size_t sigbuflen;
830 *r_buf = NULL;
831 rc = start_scd (ctrl);
832 if (rc)
833 return rc;
835 if (indatalen*2 + 50 > DIM(line))
836 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
838 sprintf (line, "SETDATA ");
839 p = line + strlen (line);
840 for (i=0; i < indatalen ; i++, p += 2 )
841 sprintf (p, "%02X", indata[i]);
842 rc = assuan_transact (ctrl->scd_local->ctx, line,
843 NULL, NULL, NULL, NULL, NULL, NULL);
844 if (rc)
845 return unlock_scd (ctrl, rc);
847 init_membuf (&data, 1024);
848 inqparm.ctx = ctrl->scd_local->ctx;
849 inqparm.getpin_cb = getpin_cb;
850 inqparm.getpin_cb_arg = getpin_cb_arg;
851 inqparm.passthru = 0;
852 snprintf (line, DIM(line)-1,
853 ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid);
854 line[DIM(line)-1] = 0;
855 rc = assuan_transact (ctrl->scd_local->ctx, line,
856 membuf_data_cb, &data,
857 inq_needpin, &inqparm,
858 NULL, NULL);
859 if (rc)
861 xfree (get_membuf (&data, &len));
862 return unlock_scd (ctrl, rc);
864 sigbuf = get_membuf (&data, &sigbuflen);
866 /* Create an S-expression from it which is formatted like this:
867 "(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
868 *r_buflen = 21 + 11 + sigbuflen + 4;
869 p = xtrymalloc (*r_buflen);
870 *r_buf = (unsigned char*)p;
871 if (!p)
872 return unlock_scd (ctrl, out_of_core ());
873 p = stpcpy (p, "(7:sig-val(3:rsa(1:s" );
874 sprintf (p, "%u:", (unsigned int)sigbuflen);
875 p += strlen (p);
876 memcpy (p, sigbuf, sigbuflen);
877 p += sigbuflen;
878 strcpy (p, ")))");
879 xfree (sigbuf);
881 assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
882 return unlock_scd (ctrl, 0);
885 /* Decipher INDATA using the current card. Note that the returned value is */
887 agent_card_pkdecrypt (ctrl_t ctrl,
888 const char *keyid,
889 int (*getpin_cb)(void *, const char *, char*, size_t),
890 void *getpin_cb_arg,
891 const unsigned char *indata, size_t indatalen,
892 char **r_buf, size_t *r_buflen)
894 int rc, i;
895 char *p, line[ASSUAN_LINELENGTH];
896 membuf_t data;
897 struct inq_needpin_s inqparm;
898 size_t len;
900 *r_buf = NULL;
901 rc = start_scd (ctrl);
902 if (rc)
903 return rc;
905 /* FIXME: use secure memory where appropriate */
906 if (indatalen*2 + 50 > DIM(line))
907 return unlock_scd (ctrl, gpg_error (GPG_ERR_GENERAL));
909 sprintf (line, "SETDATA ");
910 p = line + strlen (line);
911 for (i=0; i < indatalen ; i++, p += 2 )
912 sprintf (p, "%02X", indata[i]);
913 rc = assuan_transact (ctrl->scd_local->ctx, line,
914 NULL, NULL, NULL, NULL, NULL, NULL);
915 if (rc)
916 return unlock_scd (ctrl, rc);
918 init_membuf (&data, 1024);
919 inqparm.ctx = ctrl->scd_local->ctx;
920 inqparm.getpin_cb = getpin_cb;
921 inqparm.getpin_cb_arg = getpin_cb_arg;
922 inqparm.passthru = 0;
923 snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
924 line[DIM(line)-1] = 0;
925 rc = assuan_transact (ctrl->scd_local->ctx, line,
926 membuf_data_cb, &data,
927 inq_needpin, &inqparm,
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 certificate with ID into R_BUF and R_BUFLEN. */
945 agent_card_readcert (ctrl_t ctrl,
946 const char *id, char **r_buf, size_t *r_buflen)
948 int rc;
949 char line[ASSUAN_LINELENGTH];
950 membuf_t data;
951 size_t len;
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, "READCERT %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, r_buflen);
971 if (!*r_buf)
972 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
974 return unlock_scd (ctrl, 0);
979 /* Read a key with ID and return it in an allocate buffer pointed to
980 by r_BUF as a valid S-expression. */
982 agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
984 int rc;
985 char line[ASSUAN_LINELENGTH];
986 membuf_t data;
987 size_t len, buflen;
989 *r_buf = NULL;
990 rc = start_scd (ctrl);
991 if (rc)
992 return rc;
994 init_membuf (&data, 1024);
995 snprintf (line, DIM(line)-1, "READKEY %s", id);
996 line[DIM(line)-1] = 0;
997 rc = assuan_transact (ctrl->scd_local->ctx, line,
998 membuf_data_cb, &data,
999 NULL, NULL,
1000 NULL, NULL);
1001 if (rc)
1003 xfree (get_membuf (&data, &len));
1004 return unlock_scd (ctrl, rc);
1006 *r_buf = get_membuf (&data, &buflen);
1007 if (!*r_buf)
1008 return unlock_scd (ctrl, gpg_error (GPG_ERR_ENOMEM));
1010 if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
1012 xfree (*r_buf); *r_buf = NULL;
1013 return unlock_scd (ctrl, gpg_error (GPG_ERR_INV_VALUE));
1016 return unlock_scd (ctrl, 0);
1021 /* Type used with the card_getattr_cb. */
1022 struct card_getattr_parm_s {
1023 const char *keyword; /* Keyword to look for. */
1024 size_t keywordlen; /* strlen of KEYWORD. */
1025 char *data; /* Malloced and unescaped data. */
1026 int error; /* ERRNO value or 0 on success. */
1029 /* Callback function for agent_card_getattr. */
1030 static assuan_error_t
1031 card_getattr_cb (void *opaque, const char *line)
1033 struct card_getattr_parm_s *parm = opaque;
1034 const char *keyword = line;
1035 int keywordlen;
1037 if (parm->data)
1038 return 0; /* We want only the first occurrence. */
1040 for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1042 while (spacep (line))
1043 line++;
1045 if (keywordlen == parm->keywordlen
1046 && !memcmp (keyword, parm->keyword, keywordlen))
1048 parm->data = unescape_status_string ((const unsigned char*)line);
1049 if (!parm->data)
1050 parm->error = errno;
1053 return 0;
1057 /* Call the agent to retrieve a single line data object. On success
1058 the object is malloced and stored at RESULT; it is guaranteed that
1059 NULL is never stored in this case. On error an error code is
1060 returned and NULL stored at RESULT. */
1061 gpg_error_t
1062 agent_card_getattr (ctrl_t ctrl, const char *name, char **result)
1064 int err;
1065 struct card_getattr_parm_s parm;
1066 char line[ASSUAN_LINELENGTH];
1068 *result = NULL;
1070 if (!*name)
1071 return gpg_error (GPG_ERR_INV_VALUE);
1073 memset (&parm, 0, sizeof parm);
1074 parm.keyword = name;
1075 parm.keywordlen = strlen (name);
1077 /* We assume that NAME does not need escaping. */
1078 if (8 + strlen (name) > DIM(line)-1)
1079 return gpg_error (GPG_ERR_TOO_LARGE);
1080 stpcpy (stpcpy (line, "GETATTR "), name);
1082 err = start_scd (ctrl);
1083 if (err)
1084 return err;
1086 err = assuan_transact (ctrl->scd_local->ctx, line,
1087 NULL, NULL, NULL, NULL,
1088 card_getattr_cb, &parm);
1089 if (!err && parm.error)
1090 err = gpg_error_from_errno (parm.error);
1092 if (!err && !parm.data)
1093 err = gpg_error (GPG_ERR_NO_DATA);
1095 if (!err)
1096 *result = parm.data;
1097 else
1098 xfree (parm.data);
1100 return unlock_scd (ctrl, err);
1106 static int
1107 pass_status_thru (void *opaque, const char *line)
1109 assuan_context_t ctx = opaque;
1110 char keyword[200];
1111 int i;
1113 for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
1114 keyword[i] = *line;
1115 keyword[i] = 0;
1116 /* truncate any remaining keyword stuff. */
1117 for (; *line && !spacep (line); line++)
1119 while (spacep (line))
1120 line++;
1122 assuan_write_status (ctx, keyword, line);
1123 return 0;
1126 static int
1127 pass_data_thru (void *opaque, const void *buffer, size_t length)
1129 assuan_context_t ctx = opaque;
1131 assuan_send_data (ctx, buffer, length);
1132 return 0;
1136 /* Send the line CMDLINE with command for the SCDdaemon to it and send
1137 all status messages back. This command is used as a general quoting
1138 mechanism to pass everything verbatim to SCDAEMON. The PIN
1139 inquiry is handled inside gpg-agent. */
1141 agent_card_scd (ctrl_t ctrl, const char *cmdline,
1142 int (*getpin_cb)(void *, const char *, char*, size_t),
1143 void *getpin_cb_arg, void *assuan_context)
1145 int rc;
1146 struct inq_needpin_s inqparm;
1148 rc = start_scd (ctrl);
1149 if (rc)
1150 return rc;
1152 inqparm.ctx = ctrl->scd_local->ctx;
1153 inqparm.getpin_cb = getpin_cb;
1154 inqparm.getpin_cb_arg = getpin_cb_arg;
1155 inqparm.passthru = assuan_context;
1156 rc = assuan_transact (ctrl->scd_local->ctx, cmdline,
1157 pass_data_thru, assuan_context,
1158 inq_needpin, &inqparm,
1159 pass_status_thru, assuan_context);
1160 if (rc)
1162 return unlock_scd (ctrl, rc);
1165 return unlock_scd (ctrl, 0);