Coverage Report

Created: 2025-10-10 06:27

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