Coverage Report

Created: 2025-08-29 06:26

/src/opensc/src/libopensc/card-itacns.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * card-itacns.c: Support for Italian CNS
3
 *
4
 * Copyright (C) 2008-2010  Emanuele Pucciarelli <ep@acm.org>
5
 * Copyright (C) 2005     ST Incard srl, Giuseppe Amato <giuseppe dot amato at st dot com>, <midori3@gmail.com>
6
 * Copyright (C) 2002     Andreas Jellinghaus <aj@dungeon.inka.de>
7
 * Copyright (C) 2001     Juha Yrjölä <juha.yrjola@iki.fi>
8
 *
9
 * This library is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public
11
 * License as published by the Free Software Foundation; either
12
 * version 2.1 of the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public
20
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22
 */
23
24
/*
25
 * Specifications for the development of this driver come from:
26
 * http://www.cnipa.gov.it/html/docs/CNS%20Functional%20Specification%201.1.5_11012010.pdf
27
 */
28
29
#include "internal.h"
30
#include "cardctl.h"
31
#include "itacns.h"
32
#include <ctype.h>
33
#include <string.h>
34
#include <stdlib.h>
35
36
13.7k
#define ITACNS_MAX_PAYLOAD 0xff
37
38
static const struct sc_card_operations *default_ops = NULL;
39
40
static struct sc_card_operations itacns_ops;
41
static struct sc_card_driver itacns_drv = {
42
  "Italian CNS",
43
  "itacns",
44
  &itacns_ops,
45
  NULL, 0, NULL
46
};
47
48
/*
49
 * Card matching
50
 */
51
52
53
/* List of ATR's for "hard" matching. */
54
static const struct sc_atr_table itacns_atrs[] = {
55
  { "3b:f4:18:00:ff:81:31:80:55:00:31:80:00:c7", NULL, NULL,
56
    SC_CARD_TYPE_ITACNS_CIE_V1, 0, NULL},
57
  { "3b:8b:80:01:00:31:c1:64:00:00:00:00:00:00:00:00",
58
    "ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:00:00:00:00",
59
    "Idemia (Oberthur)", SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021, 0, NULL},
60
  { NULL, NULL, NULL, 0, 0, NULL}
61
};
62
63
/* Macro to access private driver data. */
64
3.35k
#define DRVDATA(card) ((itacns_drv_data_t *) card->drv_data)
65
66
static void itacns_init_cns_card(sc_card_t *card)
67
391
{
68
391
  if (15 != card->reader->atr_info.hist_bytes_len)
69
0
    return;
70
71
391
  u8 cns_version = card->reader->atr_info.hist_bytes[12];
72
391
  card->version.hw_major = (cns_version >> 4) & 0x0f;
73
391
  card->version.hw_minor = cns_version & 0x0f;
74
75
  /* Warn if version is not 1.X. */
76
391
  if (cns_version != 0x10 && cns_version != 0x11) {
77
360
    char version[8];
78
360
    snprintf(version, sizeof(version), "%d.%d", card->version.hw_major, card->version.hw_minor);
79
360
    sc_log(card->ctx, "CNS card version %s; no official specifications "
80
360
           "are published. Proceeding anyway.\n", version);
81
360
  }
82
391
}
83
84
static int itacns_match_cns_card(sc_card_t *card)
85
26.0k
{
86
26.0k
  u8 manufacturer_code;
87
26.0k
  u8 manufacturer_mask;
88
26.0k
  u8 fw_major;
89
90
26.0k
  if (15 != card->reader->atr_info.hist_bytes_len ||
91
26.0k
      0 != memcmp(card->reader->atr_info.hist_bytes+9, "CNS", 3))
92
25.6k
    return 0;
93
94
412
  card->type = SC_CARD_TYPE_ITACNS_CNS;
95
96
412
  manufacturer_code = card->reader->atr_info.hist_bytes[2];
97
412
  manufacturer_mask = card->reader->atr_info.hist_bytes[3];
98
412
  fw_major = card->reader->atr_info.hist_bytes[4];
99
100
412
  if (manufacturer_code == ITACNS_ICMAN_INFINEON &&
101
412
      manufacturer_mask == ITACNS_MASKMAN_IDEMIA &&
102
412
      fw_major >= 32) {
103
21
      card->type = SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021;
104
21
  }
105
106
412
  return 1;
107
26.0k
}
108
109
static int itacns_match_cie_card(sc_card_t *card)
110
25.6k
{
111
25.6k
  u8 h7_to_h15[] = { 0x02, 'I', 'T', 'I', 'D', 0x20, 0x20, 0x31, 0x80, };
112
25.6k
  if (15 != card->reader->atr_info.hist_bytes_len ||
113
25.6k
      0 != memcmp(card->reader->atr_info.hist_bytes+6,
114
1.05k
      h7_to_h15, sizeof h7_to_h15))
115
25.4k
    return 0;
116
117
200
  card->type = SC_CARD_TYPE_ITACNS_CIE_V2;
118
200
  return 1;
119
25.6k
}
120
121
static int itacns_match_card(sc_card_t *card)
122
26.9k
{
123
26.9k
  int r = 0;
124
125
  /* Try table first */
126
26.9k
  r = _sc_match_atr(card, itacns_atrs, &card->type);
127
26.9k
  if(r >= 0) return 1;
128
129
26.0k
  if (itacns_match_cns_card(card)) return 1;
130
25.6k
  if (itacns_match_cie_card(card)) return 1;
131
132
  /* No card type was matched. */
133
25.4k
  return 0;
134
25.6k
}
135
136
/*
137
 * Initialization and termination
138
 */
139
140
static int itacns_init(sc_card_t *card)
141
1.55k
{
142
1.55k
  unsigned long flags;
143
144
1.55k
  SC_FUNC_CALLED(card->ctx, 1);
145
146
1.55k
  card->name = "CNS card";
147
1.55k
  card->cla = 0x00;
148
149
1.55k
  card->drv_data = calloc(1, sizeof(itacns_drv_data_t));
150
1.55k
  if (!card->drv_data)
151
0
    return SC_ERROR_OUT_OF_MEMORY;
152
153
1.55k
  if (card->type == SC_CARD_TYPE_ITACNS_CNS)
154
391
    itacns_init_cns_card(card);
155
156
1.55k
  DRVDATA(card)->ic_manufacturer_code = card->reader->atr_info.hist_bytes[2];
157
1.55k
  DRVDATA(card)->mask_manufacturer_code = card->reader->atr_info.hist_bytes[3];
158
1.55k
  card->version.fw_major = card->reader->atr_info.hist_bytes[4];
159
1.55k
  card->version.fw_minor = card->reader->atr_info.hist_bytes[5];
160
161
  /* Set up algorithm info. */
162
1.55k
  flags = SC_ALGORITHM_NEED_USAGE
163
1.55k
    | SC_ALGORITHM_RSA_RAW
164
1.55k
    | SC_ALGORITHM_RSA_HASHES
165
1.55k
    ;
166
167
1.55k
  if ((card->version.hw_major >= 1 && card->version.hw_minor >= 1) ||
168
1.55k
      card->type == SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021) {
169
819
    card->caps |= SC_CARD_CAP_APDU_EXT;
170
819
    _sc_card_add_rsa_alg(card, 2048, flags, 0);
171
819
  } else {
172
731
    _sc_card_add_rsa_alg(card, 1024, flags, 0);
173
731
  }
174
1.55k
  return SC_SUCCESS;
175
1.55k
}
176
177
static int itacns_finish(struct sc_card *card)
178
1.55k
{
179
1.55k
  if(card->drv_data) {
180
1.55k
    free(card->drv_data);
181
1.55k
  }
182
1.55k
  return 0;
183
1.55k
}
184
185
186
187
/*
188
 * Restore the indicated SE
189
 */
190
static int itacns_restore_security_env(sc_card_t *card, int se_num)
191
0
{
192
0
  sc_apdu_t apdu;
193
0
  int r;
194
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
195
196
0
  SC_FUNC_CALLED(card->ctx, 1);
197
198
  /*
199
   * The Italian CNS requires a 0-valued Lc byte at the end of the APDU
200
   * (see paragraph 13.14 of the Functional Specification), but since
201
   * it is invalid, we "cheat" and pretend it's a Le byte.
202
   *
203
   * For this workaround, we must allocate and supply a response buffer,
204
   * even though we know it will not be used (we don't even check it).
205
   */
206
207
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x22, 0xF3, se_num);
208
0
  apdu.resp = rbuf;
209
0
  apdu.resplen = sizeof(rbuf);
210
0
  apdu.le = 0;
211
212
0
  r = sc_transmit_apdu(card, &apdu);
213
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
214
215
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
216
0
  LOG_TEST_RET(card->ctx, r, "Card returned error");
217
218
0
  SC_FUNC_RETURN(card->ctx, 1, r);
219
0
}
220
221
/*
222
 * Set the security context
223
 * Things get a little messy here. It seems you cannot do any
224
 * crypto without a security environment - but there isn't really
225
 * a way to specify the security environment in PKCS15.
226
 * What I'm doing here (for now) is to assume that for a key
227
 * object with ID 0xNN there is always a corresponding SE object
228
 * with the same ID.
229
 * XXX Need to find out how the Aladdin drivers do it.
230
 */
231
static int itacns_set_security_env(sc_card_t *card,
232
        const sc_security_env_t *env, int se_num)
233
0
{
234
0
  sc_apdu_t apdu;
235
0
  u8  data[3];
236
0
  int key_id, r;
237
238
  /* Do not complain about se_num; the argument is part of the API. */
239
0
  (void) se_num;
240
241
0
  assert(card != NULL && env != NULL);
242
243
0
  if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
244
0
   || env->key_ref_len != 1) {
245
0
    sc_log(card->ctx,
246
0
      "No or invalid key reference\n");
247
0
    return SC_ERROR_INVALID_ARGUMENTS;
248
0
  }
249
0
  key_id = env->key_ref[0];
250
251
  /* CIE v1 cards need to restore security environment 0x30; all the others
252
     so far want 0x03. */
253
0
  r = itacns_restore_security_env(card,
254
0
    (card->type == SC_CARD_TYPE_ITACNS_CIE_V1 ? 0x30 : 0x03));
255
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
256
257
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF1, 0);
258
0
  switch (env->operation) {
259
0
  case SC_SEC_OPERATION_DECIPHER:
260
0
    apdu.p2 = 0xB8;
261
0
    break;
262
0
  case SC_SEC_OPERATION_SIGN:
263
0
    apdu.p2 = 0xB6;
264
0
    break;
265
0
  default:
266
0
    return SC_ERROR_INVALID_ARGUMENTS;
267
0
  }
268
269
0
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
270
0
    "Setting sec env for key_id=%d\n", key_id);
271
272
0
  data[0] = 0x83;
273
0
  data[1] = 0x01;
274
0
  data[2] = key_id;
275
0
  apdu.lc = apdu.datalen = 3;
276
0
  apdu.data = data;
277
278
0
  r = sc_transmit_apdu(card, &apdu);
279
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
280
281
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
282
0
  LOG_TEST_RET(card->ctx, r, "Card returned error");
283
284
0
  SC_FUNC_RETURN(card->ctx, 1, r);
285
0
}
286
287
/*
288
 * The 0x80 thing tells the card it's okay to search parent
289
 * directories as well for the referenced object.
290
 * This is necessary for some Italian CNS cards, and to be avoided
291
 * for others. Right now it seems that it is only needed with
292
 * cards by STIncard.
293
 */
294
static int
295
itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
296
     int *tries_left)
297
87
{
298
87
  data->flags |= SC_PIN_CMD_NEED_PADDING;
299
  /* Enable backtracking for STIncard cards. */
300
87
  if(DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_STINCARD) {
301
7
    data->pin_reference |= 0x80;
302
7
  }
303
304
  /* FIXME: the following values depend on what pin length was
305
   * used when creating the BS objects */
306
87
  if (data->pin1.max_length == 0)
307
87
    data->pin1.max_length = 8;
308
87
  if (data->pin2.max_length == 0)
309
87
    data->pin2.max_length = 8;
310
87
  return default_ops->pin_cmd(card, data, tries_left);
311
87
}
312
313
static int itacns_read_binary(sc_card_t *card,
314
             unsigned int idx, u8 *buf, size_t count,
315
             unsigned long *flags)
316
7.75k
{
317
7.75k
  size_t already_read = 0;
318
7.75k
  size_t requested;
319
7.75k
  int r;
320
8.44k
  while(1) {
321
8.44k
    requested = count - already_read;
322
8.44k
    if(requested > ITACNS_MAX_PAYLOAD)
323
5.27k
      requested = ITACNS_MAX_PAYLOAD;
324
8.44k
    r = default_ops->read_binary(card, (unsigned)(idx + already_read),
325
8.44k
      &buf[already_read], requested, flags);
326
8.44k
    if(r < 0)
327
876
      return r;
328
7.57k
    already_read += r;
329
7.57k
    if (r == 0 || (size_t)r < requested || already_read == count) {
330
      /* We have finished */
331
6.87k
      return (int)already_read;
332
6.87k
    }
333
7.57k
  }
334
7.75k
}
335
336
56
static int itacns_list_files(sc_card_t *card, u8 *buf, size_t buflen) {
337
56
  struct sc_card_operations *list_ops;
338
339
56
  if (DRVDATA(card) && (DRVDATA(card)->mask_manufacturer_code
340
56
    == ITACNS_MASKMAN_SIEMENS)) {
341
1
    list_ops = sc_get_cardos_driver()->ops;
342
55
  } else {
343
    // incrypto34 no longer supported
344
55
    return SC_ERROR_NO_CARD_SUPPORT;
345
55
  }
346
1
  return list_ops->list_files(card, buf, buflen);
347
56
}
348
349
static void add_acl_entry(sc_file_t *file, int op, u8 byte)
350
9.24k
{
351
9.24k
  unsigned int method, key_ref = SC_AC_KEY_REF_NONE;
352
353
9.24k
  switch (byte) {
354
221
  case 0x00:
355
221
    method = SC_AC_NONE;
356
221
    break;
357
8.52k
  case 0xFF:
358
8.58k
  case 0x66:
359
8.58k
    method = SC_AC_NEVER;
360
8.58k
    break;
361
443
  default:
362
443
    if (byte > 0x1F) {
363
290
      method = SC_AC_UNKNOWN;
364
290
    } else {
365
153
      method = SC_AC_CHV;
366
153
      key_ref = byte;
367
153
    }
368
443
    break;
369
9.24k
  }
370
9.24k
  sc_file_add_acl_entry(file, op, method, key_ref);
371
9.24k
}
372
373
static const int df_acl[9] = {
374
  -1,     /* LCYCLE (life cycle change) */
375
  SC_AC_OP_UPDATE,  /* UPDATE Objects */
376
  SC_AC_OP_WRITE,   /* APPEND Objects */
377
378
  SC_AC_OP_INVALIDATE,  /* DF */
379
  SC_AC_OP_REHABILITATE,  /* DF */
380
  SC_AC_OP_DELETE,  /* DF */
381
382
  SC_AC_OP_WRITE,   /* ADMIN DF */
383
  SC_AC_OP_CREATE,  /* Files */
384
  -1      /* Reserved */
385
};
386
static const int ef_acl[9] = {
387
  SC_AC_OP_READ,    /* Data */
388
  SC_AC_OP_UPDATE,  /* Data (write file content) */
389
  SC_AC_OP_WRITE,   /* */
390
391
  SC_AC_OP_INVALIDATE,  /* EF */
392
  SC_AC_OP_REHABILITATE,  /* EF */
393
  SC_AC_OP_ERASE,   /* (delete) EF */
394
395
  /* XXX: ADMIN should be an ACL type of its own, or mapped
396
   * to erase */
397
  SC_AC_OP_ERASE,   /* ADMIN EF (modify meta information?) */
398
  -1,     /* INC (-> cyclic fixed files) */
399
  -1      /* DEC */
400
};
401
402
static void parse_sec_attr(sc_file_t *file, const u8 *buf, size_t len)
403
1.32k
{
404
1.32k
  size_t i;
405
1.32k
  const int *idx;
406
407
1.32k
  idx = (file->type == SC_FILE_TYPE_DF) ?  df_acl : ef_acl;
408
409
  /* acl defaults to 0xFF if unspecified */
410
13.2k
  for (i = 0; i < 9; i++) {
411
11.8k
    if (idx[i] != -1) {
412
9.24k
      add_acl_entry(file, idx[i],
413
9.24k
        (u8)((i < len) ? buf[i] : 0xFF));
414
9.24k
    }
415
11.8k
  }
416
1.32k
}
417
418
static int itacns_select_file(sc_card_t *card,
419
            const sc_path_t *in_path,
420
            sc_file_t **file)
421
13.1k
{
422
13.1k
  int r;
423
424
13.1k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
425
13.1k
  r = default_ops->select_file(card, in_path, file);
426
13.1k
  if (r >= 0 && file) {
427
1.32k
    parse_sec_attr((*file), (*file)->sec_attr,
428
1.32k
      (*file)->sec_attr_len);
429
1.32k
  }
430
13.1k
  LOG_FUNC_RETURN(card->ctx, r);
431
13.1k
}
432
433
static int itacns_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
434
87
{
435
87
  sc_path_t path;
436
87
  sc_file_t *file;
437
87
  size_t    len;
438
87
  int r;
439
87
  u8        rbuf[256];
440
441
87
  if (!serial) return SC_ERROR_INVALID_ARGUMENTS;
442
443
  /* see if we have cached serial number */
444
87
  if (card->serialnr.len) {
445
0
    memcpy(serial, &card->serialnr, sizeof(*serial));
446
0
    return SC_SUCCESS;
447
0
  }
448
449
87
  sc_log(card->ctx, "Reading EF_IDCarta.\n");
450
451
87
  sc_format_path("3F0010001003", &path);
452
453
87
  r = sc_select_file(card, &path, &file);
454
87
  if (r != SC_SUCCESS) {
455
40
    return SC_ERROR_WRONG_CARD;
456
40
  }
457
47
  len = file->size;
458
47
  sc_file_free(file);
459
460
  //Returned file->size should be 16.
461
  //We choose to not consider it as critical, because some cards
462
  //do not return FCI/FCP templates that include the file size.
463
  //Notify abnormal length anyway.
464
47
  if (len != 16) {
465
42
    sc_log(card->ctx,
466
42
        "Unexpected file length of EF_IDCarta (%lu)\n",
467
42
        (unsigned long) len);
468
42
  }
469
470
47
  r = sc_read_binary(card, 0, rbuf, 256, 0);
471
47
  if ( r != 16 ) {
472
42
    return SC_ERROR_WRONG_CARD;
473
42
  }
474
475
  /* cache serial number */
476
5
  memcpy(card->serialnr.value, rbuf, 16);
477
5
  card->serialnr.len = 16;
478
  /* copy and return serial number */
479
5
  memcpy(serial, &card->serialnr, sizeof(*serial));
480
481
5
  return SC_SUCCESS;
482
47
}
483
484
static int
485
itacns_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
486
3.12k
{
487
3.12k
  switch (cmd) {
488
87
    case SC_CARDCTL_GET_SERIALNR:
489
87
    return itacns_get_serialnr(card, ptr);
490
3.12k
  }
491
3.04k
  return SC_ERROR_NOT_SUPPORTED;
492
3.12k
}
493
494
static int
495
itacns_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
496
723
{
497
723
  if (card->type == SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021)
498
434
    len = MIN (0x20, len);
499
500
723
  return default_ops->get_challenge(card, rnd, len);
501
723
}
502
503
static struct sc_card_driver * sc_get_driver(void)
504
99.7k
{
505
99.7k
  if (!default_ops)
506
10
    default_ops = sc_get_iso7816_driver()->ops;
507
99.7k
  itacns_ops = *default_ops;
508
99.7k
  itacns_ops.match_card = itacns_match_card;
509
99.7k
  itacns_ops.init = itacns_init;
510
99.7k
  itacns_ops.finish = itacns_finish;
511
99.7k
  itacns_ops.set_security_env = itacns_set_security_env;
512
99.7k
  itacns_ops.restore_security_env = itacns_restore_security_env;
513
99.7k
  itacns_ops.pin_cmd = itacns_pin_cmd;
514
99.7k
  itacns_ops.read_binary = itacns_read_binary;
515
99.7k
  itacns_ops.list_files = itacns_list_files;
516
99.7k
  itacns_ops.select_file = itacns_select_file;
517
99.7k
  itacns_ops.card_ctl = itacns_card_ctl;
518
99.7k
  itacns_ops.get_challenge = itacns_get_challenge;
519
99.7k
  return &itacns_drv;
520
99.7k
}
521
522
struct sc_card_driver * sc_get_itacns_driver(void)
523
99.7k
{
524
99.7k
  return sc_get_driver();
525
99.7k
}