Coverage Report

Created: 2026-09-03 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card.c
Line
Count
Source
1
/*
2
 * card.c: General smart card functions
3
 *
4
 * Copyright (C) 2001, 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 <assert.h>
26
#include <stdlib.h>
27
#ifdef HAVE_UNISTD_H
28
#include <unistd.h>
29
#endif
30
#include <string.h>
31
#include <limits.h>
32
33
#include "reader-tr03119.h"
34
#include "internal.h"
35
#include "asn1.h"
36
#include "common/compat_strlcpy.h"
37
38
#ifdef ENABLE_SM
39
static int sc_card_sm_load(sc_card_t *card, const char *path, const char *module);
40
static int sc_card_sm_unload(sc_card_t *card);
41
static int sc_card_sm_check(sc_card_t *card);
42
#endif
43
44
int sc_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
45
493k
{
46
493k
  if (card == NULL)
47
0
    return SC_ERROR_INVALID_ARGUMENTS;
48
493k
  if (card->ops->check_sw == NULL)
49
0
    return SC_ERROR_NOT_SUPPORTED;
50
493k
  return card->ops->check_sw(card, sw1, sw2);
51
493k
}
52
53
void sc_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
54
        int cse, int ins, int p1, int p2)
55
665k
{
56
665k
  if (card == NULL || apdu == NULL) {
57
0
    return;
58
0
  }
59
665k
  memset(apdu, 0, sizeof(*apdu));
60
665k
  apdu->cla = (u8) card->cla;
61
665k
  apdu->cse = cse;
62
665k
  apdu->ins = (u8) ins;
63
665k
  apdu->p1 = (u8) p1;
64
665k
  apdu->p2 = (u8) p2;
65
665k
}
66
67
void sc_format_apdu_cse_lc_le(struct sc_apdu *apdu)
68
2.92k
{
69
  /* TODO calculating the APDU case, Lc and Le should actually only be
70
   * done in sc_apdu2bytes, but to gradually change OpenSC we start here. */
71
  /* Let sc_detect_apdu_cse set short or extended  and test for chaining */
72
73
2.92k
  if (!apdu)
74
0
    return;
75
2.92k
  if (apdu->datalen > SC_MAX_APDU_DATA_SIZE
76
2.92k
      || apdu->resplen > SC_MAX_APDU_RESP_SIZE) {
77
    /* extended length  or data chaining and/or get response */
78
0
    if (apdu->datalen <= SC_MAX_EXT_APDU_DATA_SIZE)
79
0
      apdu->lc = apdu->datalen;
80
0
    if (apdu->resplen <= SC_MAX_EXT_APDU_RESP_SIZE)
81
0
      apdu->le = apdu->resplen;
82
0
    if (apdu->resplen && !apdu->datalen)
83
0
      apdu->cse = SC_APDU_CASE_2;
84
0
    if (!apdu->resplen && apdu->datalen)
85
0
      apdu->cse = SC_APDU_CASE_3;
86
0
    if (apdu->resplen && apdu->datalen)
87
0
      apdu->cse = SC_APDU_CASE_4;
88
2.92k
  } else {
89
    /* short length */
90
2.92k
    if (apdu->datalen <= SC_MAX_APDU_DATA_SIZE)
91
2.92k
      apdu->lc = apdu->datalen;
92
2.92k
    if (apdu->resplen <= SC_MAX_APDU_RESP_SIZE)
93
2.92k
      apdu->le = apdu->resplen;
94
2.92k
    if (!apdu->resplen && !apdu->datalen)
95
0
      apdu->cse = SC_APDU_CASE_1;
96
2.92k
    if (apdu->resplen && !apdu->datalen)
97
124
      apdu->cse = SC_APDU_CASE_2_SHORT;
98
2.92k
    if (!apdu->resplen && apdu->datalen)
99
2.65k
      apdu->cse = SC_APDU_CASE_3_SHORT;
100
2.92k
    if (apdu->resplen && apdu->datalen)
101
147
      apdu->cse = SC_APDU_CASE_4_SHORT;
102
2.92k
  }
103
2.92k
}
104
105
void sc_format_apdu_ex(struct sc_apdu *apdu,
106
    u8 cla, u8 ins, u8 p1, u8 p2,
107
    const u8 *data, size_t datalen,
108
    u8 *resp, size_t resplen)
109
2.92k
{
110
2.92k
  if (!apdu) {
111
0
    return;
112
0
  }
113
114
2.92k
  memset(apdu, 0, sizeof(*apdu));
115
2.92k
  apdu->cla = cla;
116
2.92k
  apdu->ins = ins;
117
2.92k
  apdu->p1 = p1;
118
2.92k
  apdu->p2 = p2;
119
2.92k
  apdu->resp = resp;
120
2.92k
  apdu->resplen = resplen;
121
2.92k
  apdu->data = data;
122
2.92k
  apdu->datalen = datalen;
123
2.92k
  sc_format_apdu_cse_lc_le(apdu);
124
2.92k
}
125
126
static sc_card_t * sc_card_new(sc_context_t *ctx)
127
17.1k
{
128
17.1k
  sc_card_t *card;
129
130
17.1k
  if (ctx == NULL)
131
0
    return NULL;
132
133
17.1k
  card = calloc(1, sizeof(struct sc_card));
134
17.1k
  if (card == NULL)
135
0
    return NULL;
136
17.1k
  card->ops = malloc(sizeof(struct sc_card_operations));
137
17.1k
  if (card->ops == NULL) {
138
0
    free(card);
139
0
    return NULL;
140
0
  }
141
142
17.1k
  card->ctx = ctx;
143
17.1k
  if (sc_mutex_create(ctx, &card->mutex) != SC_SUCCESS) {
144
0
    free(card->ops);
145
0
    free(card);
146
0
    return NULL;
147
0
  }
148
149
17.1k
  card->type = -1;
150
17.1k
  card->app_count = -1;
151
152
17.1k
  return card;
153
17.1k
}
154
155
static void sc_card_free(sc_card_t *card)
156
17.1k
{
157
17.1k
  sc_free_apps(card);
158
17.1k
  sc_free_ef_atr(card);
159
160
17.1k
  free(card->ops);
161
162
17.1k
  if (card->algorithms != NULL)   {
163
12.2k
    int i;
164
68.7k
    for (i=0; i<card->algorithm_count; i++)   {
165
56.5k
      struct sc_algorithm_info *info = (card->algorithms + i);
166
56.5k
      if (info->algorithm == SC_ALGORITHM_EC ||
167
46.3k
          info->algorithm == SC_ALGORITHM_EDDSA ||
168
46.0k
          info->algorithm == SC_ALGORITHM_XEDDSA) {
169
12.4k
        sc_clear_ec_params(&info->u._ec.params);
170
12.4k
      }
171
56.5k
    }
172
12.2k
    free(card->algorithms);
173
174
12.2k
    card->algorithms = NULL;
175
12.2k
    card->algorithm_count = 0;
176
12.2k
  }
177
178
17.1k
  if (card->mutex != NULL) {
179
0
    int r = sc_mutex_destroy(card->ctx, card->mutex);
180
0
    if (r != SC_SUCCESS)
181
0
      sc_log(card->ctx, "unable to destroy mutex");
182
0
  }
183
17.1k
  sc_mem_clear(card, sizeof(*card));
184
17.1k
  free(card);
185
17.1k
}
186
187
size_t sc_get_max_recv_size(const sc_card_t *card)
188
249k
{
189
249k
  size_t max_recv_size;
190
249k
  if (card == NULL || card->reader == NULL) {
191
0
    return 0;
192
0
  }
193
249k
  max_recv_size = card->max_recv_size;
194
195
  /* initialize max_recv_size to a meaningful value */
196
249k
  if (card->caps & SC_CARD_CAP_APDU_EXT) {
197
20.0k
    if (!max_recv_size)
198
2.59k
      max_recv_size = 65536;
199
229k
  } else {
200
229k
    if (!max_recv_size)
201
140k
      max_recv_size = 256;
202
229k
  }
203
204
  /*  Override card limitations with reader limitations. */
205
249k
  if (card->reader->max_recv_size != 0
206
10.1k
      && (card->reader->max_recv_size < card->max_recv_size))
207
0
    max_recv_size = card->reader->max_recv_size;
208
209
249k
  return max_recv_size;
210
249k
}
211
212
size_t sc_get_max_send_size(const sc_card_t *card)
213
35.5k
{
214
35.5k
  size_t max_send_size;
215
216
35.5k
  if (card == NULL || card->reader == NULL) {
217
0
    return 0;
218
0
  }
219
220
35.5k
  max_send_size = card->max_send_size;
221
222
  /* initialize max_send_size to a meaningful value */
223
35.5k
  if (card->caps & SC_CARD_CAP_APDU_EXT
224
5.86k
      && card->reader->active_protocol != SC_PROTO_T0) {
225
5.86k
    if (!max_send_size)
226
860
      max_send_size = 65535;
227
29.7k
  } else {
228
29.7k
    if (!max_send_size)
229
9.83k
      max_send_size = 255;
230
29.7k
  }
231
232
  /*  Override card limitations with reader limitations. */
233
35.5k
  if (card->reader->max_send_size != 0
234
0
      && (card->reader->max_send_size < card->max_send_size))
235
0
    max_send_size = card->reader->max_send_size;
236
237
35.5k
  return max_send_size;
238
35.5k
}
239
240
int sc_connect_card(sc_reader_t *reader, sc_card_t **card_out)
241
17.1k
{
242
17.1k
  sc_card_t *card;
243
17.1k
  sc_context_t *ctx;
244
17.1k
  struct sc_card_driver *driver;
245
17.1k
  int i, r = 0, idx, connected = 0;
246
247
17.1k
  if (card_out == NULL || reader == NULL)
248
0
    return SC_ERROR_INVALID_ARGUMENTS;
249
17.1k
  ctx = reader->ctx;
250
17.1k
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
251
17.1k
  if (reader->ops->connect == NULL)
252
17.1k
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
253
254
17.1k
  card = sc_card_new(ctx);
255
17.1k
  if (card == NULL)
256
17.1k
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
257
17.1k
  r = reader->ops->connect(reader);
258
17.1k
  if (r)
259
0
    goto err;
260
261
17.1k
  connected = 1;
262
17.1k
  card->reader = reader;
263
17.1k
  card->ctx = ctx;
264
265
17.1k
  if (reader->flags & SC_READER_ENABLE_ESCAPE)
266
0
    sc_detect_escape_cmds(reader);
267
268
17.1k
  memcpy(&card->atr, &reader->atr, sizeof(card->atr));
269
17.1k
  memcpy(&card->uid, &reader->uid, sizeof(card->uid));
270
271
17.1k
  _sc_parse_atr(reader);
272
273
  /* See if the ATR matches any ATR specified in the config file */
274
17.1k
  if ((driver = ctx->forced_driver) == NULL) {
275
17.1k
    sc_log(ctx, "matching configured ATRs");
276
786k
    for (i = 0; ctx->card_drivers[i] != NULL; i++) {
277
769k
      driver = ctx->card_drivers[i];
278
279
769k
      if (driver->atr_map == NULL ||
280
769k
          !strcmp(driver->short_name, "default")) {
281
769k
        driver = NULL;
282
769k
        continue;
283
769k
      }
284
0
      sc_log(ctx, "trying driver '%s'", driver->short_name);
285
0
      idx = _sc_match_atr(card, driver->atr_map, NULL);
286
0
      if (idx >= 0) {
287
0
        struct sc_atr_table *src = &driver->atr_map[idx];
288
289
0
        sc_log(ctx, "matched driver '%s'", driver->name);
290
        /* It's up to card driver to notice these correctly */
291
0
        card->name = src->name;
292
0
        card->type = src->type;
293
0
        card->flags = src->flags;
294
0
        break;
295
0
      }
296
0
      driver = NULL;
297
0
    }
298
17.1k
  }
299
300
17.1k
  if (driver != NULL) {
301
    /* Forced driver, or matched via ATR mapping from config file */
302
0
    card->driver = driver;
303
304
0
    memcpy(card->ops, card->driver->ops, sizeof(struct sc_card_operations));
305
0
    if (card->ops->match_card != NULL)
306
0
      if (card->ops->match_card(card) != 1)
307
0
        sc_log(ctx, "driver '%s' match_card() failed: %s (will continue anyway)", card->driver->name, sc_strerror(r));
308
309
0
    if (card->ops->init != NULL) {
310
0
      r = card->ops->init(card);
311
0
      if (r) {
312
0
        sc_log(ctx, "driver '%s' init() failed: %s", card->driver->name, sc_strerror(r));
313
0
        goto err;
314
0
      }
315
0
    }
316
0
  }
317
17.1k
  else {
318
17.1k
    sc_card_t uninitialized = *card;
319
17.1k
    sc_log(ctx, "matching built-in ATRs");
320
454k
    for (i = 0; ctx->card_drivers[i] != NULL; i++) {
321
      /* FIXME If we had a clean API description, we'd probably get a
322
       * cleaner implementation of the driver's match_card and init,
323
       * which should normally *not* modify the card object if
324
       * unsuccessful. However, after years of relentless hacking, reality
325
       * is different: The card object is changed in virtually every card
326
       * driver so in order to prevent unwanted interaction, we reset the
327
       * card object here and hope that the card driver at least doesn't
328
       * allocate any internal resources that need to be freed. If we
329
       * had more time, we should refactor the existing code to not
330
       * modify sc_card_t until complete success (possibly by combining
331
       * `match_card()` and `init()`) */
332
452k
      *card = uninitialized;
333
334
452k
      struct sc_card_driver *drv = ctx->card_drivers[i];
335
452k
      const struct sc_card_operations *ops = drv->ops;
336
337
452k
      sc_log(ctx, "trying driver '%s'", drv->short_name);
338
452k
      if (ops == NULL || ops->match_card == NULL)   {
339
0
        continue;
340
0
      }
341
452k
      else if (!(ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER)
342
452k
            && !strcmp("default", drv->short_name))   {
343
2.63k
        sc_log(ctx , "ignore 'default' card driver");
344
2.63k
        continue;
345
2.63k
      }
346
347
      /* Needed if match_card() needs to talk with the card (e.g. card-muscle) */
348
449k
      *card->ops = *ops;
349
449k
      if (ops->match_card(card) != 1)
350
433k
        continue;
351
15.4k
      sc_log(ctx, "matched: %s", drv->name);
352
15.4k
      memcpy(card->ops, ops, sizeof(struct sc_card_operations));
353
15.4k
      card->driver = drv;
354
15.4k
      r = ops->init(card);
355
15.4k
      if (r) {
356
1.68k
        sc_log(ctx, "driver '%s' init() failed: %s", drv->name, sc_strerror(r));
357
1.68k
        if (r == SC_ERROR_INVALID_CARD) {
358
984
          card->driver = NULL;
359
984
          continue;
360
984
        }
361
700
        goto err;
362
1.68k
      }
363
13.7k
      break;
364
15.4k
    }
365
17.1k
  }
366
16.4k
  if (card->driver == NULL) {
367
2.63k
    sc_log(ctx, "unable to find driver for inserted card");
368
2.63k
    r = SC_ERROR_INVALID_CARD;
369
2.63k
    goto err;
370
2.63k
  }
371
13.7k
  if (card->name == NULL)
372
1.92k
    card->name = card->driver->name;
373
374
  /* initialize max_send_size/max_recv_size to a meaningful value */
375
13.7k
  card->max_recv_size = sc_get_max_recv_size(card);
376
13.7k
  card->max_send_size = sc_get_max_send_size(card);
377
378
13.7k
  sc_log(ctx, "card info name:'%s', type:%i, flags:0x%lX, max_send/recv_size:%zu/%zu",
379
13.7k
      card->name, card->type, card->flags, card->max_send_size, card->max_recv_size);
380
381
13.7k
#ifdef ENABLE_SM
382
  /* Check, if secure messaging module present. */
383
13.7k
  r = sc_card_sm_check(card);
384
13.7k
  if (r)   {
385
0
    sc_log(ctx, "cannot load secure messaging module");
386
0
    goto err;
387
0
  }
388
13.7k
#endif
389
13.7k
  *card_out = card;
390
391
13.7k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
392
3.33k
err:
393
3.33k
  if (connected)
394
3.33k
    reader->ops->disconnect(reader);
395
3.33k
  if (card != NULL)
396
3.33k
    sc_card_free(card);
397
3.33k
  LOG_FUNC_RETURN(ctx, r);
398
3.33k
}
399
400
int sc_disconnect_card(sc_card_t *card)
401
13.7k
{
402
13.7k
  sc_context_t *ctx;
403
404
13.7k
  if (!card)
405
0
    return SC_ERROR_INVALID_ARGUMENTS;
406
407
13.7k
  ctx = card->ctx;
408
13.7k
  LOG_FUNC_CALLED(ctx);
409
410
13.7k
  if (card->ops->finish) {
411
12.7k
    int r = card->ops->finish(card);
412
12.7k
    if (r)
413
8
      sc_log(ctx, "card driver finish() failed: %s", sc_strerror(r));
414
12.7k
  }
415
416
13.7k
  if (card->reader->ops->disconnect) {
417
13.7k
    int r = card->reader->ops->disconnect(card->reader);
418
13.7k
    if (r)
419
0
      sc_log(ctx, "disconnect() failed: %s", sc_strerror(r));
420
13.7k
  }
421
422
13.7k
#ifdef ENABLE_SM
423
  /* release SM related resources */
424
13.7k
  sc_card_sm_unload(card);
425
13.7k
#endif
426
427
13.7k
  sc_card_free(card);
428
13.7k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
429
13.7k
}
430
431
int sc_reset(sc_card_t *card, int do_cold_reset)
432
0
{
433
0
  int r, r2;
434
435
0
  if (card == NULL)
436
0
    return SC_ERROR_INVALID_ARGUMENTS;
437
0
  if (card->reader->ops->reset == NULL)
438
0
    return SC_ERROR_NOT_SUPPORTED;
439
440
0
  r = sc_mutex_lock(card->ctx, card->mutex);
441
0
  if (r != SC_SUCCESS)
442
0
    return r;
443
444
0
  r = card->reader->ops->reset(card->reader, do_cold_reset);
445
446
0
  r2 = sc_mutex_unlock(card->ctx, card->mutex);
447
0
  if (r2 != SC_SUCCESS) {
448
0
    sc_log(card->ctx, "unable to release lock");
449
0
    r = r != SC_SUCCESS ? r : r2;
450
0
  }
451
452
0
  return r;
453
0
}
454
455
int sc_lock(sc_card_t *card)
456
718k
{
457
718k
  int r = 0, r2 = 0;
458
718k
  int was_reset = 0;
459
718k
  int reader_lock_obtained  = 0;
460
461
718k
  if (card == NULL)
462
0
    return SC_ERROR_INVALID_ARGUMENTS;
463
464
718k
  LOG_FUNC_CALLED(card->ctx);
465
466
718k
  r = sc_mutex_lock(card->ctx, card->mutex);
467
718k
  if (r != SC_SUCCESS)
468
0
    return r;
469
718k
  if (card->lock_count == 0) {
470
461k
    if (card->reader->ops->lock != NULL) {
471
461k
      r = card->reader->ops->lock(card->reader);
472
461k
      while (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
473
0
        if (was_reset++ > 4) /* TODO retry a few times */
474
0
          break;
475
0
        r = card->reader->ops->lock(card->reader);
476
0
      }
477
461k
      if (r == 0)
478
461k
        reader_lock_obtained = 1;
479
461k
    }
480
461k
  }
481
718k
  if (r == 0)
482
718k
    card->lock_count++;
483
484
718k
  r2 = sc_mutex_unlock(card->ctx, card->mutex);
485
718k
  if (r2 != SC_SUCCESS) {
486
0
    sc_log(card->ctx, "unable to release card->mutex lock");
487
0
    r = r != SC_SUCCESS ? r : r2;
488
0
  }
489
490
718k
  if (r == 0 && was_reset > 0) {
491
0
#ifdef ENABLE_SM
492
0
    if (card->sm_ctx.ops.open)
493
0
      card->sm_ctx.ops.open(card);
494
0
#endif
495
0
  }
496
497
  /* give card driver a chance to do something when reader lock first obtained */
498
718k
  if (r == 0 && reader_lock_obtained == 1  && card->ops->card_reader_lock_obtained) {
499
227k
    if (SC_SUCCESS != card->ops->card_reader_lock_obtained(card, was_reset))
500
0
      sc_log(card->ctx, "card_reader_lock_obtained failed");
501
227k
  }
502
503
718k
  LOG_FUNC_RETURN(card->ctx, r);
504
718k
}
505
506
int sc_unlock(sc_card_t *card)
507
718k
{
508
718k
  int r, r2;
509
510
718k
  if (!card)
511
0
    return SC_ERROR_INVALID_ARGUMENTS;
512
513
718k
  LOG_FUNC_CALLED(card->ctx);
514
515
718k
  r = sc_mutex_lock(card->ctx, card->mutex);
516
718k
  if (r != SC_SUCCESS)
517
718k
    LOG_FUNC_RETURN(card->ctx, r);
518
519
718k
  if (card->lock_count < 1) {
520
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
521
0
  }
522
718k
  if (--card->lock_count == 0) {
523
    /* release reader lock */
524
461k
    if (card->reader->ops->unlock != NULL)
525
461k
      r = card->reader->ops->unlock(card->reader);
526
461k
  }
527
718k
  r2 = sc_mutex_unlock(card->ctx, card->mutex);
528
718k
  if (r2 != SC_SUCCESS) {
529
0
    sc_log(card->ctx, "unable to release lock");
530
0
    r = (r == SC_SUCCESS) ? r2 : r;
531
0
  }
532
533
718k
  return r;
534
718k
}
535
536
int sc_list_files(sc_card_t *card, u8 *buf, size_t buflen)
537
583
{
538
583
  int r;
539
540
583
  if (card == NULL) {
541
0
    return SC_ERROR_INVALID_ARGUMENTS;
542
0
  }
543
583
  LOG_FUNC_CALLED(card->ctx);
544
545
583
  if (card->ops->list_files == NULL)
546
583
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
547
583
  r = card->ops->list_files(card, buf, buflen);
548
549
583
  LOG_FUNC_RETURN(card->ctx, r);
550
583
}
551
552
int sc_create_file(sc_card_t *card, sc_file_t *file)
553
3.07k
{
554
3.07k
  int r;
555
3.07k
  char pbuf[SC_MAX_PATH_STRING_SIZE];
556
3.07k
  const sc_path_t *in_path;
557
558
3.07k
  if (card == NULL || file == NULL) {
559
0
    return SC_ERROR_INVALID_ARGUMENTS;
560
0
  }
561
562
3.07k
  in_path = &file->path;
563
3.07k
  r = sc_path_print(pbuf, sizeof(pbuf), in_path);
564
3.07k
  if (r != SC_SUCCESS)
565
3
    pbuf[0] = '\0';
566
567
3.07k
  sc_log(card->ctx, "called; type=%d, path=%s, id=%04i, size=%zu",
568
3.07k
      in_path->type, pbuf, file->id, file->size);
569
  /* ISO 7816-4: "Number of data bytes in the file, including structural information if any"
570
   * can not be bigger than two bytes */
571
3.07k
  if (file->size > 0xFFFF)
572
3.07k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
573
574
3.06k
  if (card->ops->create_file == NULL)
575
3.06k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
576
577
3.06k
  r = card->ops->create_file(card, file);
578
3.06k
  LOG_FUNC_RETURN(card->ctx, r);
579
3.06k
}
580
581
int sc_delete_file(sc_card_t *card, const sc_path_t *path)
582
872
{
583
872
  int r;
584
872
  char pbuf[SC_MAX_PATH_STRING_SIZE];
585
586
872
  if (card == NULL) {
587
0
    return SC_ERROR_INVALID_ARGUMENTS;
588
0
  }
589
590
872
  r = sc_path_print(pbuf, sizeof(pbuf), path);
591
872
  if (r != SC_SUCCESS)
592
8
    pbuf[0] = '\0';
593
594
872
  sc_log(card->ctx, "called; type=%d, path=%s", path->type, pbuf);
595
872
  if (card->ops->delete_file == NULL)
596
872
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
597
864
  r = card->ops->delete_file(card, path);
598
599
864
  LOG_FUNC_RETURN(card->ctx, r);
600
864
}
601
602
int sc_read_binary(sc_card_t *card, unsigned int idx,
603
       unsigned char *buf, size_t count, unsigned long *flags)
604
6.71k
{
605
6.71k
  size_t max_le = sc_get_max_recv_size(card);
606
6.71k
  size_t todo = count;
607
6.71k
  int r;
608
609
6.71k
  if (card == NULL || card->ops == NULL || buf == NULL) {
610
0
    return SC_ERROR_INVALID_ARGUMENTS;
611
0
  }
612
6.71k
  sc_log(card->ctx, "called; %zu bytes at index %d", count, idx);
613
6.71k
  if (count == 0)
614
6.71k
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
615
616
5.87k
#ifdef ENABLE_SM
617
5.87k
  if (card->sm_ctx.ops.read_binary)   {
618
116
    r = card->sm_ctx.ops.read_binary(card, idx, buf, count);
619
116
    if (r)
620
116
      LOG_FUNC_RETURN(card->ctx, r);
621
116
  }
622
5.78k
#endif
623
624
5.78k
  if (card->ops->read_binary == NULL)
625
5.78k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
626
627
  /* lock the card now to avoid deselection of the file */
628
5.78k
  r = sc_lock(card);
629
5.78k
  LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
630
631
13.7k
  while (todo > 0) {
632
13.0k
    size_t chunk = MIN(todo, max_le);
633
634
13.0k
    r = card->ops->read_binary(card, idx, buf, chunk, flags);
635
13.0k
    if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
636
771
      break;
637
12.3k
    if (r < 0 && todo != count) {
638
      /* the last command failed, but previous ones succeeded.
639
       * Let's just return what we've successfully read. */
640
1.64k
      sc_log(card->ctx, "Subsequent read failed with %d, returning what was read successfully.", r);
641
1.64k
      break;
642
1.64k
    }
643
10.6k
    if (r < 0) {
644
2.71k
      sc_unlock(card);
645
2.71k
      LOG_FUNC_RETURN(card->ctx, r);
646
2.71k
    }
647
7.95k
    if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) {
648
      /* `idx + r` or `todo - r` would overflow */
649
0
      sc_unlock(card);
650
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE);
651
0
    }
652
653
7.95k
    todo -= (size_t) r;
654
7.95k
    buf  += (size_t) r;
655
7.95k
    idx  += (size_t) r;
656
7.95k
  }
657
658
3.06k
  sc_unlock(card);
659
660
3.06k
  LOG_FUNC_RETURN(card->ctx, (int)(count - todo));
661
3.06k
}
662
663
int sc_write_binary(sc_card_t *card, unsigned int idx,
664
        const u8 *buf, size_t count, unsigned long flags)
665
0
{
666
0
  size_t max_lc = sc_get_max_send_size(card);
667
0
  size_t todo = count;
668
0
  int r;
669
670
0
  if (card == NULL || card->ops == NULL || buf == NULL) {
671
0
    return SC_ERROR_INVALID_ARGUMENTS;
672
0
  }
673
0
  sc_log(card->ctx, "called; %zu bytes at index %d", count, idx);
674
0
  if (count == 0)
675
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
676
677
0
  if (card->ops->write_binary == NULL)
678
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
679
680
  /* lock the card now to avoid deselection of the file */
681
0
  r = sc_lock(card);
682
0
  LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
683
684
0
  while (todo > 0) {
685
0
    size_t chunk = MIN(todo, max_lc);
686
687
0
    r = card->ops->write_binary(card, idx, buf, chunk, flags);
688
0
    if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
689
0
      break;
690
0
    if (r < 0) {
691
0
      sc_unlock(card);
692
0
      LOG_FUNC_RETURN(card->ctx, r);
693
0
    }
694
0
    if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) {
695
      /* `idx + r` or `todo - r` would overflow */
696
0
      sc_unlock(card);
697
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE);
698
0
    }
699
700
0
    todo -= (size_t) r;
701
0
    buf  += (size_t) r;
702
0
    idx  += (size_t) r;
703
0
  }
704
705
0
  sc_unlock(card);
706
707
0
  LOG_FUNC_RETURN(card->ctx, (int)(count - todo));
708
0
}
709
710
int sc_update_binary(sc_card_t *card, unsigned int idx,
711
         const u8 *buf, size_t count, unsigned long flags)
712
1.51k
{
713
1.51k
  size_t max_lc = sc_get_max_send_size(card);
714
1.51k
  size_t todo = count;
715
1.51k
  int r;
716
717
1.51k
  if (card == NULL || card->ops == NULL || buf == NULL) {
718
0
    return SC_ERROR_INVALID_ARGUMENTS;
719
0
  }
720
1.51k
  sc_log(card->ctx, "called; %zu bytes at index %d", count, idx);
721
1.51k
  if (count == 0)
722
1.51k
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
723
724
1.51k
#ifdef ENABLE_SM
725
1.51k
  if (card->sm_ctx.ops.update_binary)   {
726
6
    r = card->sm_ctx.ops.update_binary(card, idx, buf, count);
727
6
    if (r)
728
6
      LOG_FUNC_RETURN(card->ctx, r);
729
6
  }
730
1.50k
#endif
731
732
1.50k
  if (card->ops->update_binary == NULL)
733
1.50k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
734
735
  /* lock the card now to avoid deselection of the file */
736
1.50k
  r = sc_lock(card);
737
1.50k
  LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
738
739
6.60k
  while (todo > 0) {
740
5.32k
    size_t chunk = MIN(todo, max_lc);
741
742
5.32k
    r = card->ops->update_binary(card, idx, buf, chunk, flags);
743
5.32k
    if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
744
6
      break;
745
5.32k
    if (r < 0) {
746
220
      sc_unlock(card);
747
220
      LOG_FUNC_RETURN(card->ctx, r);
748
220
    }
749
5.10k
    if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) {
750
      /* `idx + r` or `todo - r` would overflow */
751
0
      sc_unlock(card);
752
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE);
753
0
    }
754
755
5.10k
    todo -= (size_t) r;
756
5.10k
    buf  += (size_t) r;
757
5.10k
    idx  += (size_t) r;
758
5.10k
  }
759
760
1.28k
  sc_unlock(card);
761
762
1.28k
  LOG_FUNC_RETURN(card->ctx, (int)(count - todo));
763
1.28k
}
764
765
766
int sc_erase_binary(struct sc_card *card, unsigned int idx, size_t count,  unsigned long flags)
767
65
{
768
65
  int r;
769
65
  size_t todo = count;
770
771
65
  if (card == NULL || card->ops == NULL) {
772
0
    return SC_ERROR_INVALID_ARGUMENTS;
773
0
  }
774
65
  sc_log(card->ctx, "called; erase %zu bytes from offset %d", count, idx);
775
65
  if (count == 0)
776
65
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
777
778
44
  if (card->ops->erase_binary == NULL)
779
44
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
780
781
  /* lock the card now to avoid deselection of the file */
782
44
  r = sc_lock(card);
783
44
  LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
784
785
64
  while (todo > 0) {
786
44
    r = card->ops->erase_binary(card, idx, todo, flags);
787
44
    if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
788
1
      break;
789
43
    if (r < 0) {
790
23
      sc_unlock(card);
791
23
      LOG_FUNC_RETURN(card->ctx, r);
792
23
    }
793
20
    if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) {
794
      /* `idx + r` or `todo - r` would overflow */
795
0
      sc_unlock(card);
796
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE);
797
0
    }
798
799
20
    todo -= (size_t) r;
800
20
    idx  += (size_t) r;
801
20
  }
802
803
21
  sc_unlock(card);
804
805
21
  LOG_FUNC_RETURN(card->ctx, (int)(count - todo));
806
21
}
807
808
809
int sc_select_file(sc_card_t *card, const sc_path_t *in_path,  sc_file_t **file)
810
123k
{
811
123k
  int r;
812
123k
  char pbuf[SC_MAX_PATH_STRING_SIZE];
813
814
123k
  if (card == NULL || in_path == NULL) {
815
0
    return SC_ERROR_INVALID_ARGUMENTS;
816
0
  }
817
818
123k
  r = sc_path_print(pbuf, sizeof(pbuf), in_path);
819
123k
  if (r != SC_SUCCESS)
820
402
    pbuf[0] = '\0';
821
822
  /* FIXME We should be a bit less strict and let the upper layers do
823
   * the initialization (including reuse of existing file objects). We
824
   * implemented this here because we are lazy. */
825
123k
  if (file != NULL)
826
74.8k
    *file = NULL;
827
828
123k
  sc_log(card->ctx, "called; type=%d, path=%s", in_path->type, pbuf);
829
123k
  if (in_path->len > SC_MAX_PATH_SIZE)
830
123k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
831
832
123k
  if (in_path->type == SC_PATH_TYPE_PATH) {
833
    /* Perform a sanity check */
834
91.1k
    size_t i;
835
836
91.1k
    if ((in_path->len & 1) != 0)
837
91.1k
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
838
839
306k
    for (i = 0; i < in_path->len/2; i++) {
840
216k
      u8 p1 = in_path->value[2*i],
841
216k
         p2 = in_path->value[2*i+1];
842
843
216k
      if ((p1 == 0x3F && p2 == 0x00) && i != 0)
844
216k
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
845
216k
    }
846
90.0k
  }
847
121k
  if (card->ops->select_file == NULL)
848
121k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
849
121k
  r = card->ops->select_file(card, in_path, file);
850
121k
  LOG_TEST_RET(card->ctx, r, "'SELECT' error");
851
852
33.3k
  if (file) {
853
18.6k
    if (*file)
854
      /* Remember file path */
855
17.9k
      (*file)->path = *in_path;
856
707
    else
857
      /* FIXME We should be a bit less strict and let the upper layers do
858
       * the error checking. We implemented this here because we are
859
       * lazy.  */
860
707
      r = SC_ERROR_INVALID_DATA;
861
18.6k
  }
862
863
33.3k
  LOG_FUNC_RETURN(card->ctx, r);
864
33.3k
}
865
866
867
int sc_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t len)
868
9.26k
{
869
9.26k
  int r;
870
871
9.26k
  sc_log(card->ctx, "called, tag=%04x", tag);
872
9.26k
  if (card->ops->get_data == NULL)
873
9.26k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
874
9.26k
  r = card->ops->get_data(card, tag, buf, len);
875
876
9.26k
  LOG_FUNC_RETURN(card->ctx, r);
877
9.26k
}
878
879
int sc_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t len)
880
0
{
881
0
  int r;
882
883
0
  sc_log(card->ctx,"called, tag=%04x", tag);
884
885
0
  if (card->ops->put_data == NULL)
886
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
887
0
  r = card->ops->put_data(card, tag, buf, len);
888
889
0
  LOG_FUNC_RETURN(card->ctx, r);
890
0
}
891
892
int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
893
15
{
894
15
  int r;
895
896
15
  if (len == 0)
897
0
    return SC_SUCCESS;
898
899
15
  if (card == NULL || rnd == NULL) {
900
0
    return SC_ERROR_INVALID_ARGUMENTS;
901
0
  }
902
903
15
  LOG_FUNC_CALLED(card->ctx);
904
905
15
  if (card->ops == NULL || card->ops->get_challenge == NULL)
906
15
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
907
908
15
  r = sc_lock(card);
909
15
  if (r != SC_SUCCESS)
910
15
    LOG_FUNC_RETURN(card->ctx, r);
911
912
34
  while (len > 0) {
913
27
    r = card->ops->get_challenge(card, rnd, len);
914
27
    if (r == 0)
915
2
      r = SC_ERROR_INVALID_DATA;
916
27
    if (r < 0) {
917
8
      sc_unlock(card);
918
8
      LOG_FUNC_RETURN(card->ctx, r);
919
8
    }
920
921
19
    rnd += (size_t) r;
922
19
    len -= (size_t) r;
923
19
  }
924
925
7
  sc_unlock(card);
926
927
7
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
928
7
}
929
930
int sc_read_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx,
931
       u8 *buf ,size_t count, unsigned long flags)
932
5.11k
{
933
5.11k
  size_t max_le = sc_get_max_recv_size(card);
934
5.11k
  size_t todo = count;
935
5.11k
  int r;
936
937
5.11k
  if (card == NULL || card->ops == NULL || buf == NULL) {
938
0
    return SC_ERROR_INVALID_ARGUMENTS;
939
0
  }
940
5.11k
  LOG_FUNC_CALLED(card->ctx);
941
5.11k
  if (count == 0)
942
5.11k
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
943
944
4.75k
  if (card->ops->read_record == NULL)
945
4.75k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
946
947
  /* lock the card now to avoid deselection of the file */
948
4.73k
  r = sc_lock(card);
949
4.73k
  LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
950
951
8.06k
  while (todo > 0) {
952
7.72k
    size_t chunk = MIN(todo, max_le);
953
954
7.72k
    r = card->ops->read_record(card, rec_nr, idx, buf, chunk, flags);
955
7.72k
    if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
956
1.36k
      break;
957
6.36k
    if (r < 0 && todo != count) {
958
      /* the last command failed, but previous ones succeeded.
959
       * Let's just return what we've successfully read. */
960
2.64k
      sc_log(card->ctx, "Subsequent read failed with %d, returning what was read successfully.", r);
961
2.64k
      break;
962
2.64k
    }
963
3.71k
    if (r < 0) {
964
387
      sc_unlock(card);
965
387
      LOG_FUNC_RETURN(card->ctx, r);
966
387
    }
967
3.32k
    if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) {
968
      /* `idx + r` or `todo - r` would overflow */
969
0
      sc_unlock(card);
970
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE);
971
0
    }
972
973
3.32k
    todo -= (size_t) r;
974
3.32k
    buf  += (size_t) r;
975
3.32k
    idx  += (size_t) r;
976
3.32k
  }
977
978
4.35k
  sc_unlock(card);
979
980
4.35k
  LOG_FUNC_RETURN(card->ctx, (int)(count - todo));
981
4.35k
}
982
983
int sc_write_record(sc_card_t *card, unsigned int rec_nr, const u8 * buf,
984
        size_t count, unsigned long flags)
985
0
{
986
0
  int r;
987
988
0
  if (card == NULL) {
989
0
    return SC_ERROR_INVALID_ARGUMENTS;
990
0
  }
991
0
  LOG_FUNC_CALLED(card->ctx);
992
993
0
  if (card->ops->write_record == NULL)
994
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
995
996
0
  r = card->ops->write_record(card, rec_nr, buf, count, flags);
997
0
  if (r == SC_SUCCESS) {
998
0
    r = (int)count;
999
0
  }
1000
1001
0
  LOG_FUNC_RETURN(card->ctx, r);
1002
0
}
1003
1004
int sc_append_record(sc_card_t *card, const u8 * buf, size_t count,
1005
         unsigned long flags)
1006
1
{
1007
1
  int r;
1008
1009
1
  if (card == NULL) {
1010
0
    return SC_ERROR_INVALID_ARGUMENTS;
1011
0
  }
1012
1
  LOG_FUNC_CALLED(card->ctx);
1013
1014
1
  if (card->ops->append_record == NULL)
1015
1
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1016
1017
0
  r = card->ops->append_record(card, buf, count, flags);
1018
0
  if (r == SC_SUCCESS) {
1019
0
    r = (int)count;
1020
0
  }
1021
1022
0
  LOG_FUNC_RETURN(card->ctx, r);
1023
0
}
1024
1025
int sc_update_record(sc_card_t *card, unsigned int rec_nr, unsigned int idx,
1026
         const u8 * buf, size_t count, unsigned long flags)
1027
1
{
1028
1
  size_t max_lc = sc_get_max_send_size(card);
1029
1
  size_t todo = count;
1030
1
  int r;
1031
1032
1
  if (card == NULL || card->ops == NULL || buf == NULL) {
1033
0
    return SC_ERROR_INVALID_ARGUMENTS;
1034
0
  }
1035
1
  LOG_FUNC_CALLED(card->ctx);
1036
1
  if (count == 0)
1037
1
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1038
1039
1
  if (card->ops->update_record == NULL)
1040
1
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1041
1042
  /* lock the card now to avoid deselection of the file */
1043
0
  r = sc_lock(card);
1044
0
  LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
1045
1046
0
  while (todo > 0) {
1047
0
    size_t chunk = MIN(todo, max_lc);
1048
1049
0
    r = card->ops->update_record(card, rec_nr, idx, buf, chunk, flags);
1050
0
    if (r == 0 || r == SC_ERROR_FILE_END_REACHED)
1051
0
      break;
1052
0
    if (r < 0) {
1053
0
      sc_unlock(card);
1054
0
      LOG_FUNC_RETURN(card->ctx, r);
1055
0
    }
1056
0
    if ((idx > SIZE_MAX - (size_t) r) || (size_t) r > todo) {
1057
      /* `idx + r` or `todo - r` would overflow */
1058
0
      sc_unlock(card);
1059
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OFFSET_TOO_LARGE);
1060
0
    }
1061
1062
0
    todo -= (size_t) r;
1063
0
    buf  += (size_t) r;
1064
0
    idx  += (size_t) r;
1065
0
  }
1066
1067
0
  sc_unlock(card);
1068
1069
0
  LOG_FUNC_RETURN(card->ctx, (int)(count - todo));
1070
0
}
1071
1072
int sc_delete_record(sc_card_t *card, unsigned int rec_nr)
1073
0
{
1074
0
  int r;
1075
1076
0
  if (card == NULL) {
1077
0
    return SC_ERROR_INVALID_ARGUMENTS;
1078
0
  }
1079
0
  LOG_FUNC_CALLED(card->ctx);
1080
1081
0
  if (card->ops->delete_record == NULL)
1082
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1083
1084
0
  r = card->ops->delete_record(card, rec_nr);
1085
1086
0
  LOG_FUNC_RETURN(card->ctx, r);
1087
0
}
1088
1089
int
1090
sc_card_ctl(sc_card_t *card, unsigned long cmd, void *args)
1091
25.1k
{
1092
25.1k
  int r = SC_ERROR_NOT_SUPPORTED;
1093
1094
25.1k
  if (card == NULL) {
1095
0
    return SC_ERROR_INVALID_ARGUMENTS;
1096
0
  }
1097
25.1k
  sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called with cmd=%lu\n", cmd);
1098
1099
25.1k
  if (card->ops->card_ctl != NULL)
1100
24.9k
    r = card->ops->card_ctl(card, cmd, args);
1101
1102
  /* suppress "not supported" error messages */
1103
25.1k
  if (r == SC_ERROR_NOT_SUPPORTED) {
1104
16.4k
    sc_log(card->ctx, "card_ctl(%lu) not supported", cmd);
1105
16.4k
    return r;
1106
16.4k
  }
1107
8.65k
  LOG_FUNC_RETURN(card->ctx, r);
1108
8.65k
}
1109
1110
int _sc_card_add_algorithm(sc_card_t *card, const sc_algorithm_info_t *info)
1111
56.5k
{
1112
56.5k
  sc_algorithm_info_t *p;
1113
1114
56.5k
  if (info == NULL) {
1115
0
    return SC_ERROR_INVALID_ARGUMENTS;
1116
0
  }
1117
56.5k
  p = (sc_algorithm_info_t *) realloc(card->algorithms, (card->algorithm_count + 1) * sizeof(*info));
1118
56.5k
  if (!p) {
1119
0
    return SC_ERROR_OUT_OF_MEMORY;
1120
0
  }
1121
56.5k
  card->algorithms = p;
1122
56.5k
  p += card->algorithm_count;
1123
56.5k
  card->algorithm_count++;
1124
56.5k
  *p = *info;
1125
56.5k
  return SC_SUCCESS;
1126
56.5k
}
1127
1128
int _sc_card_add_symmetric_alg(sc_card_t *card, unsigned int algorithm,
1129
             unsigned int key_length, unsigned long flags)
1130
1.71k
{
1131
1.71k
  sc_algorithm_info_t info;
1132
1133
1.71k
  memset(&info, 0, sizeof(info));
1134
1.71k
  info.algorithm = algorithm;
1135
1.71k
  info.key_length = key_length;
1136
1.71k
  info.flags = flags;
1137
1138
1.71k
  return _sc_card_add_algorithm(card, &info);
1139
1.71k
}
1140
1141
static int
1142
_sc_card_add_ec_alg_int(sc_card_t *card, size_t key_length,
1143
      unsigned long flags, unsigned long ext_flags,
1144
      struct sc_object_id *curve_oid,
1145
      int algorithm)
1146
12.4k
{
1147
12.4k
  sc_algorithm_info_t info;
1148
12.4k
  int r;
1149
1150
12.4k
  memset(&info, 0, sizeof(info));
1151
12.4k
  sc_init_oid(&info.u._ec.params.id);
1152
1153
12.4k
  info.algorithm = algorithm;
1154
12.4k
  info.key_length = key_length;
1155
12.4k
  info.flags = flags;
1156
1157
12.4k
  info.u._ec.ext_flags = ext_flags;
1158
12.4k
  if (curve_oid) {
1159
7.38k
    info.u._ec.params.id = *curve_oid;
1160
7.38k
    r = sc_encode_oid(card->ctx, &info.u._ec.params.id, &info.u._ec.params.der.value, &info.u._ec.params.der.len);
1161
7.38k
    LOG_TEST_GOTO_ERR(card->ctx, r, "sc_encode_oid failed");
1162
7.38k
    r = sc_pkcs15_fix_ec_parameters(card->ctx, &info.u._ec.params);
1163
7.38k
    LOG_TEST_GOTO_ERR(card->ctx, r, "sc_pkcs15_fix_ec_parameters failed");
1164
7.38k
  }
1165
1166
12.4k
  r = _sc_card_add_algorithm(card, &info);
1167
12.4k
  return r;
1168
0
err:
1169
0
  sc_clear_ec_params(&info.u._ec.params);
1170
0
  return r;
1171
12.4k
}
1172
1173
int  _sc_card_add_ec_alg(sc_card_t *card, size_t key_length,
1174
      unsigned long flags, unsigned long ext_flags,
1175
      struct sc_object_id *curve_oid)
1176
10.1k
{
1177
10.1k
  return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
1178
10.1k
    curve_oid, SC_ALGORITHM_EC);
1179
10.1k
}
1180
1181
int  _sc_card_add_eddsa_alg(sc_card_t *card, size_t key_length,
1182
      unsigned long flags, unsigned long ext_flags,
1183
      struct sc_object_id *curve_oid)
1184
251
{
1185
  /* For simplicity, share the ec union with the curve information */
1186
251
  return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
1187
251
    curve_oid, SC_ALGORITHM_EDDSA);
1188
251
}
1189
1190
int  _sc_card_add_xeddsa_alg(sc_card_t *card, size_t key_length,
1191
      unsigned long flags, unsigned long ext_flags,
1192
      struct sc_object_id *curve_oid)
1193
2.01k
{
1194
  /* For simplicity, share the ec union with the curve information */
1195
2.01k
  return _sc_card_add_ec_alg_int(card, key_length, flags, ext_flags,
1196
2.01k
    curve_oid, SC_ALGORITHM_XEDDSA);
1197
2.01k
}
1198
1199
sc_algorithm_info_t *sc_card_find_alg(sc_card_t *card,
1200
    unsigned int algorithm, size_t key_length, void *param)
1201
253
{
1202
253
  int i;
1203
1204
1.27k
  for (i = 0; i < card->algorithm_count; i++) {
1205
1.16k
    sc_algorithm_info_t *info = &card->algorithms[i];
1206
1207
1.16k
    if (param && (info->algorithm == SC_ALGORITHM_EC ||
1208
0
      info->algorithm == SC_ALGORITHM_EDDSA ||
1209
0
      info->algorithm == SC_ALGORITHM_XEDDSA)) {
1210
0
      if (sc_compare_oid((struct sc_object_id *)param, &info->u._ec.params.id))
1211
0
        return info;
1212
1.16k
    } else if (info->algorithm != algorithm) {
1213
417
      continue;
1214
744
    } else if (info->key_length == key_length)
1215
140
      return info;
1216
1.16k
  }
1217
113
  return NULL;
1218
253
}
1219
1220
sc_algorithm_info_t *sc_card_find_ec_alg(sc_card_t *card,
1221
    size_t key_length, struct sc_object_id *curve_name)
1222
67
{
1223
67
  return sc_card_find_alg(card, SC_ALGORITHM_EC, key_length, curve_name);
1224
67
}
1225
1226
sc_algorithm_info_t *sc_card_find_eddsa_alg(sc_card_t *card,
1227
    size_t key_length, struct sc_object_id *curve_name)
1228
0
{
1229
0
  return sc_card_find_alg(card, SC_ALGORITHM_EDDSA, key_length, curve_name);
1230
0
}
1231
1232
sc_algorithm_info_t *sc_card_find_xeddsa_alg(sc_card_t *card,
1233
    size_t key_length, struct sc_object_id *curve_name)
1234
0
{
1235
0
  return sc_card_find_alg(card, SC_ALGORITHM_XEDDSA, key_length, curve_name);
1236
0
}
1237
1238
int _sc_card_add_rsa_alg(sc_card_t *card, size_t key_length,
1239
       unsigned long flags, unsigned long exponent)
1240
42.2k
{
1241
42.2k
  sc_algorithm_info_t info;
1242
1243
42.2k
  memset(&info, 0, sizeof(info));
1244
42.2k
  info.algorithm = SC_ALGORITHM_RSA;
1245
42.2k
  info.key_length = key_length;
1246
42.2k
  info.flags = flags;
1247
  /* disable particular PKCS1 v1.5 padding type if also RAW is supported on card */
1248
42.2k
  if ((info.flags & (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_RAW)) == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_RAW)) {
1249
5.71k
    if (card->ctx->disable_hw_pkcs1_padding & SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01)
1250
0
      info.flags &= ~SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01;
1251
5.71k
    if (card->ctx->disable_hw_pkcs1_padding & SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02)
1252
5.71k
      info.flags &= ~SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02;
1253
5.71k
  }
1254
42.2k
  info.u._rsa.exponent = exponent;
1255
1256
42.2k
  return _sc_card_add_algorithm(card, &info);
1257
42.2k
}
1258
1259
sc_algorithm_info_t *sc_card_find_rsa_alg(sc_card_t *card, size_t key_length)
1260
186
{
1261
186
  return sc_card_find_alg(card, SC_ALGORITHM_RSA, key_length, NULL);
1262
186
}
1263
1264
sc_algorithm_info_t *sc_card_find_gostr3410_alg(sc_card_t *card, size_t key_length)
1265
0
{
1266
0
  return sc_card_find_alg(card, SC_ALGORITHM_GOSTR3410, key_length, NULL);
1267
0
}
1268
1269
static int match_atr_table(sc_context_t *ctx, const struct sc_atr_table *table, struct sc_atr *atr)
1270
402k
{
1271
402k
  u8 *card_atr_bin;
1272
402k
  size_t card_atr_bin_len;
1273
402k
  char card_atr_hex[3 * SC_MAX_ATR_SIZE];
1274
402k
  size_t card_atr_hex_len;
1275
402k
  unsigned int i = 0;
1276
1277
402k
  if (ctx == NULL || table == NULL || atr == NULL)
1278
13.7k
    return -1;
1279
388k
  card_atr_bin = atr->value;
1280
388k
  card_atr_bin_len = atr->len;
1281
388k
  sc_bin_to_hex(card_atr_bin, card_atr_bin_len, card_atr_hex, sizeof(card_atr_hex), ':');
1282
388k
  card_atr_hex_len = strlen(card_atr_hex);
1283
1284
388k
  sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR     : %s", card_atr_hex);
1285
1286
3.23M
  for (i = 0; table[i].atr != NULL; i++) {
1287
2.85M
    const char *tatr = table[i].atr;
1288
2.85M
    const char *matr = table[i].atrmask;
1289
2.85M
    size_t tatr_len = strlen(tatr);
1290
2.85M
    u8 mbin[SC_MAX_ATR_SIZE], tbin[SC_MAX_ATR_SIZE];
1291
2.85M
    size_t mbin_len, tbin_len, s, matr_len;
1292
2.85M
    size_t fix_hex_len = card_atr_hex_len;
1293
2.85M
    size_t fix_bin_len = card_atr_bin_len;
1294
1295
2.85M
    sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR try : %s", tatr);
1296
1297
2.85M
    if (tatr_len != fix_hex_len) {
1298
2.78M
      sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ignored - wrong length");
1299
2.78M
      continue;
1300
2.78M
    }
1301
70.1k
    if (matr != NULL) {
1302
21.7k
      sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR mask: %s", matr);
1303
1304
21.7k
      matr_len = strlen(matr);
1305
21.7k
      if (tatr_len != matr_len)
1306
0
        continue;
1307
21.7k
      tbin_len = sizeof(tbin);
1308
21.7k
      sc_hex_to_bin(tatr, tbin, &tbin_len);
1309
21.7k
      mbin_len = sizeof(mbin);
1310
21.7k
      sc_hex_to_bin(matr, mbin, &mbin_len);
1311
21.7k
      if (mbin_len != fix_bin_len) {
1312
0
        sc_debug(ctx, SC_LOG_DEBUG_MATCH, "length of atr and atr mask do not match - ignored: %s - %s", tatr, matr);
1313
0
        continue;
1314
0
      }
1315
435k
      for (s = 0; s < tbin_len; s++) {
1316
        /* reduce tatr with mask */
1317
414k
        tbin[s] = (tbin[s] & mbin[s]);
1318
        /* create copy of card_atr_bin masked) */
1319
414k
        mbin[s] = (card_atr_bin[s] & mbin[s]);
1320
414k
      }
1321
21.7k
      if (memcmp(tbin, mbin, tbin_len) != 0)
1322
18.1k
        continue;
1323
48.4k
    } else {
1324
48.4k
      if (strncasecmp(tatr, card_atr_hex, tatr_len) != 0)
1325
43.6k
        continue;
1326
48.4k
    }
1327
8.39k
    return i;
1328
70.1k
  }
1329
379k
  return -1;
1330
388k
}
1331
1332
int _sc_match_atr(sc_card_t *card, const struct sc_atr_table *table, int *type_out)
1333
388k
{
1334
388k
  int res;
1335
1336
388k
  if (card == NULL)
1337
0
    return -1;
1338
388k
  res = match_atr_table(card->ctx, table, &card->atr);
1339
388k
  if (res < 0)
1340
379k
    return res;
1341
8.39k
  if (type_out != NULL)
1342
7.78k
    *type_out = table[res].type;
1343
8.39k
  return res;
1344
388k
}
1345
1346
scconf_block *_sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr *atr)
1347
13.7k
{
1348
13.7k
  struct sc_card_driver *drv;
1349
13.7k
  struct sc_atr_table *table;
1350
13.7k
  int res;
1351
1352
13.7k
  if (ctx == NULL)
1353
0
    return NULL;
1354
13.7k
  if (driver) {
1355
13.7k
    drv = driver;
1356
13.7k
    table = drv->atr_map;
1357
13.7k
    res = match_atr_table(ctx, table, atr);
1358
13.7k
    if (res < 0)
1359
13.7k
      return NULL;
1360
0
    return table[res].card_atr;
1361
13.7k
  } else {
1362
0
    unsigned int i;
1363
1364
0
    for (i = 0; ctx->card_drivers[i] != NULL; i++) {
1365
0
      drv = ctx->card_drivers[i];
1366
0
      table = drv->atr_map;
1367
0
      res = match_atr_table(ctx, table, atr);
1368
0
      if (res < 0)
1369
0
        continue;
1370
0
      return table[res].card_atr;
1371
0
    }
1372
0
  }
1373
0
  return NULL;
1374
13.7k
}
1375
1376
int _sc_add_atr(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr_table *src)
1377
0
{
1378
0
  struct sc_atr_table *map, *dst;
1379
1380
0
  map = (struct sc_atr_table *) realloc(driver->atr_map,
1381
0
      (driver->natrs + 2) * sizeof(struct sc_atr_table));
1382
0
  if (!map)
1383
0
    return SC_ERROR_OUT_OF_MEMORY;
1384
0
  driver->atr_map = map;
1385
1386
0
  dst = &driver->atr_map[driver->natrs++];
1387
0
  memset(dst, 0, sizeof(*dst));
1388
0
  memset(&driver->atr_map[driver->natrs], 0, sizeof(struct sc_atr_table));
1389
0
  dst->atr = strdup(src->atr);
1390
0
  if (!dst->atr)
1391
0
    return SC_ERROR_OUT_OF_MEMORY;
1392
1393
0
  if (src->atrmask) {
1394
0
    dst->atrmask = strdup(src->atrmask);
1395
0
    if (!dst->atrmask)
1396
0
      return SC_ERROR_OUT_OF_MEMORY;
1397
0
  }
1398
0
  else {
1399
0
    dst->atrmask = NULL;
1400
0
  }
1401
1402
0
  if (src->name) {
1403
0
    dst->name = strdup(src->name);
1404
0
    if (!dst->name)
1405
0
      return SC_ERROR_OUT_OF_MEMORY;
1406
0
  }
1407
0
  else {
1408
0
    dst->name = NULL;
1409
0
  }
1410
1411
0
  dst->type = src->type;
1412
0
  dst->flags = src->flags;
1413
0
  dst->card_atr = src->card_atr;
1414
1415
0
  return SC_SUCCESS;
1416
0
}
1417
1418
1419
int _sc_free_atr(sc_context_t *ctx, struct sc_card_driver *driver)
1420
0
{
1421
0
  unsigned int i;
1422
1423
0
  for (i = 0; i < driver->natrs; i++) {
1424
0
    struct sc_atr_table *src = &driver->atr_map[i];
1425
1426
0
    if (src->atr)
1427
0
      free((void *)src->atr);
1428
0
    if (src->atrmask)
1429
0
      free((void *)src->atrmask);
1430
0
    if (src->name)
1431
0
      free((void *)src->name);
1432
0
    src->card_atr = NULL;
1433
0
    src = NULL;
1434
0
  }
1435
0
  if (driver->atr_map)
1436
0
    free(driver->atr_map);
1437
0
  driver->atr_map = NULL;
1438
0
  driver->natrs = 0;
1439
1440
0
  return SC_SUCCESS;
1441
0
}
1442
1443
1444
scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char *name2, int priority)
1445
37.4k
{
1446
37.4k
  int i;
1447
37.4k
  scconf_block *conf_block = NULL;
1448
1449
74.9k
  for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
1450
37.4k
    scconf_block **blocks;
1451
1452
37.4k
    blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], name1, name2);
1453
37.4k
    if (blocks != NULL) {
1454
37.4k
      conf_block = blocks[0];
1455
37.4k
      free(blocks);
1456
37.4k
    }
1457
37.4k
    if (conf_block != NULL && priority)
1458
0
      break;
1459
37.4k
  }
1460
37.4k
  return conf_block;
1461
37.4k
}
1462
1463
void
1464
sc_clear_ec_params(struct sc_ec_parameters *ecp)
1465
17.3k
{
1466
17.3k
  if (ecp) {
1467
17.3k
    free(ecp->named_curve);
1468
17.3k
    free(ecp->der.value);
1469
17.3k
    memset(ecp, 0, sizeof(struct sc_ec_parameters));
1470
17.3k
  }
1471
17.3k
  return;
1472
17.3k
}
1473
1474
int sc_copy_ec_params(struct sc_ec_parameters *dst, struct sc_ec_parameters *src)
1475
1.89k
{
1476
1.89k
  if (!dst || !src)
1477
0
    return SC_ERROR_INVALID_ARGUMENTS;
1478
1479
1.89k
  memset(dst, 0, sizeof(*dst));
1480
1.89k
  if (src->named_curve)   {
1481
1.89k
    dst->named_curve = strdup(src->named_curve);
1482
1.89k
    if (!dst->named_curve)
1483
0
      return SC_ERROR_OUT_OF_MEMORY;
1484
1.89k
  }
1485
1.89k
  dst->id = src->id;
1486
1.89k
  if (src->der.value && src->der.len)   {
1487
1.89k
    dst->der.value = malloc(src->der.len);
1488
1.89k
    if (!dst->der.value) {
1489
0
      free(dst->named_curve);
1490
0
      return SC_ERROR_OUT_OF_MEMORY;
1491
0
    }
1492
1.89k
    memcpy(dst->der.value, src->der.value, src->der.len);
1493
1.89k
    dst->der.len = src->der.len;
1494
1.89k
  }
1495
1.89k
  dst->type = src->type;
1496
1.89k
  dst->field_length = src->field_length;
1497
1.89k
  dst->key_type = src->key_type;
1498
1499
1.89k
  return SC_SUCCESS;
1500
1.89k
}
1501
1502
scconf_block *
1503
sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr *atr)
1504
0
{
1505
0
  return _sc_match_atr_block(ctx, driver, atr);
1506
0
}
1507
1508
#ifdef ENABLE_SM
1509
static int
1510
sc_card_sm_unload(struct sc_card *card)
1511
13.7k
{
1512
13.7k
  if (card->sm_ctx.module.ops.module_cleanup)
1513
0
    card->sm_ctx.module.ops.module_cleanup(card->ctx);
1514
1515
13.7k
  if (card->sm_ctx.module.handle)
1516
0
    sc_dlclose(card->sm_ctx.module.handle);
1517
13.7k
  card->sm_ctx.module.handle = NULL;
1518
13.7k
  return 0;
1519
13.7k
}
1520
1521
1522
static int
1523
sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_module)
1524
0
{
1525
0
  struct sc_context *ctx = NULL;
1526
0
  int rv = SC_ERROR_INTERNAL;
1527
0
  char *module = NULL;
1528
#ifdef _WIN32
1529
  const char path_delim = '\\';
1530
#else
1531
0
  const char path_delim = '/';
1532
0
#endif
1533
1534
0
  if (card == NULL) {
1535
0
    return SC_ERROR_INVALID_ARGUMENTS;
1536
0
  }
1537
0
  ctx = card->ctx;
1538
0
  LOG_FUNC_CALLED(ctx);
1539
0
  if (!in_module)
1540
0
    return sc_card_sm_unload(card);
1541
1542
0
  sc_log(ctx, "SM module '%s' located in '%s'", in_module, module_path);
1543
0
  if (module_path && strlen(module_path) > 0)   {
1544
0
    size_t sz = strlen(in_module) + strlen(module_path) + 3;
1545
0
    module = malloc(sz);
1546
0
    if (module)
1547
0
      snprintf(module, sz, "%s%c%s", module_path, path_delim, in_module);
1548
0
  }
1549
0
  else   {
1550
0
    module = strdup(in_module);
1551
0
  }
1552
1553
0
  if (!module)
1554
0
    return SC_ERROR_OUT_OF_MEMORY;
1555
1556
0
  sc_log(ctx, "try to load SM module '%s'", module);
1557
0
  do  {
1558
0
    struct sm_module_operations *mod_ops = &card->sm_ctx.module.ops;
1559
0
    void *mod_handle;
1560
1561
0
    card->sm_ctx.module.handle = sc_dlopen(module);
1562
0
    if (!card->sm_ctx.module.handle)   {
1563
0
      sc_log(ctx, "cannot open dynamic library '%s': %s", module, sc_dlerror());
1564
0
      break;
1565
0
    }
1566
0
    mod_handle = card->sm_ctx.module.handle;
1567
1568
0
    mod_ops->initialize = sc_dlsym(mod_handle, "initialize");
1569
0
    if (!mod_ops->initialize)   {
1570
0
      sc_log(ctx, "SM handler 'initialize' not exported: %s", sc_dlerror());
1571
0
      break;
1572
0
    }
1573
1574
0
    mod_ops->get_apdus  = sc_dlsym(mod_handle, "get_apdus");
1575
0
    if (!mod_ops->get_apdus)   {
1576
0
      sc_log(ctx, "SM handler 'get_apdus' not exported: %s", sc_dlerror());
1577
0
      break;
1578
0
    }
1579
1580
0
    mod_ops->finalize  = sc_dlsym(mod_handle, "finalize");
1581
0
    if (!mod_ops->finalize)
1582
0
      sc_log(ctx, "SM handler 'finalize' not exported -- ignored");
1583
1584
0
    mod_ops->module_init  = sc_dlsym(mod_handle, "module_init");
1585
0
    if (!mod_ops->module_init)
1586
0
      sc_log(ctx, "SM handler 'module_init' not exported -- ignored");
1587
1588
0
    mod_ops->module_cleanup  = sc_dlsym(mod_handle, "module_cleanup");
1589
0
    if (!mod_ops->module_cleanup)
1590
0
      sc_log(ctx, "SM handler 'module_cleanup' not exported -- ignored");
1591
1592
0
    mod_ops->test  = sc_dlsym(mod_handle, "test");
1593
0
    if (mod_ops->test)
1594
0
      sc_log(ctx, "SM handler 'test' not exported -- ignored");
1595
1596
0
    rv = 0;
1597
0
    break;
1598
0
  } while(0);
1599
1600
0
  if (rv)
1601
0
    sc_card_sm_unload(card);
1602
1603
0
  card->sm_ctx.sm_mode = SM_MODE_ACL;
1604
0
  if (module)
1605
0
    free(module);
1606
1607
0
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv);
1608
0
}
1609
1610
1611
/* get SM related configuration settings and initialize SM session, SM module, ... */
1612
static int
1613
sc_card_sm_check(struct sc_card *card)
1614
13.7k
{
1615
13.7k
  const char *sm = NULL, *module_name = NULL, *module_path = NULL, *module_data = NULL, *sm_mode = NULL;
1616
13.7k
  struct sc_context *ctx = card->ctx;
1617
13.7k
  scconf_block *atrblock = NULL, *sm_conf_block = NULL;
1618
13.7k
  int rv, ii;
1619
#ifdef _WIN32
1620
  char temp_path[PATH_MAX];
1621
  size_t temp_len = PATH_MAX - 1;
1622
  char expanded_val[PATH_MAX];
1623
  DWORD expanded_len = PATH_MAX;
1624
#endif
1625
1626
13.7k
  LOG_FUNC_CALLED(ctx);
1627
1628
  /* get the name of card specific SM configuration section */
1629
13.7k
  atrblock = _sc_match_atr_block(ctx, card->driver, &card->atr);
1630
13.7k
  if (atrblock == NULL)
1631
13.7k
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1632
0
  sm = scconf_get_str(atrblock, "secure_messaging", NULL);
1633
0
  if (!sm)
1634
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1635
1636
  /* get SM configuration section by the name */
1637
0
  sc_log(ctx, "secure_messaging configuration block '%s'", sm);
1638
0
        for (ii = 0; ctx->conf_blocks[ii]; ii++) {
1639
0
    scconf_block **blocks;
1640
1641
0
    blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[ii], "secure_messaging", sm);
1642
0
    if (blocks) {
1643
0
      sm_conf_block = blocks[0];
1644
0
      free(blocks);
1645
0
    }
1646
0
    if (sm_conf_block != NULL)
1647
0
      break;
1648
0
  }
1649
1650
0
  if (!sm_conf_block)
1651
0
    LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "SM configuration block not preset");
1652
1653
  /* check if an external SM module has to be used */
1654
#ifdef _WIN32
1655
  rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX,
1656
      temp_path, &temp_len);
1657
  if (rv == SC_SUCCESS) {
1658
    temp_path[temp_len] = '\0';
1659
    module_path = temp_path;
1660
  }
1661
  expanded_len = ExpandEnvironmentStringsA(module_path, expanded_val, expanded_len);
1662
  if (0 < expanded_len && expanded_len < sizeof expanded_val)
1663
    module_path = expanded_val;
1664
#else
1665
0
  module_path = scconf_get_str(sm_conf_block, "module_path", DEFAULT_SM_MODULE_PATH);
1666
0
#endif
1667
0
  module_name = scconf_get_str(sm_conf_block, "module_name", DEFAULT_SM_MODULE);
1668
0
  sc_log(ctx, "SM module '%s' in  '%s'", module_name, module_path);
1669
0
  if (!module_name)
1670
0
    LOG_TEST_RET(ctx, SC_ERROR_INCONSISTENT_CONFIGURATION, "Invalid SM configuration: module not defined");
1671
1672
0
  rv = sc_card_sm_load(card, module_path, module_name);
1673
0
  LOG_TEST_RET(ctx, rv, "Failed to load SM module");
1674
1675
0
  strlcpy(card->sm_ctx.module.filename, module_name, sizeof(card->sm_ctx.module.filename));
1676
0
  strlcpy(card->sm_ctx.config_section, sm, sizeof(card->sm_ctx.config_section));
1677
1678
  /* allocate resources for the external SM module */
1679
0
  if (card->sm_ctx.module.ops.module_init)   {
1680
0
    module_data = scconf_get_str(sm_conf_block, "module_data", NULL);
1681
1682
0
    rv = card->sm_ctx.module.ops.module_init(ctx, module_data);
1683
0
    LOG_TEST_RET(ctx, rv, "Cannot initialize SM module");
1684
0
  }
1685
1686
  /* initialize SM session in the case of 'APDU TRANSMIT' SM mode */
1687
0
  sm_mode = scconf_get_str(sm_conf_block, "mode", NULL);
1688
0
  if (sm_mode && !strcasecmp("Transmit", sm_mode))   {
1689
0
    if (!card->sm_ctx.ops.open || !card->sm_ctx.ops.get_sm_apdu || !card->sm_ctx.ops.free_sm_apdu)
1690
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "'Transmit' SM asked but not supported by card driver");
1691
1692
0
    card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
1693
0
    rv = card->sm_ctx.ops.open(card);
1694
0
    LOG_TEST_RET(ctx, rv, "Cannot initialize SM");
1695
0
  }
1696
1697
0
  sc_log(ctx, "SM mode:%X", card->sm_ctx.sm_mode);
1698
0
  SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, rv);
1699
0
}
1700
#endif