1
/* call-scd.c - fork of the scdaemon to do SC operations
2
* Copyright (C) 2001, 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
/* Fixme: For now we have serialized all access to the scdaemon which
22
make sense becuase the scdaemon can't handle concurrent connections
23
right now. We should however keep a list of connections and lock
24
just that connection - it migth make sense to implemtn parts of
36
#include <sys/types.h>
37
#ifndef HAVE_W32_SYSTEM
47
#ifdef _POSIX_OPEN_MAX
48
#define MAX_OPEN_FDS _POSIX_OPEN_MAX
50
#define MAX_OPEN_FDS 20
53
static ASSUAN_CONTEXT scd_ctx = NULL;
55
static pth_mutex_t scd_lock;
57
/* We need to keep track of the connection currently using the SCD.
58
For a pipe server this is all a NOP because the connection will
59
always have the connection indicator -1. agent_reset_scd releases
60
the active connection; i.e. sets it back to -1, so that a new
61
connection can start using the SCD. If we eventually allow
62
multiple SCD session we will either make scdaemon multi-threaded or
63
fork of a new scdaemon and let it see how it can get access to a
66
static int active_connection_fd = -1;
67
static int active_connection = 0;
69
/* 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 *);
79
struct inq_needpin_s {
81
int (*getpin_cb)(void *, const char *, char*, size_t);
87
/* This function must be called once to initialize this module. This
88
has to be done before a second thread is spawned. We can't do the
89
static initialization because Pth emulation code might not be able
90
to do a static init; in particualr, it is not possible for W32. */
92
initialize_module_call_scd (void)
95
static int initialized;
98
if (pth_mutex_init (&scd_lock))
100
#endif /*USE_GNU_PTH*/
108
if (!pth_mutex_release (&scd_lock))
110
log_error ("failed to release the SCD lock\n");
112
rc = gpg_error (GPG_ERR_INTERNAL);
114
#endif /*USE_GNU_PTH*/
118
/* To make sure we leave no secrets in our image after forking of the
119
scdaemon, we use this callback. */
121
atfork_cb (void *opaque, int where)
124
gcry_control (GCRYCTL_TERM_SECMEM);
128
/* Fork off the SCdaemon if this has not already been done. Note that
129
this fucntion alos locks the daemon. */
131
start_scd (ctrl_t ctrl)
137
int no_close_list[3];
141
if (!pth_mutex_acquire (&scd_lock, 0, NULL))
143
log_error ("failed to acquire the SCD lock\n");
144
return gpg_error (GPG_ERR_INTERNAL);
152
/* If we are not the connection currently using the SCD, return
154
if (!active_connection)
156
active_connection_fd = ctrl->connection_fd;
157
active_connection = 1;
159
else if (ctrl->connection_fd != active_connection_fd)
160
return unlock_scd (gpg_error (GPG_ERR_CONFLICT));
162
/* Okay, we already started the scdaemon and it is used by us.*/
164
/* We better do a sanity check now to see whether it has
166
#ifndef HAVE_W32_SYSTEM
167
pid = assuan_get_pid (scd_ctx);
168
if (pid != (pid_t)(-1) && pid
169
&& ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) )
171
assuan_disconnect (scd_ctx);
180
log_info ("no running SCdaemon - starting it\n");
184
gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
185
log_error ("error flushing pending output: %s\n", strerror (errno));
186
return unlock_scd (tmperr);
189
if (!opt.scdaemon_program || !*opt.scdaemon_program)
190
opt.scdaemon_program = GNUPG_DEFAULT_SCDAEMON;
191
if ( !(pgmname = strrchr (opt.scdaemon_program, '/')))
192
pgmname = opt.scdaemon_program;
197
argv[1] = "--server";
201
if (!opt.running_detached)
203
if (log_get_fd () != -1)
204
no_close_list[i++] = log_get_fd ();
205
no_close_list[i++] = fileno (stderr);
207
no_close_list[i] = -1;
209
/* Connect to the pinentry and perform initial handshaking */
210
rc = assuan_pipe_connect2 (&ctx, opt.scdaemon_program, (char**)argv,
211
no_close_list, atfork_cb, NULL);
214
log_error ("can't connect to the SCdaemon: %s\n",
215
assuan_strerror (rc));
216
return unlock_scd (gpg_error (GPG_ERR_NO_SCDAEMON));
219
active_connection_fd = ctrl->connection_fd;
220
active_connection = 1;
223
log_debug ("connection to SCdaemon established\n");
225
/* Tell the scdaemon that we want him to send us an event signal.
226
But only do this if we are running as a regular sever and not
227
simply as a pipe server. */
228
if (ctrl->connection_fd != -1)
230
#ifndef HAVE_W32_SYSTEM
233
sprintf (buf, "OPTION event-signal=%d", SIGUSR2);
234
assuan_transact (scd_ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
243
/* Reset the SCD if it has been used. */
245
agent_reset_scd (ctrl_t ctrl)
250
if (!pth_mutex_acquire (&scd_lock, 0, NULL))
252
log_error ("failed to acquire the SCD lock for reset\n");
253
return gpg_error (GPG_ERR_INTERNAL);
256
if (active_connection && active_connection_fd == ctrl->connection_fd)
259
rc = assuan_transact (scd_ctx, "RESET", NULL, NULL,
260
NULL, NULL, NULL, NULL);
261
active_connection_fd = -1;
262
active_connection = 0;
265
return unlock_scd (map_assuan_err (rc));
273
learn_status_cb (void *opaque, const char *line)
275
struct learn_parm_s *parm = opaque;
276
const char *keyword = line;
279
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
281
while (spacep (line))
283
if (keywordlen == 8 && !memcmp (keyword, "CERTINFO", keywordlen))
285
parm->certinfo_cb (parm->certinfo_cb_arg, line);
287
else if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen))
289
parm->kpinfo_cb (parm->kpinfo_cb_arg, line);
291
else if (keywordlen && *line)
293
parm->sinfo_cb (parm->sinfo_cb_arg, keyword, keywordlen, line);
299
/* Perform the learn command and return a list of all private keys
300
stored on the card. */
302
agent_card_learn (ctrl_t ctrl,
303
void (*kpinfo_cb)(void*, const char *),
305
void (*certinfo_cb)(void*, const char *),
306
void *certinfo_cb_arg,
307
void (*sinfo_cb)(void*, const char *, size_t, const char *),
311
struct learn_parm_s parm;
313
rc = start_scd (ctrl);
317
memset (&parm, 0, sizeof parm);
318
parm.kpinfo_cb = kpinfo_cb;
319
parm.kpinfo_cb_arg = kpinfo_cb_arg;
320
parm.certinfo_cb = certinfo_cb;
321
parm.certinfo_cb_arg = certinfo_cb_arg;
322
parm.sinfo_cb = sinfo_cb;
323
parm.sinfo_cb_arg = sinfo_cb_arg;
324
rc = assuan_transact (scd_ctx, "LEARN --force",
325
NULL, NULL, NULL, NULL,
326
learn_status_cb, &parm);
328
return unlock_scd (map_assuan_err (rc));
330
return unlock_scd (0);
336
get_serialno_cb (void *opaque, const char *line)
338
char **serialno = opaque;
339
const char *keyword = line;
343
for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
345
while (spacep (line))
348
if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
351
return ASSUAN_Unexpected_Status;
352
for (n=0,s=line; hexdigitp (s); s++, n++)
354
if (!n || (n&1)|| !(spacep (s) || !*s) )
355
return ASSUAN_Invalid_Status;
356
*serialno = xtrymalloc (n+1);
358
return ASSUAN_Out_Of_Core;
359
memcpy (*serialno, line, n);
366
/* Return the serial number of the card or an appropriate error. The
367
serial number is returned as a hexstring. */
369
agent_card_serialno (ctrl_t ctrl, char **r_serialno)
372
char *serialno = NULL;
374
rc = start_scd (ctrl);
378
/* Hmm, do we really need this reset - scddaemon should do this or
379
we can do this if we for some reason figure out that the
380
operation might have failed due to a missing RESET. Hmmm, I feel
381
this is really SCdaemon's duty */
382
/* rc = assuan_transact (scd_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); */
384
/* return unlock_scd (map_assuan_err (rc)); */
386
rc = assuan_transact (scd_ctx, "SERIALNO",
387
NULL, NULL, NULL, NULL,
388
get_serialno_cb, &serialno);
392
return unlock_scd (map_assuan_err (rc));
394
*r_serialno = serialno;
395
return unlock_scd (0);
400
membuf_data_cb (void *opaque, const void *buffer, size_t length)
402
membuf_t *data = opaque;
405
put_membuf (data, buffer, length);
409
/* Handle the NEEDPIN inquiry. */
411
inq_needpin (void *opaque, const char *line)
413
struct inq_needpin_s *parm = opaque;
418
if (!(!strncmp (line, "NEEDPIN", 7) && (line[7] == ' ' || !line[7])))
420
log_error ("unsupported inquiry `%s'\n", line);
421
return ASSUAN_Inquire_Unknown;
426
pin = gcry_malloc_secure (pinlen);
428
return ASSUAN_Out_Of_Core;
430
rc = parm->getpin_cb (parm->getpin_cb_arg, line, pin, pinlen);
432
rc = ASSUAN_Canceled;
434
rc = assuan_send_data (parm->ctx, pin, pinlen);
442
/* Create a signature using the current card */
444
agent_card_pksign (ctrl_t ctrl,
446
int (*getpin_cb)(void *, const char *, char*, size_t),
448
const unsigned char *indata, size_t indatalen,
449
char **r_buf, size_t *r_buflen)
452
char *p, line[ASSUAN_LINELENGTH];
454
struct inq_needpin_s inqparm;
456
unsigned char *sigbuf;
460
rc = start_scd (ctrl);
464
if (indatalen*2 + 50 > DIM(line))
465
return unlock_scd (gpg_error (GPG_ERR_GENERAL));
467
sprintf (line, "SETDATA ");
468
p = line + strlen (line);
469
for (i=0; i < indatalen ; i++, p += 2 )
470
sprintf (p, "%02X", indata[i]);
471
rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
473
return unlock_scd (map_assuan_err (rc));
475
init_membuf (&data, 1024);
476
inqparm.ctx = scd_ctx;
477
inqparm.getpin_cb = getpin_cb;
478
inqparm.getpin_cb_arg = getpin_cb_arg;
479
snprintf (line, DIM(line)-1, "PKSIGN %s", keyid);
480
line[DIM(line)-1] = 0;
481
rc = assuan_transact (scd_ctx, line,
482
membuf_data_cb, &data,
483
inq_needpin, &inqparm,
487
xfree (get_membuf (&data, &len));
488
return unlock_scd (map_assuan_err (rc));
490
sigbuf = get_membuf (&data, &sigbuflen);
492
/* create an S-expression from it which is formatted like this:
493
"(7:sig-val(3:rsa(1:sSIGBUFLEN:SIGBUF)))" */
494
*r_buflen = 21 + 11 + sigbuflen + 4;
495
*r_buf = xtrymalloc (*r_buflen);
498
gpg_error_t tmperr = out_of_core ();
500
return unlock_scd (tmperr);
502
p = stpcpy (*r_buf, "(7:sig-val(3:rsa(1:s" );
503
sprintf (p, "%u:", (unsigned int)sigbuflen);
505
memcpy (p, sigbuf, sigbuflen);
510
assert (gcry_sexp_canon_len (*r_buf, *r_buflen, NULL, NULL));
511
return unlock_scd (0);
514
/* Decipher INDATA using the current card. Note that the returned value is */
516
agent_card_pkdecrypt (ctrl_t ctrl,
518
int (*getpin_cb)(void *, const char *, char*, size_t),
520
const unsigned char *indata, size_t indatalen,
521
char **r_buf, size_t *r_buflen)
524
char *p, line[ASSUAN_LINELENGTH];
526
struct inq_needpin_s inqparm;
530
rc = start_scd (ctrl);
534
/* FIXME: use secure memory where appropriate */
535
if (indatalen*2 + 50 > DIM(line))
536
return unlock_scd (gpg_error (GPG_ERR_GENERAL));
538
sprintf (line, "SETDATA ");
539
p = line + strlen (line);
540
for (i=0; i < indatalen ; i++, p += 2 )
541
sprintf (p, "%02X", indata[i]);
542
rc = assuan_transact (scd_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
544
return unlock_scd (map_assuan_err (rc));
546
init_membuf (&data, 1024);
547
inqparm.ctx = scd_ctx;
548
inqparm.getpin_cb = getpin_cb;
549
inqparm.getpin_cb_arg = getpin_cb_arg;
550
snprintf (line, DIM(line)-1, "PKDECRYPT %s", keyid);
551
line[DIM(line)-1] = 0;
552
rc = assuan_transact (scd_ctx, line,
553
membuf_data_cb, &data,
554
inq_needpin, &inqparm,
558
xfree (get_membuf (&data, &len));
559
return unlock_scd (map_assuan_err (rc));
561
*r_buf = get_membuf (&data, r_buflen);
563
return unlock_scd (gpg_error (GPG_ERR_ENOMEM));
565
return unlock_scd (0);
570
/* Read a certificate with ID into R_BUF and R_BUFLEN. */
572
agent_card_readcert (ctrl_t ctrl,
573
const char *id, char **r_buf, size_t *r_buflen)
576
char line[ASSUAN_LINELENGTH];
581
rc = start_scd (ctrl);
585
init_membuf (&data, 1024);
586
snprintf (line, DIM(line)-1, "READCERT %s", id);
587
line[DIM(line)-1] = 0;
588
rc = assuan_transact (scd_ctx, line,
589
membuf_data_cb, &data,
594
xfree (get_membuf (&data, &len));
595
return unlock_scd (map_assuan_err (rc));
597
*r_buf = get_membuf (&data, r_buflen);
599
return unlock_scd (gpg_error (GPG_ERR_ENOMEM));
601
return unlock_scd (0);
606
/* Read a key with ID and return it in an allocate buffer pointed to
607
by r_BUF as a valid S-expression. */
609
agent_card_readkey (ctrl_t ctrl, const char *id, unsigned char **r_buf)
612
char line[ASSUAN_LINELENGTH];
617
rc = start_scd (ctrl);
621
init_membuf (&data, 1024);
622
snprintf (line, DIM(line)-1, "READKEY %s", id);
623
line[DIM(line)-1] = 0;
624
rc = assuan_transact (scd_ctx, line,
625
membuf_data_cb, &data,
630
xfree (get_membuf (&data, &len));
631
return unlock_scd (map_assuan_err (rc));
633
*r_buf = get_membuf (&data, &buflen);
635
return unlock_scd (gpg_error (GPG_ERR_ENOMEM));
637
if (!gcry_sexp_canon_len (*r_buf, buflen, NULL, NULL))
639
xfree (*r_buf); *r_buf = NULL;
640
return unlock_scd (gpg_error (GPG_ERR_INV_VALUE));
643
return unlock_scd (0);
650
pass_status_thru (void *opaque, const char *line)
652
ASSUAN_CONTEXT ctx = opaque;
656
for (i=0; *line && !spacep (line) && i < DIM(keyword)-1; line++, i++)
659
/* truncate any remaining keyword stuff. */
660
for (; *line && !spacep (line); line++)
662
while (spacep (line))
665
assuan_write_status (ctx, keyword, line);
670
pass_data_thru (void *opaque, const void *buffer, size_t length)
672
ASSUAN_CONTEXT ctx = opaque;
674
assuan_send_data (ctx, buffer, length);
679
/* Send the line CMDLINE with command for the SCDdaemon to it and send
680
all status messages back. This command is used as a general quoting
681
mechanism to pass everything verbatim to SCDAEMOPN. The PIN
682
inquirey is handled inside gpg-agent. */
684
agent_card_scd (ctrl_t ctrl, const char *cmdline,
685
int (*getpin_cb)(void *, const char *, char*, size_t),
686
void *getpin_cb_arg, void *assuan_context)
689
struct inq_needpin_s inqparm;
691
rc = start_scd (ctrl);
695
inqparm.ctx = scd_ctx;
696
inqparm.getpin_cb = getpin_cb;
697
inqparm.getpin_cb_arg = getpin_cb_arg;
698
rc = assuan_transact (scd_ctx, cmdline,
699
pass_data_thru, assuan_context,
700
inq_needpin, &inqparm,
701
pass_status_thru, assuan_context);
704
return unlock_scd (map_assuan_err (rc));
707
return unlock_scd (0);