Coverage Report

Created: 2025-10-10 06:27

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