1 /*
2 * ctx.c: Context related functions
3 *
4 * Copyright (C) 2002 Juha Yrjölä <juha.yrjola@iki.fi>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #include <sys/stat.h>
31 #include <limits.h>
32
33 #ifdef _WIN32
34 #include <windows.h>
35 #include <winreg.h>
36 #include <direct.h>
37 #include <io.h>
38 #endif
39
40 #include "common/libscdl.h"
41 #include "common/compat_strlcpy.h"
42 #include "internal.h"
43 #include "sc-ossl-compat.h"
44
ignored_reader(sc_context_t * ctx,sc_reader_t * reader)45 static int ignored_reader(sc_context_t *ctx, sc_reader_t *reader)
46 {
47 if (ctx != NULL && reader != NULL && reader->name != NULL) {
48 size_t i;
49 const scconf_list *list;
50
51 for (i = 0; ctx->conf_blocks[i]; i++) {
52 list = scconf_find_list(ctx->conf_blocks[i], "ignored_readers");
53 while (list != NULL) {
54 if (strstr(reader->name, list->data) != NULL) {
55 sc_log(ctx, "Ignoring reader \'%s\' because of \'%s\'\n",
56 reader->name, list->data);
57 return 1;
58 }
59 list = list->next;
60 }
61 }
62 }
63
64 return 0;
65 }
66
_sc_add_reader(sc_context_t * ctx,sc_reader_t * reader)67 int _sc_add_reader(sc_context_t *ctx, sc_reader_t *reader)
68 {
69 if (reader == NULL || ignored_reader(ctx, reader)) {
70 return SC_ERROR_INVALID_ARGUMENTS;
71 }
72 reader->ctx = ctx;
73 list_append(&ctx->readers, reader);
74 return SC_SUCCESS;
75 }
76
_sc_delete_reader(sc_context_t * ctx,sc_reader_t * reader)77 int _sc_delete_reader(sc_context_t *ctx, sc_reader_t *reader)
78 {
79 if (reader == NULL) {
80 return SC_ERROR_INVALID_ARGUMENTS;
81 }
82 if (reader->ops->release)
83 reader->ops->release(reader);
84 free(reader->name);
85 free(reader->vendor);
86 list_delete(&ctx->readers, reader);
87 free(reader);
88 return SC_SUCCESS;
89 }
90
91 struct _sc_driver_entry {
92 const char *name;
93 void *(*func)(void);
94 };
95
96 static const struct _sc_driver_entry internal_card_drivers[] = {
97 { "cardos", (void *(*)(void)) sc_get_cardos_driver },
98 { "flex", (void *(*)(void)) sc_get_cryptoflex_driver },
99 { "cyberflex", (void *(*)(void)) sc_get_cyberflex_driver },
100 #ifdef ENABLE_OPENSSL
101 { "gpk", (void *(*)(void)) sc_get_gpk_driver },
102 #endif
103 { "gemsafeV1", (void *(*)(void)) sc_get_gemsafeV1_driver },
104 { "asepcos", (void *(*)(void)) sc_get_asepcos_driver },
105 { "starcos", (void *(*)(void)) sc_get_starcos_driver },
106 { "tcos", (void *(*)(void)) sc_get_tcos_driver },
107 #ifdef ENABLE_OPENSSL
108 { "oberthur", (void *(*)(void)) sc_get_oberthur_driver },
109 { "authentic", (void *(*)(void)) sc_get_authentic_driver },
110 { "iasecc", (void *(*)(void)) sc_get_iasecc_driver },
111 #endif
112 { "belpic", (void *(*)(void)) sc_get_belpic_driver },
113 { "incrypto34", (void *(*)(void)) sc_get_incrypto34_driver },
114 { "akis", (void *(*)(void)) sc_get_akis_driver },
115 #ifdef ENABLE_OPENSSL
116 { "entersafe",(void *(*)(void)) sc_get_entersafe_driver },
117 #ifdef ENABLE_SM
118 { "epass2003",(void *(*)(void)) sc_get_epass2003_driver },
119 #endif
120 #endif
121 { "rutoken", (void *(*)(void)) sc_get_rutoken_driver },
122 { "rutoken_ecp",(void *(*)(void)) sc_get_rtecp_driver },
123 { "myeid", (void *(*)(void)) sc_get_myeid_driver },
124 #if defined(ENABLE_OPENSSL) && defined(ENABLE_SM)
125 { "dnie", (void *(*)(void)) sc_get_dnie_driver },
126 #endif
127 { "masktech", (void *(*)(void)) sc_get_masktech_driver },
128 { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver },
129 { "westcos", (void *(*)(void)) sc_get_westcos_driver },
130 { "esteid2018", (void *(*)(void)) sc_get_esteid2018_driver },
131 { "idprime", (void *(*)(void)) sc_get_idprime_driver },
132 #if defined(ENABLE_SM) && defined(ENABLE_OPENPACE)
133 { "edo", (void *(*)(void)) sc_get_edo_driver },
134 #endif
135
136 /* Here should be placed drivers that need some APDU transactions in the
137 * driver's `match_card()` function. */
138 { "coolkey", (void *(*)(void)) sc_get_coolkey_driver },
139 /* MUSCLE card applet returns 9000 on whatever AID is selected, see
140 * https://github.com/JavaCardOS/MuscleCard-Applet/blob/master/musclecard/src/com/musclecard/CardEdge/CardEdge.java#L326
141 * put the muscle driver first to cope with this bug. */
142 { "muscle", (void *(*)(void)) sc_get_muscle_driver },
143 { "sc-hsm", (void *(*)(void)) sc_get_sc_hsm_driver },
144 { "mcrd", (void *(*)(void)) sc_get_mcrd_driver },
145 { "setcos", (void *(*)(void)) sc_get_setcos_driver },
146 { "PIV-II", (void *(*)(void)) sc_get_piv_driver },
147 { "cac", (void *(*)(void)) sc_get_cac_driver },
148 { "itacns", (void *(*)(void)) sc_get_itacns_driver },
149 { "isoApplet", (void *(*)(void)) sc_get_isoApplet_driver },
150 #ifdef ENABLE_ZLIB
151 { "gids", (void *(*)(void)) sc_get_gids_driver },
152 #endif
153 { "openpgp", (void *(*)(void)) sc_get_openpgp_driver },
154 { "jpki", (void *(*)(void)) sc_get_jpki_driver },
155 { "npa", (void *(*)(void)) sc_get_npa_driver },
156 { "cac1", (void *(*)(void)) sc_get_cac1_driver },
157 /* The default driver should be last, as it handles all the
158 * unrecognized cards. */
159 { "default", (void *(*)(void)) sc_get_default_driver },
160 { NULL, NULL }
161 };
162
163 static const struct _sc_driver_entry old_card_drivers[] = {
164 { "miocos", (void *(*)(void)) sc_get_miocos_driver },
165 { "jcop", (void *(*)(void)) sc_get_jcop_driver },
166 { NULL, NULL }
167 };
168
169 struct _sc_ctx_options {
170 struct _sc_driver_entry cdrv[SC_MAX_CARD_DRIVERS];
171 int ccount;
172 };
173
174
175 int
sc_ctx_win32_get_config_value(const char * name_env,const char * name_reg,const char * name_key,void * out,size_t * out_len)176 sc_ctx_win32_get_config_value(const char *name_env,
177 const char *name_reg, const char *name_key,
178 void *out, size_t *out_len)
179 {
180 #ifdef _WIN32
181 long rc;
182 HKEY hKey;
183
184 if (!out || !out_len)
185 return SC_ERROR_INVALID_ARGUMENTS;
186
187 if (name_env) {
188 char *value = getenv(name_env);
189 if (value) {
190 if (strlen(value) > *out_len)
191 return SC_ERROR_NOT_ENOUGH_MEMORY;
192 memcpy(out, value, strlen(value));
193 *out_len = strlen(value);
194 return SC_SUCCESS;
195 }
196 }
197
198 if (!name_reg)
199 return SC_ERROR_INVALID_ARGUMENTS;
200
201 if (!name_key)
202 name_key = "Software\\OpenSC Project\\OpenSC";
203
204 rc = RegOpenKeyExA(HKEY_CURRENT_USER, name_key, 0, KEY_QUERY_VALUE, &hKey);
205 if (rc == ERROR_SUCCESS) {
206 DWORD len = *out_len;
207 rc = RegQueryValueEx(hKey, name_reg, NULL, NULL, out, &len);
208 RegCloseKey(hKey);
209 if (rc == ERROR_SUCCESS) {
210 *out_len = len;
211 return SC_SUCCESS;
212 }
213 }
214
215 rc = RegOpenKeyExA(HKEY_LOCAL_MACHINE, name_key, 0, KEY_QUERY_VALUE, &hKey);
216 if (rc == ERROR_SUCCESS) {
217 DWORD len = *out_len;
218 rc = RegQueryValueEx(hKey, name_reg, NULL, NULL, out, &len);
219 RegCloseKey(hKey);
220 if (rc == ERROR_SUCCESS) {
221 *out_len = len;
222 return SC_SUCCESS;
223 }
224 }
225
226 return SC_ERROR_OBJECT_NOT_FOUND;
227 #else
228 return SC_ERROR_NOT_SUPPORTED;
229 #endif
230 }
231
232
233 /* Simclist helper to locate readers by name */
reader_list_seeker(const void * el,const void * key)234 static int reader_list_seeker(const void *el, const void *key) {
235 const struct sc_reader *reader = (struct sc_reader *)el;
236 if ((el == NULL) || (key == NULL))
237 return 0;
238 if (strcmp(reader->name, (char*)key) == 0)
239 return 1;
240 return 0;
241 }
242
del_drvs(struct _sc_ctx_options * opts)243 static void del_drvs(struct _sc_ctx_options *opts)
244 {
245 struct _sc_driver_entry *lst;
246 int *cp, i;
247
248 lst = opts->cdrv;
249 cp = &opts->ccount;
250
251 for (i = 0; i < *cp; i++) {
252 free((void *)lst[i].name);
253 }
254 *cp = 0;
255 }
256
add_drv(struct _sc_ctx_options * opts,const char * name)257 static void add_drv(struct _sc_ctx_options *opts, const char *name)
258 {
259 struct _sc_driver_entry *lst;
260 int *cp, max, i;
261
262 lst = opts->cdrv;
263 cp = &opts->ccount;
264 max = SC_MAX_CARD_DRIVERS;
265 if (*cp == max) /* No space for more drivers... */
266 return;
267 for (i = 0; i < *cp; i++)
268 if (strcmp(name, lst[i].name) == 0)
269 return;
270 lst[*cp].name = strdup(name);
271
272 *cp = *cp + 1;
273 }
274
add_internal_drvs(struct _sc_ctx_options * opts)275 static void add_internal_drvs(struct _sc_ctx_options *opts)
276 {
277 const struct _sc_driver_entry *lst;
278 int i;
279
280 lst = internal_card_drivers;
281 i = 0;
282 while (lst[i].name != NULL) {
283 add_drv(opts, lst[i].name);
284 i++;
285 }
286 }
287
add_old_drvs(struct _sc_ctx_options * opts)288 static void add_old_drvs(struct _sc_ctx_options *opts)
289 {
290 const struct _sc_driver_entry *lst;
291 int i;
292
293 lst = old_card_drivers;
294 i = 0;
295 while (lst[i].name != NULL) {
296 add_drv(opts, lst[i].name);
297 i++;
298 }
299 }
300
set_defaults(sc_context_t * ctx,struct _sc_ctx_options * opts)301 static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts)
302 {
303 ctx->debug = 0;
304 if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
305 fclose(ctx->debug_file);
306 ctx->debug_file = stderr;
307 ctx->flags = 0;
308
309 #ifdef __APPLE__
310 /* Override the default debug log for OpenSC.tokend to be different from PKCS#11.
311 * TODO: Could be moved to OpenSC.tokend */
312 if (!strcmp(ctx->app_name, "tokend"))
313 ctx->debug_file = fopen("/tmp/opensc-tokend.log", "a");
314 #endif
315 ctx->forced_driver = NULL;
316 add_internal_drvs(opts);
317 }
318
319 /* In Windows, file handles can not be shared between DLL-s,
320 * each DLL has a separate file handle table. Thus tools and utilities
321 * can not set the file handle themselves when -v is specified on command line.
322 */
sc_ctx_log_to_file(sc_context_t * ctx,const char * filename)323 int sc_ctx_log_to_file(sc_context_t *ctx, const char* filename)
324 {
325 /* Close any existing handles */
326 if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) {
327 fclose(ctx->debug_file);
328 ctx->debug_file = NULL;
329 }
330
331 if (!ctx->debug_filename) {
332 if (!filename)
333 filename = "stderr";
334 ctx->debug_filename = strdup(filename);
335 }
336
337 if (!filename)
338 return SC_SUCCESS;
339
340 /* Handle special names */
341 if (!strcmp(filename, "stdout"))
342 ctx->debug_file = stdout;
343 else if (!strcmp(filename, "stderr"))
344 ctx->debug_file = stderr;
345 else {
346 ctx->debug_file = fopen(filename, "a");
347 if (ctx->debug_file == NULL)
348 return SC_ERROR_INTERNAL;
349 }
350 return SC_SUCCESS;
351 }
352
353 static void
set_drivers(struct _sc_ctx_options * opts,const scconf_list * list)354 set_drivers(struct _sc_ctx_options *opts, const scconf_list *list)
355 {
356 const char *s_internal = "internal", *s_old = "old";
357 if (list != NULL)
358 del_drvs(opts);
359 while (list != NULL) {
360 if (strcmp(list->data, s_internal) == 0)
361 add_internal_drvs(opts);
362 else if (strcmp(list->data, s_old) == 0)
363 add_old_drvs(opts);
364 else
365 add_drv(opts, list->data);
366 list = list->next;
367 }
368 }
369
370 static int
load_parameters(sc_context_t * ctx,scconf_block * block,struct _sc_ctx_options * opts)371 load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *opts)
372 {
373 int err = 0;
374 const scconf_list *list;
375 const char *val;
376 int debug;
377 #ifdef _WIN32
378 char expanded_val[PATH_MAX];
379 DWORD expanded_len;
380 #endif
381
382 debug = scconf_get_int(block, "debug", ctx->debug);
383 if (debug > ctx->debug)
384 ctx->debug = debug;
385
386 val = scconf_get_str(block, "debug_file", NULL);
387 if (val) {
388 #ifdef _WIN32
389 expanded_len = PATH_MAX;
390 expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len);
391 if (0 < expanded_len && expanded_len < sizeof expanded_val)
392 val = expanded_val;
393 #endif
394 sc_ctx_log_to_file(ctx, val);
395 }
396 else if (ctx->debug) {
397 sc_ctx_log_to_file(ctx, NULL);
398 }
399
400 if (scconf_get_bool (block, "disable_popups",
401 ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS))
402 ctx->flags |= SC_CTX_FLAG_DISABLE_POPUPS;
403
404 if (scconf_get_bool (block, "disable_colors",
405 ctx->flags & SC_CTX_FLAG_DISABLE_COLORS))
406 ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS;
407
408 if (scconf_get_bool (block, "enable_default_driver",
409 ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER))
410 ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER;
411
412 list = scconf_find_list(block, "card_drivers");
413 set_drivers(opts, list);
414
415 return err;
416 }
417
418
419 /**
420 * find library module for provided driver in configuration file
421 * if not found assume library name equals to module name
422 */
find_library(sc_context_t * ctx,const char * name)423 static const char *find_library(sc_context_t *ctx, const char *name)
424 {
425 int i, log_warning;
426 const char *libname = NULL;
427 scconf_block **blocks, *blk;
428
429 for (i = 0; ctx->conf_blocks[i]; i++) {
430 blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_driver", name);
431 if (!blocks)
432 continue;
433 blk = blocks[0];
434 free(blocks);
435 if (blk == NULL)
436 continue;
437 libname = scconf_get_str(blk, "module", name);
438 #ifdef _WIN32
439 log_warning = libname && libname[0] != '\\';
440 #else
441 log_warning = libname && libname[0] != '/';
442 #endif
443 if (log_warning)
444 sc_log(ctx, "warning: relative path to driver '%s' used", libname);
445 break;
446 }
447
448 return libname;
449 }
450
451 /**
452 * load card/reader driver modules
453 * Every module should contain a function " void * sc_module_init(char *) "
454 * that returns a pointer to the function _sc_get_xxxx_driver()
455 * used to initialize static modules
456 * Also, an exported "char *sc_module_version" variable should exist in module
457 */
load_dynamic_driver(sc_context_t * ctx,void ** dll,const char * name)458 static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name)
459 {
460 const char *version, *libname;
461 void *handle;
462 void *(*modinit)(const char *) = NULL;
463 void *(**tmodi)(const char *) = &modinit;
464 const char *(*modversion)(void) = NULL;
465 const char *(**tmodv)(void) = &modversion;
466
467 if (dll == NULL) {
468 sc_log(ctx, "No dll parameter specified");
469 return NULL;
470 }
471 if (name == NULL) { /* should not occur, but... */
472 sc_log(ctx, "No module specified");
473 return NULL;
474 }
475 libname = find_library(ctx, name);
476 if (libname == NULL)
477 return NULL;
478 handle = sc_dlopen(libname);
479 if (handle == NULL) {
480 sc_log(ctx, "Module %s: cannot load %s library: %s", name, libname, sc_dlerror());
481 return NULL;
482 }
483
484 /* verify correctness of module */
485 *(void **)tmodi = sc_dlsym(handle, "sc_module_init");
486 *(void **)tmodv = sc_dlsym(handle, "sc_driver_version");
487 if (modinit == NULL || modversion == NULL) {
488 sc_log(ctx, "dynamic library '%s' is not a OpenSC module",libname);
489 sc_dlclose(handle);
490 return NULL;
491 }
492 /* verify module version */
493 version = modversion();
494 /* XXX: We really need to have ABI version for each interface */
495 if (version == NULL || strncmp(version, PACKAGE_VERSION, strlen(PACKAGE_VERSION)) != 0) {
496 sc_log(ctx, "dynamic library '%s': invalid module version", libname);
497 sc_dlclose(handle);
498 return NULL;
499 }
500
501 *dll = handle;
502 sc_log(ctx, "successfully loaded card driver '%s'", name);
503 return modinit(name);
504 }
505
load_card_driver_options(sc_context_t * ctx,struct sc_card_driver * driver)506 static int load_card_driver_options(sc_context_t *ctx,
507 struct sc_card_driver *driver)
508 {
509 scconf_block **blocks, *blk;
510 int i;
511
512 for (i = 0; ctx->conf_blocks[i]; i++) {
513 blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
514 "card_driver", driver->short_name);
515 if (!blocks)
516 continue;
517 blk = blocks[0];
518 free(blocks);
519
520 if (blk == NULL)
521 continue;
522
523 /* no options at the moment */
524 }
525 return SC_SUCCESS;
526 }
527
load_card_drivers(sc_context_t * ctx,struct _sc_ctx_options * opts)528 static int load_card_drivers(sc_context_t *ctx, struct _sc_ctx_options *opts)
529 {
530 const struct _sc_driver_entry *ent;
531 int drv_count;
532 int i;
533
534 for (drv_count = 0; ctx->card_drivers[drv_count] != NULL; drv_count++)
535 ;
536
537 for (i = 0; i < opts->ccount; i++) {
538 struct sc_card_driver *(*func)(void) = NULL;
539 struct sc_card_driver *(**tfunc)(void) = &func;
540 void *dll = NULL;
541 int j;
542
543 if (drv_count >= SC_MAX_CARD_DRIVERS - 1) {
544 sc_log(ctx, "Not more then %i card drivers allowed.", SC_MAX_CARD_DRIVERS);
545 break;
546 }
547
548 ent = &opts->cdrv[i];
549 for (j = 0; internal_card_drivers[j].name != NULL; j++) {
550 if (strcmp(ent->name, internal_card_drivers[j].name) == 0) {
551 func = (struct sc_card_driver *(*)(void)) internal_card_drivers[j].func;
552 break;
553 }
554 }
555 if (func == NULL) {
556 for (j = 0; old_card_drivers[j].name != NULL; j++) {
557 if (strcmp(ent->name, old_card_drivers[j].name) == 0) {
558 func = (struct sc_card_driver *(*)(void)) old_card_drivers[j].func;
559 break;
560 }
561 }
562 }
563 /* if not initialized assume external module */
564 if (func == NULL)
565 *(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name);
566 /* if still null, assume driver not found */
567 if (func == NULL) {
568 sc_log(ctx, "Unable to load '%s'.", ent->name);
569 if (dll)
570 sc_dlclose(dll);
571 continue;
572 }
573
574 ctx->card_drivers[drv_count] = func();
575 if (ctx->card_drivers[drv_count] == NULL) {
576 sc_log(ctx, "Driver '%s' not available.", ent->name);
577 continue;
578 }
579
580 ctx->card_drivers[drv_count]->dll = dll;
581 ctx->card_drivers[drv_count]->atr_map = NULL;
582 ctx->card_drivers[drv_count]->natrs = 0;
583
584 load_card_driver_options(ctx, ctx->card_drivers[drv_count]);
585
586 /* Ensure that the list is always terminated by NULL */
587 ctx->card_drivers[drv_count + 1] = NULL;
588
589 drv_count++;
590 }
591 return SC_SUCCESS;
592 }
593
load_card_atrs(sc_context_t * ctx)594 static int load_card_atrs(sc_context_t *ctx)
595 {
596 struct sc_card_driver *driver;
597 scconf_block **blocks;
598 int i, j, k;
599
600 for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
601 blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_atr", NULL);
602 if (!blocks)
603 continue;
604 for (j = 0; blocks[j] != NULL; j++) {
605 scconf_block *b = blocks[j];
606 char *atr = b->name->data;
607 const scconf_list *list;
608 struct sc_atr_table t;
609 const char *dname;
610
611 driver = NULL;
612
613 if (strlen(atr) < 4)
614 continue;
615
616 /* The interesting part. If there's no card
617 * driver assigned for the ATR, add it to
618 * the default driver. This will reduce the
619 * amount of code required to process things
620 * related to card_atr blocks in situations,
621 * where the code is not exactly related to
622 * card driver settings, but for example
623 * forcing a protocol at the reader driver.
624 */
625 dname = scconf_get_str(b, "driver", "default");
626
627 /* Find the card driver structure according to dname */
628 for (k = 0; ctx->card_drivers[k] != NULL; k++) {
629 driver = ctx->card_drivers[k];
630 if (!strcmp(dname, driver->short_name))
631 break;
632 driver = NULL;
633 }
634
635 if (!driver)
636 continue;
637
638 memset(&t, 0, sizeof(struct sc_atr_table));
639 t.atr = atr;
640 t.atrmask = (char *) scconf_get_str(b, "atrmask", NULL);
641 t.name = (char *) scconf_get_str(b, "name", NULL);
642 t.type = scconf_get_int(b, "type", SC_CARD_TYPE_UNKNOWN);
643 list = scconf_find_list(b, "flags");
644 while (list != NULL) {
645 unsigned int flags = 0;
646
647 if (!list->data) {
648 list = list->next;
649 continue;
650 }
651
652 if (!strcmp(list->data, "rng"))
653 flags = SC_CARD_FLAG_RNG;
654 else if (!strcmp(list->data, "keep_alive"))
655 flags = SC_CARD_FLAG_KEEP_ALIVE;
656 else if (sscanf(list->data, "%x", &flags) != 1)
657 flags = 0;
658
659 t.flags |= flags;
660 list = list->next;
661 }
662 t.card_atr = b;
663 _sc_add_atr(ctx, driver, &t);
664 }
665 free(blocks);
666 }
667 return SC_SUCCESS;
668 }
669
process_config_file(sc_context_t * ctx,struct _sc_ctx_options * opts)670 static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
671 {
672 int i, r, count = 0;
673 scconf_block **blocks;
674 const char *conf_path = NULL;
675 const char *debug = NULL;
676 #ifdef _WIN32
677 char temp_path[PATH_MAX];
678 size_t temp_len;
679 #endif
680
681 /* Takes effect even when no config around */
682 debug = getenv("OPENSC_DEBUG");
683 if (debug)
684 ctx->debug = atoi(debug);
685
686 memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks));
687 #ifdef _WIN32
688 temp_len = PATH_MAX-1;
689 r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\OpenSC Project\\OpenSC",
690 temp_path, &temp_len);
691 if (r) {
692 sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key.");
693 return;
694 }
695 temp_path[temp_len] = '\0';
696 conf_path = temp_path;
697 #else
698 conf_path = getenv("OPENSC_CONF");
699 if (!conf_path)
700 conf_path = OPENSC_CONF_PATH;
701 #endif
702 ctx->conf = scconf_new(conf_path);
703 if (ctx->conf == NULL)
704 return;
705 r = scconf_parse(ctx->conf);
706 #ifdef OPENSC_CONFIG_STRING
707 /* Parse the string if config file didn't exist */
708 if (r < 0)
709 r = scconf_parse_string(ctx->conf, OPENSC_CONFIG_STRING);
710 #endif
711 if (r < 1) {
712 /* A negative return value means the config file isn't
713 * there, which is not an error. Nevertheless log this
714 * fact. */
715 if (r < 0)
716 sc_log(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
717 else
718 sc_log(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
719 scconf_free(ctx->conf);
720 ctx->conf = NULL;
721 return;
722 }
723 /* needs to be after the log file is known */
724 sc_log(ctx, "Used configuration file '%s'", conf_path);
725 blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->app_name);
726 if (blocks && blocks[0])
727 ctx->conf_blocks[count++] = blocks[0];
728 free(blocks);
729 if (strcmp(ctx->app_name, "default") != 0) {
730 blocks = scconf_find_blocks(ctx->conf, NULL, "app", "default");
731 if (blocks && blocks[0])
732 ctx->conf_blocks[count] = blocks[0];
733 free(blocks);
734 }
735 /* Above we add 2 blocks at most, but conf_blocks has 3 elements,
736 * so at least one is NULL */
737 for (i = 0; ctx->conf_blocks[i]; i++)
738 load_parameters(ctx, ctx->conf_blocks[i], opts);
739 }
740
sc_ctx_detect_readers(sc_context_t * ctx)741 int sc_ctx_detect_readers(sc_context_t *ctx)
742 {
743 int r = 0;
744 const struct sc_reader_driver *drv = ctx->reader_driver;
745
746 sc_mutex_lock(ctx, ctx->mutex);
747
748 if (drv->ops->detect_readers != NULL)
749 r = drv->ops->detect_readers(ctx);
750
751 sc_mutex_unlock(ctx, ctx->mutex);
752
753 return r;
754 }
755
sc_ctx_get_reader(sc_context_t * ctx,unsigned int i)756 sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i)
757 {
758 return list_get_at(&ctx->readers, i);
759 }
760
sc_ctx_get_reader_by_id(sc_context_t * ctx,unsigned int id)761 sc_reader_t *sc_ctx_get_reader_by_id(sc_context_t *ctx, unsigned int id)
762 {
763 return list_get_at(&ctx->readers, id);
764 }
765
sc_ctx_get_reader_by_name(sc_context_t * ctx,const char * name)766 sc_reader_t *sc_ctx_get_reader_by_name(sc_context_t *ctx, const char * name)
767 {
768 return list_seek(&ctx->readers, name);
769 }
770
sc_ctx_get_reader_count(sc_context_t * ctx)771 unsigned int sc_ctx_get_reader_count(sc_context_t *ctx)
772 {
773 return list_size(&ctx->readers);
774 }
775
sc_establish_context(sc_context_t ** ctx_out,const char * app_name)776 int sc_establish_context(sc_context_t **ctx_out, const char *app_name)
777 {
778 sc_context_param_t ctx_param;
779
780 memset(&ctx_param, 0, sizeof(sc_context_param_t));
781 ctx_param.ver = 0;
782 ctx_param.app_name = app_name;
783 return sc_context_create(ctx_out, &ctx_param);
784 }
785
786 /* For multithreaded issues */
sc_context_repair(sc_context_t ** ctx_out)787 int sc_context_repair(sc_context_t **ctx_out)
788 {
789 /* Must already exist */
790 if ((ctx_out == NULL) || (*ctx_out == NULL) ||
791 ((*ctx_out)->app_name == NULL))
792 return SC_ERROR_INVALID_ARGUMENTS;
793
794 /* The only thing that should be shared across different contexts are the
795 * card drivers - so rebuild the ATR's
796 */
797 load_card_atrs(*ctx_out);
798
799 /* TODO: May need to re-open any card driver DLL's */
800
801 return SC_SUCCESS;
802 }
803
sc_context_create(sc_context_t ** ctx_out,const sc_context_param_t * parm)804 int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
805 {
806 sc_context_t *ctx;
807 struct _sc_ctx_options opts;
808 int r;
809 char *driver;
810
811 if (ctx_out == NULL || parm == NULL)
812 return SC_ERROR_INVALID_ARGUMENTS;
813
814 ctx = calloc(1, sizeof(sc_context_t));
815 if (ctx == NULL)
816 return SC_ERROR_OUT_OF_MEMORY;
817 memset(&opts, 0, sizeof(opts));
818
819 /* set the application name if set in the parameter options */
820 if (parm->app_name != NULL)
821 ctx->app_name = strdup(parm->app_name);
822 else
823 ctx->app_name = strdup("default");
824 if (ctx->app_name == NULL) {
825 sc_release_context(ctx);
826 return SC_ERROR_OUT_OF_MEMORY;
827 }
828
829 ctx->flags = parm->flags;
830 set_defaults(ctx, &opts);
831
832 if (0 != list_init(&ctx->readers)) {
833 del_drvs(&opts);
834 sc_release_context(ctx);
835 return SC_ERROR_OUT_OF_MEMORY;
836 }
837 list_attributes_seeker(&ctx->readers, reader_list_seeker);
838 /* set thread context and create mutex object (if specified) */
839 if (parm->thread_ctx != NULL)
840 ctx->thread_ctx = parm->thread_ctx;
841 r = sc_mutex_create(ctx, &ctx->mutex);
842 if (r != SC_SUCCESS) {
843 del_drvs(&opts);
844 sc_release_context(ctx);
845 return r;
846 }
847
848 #if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE)
849 if (!CRYPTO_secure_malloc_initialized()) {
850 CRYPTO_secure_malloc_init(OPENSSL_SECURE_MALLOC_SIZE, OPENSSL_SECURE_MALLOC_SIZE/8);
851 }
852 #endif
853
854 process_config_file(ctx, &opts);
855 sc_log(ctx, "==================================="); /* first thing in the log */
856 sc_log(ctx, "opensc version: %s", sc_get_version());
857
858 #ifdef ENABLE_PCSC
859 ctx->reader_driver = sc_get_pcsc_driver();
860 #elif defined(ENABLE_CRYPTOTOKENKIT)
861 ctx->reader_driver = sc_get_cryptotokenkit_driver();
862 #elif defined(ENABLE_CTAPI)
863 ctx->reader_driver = sc_get_ctapi_driver();
864 #elif defined(ENABLE_OPENCT)
865 ctx->reader_driver = sc_get_openct_driver();
866 #endif
867
868 r = ctx->reader_driver->ops->init(ctx);
869 if (r != SC_SUCCESS) {
870 del_drvs(&opts);
871 sc_release_context(ctx);
872 return r;
873 }
874
875 driver = getenv("OPENSC_DRIVER");
876 if (driver) {
877 scconf_list *list = NULL;
878 scconf_list_add(&list, driver);
879 set_drivers(&opts, list);
880 scconf_list_destroy(list);
881 }
882
883 load_card_drivers(ctx, &opts);
884 load_card_atrs(ctx);
885
886 del_drvs(&opts);
887 sc_ctx_detect_readers(ctx);
888 *ctx_out = ctx;
889
890 return SC_SUCCESS;
891 }
892
893 /* Used by minidriver to pass in provided handles to reader-pcsc */
sc_ctx_use_reader(sc_context_t * ctx,void * pcsc_context_handle,void * pcsc_card_handle)894 int sc_ctx_use_reader(sc_context_t *ctx, void *pcsc_context_handle, void *pcsc_card_handle)
895 {
896 LOG_FUNC_CALLED(ctx);
897 if (ctx->reader_driver->ops->use_reader != NULL)
898 return ctx->reader_driver->ops->use_reader(ctx, pcsc_context_handle, pcsc_card_handle);
899
900 return SC_ERROR_NOT_SUPPORTED;
901 }
902
903 /* Following two are only implemented with internal PC/SC and don't consume a reader object */
sc_cancel(sc_context_t * ctx)904 int sc_cancel(sc_context_t *ctx)
905 {
906 LOG_FUNC_CALLED(ctx);
907 if (ctx->reader_driver->ops->cancel != NULL)
908 return ctx->reader_driver->ops->cancel(ctx);
909
910 return SC_ERROR_NOT_SUPPORTED;
911 }
912
913
sc_wait_for_event(sc_context_t * ctx,unsigned int event_mask,sc_reader_t ** event_reader,unsigned int * event,int timeout,void ** reader_states)914 int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, int timeout, void **reader_states)
915 {
916 LOG_FUNC_CALLED(ctx);
917 if (ctx->reader_driver->ops->wait_for_event != NULL)
918 return ctx->reader_driver->ops->wait_for_event(ctx, event_mask, event_reader, event, timeout, reader_states);
919
920 return SC_ERROR_NOT_SUPPORTED;
921 }
922
923
sc_release_context(sc_context_t * ctx)924 int sc_release_context(sc_context_t *ctx)
925 {
926 unsigned int i;
927
928 if (ctx == NULL) {
929 return SC_ERROR_INVALID_ARGUMENTS;
930 }
931 SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
932 while (list_size(&ctx->readers)) {
933 sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0);
934 _sc_delete_reader(ctx, rdr);
935 }
936
937 if (ctx->reader_driver->ops->finish != NULL)
938 ctx->reader_driver->ops->finish(ctx);
939
940 for (i = 0; ctx->card_drivers[i]; i++) {
941 struct sc_card_driver *drv = ctx->card_drivers[i];
942
943 if (drv->atr_map)
944 _sc_free_atr(ctx, drv);
945 if (drv->dll)
946 sc_dlclose(drv->dll);
947 }
948 if (ctx->preferred_language != NULL)
949 free(ctx->preferred_language);
950 if (ctx->mutex != NULL) {
951 int r = sc_mutex_destroy(ctx, ctx->mutex);
952 if (r != SC_SUCCESS) {
953 sc_log(ctx, "unable to destroy mutex");
954 return r;
955 }
956 }
957 if (ctx->conf != NULL)
958 scconf_free(ctx->conf);
959 if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr))
960 fclose(ctx->debug_file);
961 if (ctx->debug_filename != NULL)
962 free(ctx->debug_filename);
963 if (ctx->app_name != NULL)
964 free(ctx->app_name);
965 list_destroy(&ctx->readers);
966 sc_mem_clear(ctx, sizeof(*ctx));
967 free(ctx);
968 return SC_SUCCESS;
969 }
970
sc_set_card_driver(sc_context_t * ctx,const char * short_name)971 int sc_set_card_driver(sc_context_t *ctx, const char *short_name)
972 {
973 int i = 0, match = 0;
974
975 sc_mutex_lock(ctx, ctx->mutex);
976 if (short_name == NULL) {
977 ctx->forced_driver = NULL;
978 match = 1;
979 } else while (i < SC_MAX_CARD_DRIVERS && ctx->card_drivers[i] != NULL) {
980 struct sc_card_driver *drv = ctx->card_drivers[i];
981
982 if (strcmp(short_name, drv->short_name) == 0) {
983 ctx->forced_driver = drv;
984 match = 1;
985 break;
986 }
987 i++;
988 }
989 sc_mutex_unlock(ctx, ctx->mutex);
990 if (match == 0)
991 return SC_ERROR_OBJECT_NOT_FOUND; /* FIXME: invent error */
992 return SC_SUCCESS;
993 }
994
sc_get_cache_dir(sc_context_t * ctx,char * buf,size_t bufsize)995 int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize)
996 {
997 char *homedir;
998 const char *cache_dir;
999 scconf_block *conf_block = NULL;
1000 #ifdef _WIN32
1001 char temp_path[PATH_MAX];
1002 #endif
1003 conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
1004 cache_dir = scconf_get_str(conf_block, "file_cache_dir", NULL);
1005 if (cache_dir != NULL) {
1006 strlcpy(buf, cache_dir, bufsize);
1007 return SC_SUCCESS;
1008 }
1009
1010 #ifndef _WIN32
1011 #ifdef __APPLE__
1012 cache_dir = getenv("Caches");
1013 #else
1014 cache_dir = getenv("XDG_CACHE_HOME");
1015 #endif
1016 if (cache_dir != NULL && cache_dir[0] != '\0') {
1017 snprintf(buf, bufsize, "%s/%s", cache_dir, "opensc");
1018 return SC_SUCCESS;
1019 }
1020 cache_dir = ".cache/opensc";
1021 homedir = getenv("HOME");
1022 #else
1023 cache_dir = "eid-cache";
1024 homedir = getenv("USERPROFILE");
1025 /* If USERPROFILE isn't defined, assume it's a single-user OS
1026 * and put the cache dir in the Windows dir (usually C:\\WINDOWS) */
1027 if (homedir == NULL || homedir[0] == '\0') {
1028 GetWindowsDirectoryA(temp_path, sizeof(temp_path));
1029 homedir = temp_path;
1030 }
1031 #endif
1032 if (homedir == NULL || homedir[0] == '\0')
1033 return SC_ERROR_INTERNAL;
1034 if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0)
1035 return SC_ERROR_BUFFER_TOO_SMALL;
1036 return SC_SUCCESS;
1037 }
1038
sc_make_cache_dir(sc_context_t * ctx)1039 int sc_make_cache_dir(sc_context_t *ctx)
1040 {
1041 char dirname[PATH_MAX], *sp;
1042 int r, mkdir_checker;
1043 size_t j, namelen;
1044
1045 if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
1046 return r;
1047 namelen = strlen(dirname);
1048
1049 while (1) {
1050 #ifdef _WIN32
1051 mkdir_checker = mkdir(dirname) >= 0;
1052 #else
1053 mkdir_checker = mkdir(dirname, 0700) >= 0;
1054 #endif
1055 if (mkdir_checker)
1056 break;
1057
1058 if (errno != ENOENT || (sp = strrchr(dirname, '/')) == NULL
1059 || sp == dirname)
1060 goto failed;
1061 *sp = '\0';
1062 }
1063
1064 /* We may have stripped one or more path components from
1065 * the directory name. Restore them */
1066 while (1) {
1067 j = strlen(dirname);
1068 if (j >= namelen)
1069 break;
1070 dirname[j] = '/';
1071 #ifdef _WIN32
1072 mkdir_checker = mkdir(dirname) < 0;
1073 #else
1074 mkdir_checker = mkdir(dirname, 0700) < 0;
1075 #endif
1076 if (mkdir_checker)
1077 goto failed;
1078 }
1079 return SC_SUCCESS;
1080
1081 /* for lack of a better return code */
1082 failed:
1083 sc_log(ctx, "failed to create cache directory");
1084 return SC_ERROR_INTERNAL;
1085 }
1086