Coverage Report

Created: 2026-10-17 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-sc-hsm.c
Line
Count
Source
1
/*
2
 * card-sc-hsm.c
3
 *
4
 * Driver for the SmartCard-HSM, a light-weight hardware security module
5
 *
6
 * Copyright (C) 2012 Andreas Schwier, CardContact, Minden, Germany, and others
7
 * Copyright (C) 2018-2019 GSMK - Gesellschaft für Sichere Mobile Kommunikation mbH
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
#ifdef HAVE_CONFIG_H
25
#include "config.h"
26
#endif
27
28
#include <string.h>
29
#include <stdlib.h>
30
#include <ctype.h>
31
32
#include "internal.h"
33
#include "asn1.h"
34
#include "cardctl.h"
35
#include "types.h"
36
37
#include "card-sc-hsm.h"
38
39
#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE)
40
#include "sm/sm-eac.h"
41
#include <eac/ca.h>
42
#include <eac/cv_cert.h>
43
#include <eac/eac.h>
44
#include <eac/ta.h>
45
#include <openssl/evp.h>
46
#endif
47
48
49
/* Static reference to ISO driver */
50
static const struct sc_card_operations *iso_ops = NULL;
51
52
/* Our operations */
53
static struct sc_card_operations sc_hsm_ops;
54
55
/* Our driver description */
56
static struct sc_card_driver sc_hsm_drv = {
57
  "SmartCard-HSM",
58
  "sc-hsm",
59
  &sc_hsm_ops,
60
  NULL,
61
  0,
62
  NULL
63
};
64
65
66
67
/* Our AID */
68
struct sc_aid sc_hsm_aid = { { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02,0x01 }, 11 };
69
70
71
72
/* Known ATRs for SmartCard-HSMs */
73
const struct sc_atr_table sc_hsm_atrs[] = {
74
  /* standard version */
75
  {"3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
76
  {"3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
77
  {"3B:DE:18:FF:81:91:FE:1F:C3:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:1C", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
78
  {"3B:DE:96:FF:81:91:FE:1F:C3:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:92", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
79
80
  {"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL}, // SoC Sample Card
81
  {
82
    "3B:84:80:01:47:6f:49:44:00",
83
    "FF:FF:FF:FF:FF:FF:FF:FF:00",
84
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
85
  },
86
  {
87
    "3B:85:80:01:47:6f:49:44:00:00",
88
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00",
89
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
90
  },
91
  {
92
    "3B:86:80:01:47:6f:49:44:00:00:00",
93
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00",
94
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
95
  },
96
  {
97
    "3B:87:80:01:47:6f:49:44:00:00:00:00",
98
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00",
99
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
100
  },
101
  {
102
    "3B:88:80:01:47:6f:49:44:00:00:00:00:00",
103
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00",
104
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
105
  },
106
  {
107
    "3B:89:80:01:47:6f:49:44:00:00:00:00:00:00",
108
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00",
109
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
110
  },
111
  {
112
    "3B:8a:80:01:47:6f:49:44:00:00:00:00:00:00:00",
113
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00",
114
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
115
  },
116
  {
117
    "3B:8b:80:01:47:6f:49:44:00:00:00:00:00:00:00:00",
118
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00",
119
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
120
  },
121
  {
122
    "3B:8c:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00",
123
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00",
124
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
125
  },
126
  {
127
    "3B:8d:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00",
128
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00",
129
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
130
  },
131
  {
132
    "3B:8e:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00",
133
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00",
134
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
135
  },
136
  {
137
    "3B:8f:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00",
138
    "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00",
139
    "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
140
  },
141
  {NULL, NULL, NULL, 0, 0, NULL}
142
};
143
144
145
146
static int sc_hsm_select_file_ex(sc_card_t *card,
147
             const sc_path_t *in_path, int forceselect,
148
             sc_file_t **file_out)
149
10.1k
{
150
10.1k
  int rv;
151
10.1k
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
152
10.1k
  sc_file_t *file = NULL;
153
10.1k
  sc_path_t cpath;
154
10.1k
  size_t card_max_recv_size = card->max_recv_size;
155
10.1k
  size_t reader_max_recv_size = card->reader->max_recv_size;
156
157
10.1k
  if (file_out == NULL) {       // Versions before 0.16 of the SmartCard-HSM do not support P2='0C'
158
1.34k
    rv = sc_hsm_select_file_ex(card, in_path, forceselect, &file);
159
1.34k
    sc_file_free(file);
160
1.34k
    return rv;
161
1.34k
  }
162
163
8.78k
  if ((in_path->type == SC_PATH_TYPE_FILE_ID) && in_path->aid.len) {
164
    // Split applet selection and file selection into two separate calls
165
0
    cpath = *in_path;
166
0
    cpath.len = 0;
167
0
    cpath.type = SC_PATH_TYPE_DF_NAME;
168
0
    rv = sc_hsm_select_file_ex(card, &cpath, forceselect, NULL);
169
0
    LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
170
171
0
    if (in_path->len) {
172
0
      cpath = *in_path;
173
0
      cpath.aid.len = 0;
174
0
      rv = sc_hsm_select_file_ex(card, &cpath, forceselect, file_out);
175
0
    }
176
0
    return rv;
177
0
  }
178
179
  // Prevent selection of applet unless this is the first time, selection is forced or the device is not authenticated
180
8.78k
  if (in_path->type == SC_PATH_TYPE_DF_NAME
181
1.45k
      || (in_path->type == SC_PATH_TYPE_PATH
182
1.35k
        && in_path->len == sc_hsm_aid.len
183
0
        && !memcmp(in_path->value, sc_hsm_aid.value, sc_hsm_aid.len))
184
1.45k
      || (in_path->type == SC_PATH_TYPE_PATH
185
1.35k
        && in_path->len == 0
186
0
        && in_path->aid.len == sc_hsm_aid.len
187
7.32k
        && !memcmp(in_path->aid.value, sc_hsm_aid.value, sc_hsm_aid.len))) {
188
7.32k
    if (!priv || (priv->dffcp == NULL) || forceselect) {
189
      /* Force use of Le = 0x00 in iso7816_select_file as required by SC-HSM */
190
7.03k
      card->max_recv_size = card->reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
191
7.03k
      rv = (*iso_ops->select_file)(card, in_path, file_out);
192
7.03k
      card->max_recv_size = card_max_recv_size;
193
7.03k
      card->reader->max_recv_size = reader_max_recv_size;
194
7.03k
      LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
195
196
591
      if (priv) {
197
244
        sc_file_free(priv->dffcp);
198
        // Cache the FCP returned when selecting the applet
199
244
        sc_file_dup(&priv->dffcp, *file_out);
200
244
      }
201
591
    } else {
202
297
      sc_file_dup(file_out, priv->dffcp);
203
297
      rv = SC_SUCCESS;
204
297
    }
205
888
    return rv;
206
7.32k
  }
207
208
1.45k
  if ((in_path->len >= 2) && (in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) {
209
    // The SmartCard-HSM is an applet that is not default selected. Simulate selection of the MF
210
827
    if (in_path->len == 2) {
211
1
      file = sc_file_new();
212
1
      if (file == NULL)
213
1
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
214
1
      file->path = *in_path;
215
1
      file->id = 0x3F00;
216
1
      file->type = SC_FILE_TYPE_DF;
217
1
      file->magic = SC_FILE_MAGIC;
218
219
1
      *file_out = file;
220
1
      return SC_SUCCESS;
221
826
    } else {
222
      /* Force use of Le = 0x00 in iso7816_select_file as required by SC-HSM */
223
826
      card->max_recv_size = card->reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
224
826
      sc_path_t truncated;
225
826
      memcpy(&truncated, in_path, sizeof truncated);
226
826
      truncated.len = in_path->len - 2;
227
826
      memcpy(truncated.value, in_path->value+2, truncated.len);
228
826
      rv = (*iso_ops->select_file)(card, &truncated, file_out);
229
826
      card->max_recv_size = card_max_recv_size;
230
826
      card->reader->max_recv_size = reader_max_recv_size;
231
826
      return rv;
232
826
    }
233
827
  }
234
  /* Force use of Le = 0x00 in iso7816_select_file as required by SC-HSM */
235
628
  card->max_recv_size = card->reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
236
628
  rv = (*iso_ops->select_file)(card, in_path, file_out);
237
628
  card->max_recv_size = card_max_recv_size;
238
628
  card->reader->max_recv_size = reader_max_recv_size;
239
628
  return rv;
240
1.45k
}
241
242
243
244
static int sc_hsm_select_file(sc_card_t *card,
245
             const sc_path_t *in_path,
246
             sc_file_t **file_out)
247
8.50k
{
248
8.50k
  return sc_hsm_select_file_ex(card, in_path, 0, file_out);
249
8.50k
}
250
251
252
253
static int sc_hsm_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len)
254
0
{
255
0
  LOG_FUNC_CALLED(card->ctx);
256
257
0
  if (len > 1024) {
258
0
    len = 1024;
259
0
  }
260
261
0
  LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len));
262
0
}
263
264
265
266
static int sc_hsm_match_card(struct sc_card *card)
267
6.40k
{
268
6.40k
  sc_path_t path;
269
6.40k
  int i, r, type = 0;
270
6.40k
  sc_file_t *file = NULL;
271
272
6.40k
  i = _sc_match_atr(card, sc_hsm_atrs, &type);
273
6.40k
  if (i >= 0 && type != SC_CARD_TYPE_SC_HSM_SOC) {
274
277
    card->type = type;
275
277
    return 1;
276
277
  }
277
278
6.13k
  sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
279
6.13k
  r = sc_hsm_select_file(card, &path, &file);
280
6.13k
  LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");
281
282
  // Validate that card returns a FCP with a proprietary tag 85 with value longer than 2 byte (Fixes #1377)
283
347
  if (file != NULL) {
284
347
    size_t sz = file->prop_attr_len;
285
347
    sc_file_free(file);
286
347
    if (sz < 2) {
287
345
      return 0;
288
345
    }
289
347
  }
290
291
2
  if (type == SC_CARD_TYPE_SC_HSM_SOC) {
292
0
    card->type = SC_CARD_TYPE_SC_HSM_SOC;
293
2
  } else {
294
2
    card->type = SC_CARD_TYPE_SC_HSM;
295
2
  }
296
297
2
  return 1;
298
347
}
299
300
301
302
/*
303
 * Encode 16 hexadecimals of SO-PIN into binary form
304
 * Caller must check length of sopin and provide an 8 byte buffer
305
 */
306
static int sc_hsm_encode_sopin(const u8 *sopin, u8 *sopinbin)
307
0
{
308
0
  int i;
309
0
  unsigned char digit;
310
311
0
  memset(sopinbin, 0, 8);
312
0
  for (i = 0; i < 16; i++) {
313
0
    *sopinbin <<= 4;
314
0
    digit = *sopin++;
315
316
0
    if (!isxdigit(digit))
317
0
      return SC_ERROR_PIN_CODE_INCORRECT;
318
0
    digit = toupper(digit);
319
320
0
    if (digit >= 'A')
321
0
      digit = digit - 'A' + 10;
322
0
    else
323
0
      digit = digit & 0xF;
324
325
0
    *sopinbin |= digit & 0xf;
326
0
    if (i & 1)
327
0
      sopinbin++;
328
0
  }
329
0
  return SC_SUCCESS;
330
0
}
331
332
333
static int sc_hsm_soc_select_minbioclient(sc_card_t *card)
334
0
{
335
0
  static const struct sc_aid minBioClient_aid = {
336
0
      {0xFF, 'm', 'i', 'n', 'B', 'i', 'o', 'C', 'l', 'i', 'e', 'n', 't', 0x01},
337
0
      14
338
0
    };
339
340
  /* Select MinBioClient */
341
0
#ifdef ENABLE_SM
342
0
  sc_sm_stop(card);
343
0
#endif
344
0
  return iso7816_select_aid(card, minBioClient_aid.value, minBioClient_aid.len, NULL, NULL);
345
0
}
346
347
static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data)
348
0
{
349
0
  sc_apdu_t apdu;
350
0
  sc_path_t path;
351
0
  int r;
352
353
0
  if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
354
    /* Select MinBioClient */
355
0
    r = sc_hsm_soc_select_minbioclient(card);
356
0
    LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
357
358
    /* verify PIN */
359
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80);
360
0
    r = sc_transmit_apdu(card, &apdu);
361
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
362
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
363
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN");
364
365
    /* change PIN */
366
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80);
367
0
    r = sc_transmit_apdu(card, &apdu);
368
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
369
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
370
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
371
0
  } else {
372
0
#ifdef ENABLE_SM
373
0
    unsigned sm_mode = card->sm_ctx.sm_mode;
374
0
#endif
375
376
    /* verify PIN */
377
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x85);
378
0
    apdu.cla = 0x80;
379
0
    r = sc_transmit_apdu(card, &apdu);
380
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
381
382
0
#ifdef ENABLE_SM
383
    /* temporary disable SM, change reference data does not reach the applet */
384
0
    card->sm_ctx.sm_mode = SM_MODE_NONE;
385
0
#endif
386
387
    /* change PIN */
388
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x85);
389
0
    apdu.cla = 0x80;
390
0
    r = sc_transmit_apdu(card, &apdu);
391
0
#ifdef ENABLE_SM
392
    /* restore SM if possible */
393
0
    card->sm_ctx.sm_mode = sm_mode;
394
0
#endif
395
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
396
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
397
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
398
0
  }
399
400
0
err:
401
0
  if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
402
    /* Select SC-HSM */
403
0
    sc_path_set(&path, SC_PATH_TYPE_DF_NAME,
404
0
          sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
405
0
    LOG_TEST_RET(card->ctx,
406
0
        sc_hsm_select_file_ex(card, &path, 1, NULL),
407
0
        "Could not select SmartCard-HSM application");
408
0
  }
409
410
0
  return r;
411
0
}
412
413
static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data)
414
0
{
415
0
  sc_apdu_t apdu;
416
0
  sc_path_t path;
417
0
  int r;
418
419
0
  if (card->type == SC_CARD_TYPE_SC_HSM_GOID) {
420
0
    return SC_ERROR_NOT_SUPPORTED;
421
0
  }
422
423
  /* Select MinBioClient */
424
0
  r = sc_hsm_soc_select_minbioclient(card);
425
0
  LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
426
427
  /* verify PUK */
428
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x81);
429
0
  r = sc_transmit_apdu(card, &apdu);
430
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
431
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
432
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PUK");
433
434
  /* reset retry counter */
435
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2c, 0x03, 0x00);
436
0
  r = sc_transmit_apdu(card, &apdu);
437
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
438
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
439
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "Could not unblock PIN");
440
441
0
err:
442
  /* Select SC-HSM */
443
0
  sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
444
0
  LOG_TEST_RET(card->ctx,
445
0
      sc_hsm_select_file_ex(card, &path, 1, NULL),
446
0
      "Could not select SmartCard-HSM application");
447
448
0
  return r;
449
0
}
450
451
static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data)
452
0
{
453
0
  sc_apdu_t apdu;
454
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
455
0
  int r;
456
457
0
  if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
458
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85);
459
0
    apdu.cla = 0x80;
460
0
    apdu.data = (unsigned char*)"\x7F\x24\x00";
461
0
    apdu.datalen = 3;
462
0
    apdu.lc = 3;
463
0
    apdu.resplen = 0;
464
465
0
    r = sc_transmit_apdu(card, &apdu);
466
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
467
    /* ignore the actual status bytes */
468
0
  }
469
470
  /* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
471
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, 0x81);
472
0
  if (card->type == SC_CARD_TYPE_SC_HSM_GOID) {
473
0
    apdu.cla = 0x80;
474
0
  }
475
0
  apdu.resp = rbuf;
476
0
  apdu.resplen = sizeof rbuf;
477
0
  r = sc_transmit_apdu(card, &apdu);
478
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
479
480
  /* now check the status bytes */
481
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
482
0
  if (r == SC_SUCCESS) {
483
0
    LOG_FUNC_RETURN(card->ctx, r);
484
0
  }
485
486
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
487
0
}
488
489
#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE)
490
491
static int sc_hsm_perform_chip_authentication(sc_card_t *card)
492
33
{
493
33
  int r, protocol;
494
33
  sc_path_t path;
495
33
  u8 all_certs[1024];
496
33
  EAC_CTX *ctx = NULL;
497
33
  size_t all_certs_len = sizeof all_certs, left, device_cert_len, issuer_cert_len;
498
33
  const unsigned char *cert = all_certs, *device_cert, *issuer_cert;
499
33
  BUF_MEM *comp_pub_key = NULL;
500
33
  sc_cvc_t cvc_device, cvc_issuer;
501
  /* this is only needed to call sc_pkcs15emu_sc_hsm_decode_cvc */
502
33
  sc_pkcs15_card_t p15card;
503
33
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
504
  /* we know that sc_pkcs15emu_sc_hsm_decode_cvc does not require anything
505
   * else to be initialized than p15card->card */
506
33
  p15card.card = card;
507
508
33
  memset(&cvc_device, 0, sizeof(cvc_device));
509
33
  memset(&cvc_issuer, 0, sizeof(cvc_issuer));
510
511
512
33
  if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) {
513
5
    all_certs_len = priv->EF_C_DevAut_len;
514
5
    cert = priv->EF_C_DevAut;
515
28
  } else {
516
    /* get issuer and device certificate from the card */
517
28
    r = sc_path_set(&path, SC_PATH_TYPE_FILE_ID, (u8 *) "\x2F\x02", 2, 0, 0);
518
28
    if (r < 0)
519
0
      goto err;
520
28
    r = sc_select_file(card, &path, NULL);
521
28
    if (r < 0)
522
14
      goto err;
523
14
    r = sc_read_binary(card, 0, all_certs, all_certs_len, 0);
524
14
    if (r < 0)
525
5
      goto err;
526
9
    if (r == 0) {
527
3
      r = SC_ERROR_FILE_NOT_FOUND;
528
3
      goto err;
529
3
    }
530
531
6
    all_certs_len = r;
532
533
    /* save EF_C_DevAut for further use */
534
6
    cert = realloc(priv->EF_C_DevAut, all_certs_len);
535
6
    if (cert) {
536
6
      memcpy((unsigned char *) cert, all_certs, all_certs_len);
537
6
      priv->EF_C_DevAut = (unsigned char *) cert;
538
6
      priv->EF_C_DevAut_len = all_certs_len;
539
6
    }
540
541
6
    cert = all_certs;
542
6
  }
543
11
  left = all_certs_len;
544
545
11
  device_cert = cert;
546
11
  r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_device);
547
11
  if (r < 0)
548
11
    goto err;
549
0
  device_cert_len = all_certs_len - left;
550
551
0
  issuer_cert = cert;
552
0
  r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_issuer);
553
0
  if (r < 0)
554
0
    goto err;
555
0
  issuer_cert_len = all_certs_len - device_cert_len - left;
556
557
0
  ctx = EAC_CTX_new();
558
0
  if (!ctx) {
559
0
    r = SC_ERROR_INTERNAL;
560
0
    goto err;
561
0
  }
562
563
  /* FIXME set flags with opensc.conf */
564
0
  TA_disable_checks(ctx);
565
0
  CA_disable_passive_authentication(ctx);
566
567
  /* check all CVCs given of the document's pki */
568
0
  if (!TA_STEP2_import_certificate(ctx, issuer_cert, issuer_cert_len)
569
0
      || !TA_STEP2_import_certificate(ctx, device_cert, device_cert_len)) {
570
0
    r = SC_ERROR_INTERNAL;
571
0
    goto err;
572
0
  }
573
574
  /* XXX on older JCOPs only NID_id_CA_ECDH_3DES_CBC_CBC may be
575
   * supported. The card does not export its capabilities. We hardcode
576
   * NID_id_CA_ECDH_AES_CBC_CMAC_128 here, because we don't have the older
577
   * cards in production. */
578
0
  protocol = NID_id_CA_ECDH_AES_CBC_CMAC_128;
579
580
  /* initialize CA domain parameter with the document's public key */
581
0
  if (!EAC_CTX_init_ca(ctx, protocol, 8)) {
582
0
    r = SC_ERROR_INTERNAL;
583
0
    goto err;
584
0
  }
585
0
  EVP_PKEY_free(ctx->ca_ctx->ka_ctx->key);
586
0
  if (!EVP_PKEY_up_ref(ctx->ta_ctx->pub_key)) {
587
0
    sc_log_openssl(card->ctx);
588
0
    r = SC_ERROR_INTERNAL;
589
0
    goto err;
590
0
  }
591
0
  ctx->ca_ctx->ka_ctx->key = ctx->ta_ctx->pub_key;
592
593
  /* generate keys for CA */
594
0
  comp_pub_key = TA_STEP3_generate_ephemeral_key(ctx);
595
0
  r = perform_chip_authentication_ex(card, ctx,
596
0
      cvc_device.publicPoint, cvc_device.publicPointlen);
597
598
33
err:
599
33
  if (r < 0)
600
33
    EAC_CTX_clear_free(ctx);
601
33
  if (comp_pub_key)
602
0
    BUF_MEM_free(comp_pub_key);
603
33
  sc_pkcs15emu_sc_hsm_free_cvc(&cvc_device);
604
33
  sc_pkcs15emu_sc_hsm_free_cvc(&cvc_issuer);
605
606
33
  return r;
607
0
}
608
609
#else
610
611
static int sc_hsm_perform_chip_authentication(sc_card_t *card)
612
{
613
  return SC_ERROR_NOT_SUPPORTED;
614
}
615
#endif
616
617
618
619
static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data)
620
525
{
621
525
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
622
525
  sc_apdu_t apdu;
623
525
  u8 cmdbuff[16];
624
525
#ifdef ENABLE_SM
625
525
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
626
525
#endif
627
525
  int r;
628
525
  int cmd = data->cmd;
629
525
  size_t pin2_len = data->pin2.len;
630
631
525
  if (cmd == SC_PIN_CMD_GET_SESSION_PIN) {
632
    /* First, perform a standard VERIFY */
633
0
    data->cmd = SC_PIN_CMD_VERIFY;
634
    /* we assign pin2.len to 0 early on so that in case of an error we are
635
     * not exiting with an undefined session PIN */
636
0
    data->pin2.len = 0;
637
0
  }
638
639
525
  if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
640
0
        && (data->cmd == SC_PIN_CMD_CHANGE)
641
0
        && (data->pin_reference == 0x81)
642
0
      && (!data->pin1.data || data->pin1.len <= 0)) {
643
0
    return sc_hsm_soc_change(card, data);
644
525
  } else if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
645
0
        && (data->cmd == SC_PIN_CMD_UNBLOCK)
646
0
        && (data->pin_reference == 0x81)
647
0
      && (!data->pin1.data || data->pin1.len <= 0)) {
648
0
    return sc_hsm_soc_unblock(card, data);
649
0
  }
650
651
525
#ifdef ENABLE_SM
652
  /* For contactless cards always establish a secure channel before PIN
653
   * verification. Also, Session PIN generation requires SM. */
654
525
  if ((card->type == SC_CARD_TYPE_SC_HSM_SOC
655
525
        || card->type == SC_CARD_TYPE_SC_HSM_GOID
656
0
        || card->reader->uid.len || cmd == SC_PIN_CMD_GET_SESSION_PIN)
657
525
      && (data->cmd != SC_PIN_CMD_GET_INFO)) {
658
33
    struct sc_pin_cmd_data check_sm_pin_data;
659
33
    memset(&check_sm_pin_data, 0, sizeof(check_sm_pin_data));
660
33
    check_sm_pin_data.cmd = SC_PIN_CMD_GET_INFO;
661
33
    check_sm_pin_data.pin_type = data->pin_type;
662
33
    check_sm_pin_data.pin_reference = data->pin_reference;
663
664
33
    r = SC_ERROR_NOT_ALLOWED;
665
33
    if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) {
666
      /* check if the existing SM channel is still valid */
667
0
      r = sc_pin_cmd(card, &check_sm_pin_data);
668
0
    }
669
33
    if (r == SC_ERROR_ASN1_OBJECT_NOT_FOUND || r == SC_ERROR_NOT_ALLOWED) {
670
      /* need to establish a new SM channel */
671
33
      LOG_TEST_RET(card->ctx,
672
33
          sc_hsm_perform_chip_authentication(card),
673
33
          "Could not perform chip authentication");
674
33
    }
675
33
  }
676
492
#endif
677
678
492
  if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
679
0
      && (data->cmd == SC_PIN_CMD_VERIFY)
680
0
      && (data->pin_reference == 0x81)
681
0
      && (!data->pin1.data || data->pin1.len <= 0)) {
682
0
    r = sc_hsm_soc_biomatch(card, data);
683
492
  } else {
684
492
    if ((data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x88)) {
685
0
      if (data->pin1.len != 16)
686
0
        return SC_ERROR_INVALID_PIN_LENGTH;
687
688
      // Save SO PIN for later use in sc_hsm_init_pin()
689
0
      r = sc_hsm_encode_sopin(data->pin1.data, priv->sopin);
690
0
      LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
691
692
0
      LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
693
0
    }
694
695
492
    if ((data->cmd == SC_PIN_CMD_CHANGE) && (data->pin_reference == 0x88)) {
696
0
      if ((data->pin1.len != 16) || (data->pin2.len != 16))
697
0
        return SC_ERROR_INVALID_PIN_LENGTH;
698
699
0
      r = sc_hsm_encode_sopin(data->pin1.data, cmdbuff);
700
0
      LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
701
702
0
      r = sc_hsm_encode_sopin(data->pin2.data, cmdbuff + 8);
703
0
      LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
704
705
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, data->pin_reference);
706
0
      apdu.data = cmdbuff;
707
0
      apdu.datalen = sizeof(cmdbuff);
708
0
      apdu.lc = 16;
709
0
      apdu.resplen = 0;
710
0
      data->apdu = &apdu;
711
0
    }
712
713
492
#ifdef ENABLE_SM
714
492
    if ((data->cmd == SC_PIN_CMD_GET_INFO)
715
492
        && (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT)) {
716
      /* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
717
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, data->pin_reference);
718
0
      apdu.resp = rbuf;
719
0
      apdu.resplen = sizeof rbuf;
720
0
      data->apdu = &apdu;
721
0
    }
722
492
#endif
723
724
492
    data->pin1.offset = 5;
725
492
    data->pin2.offset = 5;
726
727
492
    r = (*iso_ops->pin_cmd)(card, data);
728
492
    data->apdu = NULL;
729
492
  }
730
492
  LOG_TEST_RET(card->ctx, r, "Verification failed");
731
732
175
  if (cmd == SC_PIN_CMD_GET_SESSION_PIN) {
733
    /* reset data->cmd to its original value */
734
0
    data->cmd = SC_PIN_CMD_GET_SESSION_PIN;
735
0
    if (data->pin_reference == 0x81) {
736
0
      u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
737
0
#ifdef ENABLE_SM
738
0
      if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) {
739
0
        sc_log(card->ctx,
740
0
            "Session PIN generation only supported in SM");
741
0
        LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
742
0
      }
743
#else
744
      sc_log(card->ctx,
745
          "Session PIN generation only supported in SM");
746
      LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
747
#endif
748
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x5A, 0x01, data->pin_reference);
749
0
      apdu.cla = 0x80;
750
0
      apdu.resp = recvbuf;
751
0
      apdu.resplen = sizeof recvbuf;
752
0
      apdu.le = 0;
753
0
      if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS
754
0
          || sc_check_sw(card, apdu.sw1, apdu.sw2) != SC_SUCCESS) {
755
0
        sc_log(card->ctx,
756
0
            "Generating session PIN failed");
757
0
        LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
758
0
      }
759
0
      if (data->pin2.data && pin2_len > 0) {
760
0
        if (pin2_len >= apdu.resplen) {
761
0
          memcpy((unsigned char *) data->pin2.data, apdu.resp,
762
0
              apdu.resplen);
763
0
          data->pin2.len = apdu.resplen;
764
0
        } else {
765
0
          sc_log(card->ctx,
766
0
              "Buffer too small for session PIN");
767
0
        }
768
0
      }
769
0
    } else {
770
0
      sc_log(card->ctx,
771
0
          "Session PIN not supported for this PIN (0x%02X)",
772
0
          data->pin_reference);
773
0
    }
774
0
  }
775
175
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
776
175
}
777
778
779
780
static int sc_hsm_logout(sc_card_t * card)
781
0
{
782
0
  sc_path_t path;
783
0
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
784
0
  memset(priv->sopin, 0, sizeof(priv->sopin));
785
0
#ifdef ENABLE_SM
786
0
  sc_sm_stop(card);
787
0
#endif
788
789
0
  sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
790
791
0
  return sc_hsm_select_file_ex(card, &path, 1, NULL);
792
0
}
793
794
795
/* NOTE: idx is an offset into the card's file, not into buf */
796
static int sc_hsm_read_binary(sc_card_t *card,
797
             unsigned int idx, u8 *buf, size_t count,
798
             unsigned long *flags)
799
666
{
800
666
  sc_context_t *ctx = card->ctx;
801
666
  sc_apdu_t apdu;
802
666
  u8 cmdbuff[4];
803
666
  int r;
804
805
666
  if (idx > 0xffff) {
806
0
    sc_log(ctx,  "invalid EF offset: 0x%X > 0xFFFF", idx);
807
0
    return SC_ERROR_OFFSET_TOO_LARGE;
808
0
  }
809
810
666
  cmdbuff[0] = 0x54;
811
666
  cmdbuff[1] = 0x02;
812
666
  cmdbuff[2] = (idx >> 8) & 0xFF;
813
666
  cmdbuff[3] = idx & 0xFF;
814
815
666
  if (count > sc_get_max_recv_size(card))
816
0
    return SC_ERROR_INTERNAL;
817
666
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB1, 0x00, 0x00);
818
666
  apdu.data = cmdbuff;
819
666
  apdu.datalen = 4;
820
666
  apdu.lc = 4;
821
666
  apdu.le = count;
822
666
  apdu.resplen = count;
823
666
  apdu.resp = buf;
824
825
666
  r = sc_transmit_apdu(card, &apdu);
826
666
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
827
828
661
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
829
661
  if (r != SC_ERROR_FILE_END_REACHED) {
830
582
    LOG_TEST_RET(ctx, r, "Check SW error");
831
582
  }
832
833
584
  LOG_FUNC_RETURN(ctx, (int)apdu.resplen);
834
584
}
835
836
837
/* NOTE: idx is an offset into the card's file, not into buf */
838
static int sc_hsm_write_ef(sc_card_t *card,
839
             int fid,
840
             unsigned int idx, const u8 *buf, size_t count)
841
0
{
842
0
  sc_context_t *ctx = card->ctx;
843
0
  sc_apdu_t apdu;
844
0
  u8 *cmdbuff, *p;
845
0
  size_t len;
846
0
  int r;
847
848
0
  if (idx > 0xffff) {
849
0
    sc_log(ctx,  "invalid EF offset: 0x%X > 0xFFFF", idx);
850
0
    return SC_ERROR_OFFSET_TOO_LARGE;
851
0
  }
852
853
0
  cmdbuff = malloc(8 + count);
854
0
  if (!cmdbuff) {
855
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
856
0
  }
857
858
0
  size_t bytes_left = count;
859
  // 8 bytes are required for T54(4) and T53(4)
860
0
  size_t blk_size = card->max_send_size - 8;
861
0
  size_t to_send = 0;
862
0
  size_t file_offset = (size_t) idx;
863
0
  size_t offset = 0;
864
0
  do {
865
0
    to_send = bytes_left >= blk_size ? blk_size : bytes_left;
866
0
    p = cmdbuff;
867
    // ASN1 0x54 offset
868
0
    *p++ = 0x54;
869
0
    *p++ = 0x02;
870
0
    *p++ = (file_offset >> 8) & 0xFF;
871
0
    *p++ = file_offset & 0xFF;
872
    // ASN1 0x53 to_send
873
0
    *p++ = 0x53;
874
0
    if (to_send < 128) {
875
0
      *p++ = (u8)to_send;
876
0
      len = 6;
877
0
    } else if (to_send < 256) {
878
0
      *p++ = 0x81;
879
0
      *p++ = (u8)to_send;
880
0
      len = 7;
881
0
    } else {
882
0
      *p++ = 0x82;
883
0
      *p++ = (to_send >> 8) & 0xFF;
884
0
      *p++ = to_send & 0xFF;
885
0
      len = 8;
886
0
    }
887
888
0
    if (buf != NULL)
889
0
      memcpy(p, buf+offset, to_send);
890
0
    len += to_send;
891
892
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF);
893
0
    apdu.data = cmdbuff;
894
0
    apdu.datalen = len;
895
0
    apdu.lc = len;
896
897
0
    r = sc_transmit_apdu(card, &apdu);
898
0
    LOG_TEST_GOTO_ERR(ctx, r, "APDU transmit failed");
899
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
900
0
    LOG_TEST_GOTO_ERR(ctx, r, "Check SW error");
901
902
0
    bytes_left -= to_send;
903
0
    offset += to_send;
904
0
    file_offset += to_send;
905
0
  } while (0 < bytes_left);
906
907
0
err:
908
0
  free(cmdbuff);
909
910
0
  LOG_FUNC_RETURN(ctx, (int)count);
911
0
}
912
913
914
static int sc_hsm_update_binary(sc_card_t *card,
915
             unsigned int idx, const u8 *buf, size_t count,
916
             unsigned long flags)
917
0
{
918
0
  return sc_hsm_write_ef(card, 0, idx, buf, count);
919
0
}
920
921
922
923
static int sc_hsm_list_files(sc_card_t *card, u8 * buf, size_t buflen)
924
0
{
925
0
  sc_apdu_t apdu;
926
0
  u8 recvbuf[MAX_EXT_APDU_LENGTH];
927
0
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
928
0
  int r;
929
930
0
  if (priv->noExtLength) {
931
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x58, 0, 0);
932
0
  } else {
933
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, 0x58, 0, 0);
934
0
  }
935
0
  apdu.cla = 0x80;
936
0
  apdu.resp = recvbuf;
937
0
  apdu.resplen = sizeof(recvbuf);
938
0
  apdu.le = 0;
939
0
  r = sc_transmit_apdu(card, &apdu);
940
941
0
  if ((r == SC_ERROR_TRANSMIT_FAILED) && (!priv->noExtLength)) {
942
0
    sc_log(card->ctx, "No extended length support ? Trying fall-back to short APDUs, probably breaking support for RSA 2048 operations");
943
0
    priv->noExtLength = 1;
944
0
    card->max_send_size = 248;    // 255 - 7 because of TLV in odd ins UPDATE BINARY
945
0
    return sc_hsm_list_files(card, buf, buflen);
946
0
  }
947
0
  LOG_TEST_RET(card->ctx, r, "ENUMERATE OBJECTS APDU transmit failed");
948
949
0
  if (buflen < apdu.resplen)
950
0
    memcpy(buf, recvbuf, buflen);
951
0
  else
952
0
    memcpy(buf, recvbuf, apdu.resplen);
953
954
0
  LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
955
0
}
956
957
958
959
static int sc_hsm_create_file(sc_card_t *card, sc_file_t *file)
960
0
{
961
0
  int r;
962
963
0
  r = sc_hsm_write_ef(card, file->id, 0, NULL, 0);
964
0
  LOG_TEST_RET(card->ctx, r, "Create file failed");
965
966
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
967
0
}
968
969
970
971
static int sc_hsm_delete_file(sc_card_t *card, const sc_path_t *path)
972
0
{
973
0
  sc_context_t *ctx = card->ctx;
974
0
  sc_apdu_t apdu;
975
0
  u8 sbuf[2];
976
0
  int r;
977
978
0
  if ((path->type != SC_PATH_TYPE_FILE_ID) || (path->len != 2)) {
979
0
    sc_log(card->ctx,  "File type has to be SC_PATH_TYPE_FILE_ID");
980
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
981
0
  }
982
983
0
  sbuf[0] = path->value[0];
984
0
  sbuf[1] = path->value[1];
985
986
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x02, 0x00);
987
0
  apdu.data = sbuf;
988
0
  apdu.datalen = sizeof(sbuf);
989
0
  apdu.lc = sizeof(sbuf);
990
991
0
  r = sc_transmit_apdu(card, &apdu);
992
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
993
994
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
995
0
  LOG_TEST_RET(ctx, r, "Check SW error");
996
997
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
998
0
}
999
1000
1001
static int sc_hsm_set_security_env(sc_card_t *card,
1002
           const sc_security_env_t *env,
1003
           int se_num)
1004
1.72k
{
1005
1.72k
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1006
1007
1.72k
  priv->env = env;
1008
1009
1.72k
  switch(env->algorithm) {
1010
1.72k
  case SC_ALGORITHM_RSA:
1011
1.72k
    if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
1012
0
      if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) {
1013
0
        priv->algorithm = ALGO_RSA_PKCS1_SHA1;
1014
0
      } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
1015
0
        priv->algorithm = ALGO_RSA_PKCS1_SHA256;
1016
0
      } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) {
1017
0
        priv->algorithm = ALGO_RSA_PKCS1_SHA384;
1018
0
      } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA512) {
1019
0
        priv->algorithm = ALGO_RSA_PKCS1_SHA512;
1020
0
      } else {
1021
0
        priv->algorithm = ALGO_RSA_PKCS1;
1022
0
      }
1023
1.72k
    } else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) {
1024
745
      if ((env->algorithm_flags & SC_ALGORITHM_RSA_HASHES) &&
1025
0
          (((env->algorithm_flags & SC_ALGORITHM_MGF1_HASHES) >> 8) != (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES))) {
1026
0
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1027
0
      }
1028
745
      priv->algorithm = ALGO_RSA_PSS;
1029
979
    } else {
1030
979
      if (env->operation == SC_SEC_OPERATION_DECIPHER) {
1031
234
        priv->algorithm = ALGO_RSA_DECRYPT;
1032
745
      } else {
1033
745
        priv->algorithm = ALGO_RSA_RAW;
1034
745
      }
1035
979
    }
1036
1.72k
    break;
1037
1.72k
  case SC_ALGORITHM_EC:
1038
0
    if (env->operation == SC_SEC_OPERATION_DERIVE) {
1039
0
      priv->algorithm = ALGO_EC_DH;
1040
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_NONE) {
1041
0
      priv->algorithm = ALGO_EC_RAW;
1042
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
1043
0
      priv->algorithm = ALGO_EC_SHA1;
1044
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA224) {
1045
0
      priv->algorithm = ALGO_EC_SHA224;
1046
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) {
1047
0
      priv->algorithm = ALGO_EC_SHA256;
1048
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA384) {
1049
0
      priv->algorithm = ALGO_EC_SHA384;
1050
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA512) {
1051
0
      priv->algorithm = ALGO_EC_SHA512;
1052
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) {
1053
0
      priv->algorithm = ALGO_EC_RAW;
1054
0
    } else {
1055
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1056
0
    }
1057
0
    break;
1058
0
  default:
1059
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1060
0
    break;
1061
1.72k
  }
1062
1.72k
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1063
1.72k
}
1064
1065
1066
1067
static int sc_hsm_decode_ecdsa_signature(sc_card_t *card,
1068
          const u8 * data, size_t datalen,
1069
          u8 * out, size_t outlen,
1070
0
          size_t key_size) {
1071
1072
0
  int r;
1073
0
  size_t fieldsizebytes = (key_size + 7) >> 3;
1074
1075
0
  sc_log(card->ctx, "Field size %zu, signature buffer size %zu", fieldsizebytes, outlen);
1076
1077
0
  r = sc_asn1_decode_ecdsa_signature(card->ctx, data, datalen, fieldsizebytes, &out, outlen);
1078
0
  LOG_FUNC_RETURN(card->ctx, r);
1079
0
}
1080
1081
1082
1083
static int sc_hsm_compute_signature(sc_card_t *card,
1084
             const u8 * data, size_t datalen,
1085
             u8 * out, size_t outlen)
1086
1.49k
{
1087
1.49k
  int r;
1088
1.49k
  sc_apdu_t apdu;
1089
1.49k
  u8 rbuf[514];
1090
1.49k
  sc_hsm_private_data_t *priv;
1091
1092
1.49k
  if (card == NULL || data == NULL || out == NULL) {
1093
0
    return SC_ERROR_INVALID_ARGUMENTS;
1094
0
  }
1095
1.49k
  priv = (sc_hsm_private_data_t *) card->drv_data;
1096
1097
1.49k
  if (priv->env == NULL) {
1098
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND);
1099
0
  }
1100
1101
1.49k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x68, priv->env->key_ref[0], priv->algorithm);
1102
1.49k
  apdu.cla = 0x80;
1103
1.49k
  apdu.resp = rbuf;
1104
1.49k
  apdu.resplen = sizeof(rbuf);
1105
1.49k
  apdu.le = 512;
1106
1107
1.49k
  apdu.data = data;
1108
1.49k
  apdu.lc = datalen;
1109
1.49k
  apdu.datalen = datalen;
1110
1.49k
  r = sc_transmit_apdu(card, &apdu);
1111
1112
1.49k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1113
1.25k
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
1114
112
    int len;
1115
1116
112
    if ((priv->algorithm & 0xF0) == ALGO_EC_RAW) {
1117
0
      len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen, priv->env->key_size_bits);
1118
0
      if (len < 0) {
1119
0
        LOG_FUNC_RETURN(card->ctx, len);
1120
0
      }
1121
112
    } else {
1122
112
      len = (int)(apdu.resplen > outlen ? outlen : apdu.resplen);
1123
112
      memcpy(out, apdu.resp, len);
1124
112
    }
1125
112
    LOG_FUNC_RETURN(card->ctx, len);
1126
112
  }
1127
1.14k
  LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1128
1.14k
}
1129
1130
1131
1132
static int sc_hsm_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen)
1133
222
{
1134
222
  int r;
1135
222
  size_t len;
1136
222
  sc_apdu_t apdu;
1137
222
  u8 rbuf[514];
1138
222
  sc_hsm_private_data_t *priv;
1139
1140
222
  if (card == NULL || crgram == NULL || out == NULL) {
1141
0
    return SC_ERROR_INVALID_ARGUMENTS;
1142
0
  }
1143
222
  LOG_FUNC_CALLED(card->ctx);
1144
222
  priv = (sc_hsm_private_data_t *) card->drv_data;
1145
1146
222
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x62, priv->env->key_ref[0], priv->algorithm);
1147
222
  apdu.cla = 0x80;
1148
222
  apdu.resp = rbuf;
1149
222
  apdu.resplen = sizeof(rbuf);
1150
222
  apdu.le = 512;
1151
1152
222
  apdu.data = (u8 *)crgram;
1153
222
  apdu.lc = crgram_len;
1154
222
  apdu.datalen = crgram_len;
1155
1156
222
  r = sc_transmit_apdu(card, &apdu);
1157
1158
222
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1159
186
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
1160
51
    if (priv->algorithm == ALGO_EC_DH) {
1161
      //
1162
      // The SmartCard-HSM returns the point result of the DH operation
1163
      // with a leading '04'
1164
0
      if (apdu.resplen <= 0)
1165
0
        return SC_ERROR_INTERNAL;
1166
0
      len = apdu.resplen - 1 > outlen ? outlen : apdu.resplen - 1;
1167
0
      memcpy(out, apdu.resp + 1, len);
1168
0
      LOG_FUNC_RETURN(card->ctx, (int)len);
1169
51
    } else {
1170
51
      len = apdu.resplen > outlen ? outlen : apdu.resplen;
1171
51
      memcpy(out, apdu.resp, len);
1172
51
      LOG_FUNC_RETURN(card->ctx, (int)len);
1173
51
    }
1174
51
  }
1175
135
  else
1176
186
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1177
186
}
1178
1179
1180
1181
void sc_hsm_set_serialnr(sc_card_t *card, char *serial)
1182
0
{
1183
0
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1184
1185
0
  if (priv->serialno) {
1186
0
    free(priv->serialno);
1187
0
  }
1188
1189
0
  priv->serialno = strdup(serial);
1190
0
}
1191
1192
1193
1194
static int sc_hsm_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
1195
168
{
1196
168
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1197
1198
168
  LOG_FUNC_CALLED(card->ctx);
1199
1200
168
  if (!priv->serialno && 0 == strcmp(card->ctx->app_name, "opensc-tool")) {
1201
    /* sc-hsm initializes the serial number via its PKCS#15 layer.
1202
     * Create and destroy a dummy card to get this initialized.  Only do
1203
     * this for `opensc-tool --serial` to avoid unnecessary card commands
1204
     * in all other cases. */
1205
0
    sc_pkcs15_card_t *p15card = NULL;
1206
0
    (void)sc_pkcs15_bind(card, NULL, &p15card);
1207
0
    sc_pkcs15_unbind(p15card);
1208
0
  }
1209
1210
168
  if (!priv->serialno) {
1211
168
    return SC_ERROR_OBJECT_NOT_FOUND;
1212
168
  }
1213
1214
0
  serial->len = strlen(priv->serialno);
1215
0
  if (serial->len > sizeof(serial->value))
1216
0
    serial->len = sizeof(serial->value);
1217
1218
0
  memcpy(serial->value, priv->serialno, serial->len);
1219
1220
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1221
0
}
1222
1223
1224
1225
static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *params)
1226
0
{
1227
0
  sc_context_t *ctx = card->ctx;
1228
0
  sc_pkcs15_tokeninfo_t ti;
1229
0
  int r;
1230
0
  size_t tilen;
1231
0
  sc_apdu_t apdu;
1232
0
  u8 ibuff[68+0xFF], *p;
1233
1234
0
  LOG_FUNC_CALLED(card->ctx);
1235
1236
0
  p = ibuff;
1237
0
  *p++ = 0x80;  // Options
1238
0
  *p++ = 0x02;
1239
0
  memcpy(p, params->options, 2);
1240
0
  p += 2;
1241
1242
0
  if (params->user_pin != NULL) {
1243
0
    if (params->user_pin_len > 16) {
1244
0
      return SC_ERROR_INVALID_ARGUMENTS;
1245
0
    }
1246
0
    *p++ = 0x81; // User PIN
1247
0
    *p++ = (u8)params->user_pin_len;
1248
0
    memcpy(p, params->user_pin, params->user_pin_len);
1249
0
    p += params->user_pin_len;
1250
0
  }
1251
1252
0
  *p++ = 0x82;  // Initialization code
1253
0
  *p++ = 0x08;
1254
0
  memcpy(p, params->init_code, 8);
1255
0
  p += 8;
1256
1257
0
  if (params->user_pin != NULL) {
1258
0
    *p++ = 0x91; // User PIN retry counter
1259
0
    *p++ = 0x01;
1260
0
    *p++ = params->user_pin_retry_counter;
1261
0
  }
1262
1263
0
  if (params->dkek_shares >= 0) {
1264
0
    *p++ = 0x92;  // Number of DKEK shares
1265
0
    *p++ = 0x01;
1266
0
    *p++ = (u8)params->dkek_shares;
1267
0
  }
1268
1269
0
  if (params->key_domains > 0) {
1270
0
    *p++ = 0x97; // Number of key domains
1271
0
    *p++ = 0x01;
1272
0
    *p++ = params->key_domains;
1273
0
  }
1274
1275
0
  if (params->num_of_pub_keys > 0) {
1276
0
    *p++ = 0x93;  // Use public key authentication
1277
0
    *p++ = 0x02;
1278
0
    *p++ = params->num_of_pub_keys; // Total number of public keys used for public authentication
1279
0
    *p++ = params->required_pub_keys; // Number of public keys required for authentication
1280
0
  }
1281
1282
0
  if (params->bio1.len) {
1283
0
    *p++ = 0x95;
1284
0
    *p++ = params->bio1.len;
1285
0
    memcpy(p, params->bio1.value, params->bio1.len);
1286
0
    p += params->bio1.len;
1287
0
  }
1288
0
  if (params->bio2.len) {
1289
0
    *p++ = 0x96;
1290
0
    *p++ = params->bio2.len;
1291
0
    memcpy(p, params->bio2.value, params->bio2.len);
1292
0
    p += params->bio2.len;
1293
0
  }
1294
1295
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x50, 0x00, 0x00);
1296
0
  apdu.cla = 0x80;
1297
0
  apdu.data = ibuff;
1298
0
  apdu.datalen = p - ibuff;
1299
0
  apdu.lc = apdu.datalen;
1300
1301
0
  r = sc_transmit_apdu(card, &apdu);
1302
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
1303
1304
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
1305
1306
0
  if (r == SC_ERROR_NOT_ALLOWED) {
1307
0
    r = SC_ERROR_PIN_CODE_INCORRECT;
1308
0
  }
1309
1310
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1311
1312
0
  if (params->label) {
1313
0
    memset(&ti, 0, sizeof(ti));
1314
1315
0
    ti.label = params->label;
1316
0
    ti.flags = SC_PKCS15_TOKEN_PRN_GENERATION;
1317
1318
0
    r = sc_pkcs15_encode_tokeninfo(ctx, &ti, &p, &tilen);
1319
0
    LOG_TEST_RET(ctx, r, "Error encoding tokeninfo");
1320
1321
0
    r = sc_hsm_write_ef(card, 0x2F03, 0, p, tilen);
1322
0
    LOG_TEST_RET(ctx, r, "Could not write EF.TokenInfo");
1323
0
  }
1324
1325
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1326
0
}
1327
1328
static int
1329
sc_hsm_manage_key_domain(sc_card_t *card, sc_cardctl_sc_hsm_key_domain_t *params)
1330
0
{
1331
0
  sc_context_t *ctx = card->ctx;
1332
0
  sc_apdu_t apdu;
1333
0
  u8 status[SC_MAX_APDU_BUFFER_SIZE];
1334
0
  int r;
1335
1336
0
  LOG_FUNC_CALLED(card->ctx);
1337
1338
0
  switch (params->operation) {
1339
0
  case SC_HSM_MANAGE_KEY_DOMAIN_GET_STATUS:
1340
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x52, 0x00, params->key_domain_idx);
1341
0
    break;
1342
0
  case SC_HSM_MANAGE_KEY_DOMAIN_IMPORT_DKEK_SHARE:
1343
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x52, params->operation - 1, params->key_domain_idx);
1344
0
    apdu.data = params->dkek_share;
1345
0
    apdu.datalen = sizeof(params->dkek_share);
1346
0
    apdu.lc = apdu.datalen;
1347
0
    break;
1348
0
  case SC_HSM_MANAGE_KEY_DOMAIN_CREATE_DKEK_KEY_DOMAIN:
1349
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x52, params->operation - 1, params->key_domain_idx);
1350
0
    apdu.data = &params->dkek_shares;
1351
0
    apdu.datalen = sizeof(params->dkek_shares);
1352
0
    apdu.lc = apdu.datalen;
1353
0
    break;
1354
0
  case SC_HSM_MANAGE_KEY_DOMAIN_DELETE_KEY_DOMAIN:
1355
0
  case SC_HSM_MANAGE_KEY_DOMAIN_CLEAR_KEK:
1356
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x52, (params->operation - 1), params->key_domain_idx);
1357
0
    break;
1358
0
  default:
1359
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN);
1360
0
  }
1361
1362
0
  apdu.cla = 0x80;
1363
0
  apdu.le = 0;
1364
0
  apdu.resp = status;
1365
0
  apdu.resplen = sizeof(status);
1366
1367
0
  r = sc_transmit_apdu(card, &apdu);
1368
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
1369
1370
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
1371
1372
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1373
1374
0
  if (params->operation == SC_HSM_MANAGE_KEY_DOMAIN_DELETE_KEY_DOMAIN) {
1375
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1376
0
  }
1377
1378
0
  if (apdu.resplen < (sizeof(params->key_check_value) + 2))
1379
0
    return SC_ERROR_INTERNAL;
1380
1381
0
  params->type = 0;
1382
0
  params->dkek_shares = status[0];
1383
0
  params->outstanding_shares = status[1];
1384
0
  memcpy(params->key_check_value, status + 2, sizeof(params->key_check_value));
1385
1386
0
  if (apdu.resplen > (sizeof(params->key_check_value) + 2)) {
1387
0
    if (apdu.resplen < (sizeof(params->key_check_value) + sizeof(params->key_domain_uid) + 2))
1388
0
      return SC_ERROR_INTERNAL;
1389
0
    memcpy(params->key_domain_uid, status + 2 + sizeof(params->key_check_value), sizeof(params->key_domain_uid));
1390
0
    params->type = 1;
1391
0
  }
1392
1393
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1394
0
}
1395
1396
1397
1398
static int sc_hsm_wrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *params)
1399
0
{
1400
0
  sc_context_t *ctx = card->ctx;
1401
0
  sc_apdu_t apdu;
1402
0
  u8 data[1500];
1403
0
  int r;
1404
1405
0
  LOG_FUNC_CALLED(card->ctx);
1406
1407
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, 0x72, params->key_id, 0x92);
1408
0
  apdu.cla = 0x80;
1409
0
  apdu.le = 0;
1410
0
  apdu.resp = data;
1411
0
  apdu.resplen = sizeof(data);
1412
1413
0
  r = sc_transmit_apdu(card, &apdu);
1414
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
1415
1416
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
1417
1418
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1419
1420
0
  if (params->wrapped_key == NULL) {
1421
0
    params->wrapped_key_length = apdu.resplen;
1422
0
    params->wrapped_key = malloc(apdu.resplen);
1423
0
    if (params->wrapped_key == NULL) {
1424
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1425
0
    }
1426
0
  } else {
1427
0
    if (apdu.resplen > params->wrapped_key_length) {
1428
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL);
1429
0
    }
1430
0
    params->wrapped_key_length = apdu.resplen;
1431
0
  }
1432
0
  memcpy(params->wrapped_key, data, apdu.resplen);
1433
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1434
0
}
1435
1436
1437
1438
static int sc_hsm_unwrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *params)
1439
0
{
1440
0
  sc_context_t *ctx = card->ctx;
1441
0
  sc_apdu_t apdu;
1442
0
  int r;
1443
1444
0
  LOG_FUNC_CALLED(card->ctx);
1445
1446
0
  r = sc_hsm_write_ef(card, 0x2F10, 0, params->wrapped_key, params->wrapped_key_length);
1447
0
  LOG_TEST_RET(card->ctx, r, "Create EF failed");
1448
1449
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x74, params->key_id, 0x93);
1450
0
  apdu.cla = 0x80;
1451
0
  r = sc_transmit_apdu(card, &apdu);
1452
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
1453
1454
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1455
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1456
1457
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1458
0
}
1459
1460
static int verify_certificate(sc_card_t *card, sc_cvc_t *cvc,
1461
    const u8 *cvc_buf, size_t cvc_buf_len)
1462
0
{
1463
0
  u8 tag = SC_ASN1_TAG_CONTEXT | SC_ASN1_TAG_BIT_STRING; /* 0x83 */
1464
0
  size_t pukref_len;
1465
0
  u8 pukref[BUFSIZ];
1466
0
  sc_apdu_t apdu;
1467
0
  u8 *ptr;
1468
0
  int r;
1469
1470
0
  LOG_FUNC_CALLED(card->ctx);
1471
1472
  /* check if public key is already known */
1473
0
  if ((r = sc_asn1_put_tag(tag, (u8 *)cvc->chr, cvc->chrLen,
1474
0
          pukref, sizeof(pukref), &ptr)) < 0) {
1475
0
    sc_log(card->ctx, "Error formatting ASN.1 sequence: %s\n", sc_strerror(r));
1476
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN);
1477
0
  }
1478
0
  pukref_len = ptr - pukref;
1479
1480
  /* MANAGE SECURITY ENVIRONMENT to query public key by chr */
1481
0
  sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x81, 0xB6, pukref, pukref_len, NULL, 0);
1482
1483
0
  r = sc_transmit_apdu(card, &apdu);
1484
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1485
1486
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1487
0
  if (!r) {
1488
    /* already known */
1489
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1490
0
  }
1491
0
  if (apdu.sw1 != 0x6A && apdu.sw2 != 0x88) {
1492
0
    LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN, "Check SW error");
1493
0
  }
1494
1495
0
  if ((r = sc_asn1_put_tag(tag, (u8 *)cvc->car, cvc->carLen,
1496
0
          pukref, sizeof(pukref), &ptr)) < 0) {
1497
0
    sc_log(card->ctx, "Error formatting ASN.1 sequence: %s\n", sc_strerror(r));
1498
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN);
1499
0
  }
1500
0
  pukref_len = ptr - pukref;
1501
1502
  /* MANAGE SECURITY ENVIRONMENT to set the CAR public key */
1503
0
  sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x81, 0xB6, pukref, pukref_len, NULL, 0);
1504
1505
0
  r = sc_transmit_apdu(card, &apdu);
1506
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1507
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1508
0
  LOG_TEST_RET(card->ctx, r, "Check SW error");
1509
1510
  /* PERFORM SECURITY OPERATION -> VERIFY CERTIFICATE */
1511
0
  sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x00, 0xBE, cvc_buf, cvc_buf_len, NULL, 0);
1512
1513
0
  r = sc_transmit_apdu(card, &apdu);
1514
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1515
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1516
0
  LOG_TEST_RET(card->ctx, r, "Check SW error");
1517
1518
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1519
0
}
1520
1521
1522
1523
static int sc_hsm_register_public_key(sc_card_t *card,
1524
    sc_cardctl_sc_hsm_pka_register_t *pka_register)
1525
0
{
1526
0
  u8 tag = SC_ASN1_TAG_CONTEXT | SC_ASN1_TAG_BIT_STRING; /* 0x83 */
1527
0
  u8 recvbuf[4];
1528
0
  sc_context_t *ctx = card->ctx;
1529
0
  sc_apdu_t apdu;
1530
0
  u8 *ptr;
1531
0
  int r;
1532
0
  sc_pkcs15_card_t p15card;
1533
0
  const u8 *pka_buf;
1534
0
  size_t pka_buf_len;
1535
0
  sc_cvc_pka_t pka;
1536
  /* outer CAR in ASN.1 needs a byte for tag and a byte for length */
1537
0
  u8 asn1_outer_car[sizeof(pka.public_key_req.cvc.outer_car) + 2];
1538
1539
0
  LOG_FUNC_CALLED(ctx);
1540
1541
0
  memset(&pka, 0, sizeof(pka));
1542
0
  memset(&p15card, 0, sizeof(p15card));
1543
0
  p15card.card = card;
1544
1545
0
  pka_buf = pka_register->buf;
1546
0
  pka_buf_len = pka_register->buflen;
1547
0
  r = sc_pkcs15emu_sc_hsm_decode_pka(&p15card, &pka_buf, &pka_buf_len, &pka);
1548
0
  LOG_TEST_GOTO_ERR(ctx, r, "sc_pkcs15emu_sc_hsm_decode_pka failed");
1549
1550
  /* the DICA CVC must be verified first */
1551
0
  r = verify_certificate(card, &pka.dica.cvc, pka.dica.ptr, pka.dica.len);
1552
0
  LOG_TEST_GOTO_ERR(ctx, r, "Verify device issuer CA CVC failed");
1553
1554
  /* the device CVC must be verified before registering the public key */
1555
0
  r = verify_certificate(card, &pka.device.cvc, pka.device.ptr, pka.device.len);
1556
0
  LOG_TEST_GOTO_ERR(ctx, r, "Verify device CVC failed");
1557
1558
0
  r = sc_asn1_put_tag(tag,
1559
0
      (u8 *)pka.public_key_req.cvc.outer_car,
1560
0
      pka.public_key_req.cvc.outerCARLen,
1561
0
      asn1_outer_car, sizeof(asn1_outer_car), &ptr);
1562
0
  LOG_TEST_GOTO_ERR(ctx, r, "ASN.1 encode outer CAR failed");
1563
1564
  /* MANAGE SECURITY ENVIRONMENT with the outer CAR of the public key */
1565
0
  sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x81, 0xB6,
1566
0
      asn1_outer_car, ptr - asn1_outer_car, NULL, 0);
1567
1568
0
  r = sc_transmit_apdu(card, &apdu);
1569
0
  LOG_TEST_GOTO_ERR(ctx, r, "APDU transmit failed");
1570
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1571
0
  LOG_TEST_GOTO_ERR(ctx, r, "Check SW error");
1572
1573
0
  sc_format_apdu_ex(&apdu, 0x80, 0x54, 0x00, 0x00,
1574
0
      pka.public_key_req.ptr, pka.public_key_req.len,
1575
0
      recvbuf, sizeof(recvbuf));
1576
1577
0
  r = sc_transmit_apdu(card, &apdu);
1578
0
  LOG_TEST_GOTO_ERR(ctx, r, "APDU transmit failed");
1579
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1580
0
  LOG_TEST_GOTO_ERR(ctx, r, "Check SW error");
1581
1582
0
  pka_register->new_status.num_total = recvbuf[0];
1583
0
  pka_register->new_status.num_missing = recvbuf[1];
1584
0
  pka_register->new_status.num_required = recvbuf[2];
1585
0
  pka_register->new_status.num_authenticated = recvbuf[3];
1586
1587
0
  r = 0;
1588
  /* fall-through */
1589
1590
0
err:
1591
0
  sc_pkcs15emu_sc_hsm_free_cvc_pka(&pka);
1592
0
  return r;
1593
0
}
1594
1595
1596
1597
static int sc_hsm_public_key_auth_status(sc_card_t *card,
1598
  sc_cardctl_sc_hsm_pka_status_t *status)
1599
0
{
1600
0
  u8 recvbuf[4];
1601
0
  sc_context_t *ctx = card->ctx;
1602
0
  sc_apdu_t apdu;
1603
0
  int r;
1604
1605
0
  LOG_FUNC_CALLED(card->ctx);
1606
1607
  /* get status */
1608
0
  sc_format_apdu_ex(&apdu, 0x00, 0x54, 0x00, 0x00, NULL, 0, recvbuf, sizeof recvbuf);
1609
0
  apdu.cla = 0x80;
1610
1611
0
  r = sc_transmit_apdu(card, &apdu);
1612
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
1613
1614
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1615
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1616
1617
0
  status->num_total = recvbuf[0];
1618
0
  status->num_missing = recvbuf[1];
1619
0
  status->num_required = recvbuf[2];
1620
0
  status->num_authenticated = recvbuf[3];
1621
1622
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1623
0
}
1624
1625
1626
1627
static int sc_hsm_init_token(sc_card_t *card, sc_cardctl_pkcs11_init_token_t *params)
1628
0
{
1629
0
  sc_context_t *ctx = card->ctx;
1630
0
  sc_cardctl_sc_hsm_init_param_t ip;
1631
0
  int r;
1632
0
  char label[33],*cpo;
1633
1634
0
  LOG_FUNC_CALLED(ctx);
1635
1636
0
  if (params->so_pin_len != 16) {
1637
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "SO PIN wrong length (!=16)");
1638
0
  }
1639
1640
0
  memset(&ip, 0, sizeof(ip));
1641
0
  ip.dkek_shares = -1;
1642
0
  ip.options[0] = 0x00;
1643
0
  ip.options[1] = 0x01;
1644
1645
0
  r = sc_hsm_encode_sopin(params->so_pin, ip.init_code);
1646
0
  LOG_TEST_RET(ctx, r, "SO PIN wrong format");
1647
1648
0
  ip.user_pin = ip.init_code;   // Use the first 6 bytes of the SO-PIN as initial User-PIN value
1649
0
  ip.user_pin_len = 6;
1650
0
  ip.user_pin_retry_counter = 3;
1651
1652
0
  if (params->label) {
1653
    // Strip trailing spaces
1654
0
    memcpy(label, params->label, 32);
1655
0
    label[32] = 0;
1656
0
    cpo = label + 31;
1657
0
    while ((cpo >= label) && (*cpo == ' ')) {
1658
0
      *cpo = 0;
1659
0
      cpo--;
1660
0
    }
1661
0
    ip.label = label;
1662
0
  }
1663
1664
0
  r = sc_hsm_initialize(card, &ip);
1665
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1666
1667
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1668
0
}
1669
1670
1671
1672
static int sc_hsm_init_pin(sc_card_t *card, sc_cardctl_pkcs11_init_pin_t *params)
1673
0
{
1674
0
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1675
0
  sc_context_t *ctx = card->ctx;
1676
0
  int r;
1677
0
  sc_apdu_t apdu;
1678
0
  u8 ibuff[50], *p;
1679
1680
0
  LOG_FUNC_CALLED(card->ctx);
1681
1682
0
  if (params->pin_len > 16) {
1683
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "User PIN too long");
1684
0
  }
1685
1686
0
  p = ibuff;
1687
1688
0
  memcpy(p, priv->sopin, sizeof(priv->sopin));
1689
0
  p += sizeof(priv->sopin);
1690
1691
0
  memcpy(p, params->pin, params->pin_len);
1692
0
  p += params->pin_len;
1693
1694
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2C, 0x00, 0x81);
1695
0
  apdu.data = ibuff;
1696
0
  apdu.datalen = p - ibuff;
1697
0
  apdu.lc = apdu.datalen;
1698
1699
0
  r = sc_transmit_apdu(card, &apdu);
1700
0
  LOG_TEST_RET(ctx, r, "APDU transmit failed");
1701
1702
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
1703
1704
  // Cards before version 1.0 do not implement RESET_RETRY_COUNTER
1705
  // For those cards the CHANGE REFERENCE DATA command is used instead
1706
0
  if (r == SC_ERROR_INS_NOT_SUPPORTED) {
1707
0
    p = ibuff;
1708
0
    memcpy(p, priv->sopin, 6);
1709
0
    p += 6;
1710
1711
0
    memcpy(p, params->pin, params->pin_len);
1712
0
    p += params->pin_len;
1713
1714
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, 0x81);
1715
0
    apdu.data = ibuff;
1716
0
    apdu.datalen = p - ibuff;
1717
0
    apdu.lc = apdu.datalen;
1718
1719
0
    r = sc_transmit_apdu(card, &apdu);
1720
0
    LOG_TEST_RET(ctx, r, "APDU transmit failed");
1721
1722
0
    r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
1723
0
  }
1724
1725
0
  LOG_TEST_RET(ctx, r, "Check SW error");
1726
1727
0
  memset(priv->sopin, 0, sizeof(priv->sopin));
1728
1729
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1730
0
}
1731
1732
1733
1734
static int sc_hsm_generate_keypair(sc_card_t *card, sc_cardctl_sc_hsm_keygen_info_t *keyinfo)
1735
0
{
1736
0
  u8 rbuf[1200];
1737
0
  int r;
1738
0
  sc_apdu_t apdu;
1739
1740
0
  LOG_FUNC_CALLED(card->ctx);
1741
1742
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x46, keyinfo->key_id, keyinfo->auth_key_id);
1743
0
  apdu.cla = 0x00;
1744
0
  apdu.resp = rbuf;
1745
0
  apdu.resplen = sizeof(rbuf);
1746
0
  apdu.le = 0;
1747
1748
0
  apdu.data = keyinfo->gakprequest;
1749
0
  apdu.lc = keyinfo->gakprequest_len;
1750
0
  apdu.datalen = keyinfo->gakprequest_len;
1751
1752
0
  r = sc_transmit_apdu(card, &apdu);
1753
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1754
1755
0
  r =  sc_check_sw(card, apdu.sw1, apdu.sw2);
1756
0
  LOG_TEST_RET(card->ctx, r, "Check SW error");
1757
1758
0
  keyinfo->gakpresponse_len = apdu.resplen;
1759
0
  keyinfo->gakpresponse = malloc(apdu.resplen);
1760
1761
0
  if (keyinfo->gakpresponse == NULL) {
1762
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1763
0
  }
1764
1765
0
  memcpy(keyinfo->gakpresponse, apdu.resp, apdu.resplen);
1766
1767
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1768
0
}
1769
1770
1771
1772
static int sc_hsm_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
1773
168
{
1774
168
  switch (cmd) {
1775
168
  case SC_CARDCTL_GET_SERIALNR:
1776
168
    return sc_hsm_get_serialnr(card, (sc_serial_number_t *)ptr);
1777
0
  case SC_CARDCTL_PKCS11_INIT_TOKEN:
1778
0
    return sc_hsm_init_token(card, (sc_cardctl_pkcs11_init_token_t *)ptr);
1779
0
  case SC_CARDCTL_PKCS11_INIT_PIN:
1780
0
    return sc_hsm_init_pin(card, (sc_cardctl_pkcs11_init_pin_t *)ptr);
1781
0
  case SC_CARDCTL_SC_HSM_GENERATE_KEY:
1782
0
    return sc_hsm_generate_keypair(card, (sc_cardctl_sc_hsm_keygen_info_t *)ptr);
1783
0
  case SC_CARDCTL_SC_HSM_INITIALIZE:
1784
0
    return sc_hsm_initialize(card, (sc_cardctl_sc_hsm_init_param_t *)ptr);
1785
0
  case SC_CARDCTL_SC_HSM_MANAGE_KEY_DOMAIN:
1786
0
    return sc_hsm_manage_key_domain(card, (sc_cardctl_sc_hsm_key_domain_t *)ptr);
1787
0
  case SC_CARDCTL_SC_HSM_WRAP_KEY:
1788
0
    return sc_hsm_wrap_key(card, (sc_cardctl_sc_hsm_wrapped_key_t *)ptr);
1789
0
  case SC_CARDCTL_SC_HSM_UNWRAP_KEY:
1790
0
    return sc_hsm_unwrap_key(card, (sc_cardctl_sc_hsm_wrapped_key_t *)ptr);
1791
0
  case SC_CARDCTL_SC_HSM_REGISTER_PUBLIC_KEY:
1792
0
    return sc_hsm_register_public_key(card, ptr);
1793
0
  case SC_CARDCTL_SC_HSM_PUBLIC_KEY_AUTH_STATUS:
1794
0
    return sc_hsm_public_key_auth_status(card, ptr);
1795
168
  }
1796
0
  return SC_ERROR_NOT_SUPPORTED;
1797
168
}
1798
1799
1800
1801
static int sc_hsm_init(struct sc_card *card)
1802
279
{
1803
#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE) && defined(_WIN32)
1804
  char expanded_val[PATH_MAX];
1805
  size_t expanded_len = PATH_MAX;
1806
#endif
1807
279
  int flags,ext_flags;
1808
279
  sc_file_t *file = NULL;
1809
279
  sc_path_t path;
1810
279
  sc_hsm_private_data_t *priv = NULL;
1811
1812
279
  LOG_FUNC_CALLED(card->ctx);
1813
1814
279
  flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN
1815
279
      |SC_ALGORITHM_RSA_HASH_SHA1|SC_ALGORITHM_RSA_HASH_SHA256|SC_ALGORITHM_RSA_HASH_SHA384|SC_ALGORITHM_RSA_HASH_SHA512
1816
279
      |SC_ALGORITHM_MGF1_SHA256|SC_ALGORITHM_MGF1_SHA384|SC_ALGORITHM_MGF1_SHA512;
1817
1818
279
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
1819
279
  _sc_card_add_rsa_alg(card, 1536, flags, 0);
1820
279
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
1821
279
  _sc_card_add_rsa_alg(card, 3072, flags, 0);
1822
279
  _sc_card_add_rsa_alg(card, 4096, flags, 0);
1823
1824
279
  flags = SC_ALGORITHM_ECDSA_RAW|
1825
279
    SC_ALGORITHM_ECDH_CDH_RAW|
1826
279
    SC_ALGORITHM_ECDSA_HASH_NONE|
1827
279
    SC_ALGORITHM_ECDSA_HASH_SHA1|
1828
279
    SC_ALGORITHM_ECDSA_HASH_SHA224|
1829
279
    SC_ALGORITHM_ECDSA_HASH_SHA256|
1830
279
    SC_ALGORITHM_ECDSA_HASH_SHA384|
1831
279
    SC_ALGORITHM_ECDSA_HASH_SHA512|
1832
279
    SC_ALGORITHM_ONBOARD_KEY_GEN;
1833
1834
279
  ext_flags = SC_ALGORITHM_EXT_EC_F_P|
1835
279
      SC_ALGORITHM_EXT_EC_ECPARAMETERS|
1836
279
      SC_ALGORITHM_EXT_EC_NAMEDCURVE|
1837
279
      SC_ALGORITHM_EXT_EC_UNCOMPRESES|
1838
279
      SC_ALGORITHM_ONBOARD_KEY_GEN;
1839
279
  _sc_card_add_ec_alg(card, 192, flags, ext_flags, NULL);
1840
279
  _sc_card_add_ec_alg(card, 224, flags, ext_flags, NULL);
1841
279
  _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
1842
279
  _sc_card_add_ec_alg(card, 320, flags, ext_flags, NULL);
1843
279
  _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
1844
279
  _sc_card_add_ec_alg(card, 512, flags, ext_flags, NULL);
1845
279
  _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL);
1846
1847
279
  card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO;
1848
1849
  // APDU Size limits
1850
  //   JCOP 2.4.1r3           1462
1851
  //   JCOP 2.4.2r3           1454
1852
  //   JCOP 3                 1232
1853
  //   JCOP 4                 1454
1854
  //   MicroSD with JCOP 3    478 / 506 - handled in reader-pcsc.c
1855
  //   Reiner SCT             1014 - handled in reader-pcsc.c
1856
  //
1857
  // Note, that these are limits for the whole APDU, but the semantics of max_send_size
1858
  // is the size of the APDU send buffer so to get the right value from them, we need
1859
  // to subtract APDU headers (CLA, INS, P1, P2, Lc (3B)), 7 bytes altogether for
1860
  // class 3 APDU
1861
  // (or 9 bytes for case 4 when we pass in >255 B data and expect return of more than 255 B)
1862
1863
  // Use JCOP 3 (smallest unhandled by reader limitation) card limits for sending
1864
  // And make it 9 smaller to make sure we fit the rest of the APDU.
1865
279
  card->max_send_size = 1232 - 9;
1866
  // Assume that card supports sending with extended length APDU and without limit
1867
279
  card->max_recv_size = 0;
1868
1869
279
  if (card->type == SC_CARD_TYPE_SC_HSM_SOC
1870
279
      || card->type == SC_CARD_TYPE_SC_HSM_GOID) {
1871
277
    card->max_recv_size = 0x0630; // SoC Proxy forces this limit
1872
277
  } else {
1873
    // Adjust to the limits set by the reader
1874
2
    if (card->reader->max_send_size < card->max_send_size) {
1875
2
      if (18 >= card->reader->max_send_size)
1876
2
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCONSISTENT_CONFIGURATION);
1877
1878
      // 17 byte header and TLV because of odd ins in UPDATE BINARY
1879
0
      card->max_send_size = card->reader->max_send_size - 17;
1880
0
    }
1881
1882
0
    if (0 < card->reader->max_recv_size) {
1883
0
      if (3 >= card->reader->max_recv_size)
1884
0
        LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCONSISTENT_CONFIGURATION);
1885
0
      card->max_recv_size = card->reader->max_recv_size - 2;
1886
0
    }
1887
0
  }
1888
1889
277
  priv = card->drv_data;
1890
277
  if (!priv) {
1891
277
    priv = calloc(1, sizeof(sc_hsm_private_data_t));
1892
277
    if (!priv)
1893
277
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1894
277
    card->drv_data = priv;
1895
277
  }
1896
1897
277
  sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
1898
277
  if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS
1899
53
      && file && file->prop_attr && file->prop_attr_len >= 2) {
1900
4
    static char card_name[SC_MAX_APDU_BUFFER_SIZE];
1901
4
    u8 type = 0xFF;
1902
4
    u8 major = file->prop_attr[file->prop_attr_len - 2];
1903
4
    u8 minor = file->prop_attr[file->prop_attr_len - 1];
1904
4
    char p00[] = "SmartCard-HSM Applet for JCOP";
1905
4
    char p01[] = "SmartCard-HSM Demo Applet for JCOP";
1906
4
    char *p = "SmartCard-HSM";
1907
4
    if (file->prop_attr_len >= 3) {
1908
3
      type = file->prop_attr[file->prop_attr_len - 3];
1909
3
    }
1910
4
    switch (type) {
1911
1
      case 0x00:
1912
1
        p = p00;
1913
1
        break;
1914
1
      case 0x01:
1915
1
        p = p01;
1916
1
        break;
1917
2
      default:
1918
2
        break;
1919
4
    }
1920
4
    snprintf(card_name, sizeof card_name, "%s version %u.%u", p, major, minor);
1921
4
    card->name = card_name;
1922
1923
4
    if (file->prop_attr[1] & 0x04) {
1924
1
      card->caps |= SC_CARD_CAP_SESSION_PIN;
1925
1
    }
1926
4
  }
1927
277
  sc_file_free(file);
1928
1929
277
  priv->EF_C_DevAut = NULL;
1930
277
  priv->EF_C_DevAut_len = 0;
1931
1932
277
#if defined(ENABLE_SM) && defined(ENABLE_OPENPACE)
1933
277
  EAC_init();
1934
#ifdef _WIN32
1935
  expanded_len = ExpandEnvironmentStringsA(CVCDIR, expanded_val, sizeof expanded_val);
1936
  if (0 < expanded_len && expanded_len < sizeof expanded_val)
1937
    EAC_set_cvc_default_dir(expanded_val);
1938
#else
1939
277
  EAC_set_cvc_default_dir(CVCDIR);
1940
277
#endif
1941
277
#endif
1942
1943
277
  return 0;
1944
277
}
1945
1946
1947
1948
static int sc_hsm_finish(sc_card_t * card)
1949
277
{
1950
277
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1951
277
#ifdef ENABLE_SM
1952
277
  sc_sm_stop(card);
1953
277
#endif
1954
277
  if (priv) {
1955
277
    free(priv->serialno);
1956
277
    sc_file_free(priv->dffcp);
1957
277
    free(priv->EF_C_DevAut);
1958
277
  }
1959
277
  free(priv);
1960
1961
277
  return SC_SUCCESS;
1962
277
}
1963
1964
1965
1966
static struct sc_card_driver * sc_get_driver(void)
1967
16.9k
{
1968
16.9k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1969
1970
16.9k
  if (iso_ops == NULL)
1971
1
    iso_ops = iso_drv->ops;
1972
1973
16.9k
  sc_hsm_ops                   = *iso_drv->ops;
1974
16.9k
  sc_hsm_ops.match_card        = sc_hsm_match_card;
1975
16.9k
  sc_hsm_ops.select_file       = sc_hsm_select_file;
1976
16.9k
  sc_hsm_ops.get_challenge     = sc_hsm_get_challenge;
1977
16.9k
  sc_hsm_ops.read_binary       = sc_hsm_read_binary;
1978
16.9k
  sc_hsm_ops.update_binary     = sc_hsm_update_binary;
1979
16.9k
  sc_hsm_ops.list_files        = sc_hsm_list_files;
1980
16.9k
  sc_hsm_ops.create_file       = sc_hsm_create_file;
1981
16.9k
  sc_hsm_ops.delete_file       = sc_hsm_delete_file;
1982
16.9k
  sc_hsm_ops.set_security_env  = sc_hsm_set_security_env;
1983
16.9k
  sc_hsm_ops.compute_signature = sc_hsm_compute_signature;
1984
16.9k
  sc_hsm_ops.decipher          = sc_hsm_decipher;
1985
16.9k
  sc_hsm_ops.init              = sc_hsm_init;
1986
16.9k
  sc_hsm_ops.finish            = sc_hsm_finish;
1987
16.9k
  sc_hsm_ops.card_ctl          = sc_hsm_card_ctl;
1988
16.9k
  sc_hsm_ops.pin_cmd           = sc_hsm_pin_cmd;
1989
16.9k
  sc_hsm_ops.logout            = sc_hsm_logout;
1990
1991
  /* no record oriented file services */
1992
16.9k
  sc_hsm_ops.read_record       = NULL;
1993
16.9k
  sc_hsm_ops.write_record      = NULL;
1994
16.9k
  sc_hsm_ops.append_record     = NULL;
1995
16.9k
  sc_hsm_ops.update_record     = NULL;
1996
1997
16.9k
  return &sc_hsm_drv;
1998
16.9k
}
1999
2000
2001
2002
struct sc_card_driver * sc_get_sc_hsm_driver(void)
2003
16.9k
{
2004
16.9k
  return sc_get_driver();
2005
16.9k
}
2006