Coverage Report

Created: 2026-10-17 06:30

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