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/>.
30 #include <sys/types.h>
31 #ifndef HAVE_W32_SYSTEM
39 #ifdef _POSIX_OPEN_MAX
40 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
42 #define MAX_OPEN_FDS 20
45 /* Definition of module local data of the CTRL structure. */
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. */
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 */
69 void (*kpinfo_cb
)(void*, const char *);
71 void (*certinfo_cb
)(void*, const char *);
72 void *certinfo_cb_arg
;
73 void (*sinfo_cb
)(void*, const char *, size_t, const char *);
80 int (*getpin_cb
)(void *, const char *, char*, size_t);
82 assuan_context_t passthru
; /* If not NULL, pass unknown inquiries
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
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
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. */
122 initialize_module_call_scd (void)
124 static int initialized
;
128 if (!pth_mutex_init (&start_scd_lock
))
129 log_fatal ("error initializing mutex: %s\n", strerror (errno
));
136 dump_mutex_state (pth_mutex_t
*m
)
139 log_printf ("unknown under W32");
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");
146 log_printf ("locked tid=0x%lx count=%lu", (long)m
->mx_owner
, m
->mx_count
);
151 /* This function may be called to print infromation pertaining to the
152 current state of this module to the log. */
154 agent_scd_dump_state (void)
156 log_info ("agent_scd_dump_state: scd_lock=");
157 dump_mutex_state (&start_scd_lock
);
159 log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
161 (long)assuan_get_pid (primary_scd_ctx
),
162 primary_scd_ctx_reusable
);
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
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
);
183 rc
= gpg_error (GPG_ERR_INTERNAL
);
185 ctrl
->scd_local
->locked
= 0;
189 /* To make sure we leave no secrets in our image after forking of the
190 scdaemon, we use this callback. */
192 atfork_cb (void *opaque
, int 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. */
207 start_scd (ctrl_t ctrl
)
211 assuan_context_t ctx
;
213 int no_close_list
[3];
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
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
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",
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;
266 log_info ("new connection to SCdaemon established (reusing)\n");
272 rc
= assuan_socket_connect (&ctx
, socket_name
, 0);
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
);
282 log_info ("new connection to SCdaemon established\n");
288 log_info ("SCdaemon is running but won't accept further connections\n");
289 err
= gpg_error (GPG_ERR_NO_SCDAEMON
);
293 /* Nope, it has not been started. Fire it up now. */
295 log_info ("no running SCdaemon - starting it\n");
299 #ifndef HAVE_W32_SYSTEM
300 err
= gpg_error_from_syserror ();
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
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
;
320 argv
[1] = "--multi-server";
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
335 rc
= assuan_pipe_connect_ext (&ctx
, opt
.scdaemon_program
, argv
,
336 no_close_list
, atfork_cb
, NULL
, 128);
339 log_error ("can't connect to the SCdaemon: %s\n",
341 err
= gpg_error (GPG_ERR_NO_SCDAEMON
);
346 log_debug ("first connection to SCdaemon established\n");
349 assuan_set_log_stream (ctx
, log_get_stream ());
351 /* Get the name of the additional socket opened by scdaemon. */
354 unsigned char *databuf
;
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);
368 log_error ("warning: can't store socket name: %s\n",
372 memcpy (socket_name
, databuf
, datalen
);
373 socket_name
[datalen
] = 0;
375 log_debug ("additional connections at `%s'\n", socket_name
);
381 /* Tell the scdaemon we want him to send us an event signal. */
385 #ifdef HAVE_W32_SYSTEM
386 snprintf (buf
, sizeof buf
, "OPTION event-signal=%lx",
387 (unsigned long)get_agent_scd_notify_event ());
389 snprintf (buf
, sizeof buf
, "OPTION event-signal=%d", SIGUSR2
);
391 assuan_transact (ctx
, buf
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
394 primary_scd_ctx
= ctx
;
395 primary_scd_ctx_reusable
= 0;
400 unlock_scd (ctrl
, err
);
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
));
412 /* Check whether the Scdaemon is still alive and clean it up if not. */
414 agent_scd_check_aliveness (void)
418 #ifdef HAVE_W32_SYSTEM
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
))
435 log_info ("failed to acquire the start_scd lock while"
436 " doing an aliveness check: %s\n", "timeout");
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
);
444 pth_event_free (evt
, PTH_FREE_THIS
);
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))
456 if (pid
!= (pid_t
)(-1) && pid
457 && ((rc
=waitpid (pid
, NULL
, WNOHANG
))==-1 || (rc
== pid
)) )
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
)
475 if (sl
->ctx
!= primary_scd_ctx
)
476 assuan_disconnect (sl
->ctx
);
481 primary_scd_ctx
= NULL
;
482 primary_scd_ctx_reusable
= 0;
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
)
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
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;
526 assuan_disconnect (ctrl
->scd_local
->ctx
);
527 ctrl
->scd_local
->ctx
= NULL
;
530 /* Remove the local context from our list and release it. */
533 else if (scd_local_list
== ctrl
->scd_local
)
534 scd_local_list
= ctrl
->scd_local
->next_local
;
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
)
544 sl
->next_local
= ctrl
->scd_local
->next_local
;
546 xfree (ctrl
->scd_local
);
547 ctrl
->scd_local
= NULL
;
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. */
560 unescape_status_string (const unsigned char *s
)
564 buffer
= d
= xtrymalloc (strlen ((const char*)s
)+1);
569 if (*s
== '%' && s
[1] && s
[2])
593 learn_status_cb (void *opaque
, const char *line
)
595 struct learn_parm_s
*parm
= opaque
;
596 const char *keyword
= line
;
599 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
601 while (spacep (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
);
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 *),
625 void (*certinfo_cb
)(void*, const char *),
626 void *certinfo_cb_arg
,
627 void (*sinfo_cb
)(void*, const char *, size_t, const char *),
631 struct learn_parm_s parm
;
633 rc
= start_scd (ctrl
);
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
);
648 return unlock_scd (ctrl
, rc
);
650 return unlock_scd (ctrl
, 0);
656 get_serialno_cb (void *opaque
, const char *line
)
658 char **serialno
= opaque
;
659 const char *keyword
= line
;
663 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
665 while (spacep (line
))
668 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
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);
678 return out_of_core ();
679 memcpy (*serialno
, line
, n
);
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
)
692 char *serialno
= NULL
;
694 rc
= start_scd (ctrl
);
698 rc
= assuan_transact (ctrl
->scd_local
->ctx
, "SERIALNO",
699 NULL
, NULL
, NULL
, NULL
,
700 get_serialno_cb
, &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
;
719 put_membuf (data
, buffer
, length
);
723 /* Handle the NEEDPIN inquiry. */
725 inq_needpin (void *opaque
, const char *line
)
727 struct inq_needpin_s
*parm
= opaque
;
732 if (!strncmp (line
, "NEEDPIN", 7) && (line
[7] == ' ' || !line
[7]))
739 pin
= gcry_malloc_secure (pinlen
);
741 return out_of_core ();
743 rc
= parm
->getpin_cb (parm
->getpin_cb_arg
, line
, pin
, pinlen
);
745 rc
= assuan_send_data (parm
->ctx
, pin
, pinlen
);
748 else if (!strncmp (line
, "POPUPKEYPADPROMPT", 17)
749 && (line
[17] == ' ' || !line
[17]))
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
;
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);
777 assuan_end_confidential (parm
->passthru
);
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
);
785 assuan_end_confidential (parm
->ctx
);
789 log_error ("error forwarding inquiry `%s': %s\n",
790 line
, gpg_strerror (rc
));
794 log_error ("unsupported inquiry `%s'\n", line
);
795 rc
= gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE
);
803 /* Create a signature using the current card */
805 agent_card_pksign (ctrl_t ctrl
,
807 int (*getpin_cb
)(void *, const char *, char*, size_t),
809 const unsigned char *indata
, size_t indatalen
,
810 unsigned char **r_buf
, size_t *r_buflen
)
813 char *p
, line
[ASSUAN_LINELENGTH
];
815 struct inq_needpin_s inqparm
;
817 unsigned char *sigbuf
;
821 rc
= start_scd (ctrl
);
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
);
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
,
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
;
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
);
866 memcpy (p
, sigbuf
, sigbuflen
);
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
,
879 int (*getpin_cb
)(void *, const char *, char*, size_t),
881 const unsigned char *indata
, size_t indatalen
,
882 char **r_buf
, size_t *r_buflen
)
885 char *p
, line
[ASSUAN_LINELENGTH
];
887 struct inq_needpin_s inqparm
;
891 rc
= start_scd (ctrl
);
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
);
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
,
921 xfree (get_membuf (&data
, &len
));
922 return unlock_scd (ctrl
, rc
);
924 *r_buf
= get_membuf (&data
, r_buflen
);
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
)
939 char line
[ASSUAN_LINELENGTH
];
944 rc
= start_scd (ctrl
);
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
,
957 xfree (get_membuf (&data
, &len
));
958 return unlock_scd (ctrl
, rc
);
960 *r_buf
= get_membuf (&data
, r_buflen
);
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
)
975 char line
[ASSUAN_LINELENGTH
];
980 rc
= start_scd (ctrl
);
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
,
993 xfree (get_membuf (&data
, &len
));
994 return unlock_scd (ctrl
, rc
);
996 *r_buf
= get_membuf (&data
, &buflen
);
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
;
1028 return 0; /* We want only the first occurrence. */
1030 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
1032 while (spacep (line
))
1035 if (keywordlen
== parm
->keywordlen
1036 && !memcmp (keyword
, parm
->keyword
, keywordlen
))
1038 parm
->data
= unescape_status_string ((const unsigned char*)line
);
1040 parm
->error
= errno
;
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. */
1052 agent_card_getattr (ctrl_t ctrl
, const char *name
, char **result
)
1055 struct card_getattr_parm_s parm
;
1056 char line
[ASSUAN_LINELENGTH
];
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
);
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
);
1086 *result
= parm
.data
;
1090 return unlock_scd (ctrl
, err
);
1097 pass_status_thru (void *opaque
, const char *line
)
1099 assuan_context_t ctx
= opaque
;
1103 for (i
=0; *line
&& !spacep (line
) && i
< DIM(keyword
)-1; line
++, i
++)
1106 /* truncate any remaining keyword stuff. */
1107 for (; *line
&& !spacep (line
); line
++)
1109 while (spacep (line
))
1112 assuan_write_status (ctx
, keyword
, line
);
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
);
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
)
1136 struct inq_needpin_s inqparm
;
1138 rc
= start_scd (ctrl
);
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
);
1152 return unlock_scd (ctrl
, rc
);
1155 return unlock_scd (ctrl
, 0);