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,
32 #include <sys/types.h>
33 #ifndef HAVE_W32_SYSTEM
41 #ifdef _POSIX_OPEN_MAX
42 #define MAX_OPEN_FDS _POSIX_OPEN_MAX
44 #define MAX_OPEN_FDS 20
47 /* Definition of module local data of the CTRL structure. */
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. */
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 */
71 void (*kpinfo_cb
)(void*, const char *);
73 void (*certinfo_cb
)(void*, const char *);
74 void *certinfo_cb_arg
;
75 void (*sinfo_cb
)(void*, const char *, size_t, const char *);
82 int (*getpin_cb
)(void *, const char *, char*, size_t);
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
)
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");
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. */
150 agent_scd_dump_state (void)
152 log_info ("agent_scd_dump_state: scd_lock=");
153 dump_mutex_state (&start_scd_lock
);
155 log_info ("agent_scd_dump_state: primary_scd_ctx=%p pid=%ld reusable=%d\n",
157 (long)assuan_get_pid (primary_scd_ctx
),
158 primary_scd_ctx_reusable
);
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
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
);
179 rc
= gpg_error (GPG_ERR_INTERNAL
);
181 ctrl
->scd_local
->locked
= 0;
185 /* To make sure we leave no secrets in our image after forking of the
186 scdaemon, we use this callback. */
188 atfork_cb (void *opaque
, int 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. */
201 start_scd (ctrl_t ctrl
)
205 assuan_context_t ctx
;
207 int no_close_list
[3];
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
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
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",
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;
260 log_info ("new connection to SCdaemon established (reusing)\n");
266 rc
= assuan_socket_connect (&ctx
, socket_name
, 0);
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
);
276 log_info ("new connection to SCdaemon established\n");
282 log_info ("SCdaemon is running but won't accept further connections\n");
283 err
= gpg_error (GPG_ERR_NO_SCDAEMON
);
287 /* Nope, it has not been started. Fire it up now. */
289 log_info ("no running SCdaemon - starting it\n");
293 err
= gpg_error (gpg_err_code_from_errno (errno
));
294 log_error ("error flushing pending output: %s\n", strerror (errno
));
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
;
306 argv
[1] = "--multi-server";
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);
323 log_error ("can't connect to the SCdaemon: %s\n",
325 err
= gpg_error (GPG_ERR_NO_SCDAEMON
);
330 log_debug ("first connection to SCdaemon established\n");
332 /* Get the name of the additional socket opened by scdaemon. */
335 unsigned char *databuf
;
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);
349 log_error ("warning: can't store socket name: %s\n",
353 memcpy (socket_name
, databuf
, datalen
);
354 socket_name
[datalen
] = 0;
356 log_debug ("additional connections at `%s'\n", socket_name
);
362 /* Tell the scdaemon we want him to send us an event signal. */
363 #ifndef HAVE_W32_SYSTEM
367 sprintf (buf
, "OPTION event-signal=%d", SIGUSR2
);
368 assuan_transact (ctx
, buf
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
372 primary_scd_ctx
= ctx
;
373 primary_scd_ctx_reusable
= 0;
378 unlock_scd (ctrl
, err
);
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
));
390 /* Check whether the Scdaemon is still alive and clean it up if not. */
392 agent_scd_check_aliveness (void)
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
))
409 log_info ("failed to acquire the start_scd lock while"
410 " doing an aliveness check: %s\n", "timeout");
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
);
418 pth_event_free (evt
, PTH_FREE_THIS
);
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
)
441 if (sl
->ctx
!= primary_scd_ctx
)
442 assuan_disconnect (sl
->ctx
);
447 primary_scd_ctx
= NULL
;
448 primary_scd_ctx_reusable
= 0;
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
)
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
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;
492 assuan_disconnect (ctrl
->scd_local
->ctx
);
493 ctrl
->scd_local
->ctx
= NULL
;
496 /* Remove the local context from our list and release it. */
499 else if (scd_local_list
== ctrl
->scd_local
)
500 scd_local_list
= ctrl
->scd_local
->next_local
;
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
)
510 sl
->next_local
= ctrl
->scd_local
->next_local
;
512 xfree (ctrl
->scd_local
);
513 ctrl
->scd_local
= NULL
;
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. */
526 unescape_status_string (const unsigned char *s
)
530 buffer
= d
= xtrymalloc (strlen ((const char*)s
)+1);
535 if (*s
== '%' && s
[1] && s
[2])
559 learn_status_cb (void *opaque
, const char *line
)
561 struct learn_parm_s
*parm
= opaque
;
562 const char *keyword
= line
;
565 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
567 while (spacep (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
);
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 *),
591 void (*certinfo_cb
)(void*, const char *),
592 void *certinfo_cb_arg
,
593 void (*sinfo_cb
)(void*, const char *, size_t, const char *),
597 struct learn_parm_s parm
;
599 rc
= start_scd (ctrl
);
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
);
614 return unlock_scd (ctrl
, rc
);
616 return unlock_scd (ctrl
, 0);
622 get_serialno_cb (void *opaque
, const char *line
)
624 char **serialno
= opaque
;
625 const char *keyword
= line
;
629 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
631 while (spacep (line
))
634 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
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);
644 return out_of_core ();
645 memcpy (*serialno
, line
, n
);
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
)
658 char *serialno
= NULL
;
660 rc
= start_scd (ctrl
);
664 rc
= assuan_transact (ctrl
->scd_local
->ctx
, "SERIALNO",
665 NULL
, NULL
, NULL
, NULL
,
666 get_serialno_cb
, &serialno
);
670 return unlock_scd (ctrl
, rc
);
672 *r_serialno
= serialno
;
673 return unlock_scd (ctrl
, 0);
680 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
682 membuf_t
*data
= opaque
;
685 put_membuf (data
, buffer
, length
);
689 /* Handle the NEEDPIN inquiry. */
691 inq_needpin (void *opaque
, const char *line
)
693 struct inq_needpin_s
*parm
= opaque
;
698 if (!strncmp (line
, "NEEDPIN", 7) && (line
[7] == ' ' || !line
[7]))
705 pin
= gcry_malloc_secure (pinlen
);
707 return out_of_core ();
709 rc
= parm
->getpin_cb (parm
->getpin_cb_arg
, line
, pin
, pinlen
);
711 rc
= assuan_send_data (parm
->ctx
, pin
, pinlen
);
714 else if (!strncmp (line
, "KEYPADINFO", 10) && (line
[10] == ' ' || !line
[10]))
719 code
= strtoul (line
+10, &endp
, 10);
724 rc
= parm
->getpin_cb (parm
->getpin_cb_arg
, line
, NULL
, code
);
728 log_error ("unsupported inquiry `%s'\n", line
);
729 rc
= gpg_error (GPG_ERR_ASS_UNKNOWN_INQUIRE
);
737 /* Create a signature using the current card */
739 agent_card_pksign (ctrl_t ctrl
,
741 int (*getpin_cb
)(void *, const char *, char*, size_t),
743 const unsigned char *indata
, size_t indatalen
,
744 unsigned char **r_buf
, size_t *r_buflen
)
747 char *p
, line
[ASSUAN_LINELENGTH
];
749 struct inq_needpin_s inqparm
;
751 unsigned char *sigbuf
;
755 rc
= start_scd (ctrl
);
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
);
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
,
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
;
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
);
799 memcpy (p
, sigbuf
, sigbuflen
);
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
,
812 int (*getpin_cb
)(void *, const char *, char*, size_t),
814 const unsigned char *indata
, size_t indatalen
,
815 char **r_buf
, size_t *r_buflen
)
818 char *p
, line
[ASSUAN_LINELENGTH
];
820 struct inq_needpin_s inqparm
;
824 rc
= start_scd (ctrl
);
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
);
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
,
853 xfree (get_membuf (&data
, &len
));
854 return unlock_scd (ctrl
, rc
);
856 *r_buf
= get_membuf (&data
, r_buflen
);
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
)
871 char line
[ASSUAN_LINELENGTH
];
876 rc
= start_scd (ctrl
);
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
,
889 xfree (get_membuf (&data
, &len
));
890 return unlock_scd (ctrl
, rc
);
892 *r_buf
= get_membuf (&data
, r_buflen
);
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
)
907 char line
[ASSUAN_LINELENGTH
];
912 rc
= start_scd (ctrl
);
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
,
925 xfree (get_membuf (&data
, &len
));
926 return unlock_scd (ctrl
, rc
);
928 *r_buf
= get_membuf (&data
, &buflen
);
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
;
960 return 0; /* We want only the first occurrence. */
962 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
964 while (spacep (line
))
967 if (keywordlen
== parm
->keywordlen
968 && !memcmp (keyword
, parm
->keyword
, keywordlen
))
970 parm
->data
= unescape_status_string ((const unsigned char*)line
);
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. */
984 agent_card_getattr (ctrl_t ctrl
, const char *name
, char **result
)
987 struct card_getattr_parm_s parm
;
988 char line
[ASSUAN_LINELENGTH
];
993 return gpg_error (GPG_ERR_INV_VALUE
);
995 memset (&parm
, 0, sizeof parm
);
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
);
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
);
1018 *result
= parm
.data
;
1022 return unlock_scd (ctrl
, err
);
1029 pass_status_thru (void *opaque
, const char *line
)
1031 assuan_context_t ctx
= opaque
;
1035 for (i
=0; *line
&& !spacep (line
) && i
< DIM(keyword
)-1; line
++, i
++)
1038 /* truncate any remaining keyword stuff. */
1039 for (; *line
&& !spacep (line
); line
++)
1041 while (spacep (line
))
1044 assuan_write_status (ctx
, keyword
, line
);
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
);
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
)
1068 struct inq_needpin_s inqparm
;
1070 rc
= start_scd (ctrl
);
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
);
1083 return unlock_scd (ctrl
, rc
);
1086 return unlock_scd (ctrl
, 0);