Coverage Report

Created: 2026-03-21 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-iasecc.c
Line
Count
Source
1
/*
2
 * card-iasecc.c: Support for IAS/ECC smart cards
3
 *
4
 * Copyright (C) 2010  Viktor Tarasov <vtarasov@gmail.com>
5
 *      OpenTrust <www.opentrust.com>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include <config.h>
24
#endif
25
26
#ifdef ENABLE_OPENSSL   /* empty file without openssl */
27
28
#include <string.h>
29
#include <stdlib.h>
30
31
#include <openssl/bn.h>
32
#include <openssl/evp.h>
33
#include <openssl/pem.h>
34
#include <openssl/err.h>
35
#include <openssl/rand.h>
36
#include <openssl/sha.h>
37
#include <openssl/rsa.h>
38
#include <openssl/pkcs12.h>
39
#include <openssl/x509v3.h>
40
41
#include "internal.h"
42
#include "asn1.h"
43
#include "cardctl.h"
44
#include "opensc.h"
45
#include "sc-ossl-compat.h"
46
/* #include "sm.h" */
47
#include "pkcs15.h"
48
/* #include "hash-strings.h" */
49
#include "gp.h"
50
51
#include "iasecc.h"
52
53
754
#define IASECC_CARD_DEFAULT_FLAGS ( 0     \
54
754
    | SC_ALGORITHM_ONBOARD_KEY_GEN    \
55
754
    | SC_ALGORITHM_RSA_PAD_ISO9796    \
56
754
    | SC_ALGORITHM_RSA_PAD_PKCS1    \
57
754
    | SC_ALGORITHM_RSA_HASH_NONE    \
58
754
    | SC_ALGORITHM_RSA_HASH_SHA1    \
59
754
    | SC_ALGORITHM_RSA_HASH_SHA256)
60
61
754
#define IASECC_CARD_DEFAULT_CAPS ( 0       \
62
754
    | SC_CARD_CAP_RNG      \
63
754
    | SC_CARD_CAP_APDU_EXT      \
64
754
    | SC_CARD_CAP_USE_FCI_AC    \
65
754
    | SC_CARD_CAP_ISO7816_PIN_INFO)
66
67
/* generic iso 7816 operations table */
68
static const struct sc_card_operations *iso_ops = NULL;
69
70
/* our operations table with overrides */
71
static struct sc_card_operations iasecc_ops;
72
73
static struct sc_card_driver iasecc_drv = {
74
  "IAS-ECC",
75
  "iasecc",
76
  &iasecc_ops,
77
  NULL, 0, NULL
78
};
79
80
static const struct sc_atr_table iasecc_known_atrs[] = {
81
  { "3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00",
82
    "FF:FF:FF:FF:FF:FF:FF:FE:FF:FF:00:00:FF:FF:FF:FF:FF:FF:FF:FF",
83
    "IAS/ECC Gemalto", SC_CARD_TYPE_IASECC_GEMALTO,  0, NULL },
84
        { "3B:DD:00:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:08:00:07:90:00:00",
85
    "FF:FF:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00",
86
    "IAS/ECC v1.0.1 Oberthur", SC_CARD_TYPE_IASECC_OBERTHUR,  0, NULL },
87
  { "3B:7D:13:00:00:4D:44:57:2D:49:41:53:2D:43:41:52:44:32", NULL,
88
    "IAS/ECC v1.0.1 Sagem MDW-IAS-CARD2", SC_CARD_TYPE_IASECC_SAGEM,  0, NULL },
89
  { "3B:7F:18:00:00:00:31:B8:64:50:23:EC:C1:73:94:01:80:82:90:00", NULL,
90
    "IAS/ECC v1.0.1 Sagem ypsID S3", SC_CARD_TYPE_IASECC_SAGEM,  0, NULL },
91
  { "3B:DF:96:00:80:31:FE:45:00:31:B8:64:04:1F:EC:C1:73:94:01:80:82:90:00:EC", NULL,
92
    "IAS/ECC Morpho MinInt - Agent Card", SC_CARD_TYPE_IASECC_MI, 0, NULL },
93
  { "3B:DF:18:FF:81:91:FE:1F:C3:00:31:B8:64:0C:01:EC:C1:73:94:01:80:82:90:00:B3", NULL,
94
    "IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
95
  { "3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:02:04:03:55:00:02:34", NULL,
96
    "IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
97
  { "3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:01:0B:03:52:00:05:38", NULL,
98
    "IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
99
  {
100
    .atr     = "3B:AC:00:40:2A:00:12:25:00:64:80:00:03:10:00:90:00",
101
    .atrmask = "FF:00:00:00:00:FF:FF:FF:FF:FF:FF:00:00:00:FF:FF:FF",
102
    .name = "IAS/ECC CPx",
103
    .type = SC_CARD_TYPE_IASECC_CPX,
104
  },
105
  {
106
    .atr     = "2B:8F:80:01:00:31:B8:64:04:B0:EC:C1:73:94:01:80:82:90:00:0E",
107
    .atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:FF:C0:FF:FF:FF:FF:FF:FF:FF:FF",
108
    .name = "IAS/ECC CPxCL",
109
    .type = SC_CARD_TYPE_IASECC_CPXCL,
110
  },
111
  { NULL, NULL, NULL, 0, 0, NULL }
112
};
113
114
static struct sc_aid OberthurIASECC_AID = {
115
  {0xA0,0x00,0x00,0x00,0x77,0x01,0x08,0x00,0x07,0x00,0x00,0xFE,0x00,0x00,0x01,0x00}, 16
116
};
117
118
static struct sc_aid MIIASECC_AID = {
119
  { 0x4D, 0x49, 0x4F, 0x4D, 0x43, 0x54}, 6
120
};
121
122
struct iasecc_pin_status  {
123
  unsigned char sha1[SHA_DIGEST_LENGTH];
124
  unsigned char reference;
125
126
  struct iasecc_pin_status *next;
127
  struct iasecc_pin_status *prev;
128
};
129
130
struct iasecc_pin_status *checked_pins = NULL;
131
132
/* Any absent field is set to -1, except scbs, which is always present */
133
struct iasecc_pin_policy {
134
  int min_length;
135
  int max_length;
136
  int stored_length;
137
  int tries_maximum;
138
  int tries_remaining;
139
  unsigned char scbs[IASECC_MAX_SCBS];
140
};
141
142
static int iasecc_select_file(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out);
143
static int iasecc_process_fci(struct sc_card *card, struct sc_file *file, const unsigned char *buf, size_t buflen);
144
static int iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial);
145
static int iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo);
146
static int iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin);
147
static int iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left);
148
static int iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left);
149
static int iasecc_check_update_pin(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin);
150
static void iasecc_set_pin_padding(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin,
151
           size_t pad_len);
152
static int iasecc_pin_merge_policy(struct sc_card *card, struct sc_pin_cmd_data *data,
153
           struct sc_pin_cmd_pin *pin, struct iasecc_pin_policy *policy);
154
static int iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_reference *ctl_data);
155
static int iasecc_sdo_put_data(struct sc_card *card, struct iasecc_sdo_update *update);
156
157
#ifdef ENABLE_SM
158
static int _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs, unsigned char *buf, size_t count);
159
static int _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs, const unsigned char *buff, size_t count);
160
#endif
161
162
void
163
sc_invalidate_cache(struct sc_card *card)
164
2.29k
{
165
2.29k
  if (card) {
166
2.29k
    struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
167
2.29k
    sc_file_free(prv->cache.current_ef);
168
2.29k
    sc_file_free(prv->cache.current_df);
169
2.29k
    memset(&prv->cache, 0, sizeof(prv->cache));
170
2.29k
    prv->cache.valid = 0;
171
2.29k
  }
172
2.29k
}
173
174
static int
175
iasecc_chv_cache_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd)
176
0
{
177
0
  struct sc_context *ctx = card->ctx;
178
0
  struct iasecc_pin_status *pin_status = NULL, *current = NULL;
179
180
0
  LOG_FUNC_CALLED(ctx);
181
182
0
  for(current = checked_pins; current; current = current->next)
183
0
    if (current->reference == pin_cmd->pin_reference)
184
0
      break;
185
186
0
  if (current)   {
187
0
    sc_log(ctx, "iasecc_chv_cache_verified() current PIN-%i", current->reference);
188
0
    pin_status = current;
189
0
  }
190
0
  else   {
191
0
    pin_status = calloc(1, sizeof(struct iasecc_pin_status));
192
0
    if (!pin_status)
193
0
      LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot callocate PIN status info");
194
0
    sc_log(ctx, "iasecc_chv_cache_verified() allocated %p", pin_status);
195
0
  }
196
197
0
  pin_status->reference = pin_cmd->pin_reference;
198
0
  if (pin_cmd->pin1.data)
199
0
    SHA1(pin_cmd->pin1.data, pin_cmd->pin1.len, pin_status->sha1);
200
0
  else
201
0
    memset(pin_status->sha1, 0, SHA_DIGEST_LENGTH);
202
203
0
  sc_log_hex(ctx, "iasecc_chv_cache_verified() sha1(PIN)", pin_status->sha1, SHA_DIGEST_LENGTH);
204
205
0
  if (!current)   {
206
0
    if (!checked_pins)   {
207
0
      checked_pins = pin_status;
208
0
    }
209
0
    else   {
210
0
    checked_pins->prev = pin_status;
211
0
      pin_status->next = checked_pins;
212
0
      checked_pins = pin_status;
213
0
    }
214
0
  }
215
216
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
217
0
}
218
219
220
static int
221
iasecc_chv_cache_clean(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd)
222
0
{
223
0
  struct sc_context *ctx = card->ctx;
224
0
  struct iasecc_pin_status *current = NULL;
225
226
0
  LOG_FUNC_CALLED(ctx);
227
228
0
  for(current = checked_pins; current; current = current->next)
229
0
    if (current->reference == pin_cmd->pin_reference)
230
0
      break;
231
232
0
  if (!current)
233
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
234
235
236
0
  if (current->next && current->prev)   {
237
0
    current->prev->next = current->next;
238
0
    current->next->prev = current->prev;
239
0
  }
240
0
  else if (!current->prev)   {
241
0
    checked_pins = current->next;
242
0
  }
243
0
  else if (!current->next && current->prev)   {
244
0
    current->prev->next = NULL;
245
0
  }
246
247
0
  free(current);
248
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
249
0
}
250
251
252
static struct iasecc_pin_status *
253
iasecc_chv_cache_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd)
254
0
{
255
0
  struct sc_context *ctx = card->ctx;
256
0
  struct iasecc_pin_status *current = NULL;
257
0
  unsigned char data_sha1[SHA_DIGEST_LENGTH];
258
259
0
  LOG_FUNC_CALLED(ctx);
260
261
0
  if (pin_cmd->pin1.data)
262
0
    SHA1(pin_cmd->pin1.data, pin_cmd->pin1.len, data_sha1);
263
0
  else
264
0
    memset(data_sha1, 0, SHA_DIGEST_LENGTH);
265
0
  sc_log_hex(ctx, "data_sha1: %s", data_sha1, SHA_DIGEST_LENGTH);
266
267
0
  for(current = checked_pins; current; current = current->next)
268
0
    if (current->reference == pin_cmd->pin_reference)
269
0
      break;
270
271
0
  if (current && !memcmp(data_sha1, current->sha1, SHA_DIGEST_LENGTH))   {
272
0
    sc_log(ctx, "PIN-%i status 'verified'", pin_cmd->pin_reference);
273
0
    return current;
274
0
  }
275
276
0
  sc_log(ctx, "PIN-%i status 'not verified'", pin_cmd->pin_reference);
277
0
  return NULL;
278
0
}
279
280
281
static int
282
iasecc_select_mf(struct sc_card *card, struct sc_file **file_out)
283
2.24k
{
284
2.24k
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
285
2.24k
  struct sc_context *ctx = card->ctx;
286
2.24k
  struct sc_file *mf_file = NULL;
287
2.24k
  struct sc_path path;
288
2.24k
  int rv;
289
290
2.24k
  LOG_FUNC_CALLED(ctx);
291
292
2.24k
  if (file_out)
293
1.33k
    *file_out = NULL;
294
295
2.24k
  memset(&path, 0, sizeof(struct sc_path));
296
2.24k
  if (!card->ef_atr || !card->ef_atr->aid.len)   {
297
347
    struct sc_apdu apdu;
298
347
    unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
299
300
    /* ISO 'select' command fails when not FCP data returned */
301
347
    sc_format_path("3F00", &path);
302
347
    path.type = SC_PATH_TYPE_FILE_ID;
303
304
347
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x0C);
305
347
    apdu.lc = path.len;
306
347
    apdu.data = path.value;
307
347
    apdu.datalen = path.len;
308
347
    apdu.resplen = sizeof(apdu_resp);
309
347
    apdu.resp = apdu_resp;
310
311
    /* TODO: this might be obsolete now that 0x0c (no data) is default for p2 */
312
347
    if (card->type == SC_CARD_TYPE_IASECC_MI2)
313
66
      apdu.p2 = 0x04;
314
315
347
    rv = sc_transmit_apdu(card, &apdu);
316
347
    LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
317
337
    rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
318
337
    LOG_TEST_RET(card->ctx, rv, "Cannot select MF");
319
337
  }
320
1.89k
  else   {
321
1.89k
    memset(&path, 0, sizeof(path));
322
1.89k
    path.type = SC_PATH_TYPE_DF_NAME;
323
1.89k
    memcpy(path.value, card->ef_atr->aid.value, card->ef_atr->aid.len);
324
1.89k
    path.len = card->ef_atr->aid.len;
325
1.89k
    rv = iasecc_select_file(card, &path, file_out);
326
1.89k
    LOG_TEST_RET(ctx, rv, "Unable to ROOT selection");
327
1.89k
  }
328
329
  /* Ignore the FCP of the MF, because:
330
   * - some cards do not return it;
331
   * - there is not need of it -- create/delete of the files in MF is not envisaged.
332
   */
333
496
  mf_file = sc_file_new();
334
496
  if (mf_file == NULL)
335
496
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate MF file");
336
496
  mf_file->type = SC_FILE_TYPE_DF;
337
496
  mf_file->path = path;
338
339
496
  sc_invalidate_cache(card);
340
496
  sc_file_dup(&prv->cache.current_df, mf_file);
341
496
  prv->cache.valid = 1;
342
343
496
  if (file_out && *file_out == NULL)
344
248
    *file_out = mf_file;
345
248
  else
346
248
    sc_file_free(mf_file);
347
348
496
  LOG_FUNC_RETURN(ctx, rv);
349
496
}
350
351
static int
352
iasecc_match_card(struct sc_card *card)
353
9.11k
{
354
9.11k
  struct sc_context *ctx = card->ctx;
355
9.11k
  int i;
356
357
9.11k
  i = _sc_match_atr(card, iasecc_known_atrs, &card->type);
358
9.11k
  if (i < 0)   {
359
8.36k
    sc_log(ctx, "card not matched");
360
8.36k
    return 0;
361
8.36k
  }
362
363
754
  sc_log(ctx, "'%s' card matched", iasecc_known_atrs[i].name);
364
754
  return 1;
365
9.11k
}
366
367
368
static int iasecc_parse_ef_atr(struct sc_card *card)
369
397
{
370
397
  struct sc_context *ctx = card->ctx;
371
397
  struct iasecc_private_data *pdata = (struct iasecc_private_data *) card->drv_data;
372
397
  struct iasecc_version *version = &pdata->version;
373
397
  struct iasecc_io_buffer_sizes *sizes = &pdata->max_sizes;
374
397
  int rv;
375
376
397
  LOG_FUNC_CALLED(ctx);
377
397
  rv = sc_parse_ef_atr(card);
378
397
  LOG_TEST_RET(ctx, rv, "MF selection error");
379
380
214
  if (card->ef_atr->pre_issuing_len < 4)
381
214
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid pre-issuing data");
382
383
119
  version->ic_manufacturer =  card->ef_atr->pre_issuing[0];
384
119
  version->ic_type =    card->ef_atr->pre_issuing[1];
385
119
  version->os_version =   card->ef_atr->pre_issuing[2];
386
119
  version->iasecc_version = card->ef_atr->pre_issuing[3];
387
119
  sc_log(ctx, "EF.ATR: IC manufacturer/type %X/%X, OS/IasEcc versions %X/%X",
388
119
    version->ic_manufacturer, version->ic_type, version->os_version, version->iasecc_version);
389
390
119
  if (card->ef_atr->issuer_data_len < 16)
391
119
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid issuer data");
392
393
116
  sizes->send =  card->ef_atr->issuer_data[2] * 0x100 + card->ef_atr->issuer_data[3];
394
116
  sizes->send_sc = card->ef_atr->issuer_data[6] * 0x100 + card->ef_atr->issuer_data[7];
395
116
  sizes->recv =  card->ef_atr->issuer_data[10] * 0x100 + card->ef_atr->issuer_data[11];
396
116
  sizes->recv_sc = card->ef_atr->issuer_data[14] * 0x100 + card->ef_atr->issuer_data[15];
397
398
116
  sc_log(ctx,
399
116
    "EF.ATR: IO Buffer Size send/sc %"SC_FORMAT_LEN_SIZE_T"d/%"SC_FORMAT_LEN_SIZE_T"d "
400
116
    "recv/sc %"SC_FORMAT_LEN_SIZE_T"d/%"SC_FORMAT_LEN_SIZE_T"d",
401
116
    sizes->send, sizes->send_sc, sizes->recv, sizes->recv_sc);
402
403
116
  card->max_send_size = sizes->send;
404
116
  card->max_recv_size = sizes->recv;
405
406
  /* Most of the card producers interpret 'send' values as "maximum APDU data size".
407
   * Oberthur strictly follows specification and interpret these values as "maximum APDU command size".
408
   * Here we need 'data size'.
409
   */
410
116
  if (card->max_send_size > 0xFF)
411
97
    card->max_send_size -= 5;
412
413
116
  sc_log(ctx,
414
116
         "EF.ATR: max send/recv sizes %"SC_FORMAT_LEN_SIZE_T"X/%"SC_FORMAT_LEN_SIZE_T"X",
415
116
         card->max_send_size, card->max_recv_size);
416
417
116
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
418
116
}
419
420
421
static int
422
iasecc_init_gemalto(struct sc_card *card)
423
19
{
424
19
  struct sc_context *ctx = card->ctx;
425
19
  struct sc_path path;
426
19
  unsigned int flags;
427
19
  int rv = 0;
428
429
19
  LOG_FUNC_CALLED(ctx);
430
431
19
  flags = IASECC_CARD_DEFAULT_FLAGS;
432
433
19
  card->caps = IASECC_CARD_DEFAULT_CAPS;
434
435
19
  sc_format_path("3F00", &path);
436
19
  if (SC_SUCCESS != sc_select_file(card, &path, NULL)) {
437
    /* Result ignored*/
438
17
    sc_log(card->ctx, "Warning, MF select failed");
439
17
  }
440
441
19
  rv = iasecc_parse_ef_atr(card);
442
19
  sc_log(ctx, "rv %i", rv);
443
19
  if (rv == SC_ERROR_FILE_NOT_FOUND)   {
444
2
    sc_log(ctx, "Select MF");
445
2
    rv = iasecc_select_mf(card, NULL);
446
2
    sc_log(ctx, "rv %i", rv);
447
2
    LOG_TEST_RET(ctx, rv, "MF selection error");
448
449
1
    rv = iasecc_parse_ef_atr(card);
450
1
    sc_log(ctx, "rv %i", rv);
451
1
  }
452
18
  sc_log(ctx, "rv %i", rv);
453
18
  LOG_TEST_RET(ctx, rv, "Cannot read/parse EF.ATR");
454
455
3
  _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
456
3
  _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
457
458
3
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
459
3
}
460
461
462
static int
463
iasecc_oberthur_match(struct sc_card *card)
464
45
{
465
45
  struct sc_context *ctx = card->ctx;
466
45
  unsigned char *hist = card->reader->atr_info.hist_bytes;
467
468
45
  LOG_FUNC_CALLED(ctx);
469
470
45
  if (*hist != 0x80 || ((*(hist+1)&0xF0) != 0xF0))
471
45
    LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND);
472
473
45
  sc_log_hex(ctx, "AID in historical_bytes", hist + 2, *(hist+1) & 0x0F);
474
475
45
  if (memcmp(hist + 2, OberthurIASECC_AID.value, *(hist+1) & 0x0F))
476
45
    LOG_FUNC_RETURN(ctx, SC_ERROR_RECORD_NOT_FOUND);
477
478
45
  if (!card->ef_atr)
479
27
    card->ef_atr = calloc(1, sizeof(struct sc_ef_atr));
480
45
  if (!card->ef_atr)
481
45
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
482
483
45
  memcpy(card->ef_atr->aid.value, OberthurIASECC_AID.value, OberthurIASECC_AID.len);
484
45
  card->ef_atr->aid.len = OberthurIASECC_AID.len;
485
486
45
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
487
45
}
488
489
490
static int
491
iasecc_init_oberthur(struct sc_card *card)
492
45
{
493
45
  struct sc_context *ctx = card->ctx;
494
45
  unsigned int flags;
495
45
  int rv = 0;
496
497
45
  LOG_FUNC_CALLED(ctx);
498
499
45
  flags = IASECC_CARD_DEFAULT_FLAGS;
500
501
45
  _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
502
45
  _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
503
504
45
  card->caps = IASECC_CARD_DEFAULT_CAPS;
505
506
45
  iasecc_parse_ef_atr(card);
507
508
  /* if we fail to select CM, */
509
45
  if (gp_select_card_manager(card)) {
510
34
    gp_select_isd_rid(card);
511
34
  }
512
513
45
  rv = iasecc_oberthur_match(card);
514
45
  LOG_TEST_RET(ctx, rv, "unknown Oberthur's IAS/ECC card");
515
516
45
  rv = iasecc_select_mf(card, NULL);
517
45
  LOG_TEST_RET(ctx, rv, "MF selection error");
518
519
13
  rv = iasecc_parse_ef_atr(card);
520
13
  LOG_TEST_RET(ctx, rv, "EF.ATR read or parse error");
521
522
4
  sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len));
523
4
  LOG_FUNC_RETURN(ctx, rv);
524
4
}
525
526
527
static int
528
iasecc_mi_match(struct sc_card *card)
529
404
{
530
404
  struct sc_context *ctx = card->ctx;
531
404
  unsigned char resp[0x100];
532
404
  size_t resp_len = sizeof(resp);
533
404
  int rv = 0;
534
535
404
  LOG_FUNC_CALLED(ctx);
536
537
404
  rv = iso7816_select_aid(card, MIIASECC_AID.value, MIIASECC_AID.len, resp, &resp_len);
538
404
  LOG_TEST_RET(ctx, rv, "IASECC: failed to select MI IAS/ECC applet");
539
540
376
  if (!card->ef_atr)
541
376
    card->ef_atr = calloc(1, sizeof(struct sc_ef_atr));
542
376
  if (!card->ef_atr)
543
376
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
544
545
376
  memcpy(card->ef_atr->aid.value, MIIASECC_AID.value, MIIASECC_AID.len);
546
376
  card->ef_atr->aid.len = MIIASECC_AID.len;
547
548
376
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
549
376
}
550
551
552
static int
553
iasecc_init_amos_or_sagem(struct sc_card *card)
554
445
{
555
445
  struct sc_context *ctx = card->ctx;
556
445
  unsigned int flags;
557
445
  int rv = 0;
558
559
445
  LOG_FUNC_CALLED(ctx);
560
561
445
  flags = IASECC_CARD_DEFAULT_FLAGS;
562
563
445
  _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
564
445
  _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
565
566
445
  card->caps = IASECC_CARD_DEFAULT_CAPS;
567
568
445
  if (card->type == SC_CARD_TYPE_IASECC_MI)   {
569
404
    rv = iasecc_mi_match(card);
570
404
    if (rv)
571
28
      card->type = SC_CARD_TYPE_IASECC_MI2;
572
376
    else
573
404
      LOG_FUNC_RETURN(ctx, SC_SUCCESS);
574
404
  }
575
576
69
  rv = iasecc_parse_ef_atr(card);
577
69
  if (rv == SC_ERROR_FILE_NOT_FOUND)   {
578
8
    rv = iasecc_select_mf(card, NULL);
579
8
    LOG_TEST_RET(ctx, rv, "MF selection error");
580
581
5
    rv = iasecc_parse_ef_atr(card);
582
5
  }
583
66
  LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed");
584
585
31
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
586
31
}
587
588
inline static int
589
iasecc_is_cpx(const struct sc_card *card)
590
11.6k
{
591
11.6k
  switch(card->type) {
592
2.44k
    case SC_CARD_TYPE_IASECC_CPX:
593
2.64k
    case SC_CARD_TYPE_IASECC_CPXCL:
594
2.64k
      return 1;
595
8.97k
    default:
596
8.97k
      return 0;
597
11.6k
  }
598
599
0
  return 0;
600
11.6k
}
601
602
static int
603
iasecc_init_cpx(struct sc_card *card)
604
245
{
605
245
  struct sc_context *ctx = card->ctx;
606
245
  unsigned int flags;
607
245
  int rv = 0;
608
609
245
  LOG_FUNC_CALLED(ctx);
610
611
245
  card->caps = IASECC_CARD_DEFAULT_CAPS;
612
613
245
  flags = IASECC_CARD_DEFAULT_FLAGS;
614
615
245
  _sc_card_add_rsa_alg(card, 512, flags, 0);
616
245
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
617
245
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
618
619
245
  rv = iasecc_parse_ef_atr(card);
620
245
  LOG_TEST_RET(ctx, rv, "Parse EF.ATR");
621
622
78
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
623
78
}
624
625
626
static int
627
iasecc_init(struct sc_card *card)
628
754
{
629
754
  struct sc_context *ctx = card->ctx;
630
754
  struct iasecc_private_data *private_data = NULL;
631
754
  int rv = SC_ERROR_NO_CARD_SUPPORT;
632
754
  void *old_drv_data = card->drv_data;
633
634
754
  LOG_FUNC_CALLED(ctx);
635
754
  private_data = (struct iasecc_private_data *) calloc(1, sizeof(struct iasecc_private_data));
636
754
  if (private_data == NULL)
637
754
    LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
638
639
754
  card->cla  = 0x00;
640
754
  card->drv_data = private_data;
641
642
754
  if (card->type == SC_CARD_TYPE_IASECC_GEMALTO)
643
19
    rv = iasecc_init_gemalto(card);
644
735
  else if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)
645
45
    rv = iasecc_init_oberthur(card);
646
690
  else if (card->type == SC_CARD_TYPE_IASECC_SAGEM)
647
28
    rv = iasecc_init_amos_or_sagem(card);
648
662
  else if (card->type == SC_CARD_TYPE_IASECC_AMOS)
649
13
    rv = iasecc_init_amos_or_sagem(card);
650
649
  else if (card->type == SC_CARD_TYPE_IASECC_MI)
651
404
    rv = iasecc_init_amos_or_sagem(card);
652
245
  else if (iasecc_is_cpx(card))
653
245
    rv = iasecc_init_cpx(card);
654
0
  else {
655
0
    LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_CARD, "");
656
0
  }
657
658
659
754
  if (!rv)   {
660
492
    if (card->ef_atr && card->ef_atr->aid.len)   {
661
380
      struct sc_path path;
662
663
380
      memset(&path, 0, sizeof(struct sc_path));
664
380
      path.type = SC_PATH_TYPE_DF_NAME;
665
380
      memcpy(path.value, card->ef_atr->aid.value, card->ef_atr->aid.len);
666
380
      path.len = card->ef_atr->aid.len;
667
668
380
      rv = iasecc_select_file(card, &path, NULL);
669
380
      sc_log(ctx, "Select ECC ROOT with the AID from EF.ATR: rv %i", rv);
670
380
      LOG_TEST_GOTO_ERR(ctx, rv, "Select EF.ATR AID failed");
671
380
    }
672
673
489
    iasecc_get_serialnr(card, NULL);
674
489
  }
675
676
751
#ifdef ENABLE_SM
677
751
  card->sm_ctx.ops.read_binary = _iasecc_sm_read_binary;
678
751
  card->sm_ctx.ops.update_binary = _iasecc_sm_update_binary;
679
751
#endif
680
681
751
  if (!rv && card->ef_atr && card->ef_atr->aid.len)   {
682
377
    sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len));
683
377
  }
684
685
754
err:
686
754
  if (rv < 0) {
687
265
    sc_invalidate_cache(card);
688
265
    free(private_data);
689
265
    card->drv_data = old_drv_data;
690
489
  } else {
691
489
    free(old_drv_data);
692
489
  }
693
694
754
  LOG_FUNC_RETURN(ctx, rv);
695
754
}
696
697
698
static int
699
iasecc_read_binary(struct sc_card *card, unsigned int offs,
700
    unsigned char *buf, size_t count, unsigned long *flags)
701
1.16k
{
702
1.16k
  struct sc_context *ctx = card->ctx;
703
1.16k
  struct sc_apdu apdu;
704
1.16k
  int rv;
705
706
1.16k
  LOG_FUNC_CALLED(ctx);
707
1.16k
  sc_log(ctx,
708
1.16k
         "iasecc_read_binary(card:%p) offs %i; count %"SC_FORMAT_LEN_SIZE_T"u",
709
1.16k
         card, offs, count);
710
1.16k
  if (offs > 0x7fff) {
711
1
    sc_log(ctx, "invalid EF offset: 0x%X > 0x7FFF", offs);
712
1
    return SC_ERROR_OFFSET_TOO_LARGE;
713
1
  }
714
715
1.16k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, (offs >> 8) & 0x7F, offs & 0xFF);
716
1.16k
  apdu.le = count < 0x100 ? count : 0x100;
717
1.16k
  apdu.resplen = count;
718
1.16k
  apdu.resp = buf;
719
720
1.16k
  rv = sc_transmit_apdu(card, &apdu);
721
1.16k
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
722
1.14k
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
723
1.14k
  LOG_TEST_RET(ctx, rv, "iasecc_read_binary() failed");
724
857
  sc_log(ctx,
725
857
         "iasecc_read_binary() apdu.resplen %"SC_FORMAT_LEN_SIZE_T"u",
726
857
         apdu.resplen);
727
728
857
  if (apdu.resplen == IASECC_READ_BINARY_LENGTH_MAX && apdu.resplen < count)   {
729
38
    rv = iasecc_read_binary(card, (int)(offs + apdu.resplen), buf + apdu.resplen, count - apdu.resplen, flags);
730
38
    if (rv != SC_ERROR_WRONG_LENGTH)   {
731
34
      LOG_TEST_RET(ctx, rv, "iasecc_read_binary() read tail failed");
732
15
      apdu.resplen += rv;
733
15
    }
734
38
  }
735
736
838
  LOG_FUNC_RETURN(ctx, (int)apdu.resplen);
737
838
}
738
739
740
static int
741
iasecc_erase_binary(struct sc_card *card, unsigned int offs, size_t count, unsigned long flags)
742
0
{
743
0
  struct sc_context *ctx = card->ctx;
744
0
  unsigned char *tmp = NULL;
745
0
  int rv;
746
747
0
  LOG_FUNC_CALLED(ctx);
748
0
  sc_log(ctx,
749
0
         "iasecc_erase_binary(card:%p) count %"SC_FORMAT_LEN_SIZE_T"u",
750
0
         card, count);
751
0
  if (!count)
752
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "'ERASE BINARY' failed: invalid size to erase");
753
754
0
  tmp = malloc(count);
755
0
  if (!tmp)
756
0
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate temporary buffer");
757
0
  memset(tmp, 0xFF, count);
758
759
0
  rv = sc_update_binary(card, offs, tmp, count, flags);
760
0
  free(tmp);
761
762
0
  LOG_FUNC_RETURN(ctx, rv);
763
0
}
764
765
766
#if ENABLE_SM
767
static int
768
_iasecc_sm_read_binary(struct sc_card *card, unsigned int offs,
769
    unsigned char *buff, size_t count)
770
193
{
771
193
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
772
193
  struct sc_context *ctx = card->ctx;
773
193
  const struct sc_acl_entry *entry = NULL;
774
193
  int rv;
775
776
193
  LOG_FUNC_CALLED(ctx);
777
193
  sc_log(ctx,
778
193
         "iasecc_sm_read_binary() card:%p offs:%i count:%"SC_FORMAT_LEN_SIZE_T"u ",
779
193
         card, offs, count);
780
193
  if (offs > 0x7fff)
781
193
    LOG_TEST_RET(ctx, SC_ERROR_OFFSET_TOO_LARGE, "Invalid arguments");
782
783
193
  if (count == 0)
784
0
    return 0;
785
786
193
  if (prv->cache.valid && prv->cache.current_ef) {
787
185
    entry = sc_file_get_acl_entry(prv->cache.current_ef, SC_AC_OP_READ);
788
185
    if (!entry)
789
185
      LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_sm_read() 'READ' ACL not present");
790
791
172
    sc_log(ctx, "READ method/reference %X/%X", entry->method, entry->key_ref);
792
172
    if ((entry->method == SC_AC_SCB) && (entry->key_ref & IASECC_SCB_METHOD_SM))   {
793
140
      unsigned char se_num = entry->key_ref & IASECC_SCB_METHOD_MASK_REF;
794
795
140
      rv = iasecc_sm_read_binary(card, se_num, offs, buff, count);
796
140
      LOG_FUNC_RETURN(ctx, rv);
797
140
    }
798
172
  }
799
800
40
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
801
40
}
802
803
804
static int
805
_iasecc_sm_update_binary(struct sc_card *card, unsigned int offs,
806
    const unsigned char *buff, size_t count)
807
0
{
808
0
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
809
0
  struct sc_context *ctx = card->ctx;
810
0
  const struct sc_acl_entry *entry = NULL;
811
0
  int rv;
812
813
0
  if (count == 0)
814
0
    return SC_SUCCESS;
815
816
0
  LOG_FUNC_CALLED(ctx);
817
0
  sc_log(ctx,
818
0
      "iasecc_sm_read_binary() card:%p offs:%i count:%" SC_FORMAT_LEN_SIZE_T "u ",
819
0
      card, offs, count);
820
821
0
  if (prv->cache.valid && prv->cache.current_ef) {
822
0
    entry = sc_file_get_acl_entry(prv->cache.current_ef, SC_AC_OP_UPDATE);
823
0
    if (!entry)
824
0
      LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_sm_update() 'UPDATE' ACL not present");
825
826
0
    sc_log(ctx, "UPDATE method/reference %X/%X", entry->method, entry->key_ref);
827
0
    if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM))   {
828
0
      unsigned char se_num = entry->key_ref & IASECC_SCB_METHOD_MASK_REF;
829
830
0
      rv = iasecc_sm_update_binary(card, se_num, offs, buff, count);
831
0
      LOG_FUNC_RETURN(ctx, rv);
832
0
    }
833
0
  }
834
835
0
  LOG_FUNC_RETURN(ctx, 0);
836
0
}
837
#endif
838
839
840
static int
841
iasecc_emulate_fcp(struct sc_context *ctx, struct sc_apdu *apdu)
842
81
{
843
81
  unsigned char dummy_df_fcp[] = {
844
81
    0x62,0xFF,
845
81
      0x82,0x01,0x38,
846
81
      0x8A,0x01,0x05,
847
81
      0xA1,0x04,0x8C,0x02,0x02,0x00,
848
81
      0x84,0xFF,
849
81
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
850
81
        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
851
81
  };
852
853
81
  LOG_FUNC_CALLED(ctx);
854
855
81
  if (apdu->p1 != 0x04)
856
81
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "FCP emulation supported only for the DF-NAME selection type");
857
81
  if (apdu->datalen > 16)
858
81
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid DF-NAME length");
859
81
  if (apdu->resplen < apdu->datalen + 16)
860
81
    LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "not enough space for FCP data");
861
862
81
  memcpy(dummy_df_fcp + 16, apdu->data, apdu->datalen);
863
81
  dummy_df_fcp[15] = apdu->datalen;
864
81
  dummy_df_fcp[1] = apdu->datalen + 14;
865
81
  apdu->resplen = apdu->datalen + 16;
866
81
  memcpy(apdu->resp, dummy_df_fcp, apdu->resplen);
867
868
81
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
869
81
}
870
871
872
/* TODO: redesign using of cache
873
 * TODO: do not keep intermediate results in 'file_out' argument */
874
static int
875
iasecc_select_file(struct sc_card *card, const struct sc_path *path,
876
     struct sc_file **file_out)
877
6.28k
{
878
6.28k
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
879
6.28k
  struct sc_context *ctx = card->ctx;
880
6.28k
  struct sc_path lpath;
881
6.28k
  int rv, ii;
882
883
6.28k
  LOG_FUNC_CALLED(ctx);
884
6.28k
  memcpy(&lpath, path, sizeof(struct sc_path));
885
6.28k
  if (file_out)
886
2.99k
    *file_out = NULL;
887
888
6.28k
  sc_log(ctx,
889
6.28k
         "iasecc_select_file(card:%p) path.len %"SC_FORMAT_LEN_SIZE_T"u; path.type %i; aid_len %"SC_FORMAT_LEN_SIZE_T"u",
890
6.28k
         card, path->len, path->type, path->aid.len);
891
6.28k
  sc_log(ctx, "iasecc_select_file() path:%s", sc_print_path(path));
892
893
6.28k
  if ((!iasecc_is_cpx(card)) &&
894
5.50k
      (card->type != SC_CARD_TYPE_IASECC_GEMALTO) &&
895
5.44k
      (path->type != SC_PATH_TYPE_DF_NAME
896
2.16k
      && lpath.len >= 2
897
2.16k
      && lpath.value[0] == 0x3F && lpath.value[1] == 0x00))   {
898
2.12k
    sc_log(ctx, "EF.ATR(aid:'%s')", card->ef_atr ? sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len) : "");
899
900
2.12k
    rv = iasecc_select_mf(card, file_out);
901
2.12k
    LOG_TEST_RET(ctx, rv, "MF selection error");
902
903
429
    memmove(&lpath.value[0], &lpath.value[2], lpath.len - 2);
904
429
    lpath.len -=  2;
905
429
  }
906
907
4.58k
  if (lpath.aid.len)  {
908
9
    struct sc_file *file = NULL;
909
9
    struct sc_path ppath;
910
911
9
    sc_log(ctx,
912
9
           "iasecc_select_file() select parent AID:%p/%"SC_FORMAT_LEN_SIZE_T"u",
913
9
           lpath.aid.value, lpath.aid.len);
914
9
    sc_log(ctx, "iasecc_select_file() select parent AID:%s", sc_dump_hex(lpath.aid.value, lpath.aid.len));
915
9
    memset(&ppath, 0, sizeof(ppath));
916
9
    memcpy(ppath.value, lpath.aid.value, lpath.aid.len);
917
9
    ppath.len = lpath.aid.len;
918
9
    ppath.type = SC_PATH_TYPE_DF_NAME;
919
920
9
    rv = iasecc_select_file(card, &ppath, &file);
921
9
    LOG_TEST_GOTO_ERR(ctx, rv, "select AID path failed");
922
923
5
    if (file_out) {
924
5
      sc_file_free(*file_out);
925
5
      *file_out = file;
926
5
    } else {
927
0
      sc_file_free(file);
928
0
    }
929
930
5
    if (lpath.type == SC_PATH_TYPE_DF_NAME)
931
0
      lpath.type = SC_PATH_TYPE_FROM_CURRENT;
932
5
  }
933
934
4.58k
  if (lpath.type == SC_PATH_TYPE_PATH)
935
1.12k
    lpath.type = SC_PATH_TYPE_FROM_CURRENT;
936
937
4.58k
  if (!lpath.len) {
938
7
    if (file_out) {
939
3
      sc_file_free(*file_out);
940
3
      *file_out = NULL;
941
3
    }
942
7
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
943
7
  }
944
945
4.57k
  do   {
946
4.57k
    struct sc_apdu apdu;
947
4.57k
    struct sc_file *file = NULL;
948
4.57k
    unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
949
4.57k
    size_t pathlen = lpath.len;
950
951
4.57k
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00);
952
953
4.57k
    if (card->type != SC_CARD_TYPE_IASECC_GEMALTO
954
4.51k
        && card->type != SC_CARD_TYPE_IASECC_OBERTHUR
955
4.40k
        && card->type != SC_CARD_TYPE_IASECC_SAGEM
956
4.34k
        && card->type != SC_CARD_TYPE_IASECC_AMOS
957
4.29k
        && card->type != SC_CARD_TYPE_IASECC_MI
958
828
        && card->type != SC_CARD_TYPE_IASECC_MI2
959
776
        && !iasecc_is_cpx(card)) {
960
0
      rv = SC_ERROR_NOT_SUPPORTED;
961
0
      LOG_TEST_GOTO_ERR(ctx, rv, "Unsupported card");
962
0
    }
963
964
4.57k
    if (lpath.type == SC_PATH_TYPE_FILE_ID)   {
965
3
      apdu.p1 = 0x02;
966
3
      if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)
967
0
        apdu.p1 = 0x01;
968
3
      if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
969
3
          card->type == SC_CARD_TYPE_IASECC_AMOS ||
970
3
          card->type == SC_CARD_TYPE_IASECC_MI ||
971
3
          card->type == SC_CARD_TYPE_IASECC_MI2 ||
972
3
          card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
973
3
          iasecc_is_cpx(card)
974
3
          )   {
975
3
        apdu.p2 = 0x04;
976
3
      }
977
3
    }
978
4.57k
    else if (lpath.type == SC_PATH_TYPE_FROM_CURRENT)  {
979
1.12k
      apdu.p1 = 0x09;
980
1.12k
      if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
981
1.07k
          card->type == SC_CARD_TYPE_IASECC_AMOS ||
982
1.04k
          card->type == SC_CARD_TYPE_IASECC_MI ||
983
718
          card->type == SC_CARD_TYPE_IASECC_MI2 ||
984
695
          card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
985
1.08k
          iasecc_is_cpx(card)) {
986
1.08k
        apdu.p2 = 0x04;
987
1.08k
      }
988
1.12k
    }
989
3.45k
    else if (lpath.type == SC_PATH_TYPE_PARENT)   {
990
0
      apdu.p1 = 0x03;
991
0
      pathlen = 0;
992
0
      apdu.cse = SC_APDU_CASE_2_SHORT;
993
0
    }
994
3.45k
    else if (lpath.type == SC_PATH_TYPE_DF_NAME)   {
995
3.45k
      apdu.p1 = 0x04;
996
3.45k
      if (card->type == SC_CARD_TYPE_IASECC_AMOS ||
997
3.43k
          card->type == SC_CARD_TYPE_IASECC_MI2 ||
998
3.40k
          card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
999
3.33k
          card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
1000
3.33k
          iasecc_is_cpx(card)) {
1001
285
        apdu.p2 = 0x04;
1002
285
      }
1003
3.45k
    }
1004
0
    else   {
1005
0
      sc_log(ctx, "Invalid PATH type: 0x%X", lpath.type);
1006
0
      rv = SC_ERROR_NOT_SUPPORTED;
1007
0
      LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_select_file() invalid PATH type");
1008
0
    }
1009
1010
4.65k
    for (ii=0; ii<2; ii++)   {
1011
4.65k
      apdu.lc = pathlen;
1012
4.65k
      apdu.data = lpath.value;
1013
4.65k
      apdu.datalen = pathlen;
1014
1015
4.65k
      apdu.resp = rbuf;
1016
4.65k
      apdu.resplen = sizeof(rbuf);
1017
4.65k
      apdu.le = 256;
1018
1019
4.65k
      rv = sc_transmit_apdu(card, &apdu);
1020
4.65k
      LOG_TEST_GOTO_ERR(ctx, rv, "APDU transmit failed");
1021
4.63k
      rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1022
4.63k
      if (rv == SC_ERROR_INCORRECT_PARAMETERS &&
1023
119
          lpath.type == SC_PATH_TYPE_DF_NAME && apdu.p2 == 0x00)   {
1024
81
        sc_log(ctx, "Warning: SC_ERROR_INCORRECT_PARAMETERS for SC_PATH_TYPE_DF_NAME, try again with P2=0x0C");
1025
81
        apdu.p2 = 0x0C;
1026
81
        continue;
1027
81
      }
1028
1029
4.55k
      if (ii)   {
1030
        /* 'SELECT AID' do not returned FCP. Try to emulate. */
1031
81
        apdu.resplen = sizeof(rbuf);
1032
81
        rv = iasecc_emulate_fcp(ctx, &apdu);
1033
81
        LOG_TEST_GOTO_ERR(ctx, rv, "Failed to emulate DF FCP");
1034
81
      }
1035
1036
4.55k
      break;
1037
4.55k
    }
1038
1039
4.55k
    LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_select_file() check SW failed");
1040
1041
1.90k
    sc_log(ctx,
1042
1.90k
           "iasecc_select_file() apdu.resp %"SC_FORMAT_LEN_SIZE_T"u",
1043
1.90k
           apdu.resplen);
1044
1.90k
    if (apdu.resplen)   {
1045
845
      sc_log(ctx, "apdu.resp %02X:%02X:%02X...", apdu.resp[0], apdu.resp[1], apdu.resp[2]);
1046
1047
845
      switch (apdu.resp[0]) {
1048
99
      case 0x62:
1049
796
      case 0x6F:
1050
796
        file = sc_file_new();
1051
796
        if (file == NULL) {
1052
0
          if (file_out) {
1053
0
            sc_file_free(*file_out);
1054
0
            *file_out = NULL;
1055
0
          }
1056
0
          LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1057
0
        }
1058
796
        file->path = lpath;
1059
1060
796
        rv = iasecc_process_fci(card, file, apdu.resp, apdu.resplen);
1061
796
        if (rv) {
1062
78
          sc_file_free(file);
1063
78
          if (file_out) {
1064
51
            sc_file_free(*file_out);
1065
51
            *file_out = NULL;
1066
51
          }
1067
78
          LOG_FUNC_RETURN(ctx, rv);
1068
78
        }
1069
718
        break;
1070
718
      default:
1071
49
        if (file_out) {
1072
19
          sc_file_free(*file_out);
1073
19
          *file_out = NULL;
1074
19
        }
1075
49
        LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1076
845
      }
1077
1078
718
      sc_log(ctx, "FileType %i", file->type);
1079
718
      if (file->type == SC_FILE_TYPE_DF)   {
1080
89
        sc_invalidate_cache(card);
1081
89
        sc_file_dup(&prv->cache.current_df, file);
1082
89
        prv->cache.valid = 1;
1083
89
      }
1084
629
      else   {
1085
629
        sc_file_free(prv->cache.current_ef);
1086
629
        sc_file_dup(&prv->cache.current_ef, file);
1087
629
        prv->cache.valid = 1;
1088
629
      }
1089
1090
718
      if (file_out)   {
1091
572
        sc_file_free(*file_out);
1092
572
        *file_out = file;
1093
572
      }
1094
146
      else   {
1095
146
        sc_file_free(file);
1096
146
      }
1097
718
    }
1098
1.05k
    else if (lpath.type == SC_PATH_TYPE_DF_NAME)   {
1099
956
      sc_invalidate_cache(card);
1100
956
      prv->cache.valid = 1;
1101
956
    }
1102
1.90k
  } while(0);
1103
1104
1.77k
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1105
2.68k
err:
1106
2.68k
  if (file_out) {
1107
1.15k
    sc_file_free(*file_out);
1108
1.15k
    *file_out = NULL;
1109
1.15k
  }
1110
2.68k
  return rv;
1111
1.77k
}
1112
1113
1114
static int
1115
iasecc_process_fci(struct sc_card *card, struct sc_file *file,
1116
     const unsigned char *buf, size_t buflen)
1117
796
{
1118
796
  struct sc_context *ctx = card->ctx;
1119
796
  size_t taglen, offs, ii;
1120
796
  int rv;
1121
796
  const unsigned char *acls = NULL, *tag = NULL;
1122
796
  unsigned char mask;
1123
796
  unsigned char ops_DF[7] = {
1124
796
    SC_AC_OP_DELETE, 0xFF, SC_AC_OP_ACTIVATE, SC_AC_OP_DEACTIVATE, 0xFF, SC_AC_OP_CREATE, 0xFF
1125
796
  };
1126
796
  unsigned char ops_EF[7] = {
1127
796
    SC_AC_OP_DELETE, 0xFF, SC_AC_OP_ACTIVATE, SC_AC_OP_DEACTIVATE, 0xFF, SC_AC_OP_UPDATE, SC_AC_OP_READ
1128
796
  };
1129
1130
796
  LOG_FUNC_CALLED(ctx);
1131
1132
796
  tag = sc_asn1_find_tag(ctx,  buf, buflen, 0x6F, &taglen);
1133
796
  sc_log(ctx, "processing FCI: 0x6F tag %p", tag);
1134
796
  if (tag != NULL) {
1135
675
    sc_log(ctx, "  FCP length %"SC_FORMAT_LEN_SIZE_T"u", taglen);
1136
675
    buf = tag;
1137
675
    buflen = taglen;
1138
675
  }
1139
1140
796
  tag = sc_asn1_find_tag(ctx,  buf, buflen, 0x62, &taglen);
1141
796
  sc_log(ctx, "processing FCI: 0x62 tag %p", tag);
1142
796
  if (tag != NULL) {
1143
87
    sc_log(ctx, "  FCP length %"SC_FORMAT_LEN_SIZE_T"u", taglen);
1144
87
    buf = tag;
1145
87
    buflen = taglen;
1146
87
  }
1147
1148
796
  rv = iso_ops->process_fci(card, file, buf, buflen);
1149
796
  LOG_TEST_RET(ctx, rv, "ISO parse FCI failed");
1150
/*
1151
  Gemalto:  6F 19 80 02 02 ED 82 01 01 83 02 B0 01 88 00  8C 07 7B 17 17 17 17 17 00 8A 01 05 90 00
1152
  Sagem:    6F 17 62 15 80 02 00 7D 82 01 01                   8C 02 01 00 83 02 2F 00 88 01 F0 8A 01 05 90 00
1153
  Oberthur: 62 1B 80 02 05 DC 82 01 01 83 02 B0 01 88 00 A1 09 8C 07 7B 17 FF 17 17 17 00 8A 01 05 90 00
1154
*/
1155
1156
796
  sc_log(ctx, "iasecc_process_fci() type %i; let's parse file ACLs", file->type);
1157
796
  tag = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS, &taglen);
1158
796
  if (tag)
1159
82
    acls = sc_asn1_find_tag(ctx, tag, taglen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen);
1160
714
  else
1161
714
    acls = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen);
1162
1163
796
  if (!acls)   {
1164
78
    sc_log(ctx,
1165
78
           "ACLs not found in data(%"SC_FORMAT_LEN_SIZE_T"u) %s",
1166
78
           buflen, sc_dump_hex(buf, buflen));
1167
78
    LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "ACLs tag missing");
1168
78
  }
1169
1170
718
  sc_log(ctx, "ACLs(%"SC_FORMAT_LEN_SIZE_T"u) '%s'", taglen,
1171
718
         sc_dump_hex(acls, taglen));
1172
718
  mask = 0x40, offs = 1;
1173
4.34k
  for (ii = 0; ii < 7; ii++, mask /= 2)  {
1174
3.92k
    unsigned char op = file->type == SC_FILE_TYPE_DF ? ops_DF[ii] : ops_EF[ii];
1175
1176
    /* avoid any access to acls[offs] beyond the taglen */
1177
3.92k
    if (offs >= taglen) {
1178
300
      sc_log(ctx, "Warning: Invalid offset reached during ACL parsing");
1179
300
      break;
1180
300
    }
1181
3.62k
    if (!(mask & acls[0]))
1182
1.42k
      continue;
1183
1184
2.19k
    sc_log(ctx, "ACLs mask 0x%X, offs %"SC_FORMAT_LEN_SIZE_T"u, op 0x%X, acls[offs] 0x%X", mask, offs, op, acls[offs]);
1185
2.19k
    if (op == 0xFF)   {
1186
587
      ;
1187
587
    }
1188
1.61k
    else if (acls[offs] == 0)   {
1189
487
      sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);
1190
487
    }
1191
1.12k
    else if (acls[offs] == 0xFF)   {
1192
137
      sc_file_add_acl_entry(file, op, SC_AC_NEVER, 0);
1193
137
    }
1194
987
    else if ((acls[offs] & IASECC_SCB_METHOD_MASK) == IASECC_SCB_METHOD_USER_AUTH)   {
1195
134
      sc_file_add_acl_entry(file, op, SC_AC_SEN, acls[offs] & IASECC_SCB_METHOD_MASK_REF);
1196
134
    }
1197
853
    else if (acls[offs] & IASECC_SCB_METHOD_MASK)   {
1198
628
      sc_file_add_acl_entry(file, op, SC_AC_SCB, acls[offs]);
1199
628
    }
1200
225
    else   {
1201
225
      sc_log(ctx, "Warning: non supported SCB method: %X", acls[offs]);
1202
225
      sc_file_add_acl_entry(file, op, SC_AC_NEVER, 0);
1203
225
    }
1204
1205
2.19k
    offs++;
1206
2.19k
  }
1207
1208
718
  LOG_FUNC_RETURN(ctx, 0);
1209
718
}
1210
1211
1212
static int
1213
iasecc_fcp_encode(struct sc_card *card, struct sc_file *file, unsigned char *out, size_t out_len)
1214
0
{
1215
0
  struct sc_context *ctx = card->ctx;
1216
0
  unsigned char buf[0x80], type;
1217
0
  unsigned char  ops[7] = {
1218
0
    SC_AC_OP_DELETE, 0xFF, SC_AC_OP_ACTIVATE, SC_AC_OP_DEACTIVATE, 0xFF, SC_AC_OP_UPDATE, SC_AC_OP_READ
1219
0
  };
1220
0
  unsigned char smbs[8];
1221
0
  size_t ii, amb, offs = 0, mask, nn_smb;
1222
1223
0
  LOG_FUNC_CALLED(ctx);
1224
1225
0
  if (file->type == SC_FILE_TYPE_DF)
1226
0
    type = IASECC_FCP_TYPE_DF;
1227
0
  else
1228
0
    type = IASECC_FCP_TYPE_EF;
1229
1230
0
  buf[offs++] = IASECC_FCP_TAG_SIZE;
1231
0
  buf[offs++] = 2;
1232
0
  buf[offs++] = (file->size >> 8) & 0xFF;
1233
0
  buf[offs++] = file->size & 0xFF;
1234
1235
0
  buf[offs++] = IASECC_FCP_TAG_TYPE;
1236
0
  buf[offs++] = 1;
1237
0
  buf[offs++] = type;
1238
1239
0
  buf[offs++] = IASECC_FCP_TAG_FID;
1240
0
  buf[offs++] = 2;
1241
0
  buf[offs++] = (file->id >> 8) & 0xFF;
1242
0
  buf[offs++] = file->id & 0xFF;
1243
1244
0
  buf[offs++] = IASECC_FCP_TAG_SFID;
1245
0
  buf[offs++] = 0;
1246
1247
0
  amb = 0, mask = 0x40, nn_smb = 0;
1248
0
  for (ii = 0; ii < sizeof(ops); ii++, mask >>= 1) {
1249
0
    const struct sc_acl_entry *entry;
1250
1251
0
    if (ops[ii]==0xFF)
1252
0
      continue;
1253
1254
0
    entry = sc_file_get_acl_entry(file, ops[ii]);
1255
0
    if (!entry)
1256
0
      continue;
1257
1258
0
    sc_log(ctx, "method %X; reference %X", entry->method, entry->key_ref);
1259
0
    if (entry->method == SC_AC_NEVER)
1260
0
      continue;
1261
0
    else if (entry->method == SC_AC_NONE)
1262
0
      smbs[nn_smb++] = 0x00;
1263
0
    else if (entry->method == SC_AC_CHV)
1264
0
      smbs[nn_smb++] = entry->key_ref | IASECC_SCB_METHOD_USER_AUTH;
1265
0
    else if (entry->method == SC_AC_SEN)
1266
0
      smbs[nn_smb++] = entry->key_ref | IASECC_SCB_METHOD_USER_AUTH;
1267
0
    else if (entry->method == SC_AC_SCB)
1268
0
      smbs[nn_smb++] = entry->key_ref;
1269
0
    else if (entry->method == SC_AC_PRO)
1270
0
      smbs[nn_smb++] = entry->key_ref | IASECC_SCB_METHOD_SM;
1271
0
    else
1272
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Non supported AC method");
1273
1274
0
    amb |= mask;
1275
0
    sc_log(ctx,
1276
0
           "%"SC_FORMAT_LEN_SIZE_T"u: AMB %"SC_FORMAT_LEN_SIZE_T"X; nn_smb %"SC_FORMAT_LEN_SIZE_T"u",
1277
0
           ii, amb, nn_smb);
1278
0
  }
1279
1280
  /* TODO: Encode contactless ACLs and life cycle status for all IAS/ECC cards */
1281
0
  if (card->type == SC_CARD_TYPE_IASECC_SAGEM ||
1282
0
      card->type == SC_CARD_TYPE_IASECC_AMOS )  {
1283
0
    unsigned char status = 0;
1284
1285
0
    buf[offs++] = IASECC_FCP_TAG_ACLS;
1286
0
    buf[offs++] = 2*(2 + 1 + nn_smb);
1287
1288
0
    buf[offs++] = IASECC_FCP_TAG_ACLS_CONTACT;
1289
0
    buf[offs++] = nn_smb + 1;
1290
0
    buf[offs++] = amb;
1291
0
    memcpy(buf + offs, smbs, nn_smb);
1292
0
    offs += nn_smb;
1293
1294
    /* Same ACLs for contactless */
1295
0
    buf[offs++] = IASECC_FCP_TAG_ACLS_CONTACTLESS;
1296
0
    buf[offs++] = nn_smb + 1;
1297
0
    buf[offs++] = amb;
1298
0
    memcpy(buf + offs, smbs, nn_smb);
1299
0
    offs += nn_smb;
1300
1301
0
    if (file->status == SC_FILE_STATUS_ACTIVATED)
1302
0
      status = 0x05;
1303
0
    else if (file->status == SC_FILE_STATUS_CREATION)
1304
0
      status = 0x01;
1305
1306
0
    if (status)   {
1307
0
      buf[offs++] = 0x8A;
1308
0
      buf[offs++] = 0x01;
1309
0
      buf[offs++] = status;
1310
0
    }
1311
0
  }
1312
0
  else   {
1313
0
    buf[offs++] = IASECC_FCP_TAG_ACLS;
1314
0
    buf[offs++] = 2 + 1 + nn_smb;
1315
1316
0
    buf[offs++] = IASECC_FCP_TAG_ACLS_CONTACT;
1317
0
    buf[offs++] = nn_smb + 1;
1318
0
    buf[offs++] = amb;
1319
0
    memcpy(buf + offs, smbs, nn_smb);
1320
0
    offs += nn_smb;
1321
0
  }
1322
1323
0
  if (out)   {
1324
0
    if (out_len < offs)
1325
0
      LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to encode FCP");
1326
0
    memcpy(out, buf, offs);
1327
0
  }
1328
1329
0
  LOG_FUNC_RETURN(ctx, (int)offs);
1330
0
}
1331
1332
1333
static int
1334
iasecc_create_file(struct sc_card *card, struct sc_file *file)
1335
0
{
1336
0
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
1337
0
  struct sc_context *ctx = card->ctx;
1338
0
  struct sc_apdu apdu;
1339
0
  const struct sc_acl_entry *entry = NULL;
1340
0
  unsigned char sbuf[0x100];
1341
0
  size_t sbuf_len;
1342
0
  int rv;
1343
1344
0
  LOG_FUNC_CALLED(ctx);
1345
1346
0
  if (file->type != SC_FILE_TYPE_WORKING_EF)
1347
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Creation of the file with of this type is not supported");
1348
1349
0
  rv = iasecc_fcp_encode(card, file, sbuf + 2, sizeof(sbuf)-2);
1350
0
  LOG_TEST_RET(ctx, rv, "FCP encode error");
1351
0
  sbuf_len = rv;
1352
1353
0
  sbuf[0] = IASECC_FCP_TAG;
1354
0
  sbuf[1] = sbuf_len;
1355
1356
0
  if (prv->cache.valid && prv->cache.current_df) {
1357
0
    entry = sc_file_get_acl_entry(prv->cache.current_df, SC_AC_OP_CREATE);
1358
0
    if (!entry)
1359
0
      LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_create_file() 'CREATE' ACL not present");
1360
1361
0
    sc_log(ctx, "iasecc_create_file() 'CREATE' method/reference %X/%X", entry->method, entry->key_ref);
1362
0
    sc_log(ctx, "iasecc_create_file() create data: '%s'", sc_dump_hex(sbuf, sbuf_len + 2));
1363
0
    if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM))   {
1364
0
                        rv = iasecc_sm_create_file(card, entry->key_ref & IASECC_SCB_METHOD_MASK_REF, sbuf, sbuf_len + 2);
1365
0
                        LOG_TEST_RET(ctx, rv, "iasecc_create_file() SM create file error");
1366
1367
0
                        rv = iasecc_select_file(card, &file->path, NULL);
1368
0
                        LOG_FUNC_RETURN(ctx, rv);
1369
1370
0
    }
1371
0
  }
1372
1373
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0, 0);
1374
0
  apdu.data = sbuf;
1375
0
  apdu.datalen = sbuf_len + 2;
1376
0
  apdu.lc = sbuf_len + 2;
1377
1378
0
  rv = sc_transmit_apdu(card, &apdu);
1379
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1380
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1381
0
  LOG_TEST_RET(ctx, rv, "iasecc_create_file() create file error");
1382
1383
0
  rv = iasecc_select_file(card, &file->path, NULL);
1384
0
  LOG_TEST_RET(ctx, rv, "Cannot select newly created file");
1385
1386
0
  LOG_FUNC_RETURN(ctx, rv);
1387
0
}
1388
1389
static int
1390
iasecc_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
1391
0
{
1392
  /* As IAS/ECC cannot handle other data length than 0x08 */
1393
0
  u8 rbuf[8];
1394
0
  size_t out_len;
1395
0
  int r;
1396
1397
0
  LOG_FUNC_CALLED(card->ctx);
1398
1399
0
  r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
1400
0
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");
1401
1402
0
  if (len < (size_t) r) {
1403
0
    out_len = len;
1404
0
  } else {
1405
0
    out_len = (size_t) r;
1406
0
  }
1407
0
  memcpy(rnd, rbuf, out_len);
1408
1409
0
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
1410
0
}
1411
1412
1413
static int
1414
iasecc_logout(struct sc_card *card)
1415
0
{
1416
0
  struct sc_context *ctx = card->ctx;
1417
0
  struct sc_path path;
1418
0
  int rv;
1419
1420
0
  LOG_FUNC_CALLED(ctx);
1421
0
  if (!card->ef_atr || !card->ef_atr->aid.len)
1422
0
    return SC_SUCCESS;
1423
1424
0
  memset(&path, 0, sizeof(struct sc_path));
1425
0
  path.type = SC_PATH_TYPE_DF_NAME;
1426
0
  memcpy(path.value, card->ef_atr->aid.value, card->ef_atr->aid.len);
1427
0
  path.len = card->ef_atr->aid.len;
1428
1429
0
  rv = iasecc_select_file(card, &path, NULL);
1430
0
  sc_log(ctx, "Select ECC ROOT with the AID from EF.ATR: rv %i", rv);
1431
1432
0
  LOG_FUNC_RETURN(ctx, rv);
1433
0
}
1434
1435
1436
static int
1437
iasecc_finish(struct sc_card *card)
1438
489
{
1439
489
  struct sc_context *ctx = card->ctx;
1440
489
  struct iasecc_private_data *private_data = (struct iasecc_private_data *)card->drv_data;
1441
489
  struct iasecc_se_info *se_info = private_data->se_info, *next;
1442
1443
489
  LOG_FUNC_CALLED(ctx);
1444
1445
489
  sc_invalidate_cache(card);
1446
1447
500
  while (se_info)   {
1448
11
    sc_file_free(se_info->df);
1449
11
    next = se_info->next;
1450
11
    free(se_info);
1451
11
    se_info = next;
1452
11
  }
1453
1454
489
  free(card->drv_data);
1455
489
  card->drv_data = NULL;
1456
1457
489
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1458
489
}
1459
1460
1461
static int
1462
iasecc_delete_file(struct sc_card *card, const struct sc_path *path)
1463
0
{
1464
0
  struct sc_context *ctx = card->ctx;
1465
0
  const struct sc_acl_entry *entry = NULL;
1466
0
  struct sc_apdu apdu;
1467
0
  struct sc_file *file = NULL;
1468
0
  int rv;
1469
1470
0
  LOG_FUNC_CALLED(ctx);
1471
1472
0
  rv = iasecc_select_file(card, path, &file);
1473
0
  if (rv == SC_ERROR_FILE_NOT_FOUND)
1474
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1475
0
  LOG_TEST_RET(ctx, rv, "Cannot select file to delete");
1476
1477
0
  entry = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
1478
0
  if (!entry) {
1479
0
    sc_file_free(file);
1480
0
    LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Cannot delete file: no 'DELETE' acl");
1481
0
  }
1482
1483
0
  sc_log(ctx, "DELETE method/reference %X/%X", entry->method, entry->key_ref);
1484
0
  if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM))   {
1485
0
    unsigned char se_num = entry->key_ref & IASECC_SCB_METHOD_MASK_REF;
1486
0
    rv = iasecc_sm_delete_file(card, se_num, file->id);
1487
0
    sc_file_free(file);
1488
0
  }
1489
0
  else   {
1490
0
    struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
1491
0
    sc_file_free(file);
1492
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00);
1493
1494
0
    rv = sc_transmit_apdu(card, &apdu);
1495
0
    LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1496
0
    rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1497
0
    LOG_TEST_RET(ctx, rv, "Delete file failed");
1498
1499
0
    if (prv->cache.valid) {
1500
0
      sc_file_free(prv->cache.current_ef);
1501
0
    }
1502
0
    prv->cache.current_ef = NULL;
1503
0
  }
1504
1505
0
  LOG_FUNC_RETURN(ctx, rv);
1506
0
}
1507
1508
1509
static int
1510
iasecc_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
1511
7.92k
{
1512
7.92k
  if (sw1 == 0x62 && sw2 == 0x82)
1513
253
    return SC_SUCCESS;
1514
1515
7.67k
  return iso_ops->check_sw(card, sw1, sw2);
1516
7.92k
}
1517
1518
1519
static unsigned
1520
iasecc_get_algorithm(struct sc_context *ctx, const struct sc_security_env *env,
1521
    unsigned operation, unsigned mechanism)
1522
0
{
1523
0
    const struct sc_supported_algo_info *info = NULL;
1524
0
    int ii;
1525
1526
0
    if (!env)
1527
0
        return 0;
1528
1529
0
    for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && env->supported_algos[ii].reference; ii++)
1530
0
        if ((env->supported_algos[ii].operations & operation)
1531
0
      && (env->supported_algos[ii].mechanism == mechanism))
1532
0
            break;
1533
1534
0
    if (ii < SC_MAX_SUPPORTED_ALGORITHMS && env->supported_algos[ii].reference)   {
1535
0
        info = &env->supported_algos[ii];
1536
0
        sc_log(ctx, "found IAS/ECC algorithm %X:%X:%X:%X",
1537
0
      info->reference, info->mechanism, info->operations, info->algo_ref);
1538
0
    }
1539
0
    else   {
1540
0
        sc_log(ctx, "cannot find IAS/ECC algorithm (operation:%X,mechanism:%X)", operation, mechanism);
1541
0
    }
1542
1543
0
    return info ? info->algo_ref : 0;
1544
0
}
1545
1546
1547
static int
1548
iasecc_se_cache_info(struct sc_card *card, struct iasecc_se_info *se)
1549
11
{
1550
11
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
1551
11
  struct sc_context *ctx = card->ctx;
1552
11
  struct iasecc_se_info *se_info = NULL, *si = NULL;
1553
11
  int rv;
1554
1555
11
  LOG_FUNC_CALLED(ctx);
1556
1557
11
  se_info = calloc(1, sizeof(struct iasecc_se_info));
1558
11
  if (!se_info)
1559
11
    LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SE info allocation error");
1560
11
  memcpy(se_info, se, sizeof(struct iasecc_se_info));
1561
1562
11
  if (prv->cache.valid && prv->cache.current_df) {
1563
10
    sc_file_dup(&se_info->df, prv->cache.current_df);
1564
10
    if (se_info->df == NULL)   {
1565
0
      free(se_info);
1566
0
      LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file");
1567
0
    }
1568
10
  }
1569
1570
11
  rv = iasecc_docp_copy(ctx, &se->docp, &se_info->docp);
1571
11
  if (rv < 0)   {
1572
0
    free(se_info->df);
1573
0
    free(se_info);
1574
0
    LOG_TEST_RET(ctx, rv, "Cannot make copy of DOCP");
1575
0
  }
1576
1577
11
  if (!prv->se_info)   {
1578
11
    prv->se_info = se_info;
1579
11
  }
1580
0
  else    {
1581
0
    for (si = prv->se_info; si->next; si = si->next)
1582
0
      ;
1583
0
    si->next = se_info;
1584
0
  }
1585
1586
11
  LOG_FUNC_RETURN(ctx, rv);
1587
11
}
1588
1589
1590
static int
1591
iasecc_se_get_info_from_cache(struct sc_card *card, struct iasecc_se_info *se)
1592
128
{
1593
128
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
1594
128
  struct sc_context *ctx = card->ctx;
1595
128
  struct iasecc_se_info *si = NULL;
1596
128
  int rv;
1597
1598
128
  LOG_FUNC_CALLED(ctx);
1599
1600
128
  for(si = prv->se_info; si; si = si->next)   {
1601
0
    if (si->reference != se->reference)
1602
0
      continue;
1603
0
    if (!(prv->cache.valid && prv->cache.current_df) && si->df)
1604
0
      continue;
1605
0
    if (prv->cache.valid && prv->cache.current_df && !si->df)
1606
0
      continue;
1607
0
    if (prv->cache.valid && prv->cache.current_df && si->df)
1608
0
      if (memcmp(&prv->cache.current_df->path, &si->df->path, sizeof(struct sc_path)))
1609
0
        continue;
1610
0
    break;
1611
0
  }
1612
1613
128
  if (!si)
1614
128
    return SC_ERROR_OBJECT_NOT_FOUND;
1615
1616
0
  memcpy(se, si, sizeof(struct iasecc_se_info));
1617
1618
0
  if (si->df)   {
1619
0
    sc_file_dup(&se->df, si->df);
1620
0
    if (se->df == NULL)
1621
0
      LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file");
1622
0
  }
1623
1624
0
  rv = iasecc_docp_copy(ctx, &si->docp, &se->docp);
1625
0
  LOG_TEST_RET(ctx, rv, "Cannot make copy of DOCP");
1626
1627
0
  LOG_FUNC_RETURN(ctx, rv);
1628
0
}
1629
1630
1631
int
1632
iasecc_se_get_info(struct sc_card *card, struct iasecc_se_info *se)
1633
140
{
1634
140
  struct sc_context *ctx = card->ctx;
1635
140
  struct sc_apdu apdu;
1636
140
  unsigned char rbuf[0x100];
1637
140
  unsigned char sbuf_iasecc[10] = {
1638
140
    0x4D, 0x08, IASECC_SDO_TEMPLATE_TAG, 0x06,
1639
140
    IASECC_SDO_TAG_HEADER, IASECC_SDO_CLASS_SE | IASECC_OBJECT_REF_LOCAL,
1640
140
    se->reference & 0x3F,
1641
140
    0x02, IASECC_SDO_CLASS_SE, 0x80
1642
140
  };
1643
140
  int rv;
1644
1645
140
  LOG_FUNC_CALLED(ctx);
1646
1647
140
  if (iasecc_is_cpx(card)) {
1648
60
    rv = iasecc_select_mf(card, NULL);
1649
60
    LOG_TEST_RET(ctx, rv, "MF invalid");
1650
60
  }
1651
1652
128
  if (se->reference > IASECC_SE_REF_MAX)
1653
128
                LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1654
1655
128
  rv = iasecc_se_get_info_from_cache(card, se);
1656
128
  if (rv == SC_ERROR_OBJECT_NOT_FOUND)   {
1657
128
    sc_log(ctx, "No SE#%X info in cache, try to use 'GET DATA'", se->reference);
1658
1659
128
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF);
1660
128
    apdu.data = sbuf_iasecc;
1661
128
    apdu.datalen = sizeof(sbuf_iasecc);
1662
128
    apdu.lc = apdu.datalen;
1663
128
    apdu.resp = rbuf;
1664
128
    apdu.resplen = sizeof(rbuf);
1665
128
    apdu.le = sizeof(rbuf);
1666
1667
128
    rv = sc_transmit_apdu(card, &apdu);
1668
128
    LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1669
122
    rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1670
122
    LOG_TEST_RET(ctx, rv, "get SE data  error");
1671
1672
99
    rv = iasecc_se_parse(card, apdu.resp, apdu.resplen, se);
1673
99
    LOG_TEST_RET(ctx, rv, "cannot parse SE data");
1674
1675
11
    rv = iasecc_se_cache_info(card, se);
1676
11
    LOG_TEST_RET(ctx, rv, "failed to put SE data into cache");
1677
11
  }
1678
1679
11
  LOG_FUNC_RETURN(ctx, rv);
1680
11
}
1681
1682
1683
static int
1684
iasecc_set_security_env(struct sc_card *card,
1685
    const struct sc_security_env *env, int se_num)
1686
0
{
1687
0
  struct sc_context *ctx = card->ctx;
1688
0
  struct iasecc_sdo sdo;
1689
0
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
1690
0
  unsigned algo_ref;
1691
0
  struct sc_apdu apdu;
1692
0
  unsigned sign_meth, sign_ref, auth_meth, auth_ref;
1693
0
  unsigned long aflags;
1694
0
  unsigned char cse_crt_at[] = {
1695
0
    0x84, 0x01, 0xFF,
1696
0
    0x80, 0x01, IASECC_ALGORITHM_RSA_PKCS
1697
0
  };
1698
0
  unsigned char cse_crt_dst[] = {
1699
0
    0x84, 0x01, 0xFF,
1700
0
    0x80, 0x01, (IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA1)
1701
0
  };
1702
0
  unsigned char cse_crt_ht[] = {
1703
0
    0x80, 0x01, IASECC_ALGORITHM_SHA1
1704
0
  };
1705
0
  unsigned char cse_crt_ct[] = {
1706
0
    0x84, 0x01, 0xFF,
1707
0
    0x80, 0x01, (IASECC_ALGORITHM_RSA_PKCS_DECRYPT | IASECC_ALGORITHM_SHA1)
1708
0
  };
1709
0
  int rv, operation = env->operation;
1710
1711
  /* TODO: take algorithm references from 5032, not from header file. */
1712
0
  LOG_FUNC_CALLED(ctx);
1713
0
  sc_log(ctx, "iasecc_set_security_env(card:%p) operation 0x%X; senv.algorithm 0x%lX, senv.algorithm_ref 0x%lX",
1714
0
      card, env->operation, env->algorithm, env->algorithm_ref);
1715
1716
0
  memset(&sdo, 0, sizeof(sdo));
1717
0
  sdo.sdo_class = IASECC_SDO_CLASS_RSA_PRIVATE;
1718
0
  sdo.sdo_ref  = env->key_ref[0] & ~IASECC_OBJECT_REF_LOCAL;
1719
0
  rv = iasecc_sdo_get_data(card, &sdo);
1720
0
  LOG_TEST_RET(ctx, rv, "Cannot get RSA PRIVATE SDO data");
1721
1722
  /* To made by iasecc_sdo_convert_to_file() */
1723
0
  prv->key_size = *(sdo.docp.size.value + 0) * 0x100 + *(sdo.docp.size.value + 1);
1724
0
  sc_log(ctx, "prv->key_size 0x%"SC_FORMAT_LEN_SIZE_T"X", prv->key_size);
1725
1726
0
  rv = iasecc_sdo_convert_acl(card, &sdo, SC_AC_OP_PSO_COMPUTE_SIGNATURE, &sign_meth, &sign_ref);
1727
0
  LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_SIGN acl");
1728
1729
0
  rv = iasecc_sdo_convert_acl(card, &sdo, SC_AC_OP_INTERNAL_AUTHENTICATE, &auth_meth, &auth_ref);
1730
0
  LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_INT_AUTH acl");
1731
1732
0
  aflags = env->algorithm_flags;
1733
1734
0
  if (!(aflags & SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01))
1735
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Only supported signature with PKCS1 padding");
1736
1737
0
  if (operation == SC_SEC_OPERATION_SIGN)   {
1738
0
    if (!(aflags & (SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_HASH_SHA256)))   {
1739
0
      sc_log(ctx, "CKM_RSA_PKCS asked -- use 'AUTHENTICATE' sign operation instead of 'SIGN'");
1740
0
      operation = SC_SEC_OPERATION_AUTHENTICATE;
1741
0
    }
1742
0
    else if (sign_meth == SC_AC_NEVER)   {
1743
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "PSO_DST not allowed for this key");
1744
0
    }
1745
0
  }
1746
1747
0
  if (operation == SC_SEC_OPERATION_SIGN)   {
1748
0
    prv->op_method = sign_meth;
1749
0
    prv->op_ref = sign_ref;
1750
0
  }
1751
0
  else if (operation == SC_SEC_OPERATION_AUTHENTICATE)   {
1752
0
    if (auth_meth == SC_AC_NEVER)
1753
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "INTERNAL_AUTHENTICATE is not allowed for this key");
1754
1755
0
    prv->op_method = auth_meth;
1756
0
    prv->op_ref = auth_ref;
1757
0
  }
1758
1759
0
  sc_log(ctx, "senv.algorithm 0x%lX, senv.algorithm_ref 0x%lX", env->algorithm, env->algorithm_ref);
1760
0
  sc_log(ctx,
1761
0
         "se_num %i, operation 0x%X, algorithm 0x%lX, algorithm_ref 0x%lX, flags 0x%lX; key size %"SC_FORMAT_LEN_SIZE_T"u",
1762
0
         se_num, operation, env->algorithm, env->algorithm_ref,
1763
0
         env->algorithm_flags, prv->key_size);
1764
0
  switch (operation)  {
1765
0
  case SC_SEC_OPERATION_SIGN:
1766
0
    if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01))
1767
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_PKCS1 specified");
1768
1769
0
    if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256)   {
1770
0
      algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_HASH, CKM_SHA256);
1771
0
      if (!algo_ref)
1772
0
        LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports HASH:SHA256");
1773
1774
0
      cse_crt_ht[2] = algo_ref; /* IASECC_ALGORITHM_SHA2 */
1775
1776
0
      algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE,  CKM_SHA256_RSA_PKCS);
1777
0
      if (!algo_ref)
1778
0
        LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports SIGNATURE:SHA1_RSA_PKCS");
1779
1780
0
      cse_crt_dst[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1781
0
      cse_crt_dst[5] = algo_ref;   /* IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA2 */
1782
0
    }
1783
0
    else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1)   {
1784
0
      algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_HASH,  CKM_SHA_1);
1785
0
      if (!algo_ref)
1786
0
        LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports HASH:SHA1");
1787
1788
0
      cse_crt_ht[2] = algo_ref; /* IASECC_ALGORITHM_SHA1 */
1789
1790
0
      algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE,  CKM_SHA1_RSA_PKCS);
1791
0
      if (!algo_ref)
1792
0
        LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports SIGNATURE:SHA1_RSA_PKCS");
1793
1794
0
      cse_crt_dst[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1795
0
      cse_crt_dst[5] = algo_ref;   /* IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA1 */
1796
0
    }
1797
0
    else   {
1798
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_HASH_SHA[1,256] specified");
1799
0
    }
1800
1801
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_HT);
1802
0
    apdu.data = cse_crt_ht;
1803
0
    apdu.datalen = sizeof(cse_crt_ht);
1804
0
    apdu.lc = sizeof(cse_crt_ht);
1805
1806
0
    rv = sc_transmit_apdu(card, &apdu);
1807
0
    LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1808
0
    rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1809
0
    LOG_TEST_RET(ctx, rv, "MSE restore error");
1810
1811
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_DST);
1812
0
    apdu.data = cse_crt_dst;
1813
0
    apdu.datalen = sizeof(cse_crt_dst);
1814
0
    apdu.lc = sizeof(cse_crt_dst);
1815
0
    break;
1816
0
  case SC_SEC_OPERATION_AUTHENTICATE:
1817
0
    algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE,  CKM_RSA_PKCS);
1818
0
    if (!algo_ref)
1819
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Application do not supports SIGNATURE:RSA_PKCS");
1820
1821
0
    cse_crt_at[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1822
0
    cse_crt_at[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS */
1823
1824
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_AT);
1825
0
    apdu.data = cse_crt_at;
1826
0
    apdu.datalen = sizeof(cse_crt_at);
1827
0
    apdu.lc = sizeof(cse_crt_at);
1828
0
    break;
1829
0
  case SC_SEC_OPERATION_DECIPHER:
1830
0
    rv = iasecc_sdo_convert_acl(card, &sdo, SC_AC_OP_PSO_DECRYPT, &prv->op_method, &prv->op_ref);
1831
0
    LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_PSO_DECRYPT acl");
1832
0
    algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_DECIPHER,  CKM_RSA_PKCS);
1833
0
    if (!algo_ref)
1834
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Application do not supports DECIPHER:RSA_PKCS");
1835
1836
0
    cse_crt_ct[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1837
0
    cse_crt_ct[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS_DECRYPT | IASECC_ALGORITHM_SHA1 */
1838
1839
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_CT);
1840
0
    apdu.data = cse_crt_ct;
1841
0
    apdu.datalen = sizeof(cse_crt_ct);
1842
0
    apdu.lc = sizeof(cse_crt_ct);
1843
0
    break;
1844
0
  default:
1845
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
1846
0
  }
1847
1848
0
  rv = sc_transmit_apdu(card, &apdu);
1849
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1850
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1851
0
  LOG_TEST_RET(ctx, rv, "MSE restore error");
1852
1853
0
  prv->security_env = *env;
1854
0
  prv->security_env.operation = operation;
1855
1856
0
  LOG_FUNC_RETURN(ctx, 0);
1857
0
}
1858
1859
1860
static int
1861
iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, unsigned char *scbs,
1862
      int *tries_left)
1863
0
{
1864
0
  struct sc_context *ctx = card->ctx;
1865
0
  unsigned char scb = scbs[IASECC_ACLS_CHV_VERIFY];
1866
0
  int rv;
1867
1868
0
  LOG_FUNC_CALLED(ctx);
1869
0
  sc_log(ctx, "Verify CHV PIN(ref:%i,len:%zu,scb:%X)", pin_cmd->pin_reference, pin_cmd->pin1.len,
1870
0
         scb);
1871
1872
0
  if (scb & IASECC_SCB_METHOD_SM) {
1873
0
    rv = iasecc_sm_pin_verify(card, scb & IASECC_SCB_METHOD_MASK_REF, pin_cmd, tries_left);
1874
0
    LOG_FUNC_RETURN(ctx, rv);
1875
0
  }
1876
1877
0
  rv = iso_ops->pin_cmd(card, pin_cmd, tries_left);
1878
0
  LOG_FUNC_RETURN(ctx, rv);
1879
0
}
1880
1881
1882
static int
1883
iasecc_se_at_to_chv_reference(struct sc_card *card, unsigned reference,
1884
    unsigned *chv_reference)
1885
0
{
1886
0
  struct sc_context *ctx = card->ctx;
1887
0
  struct iasecc_se_info se;
1888
0
  struct sc_crt crt;
1889
0
  int rv;
1890
1891
0
  LOG_FUNC_CALLED(ctx);
1892
0
  sc_log(ctx, "SE reference %i", reference);
1893
1894
0
  if (reference > IASECC_SE_REF_MAX)
1895
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1896
1897
0
  memset(&se, 0, sizeof(se));
1898
0
  se.reference = reference;
1899
1900
0
  rv = iasecc_se_get_info(card, &se);
1901
0
  LOG_TEST_RET(ctx, rv, "SDO get data error");
1902
1903
0
  memset(&crt, 0, sizeof(crt));
1904
0
  crt.tag = IASECC_CRT_TAG_AT;
1905
0
  crt.usage = IASECC_UQB_AT_USER_PASSWORD;
1906
1907
0
  rv = iasecc_se_get_crt(card, &se, &crt);
1908
0
  LOG_TEST_RET(ctx, rv, "no authentication template for USER PASSWORD");
1909
1910
0
  if (chv_reference)
1911
0
    *chv_reference = crt.refs[0];
1912
1913
0
  sc_file_free(se.df);
1914
1915
0
  LOG_FUNC_RETURN(ctx, rv);
1916
0
}
1917
1918
1919
static int
1920
iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
1921
205
{
1922
205
  struct sc_context *ctx = card->ctx;
1923
205
  struct sc_pin_cmd_data info;
1924
205
  int rv;
1925
1926
205
  LOG_FUNC_CALLED(ctx);
1927
1928
205
  if (data->pin_type != SC_AC_CHV)
1929
205
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "PIN type is not supported for status");
1930
1931
205
  memset(&info, 0, sizeof(info));
1932
205
  info.cmd = SC_PIN_CMD_GET_INFO;
1933
205
  info.pin_type = data->pin_type;
1934
205
  info.pin_reference = data->pin_reference;
1935
1936
205
  rv = iso_ops->pin_cmd(card, &info, tries_left);
1937
205
  LOG_TEST_RET(ctx, rv, "Failed to get PIN info");
1938
1939
192
  data->pin1.max_tries = info.pin1.max_tries;
1940
192
  data->pin1.tries_left = info.pin1.tries_left;
1941
192
  data->pin1.logged_in = info.pin1.logged_in;
1942
1943
192
  LOG_FUNC_RETURN(ctx, rv);
1944
192
}
1945
1946
1947
static int
1948
iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
1949
0
{
1950
0
  struct sc_context *ctx = card->ctx;
1951
0
  unsigned type = data->pin_type;
1952
0
  unsigned reference = data->pin_reference;
1953
0
  struct sc_pin_cmd_data pin_cmd;
1954
0
  struct iasecc_pin_policy policy;
1955
0
  int tries_before_verify = -1;
1956
0
  int rv;
1957
1958
0
  LOG_FUNC_CALLED(ctx);
1959
0
  sc_log(ctx,
1960
0
         "Verify PIN(type:%X,ref:%i,data(len:%zu,%p)",
1961
0
         type, reference, data->pin1.len, data->pin1.data);
1962
1963
0
  if (type == SC_AC_AUT)   {
1964
0
    rv =  iasecc_sm_external_authentication(card, reference, tries_left);
1965
0
    LOG_FUNC_RETURN(ctx, rv);
1966
0
  }
1967
1968
0
  if (type == SC_AC_SCB)   {
1969
0
    if (reference & IASECC_SCB_METHOD_USER_AUTH)   {
1970
0
      type = SC_AC_SEN;
1971
0
      reference = reference & IASECC_SCB_METHOD_MASK_REF;
1972
0
    }
1973
0
  }
1974
1975
0
  if (type == SC_AC_SEN)   {
1976
0
    type = SC_AC_CHV;
1977
0
    rv = iasecc_se_at_to_chv_reference(card, reference,  &reference);
1978
0
    LOG_TEST_RET(ctx, rv, "SE AT to CHV reference error");
1979
0
  }
1980
1981
0
  if (type != SC_AC_CHV)   {
1982
0
    sc_log(ctx, "Do not try to verify non CHV PINs");
1983
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1984
0
  }
1985
1986
0
  pin_cmd = *data;
1987
0
  pin_cmd.pin_type = SC_AC_CHV;
1988
0
  pin_cmd.pin_reference = reference;
1989
0
  pin_cmd.cmd = SC_PIN_CMD_VERIFY;
1990
1991
0
  rv = iasecc_pin_get_status(card, &pin_cmd, tries_left);
1992
0
  if (data->pin1.data && !data->pin1.len)
1993
0
    LOG_FUNC_RETURN(ctx, rv);
1994
1995
0
  if (!rv)   {
1996
0
    if (pin_cmd.pin1.logged_in & SC_PIN_STATE_LOGGED_IN)
1997
0
      if (iasecc_chv_cache_is_verified(card, &pin_cmd))
1998
0
        LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1999
0
  }
2000
0
  else if (rv != SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)   {
2001
0
    LOG_FUNC_RETURN(ctx, rv);
2002
0
  }
2003
2004
0
  iasecc_chv_cache_clean(card, &pin_cmd);
2005
2006
0
  rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin1, &policy);
2007
0
  LOG_TEST_RET(ctx, rv, "Failed to update PIN1 info");
2008
2009
  /* PIN-pads work best with fixed-size lengths. Use PIN padding when length is available. */
2010
0
  if (pin_cmd.flags & SC_PIN_CMD_USE_PINPAD) {
2011
0
    tries_before_verify = pin_cmd.pin1.tries_left;
2012
0
    if (policy.stored_length > 0)
2013
0
      iasecc_set_pin_padding(&pin_cmd, &pin_cmd.pin1, policy.stored_length);
2014
0
  }
2015
2016
0
  rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs, tries_left);
2017
2018
  /*
2019
   * Detect and log PIN-pads which don't handle variable-length PIN - special case where they
2020
   * forward the CHV verify command with Lc = 0 to the card, without updating Lc. An IAS-ECC
2021
   * card responds to this command by returning the number of attempts left, without
2022
   * decreasing the counter.
2023
   */
2024
0
  if ((pin_cmd.flags & SC_PIN_CMD_USE_PINPAD) && !(pin_cmd.flags & SC_PIN_CMD_NEED_PADDING)) {
2025
0
    if (rv == SC_ERROR_PIN_CODE_INCORRECT && pin_cmd.pin1.tries_left == tries_before_verify) {
2026
0
      SC_TEST_RET(ctx, SC_LOG_DEBUG_VERBOSE, rv,
2027
0
            "PIN-pad reader does not support variable-length PIN");
2028
0
    }
2029
0
  }
2030
2031
0
  LOG_TEST_RET(ctx, rv, "PIN CHV verification error");
2032
2033
0
  rv = iasecc_chv_cache_verified(card, &pin_cmd);
2034
2035
0
  LOG_FUNC_RETURN(ctx, rv);
2036
0
}
2037
2038
2039
static int
2040
iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin)
2041
192
{
2042
192
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
2043
192
  struct sc_context *ctx = card->ctx;
2044
192
  struct sc_file *save_current_df = NULL, *save_current_ef = NULL;
2045
192
  struct iasecc_sdo sdo;
2046
192
  struct sc_path path;
2047
192
  int rv;
2048
2049
192
  LOG_FUNC_CALLED(ctx);
2050
192
  sc_log(ctx, "iasecc_pin_get_policy(card:%p)", card);
2051
2052
192
  if (data->pin_type != SC_AC_CHV)   {
2053
0
    sc_log(ctx, "PIN policy only available for CHV type");
2054
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2055
0
  }
2056
2057
192
  if (prv->cache.valid && prv->cache.current_df) {
2058
5
    sc_file_dup(&save_current_df, prv->cache.current_df);
2059
5
    if (save_current_df == NULL) {
2060
0
      rv = SC_ERROR_OUT_OF_MEMORY;
2061
0
      sc_log(ctx, "Cannot duplicate current DF file");
2062
0
      goto err;
2063
0
    }
2064
5
  }
2065
2066
192
  if (prv->cache.valid && prv->cache.current_ef) {
2067
4
    sc_file_dup(&save_current_ef, prv->cache.current_ef);
2068
4
    if (save_current_ef == NULL) {
2069
0
      rv = SC_ERROR_OUT_OF_MEMORY;
2070
0
      sc_log(ctx, "Cannot duplicate current EF file");
2071
0
      goto err;
2072
0
    }
2073
4
  }
2074
2075
192
  if (!(data->pin_reference & IASECC_OBJECT_REF_LOCAL) && prv->cache.valid && prv->cache.current_df) {
2076
5
    sc_format_path("3F00", &path);
2077
5
    path.type = SC_PATH_TYPE_FILE_ID;
2078
5
    rv = iasecc_select_file(card, &path, NULL);
2079
5
    LOG_TEST_GOTO_ERR(ctx, rv, "Unable to select MF");
2080
5
  }
2081
2082
189
  memset(&sdo, 0, sizeof(sdo));
2083
189
  sdo.sdo_class = IASECC_SDO_CLASS_CHV;
2084
2085
189
  sdo.sdo_ref = data->pin_reference & ~IASECC_OBJECT_REF_LOCAL;
2086
2087
189
  sc_log(ctx, "iasecc_pin_get_policy() reference %i", sdo.sdo_ref);
2088
2089
189
  rv = iasecc_sdo_get_data(card, &sdo);
2090
189
  LOG_TEST_GOTO_ERR(ctx, rv, "Cannot get SDO PIN data");
2091
2092
0
  if (sdo.docp.acls_contact.size == 0) {
2093
0
    rv = SC_ERROR_INVALID_DATA;
2094
0
    sc_log(ctx, "Extremely strange ... there is no ACLs");
2095
0
    goto err;
2096
0
  }
2097
2098
0
  sc_log(ctx,
2099
0
         "iasecc_pin_get_policy() sdo.docp.size.size %"SC_FORMAT_LEN_SIZE_T"u",
2100
0
         sdo.docp.size.size);
2101
2102
0
  memcpy(pin->scbs, sdo.docp.scbs, sizeof(pin->scbs));
2103
2104
0
  pin->min_length = (sdo.data.chv.size_min.value ? *sdo.data.chv.size_min.value : -1);
2105
0
  pin->max_length = (sdo.data.chv.size_max.value ? *sdo.data.chv.size_max.value : -1);
2106
0
  pin->tries_maximum = (sdo.docp.tries_maximum.value ? *sdo.docp.tries_maximum.value : -1);
2107
0
  pin->tries_remaining = (sdo.docp.tries_remaining.value ? *sdo.docp.tries_remaining.value : -1);
2108
0
  if (sdo.docp.size.value && sdo.docp.size.size <= sizeof(int)) {
2109
0
    unsigned int n = 0;
2110
0
    unsigned int i;
2111
0
    for (i=0; i<sdo.docp.size.size; i++)
2112
0
      n = (n << 8) + *(sdo.docp.size.value + i);
2113
0
    pin->stored_length = n;
2114
0
  } else {
2115
0
    pin->stored_length = -1;
2116
0
  }
2117
2118
0
  sc_log(ctx, "PIN policy: size max/min %i/%i, tries max/left %i/%i",
2119
0
         pin->max_length, pin->min_length, pin->tries_maximum, pin->tries_remaining);
2120
0
  iasecc_sdo_free_fields(card, &sdo);
2121
2122
0
  if (save_current_df)   {
2123
0
    sc_log(ctx, "iasecc_pin_get_policy() restore current DF");
2124
0
    rv = iasecc_select_file(card, &save_current_df->path, NULL);
2125
0
    LOG_TEST_GOTO_ERR(ctx, rv, "Cannot return to saved DF");
2126
0
  }
2127
2128
0
  if (save_current_ef)   {
2129
0
    sc_log(ctx, "iasecc_pin_get_policy() restore current EF");
2130
0
    rv = iasecc_select_file(card, &save_current_ef->path, NULL);
2131
0
    LOG_TEST_GOTO_ERR(ctx, rv, "Cannot return to saved EF");
2132
0
  }
2133
2134
192
err:
2135
192
  sc_file_free(save_current_df);
2136
192
  sc_file_free(save_current_ef);
2137
2138
192
  LOG_FUNC_RETURN(ctx, rv);
2139
192
}
2140
2141
2142
static int
2143
iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2144
205
{
2145
205
  struct sc_context *ctx = card->ctx;
2146
205
  struct iasecc_pin_policy policy;
2147
205
  int rv;
2148
2149
205
  LOG_FUNC_CALLED(ctx);
2150
205
  sc_log(ctx, "iasecc_pin_get_info(card:%p)", card);
2151
2152
  /*
2153
   * Get PIN status first and thereafter update with info from PIN policy, when available.
2154
   * The first one is typically used for the PIN verification status and number of remaining
2155
   * tries, and the second one for the maximum tries. If a field is present in both, the
2156
   * policy takes precedence.
2157
   */
2158
205
  rv = iasecc_pin_get_status(card, data, tries_left);
2159
205
  LOG_TEST_RET(ctx, rv, "Failed to get PIN status");
2160
2161
192
  rv = iasecc_pin_get_policy(card, data, &policy);
2162
192
  LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
2163
2164
  /*
2165
   * We only care about the tries_xxx fields in the PIN policy, since the other ones are not
2166
   * commonly expected or used in a SC_PIN_CMD_GET_INFO response. Note that max_tries is
2167
   * always taken from the policy, since it is never expected to be available in status (it
2168
   * is set to -1 when not available in policy).
2169
   */
2170
0
  data->pin1.max_tries = policy.tries_maximum;
2171
0
  if (policy.tries_remaining >= 0)
2172
0
    data->pin1.tries_left = policy.tries_remaining;
2173
2174
0
  if (tries_left)
2175
0
    *tries_left = data->pin1.tries_left;
2176
2177
0
  LOG_FUNC_RETURN(ctx, rv);
2178
0
}
2179
2180
2181
/*
2182
 * Check PIN and update flags. We reject empty PINs (where data is non-NULL but length is 0) due
2183
 * to their non-obvious meaning in verification/change/unblock. We also need to update the
2184
 * SC_PIN_CMD_USE_PINPAD flag depending on the PIN being available or not (where data is NULL means
2185
 * that PIN is not available). Unfortunately we can not rely on the flag provided by the caller due
2186
 * to its ambiguous use. The approach here is to assume pin-pad input when the PIN data is NULL,
2187
 * otherwise not.
2188
 */
2189
static int iasecc_check_update_pin(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin)
2190
0
{
2191
0
  if ((!pin->data && pin->len) || (pin->data && !pin->len))
2192
0
    return SC_ERROR_INVALID_ARGUMENTS;
2193
2194
0
  if (pin->data)
2195
0
    data->flags &= ~SC_PIN_CMD_USE_PINPAD;
2196
0
  else
2197
0
    data->flags |= SC_PIN_CMD_USE_PINPAD;
2198
2199
0
  return SC_SUCCESS;
2200
0
}
2201
2202
2203
/* Enable PIN padding with 0xff as the padding character, unless already enabled */
2204
static void iasecc_set_pin_padding(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin,
2205
           size_t pad_len)
2206
0
{
2207
0
  if (data->flags & SC_PIN_CMD_NEED_PADDING)
2208
0
    return;
2209
2210
0
  pin->pad_length = pad_len;
2211
0
  pin->pad_char = 0xff;
2212
0
  data->flags |= SC_PIN_CMD_NEED_PADDING;
2213
0
}
2214
2215
2216
/*
2217
 * Retrieve the PIN policy and combine it with the existing fields in an intelligent way. This is
2218
 * needed since we may be called with existing settings, typically from the PKCS #15 layer. We use
2219
 * the IAS-ECC card-level PIN settings as complementary.
2220
 */
2221
static int
2222
iasecc_pin_merge_policy(struct sc_card *card, struct sc_pin_cmd_data *data,
2223
      struct sc_pin_cmd_pin *pin, struct iasecc_pin_policy *policy)
2224
0
{
2225
0
  struct sc_context *ctx = card->ctx;
2226
0
  size_t pad_len = 0;
2227
0
  int rv;
2228
2229
0
  LOG_FUNC_CALLED(ctx);
2230
0
  sc_log(ctx, "iasecc_pin_merge_policy(card:%p)", card);
2231
2232
0
  rv = iasecc_check_update_pin(data, pin);
2233
0
  LOG_TEST_RET(ctx, rv, "Invalid PIN");
2234
2235
0
  rv = iasecc_pin_get_policy(card, data, policy);
2236
0
  LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
2237
2238
  /* Some cards obviously use the min/max length fields to signal PIN padding */
2239
0
  if (policy->min_length > 0 && policy->min_length == policy->max_length) {
2240
0
    pad_len = policy->min_length;
2241
0
    policy->min_length = 0;
2242
0
  }
2243
2244
  /* Take the most limited values of min/max lengths */
2245
0
  if (policy->min_length > 0 && (size_t) policy->min_length > pin->min_length)
2246
0
    pin->min_length = policy->min_length;
2247
0
  if (policy->max_length > 0 && (!pin->max_length || (size_t) policy->max_length < pin->max_length))
2248
0
    pin->max_length = policy->max_length;
2249
2250
  /* Set PIN padding if needed and not already set by the caller */
2251
0
  if (pad_len)
2252
0
    iasecc_set_pin_padding(data, pin, pad_len);
2253
2254
0
  LOG_FUNC_RETURN(ctx, rv);
2255
0
}
2256
2257
2258
static int
2259
iasecc_keyset_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2260
0
{
2261
0
  struct sc_context *ctx = card->ctx;
2262
0
  struct iasecc_sdo_update update;
2263
0
  struct iasecc_sdo sdo;
2264
0
  unsigned scb;
2265
0
  int rv;
2266
2267
0
  LOG_FUNC_CALLED(ctx);
2268
0
  sc_log(ctx, "Change keyset(ref:%i,lengths:%zu)", data->pin_reference, data->pin2.len);
2269
0
  if (!data->pin2.data || data->pin2.len < 32)
2270
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Needs at least 32 bytes for a new keyset value");
2271
2272
0
  memset(&sdo, 0, sizeof(sdo));
2273
0
  sdo.sdo_class = IASECC_SDO_CLASS_KEYSET;
2274
0
  sdo.sdo_ref  = data->pin_reference;
2275
2276
0
  rv = iasecc_sdo_get_data(card, &sdo);
2277
0
  LOG_TEST_RET(ctx, rv, "Cannot get keyset data");
2278
2279
0
  if (sdo.docp.acls_contact.size == 0)
2280
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Bewildered ... there are no ACLs");
2281
0
  scb = sdo.docp.scbs[IASECC_ACLS_KEYSET_PUT_DATA];
2282
2283
0
  memset(&update, 0, sizeof(update));
2284
0
  update.magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA;
2285
0
  update.sdo_class = sdo.sdo_class;
2286
0
  update.sdo_ref = sdo.sdo_ref;
2287
0
  iasecc_sdo_free_fields(card, &sdo);
2288
2289
0
  sc_log(ctx, "SCB:0x%X", scb);
2290
0
  if (!(scb & IASECC_SCB_METHOD_SM))
2291
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Other then protected by SM, the keyset change is not supported");
2292
2293
2294
0
  update.fields[0].parent_tag = IASECC_SDO_KEYSET_TAG;
2295
0
  update.fields[0].tag = IASECC_SDO_KEYSET_TAG_MAC;
2296
  /* FIXME is it safe to modify the const value here? */
2297
0
  update.fields[0].value = (unsigned char *) data->pin2.data;
2298
0
  update.fields[0].size = 16;
2299
2300
0
  update.fields[1].parent_tag = IASECC_SDO_KEYSET_TAG;
2301
0
  update.fields[1].tag = IASECC_SDO_KEYSET_TAG_ENC;
2302
  /* FIXME is it safe to modify the const value here? */
2303
0
  update.fields[1].value = (unsigned char *) data->pin2.data + 16;
2304
0
  update.fields[1].size = 16;
2305
2306
0
  rv = iasecc_sm_sdo_update(card, (scb & IASECC_SCB_METHOD_MASK_REF), &update);
2307
0
  LOG_FUNC_RETURN(ctx, rv);
2308
0
}
2309
2310
2311
/*
2312
 * The PIN change function can handle different PIN-pad input combinations for the old and new
2313
 * PINs:
2314
 *   OLD PIN:   NEW PIN:     DESCRIPTION:
2315
 *   Available  Available    No input.
2316
 *   Available  Absent       Only new PIN is input.
2317
 *   Absent     Available    Both PINs are input (due to limitations in IAS-ECC)
2318
 *   Absent     Absent       Both PINs are input.
2319
 */
2320
static int
2321
iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2322
0
{
2323
0
  struct sc_context *ctx = card->ctx;
2324
0
  struct sc_pin_cmd_data pin_cmd;
2325
0
  struct iasecc_pin_policy policy;
2326
0
  int rv;
2327
2328
0
  LOG_FUNC_CALLED(ctx);
2329
0
  sc_log(ctx, "Change PIN(ref:%i,type:0x%X,lengths:%zu/%zu)",
2330
0
         data->pin_reference, data->pin_type, data->pin1.len, data->pin2.len);
2331
2332
0
  if (data->pin_type != SC_AC_CHV)   {
2333
0
    sc_log(ctx, "Can not change non-CHV PINs");
2334
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
2335
0
  }
2336
2337
  /*
2338
   * Verify the original PIN. This would normally not be needed since it is implicitly done
2339
   * by the card when executing a PIN change command. But we must go through our verification
2340
   * function in order to handle secure messaging setup, if enabled for the PIN. The
2341
   * verification is skipped for PIN-pads (which do not work with SM anyway), to avoid the
2342
   * user having to enter the PIN twice.
2343
   */
2344
0
  pin_cmd = *data;
2345
0
  pin_cmd.cmd = SC_PIN_CMD_VERIFY;
2346
2347
0
  rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin1, &policy);
2348
0
  LOG_TEST_RET(ctx, rv, "Failed to update PIN1 info");
2349
2350
0
  if (!(pin_cmd.flags & SC_PIN_CMD_USE_PINPAD)) {
2351
0
    rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs, tries_left);
2352
0
    LOG_TEST_RET(ctx, rv, "PIN CHV verification error");
2353
0
  }
2354
2355
  /*
2356
   * To keep things simple, assume that we can use the same PIN parameters for the new PIN as
2357
   * for the old one, ignoring the ones specified by the caller, with the exception of the
2358
   * PIN prompt and the PIN data itself. Note that the old PIN is re-verified since the
2359
   * IAS-ECC specification has no implicit verification for the PIN change command. This also
2360
   * forces us to always use PIN-pad for the second PIN if the first one was input on a
2361
   * PIN-pad.
2362
   */
2363
0
  pin_cmd.cmd = SC_PIN_CMD_CHANGE;
2364
0
  pin_cmd.pin2 = pin_cmd.pin1;
2365
0
  pin_cmd.pin2.prompt = data->pin2.prompt;
2366
0
  if (pin_cmd.flags & SC_PIN_CMD_USE_PINPAD) {
2367
0
    pin_cmd.pin2.data = NULL;
2368
0
    pin_cmd.pin2.len = 0;
2369
0
  } else {
2370
0
    pin_cmd.pin2.data = data->pin2.data;
2371
0
    pin_cmd.pin2.len = data->pin2.len;
2372
0
  }
2373
2374
0
  rv = iasecc_check_update_pin(&pin_cmd, &pin_cmd.pin2);
2375
0
  LOG_TEST_RET(ctx, rv, "Invalid PIN2");
2376
2377
0
  rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left);
2378
0
  LOG_FUNC_RETURN(ctx, rv);
2379
0
}
2380
2381
2382
/*
2383
 * The PIN unblock function can handle different PIN-pad input combinations for the PUK and the new
2384
 * PIN:
2385
 *   PUK:       NEW PIN:     DESCRIPTION:
2386
 *   Available  Available    No input.
2387
 *   Available  Absent       Only new PIN is input.
2388
 *   Absent     Available    Only PUK is input.
2389
 *   Absent     Absent       Both PUK and new PIN are input.
2390
 */
2391
static int
2392
iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2393
0
{
2394
0
  struct sc_context *ctx = card->ctx;
2395
0
  unsigned char scb;
2396
0
  struct sc_pin_cmd_data pin_cmd;
2397
0
  struct iasecc_pin_policy policy;
2398
0
  int rv;
2399
2400
0
  LOG_FUNC_CALLED(ctx);
2401
0
  sc_log(ctx, "Reset PIN(ref:%i,lengths:%zu/%zu)", data->pin_reference, data->pin1.len, data->pin2.len);
2402
2403
0
  if (data->pin_type != SC_AC_CHV)
2404
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unblock procedure can be used only with the PINs of type CHV");
2405
2406
0
  rv = iasecc_pin_get_policy(card, data, &policy);
2407
0
  LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
2408
2409
0
  scb = policy.scbs[IASECC_ACLS_CHV_RESET];
2410
0
  do   {
2411
0
    unsigned need_all = scb & IASECC_SCB_METHOD_NEED_ALL ? 1 : 0;
2412
0
    unsigned char se_num = scb & IASECC_SCB_METHOD_MASK_REF;
2413
2414
0
    if (scb & IASECC_SCB_METHOD_USER_AUTH)   {
2415
0
      pin_cmd = *data;
2416
0
      if (pin_cmd.puk_reference)   {
2417
0
        sc_log(ctx, "Verify PIN with CHV %X", pin_cmd.puk_reference);
2418
0
        pin_cmd.pin_type = SC_AC_CHV;
2419
0
        pin_cmd.pin_reference = pin_cmd.puk_reference;
2420
0
      } else   {
2421
0
        sc_log(ctx, "Verify PIN in SE %X", se_num);
2422
0
        pin_cmd.pin_type = SC_AC_SEN;
2423
0
        pin_cmd.pin_reference = se_num;
2424
0
      }
2425
0
      rv = iasecc_pin_verify(card, &pin_cmd, tries_left);
2426
0
      LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() verify PUK error");
2427
2428
0
      if (!need_all)
2429
0
        break;
2430
0
    }
2431
2432
0
    if (scb & IASECC_SCB_METHOD_SM)   {
2433
0
      rv = iasecc_sm_pin_reset(card, se_num, data);
2434
0
      LOG_FUNC_RETURN(ctx, rv);
2435
0
    }
2436
2437
0
    if (scb & IASECC_SCB_METHOD_EXT_AUTH)   {
2438
0
      rv =  iasecc_sm_external_authentication(card, data->pin_reference, tries_left);
2439
0
      LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() external authentication error");
2440
0
    }
2441
0
  } while(0);
2442
2443
  /* Use iso 7816 layer for unblock, with implicit pin for PIN1 and the new PIN for PIN2 */
2444
0
  pin_cmd = *data;
2445
0
  pin_cmd.cmd = SC_PIN_CMD_UNBLOCK;
2446
0
  pin_cmd.flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
2447
0
  pin_cmd.pin1.len = 0;
2448
2449
0
  rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin2, &policy);
2450
0
  LOG_TEST_RET(ctx, rv, "Failed to update PIN2 info");
2451
2452
0
  rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left);
2453
2454
0
  LOG_FUNC_RETURN(ctx, rv);
2455
0
}
2456
2457
2458
static int
2459
iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2460
205
{
2461
205
  struct sc_context *ctx = card->ctx;
2462
205
  int rv;
2463
2464
205
  LOG_FUNC_CALLED(ctx);
2465
205
  sc_log(ctx, "iasecc_pin_cmd() cmd 0x%X, PIN type 0x%X, PIN reference %i, PIN-1 %p:%zu, PIN-2 %p:%zu",
2466
205
      data->cmd, data->pin_type, data->pin_reference,
2467
205
      data->pin1.data, data->pin1.len, data->pin2.data, data->pin2.len);
2468
2469
205
  switch (data->cmd)   {
2470
0
  case SC_PIN_CMD_VERIFY:
2471
0
    rv = iasecc_pin_verify(card, data, tries_left);
2472
0
    break;
2473
0
  case SC_PIN_CMD_CHANGE:
2474
0
    if (data->pin_type == SC_AC_AUT)
2475
0
      rv = iasecc_keyset_change(card, data, tries_left);
2476
0
    else
2477
0
      rv = iasecc_pin_change(card, data, tries_left);
2478
0
    break;
2479
0
  case SC_PIN_CMD_UNBLOCK:
2480
0
    rv = iasecc_pin_reset(card, data, tries_left);
2481
0
    break;
2482
205
  case SC_PIN_CMD_GET_INFO:
2483
205
    rv = iasecc_pin_get_info(card, data, tries_left);
2484
205
    break;
2485
0
  default:
2486
0
    sc_log(ctx, "Other pin commands not supported yet: 0x%X", data->cmd);
2487
0
    rv = SC_ERROR_NOT_SUPPORTED;
2488
205
  }
2489
2490
205
  LOG_FUNC_RETURN(ctx, rv);
2491
205
}
2492
2493
2494
static int
2495
iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial)
2496
694
{
2497
694
  struct sc_context *ctx = card->ctx;
2498
694
  struct sc_iin *iin = &card->serialnr.iin;
2499
694
  struct sc_apdu apdu;
2500
694
  unsigned char rbuf[0xC0];
2501
694
  size_t ii, offs, len;
2502
694
  int rv;
2503
2504
694
  LOG_FUNC_CALLED(ctx);
2505
694
  if (card->serialnr.len)
2506
1
    goto end;
2507
2508
693
  memset(&card->serialnr, 0, sizeof(card->serialnr));
2509
2510
693
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x80 | IASECC_SFI_EF_SN, 0);
2511
693
  apdu.le = sizeof(rbuf);
2512
693
  apdu.resp = rbuf;
2513
693
  apdu.resplen = sizeof(rbuf);
2514
2515
693
  rv = sc_transmit_apdu(card, &apdu);
2516
693
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2517
688
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2518
688
  LOG_TEST_RET(ctx, rv, "Get 'serial number' data failed");
2519
2520
246
  if (apdu.resplen < 2 || rbuf[0] != ISO7812_PAN_SN_TAG || rbuf[1] > (apdu.resplen-2))
2521
246
    LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "serial number parse error");
2522
13
  len = rbuf[1];
2523
2524
13
  iin->mii = (rbuf[2] >> 4) & 0x0F;
2525
2526
13
  iin->country = 0;
2527
52
  for (ii=5; ii<8; ii++)   {
2528
39
    iin->country *= 10;
2529
39
    iin->country += (rbuf[ii/2] >> ((ii & 0x01) ? 0 : 4)) & 0x0F;
2530
39
  }
2531
2532
13
  iin->issuer_id = 0;
2533
39
  for (ii=8; ii<10; ii++)   {
2534
26
    iin->issuer_id *= 10;
2535
26
    iin->issuer_id += (rbuf[ii/2] >> (ii & 0x01 ? 0 : 4)) & 0x0F;
2536
26
  }
2537
2538
  /* Copy the serial number from the last 8 bytes (at most) */
2539
13
  offs = len > 8 ? len - 8 : 0;
2540
13
  if (card->type == SC_CARD_TYPE_IASECC_SAGEM)   {
2541
    /* 5A 0A 92 50 00 20 10 10 25 00 01 3F */
2542
    /*            00 02 01 01 02 50 00 13  */
2543
25
    for (ii=0; ii < len - offs; ii++)
2544
19
      *(card->serialnr.value + ii) = ((rbuf[ii + offs + 1] & 0x0F) << 4)
2545
19
        + ((rbuf[ii + offs + 2] & 0xF0) >> 4) ;
2546
6
    card->serialnr.len = ii;
2547
6
  }
2548
7
  else   {
2549
33
    for (ii=0; ii < len - offs; ii++)
2550
26
      *(card->serialnr.value + ii) = rbuf[ii + offs + 2];
2551
7
    card->serialnr.len = ii;
2552
7
  }
2553
2554
13
  do  {
2555
13
    char txt[0x200];
2556
2557
58
    for (ii=0;ii<card->serialnr.len;ii++)
2558
45
      sprintf(txt + ii*2, "%02X", *(card->serialnr.value + ii));
2559
2560
13
    sc_log(ctx, "serial number '%s'; mii %i; country %i; issuer_id %li", txt, iin->mii, iin->country, iin->issuer_id);
2561
13
  } while(0);
2562
2563
14
end:
2564
14
  if (serial)
2565
2
    memcpy(serial, &card->serialnr, sizeof(*serial));
2566
2567
14
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2568
14
}
2569
2570
2571
static int
2572
iasecc_sdo_create(struct sc_card *card, struct iasecc_sdo *sdo)
2573
0
{
2574
0
  struct sc_context *ctx = card->ctx;
2575
0
  struct sc_apdu apdu;
2576
0
  unsigned char *data = NULL, sdo_class = sdo->sdo_class;
2577
0
  struct iasecc_sdo_update update;
2578
0
  struct iasecc_extended_tlv *field = NULL;
2579
0
  int rv = SC_ERROR_NOT_SUPPORTED, data_len;
2580
2581
0
  LOG_FUNC_CALLED(ctx);
2582
0
  if (sdo->magic != SC_CARDCTL_IASECC_SDO_MAGIC)
2583
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO data");
2584
2585
0
  sc_log(ctx, "iasecc_sdo_create(card:%p) %02X%02X%02X", card,
2586
0
      IASECC_SDO_TAG_HEADER, sdo->sdo_class | 0x80, sdo->sdo_ref);
2587
2588
0
  data_len = iasecc_sdo_encode_create(ctx, sdo, &data);
2589
0
  LOG_TEST_RET(ctx, data_len, "iasecc_sdo_create() cannot encode SDO create data");
2590
0
  sc_log(ctx, "iasecc_sdo_create() create data(%i):%s", data_len, sc_dump_hex(data, data_len));
2591
2592
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDB, 0x3F, 0xFF);
2593
0
  apdu.data = data;
2594
0
  apdu.datalen = data_len;
2595
0
  apdu.lc = data_len;
2596
0
  apdu.flags |= SC_APDU_FLAGS_CHAINING;
2597
2598
0
  rv = sc_transmit_apdu(card, &apdu);
2599
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2600
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2601
0
  LOG_TEST_RET(ctx, rv, "iasecc_sdo_create() SDO put data error");
2602
2603
0
  memset(&update, 0, sizeof(update));
2604
0
  update.magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA;
2605
0
  update.sdo_class = sdo->sdo_class;
2606
0
  update.sdo_ref = sdo->sdo_ref;
2607
2608
0
  if (sdo_class == IASECC_SDO_CLASS_RSA_PRIVATE)   {
2609
0
    update.fields[0] = sdo->data.prv_key.compulsory;
2610
0
    update.fields[0].parent_tag = IASECC_SDO_PRVKEY_TAG;
2611
0
    field = &sdo->data.prv_key.compulsory;
2612
0
  }
2613
0
  else if (sdo_class == IASECC_SDO_CLASS_RSA_PUBLIC)   {
2614
0
    update.fields[0] = sdo->data.pub_key.compulsory;
2615
0
    update.fields[0].parent_tag = IASECC_SDO_PUBKEY_TAG;
2616
0
    field = &sdo->data.pub_key.compulsory;
2617
0
  }
2618
0
  else if (sdo_class == IASECC_SDO_CLASS_KEYSET)   {
2619
0
    update.fields[0] = sdo->data.keyset.compulsory;
2620
0
    update.fields[0].parent_tag = IASECC_SDO_KEYSET_TAG;
2621
0
    field = &sdo->data.keyset.compulsory;
2622
0
  }
2623
2624
0
  if (update.fields[0].value && !update.fields[0].on_card)   {
2625
0
    rv = iasecc_sdo_put_data(card, &update);
2626
0
    LOG_TEST_RET(ctx, rv, "failed to update 'Compulsory usage' data");
2627
2628
0
    if (field)
2629
0
      field->on_card = 1;
2630
0
  }
2631
2632
0
  free(data);
2633
0
  LOG_FUNC_RETURN(ctx, rv);
2634
0
}
2635
2636
/* Oberthur's specific */
2637
static int
2638
iasecc_sdo_delete(struct sc_card *card, struct iasecc_sdo *sdo)
2639
0
{
2640
0
  struct sc_context *ctx = card->ctx;
2641
0
  struct sc_apdu apdu;
2642
0
  unsigned char data[6] = {
2643
0
    0x70, 0x04, 0xBF, 0xFF, 0xFF, 0x00
2644
0
  };
2645
0
  int rv;
2646
2647
0
  LOG_FUNC_CALLED(ctx);
2648
0
  if (sdo->magic != SC_CARDCTL_IASECC_SDO_MAGIC)
2649
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO data");
2650
2651
0
  data[2] = IASECC_SDO_TAG_HEADER;
2652
0
  data[3] = sdo->sdo_class | 0x80;
2653
0
  data[4] = sdo->sdo_ref;
2654
0
  sc_log(ctx, "delete SDO %02X%02X%02X", data[2], data[3], data[4]);
2655
2656
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDB, 0x3F, 0xFF);
2657
0
  apdu.data = data;
2658
0
  apdu.datalen = sizeof(data);
2659
0
  apdu.lc = sizeof(data);
2660
0
  apdu.flags |= SC_APDU_FLAGS_CHAINING;
2661
2662
0
  rv = sc_transmit_apdu(card, &apdu);
2663
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2664
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2665
0
  LOG_TEST_RET(ctx, rv, "delete SDO error");
2666
2667
0
  LOG_FUNC_RETURN(ctx, rv);
2668
0
}
2669
2670
2671
static int
2672
iasecc_sdo_put_data(struct sc_card *card, struct iasecc_sdo_update *update)
2673
0
{
2674
0
  struct sc_context *ctx = card->ctx;
2675
0
  struct sc_apdu apdu;
2676
0
  int ii, rv;
2677
2678
0
  LOG_FUNC_CALLED(ctx);
2679
0
  if (update->magic != SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA)
2680
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO update data");
2681
2682
0
  for(ii=0; update->fields[ii].tag && ii < IASECC_SDO_TAGS_UPDATE_MAX; ii++)   {
2683
0
    unsigned char *encoded = NULL;
2684
0
    int encoded_len;
2685
2686
0
    encoded_len = iasecc_sdo_encode_update_field(ctx, update->sdo_class, update->sdo_ref,
2687
0
              &update->fields[ii], &encoded);
2688
0
    sc_log(ctx, "iasecc_sdo_put_data() encode[%i]; tag %X; encoded_len %i", ii, update->fields[ii].tag, encoded_len);
2689
0
    LOG_TEST_RET(ctx, encoded_len, "Cannot encode update data");
2690
2691
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDB, 0x3F, 0xFF);
2692
0
    apdu.data = encoded;
2693
0
    apdu.datalen = encoded_len;
2694
0
    apdu.lc = encoded_len;
2695
0
    apdu.flags |= SC_APDU_FLAGS_CHAINING;
2696
2697
0
    rv = sc_transmit_apdu(card, &apdu);
2698
0
    LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2699
0
    rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2700
0
    LOG_TEST_RET(ctx, rv, "SDO put data error");
2701
2702
0
    free(encoded);
2703
0
  }
2704
2705
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2706
0
}
2707
2708
2709
static int
2710
iasecc_sdo_key_rsa_put_data(struct sc_card *card, struct iasecc_sdo_rsa_update *update)
2711
0
{
2712
0
  struct sc_context *ctx = card->ctx;
2713
0
  unsigned char scb;
2714
0
  int rv;
2715
2716
0
  LOG_FUNC_CALLED(ctx);
2717
2718
0
  if (update->sdo_prv_key)   {
2719
0
    sc_log(ctx, "encode private rsa in %p", &update->update_prv);
2720
0
    rv = iasecc_sdo_encode_rsa_update(card->ctx, update->sdo_prv_key, update->p15_rsa, &update->update_prv);
2721
0
    LOG_TEST_RET(ctx, rv, "failed to encode update of RSA private key");
2722
0
  }
2723
2724
0
  if (update->sdo_pub_key)   {
2725
0
    sc_log(ctx, "encode public rsa in %p", &update->update_pub);
2726
0
    if (card->type == SC_CARD_TYPE_IASECC_SAGEM)   {
2727
0
      if (update->sdo_pub_key->data.pub_key.cha.value)   {
2728
0
        free(update->sdo_pub_key->data.pub_key.cha.value);
2729
0
        memset(&update->sdo_pub_key->data.pub_key.cha, 0, sizeof(update->sdo_pub_key->data.pub_key.cha));
2730
0
      }
2731
0
    }
2732
0
    rv = iasecc_sdo_encode_rsa_update(card->ctx, update->sdo_pub_key, update->p15_rsa, &update->update_pub);
2733
0
    LOG_TEST_RET(ctx, rv, "failed to encode update of RSA public key");
2734
0
  }
2735
2736
0
  if (update->sdo_prv_key)   {
2737
0
    sc_log(ctx, "reference of the private key to store: %X", update->sdo_prv_key->sdo_ref);
2738
2739
0
    if (update->sdo_prv_key->docp.acls_contact.size == 0)
2740
0
      LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "extremely strange ... there are no ACLs");
2741
2742
0
    scb = update->sdo_prv_key->docp.scbs[IASECC_ACLS_RSAKEY_PUT_DATA];
2743
0
    sc_log(ctx, "'UPDATE PRIVATE RSA' scb 0x%X", scb);
2744
2745
0
    do   {
2746
0
      unsigned all_conditions = scb & IASECC_SCB_METHOD_NEED_ALL ? 1 : 0;
2747
2748
0
      if ((scb & IASECC_SCB_METHOD_USER_AUTH) && !all_conditions)
2749
0
        break;
2750
2751
0
      if (scb & IASECC_SCB_METHOD_EXT_AUTH)
2752
0
        LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet");
2753
2754
0
      if (scb & IASECC_SCB_METHOD_SM)   {
2755
0
#ifdef ENABLE_SM
2756
0
        rv = iasecc_sm_rsa_update(card, scb & IASECC_SCB_METHOD_MASK_REF, update);
2757
0
        LOG_FUNC_RETURN(ctx, rv);
2758
#else
2759
        LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
2760
#endif
2761
0
      }
2762
0
    } while(0);
2763
2764
0
    rv = iasecc_sdo_put_data(card, &update->update_prv);
2765
0
    LOG_TEST_RET(ctx, rv, "failed to update of RSA private key");
2766
0
  }
2767
2768
0
  if (update->sdo_pub_key)   {
2769
0
    sc_log(ctx, "reference of the public key to store: %X", update->sdo_pub_key->sdo_ref);
2770
2771
0
    rv = iasecc_sdo_put_data(card, &update->update_pub);
2772
0
    LOG_TEST_RET(ctx, rv, "failed to update of RSA public key");
2773
0
  }
2774
2775
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2776
0
}
2777
2778
2779
static int
2780
iasecc_sdo_tag_from_class(unsigned sdo_class)
2781
189
{
2782
189
  switch (sdo_class & ~IASECC_OBJECT_REF_LOCAL)   {
2783
189
  case IASECC_SDO_CLASS_CHV:
2784
189
    return IASECC_SDO_CHV_TAG;
2785
0
  case IASECC_SDO_CLASS_RSA_PRIVATE:
2786
0
    return IASECC_SDO_PRVKEY_TAG;
2787
0
  case IASECC_SDO_CLASS_RSA_PUBLIC:
2788
0
    return IASECC_SDO_PUBKEY_TAG;
2789
0
  case IASECC_SDO_CLASS_SE:
2790
0
    return IASECC_SDO_CLASS_SE;
2791
0
  case IASECC_SDO_CLASS_KEYSET:
2792
0
    return IASECC_SDO_KEYSET_TAG;
2793
189
  }
2794
2795
0
  return -1;
2796
189
}
2797
2798
2799
static int
2800
iasecc_sdo_get_tagged_data(struct sc_card *card, int sdo_tag, struct iasecc_sdo *sdo)
2801
195
{
2802
195
  struct sc_context *ctx = card->ctx;
2803
195
  struct sc_apdu apdu;
2804
195
  unsigned char sbuf[0x100];
2805
195
  size_t offs = sizeof(sbuf) - 1;
2806
195
  unsigned char rbuf[0x400];
2807
195
  int rv;
2808
2809
195
  LOG_FUNC_CALLED(ctx);
2810
2811
195
  sc_log(ctx, "sdo_tag=0x%x sdo_ref=0x%x sdo_class=0x%x", sdo_tag,
2812
195
      sdo->sdo_ref, sdo->sdo_class);
2813
2814
  /* XXX: for the CPx, the SDO are available from some specific path */
2815
195
  if (iasecc_is_cpx(card)) {
2816
6
    struct sc_path path;
2817
6
    char *path_str = NULL;
2818
6
    switch(sdo_tag) {
2819
0
      case IASECC_SDO_PRVKEY_TAG:
2820
      /* APDU 00 CB 3F FF 0B 4D 09 70 07 BF 90 02 03 7F 48 80 */
2821
0
      path_str = "3F00:0001";
2822
0
      break;
2823
4
      case IASECC_SDO_CHV_TAG:
2824
      /* APDU 00 CB 3F FF 0B 4D 09 70 07 BF 81 01 03 7F 41 80 */
2825
4
      path_str = "3F00";
2826
4
      break;
2827
2
      default:
2828
2
      path_str = NULL;
2829
2
      break;
2830
6
    }
2831
6
    if (path_str) {
2832
4
      sc_log(ctx, "Warning: Enforce the path=%s", path_str);
2833
4
      sc_format_path(path_str, &path);
2834
4
      rv = iasecc_select_file(card, &path, NULL);
2835
4
      LOG_TEST_RET(ctx, rv, "path error");
2836
4
    }
2837
6
  }
2838
2839
193
  sbuf[offs--] = 0x80;
2840
193
  sbuf[offs--] = sdo_tag & 0xFF;
2841
193
  if ((sdo_tag >> 8) & 0xFF)
2842
187
    sbuf[offs--] = (sdo_tag >> 8) & 0xFF;
2843
193
  sbuf[offs] = sizeof(sbuf) - offs - 1;
2844
193
  offs--;
2845
2846
193
  sbuf[offs--] = sdo->sdo_ref & 0x9F;
2847
193
  sbuf[offs--] = sdo->sdo_class | IASECC_OBJECT_REF_LOCAL;
2848
193
  sbuf[offs--] = IASECC_SDO_TAG_HEADER;
2849
2850
193
  sbuf[offs] = sizeof(sbuf) - offs - 1;
2851
193
  offs--;
2852
193
  sbuf[offs--] = IASECC_SDO_TEMPLATE_TAG;
2853
2854
193
  sbuf[offs] = sizeof(sbuf) - offs - 1;
2855
193
  offs--;
2856
193
  sbuf[offs] = 0x4D;
2857
2858
193
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF);
2859
193
  apdu.data = sbuf + offs;
2860
193
  apdu.datalen = sizeof(sbuf) - offs;
2861
193
  apdu.lc = sizeof(sbuf) - offs;
2862
193
  apdu.resp = rbuf;
2863
193
  apdu.resplen = sizeof(rbuf);
2864
193
  apdu.le = 0x100;
2865
2866
193
  rv = sc_transmit_apdu(card, &apdu);
2867
193
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2868
190
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2869
190
  LOG_TEST_RET(ctx, rv, "SDO get data error");
2870
2871
173
  rv = iasecc_sdo_parse(card, apdu.resp, apdu.resplen, sdo);
2872
173
  LOG_TEST_RET(ctx, rv, "cannot parse SDO data");
2873
2874
2
  LOG_FUNC_RETURN(ctx, rv);
2875
2
}
2876
2877
2878
static int
2879
iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo)
2880
189
{
2881
189
  struct sc_context *ctx = card->ctx;
2882
189
  int rv, sdo_tag;
2883
2884
189
  LOG_FUNC_CALLED(ctx);
2885
2886
189
  sdo_tag = iasecc_sdo_tag_from_class(sdo->sdo_class);
2887
2888
189
  rv = iasecc_sdo_get_tagged_data(card, sdo_tag, sdo);
2889
  /* When there is no public data 'GET DATA' returns error */
2890
189
  if (rv != SC_ERROR_INCORRECT_PARAMETERS)
2891
189
    LOG_TEST_RET(ctx, rv, "cannot parse ECC SDO data");
2892
2893
6
  rv = iasecc_sdo_get_tagged_data(card, IASECC_DOCP_TAG, sdo);
2894
6
  LOG_TEST_RET(ctx, rv, "cannot parse ECC DOCP data");
2895
2896
0
  LOG_FUNC_RETURN(ctx, rv);
2897
0
}
2898
2899
2900
static int
2901
iasecc_sdo_generate(struct sc_card *card, struct iasecc_sdo *sdo)
2902
0
{
2903
0
  struct sc_context *ctx = card->ctx;
2904
0
  struct iasecc_sdo_update update_pubkey;
2905
0
  struct sc_apdu apdu;
2906
0
  unsigned char scb, sbuf[5], rbuf[0x400], exponent[3] = {0x01, 0x00, 0x01};
2907
0
  int offs = 0, rv = SC_ERROR_NOT_SUPPORTED;
2908
2909
0
  LOG_FUNC_CALLED(ctx);
2910
2911
0
  if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PRIVATE)
2912
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "For a moment, only RSA_PRIVATE class can be accepted for the SDO generation");
2913
2914
0
  if (sdo->docp.acls_contact.size == 0)
2915
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Bewildered ... there are no ACLs");
2916
2917
0
  scb = sdo->docp.scbs[IASECC_ACLS_RSAKEY_GENERATE];
2918
0
  sc_log(ctx, "'generate RSA key' SCB 0x%X", scb);
2919
0
  do   {
2920
0
    unsigned all_conditions = scb & IASECC_SCB_METHOD_NEED_ALL ? 1 : 0;
2921
2922
0
    if (scb & IASECC_SCB_METHOD_USER_AUTH)
2923
0
      if (!all_conditions)
2924
0
        break;
2925
2926
0
    if (scb & IASECC_SCB_METHOD_EXT_AUTH)
2927
0
      LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet");
2928
2929
0
    if (scb & IASECC_SCB_METHOD_SM)   {
2930
0
      rv = iasecc_sm_rsa_generate(card, scb & IASECC_SCB_METHOD_MASK_REF, sdo);
2931
0
                        LOG_FUNC_RETURN(ctx, rv);
2932
0
    }
2933
0
  } while(0);
2934
2935
0
  memset(&update_pubkey, 0, sizeof(update_pubkey));
2936
0
  update_pubkey.magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA;
2937
0
  update_pubkey.sdo_class = IASECC_SDO_CLASS_RSA_PUBLIC;
2938
0
  update_pubkey.sdo_ref = sdo->sdo_ref;
2939
2940
0
  update_pubkey.fields[0].parent_tag = IASECC_SDO_PUBKEY_TAG;
2941
0
  update_pubkey.fields[0].tag = IASECC_SDO_PUBKEY_TAG_E;
2942
0
  update_pubkey.fields[0].value = exponent;
2943
0
  update_pubkey.fields[0].size = sizeof(exponent);
2944
2945
0
  rv = iasecc_sdo_put_data(card, &update_pubkey);
2946
0
  LOG_TEST_RET(ctx, rv, "iasecc_sdo_generate() update SDO public key failed");
2947
2948
0
  offs = 0;
2949
0
  sbuf[offs++] = IASECC_SDO_TEMPLATE_TAG;
2950
0
  sbuf[offs++] = 0x03;
2951
0
  sbuf[offs++] = IASECC_SDO_TAG_HEADER;
2952
0
  sbuf[offs++] = IASECC_SDO_CLASS_RSA_PRIVATE | IASECC_OBJECT_REF_LOCAL;
2953
0
  sbuf[offs++] = sdo->sdo_ref & ~IASECC_OBJECT_REF_LOCAL;
2954
2955
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x47, 0x00, 0x00);
2956
0
  apdu.data = sbuf;
2957
0
  apdu.datalen = offs;
2958
0
  apdu.lc = offs;
2959
0
  apdu.resp = rbuf;
2960
0
  apdu.resplen = sizeof(rbuf);
2961
0
  apdu.le = 0x100;
2962
2963
0
  rv = sc_transmit_apdu(card, &apdu);
2964
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2965
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2966
0
  LOG_TEST_RET(ctx, rv, "SDO get data error");
2967
2968
0
  LOG_FUNC_RETURN(ctx, rv);
2969
0
}
2970
2971
2972
static int
2973
iasecc_get_chv_reference_from_se(struct sc_card *card, int *se_reference)
2974
0
{
2975
0
  struct sc_context *ctx = card->ctx;
2976
0
  struct iasecc_se_info se;
2977
0
  struct sc_crt crt;
2978
0
  int rv;
2979
2980
0
  LOG_FUNC_CALLED(ctx);
2981
2982
0
  if (!se_reference)
2983
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid arguments");
2984
2985
0
  memset(&se, 0, sizeof(se));
2986
0
  se.reference = *se_reference;
2987
2988
0
  rv = iasecc_se_get_info(card, &se);
2989
0
  LOG_TEST_RET(ctx, rv, "get SE info error");
2990
2991
0
  memset(&crt, 0, sizeof(crt));
2992
0
  crt.tag = IASECC_CRT_TAG_AT;
2993
0
  crt.usage = IASECC_UQB_AT_USER_PASSWORD;
2994
2995
0
  rv = iasecc_se_get_crt(card, &se, &crt);
2996
0
  LOG_TEST_RET(ctx, rv, "Cannot get 'USER PASSWORD' authentication template");
2997
2998
0
  sc_file_free(se.df);
2999
0
  LOG_FUNC_RETURN(ctx, crt.refs[0]);
3000
0
}
3001
3002
3003
static int
3004
iasecc_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
3005
205
{
3006
205
  struct sc_context *ctx = card->ctx;
3007
205
  struct iasecc_sdo *sdo = (struct iasecc_sdo *) ptr;
3008
3009
205
  switch (cmd) {
3010
205
  case SC_CARDCTL_GET_SERIALNR:
3011
205
    return iasecc_get_serialnr(card, (struct sc_serial_number *)ptr);
3012
0
  case SC_CARDCTL_IASECC_SDO_CREATE:
3013
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_CREATE: sdo_class %X", sdo->sdo_class);
3014
0
    return iasecc_sdo_create(card, (struct iasecc_sdo *) ptr);
3015
0
  case SC_CARDCTL_IASECC_SDO_DELETE:
3016
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_DELETE: sdo_class %X", sdo->sdo_class);
3017
0
    return iasecc_sdo_delete(card, (struct iasecc_sdo *) ptr);
3018
0
  case SC_CARDCTL_IASECC_SDO_PUT_DATA:
3019
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_PUT_DATA: sdo_class %X", sdo->sdo_class);
3020
0
    return iasecc_sdo_put_data(card, (struct iasecc_sdo_update *) ptr);
3021
0
  case SC_CARDCTL_IASECC_SDO_KEY_RSA_PUT_DATA:
3022
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_KEY_RSA_PUT_DATA");
3023
0
    return iasecc_sdo_key_rsa_put_data(card, (struct iasecc_sdo_rsa_update *) ptr);
3024
0
  case SC_CARDCTL_IASECC_SDO_GET_DATA:
3025
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_GET_DATA: sdo_class %X", sdo->sdo_class);
3026
0
    return iasecc_sdo_get_data(card, (struct iasecc_sdo *) ptr);
3027
0
  case SC_CARDCTL_IASECC_SDO_GENERATE:
3028
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_GET_DATA: sdo_class %X", sdo->sdo_class);
3029
0
    return iasecc_sdo_generate(card, (struct iasecc_sdo *) ptr);
3030
0
  case SC_CARDCTL_GET_SE_INFO:
3031
0
    sc_log(ctx, "CMD SC_CARDCTL_GET_SE_INFO: sdo_class %X", sdo->sdo_class);
3032
0
    return iasecc_se_get_info(card, (struct iasecc_se_info *) ptr);
3033
0
  case SC_CARDCTL_GET_CHV_REFERENCE_IN_SE:
3034
0
    sc_log(ctx, "CMD SC_CARDCTL_GET_CHV_REFERENCE_IN_SE");
3035
0
    return iasecc_get_chv_reference_from_se(card, (int *)ptr);
3036
0
  case SC_CARDCTL_IASECC_GET_FREE_KEY_REFERENCE:
3037
0
    sc_log(ctx, "CMD SC_CARDCTL_IASECC_GET_FREE_KEY_REFERENCE");
3038
0
    return iasecc_get_free_reference(card, (struct iasecc_ctl_get_free_reference *)ptr);
3039
205
  }
3040
0
  return SC_ERROR_NOT_SUPPORTED;
3041
205
}
3042
3043
3044
static int
3045
iasecc_decipher(struct sc_card *card,
3046
    const unsigned char *in, size_t in_len,
3047
    unsigned char *out, size_t out_len)
3048
0
{
3049
0
  struct sc_context *ctx = card->ctx;
3050
0
  struct sc_apdu apdu;
3051
0
  unsigned char sbuf[0x200];
3052
0
  unsigned char resp[SC_MAX_APDU_BUFFER_SIZE];
3053
0
  size_t offs;
3054
0
  int rv;
3055
3056
0
  LOG_FUNC_CALLED(ctx);
3057
0
  sc_log(card->ctx,
3058
0
         "crgram_len %"SC_FORMAT_LEN_SIZE_T"u;  outlen %"SC_FORMAT_LEN_SIZE_T"u",
3059
0
         in_len, out_len);
3060
0
  if (!out || !out_len || in_len > SC_MAX_APDU_BUFFER_SIZE)
3061
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3062
3063
0
  offs = 0;
3064
0
  sbuf[offs++] = 0x81;
3065
0
  memcpy(sbuf + offs, in, in_len);
3066
0
  offs += in_len;
3067
3068
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86);
3069
0
  apdu.flags |= SC_APDU_FLAGS_CHAINING;
3070
0
  apdu.data = sbuf;
3071
0
  apdu.datalen = offs;
3072
0
  apdu.lc = offs;
3073
0
  apdu.resp = resp;
3074
0
  apdu.resplen = sizeof(resp);
3075
0
  apdu.le = 256;
3076
3077
0
  rv = sc_transmit_apdu(card, &apdu);
3078
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3079
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3080
0
  LOG_TEST_RET(ctx, rv, "Card returned error");
3081
3082
0
  if (out_len > apdu.resplen)
3083
0
    out_len = apdu.resplen;
3084
3085
0
  memcpy(out, apdu.resp, out_len);
3086
0
  rv = (int)out_len;
3087
3088
0
  LOG_FUNC_RETURN(ctx, rv);
3089
0
}
3090
3091
3092
static int
3093
iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t in_len,
3094
        struct iasecc_qsign_data *out)
3095
0
{
3096
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
3097
3098
0
  int r = SC_ERROR_INTERNAL;
3099
0
  EVP_MD_CTX *mdctx = NULL;
3100
0
  EVP_MD *md = NULL;
3101
0
  SHA_CTX *md_data = NULL;
3102
0
  unsigned int md_out_len;
3103
0
  SHA_LONG pre_hash_Nl, *hh[5] = {NULL, NULL, NULL, NULL, NULL};
3104
0
  int jj, ii;
3105
0
  int hh_size = sizeof(SHA_LONG), hh_num = SHA_DIGEST_LENGTH / sizeof(SHA_LONG);
3106
3107
0
  LOG_FUNC_CALLED(ctx);
3108
3109
0
  if (!in || !in_len || !out)
3110
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3111
3112
0
  sc_log(ctx,
3113
0
         "sc_pkcs15_get_qsign_data() input data length %"SC_FORMAT_LEN_SIZE_T"u",
3114
0
         in_len);
3115
0
  memset(out, 0, sizeof(struct iasecc_qsign_data));
3116
3117
0
  md = sc_evp_md(ctx, "SHA1");
3118
0
  mdctx = EVP_MD_CTX_new();
3119
0
  if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
3120
0
    sc_log_openssl(ctx);
3121
0
    sc_log(ctx, "EVP_DigestInit_ex failed");
3122
0
    goto end;
3123
0
  }
3124
3125
0
  md_data = EVP_MD_CTX_md_data(mdctx);
3126
0
  if (md_data == NULL) {
3127
0
    sc_log_openssl(ctx);
3128
0
    sc_log(ctx, "Failed to find md_data");
3129
0
    r = SC_ERROR_NOT_SUPPORTED;
3130
0
    goto end;
3131
0
  }
3132
3133
0
  if (EVP_DigestUpdate(mdctx, in, in_len) != 1) {
3134
0
    sc_log_openssl(ctx);
3135
0
    sc_log(ctx, "EVP_DigestUpdate failed");
3136
0
    goto end;
3137
0
  }
3138
3139
0
  hh[0] = &md_data->h0;
3140
0
  hh[1] = &md_data->h1;
3141
0
  hh[2] = &md_data->h2;
3142
0
  hh[3] = &md_data->h3;
3143
0
  hh[4] = &md_data->h4;
3144
3145
0
  for (jj=0; jj<hh_num; jj++)
3146
0
    for(ii=0; ii<hh_size; ii++)
3147
0
      out->pre_hash[jj*hh_size + ii] = ((*hh[jj] >> 8*(hh_size-1-ii)) & 0xFF);
3148
0
  out->pre_hash_size = SHA_DIGEST_LENGTH;
3149
0
  sc_log(ctx, "Pre SHA1:%s", sc_dump_hex(out->pre_hash, out->pre_hash_size));
3150
3151
0
  pre_hash_Nl = md_data->Nl - (md_data->Nl % (sizeof(md_data->data) *8));
3152
0
  for (ii=0; ii<hh_size; ii++)   {
3153
0
    out->counter[ii] = (md_data->Nh >> 8*(hh_size-1-ii)) &0xFF;
3154
0
    out->counter[hh_size+ii] = (pre_hash_Nl >> 8*(hh_size-1-ii)) &0xFF;
3155
0
  }
3156
0
  for (ii=0, out->counter_long=0; ii<(int)sizeof(out->counter); ii++)
3157
0
    out->counter_long = out->counter_long*0x100 + out->counter[ii];
3158
0
  sc_log(ctx, "Pre counter(%li):%s", out->counter_long, sc_dump_hex(out->counter, sizeof(out->counter)));
3159
3160
0
  if (md_data->num)   {
3161
0
    memcpy(out->last_block, in + in_len - md_data->num, md_data->num);
3162
0
    out->last_block_size = md_data->num;
3163
0
    sc_log(ctx, "Last block(%"SC_FORMAT_LEN_SIZE_T"u):%s",
3164
0
           out->last_block_size,
3165
0
           sc_dump_hex(out->last_block, out->last_block_size));
3166
0
  }
3167
3168
0
  if (EVP_DigestFinal_ex(mdctx, out->hash, &md_out_len) != 1) {
3169
0
    sc_log_openssl(ctx);
3170
0
    sc_log(ctx, "EVP_DigestFinal_ex failed");
3171
0
    goto end;
3172
0
  }
3173
3174
0
  out->hash_size = SHA_DIGEST_LENGTH;
3175
0
  sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size));
3176
3177
0
  r = SC_SUCCESS;
3178
3179
0
end:
3180
0
  EVP_MD_CTX_free(mdctx);
3181
0
  sc_evp_md_free(md);
3182
3183
0
  LOG_FUNC_RETURN(ctx, r);
3184
3185
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
3186
  LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3187
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
3188
0
}
3189
3190
3191
static int
3192
iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len,
3193
        struct iasecc_qsign_data *out)
3194
0
{
3195
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
3196
3197
0
  int r = SC_ERROR_INTERNAL;
3198
0
  EVP_MD_CTX *mdctx = NULL;
3199
0
  EVP_MD *md = NULL;
3200
0
  SHA256_CTX *md_data;
3201
0
  unsigned int md_out_len;
3202
3203
0
  SHA_LONG pre_hash_Nl;
3204
0
  int jj, ii;
3205
0
  int hh_size = sizeof(SHA_LONG), hh_num = SHA256_DIGEST_LENGTH / sizeof(SHA_LONG);
3206
3207
0
  LOG_FUNC_CALLED(ctx);
3208
0
  if (!in || !in_len || !out)
3209
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3210
3211
0
  sc_log(ctx,
3212
0
         "sc_pkcs15_get_qsign_data() input data length %"SC_FORMAT_LEN_SIZE_T"u",
3213
0
         in_len);
3214
0
  memset(out, 0, sizeof(struct iasecc_qsign_data));
3215
3216
0
  md = sc_evp_md(ctx, "SHA256");
3217
0
  mdctx = EVP_MD_CTX_new();
3218
0
  if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) {
3219
0
    sc_log_openssl(ctx);
3220
0
    sc_log(ctx, "EVP_DigestInit_ex failed");
3221
0
    goto end;
3222
0
  }
3223
3224
0
  md_data = EVP_MD_CTX_md_data(mdctx);
3225
0
  if (md_data == NULL) {
3226
0
    sc_log_openssl(ctx);
3227
0
    sc_log(ctx, "Failed to find md_data");
3228
0
    r = SC_ERROR_NOT_SUPPORTED;
3229
0
    goto end;
3230
0
  }
3231
3232
0
  if (EVP_DigestUpdate(mdctx, in, in_len) != 1) {
3233
0
    sc_log_openssl(ctx);
3234
0
    sc_log(ctx, "EVP_DigestUpdate failed");
3235
0
    goto end;
3236
0
  }
3237
3238
0
  for (jj=0; jj<hh_num; jj++)
3239
0
    for(ii=0; ii<hh_size; ii++)
3240
0
      out->pre_hash[jj*hh_size + ii] = ((md_data->h[jj] >> 8*(hh_size-1-ii)) & 0xFF);
3241
0
  out->pre_hash_size = SHA256_DIGEST_LENGTH;
3242
0
  sc_log(ctx, "Pre hash:%s", sc_dump_hex(out->pre_hash, out->pre_hash_size));
3243
3244
0
  pre_hash_Nl = md_data->Nl - (md_data->Nl % (sizeof(md_data->data) * 8));
3245
0
  for (ii=0; ii<hh_size; ii++)   {
3246
0
    out->counter[ii] = (md_data->Nh >> 8*(hh_size-1-ii)) &0xFF;
3247
0
    out->counter[hh_size+ii] = (pre_hash_Nl >> 8*(hh_size-1-ii)) &0xFF;
3248
0
  }
3249
0
  for (ii=0, out->counter_long=0; ii<(int)sizeof(out->counter); ii++)
3250
0
    out->counter_long = out->counter_long*0x100 + out->counter[ii];
3251
0
  sc_log(ctx, "Pre counter(%li):%s", out->counter_long, sc_dump_hex(out->counter, sizeof(out->counter)));
3252
3253
0
  if (md_data->num)   {
3254
0
    memcpy(out->last_block, in + in_len - md_data->num, md_data->num);
3255
0
    out->last_block_size = md_data->num;
3256
0
    sc_log(ctx, "Last block(%"SC_FORMAT_LEN_SIZE_T"u):%s",
3257
0
           out->last_block_size,
3258
0
           sc_dump_hex(out->last_block, out->last_block_size));
3259
0
  }
3260
3261
0
  if (EVP_DigestFinal_ex(mdctx, out->hash, &md_out_len) != 1) {
3262
0
    sc_log_openssl(ctx);
3263
0
    sc_log(ctx, "EVP_DigestFinal_ex failed");
3264
0
    goto end;
3265
0
  }
3266
3267
0
  out->hash_size = SHA256_DIGEST_LENGTH;
3268
0
  sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size));
3269
3270
0
  r = SC_SUCCESS;
3271
3272
0
end:
3273
0
  EVP_MD_CTX_free(mdctx);
3274
0
  sc_evp_md_free(md);
3275
3276
0
  LOG_FUNC_RETURN(ctx, r);
3277
3278
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
3279
  LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3280
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
3281
0
}
3282
3283
3284
static int
3285
iasecc_compute_signature_dst(struct sc_card *card,
3286
    const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len)
3287
0
{
3288
0
  struct sc_context *ctx = card->ctx;
3289
0
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
3290
0
  struct sc_security_env *env = &prv->security_env;
3291
0
  struct iasecc_qsign_data qsign_data;
3292
0
  struct sc_apdu apdu;
3293
0
  size_t offs = 0, hash_len = 0;
3294
0
  unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE];
3295
0
  unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
3296
0
  int rv = SC_SUCCESS;
3297
3298
0
  LOG_FUNC_CALLED(ctx);
3299
0
  sc_log(ctx,
3300
0
         "iasecc_compute_signature_dst() input length %"SC_FORMAT_LEN_SIZE_T"u",
3301
0
         in_len);
3302
0
  if (env->operation != SC_SEC_OPERATION_SIGN)
3303
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "It's not SC_SEC_OPERATION_SIGN");
3304
0
  else if (!(prv->key_size & 0x1E0) || (prv->key_size & ~0x1E0))
3305
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key size for SC_SEC_OPERATION_SIGN");
3306
3307
0
  memset(&qsign_data, 0, sizeof(qsign_data));
3308
0
  if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1)   {
3309
0
    rv = iasecc_qsign_data_sha1(card->ctx, in, in_len, &qsign_data);
3310
0
  }
3311
0
  else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256)   {
3312
0
    rv = iasecc_qsign_data_sha256(card->ctx, in, in_len, &qsign_data);
3313
0
  }
3314
0
  else
3315
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_HASH_SHA1 or RSA_HASH_SHA256 algorithm");
3316
0
  LOG_TEST_RET(ctx, rv, "Cannot get QSign data");
3317
3318
0
  sc_log(ctx,
3319
0
         "iasecc_compute_signature_dst() hash_len %"SC_FORMAT_LEN_SIZE_T"u; key_size %"SC_FORMAT_LEN_SIZE_T"u",
3320
0
         hash_len, prv->key_size);
3321
3322
0
  memset(sbuf, 0, sizeof(sbuf));
3323
0
  sbuf[offs++] = 0x90;
3324
0
  if (qsign_data.counter_long)   {
3325
0
    sbuf[offs++] = qsign_data.hash_size + 8;
3326
0
    memcpy(sbuf + offs, qsign_data.pre_hash, qsign_data.pre_hash_size);
3327
0
    offs += qsign_data.pre_hash_size;
3328
0
    memcpy(sbuf + offs, qsign_data.counter, sizeof(qsign_data.counter));
3329
0
    offs += sizeof(qsign_data.counter);
3330
0
  }
3331
0
  else   {
3332
0
    sbuf[offs++] = 0;
3333
0
  }
3334
3335
0
  sbuf[offs++] = 0x80;
3336
0
  sbuf[offs++] = qsign_data.last_block_size;
3337
0
  memcpy(sbuf + offs, qsign_data.last_block, qsign_data.last_block_size);
3338
0
  offs += qsign_data.last_block_size;
3339
3340
0
  sc_log(ctx,
3341
0
         "iasecc_compute_signature_dst() offs %"SC_FORMAT_LEN_SIZE_T"u; OP(meth:%X,ref:%X)",
3342
0
         offs, prv->op_method, prv->op_ref);
3343
0
  if (prv->op_method == SC_AC_SCB && (prv->op_ref & IASECC_SCB_METHOD_SM))
3344
0
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet");
3345
3346
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x90, 0xA0);
3347
0
  apdu.data = sbuf;
3348
0
  apdu.datalen = offs;
3349
0
  apdu.lc = offs;
3350
3351
0
  rv = sc_transmit_apdu(card, &apdu);
3352
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3353
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3354
0
  LOG_TEST_RET(ctx, rv, "Compute signature failed");
3355
3356
0
  sc_log(ctx, "iasecc_compute_signature_dst() partial hash OK");
3357
3358
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x9E, 0x9A);
3359
0
  apdu.resp = rbuf;
3360
0
  apdu.resplen = prv->key_size;
3361
0
  apdu.le = prv->key_size;
3362
3363
0
  rv = sc_transmit_apdu(card, &apdu);
3364
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3365
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3366
0
  LOG_TEST_RET(ctx, rv, "Compute signature failed");
3367
3368
0
  sc_log(ctx,
3369
0
         "iasecc_compute_signature_dst() DST resplen %"SC_FORMAT_LEN_SIZE_T"u",
3370
0
         apdu.resplen);
3371
0
  if (apdu.resplen > out_len)
3372
0
    LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Result buffer too small for the DST signature");
3373
3374
0
  memcpy(out, apdu.resp, apdu.resplen);
3375
3376
0
  LOG_FUNC_RETURN(ctx, (int)apdu.resplen);
3377
0
}
3378
3379
3380
static int
3381
iasecc_compute_signature_at(struct sc_card *card,
3382
    const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len)
3383
0
{
3384
0
  struct sc_context *ctx = card->ctx;
3385
0
  struct iasecc_private_data *prv = (struct iasecc_private_data *)card->drv_data;
3386
0
  struct sc_security_env *env = &prv->security_env;
3387
0
  struct sc_apdu apdu;
3388
0
  size_t offs = 0, sz = 0;
3389
0
  unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
3390
0
  int rv;
3391
3392
0
  LOG_FUNC_CALLED(ctx);
3393
0
  if (env->operation != SC_SEC_OPERATION_AUTHENTICATE)
3394
0
    LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "It's not SC_SEC_OPERATION_AUTHENTICATE");
3395
3396
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, 0x00);
3397
0
  apdu.datalen = in_len;
3398
0
  apdu.data = in;
3399
0
  apdu.lc = in_len;
3400
0
  apdu.resp = rbuf;
3401
0
  apdu.resplen = sizeof(rbuf);
3402
0
  apdu.le = 0x100;
3403
3404
0
  rv = sc_transmit_apdu(card, &apdu);
3405
0
  LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3406
0
  rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3407
0
  LOG_TEST_RET(ctx, rv, "Compute signature failed");
3408
3409
0
  do   {
3410
0
    if (offs + apdu.resplen > out_len)
3411
0
      LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to return signature");
3412
3413
0
    memcpy(out + offs, rbuf, apdu.resplen);
3414
0
    offs += apdu.resplen;
3415
3416
0
    if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
3417
0
      break;
3418
3419
0
    if (apdu.sw1 == 0x61)   {
3420
0
      sz = apdu.sw2 == 0x00 ? 0x100 : apdu.sw2;
3421
0
      rv = iso_ops->get_response(card, &sz, rbuf);
3422
0
      LOG_TEST_RET(ctx, rv, "Get response error");
3423
3424
0
      apdu.resplen = rv;
3425
0
    }
3426
0
    else   {
3427
0
      LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Impossible error: SW1 is not 0x90 neither 0x61");
3428
0
    }
3429
3430
0
  } while(rv > 0);
3431
3432
0
  LOG_FUNC_RETURN(ctx, (int)offs);
3433
0
}
3434
3435
3436
static int
3437
iasecc_compute_signature(struct sc_card *card,
3438
    const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len)
3439
0
{
3440
0
  struct sc_context *ctx;
3441
0
  struct iasecc_private_data *prv;
3442
0
  struct sc_security_env *env;
3443
3444
0
  if (!card || !in || !out)
3445
0
    return SC_ERROR_INVALID_ARGUMENTS;
3446
3447
0
  ctx = card->ctx;
3448
0
  prv = (struct iasecc_private_data *)card->drv_data;
3449
0
  env = &prv->security_env;
3450
3451
0
  LOG_FUNC_CALLED(ctx);
3452
0
  sc_log(ctx,
3453
0
         "inlen %"SC_FORMAT_LEN_SIZE_T"u, outlen %"SC_FORMAT_LEN_SIZE_T"u",
3454
0
         in_len, out_len);
3455
3456
0
  if (env->operation == SC_SEC_OPERATION_SIGN)
3457
0
    return iasecc_compute_signature_dst(card, in, in_len, out,  out_len);
3458
0
  else if (env->operation == SC_SEC_OPERATION_AUTHENTICATE)
3459
0
    return iasecc_compute_signature_at(card, in, in_len, out,  out_len);
3460
3461
0
  LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3462
0
}
3463
3464
3465
static int
3466
iasecc_read_public_key(struct sc_card *card, unsigned type,
3467
    struct sc_path *key_path, unsigned ref, unsigned size,
3468
    unsigned char **out, size_t *out_len)
3469
0
{
3470
0
  struct sc_context *ctx = card->ctx;
3471
0
  struct iasecc_sdo sdo;
3472
0
  struct sc_pkcs15_bignum bn[2];
3473
0
  struct sc_pkcs15_pubkey_rsa rsa_key;
3474
0
  int rv;
3475
3476
0
  LOG_FUNC_CALLED(ctx);
3477
0
  if (type != SC_ALGORITHM_RSA)
3478
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3479
3480
0
  sc_log(ctx, "read public kay(ref:%i;size:%i)", ref, size);
3481
3482
0
  memset(&bn, 0, sizeof bn);
3483
0
  memset(&sdo, 0, sizeof(sdo));
3484
0
  sdo.sdo_class = IASECC_SDO_CLASS_RSA_PUBLIC;
3485
0
  sdo.sdo_ref  = ref & ~IASECC_OBJECT_REF_LOCAL;
3486
3487
0
  rv = iasecc_sdo_get_data(card, &sdo);
3488
0
  LOG_TEST_GOTO_ERR(ctx, rv, "failed to read public key: cannot get RSA SDO data");
3489
3490
0
  if (out)
3491
0
    *out = NULL;
3492
0
  if (out_len)
3493
0
    *out_len = 0;
3494
3495
0
  bn[0].data = (unsigned char *) malloc(sdo.data.pub_key.n.size);
3496
0
  if (!bn[0].data)
3497
0
    LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate modulus");
3498
0
  bn[0].len = sdo.data.pub_key.n.size;
3499
0
  memcpy(bn[0].data, sdo.data.pub_key.n.value, sdo.data.pub_key.n.size);
3500
3501
0
  bn[1].data = (unsigned char *) malloc(sdo.data.pub_key.e.size);
3502
0
  if (!bn[1].data)
3503
0
    LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate exponent");
3504
0
  bn[1].len = sdo.data.pub_key.e.size;
3505
0
  memcpy(bn[1].data, sdo.data.pub_key.e.value, sdo.data.pub_key.e.size);
3506
3507
0
  rsa_key.modulus = bn[0];
3508
0
  rsa_key.exponent = bn[1];
3509
3510
0
  rv = sc_pkcs15_encode_pubkey_rsa(ctx, &rsa_key, out, out_len);
3511
0
  LOG_TEST_GOTO_ERR(ctx, rv, "failed to read public key: cannot encode RSA public key");
3512
3513
0
  if (out && out_len)
3514
0
    sc_log(ctx, "encoded public key: %s", sc_dump_hex(*out, *out_len));
3515
3516
0
err:
3517
0
  if (bn[0].data)
3518
0
    free(bn[0].data);
3519
0
  if (bn[1].data)
3520
0
    free(bn[1].data);
3521
3522
0
  iasecc_sdo_free_fields(card, &sdo);
3523
3524
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3525
0
}
3526
3527
3528
static int
3529
iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_reference *ctl_data)
3530
0
{
3531
0
  struct sc_context *ctx = card->ctx;
3532
0
  struct iasecc_sdo *sdo = NULL;
3533
0
  int idx, rv;
3534
3535
0
  LOG_FUNC_CALLED(ctx);
3536
3537
0
  if ((ctl_data->key_size % 0x40) || ctl_data->index < 1 || (ctl_data->index > IASECC_OBJECT_REF_MAX))
3538
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3539
3540
0
  sc_log(ctx, "get reference for key(index:%i,usage:%X,access:%X)", ctl_data->index, ctl_data->usage, ctl_data->access);
3541
  /* TODO: when looking for the slot for the signature keys, check also PSO_SIGNATURE ACL */
3542
0
  for (idx = ctl_data->index; idx <= IASECC_OBJECT_REF_MAX; idx++)   {
3543
0
    unsigned char sdo_tag[3] = {
3544
0
      IASECC_SDO_TAG_HEADER, IASECC_OBJECT_REF_LOCAL | IASECC_SDO_CLASS_RSA_PRIVATE, idx
3545
0
    };
3546
0
    size_t sz;
3547
3548
0
    if (sdo)
3549
0
      iasecc_sdo_free(card, sdo);
3550
3551
0
    rv = iasecc_sdo_allocate_and_parse(card, sdo_tag, 3, &sdo);
3552
0
    LOG_TEST_RET(ctx, rv, "cannot parse SDO data");
3553
3554
0
    rv = iasecc_sdo_get_data(card, sdo);
3555
0
    if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND)   {
3556
0
      iasecc_sdo_free(card, sdo);
3557
3558
0
      sc_log(ctx, "found empty key slot %i", idx);
3559
0
      break;
3560
0
    } else if (rv != SC_SUCCESS) {
3561
0
      iasecc_sdo_free(card, sdo);
3562
3563
0
      sc_log(ctx, "get new key reference failed");
3564
0
      LOG_FUNC_RETURN(ctx, rv);
3565
0
    }
3566
3567
0
    sz = *(sdo->docp.size.value + 0) * 0x100 + *(sdo->docp.size.value + 1);
3568
0
    sc_log(ctx,
3569
0
           "SDO(idx:%i) size %"SC_FORMAT_LEN_SIZE_T"u; key_size %"SC_FORMAT_LEN_SIZE_T"u",
3570
0
           idx, sz, ctl_data->key_size);
3571
3572
0
    if (sz != ctl_data->key_size / 8)   {
3573
0
      sc_log(ctx,
3574
0
             "key index %i ignored: different key sizes %"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u",
3575
0
             idx, sz, ctl_data->key_size / 8);
3576
0
      continue;
3577
0
    }
3578
3579
0
    if (sdo->docp.non_repudiation.value)   {
3580
0
      sc_log(ctx, "non repudiation flag %X", sdo->docp.non_repudiation.value[0]);
3581
0
      if ((ctl_data->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) && !(*sdo->docp.non_repudiation.value))   {
3582
0
        sc_log(ctx, "key index %i ignored: need non repudiation", idx);
3583
0
        continue;
3584
0
      }
3585
3586
0
      if (!(ctl_data->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) && *sdo->docp.non_repudiation.value)   {
3587
0
        sc_log(ctx, "key index %i ignored: don't need non-repudiation", idx);
3588
0
        continue;
3589
0
      }
3590
0
    }
3591
3592
0
    if (ctl_data->access & SC_PKCS15_PRKEY_ACCESS_LOCAL)   {
3593
0
      if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_GENERATE] == IASECC_SCB_NEVER)   {
3594
0
        sc_log(ctx, "key index %i ignored: GENERATE KEY not allowed", idx);
3595
0
        continue;
3596
0
      }
3597
0
    }
3598
0
    else   {
3599
0
      if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_PUT_DATA] == IASECC_SCB_NEVER)   {
3600
0
        sc_log(ctx, "key index %i ignored: PUT DATA not allowed", idx);
3601
0
        continue;
3602
0
      }
3603
0
    }
3604
3605
0
    if ((ctl_data->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) && (ctl_data->usage & SC_PKCS15_PRKEY_USAGE_SIGN))   {
3606
0
      if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_PSO_SIGN] == IASECC_SCB_NEVER)   {
3607
0
        sc_log(ctx, "key index %i ignored: PSO SIGN not allowed", idx);
3608
0
        continue;
3609
0
      }
3610
0
    }
3611
0
    else if (ctl_data->usage & SC_PKCS15_PRKEY_USAGE_SIGN)   {
3612
0
      if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_INTERNAL_AUTH] == IASECC_SCB_NEVER)   {
3613
0
        sc_log(ctx, "key index %i ignored: INTERNAL AUTHENTICATE not allowed", idx);
3614
0
        continue;
3615
0
      }
3616
0
    }
3617
3618
0
    if (ctl_data->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP))   {
3619
0
      if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_PSO_DECIPHER] == IASECC_SCB_NEVER)   {
3620
0
        sc_log(ctx, "key index %i ignored: PSO DECIPHER not allowed", idx);
3621
0
        continue;
3622
0
      }
3623
0
    }
3624
3625
0
    break;
3626
0
  }
3627
3628
0
  ctl_data->index = idx;
3629
3630
0
  if (idx > IASECC_OBJECT_REF_MAX)
3631
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_DATA_OBJECT_NOT_FOUND);
3632
3633
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3634
0
}
3635
3636
3637
static struct sc_card_driver *
3638
sc_get_driver(void)
3639
14.0k
{
3640
14.0k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
3641
3642
14.0k
  if (!iso_ops)
3643
1
    iso_ops = iso_drv->ops;
3644
3645
14.0k
  iasecc_ops = *iso_ops;
3646
3647
14.0k
  iasecc_ops.match_card = iasecc_match_card;
3648
14.0k
  iasecc_ops.init = iasecc_init;
3649
14.0k
  iasecc_ops.finish = iasecc_finish;
3650
14.0k
  iasecc_ops.read_binary = iasecc_read_binary;
3651
  /*  write_binary: ISO7816 implementation works  */
3652
  /*  update_binary: ISO7816 implementation works */
3653
14.0k
  iasecc_ops.erase_binary = iasecc_erase_binary;
3654
  /*  resize_binary */
3655
  /*  read_record: Untested */
3656
  /*  write_record: Untested  */
3657
  /*  append_record: Untested */
3658
  /*  update_record: Untested */
3659
14.0k
  iasecc_ops.select_file = iasecc_select_file;
3660
  /*  get_response: Untested  */
3661
14.0k
  iasecc_ops.get_challenge = iasecc_get_challenge;
3662
14.0k
  iasecc_ops.logout = iasecc_logout;
3663
  /*  restore_security_env  */
3664
14.0k
  iasecc_ops.set_security_env = iasecc_set_security_env;
3665
14.0k
  iasecc_ops.decipher = iasecc_decipher;
3666
14.0k
  iasecc_ops.compute_signature = iasecc_compute_signature;
3667
14.0k
  iasecc_ops.create_file = iasecc_create_file;
3668
14.0k
  iasecc_ops.delete_file = iasecc_delete_file;
3669
  /*  list_files  */
3670
14.0k
  iasecc_ops.check_sw = iasecc_check_sw;
3671
14.0k
  iasecc_ops.card_ctl = iasecc_card_ctl;
3672
14.0k
  iasecc_ops.process_fci = iasecc_process_fci;
3673
  /*  construct_fci: Not needed */
3674
14.0k
  iasecc_ops.pin_cmd = iasecc_pin_cmd;
3675
  /*  get_data: Not implemented */
3676
  /*  put_data: Not implemented */
3677
  /*  delete_record: Not implemented  */
3678
3679
14.0k
  iasecc_ops.read_public_key = iasecc_read_public_key;
3680
3681
14.0k
  return &iasecc_drv;
3682
14.0k
}
3683
3684
struct sc_card_driver *
3685
sc_get_iasecc_driver(void)
3686
14.0k
{
3687
14.0k
  return sc_get_driver();
3688
14.0k
}
3689
3690
#else
3691
3692
/* we need to define the functions below to export them */
3693
#include "errors.h"
3694
3695
int
3696
iasecc_se_get_info()
3697
{
3698
  return SC_ERROR_NOT_SUPPORTED;
3699
}
3700
3701
#endif /* ENABLE_OPENSSL */