Coverage Report

Created: 2026-01-09 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-idprime.c
Line
Count
Source
1
/*
2
 * card-idprime.c: Support for Gemalto IDPrime smart cards
3
 *
4
 * Copyright (c) 2019 Red Hat, Inc.
5
 *
6
 * Author: Jakub Jelen <jjelen@redhat.com>
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
#ifdef HAVE_CONFIG_H
24
#include "config.h"
25
#endif
26
27
#include "internal.h"
28
#include <stddef.h>
29
#include <stdlib.h>
30
#include <string.h>
31
32
#include "cardctl.h"
33
#include "pkcs15.h"
34
35
static const struct sc_card_operations *iso_ops = NULL;
36
37
static struct sc_card_operations idprime_ops;
38
static struct sc_card_driver idprime_drv = {
39
  "Gemalto IDPrime",
40
  "idprime",
41
  &idprime_ops,
42
  NULL, 0, NULL
43
};
44
45
/* This ATR says, there is no EF.DIR nor EF.ATR so ISO discovery mechanisms
46
 * are not useful here */
47
// clang-format off
48
static const struct sc_atr_table idprime_atrs[] = {
49
  /* known ATRs for IDPrime 3810:
50
   * 3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00    Jakuje/xhanulik
51
   */
52
  { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00",
53
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff",
54
    "Gemalto IDPrime 3810",
55
    SC_CARD_TYPE_IDPRIME_3810, 0, NULL },
56
  /* known ATRs for IDPrime 930:
57
   * 3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00    Jakuje/xhanulik
58
   */
59
  { "3b:7f:96:00:00:80:31:80:65:b0:84:56:51:10:12:0f:fe:82:90:00",
60
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff",
61
    "Gemalto IDPrime 830",
62
    SC_CARD_TYPE_IDPRIME_830, 0, NULL },
63
  /* known ATRs for IDPrime 930:
64
   * 3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fd:82:90:00    Jakuje/xhanulik
65
   */
66
  { "3b:7f:96:00:00:80:31:80:65:b0:84:61:60:fb:12:0f:fe:82:90:00",
67
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff",
68
    "Gemalto IDPrime 930/3930",
69
    SC_CARD_TYPE_IDPRIME_930, 0, NULL },
70
  /* known ATRs:
71
   * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85    metsma
72
   */
73
  { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:84:65:66:fb:12:01:78:82:90:00:85",
74
    "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:ff:ff:ff:ff:ff:ff:00",
75
    "based Gemalto IDPrime 930 (eToken 5110+ FIPS)",
76
    SC_CARD_TYPE_IDPRIME_930_PLUS, 0, NULL },
77
  /* known ATR for IDPrime 940: Placing in front of the 940 as its mask overlaps this one!
78
   * 3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00   msetina
79
   */
80
  { "3b:7f:96:00:00:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00",
81
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff",
82
    "Gemalto IDPrime 840",
83
    SC_CARD_TYPE_IDPRIME_840, 0, NULL },
84
  /* known ATR for IDPrime 940:
85
   * 3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00    Jakuje/xhanulik, msetina, kirichkov
86
   */
87
  { "3b:7f:96:00:00:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00",
88
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:ff:00:00:ff:ff:ff",
89
    "Gemalto IDPrime 940",
90
    SC_CARD_TYPE_IDPRIME_940, 0, NULL },
91
  /* Known ATRs:
92
   * 3b:7f:96:00:00:80:31:80:65:b0:85:05:00:39:12:0f:fe:82:90:00    vbonamy
93
   */
94
  { "3b:7f:96:00:00:80:31:80:65:b0:85:05:00:39:12:0f:fe:82:90:00",
95
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:ff:ff:ff",
96
    "Gemalto IDPrime 940C",
97
    SC_CARD_TYPE_IDPRIME_940, 0, NULL },
98
  /* Known ATRs for IDPrime 940 (eToken 5110)
99
   * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00    metsma, jurajsarinay
100
   * 3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:01:78:82:90:00:88    hardening
101
   */
102
  { "3b:ff:96:00:00:81:31:fe:43:80:31:80:65:b0:85:59:56:fb:12:0f:fe:82:90:00:00",
103
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:f0:00:ff:ff:ff:00",
104
    "Gemalto IDPrime MD 940 (eToken 5110)",
105
    SC_CARD_TYPE_IDPRIME_940, 0, NULL },
106
  { "3b:7f:96:00:00:80:31:80:65:b0:84:41:3d:f6:12:0f:fe:82:90:00",
107
    "ff:ff:00:ff:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:00:00:ff:ff:ff",
108
    "Gemalto IDPrime MD 8840, 3840, 3810, 840, 830 and MD 940 Cards",
109
    SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL },
110
  /* Known ATRs: Overlaps partially with 930 and 940
111
   * 3b:ff:96:00:00:81:31:80:43:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00:66    metsma
112
   */
113
  { "3b:ff:96:00:00:81:31:80:43:80:31:80:65:b0:85:03:00:ef:12:0f:fe:82:90:00:66",
114
    "ff:ff:00:ff:ff:ff:ff:00:ff:ff:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:00",
115
    "Gemalto IDPrime MD 8840, 3840, 3810, 840 and 830 Cards (eToken)",
116
    SC_CARD_TYPE_IDPRIME_GENERIC, 0, NULL },
117
  { NULL, NULL, NULL, 0, 0, NULL }
118
};
119
// clang-format on
120
121
static const sc_path_t idprime_path = {
122
  "", 0,
123
  0, 0, SC_PATH_TYPE_DF_NAME,
124
  { "\xA0\x00\x00\x00\x18\x80\x00\x00\x00\x06\x62", 11 }
125
};
126
127
/* data structures to store meta data about IDPrime objects */
128
typedef struct idprime_object {
129
  int fd;
130
  int key_reference;
131
  int valid_key_ref;
132
  u8 df[2];
133
  unsigned short length;
134
  int pin_index;
135
} idprime_object_t;
136
137
/*
138
 * IDPrime Container structure
139
 * Simplification of auxiliary data from aux-data.c
140
 */
141
3.66k
#define MAX_CONTAINER_NAME_LEN 39
142
5.67k
#define CONTAINER_OBJ_LEN 86
143
typedef struct idprime_container {
144
  uint8_t index;              /* Index of the container */
145
  char guid[MAX_CONTAINER_NAME_LEN + 1];  /* Container name */
146
} idprime_container_t;
147
148
/*
149
 * IDPrime key reference structure
150
 */
151
11.7k
#define KEYREF_OBJ_LEN 8
152
typedef struct idprime_keyref {
153
  uint8_t index;          /* Index of the key reference */
154
  uint8_t pin_index;        /* Index of the auth pin used for accessing key */
155
  int key_reference;  /* Key reference used for accessing key */
156
} idprime_keyref_t;
157
158
/*
159
 * IDPrime private data per card state
160
 */
161
typedef struct idprime_private_data {
162
  u8 *cache_buf;        /* cached version of the currently selected file */
163
  size_t cache_buf_len;     /* length of the cached selected file */
164
  int cached;       /* is the cached selected file valid */
165
  size_t file_size;     /* this is real file size since IDPrime is quite strict about lengths */
166
  list_t pki_list;      /* list of pki containers */
167
  idprime_object_t *pki_current;    /* current pki object _ctl function */
168
  int tinfo_present;      /* Token Info Label object is present*/
169
  u8 tinfo_df[2];       /* DF of object with Token Info Label */
170
  unsigned long current_op;   /* current operation set by idprime_set_security_env */
171
  list_t containers;      /* list of private key containers */
172
  list_t keyrefmap;     /* list of key references for private keys */
173
} idprime_private_data_t;
174
175
/* For SimCList autocopy, we need to know the size of the data elements */
176
1.54k
static size_t idprime_list_meter(const void *el) {
177
1.54k
  return sizeof(idprime_object_t);
178
1.54k
}
179
180
179
static size_t idprime_container_list_meter(const void *el) {
181
179
  return sizeof(idprime_container_t);
182
179
}
183
184
10.1k
static size_t idprime_keyref_list_meter(const void *el) {
185
10.1k
  return sizeof(idprime_keyref_t);
186
10.1k
}
187
188
static int idprime_add_container_to_list(list_t *list, const idprime_container_t *container)
189
179
{
190
179
  if (list_append(list, container) < 0)
191
0
    return SC_ERROR_INTERNAL;
192
179
  return SC_SUCCESS;
193
179
}
194
195
static int idprime_container_list_seeker(const void *el, const void *key)
196
348
{
197
348
  const idprime_container_t *container = (idprime_container_t *)el;
198
199
348
  if ((el == NULL) || (key == NULL))
200
0
    return 0;
201
348
  if (container->index == *(uint8_t *)key)
202
332
    return 1;
203
16
  return 0;
204
348
}
205
206
static int idprime_add_keyref_to_list(list_t *list, const idprime_keyref_t *keyref)
207
10.1k
{
208
10.1k
  if (list_append(list, keyref) < 0)
209
0
    return SC_ERROR_INTERNAL;
210
10.1k
  return SC_SUCCESS;
211
10.1k
}
212
213
static int idprime_keyref_list_seeker(const void *el, const void *key)
214
183
{
215
183
  const idprime_keyref_t *keyref = (idprime_keyref_t *)el;
216
217
183
  if ((el == NULL) || (key == NULL))
218
0
    return 0;
219
183
  if (keyref->index == *(uint8_t *)key)
220
68
    return 1;
221
115
  return 0;
222
183
}
223
224
void idprime_free_private_data(idprime_private_data_t *priv)
225
513
{
226
513
  free(priv->cache_buf);
227
513
  list_destroy(&priv->pki_list);
228
513
  list_destroy(&priv->containers);
229
513
  list_destroy(&priv->keyrefmap);
230
513
  free(priv);
231
513
  return;
232
513
}
233
234
idprime_private_data_t *idprime_new_private_data(void)
235
513
{
236
513
  idprime_private_data_t *priv;
237
238
513
  priv = calloc(1, sizeof(idprime_private_data_t));
239
513
  if (priv == NULL)
240
0
    return NULL;
241
242
  /* Initialize PKI Applets list */
243
513
  if (list_init(&priv->pki_list) != 0 ||
244
513
      list_attributes_copy(&priv->pki_list, idprime_list_meter, 1) != 0) {
245
0
    idprime_free_private_data(priv);
246
0
    return NULL;
247
0
  }
248
249
  /* Initialize container list */
250
513
  if (list_init(&priv->containers) != 0 ||
251
513
      list_attributes_copy(&priv->containers, idprime_container_list_meter, 1) != 0 ||
252
513
      list_attributes_seeker(&priv->containers, idprime_container_list_seeker) != 0) {
253
0
    idprime_free_private_data(priv);
254
0
    return NULL;
255
0
  }
256
257
  /* Initialize keyref list */
258
513
  if (list_init(&priv->keyrefmap) != 0 ||
259
513
      list_attributes_copy(&priv->keyrefmap, idprime_keyref_list_meter, 1) != 0 ||
260
513
      list_attributes_seeker(&priv->keyrefmap, idprime_keyref_list_seeker) != 0) {
261
0
    idprime_free_private_data(priv);
262
0
    return NULL;
263
0
  }
264
513
  return priv;
265
513
}
266
267
int idprime_add_object_to_list(list_t *list, const idprime_object_t *object)
268
1.54k
{
269
1.54k
  if (list_append(list, object) < 0)
270
0
    return SC_ERROR_INTERNAL;
271
1.54k
  return SC_SUCCESS;
272
1.54k
}
273
274
/* This selects main IDPrime AID which is used for communication with
275
 * the card */
276
static int idprime_select_idprime(sc_card_t *card)
277
1.50k
{
278
1.50k
  return iso_ops->select_file(card, &idprime_path, NULL);
279
1.50k
}
280
281
/* Select file by string path */
282
static int idprime_select_file_by_path(sc_card_t *card, const char *str_path)
283
1.50k
{
284
1.50k
  int r;
285
1.50k
  sc_file_t *file = NULL;
286
1.50k
  sc_path_t index_path;
287
288
  /* First, we need to make sure the IDPrime AID is selected */
289
1.50k
  r = idprime_select_idprime(card);
290
1.50k
  if (r != SC_SUCCESS) {
291
114
    LOG_FUNC_RETURN(card->ctx, r);
292
114
  }
293
294
  /* Returns FCI with expected length of data */
295
1.39k
  sc_format_path(str_path, &index_path);
296
1.39k
  r = iso_ops->select_file(card, &index_path, &file);
297
298
1.39k
  if (r != SC_SUCCESS) {
299
11
    LOG_FUNC_RETURN(card->ctx, r);
300
11
  }
301
  /* Ignore too large files */
302
1.38k
  if (file->size > MAX_FILE_SIZE) {
303
0
    r = SC_ERROR_INVALID_DATA;
304
1.38k
  } else {
305
1.38k
    r = (int)file->size;
306
1.38k
  }
307
1.38k
  sc_file_free(file);
308
1.38k
  LOG_FUNC_RETURN(card->ctx, r);
309
1.38k
}
310
311
static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t *priv, int length)
312
461
{
313
461
  u8 *buf = NULL;
314
461
  int r = SC_ERROR_OUT_OF_MEMORY;
315
461
  int i;
316
461
  uint8_t max_entries, container_index;
317
318
461
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
319
320
461
  buf = malloc(length);
321
461
  if (buf == NULL) {
322
0
    goto done;
323
0
  }
324
325
461
  r = 0;
326
1.39k
  do {
327
    /* Read at most CONTAINER_OBJ_LEN bytes */
328
1.39k
    int read_length = length - r > CONTAINER_OBJ_LEN ? CONTAINER_OBJ_LEN : length - r;
329
1.39k
    if (length == r) {
330
0
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
331
0
      goto done;
332
0
    }
333
1.39k
    const int got = iso_ops->read_binary(card, r, buf + r, read_length, 0);
334
1.39k
    if (got < 1) {
335
51
      r = SC_ERROR_WRONG_LENGTH;
336
51
      goto done;
337
51
    }
338
339
1.34k
    r += got;
340
    /* Try to read chunks of container size and stop when last container looks empty */
341
1.34k
    container_index = r > CONTAINER_OBJ_LEN ? (r / CONTAINER_OBJ_LEN - 1) * CONTAINER_OBJ_LEN : 0;
342
1.34k
  } while(length - r > 0 && buf[container_index] != 0);
343
410
  max_entries = r / CONTAINER_OBJ_LEN;
344
345
589
  for (i = 0; i < max_entries; i++) {
346
183
    u8 *start = &buf[i * CONTAINER_OBJ_LEN];
347
183
    idprime_container_t new_container = {0};
348
183
    if (start[0] == 0) /* Empty record */
349
4
      break;
350
351
179
    new_container.index = i;
352
    /* Reading UNICODE characters but skipping second byte */
353
179
    int j = 0;
354
3.66k
    for (j = 0; j < MAX_CONTAINER_NAME_LEN; j++) {
355
3.59k
      if (start[2 * j] == 0)
356
104
        break;
357
3.48k
      new_container.guid[j] = start[2 * j];
358
3.48k
    }
359
360
179
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found container with index=%d, guid=%s", new_container.index, new_container.guid);
361
362
179
    if ((r = idprime_add_container_to_list(&priv->containers, &new_container)) != SC_SUCCESS) {
363
0
      goto done;
364
0
    }
365
179
  }
366
367
410
  r = SC_SUCCESS;
368
461
done:
369
461
  free(buf);
370
461
  LOG_FUNC_RETURN(card->ctx, r);
371
461
}
372
373
static int idprime_process_keyrefmap(sc_card_t *card, idprime_private_data_t *priv, int length)
374
72
{
375
72
  u8 *buf = NULL;
376
72
  int r = SC_ERROR_OUT_OF_MEMORY;
377
72
  int i, max_entries;
378
379
72
  buf = malloc(length);
380
72
  if (buf == NULL) {
381
0
    goto done;
382
0
  }
383
384
72
  r = 0;
385
297
  do {
386
297
    if (length == r) {
387
0
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
388
0
      goto done;
389
0
    }
390
297
    const int got = iso_ops->read_binary(card, r, buf + r, length - r, 0);
391
297
    if (got < 1) {
392
20
      r = SC_ERROR_WRONG_LENGTH;
393
20
      goto done;
394
20
    }
395
396
277
    r += got;
397
277
  } while(length - r > 0);
398
52
  max_entries = r / KEYREF_OBJ_LEN;
399
400
11.7k
  for (i = 0; i < max_entries; i++) {
401
11.6k
    idprime_keyref_t new_keyref;
402
11.6k
    u8 *start = &buf[i * KEYREF_OBJ_LEN];
403
11.6k
    if (start[0] == 0) /* Empty key ref */
404
1.47k
      continue;
405
406
10.1k
    new_keyref.index = start[2];
407
10.1k
    new_keyref.key_reference = start[1];
408
10.1k
    new_keyref.pin_index = start[7];
409
10.1k
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found key reference with index=%d, pin=%d, keyref=%d", new_keyref.index, new_keyref.pin_index, new_keyref.key_reference);
410
411
10.1k
    if ((r = idprime_add_keyref_to_list(&priv->keyrefmap, &new_keyref)) != SC_SUCCESS) {
412
0
      goto done;
413
0
    }
414
10.1k
  }
415
52
  r = SC_SUCCESS;
416
72
done:
417
72
  free(buf);
418
72
  LOG_FUNC_RETURN(card->ctx, r);
419
72
}
420
421
static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int length)
422
329
{
423
329
  u8 *buf = NULL;
424
329
  int r = SC_ERROR_OUT_OF_MEMORY;
425
329
  int i, num_entries;
426
329
  idprime_object_t new_object;
427
428
329
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
429
430
329
  buf = malloc(length);
431
329
  if (buf == NULL) {
432
0
    goto done;
433
0
  }
434
435
329
  r = 0;
436
526
  do {
437
526
    if (length == r) {
438
2
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
439
2
      goto done;
440
2
    }
441
524
    const int got = iso_ops->read_binary(card, r, buf + r, length - r, 0);
442
524
    if (got < 1) {
443
25
      r = SC_ERROR_WRONG_LENGTH;
444
25
      goto done;
445
25
    }
446
    /* First byte shows the number of entries, each of them 21 bytes long */
447
499
    num_entries = buf[0];
448
499
    r += got;
449
499
  } while(r < num_entries * 21 + 1);
450
451
302
  new_object.fd = 0;
452
6.75k
  for (i = 0; i < num_entries; i++) {
453
6.45k
    u8 *start = &buf[i*21+1];
454
455
    /* First two bytes specify the object DF */
456
6.45k
    new_object.df[0] = start[0];
457
6.45k
    new_object.df[1] = start[1];
458
    /* Second two bytes refer to the object size */
459
6.45k
    new_object.length = bebytes2ushort(&start[2]);
460
6.45k
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "df=%s, len=%u",
461
6.45k
      sc_dump_hex(new_object.df, sizeof(new_object.df)), new_object.length);
462
    /* in minidriver, mscp/kxcNN or kscNN lists certificates */
463
6.45k
    if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0)
464
1.81k
      && (memcmp(&start[12], "mscp", 5) == 0)) {
465
1.54k
      uint8_t cert_id = 0;
466
1.54k
      idprime_container_t *container = NULL;
467
468
1.54k
      if (start[7] >= '0' && start[7] <= '9' && start[8] >= '0' && start[8] <= '9') {
469
26
        cert_id = (start[7] - '0') * 10 + start[8] - '0';
470
26
      }
471
1.54k
      new_object.fd++;
472
1.54k
      new_object.key_reference = -1;
473
1.54k
      new_object.valid_key_ref = 0;
474
1.54k
      new_object.pin_index = 1;
475
476
1.54k
      container = (idprime_container_t *) list_seek(&priv->containers, &cert_id);
477
1.54k
      if (!container) {
478
        /* Container map missing container with certificate ID */
479
1.20k
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding container with private key found for certificate with id=%d", cert_id);
480
1.20k
        if (card->type != SC_CARD_TYPE_IDPRIME_940) {
481
          /* For cards other than the 940, we don't know how to recognize
482
          certificates missing keys other than to check
483
          that there is a corresponding entry in the container map.*/
484
1.02k
          sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd);
485
1.02k
          idprime_add_object_to_list(&priv->pki_list, &new_object);
486
1.02k
          continue;
487
1.02k
        }
488
1.20k
      }
489
490
517
      switch (card->type) {
491
67
      case SC_CARD_TYPE_IDPRIME_3810:
492
67
        new_object.key_reference = 0x31 + cert_id;
493
67
        break;
494
35
      case SC_CARD_TYPE_IDPRIME_830:
495
35
        new_object.key_reference = 0x41 + cert_id;
496
35
        break;
497
73
      case SC_CARD_TYPE_IDPRIME_930:
498
73
        new_object.key_reference = 0x11 + cert_id * 2;
499
73
        break;
500
0
      case SC_CARD_TYPE_IDPRIME_930_PLUS:
501
0
        new_object.key_reference = 0x10 + cert_id * 2;
502
0
        break;
503
185
      case SC_CARD_TYPE_IDPRIME_940: {
504
185
          idprime_keyref_t *keyref = (idprime_keyref_t *) list_seek(&priv->keyrefmap, &cert_id);
505
185
          if (!keyref) {
506
            /* Key reference file does not contain record of the key for given certificate */
507
117
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding key reference found for certificate with id=%d", cert_id);
508
117
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd);
509
117
            idprime_add_object_to_list(&priv->pki_list, &new_object);
510
117
            continue;
511
117
          }
512
68
          new_object.key_reference = keyref->key_reference;
513
68
          new_object.pin_index = keyref->pin_index;
514
68
          break;
515
185
        }
516
68
      case SC_CARD_TYPE_IDPRIME_840:
517
68
        new_object.key_reference = 0xf7 + cert_id;
518
68
        break;
519
89
      default:
520
89
        new_object.key_reference = 0x56 + cert_id;
521
89
        break;
522
517
      }
523
400
      new_object.valid_key_ref = 1;
524
400
      if (container != NULL) {
525
332
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d corresponding to container \"%s\"",
526
332
          new_object.fd, new_object.key_reference, container->guid);
527
332
      } else {
528
68
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d without corresponding container",
529
68
          new_object.fd, new_object.key_reference);
530
68
      }
531
532
400
      idprime_add_object_to_list(&priv->pki_list, &new_object);
533
534
    /* This looks like non-standard extension listing pkcs11 token info label in my card */
535
4.91k
    } else if ((memcmp(&start[4], "tinfo", 6) == 0) && (memcmp(&start[12], "p11", 4) == 0)) {
536
36
      memcpy(priv->tinfo_df, new_object.df, sizeof(priv->tinfo_df));
537
36
      priv->tinfo_present = 1;
538
36
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found p11/tinfo object");
539
4.87k
    } else if ((memcmp(&start[4], "cmapfile", 8) == 0) && (memcmp(&start[12], "mscp", 4) == 0)) {
540
22
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found mscp/cmapfile object %s",
541
22
          (start[0] == 02 && start[1] == 04 ? "(already processed)" : "(in non-standard path!)"));
542
4.85k
    } else if (memcmp(&start[4], "cardapps", 8) == 0) {
543
10
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found cardapps object");
544
4.84k
    } else if (memcmp(&start[4], "cardid", 6) == 0) {
545
15
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found cardid object");
546
4.83k
    } else if (memcmp(&start[4], "cardcf", 6) == 0) {
547
12
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found cardcf object");
548
12
    }
549
6.45k
  }
550
551
302
  r = SC_SUCCESS;
552
329
done:
553
329
  free(buf);
554
329
  LOG_FUNC_RETURN(card->ctx, r);
555
329
}
556
557
/* CPLC has 42 bytes, but we get it with 3B header */
558
488
#define CPLC_LENGTH 45
559
static int idprime_init(sc_card_t *card)
560
513
{
561
513
  int r;
562
513
  unsigned long flags, ext_flags;
563
513
  idprime_private_data_t *priv = NULL;
564
513
  struct sc_apdu apdu;
565
513
  u8 rbuf[CPLC_LENGTH];
566
513
  size_t rbuflen = sizeof(rbuf);
567
568
513
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
569
570
  /* We need to differentiate the OS version since they behave slightly differently */
571
513
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xCA, 0x9F, 0x7F);
572
513
  apdu.resp = rbuf;
573
513
  apdu.resplen = rbuflen;
574
513
  apdu.le = rbuflen;
575
513
  r = sc_transmit_apdu(card, &apdu);
576
513
  if (r == SC_SUCCESS && apdu.resplen == CPLC_LENGTH) {
577
    /* We are interested in the OS release level here */
578
5
    switch (rbuf[11]) {
579
1
    case 0x01:
580
1
      sc_log(card->ctx, "Detected IDPrime applet version 1");
581
1
      break;
582
1
    case 0x02:
583
1
      sc_log(card->ctx, "Detected IDPrime applet version 2");
584
1
      break;
585
1
    case 0x03:
586
1
      sc_log(card->ctx, "Detected IDPrime applet version 3");
587
1
      break;
588
1
    case 0x04:
589
1
      sc_log(card->ctx, "Detected IDPrime applet version 4");
590
1
      break;
591
1
    default:
592
1
      sc_log(card->ctx, "Unknown OS version received: %d", rbuf[11]);
593
1
      break;
594
5
    }
595
508
  } else {
596
508
    sc_log(card->ctx, "Failed to get CPLC data or invalid length returned, "
597
508
      "err=%d, len=%"SC_FORMAT_LEN_SIZE_T"u",
598
508
      r, apdu.resplen);
599
508
  }
600
601
  /* Proprietary data -- Applet version */
602
513
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xCA, 0xDF, 0x30);
603
513
  apdu.resp = rbuf;
604
513
  apdu.resplen = rbuflen;
605
513
  apdu.le = rbuflen;
606
513
  r = sc_transmit_apdu(card, &apdu);
607
513
  if (r == SC_SUCCESS && apdu.resplen >= 10) {
608
    /* Ber-TLV encoded */
609
116
    if (rbuf[0] == 0xDF && rbuf[1] == 0x30 && rbuf[2] == apdu.resplen - 3) {
610
1
      sc_log(card->ctx, "IDPrime Java Applet version %.*s", (int)apdu.resplen - 3, rbuf + 3);
611
1
    }
612
116
  }
613
614
513
  priv = idprime_new_private_data();
615
513
  if (!priv) {
616
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
617
0
  }
618
619
  /* Select and process container file */
620
513
  r = idprime_select_file_by_path(card, "0204");;
621
513
  if (r <= 0) {
622
52
    idprime_free_private_data(priv);
623
52
    if (r == 0)
624
1
      r = SC_ERROR_INVALID_DATA;
625
52
    LOG_FUNC_RETURN(card->ctx, r);
626
52
  }
627
628
461
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Container file found");
629
630
461
  r = idprime_process_containermap(card, priv, r);
631
461
  if (r != SC_SUCCESS) {
632
51
    idprime_free_private_data(priv);
633
51
    LOG_FUNC_RETURN(card->ctx, r);
634
51
  }
635
636
410
  if (card->type == SC_CARD_TYPE_IDPRIME_940) {
637
83
    if ((r = idprime_select_file_by_path(card, "0005")) <= 0) {
638
11
      idprime_free_private_data(priv);
639
11
      if (r == 0)
640
1
        r = SC_ERROR_INVALID_DATA;
641
11
      LOG_FUNC_RETURN(card->ctx, r);
642
11
    }
643
644
72
    if ((r = idprime_process_keyrefmap(card, priv, r)) != SC_SUCCESS) {
645
20
      idprime_free_private_data(priv);
646
20
      LOG_FUNC_RETURN(card->ctx, r);
647
20
    }
648
72
  }
649
650
  /* Select and process the index file */
651
379
  r = idprime_select_file_by_path(card, "0101");
652
379
  if (r <= 0) {
653
50
    idprime_free_private_data(priv);
654
50
    if (r == 0)
655
3
      r = SC_ERROR_INVALID_DATA;
656
50
    LOG_FUNC_RETURN(card->ctx, r);
657
50
  }
658
659
329
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Index file found");
660
661
329
  r = idprime_process_index(card, priv, r);
662
329
  if (r != SC_SUCCESS) {
663
27
    idprime_free_private_data(priv);
664
27
    LOG_FUNC_RETURN(card->ctx, r);
665
27
  }
666
667
302
  card->drv_data = priv;
668
669
302
  switch (card->type) {
670
9
  case SC_CARD_TYPE_IDPRIME_3810:
671
9
    card->name = "Gemalto IDPrime 3810";
672
9
    break;
673
8
  case SC_CARD_TYPE_IDPRIME_830:
674
8
    card->name = "Gemalto IDPrime MD 830";
675
8
    break;
676
15
  case SC_CARD_TYPE_IDPRIME_930:
677
15
  case SC_CARD_TYPE_IDPRIME_930_PLUS:
678
15
    card->name = "Gemalto IDPrime 930/3930";
679
15
    break;
680
22
  case SC_CARD_TYPE_IDPRIME_940:
681
22
    card->name = "Gemalto IDPrime 940";
682
22
    break;
683
42
  case SC_CARD_TYPE_IDPRIME_840:
684
42
    card->name = "Gemalto IDPrime MD 840";
685
42
    break;
686
206
  case SC_CARD_TYPE_IDPRIME_GENERIC:
687
206
  default:
688
206
    card->name = "Gemalto IDPrime (generic)";
689
206
    break;
690
302
  }
691
302
  card->cla = 0x00;
692
693
  /* Set up algorithm info for RSA. */
694
302
  flags = SC_ALGORITHM_RSA_PAD_PKCS1
695
302
    | SC_ALGORITHM_RSA_PAD_PSS
696
302
    | SC_ALGORITHM_RSA_PAD_OAEP
697
    /* SHA-1 mechanisms are not allowed in the card I have */
698
302
    | (SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_HASH_SHA384 | SC_ALGORITHM_RSA_HASH_SHA512)
699
302
    | (SC_ALGORITHM_MGF1_SHA256 | SC_ALGORITHM_MGF1_SHA384 | SC_ALGORITHM_MGF1_SHA512)
700
302
    ;
701
702
302
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
703
302
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
704
302
  switch (card->type) {
705
0
  case SC_CARD_TYPE_IDPRIME_930_PLUS:
706
22
  case SC_CARD_TYPE_IDPRIME_940:
707
22
    _sc_card_add_rsa_alg(card, 3072, flags, 0);
708
    /* fallthrough */
709
37
  case SC_CARD_TYPE_IDPRIME_930:
710
37
    _sc_card_add_rsa_alg(card, 4096, flags, 0);
711
    /* fallthrough */
712
79
  case SC_CARD_TYPE_IDPRIME_840:
713
    /* Set up algorithm info for EC */
714
79
    flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
715
79
    if (card->type == SC_CARD_TYPE_IDPRIME_930_PLUS || card->type == SC_CARD_TYPE_IDPRIME_940) {
716
22
      flags |= SC_ALGORITHM_ECDH_CDH_RAW;
717
22
    }
718
79
    ext_flags = SC_ALGORITHM_EXT_EC_F_P
719
79
      | SC_ALGORITHM_EXT_EC_ECPARAMETERS
720
79
      | SC_ALGORITHM_EXT_EC_NAMEDCURVE
721
79
      | SC_ALGORITHM_EXT_EC_UNCOMPRESES
722
79
      ;
723
79
    _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
724
79
    _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
725
79
    _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL);
726
79
    break;
727
223
  default:
728
223
    break;
729
302
  }
730
731
302
  card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO;
732
733
302
  card->caps |= SC_CARD_CAP_RNG;
734
735
302
  LOG_FUNC_RETURN(card->ctx, 0);
736
302
}
737
738
static int idprime_finish(sc_card_t *card)
739
302
{
740
302
  idprime_private_data_t * priv = card->drv_data;
741
742
302
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
743
302
  if (priv) {
744
302
    idprime_free_private_data(priv);
745
302
  }
746
302
  return SC_SUCCESS;
747
302
}
748
749
static int idprime_match_card(sc_card_t *card)
750
7.78k
{
751
7.78k
  int i, r;
752
753
7.78k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
754
7.78k
  i = _sc_match_atr(card, idprime_atrs, &card->type);
755
7.78k
  if (i < 0)
756
7.25k
    return 0;
757
758
532
  r = idprime_select_file_by_path(card, "0101");
759
532
  LOG_FUNC_RETURN(card->ctx, r > 0);
760
532
}
761
762
/* initialize getting a list and return the number of elements in the list */
763
static int idprime_get_init_and_get_count(list_t *list, idprime_object_t **entry, int *countp)
764
301
{
765
301
  if (countp == NULL || entry == NULL) {
766
0
    return SC_ERROR_INVALID_ARGUMENTS;
767
0
  }
768
301
  *countp = list_size(list);
769
301
  list_iterator_start(list);
770
301
  *entry = list_iterator_next(list);
771
301
  return SC_SUCCESS;
772
301
}
773
774
/* finalize the list iterator */
775
static int idprime_final_iterator(list_t *list)
776
301
{
777
301
  list_iterator_stop(list);
778
301
  return SC_SUCCESS;
779
301
}
780
781
/* fill in the prkey_info for the current object on the list and advance to the next object */
782
static int idprime_fill_prkey_info(list_t *list, idprime_object_t **entry, sc_pkcs15_prkey_info_t *prkey_info)
783
1.54k
{
784
1.54k
  memset(prkey_info, 0, sizeof(sc_pkcs15_prkey_info_t));
785
1.54k
  if (*entry == NULL) {
786
0
    return SC_ERROR_FILE_END_REACHED;
787
0
  }
788
789
1.54k
  prkey_info->path.len = sizeof((*entry)->df);
790
1.54k
  memcpy(prkey_info->path.value, (*entry)->df, sizeof((*entry)->df));
791
1.54k
  prkey_info->path.type = SC_PATH_TYPE_FILE_ID;
792
  /* Do not specify the length -- it will be read from the FCI */
793
1.54k
  prkey_info->path.count = -1;
794
795
  /* TODO figure out the IDs as the original driver? */
796
1.54k
  prkey_info->id.value[0] = ((*entry)->fd >> 8) & 0xff;
797
1.54k
  prkey_info->id.value[1] = (*entry)->fd & 0xff;
798
1.54k
  prkey_info->id.len = 2;
799
1.54k
  if ((*entry)->valid_key_ref)
800
400
    prkey_info->key_reference = (*entry)->key_reference;
801
1.14k
  else
802
1.14k
    prkey_info->key_reference = -1;
803
1.54k
  *entry = list_iterator_next(list);
804
1.54k
  return SC_SUCCESS;
805
1.54k
}
806
807
/* get PIN id of the current object on the list */
808
static int idprime_get_pin_id(list_t *list, idprime_object_t **entry, const char **pin_id)
809
1.54k
{
810
1.54k
  if (pin_id == NULL || entry == NULL) {
811
0
    return SC_ERROR_INVALID_ARGUMENTS;
812
0
  }
813
1.54k
  *pin_id = "11"; // normal PIN id
814
1.54k
  if ((*entry)->pin_index != 1)
815
68
    *pin_id = "83"; // signature PIN id
816
1.54k
  return SC_SUCCESS;
817
1.54k
}
818
819
19
#define IDPRIME_CARDID_LEN 16
820
821
static int idprime_get_serial(sc_card_t* card, sc_serial_number_t* serial)
822
301
{
823
301
  sc_path_t cardid_path;
824
301
  sc_file_t *file = NULL;
825
301
  u8 buf[IDPRIME_CARDID_LEN];
826
301
  int r;
827
828
301
  LOG_FUNC_CALLED(card->ctx);
829
830
  /* XXX this is assumed to be cardid for windows. It can be read from the index file */
831
301
  sc_format_path("0201", &cardid_path);
832
301
  r = iso_ops->select_file(card, &cardid_path, &file);
833
301
  if (r != SC_SUCCESS || file->size != IDPRIME_CARDID_LEN) { /* The cardid is always 16 B */
834
293
    sc_file_free(file);
835
293
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH);
836
293
  }
837
838
8
  r = iso_ops->read_binary(card, 0, buf, file->size, 0);
839
8
  sc_file_free(file);
840
8
  if (r < 1) {
841
6
    LOG_FUNC_RETURN(card->ctx, r);
842
6
  } else if (r != IDPRIME_CARDID_LEN) {
843
1
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
844
1
  }
845
846
1
  serial->len = MIN(IDPRIME_CARDID_LEN, SC_MAX_SERIALNR);
847
1
  memcpy(serial->value, buf, serial->len);
848
1
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
849
1
}
850
851
static int idprime_get_token_name(sc_card_t* card, char** tname)
852
301
{
853
301
  idprime_private_data_t * priv = card->drv_data;
854
301
  sc_path_t tinfo_path = {"\x00\x00", 2, 0, 0, SC_PATH_TYPE_PATH, {"", 0}};
855
301
  sc_file_t *file = NULL;
856
301
  u8 buf[2];
857
301
  char *name;
858
301
  int r;
859
860
301
  LOG_FUNC_CALLED(card->ctx);
861
862
301
  if (tname == NULL) {
863
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
864
0
  }
865
866
301
  if (!priv->tinfo_present) {
867
278
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
868
278
  }
869
870
23
  memcpy(tinfo_path.value, priv->tinfo_df, 2);
871
23
  r = iso_ops->select_file(card, &tinfo_path, &file);
872
23
  if (r != SC_SUCCESS || file->size == 0) {
873
7
    sc_file_free(file);
874
7
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
875
7
  }
876
877
  /* First two bytes lists 0x01, the second indicates length */
878
16
  r = iso_ops->read_binary(card, 0, buf, 2, 0);
879
16
  if (r < 2 || buf[1] > file->size) { /* make sure we do not overrun */
880
4
    sc_file_free(file);
881
4
    LOG_FUNC_RETURN(card->ctx, r);
882
4
  }
883
12
  sc_file_free(file);
884
885
12
  name = malloc(buf[1]);
886
12
  if (name == NULL) {
887
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
888
0
  }
889
890
12
  r = iso_ops->read_binary(card, 2, (unsigned char *)name, buf[1], 0);
891
12
  if (r < 1) {
892
8
    free(name);
893
8
    LOG_FUNC_RETURN(card->ctx, r);
894
8
  }
895
896
4
  if (name[r-1] != '\0') {
897
3
    name[r-1] = '\0';
898
3
  }
899
4
  *tname = name;
900
901
4
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
902
4
}
903
904
static int idprime_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
905
4.29k
{
906
4.29k
  idprime_private_data_t * priv = card->drv_data;
907
908
4.29k
  LOG_FUNC_CALLED(card->ctx);
909
4.29k
  sc_log(card->ctx, "cmd=%ld ptr=%p", cmd, ptr);
910
911
4.29k
  if (priv == NULL) {
912
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
913
0
  }
914
4.29k
  switch (cmd) {
915
301
    case SC_CARDCTL_GET_SERIALNR:
916
301
      return idprime_get_serial(card, (sc_serial_number_t *) ptr);
917
301
    case SC_CARDCTL_IDPRIME_GET_TOKEN_NAME:
918
301
      return idprime_get_token_name(card, (char **) ptr);
919
301
    case SC_CARDCTL_IDPRIME_INIT_GET_OBJECTS:
920
301
      return idprime_get_init_and_get_count(&priv->pki_list, &priv->pki_current,
921
301
        (int *)ptr);
922
1.54k
    case SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT:
923
1.54k
      return idprime_fill_prkey_info(&priv->pki_list, &priv->pki_current,
924
1.54k
        (sc_pkcs15_prkey_info_t *)ptr);
925
301
    case SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS:
926
301
      return idprime_final_iterator(&priv->pki_list);
927
1.54k
    case SC_CARDCTL_IDPRIME_GET_PIN_ID:
928
1.54k
      return idprime_get_pin_id(&priv->pki_list, &priv->pki_current,
929
1.54k
        (const char **)ptr);
930
4.29k
  }
931
932
14
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
933
14
}
934
935
#define HEADER_LEN 4
936
937
static int idprime_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out)
938
2.48k
{
939
2.48k
  int r;
940
2.48k
  idprime_private_data_t * priv = card->drv_data;
941
942
2.48k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
943
944
  /* forget any old cached values */
945
2.48k
  if (priv->cache_buf) {
946
36
    free(priv->cache_buf);
947
36
    priv->cache_buf = NULL;
948
36
  }
949
2.48k
  priv->cache_buf_len = 0;
950
2.48k
  priv->cached = 0;
951
952
2.48k
  r = iso_ops->select_file(card, in_path, file_out);
953
2.48k
  if (r == SC_SUCCESS && file_out != NULL) {
954
    /* Cache the real file size for the caching read_binary() */
955
231
    priv->file_size = (*file_out)->size;
956
231
  }
957
  /* Return the exit code of the select command */
958
2.48k
  return r;
959
2.48k
}
960
961
// used to read existing certificates
962
static int idprime_read_binary(sc_card_t *card, unsigned int offset,
963
  unsigned char *buf, size_t count, unsigned long *flags)
964
933
{
965
933
  struct idprime_private_data *priv = card->drv_data;
966
933
  int r = 0;
967
933
  int size;
968
933
  size_t sz;
969
970
933
  sc_log(card->ctx, "called; %"SC_FORMAT_LEN_SIZE_T"u bytes at offset %d",
971
933
    count, offset);
972
973
933
  if (!priv->cached && offset == 0) {
974
    /* Read what was reported by FCI from select command */
975
214
    size_t left = priv->file_size;
976
214
    unsigned read = 0;
977
978
    // this function is called to read and uncompress the certificate
979
214
    u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
980
214
    u8 *data_buffer = buffer;
981
214
    if (sizeof(buffer) < count || sizeof(buffer) < priv->file_size) {
982
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
983
0
    }
984
317
    while (left > 0) {
985
199
      r = iso_ops->read_binary(card, read, buffer + read, priv->file_size - read, flags);
986
199
      if (r <= 0) {
987
96
        LOG_FUNC_RETURN(card->ctx, r);
988
96
      }
989
103
      left -= r;
990
103
      read += r;
991
103
    }
992
118
    if (read < 4 || read != priv->file_size) {
993
69
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
994
69
    }
995
49
    if (buffer[0] == 1 && buffer[1] == 0) {
996
      /* Data will be decompressed later */
997
9
      data_buffer += 4;
998
9
      sz = priv->file_size - 4;
999
9
      if (flags)
1000
1
        *flags |= SC_FILE_FLAG_COMPRESSED_AUTO;
1001
40
    } else {
1002
40
      sz = priv->file_size;
1003
40
    }
1004
49
    priv->cache_buf = malloc(sz);
1005
49
    if (priv->cache_buf == NULL) {
1006
0
      return SC_ERROR_OUT_OF_MEMORY;
1007
0
    }
1008
49
    memcpy(priv->cache_buf, data_buffer, sz);
1009
49
    priv->cache_buf_len = sz;
1010
49
    priv->cached = 1;
1011
49
  }
1012
768
  if (offset >= priv->cache_buf_len) {
1013
9
    return 0;
1014
9
  }
1015
759
  size = (int) MIN((priv->cache_buf_len - offset), count);
1016
759
  memcpy(buf, priv->cache_buf + offset, size);
1017
759
  return size;
1018
768
}
1019
1020
static int
1021
idprime_set_security_env(struct sc_card *card,
1022
  const struct sc_security_env *env, int se_num)
1023
0
{
1024
0
  int r;
1025
0
  struct sc_security_env new_env;
1026
0
  idprime_private_data_t *priv = NULL;
1027
1028
0
  if (card == NULL || env == NULL) {
1029
0
    return SC_ERROR_INVALID_ARGUMENTS;
1030
0
  }
1031
1032
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1033
1034
0
  priv = card->drv_data;
1035
1036
  /* The card requires algorithm reference here */
1037
0
  new_env = *env;
1038
0
  new_env.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
1039
  /* SHA-1 mechanisms are not allowed in the card I have available */
1040
0
  switch (env->operation) {
1041
0
  case SC_SEC_OPERATION_DERIVE:
1042
0
    priv->current_op = SC_ALGORITHM_EC;
1043
0
    new_env.flags &= ~SC_SEC_ENV_ALG_REF_PRESENT;
1044
0
    break;
1045
0
  case SC_SEC_OPERATION_DECIPHER:
1046
0
    if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_OAEP) {
1047
0
      if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA1) {
1048
0
        new_env.algorithm_ref = 0x1D;
1049
0
      } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA256) {
1050
0
        new_env.algorithm_ref = 0x4D;
1051
0
      } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA384) {
1052
0
        new_env.algorithm_ref = 0x5D;
1053
0
      } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) {
1054
0
        new_env.algorithm_ref = 0x6D;
1055
0
      }
1056
0
    } else { /* RSA-PKCS without hashing */
1057
0
      new_env.algorithm_ref = 0x1A;
1058
0
    }
1059
0
    break;
1060
0
  case SC_SEC_OPERATION_SIGN:
1061
0
    if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) {
1062
0
      if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA256) {
1063
0
        new_env.algorithm_ref = 0x45;
1064
0
      } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA384) {
1065
0
        new_env.algorithm_ref = 0x55;
1066
0
      } else if (env->algorithm_flags & SC_ALGORITHM_MGF1_SHA512) {
1067
0
        new_env.algorithm_ref = 0x65;
1068
0
      }
1069
0
      priv->current_op = SC_ALGORITHM_RSA;
1070
0
    } else if (env->algorithm_flags & (SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01 | SC_ALGORITHM_RSA_PAD_OAEP)) {
1071
0
      if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
1072
0
        new_env.algorithm_ref = 0x42;
1073
0
      } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA384) {
1074
0
        new_env.algorithm_ref = 0x52;
1075
0
      } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA512) {
1076
0
        new_env.algorithm_ref = 0x62;
1077
0
      } else { /* RSA-PKCS without hashing */
1078
0
        new_env.algorithm_ref = 0x02;
1079
0
      }
1080
0
      priv->current_op = SC_ALGORITHM_RSA;
1081
0
    } else if (env->algorithm == SC_ALGORITHM_EC) {
1082
0
      new_env.algorithm_ref = 0x44;
1083
0
      priv->current_op = SC_ALGORITHM_EC;
1084
0
    }
1085
0
    break;
1086
0
  default:
1087
0
    return SC_ERROR_INVALID_ARGUMENTS;
1088
0
  }
1089
0
  r = iso_ops->set_security_env(card,
1090
0
    (const struct sc_security_env *) &new_env, se_num);
1091
1092
0
  LOG_FUNC_RETURN(card->ctx, r);
1093
0
}
1094
1095
/* These are mostly ISO versions updated to IDPrime specifics */
1096
static int
1097
idprime_compute_signature(struct sc_card *card,
1098
  const u8 * data, size_t datalen, u8 * out, size_t outlen)
1099
0
{
1100
0
  int r;
1101
0
  struct sc_apdu apdu;
1102
0
  u8 *p;
1103
0
  u8 sbuf[128] = {0}; /* For SHA-512 we need 64 + 2 bytes */
1104
0
  u8 rbuf[4096]; /* needs work. for 3072 keys, needs 384+2 or so */
1105
0
  size_t rbuflen = sizeof(rbuf);
1106
0
  idprime_private_data_t *priv = card->drv_data;
1107
1108
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1109
1110
  /* We should be signing hashes only so we should not reach this limit */
1111
0
  if (datalen + 2 > sizeof(sbuf)) {
1112
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1113
0
  }
1114
1115
  /* The data for ECDSA should be padded to the length of a multiple of 8 */
1116
0
  size_t pad = 0;
1117
0
  if (priv->current_op == SC_ALGORITHM_EC && datalen % 8 != 0) {
1118
0
    pad = 8 - (datalen % 8);
1119
0
    datalen += pad;
1120
0
  }
1121
1122
0
  p = sbuf;
1123
0
  *(p++) = 0x90;
1124
0
  *(p++) = datalen;
1125
0
  memcpy(p + pad, data, datalen - pad);
1126
0
  p += datalen;
1127
1128
  /* INS: 0x2A  PERFORM SECURITY OPERATION
1129
   * P1:  0x90  Hash code
1130
   * P2:  0xA0  Input template for the computation of a hash-code (the template is hashed) */
1131
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x90, 0xA0);
1132
0
  apdu.resp = rbuf;
1133
0
  apdu.resplen = rbuflen;
1134
0
  apdu.le = datalen;
1135
1136
0
  apdu.data = sbuf;
1137
0
  apdu.lc = p - sbuf;
1138
0
  apdu.datalen = p - sbuf;
1139
1140
0
  r = sc_transmit_apdu(card, &apdu);
1141
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1142
1143
  /* This just returns the passed data (hash code) (for verification?) */
1144
0
  if (apdu.resplen != datalen || memcmp(rbuf + pad, data, datalen - pad) != 0) {
1145
0
    sc_log(card->ctx, "The initial APDU did not return the same data");
1146
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
1147
0
  }
1148
  /* INS: 0x2A  PERFORM SECURITY OPERATION
1149
   * P1:  0x9E  Resp: Digital Signature
1150
   * P2:  0x9A  Cmd: Input for Digital Signature */
1151
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x2A, 0x9E, 0x9A);
1152
0
  apdu.resp = out;
1153
0
  apdu.resplen = outlen;
1154
0
  apdu.le = outlen;
1155
0
  iso7816_fixup_transceive_length(card, &apdu);
1156
1157
0
  apdu.data = NULL;
1158
0
  apdu.datalen = 0;
1159
0
  apdu.lc = 0;
1160
0
  r = sc_transmit_apdu(card, &apdu);
1161
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1162
1163
0
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
1164
0
    LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
1165
1166
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1167
0
  LOG_TEST_RET(card->ctx, r, "Card returned error");
1168
1169
0
  LOG_FUNC_RETURN(card->ctx, r);
1170
0
}
1171
1172
/* These are mostly ISO versions updated to IDPrime specifics */
1173
static int
1174
idprime_decipher(struct sc_card *card,
1175
  const u8 * crgram, size_t crgram_len,
1176
  u8 * out, size_t outlen)
1177
0
{
1178
0
  int r;
1179
0
  struct sc_apdu apdu;
1180
0
  u8 *sbuf = NULL;
1181
0
  idprime_private_data_t *priv;
1182
1183
0
  if (card == NULL || crgram == NULL || out == NULL) {
1184
0
    return SC_ERROR_INVALID_ARGUMENTS;
1185
0
  }
1186
0
  LOG_FUNC_CALLED(card->ctx);
1187
0
  priv = card->drv_data;
1188
0
  sc_log(card->ctx,
1189
0
    "IDPrime decipher: in-len %"SC_FORMAT_LEN_SIZE_T"u, out-len %"SC_FORMAT_LEN_SIZE_T"u",
1190
0
    crgram_len, outlen);
1191
1192
0
  sbuf = malloc(crgram_len + 1);
1193
0
  if (sbuf == NULL)
1194
0
    return SC_ERROR_OUT_OF_MEMORY;
1195
1196
  /* INS: 0x2A  PERFORM SECURITY OPERATION
1197
   * P1:  0x80  Resp: Plain value
1198
   * P2:  0x86  Cmd: Padding indicator byte followed by cryptogram */
1199
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x2A, 0x80, 0x86);
1200
0
  apdu.resp    = out;
1201
0
  apdu.resplen = outlen;
1202
0
  apdu.le      = outlen;
1203
1204
0
  sbuf[0] = priv->current_op == SC_ALGORITHM_EC ? 0x00 : 0x81; /* padding indicator byte, 0x81 = Proprietary, 0x00 = No further indication  */
1205
0
  memcpy(sbuf + 1, crgram, crgram_len);
1206
0
  apdu.data = sbuf;
1207
0
  apdu.lc = crgram_len + 1;
1208
0
  iso7816_fixup_transceive_length(card, &apdu);
1209
0
  apdu.datalen = crgram_len + 1;
1210
1211
0
  r = sc_transmit_apdu(card, &apdu);
1212
0
  sc_mem_clear(sbuf, crgram_len + 1);
1213
0
  free(sbuf);
1214
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1215
1216
0
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
1217
0
    LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
1218
0
  else
1219
0
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1220
0
}
1221
1222
static int
1223
idprime_get_challenge(struct sc_card *card, u8 *rnd, size_t len)
1224
0
{
1225
0
  u8 rbuf[16];
1226
0
  size_t out_len;
1227
0
  struct sc_apdu apdu;
1228
0
  int r;
1229
1230
0
  LOG_FUNC_CALLED(card->ctx);
1231
1232
0
  if (len <= 8) {
1233
    /* official closed driver always calls this regardless the length */
1234
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x01);
1235
0
    apdu.le = apdu.resplen = 8;
1236
0
  } else {
1237
    /* this was discovered accidentally - all 16 bytes seem random */
1238
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00);
1239
0
    apdu.le = apdu.resplen = 16;
1240
0
  }
1241
0
  apdu.resp = rbuf;
1242
1243
0
  r = sc_transmit_apdu(card, &apdu);
1244
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1245
1246
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1247
0
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed");
1248
1249
0
  out_len = len < apdu.resplen ? len : apdu.resplen;
1250
0
  memcpy(rnd, rbuf, out_len);
1251
1252
0
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
1253
0
}
1254
1255
static struct sc_card_driver * sc_get_driver(void)
1256
15.3k
{
1257
15.3k
  if (iso_ops == NULL) {
1258
1
    iso_ops = sc_get_iso7816_driver()->ops;
1259
1
  }
1260
1261
15.3k
  idprime_ops = *iso_ops;
1262
15.3k
  idprime_ops.match_card = idprime_match_card;
1263
15.3k
  idprime_ops.init = idprime_init;
1264
15.3k
  idprime_ops.finish = idprime_finish;
1265
1266
15.3k
  idprime_ops.read_binary = idprime_read_binary;
1267
15.3k
  idprime_ops.select_file = idprime_select_file;
1268
15.3k
  idprime_ops.card_ctl = idprime_card_ctl;
1269
15.3k
  idprime_ops.set_security_env = idprime_set_security_env;
1270
15.3k
  idprime_ops.compute_signature = idprime_compute_signature;
1271
15.3k
  idprime_ops.decipher = idprime_decipher;
1272
1273
15.3k
  idprime_ops.get_challenge = idprime_get_challenge;
1274
1275
15.3k
  return &idprime_drv;
1276
15.3k
}
1277
1278
struct sc_card_driver * sc_get_idprime_driver(void)
1279
15.3k
{
1280
15.3k
  return sc_get_driver();
1281
15.3k
}