Coverage Report

Created: 2026-08-31 06:13

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