Coverage Report

Created: 2025-12-14 06:57

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.29k
#define MAX_CONTAINER_NAME_LEN 39
142
5.09k
#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
13.6k
#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
829
static size_t idprime_list_meter(const void *el) {
177
829
  return sizeof(idprime_object_t);
178
829
}
179
180
88
static size_t idprime_container_list_meter(const void *el) {
181
88
  return sizeof(idprime_container_t);
182
88
}
183
184
11.6k
static size_t idprime_keyref_list_meter(const void *el) {
185
11.6k
  return sizeof(idprime_keyref_t);
186
11.6k
}
187
188
static int idprime_add_container_to_list(list_t *list, const idprime_container_t *container)
189
88
{
190
88
  if (list_append(list, container) < 0)
191
0
    return SC_ERROR_INTERNAL;
192
88
  return SC_SUCCESS;
193
88
}
194
195
static int idprime_container_list_seeker(const void *el, const void *key)
196
516
{
197
516
  const idprime_container_t *container = (idprime_container_t *)el;
198
199
516
  if ((el == NULL) || (key == NULL))
200
0
    return 0;
201
516
  if (container->index == *(uint8_t *)key)
202
278
    return 1;
203
238
  return 0;
204
516
}
205
206
static int idprime_add_keyref_to_list(list_t *list, const idprime_keyref_t *keyref)
207
11.6k
{
208
11.6k
  if (list_append(list, keyref) < 0)
209
0
    return SC_ERROR_INTERNAL;
210
11.6k
  return SC_SUCCESS;
211
11.6k
}
212
213
static int idprime_keyref_list_seeker(const void *el, const void *key)
214
301
{
215
301
  const idprime_keyref_t *keyref = (idprime_keyref_t *)el;
216
217
301
  if ((el == NULL) || (key == NULL))
218
0
    return 0;
219
301
  if (keyref->index == *(uint8_t *)key)
220
38
    return 1;
221
263
  return 0;
222
301
}
223
224
void idprime_free_private_data(idprime_private_data_t *priv)
225
488
{
226
488
  free(priv->cache_buf);
227
488
  list_destroy(&priv->pki_list);
228
488
  list_destroy(&priv->containers);
229
488
  list_destroy(&priv->keyrefmap);
230
488
  free(priv);
231
488
  return;
232
488
}
233
234
idprime_private_data_t *idprime_new_private_data(void)
235
488
{
236
488
  idprime_private_data_t *priv;
237
238
488
  priv = calloc(1, sizeof(idprime_private_data_t));
239
488
  if (priv == NULL)
240
0
    return NULL;
241
242
  /* Initialize PKI Applets list */
243
488
  if (list_init(&priv->pki_list) != 0 ||
244
488
      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
488
  if (list_init(&priv->containers) != 0 ||
251
488
      list_attributes_copy(&priv->containers, idprime_container_list_meter, 1) != 0 ||
252
488
      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
488
  if (list_init(&priv->keyrefmap) != 0 ||
259
488
      list_attributes_copy(&priv->keyrefmap, idprime_keyref_list_meter, 1) != 0 ||
260
488
      list_attributes_seeker(&priv->keyrefmap, idprime_keyref_list_seeker) != 0) {
261
0
    idprime_free_private_data(priv);
262
0
    return NULL;
263
0
  }
264
488
  return priv;
265
488
}
266
267
int idprime_add_object_to_list(list_t *list, const idprime_object_t *object)
268
829
{
269
829
  if (list_append(list, object) < 0)
270
0
    return SC_ERROR_INTERNAL;
271
829
  return SC_SUCCESS;
272
829
}
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
190
    LOG_FUNC_RETURN(card->ctx, r);
292
190
  }
293
294
  /* Returns FCI with expected length of data */
295
1.31k
  sc_format_path(str_path, &index_path);
296
1.31k
  r = iso_ops->select_file(card, &index_path, &file);
297
298
1.31k
  if (r != SC_SUCCESS) {
299
26
    LOG_FUNC_RETURN(card->ctx, r);
300
26
  }
301
  /* Ignore too large files */
302
1.28k
  if (file->size > MAX_FILE_SIZE) {
303
0
    r = SC_ERROR_INVALID_DATA;
304
1.28k
  } else {
305
1.28k
    r = (int)file->size;
306
1.28k
  }
307
1.28k
  sc_file_free(file);
308
1.28k
  LOG_FUNC_RETURN(card->ctx, r);
309
1.28k
}
310
311
static int idprime_process_containermap(sc_card_t *card, idprime_private_data_t *priv, int length)
312
435
{
313
435
  u8 *buf = NULL;
314
435
  int r = SC_ERROR_OUT_OF_MEMORY;
315
435
  int i;
316
435
  uint8_t max_entries, container_index;
317
318
435
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
319
320
435
  buf = malloc(length);
321
435
  if (buf == NULL) {
322
0
    goto done;
323
0
  }
324
325
435
  r = 0;
326
1.47k
  do {
327
    /* Read at most CONTAINER_OBJ_LEN bytes */
328
1.47k
    int read_length = length - r > CONTAINER_OBJ_LEN ? CONTAINER_OBJ_LEN : length - r;
329
1.47k
    if (length == r) {
330
0
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
331
0
      goto done;
332
0
    }
333
1.47k
    const int got = iso_ops->read_binary(card, r, buf + r, read_length, 0);
334
1.47k
    if (got < 1) {
335
68
      r = SC_ERROR_WRONG_LENGTH;
336
68
      goto done;
337
68
    }
338
339
1.40k
    r += got;
340
    /* Try to read chunks of container size and stop when last container looks empty */
341
1.40k
    container_index = r > CONTAINER_OBJ_LEN ? (r / CONTAINER_OBJ_LEN - 1) * CONTAINER_OBJ_LEN : 0;
342
1.40k
  } while(length - r > 0 && buf[container_index] != 0);
343
367
  max_entries = r / CONTAINER_OBJ_LEN;
344
345
455
  for (i = 0; i < max_entries; i++) {
346
104
    u8 *start = &buf[i * CONTAINER_OBJ_LEN];
347
104
    idprime_container_t new_container = {0};
348
104
    if (start[0] == 0) /* Empty record */
349
16
      break;
350
351
88
    new_container.index = i;
352
    /* Reading UNICODE characters but skipping second byte */
353
88
    int j = 0;
354
1.29k
    for (j = 0; j < MAX_CONTAINER_NAME_LEN; j++) {
355
1.26k
      if (start[2 * j] == 0)
356
66
        break;
357
1.20k
      new_container.guid[j] = start[2 * j];
358
1.20k
    }
359
360
88
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found container with index=%d, guid=%s", new_container.index, new_container.guid);
361
362
88
    if ((r = idprime_add_container_to_list(&priv->containers, &new_container)) != SC_SUCCESS) {
363
0
      goto done;
364
0
    }
365
88
  }
366
367
367
  r = SC_SUCCESS;
368
435
done:
369
435
  free(buf);
370
435
  LOG_FUNC_RETURN(card->ctx, r);
371
435
}
372
373
static int idprime_process_keyrefmap(sc_card_t *card, idprime_private_data_t *priv, int length)
374
109
{
375
109
  u8 *buf = NULL;
376
109
  int r = SC_ERROR_OUT_OF_MEMORY;
377
109
  int i, max_entries;
378
379
109
  buf = malloc(length);
380
109
  if (buf == NULL) {
381
0
    goto done;
382
0
  }
383
384
109
  r = 0;
385
514
  do {
386
514
    if (length == r) {
387
0
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
388
0
      goto done;
389
0
    }
390
514
    const int got = iso_ops->read_binary(card, r, buf + r, length - r, 0);
391
514
    if (got < 1) {
392
50
      r = SC_ERROR_WRONG_LENGTH;
393
50
      goto done;
394
50
    }
395
396
464
    r += got;
397
464
  } while(length - r > 0);
398
59
  max_entries = r / KEYREF_OBJ_LEN;
399
400
13.6k
  for (i = 0; i < max_entries; i++) {
401
13.6k
    idprime_keyref_t new_keyref;
402
13.6k
    u8 *start = &buf[i * KEYREF_OBJ_LEN];
403
13.6k
    if (start[0] == 0) /* Empty key ref */
404
2.00k
      continue;
405
406
11.6k
    new_keyref.index = start[2];
407
11.6k
    new_keyref.key_reference = start[1];
408
11.6k
    new_keyref.pin_index = start[7];
409
11.6k
    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
11.6k
    if ((r = idprime_add_keyref_to_list(&priv->keyrefmap, &new_keyref)) != SC_SUCCESS) {
412
0
      goto done;
413
0
    }
414
11.6k
  }
415
59
  r = SC_SUCCESS;
416
109
done:
417
109
  free(buf);
418
109
  LOG_FUNC_RETURN(card->ctx, r);
419
109
}
420
421
static int idprime_process_index(sc_card_t *card, idprime_private_data_t *priv, int length)
422
250
{
423
250
  u8 *buf = NULL;
424
250
  int r = SC_ERROR_OUT_OF_MEMORY;
425
250
  int i, num_entries;
426
250
  idprime_object_t new_object;
427
428
250
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
429
430
250
  buf = malloc(length);
431
250
  if (buf == NULL) {
432
0
    goto done;
433
0
  }
434
435
250
  r = 0;
436
515
  do {
437
515
    if (length == r) {
438
1
      r = SC_ERROR_NOT_ENOUGH_MEMORY;
439
1
      goto done;
440
1
    }
441
514
    const int got = iso_ops->read_binary(card, r, buf + r, length - r, 0);
442
514
    if (got < 1) {
443
27
      r = SC_ERROR_WRONG_LENGTH;
444
27
      goto done;
445
27
    }
446
    /* First byte shows the number of entries, each of them 21 bytes long */
447
487
    num_entries = buf[0];
448
487
    r += got;
449
487
  } while(r < num_entries * 21 + 1);
450
451
222
  new_object.fd = 0;
452
6.56k
  for (i = 0; i < num_entries; i++) {
453
6.34k
    u8 *start = &buf[i*21+1];
454
455
    /* First two bytes specify the object DF */
456
6.34k
    new_object.df[0] = start[0];
457
6.34k
    new_object.df[1] = start[1];
458
    /* Second two bytes refer to the object size */
459
6.34k
    new_object.length = bebytes2ushort(&start[2]);
460
6.34k
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "df=%s, len=%u",
461
6.34k
      sc_dump_hex(new_object.df, sizeof(new_object.df)), new_object.length);
462
    /* in minidriver, mscp/kxcNN or kscNN lists certificates */
463
6.34k
    if (((memcmp(&start[4], "ksc", 3) == 0) || memcmp(&start[4], "kxc", 3) == 0)
464
1.00k
      && (memcmp(&start[12], "mscp", 5) == 0)) {
465
829
      uint8_t cert_id = 0;
466
829
      idprime_container_t *container = NULL;
467
468
829
      if (start[7] >= '0' && start[7] <= '9' && start[8] >= '0' && start[8] <= '9') {
469
331
        cert_id = (start[7] - '0') * 10 + start[8] - '0';
470
331
      }
471
829
      new_object.fd++;
472
829
      new_object.key_reference = -1;
473
829
      new_object.valid_key_ref = 0;
474
829
      new_object.pin_index = 1;
475
476
829
      container = (idprime_container_t *) list_seek(&priv->containers, &cert_id);
477
829
      if (!container) {
478
        /* Container map missing container with certificate ID */
479
551
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding container with private key found for certificate with id=%d", cert_id);
480
551
        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
323
          sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd);
485
323
          idprime_add_object_to_list(&priv->pki_list, &new_object);
486
323
          continue;
487
323
        }
488
551
      }
489
490
506
      switch (card->type) {
491
41
      case SC_CARD_TYPE_IDPRIME_3810:
492
41
        new_object.key_reference = 0x31 + cert_id;
493
41
        break;
494
41
      case SC_CARD_TYPE_IDPRIME_830:
495
41
        new_object.key_reference = 0x41 + cert_id;
496
41
        break;
497
38
      case SC_CARD_TYPE_IDPRIME_930:
498
38
        new_object.key_reference = 0x11 + cert_id * 2;
499
38
        break;
500
0
      case SC_CARD_TYPE_IDPRIME_930_PLUS:
501
0
        new_object.key_reference = 0x10 + cert_id * 2;
502
0
        break;
503
255
      case SC_CARD_TYPE_IDPRIME_940: {
504
255
          idprime_keyref_t *keyref = (idprime_keyref_t *) list_seek(&priv->keyrefmap, &cert_id);
505
255
          if (!keyref) {
506
            /* Key reference file does not contain record of the key for given certificate */
507
217
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "No corresponding key reference found for certificate with id=%d", cert_id);
508
217
            sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Adding certificate with fd=%d", new_object.fd);
509
217
            idprime_add_object_to_list(&priv->pki_list, &new_object);
510
217
            continue;
511
217
          }
512
38
          new_object.key_reference = keyref->key_reference;
513
38
          new_object.pin_index = keyref->pin_index;
514
38
          break;
515
255
        }
516
42
      case SC_CARD_TYPE_IDPRIME_840:
517
42
        new_object.key_reference = 0xf7 + cert_id;
518
42
        break;
519
89
      default:
520
89
        new_object.key_reference = 0x56 + cert_id;
521
89
        break;
522
506
      }
523
289
      new_object.valid_key_ref = 1;
524
289
      if (container != NULL) {
525
251
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d corresponding to container \"%s\"",
526
251
          new_object.fd, new_object.key_reference, container->guid);
527
251
      } else {
528
38
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found certificate with fd=%d, key_ref=%d without corresponding container",
529
38
          new_object.fd, new_object.key_reference);
530
38
      }
531
532
289
      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
5.51k
    } else if ((memcmp(&start[4], "tinfo", 6) == 0) && (memcmp(&start[12], "p11", 4) == 0)) {
536
10
      memcpy(priv->tinfo_df, new_object.df, sizeof(priv->tinfo_df));
537
10
      priv->tinfo_present = 1;
538
10
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found p11/tinfo object");
539
5.50k
    } else if ((memcmp(&start[4], "cmapfile", 8) == 0) && (memcmp(&start[12], "mscp", 4) == 0)) {
540
184
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found mscp/cmapfile object %s",
541
184
          (start[0] == 02 && start[1] == 04 ? "(already processed)" : "(in non-standard path!)"));
542
5.32k
    } else if (memcmp(&start[4], "cardapps", 8) == 0) {
543
34
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found cardapps object");
544
5.28k
    } else if (memcmp(&start[4], "cardid", 6) == 0) {
545
37
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found cardid object");
546
5.25k
    } else if (memcmp(&start[4], "cardcf", 6) == 0) {
547
20
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Found cardcf object");
548
20
    }
549
6.34k
  }
550
551
222
  r = SC_SUCCESS;
552
250
done:
553
250
  free(buf);
554
250
  LOG_FUNC_RETURN(card->ctx, r);
555
250
}
556
557
/* CPLC has 42 bytes, but we get it with 3B header */
558
484
#define CPLC_LENGTH 45
559
static int idprime_init(sc_card_t *card)
560
488
{
561
488
  int r;
562
488
  unsigned long flags, ext_flags;
563
488
  idprime_private_data_t *priv = NULL;
564
488
  struct sc_apdu apdu;
565
488
  u8 rbuf[CPLC_LENGTH];
566
488
  size_t rbuflen = sizeof(rbuf);
567
568
488
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
569
570
  /* We need to differentiate the OS version since they behave slightly differently */
571
488
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xCA, 0x9F, 0x7F);
572
488
  apdu.resp = rbuf;
573
488
  apdu.resplen = rbuflen;
574
488
  apdu.le = rbuflen;
575
488
  r = sc_transmit_apdu(card, &apdu);
576
488
  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
483
  } else {
596
483
    sc_log(card->ctx, "Failed to get CPLC data or invalid length returned, "
597
483
      "err=%d, len=%"SC_FORMAT_LEN_SIZE_T"u",
598
483
      r, apdu.resplen);
599
483
  }
600
601
  /* Proprietary data -- Applet version */
602
488
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0xCA, 0xDF, 0x30);
603
488
  apdu.resp = rbuf;
604
488
  apdu.resplen = rbuflen;
605
488
  apdu.le = rbuflen;
606
488
  r = sc_transmit_apdu(card, &apdu);
607
488
  if (r == SC_SUCCESS && apdu.resplen >= 10) {
608
    /* Ber-TLV encoded */
609
19
    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
19
  }
613
614
488
  priv = idprime_new_private_data();
615
488
  if (!priv) {
616
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
617
0
  }
618
619
  /* Select and process container file */
620
488
  r = idprime_select_file_by_path(card, "0204");;
621
488
  if (r <= 0) {
622
53
    idprime_free_private_data(priv);
623
53
    if (r == 0)
624
1
      r = SC_ERROR_INVALID_DATA;
625
53
    LOG_FUNC_RETURN(card->ctx, r);
626
53
  }
627
628
435
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Container file found");
629
630
435
  r = idprime_process_containermap(card, priv, r);
631
435
  if (r != SC_SUCCESS) {
632
68
    idprime_free_private_data(priv);
633
68
    LOG_FUNC_RETURN(card->ctx, r);
634
68
  }
635
636
367
  if (card->type == SC_CARD_TYPE_IDPRIME_940) {
637
118
    if ((r = idprime_select_file_by_path(card, "0005")) <= 0) {
638
9
      idprime_free_private_data(priv);
639
9
      if (r == 0)
640
1
        r = SC_ERROR_INVALID_DATA;
641
9
      LOG_FUNC_RETURN(card->ctx, r);
642
9
    }
643
644
109
    if ((r = idprime_process_keyrefmap(card, priv, r)) != SC_SUCCESS) {
645
50
      idprime_free_private_data(priv);
646
50
      LOG_FUNC_RETURN(card->ctx, r);
647
50
    }
648
109
  }
649
650
  /* Select and process the index file */
651
308
  r = idprime_select_file_by_path(card, "0101");
652
308
  if (r <= 0) {
653
58
    idprime_free_private_data(priv);
654
58
    if (r == 0)
655
2
      r = SC_ERROR_INVALID_DATA;
656
58
    LOG_FUNC_RETURN(card->ctx, r);
657
58
  }
658
659
250
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Index file found");
660
661
250
  r = idprime_process_index(card, priv, r);
662
250
  if (r != SC_SUCCESS) {
663
28
    idprime_free_private_data(priv);
664
28
    LOG_FUNC_RETURN(card->ctx, r);
665
28
  }
666
667
222
  card->drv_data = priv;
668
669
222
  switch (card->type) {
670
8
  case SC_CARD_TYPE_IDPRIME_3810:
671
8
    card->name = "Gemalto IDPrime 3810";
672
8
    break;
673
10
  case SC_CARD_TYPE_IDPRIME_830:
674
10
    card->name = "Gemalto IDPrime MD 830";
675
10
    break;
676
11
  case SC_CARD_TYPE_IDPRIME_930:
677
11
  case SC_CARD_TYPE_IDPRIME_930_PLUS:
678
11
    card->name = "Gemalto IDPrime 930/3930";
679
11
    break;
680
25
  case SC_CARD_TYPE_IDPRIME_940:
681
25
    card->name = "Gemalto IDPrime 940";
682
25
    break;
683
32
  case SC_CARD_TYPE_IDPRIME_840:
684
32
    card->name = "Gemalto IDPrime MD 840";
685
32
    break;
686
136
  case SC_CARD_TYPE_IDPRIME_GENERIC:
687
136
  default:
688
136
    card->name = "Gemalto IDPrime (generic)";
689
136
    break;
690
222
  }
691
222
  card->cla = 0x00;
692
693
  /* Set up algorithm info for RSA. */
694
222
  flags = SC_ALGORITHM_RSA_PAD_PKCS1
695
222
    | SC_ALGORITHM_RSA_PAD_PSS
696
222
    | SC_ALGORITHM_RSA_PAD_OAEP
697
    /* SHA-1 mechanisms are not allowed in the card I have */
698
222
    | (SC_ALGORITHM_RSA_HASH_SHA256 | SC_ALGORITHM_RSA_HASH_SHA384 | SC_ALGORITHM_RSA_HASH_SHA512)
699
222
    | (SC_ALGORITHM_MGF1_SHA256 | SC_ALGORITHM_MGF1_SHA384 | SC_ALGORITHM_MGF1_SHA512)
700
222
    ;
701
702
222
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
703
222
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
704
222
  switch (card->type) {
705
0
  case SC_CARD_TYPE_IDPRIME_930_PLUS:
706
25
  case SC_CARD_TYPE_IDPRIME_940:
707
25
    _sc_card_add_rsa_alg(card, 3072, flags, 0);
708
    /* fallthrough */
709
36
  case SC_CARD_TYPE_IDPRIME_930:
710
36
    _sc_card_add_rsa_alg(card, 4096, flags, 0);
711
    /* fallthrough */
712
68
  case SC_CARD_TYPE_IDPRIME_840:
713
    /* Set up algorithm info for EC */
714
68
    flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
715
68
    if (card->type == SC_CARD_TYPE_IDPRIME_930_PLUS || card->type == SC_CARD_TYPE_IDPRIME_940) {
716
25
      flags |= SC_ALGORITHM_ECDH_CDH_RAW;
717
25
    }
718
68
    ext_flags = SC_ALGORITHM_EXT_EC_F_P
719
68
      | SC_ALGORITHM_EXT_EC_ECPARAMETERS
720
68
      | SC_ALGORITHM_EXT_EC_NAMEDCURVE
721
68
      | SC_ALGORITHM_EXT_EC_UNCOMPRESES
722
68
      ;
723
68
    _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
724
68
    _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
725
68
    _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL);
726
68
    break;
727
154
  default:
728
154
    break;
729
222
  }
730
731
222
  card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO;
732
733
222
  card->caps |= SC_CARD_CAP_RNG;
734
735
222
  LOG_FUNC_RETURN(card->ctx, 0);
736
222
}
737
738
static int idprime_finish(sc_card_t *card)
739
222
{
740
222
  idprime_private_data_t * priv = card->drv_data;
741
742
222
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
743
222
  if (priv) {
744
222
    idprime_free_private_data(priv);
745
222
  }
746
222
  return SC_SUCCESS;
747
222
}
748
749
static int idprime_match_card(sc_card_t *card)
750
6.21k
{
751
6.21k
  int i, r;
752
753
6.21k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
754
6.21k
  i = _sc_match_atr(card, idprime_atrs, &card->type);
755
6.21k
  if (i < 0)
756
5.62k
    return 0;
757
758
591
  r = idprime_select_file_by_path(card, "0101");
759
591
  LOG_FUNC_RETURN(card->ctx, r > 0);
760
591
}
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
0
{
765
0
  if (countp == NULL || entry == NULL) {
766
0
    return SC_ERROR_INVALID_ARGUMENTS;
767
0
  }
768
0
  *countp = list_size(list);
769
0
  list_iterator_start(list);
770
0
  *entry = list_iterator_next(list);
771
0
  return SC_SUCCESS;
772
0
}
773
774
/* finalize the list iterator */
775
static int idprime_final_iterator(list_t *list)
776
0
{
777
0
  list_iterator_stop(list);
778
0
  return SC_SUCCESS;
779
0
}
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
0
{
784
0
  memset(prkey_info, 0, sizeof(sc_pkcs15_prkey_info_t));
785
0
  if (*entry == NULL) {
786
0
    return SC_ERROR_FILE_END_REACHED;
787
0
  }
788
789
0
  prkey_info->path.len = sizeof((*entry)->df);
790
0
  memcpy(prkey_info->path.value, (*entry)->df, sizeof((*entry)->df));
791
0
  prkey_info->path.type = SC_PATH_TYPE_FILE_ID;
792
  /* Do not specify the length -- it will be read from the FCI */
793
0
  prkey_info->path.count = -1;
794
795
  /* TODO figure out the IDs as the original driver? */
796
0
  prkey_info->id.value[0] = ((*entry)->fd >> 8) & 0xff;
797
0
  prkey_info->id.value[1] = (*entry)->fd & 0xff;
798
0
  prkey_info->id.len = 2;
799
0
  if ((*entry)->valid_key_ref)
800
0
    prkey_info->key_reference = (*entry)->key_reference;
801
0
  else
802
0
    prkey_info->key_reference = -1;
803
0
  *entry = list_iterator_next(list);
804
0
  return SC_SUCCESS;
805
0
}
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
0
{
810
0
  if (pin_id == NULL || entry == NULL) {
811
0
    return SC_ERROR_INVALID_ARGUMENTS;
812
0
  }
813
0
  *pin_id = "11"; // normal PIN id
814
0
  if ((*entry)->pin_index != 1)
815
0
    *pin_id = "83"; // signature PIN id
816
0
  return SC_SUCCESS;
817
0
}
818
819
0
#define IDPRIME_CARDID_LEN 16
820
821
static int idprime_get_serial(sc_card_t* card, sc_serial_number_t* serial)
822
0
{
823
0
  sc_path_t cardid_path;
824
0
  sc_file_t *file = NULL;
825
0
  u8 buf[IDPRIME_CARDID_LEN];
826
0
  int r;
827
828
0
  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
0
  sc_format_path("0201", &cardid_path);
832
0
  r = iso_ops->select_file(card, &cardid_path, &file);
833
0
  if (r != SC_SUCCESS || file->size != IDPRIME_CARDID_LEN) { /* The cardid is always 16 B */
834
0
    sc_file_free(file);
835
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_LENGTH);
836
0
  }
837
838
0
  r = iso_ops->read_binary(card, 0, buf, file->size, 0);
839
0
  sc_file_free(file);
840
0
  if (r < 1) {
841
0
    LOG_FUNC_RETURN(card->ctx, r);
842
0
  } else if (r != IDPRIME_CARDID_LEN) {
843
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
844
0
  }
845
846
0
  serial->len = MIN(IDPRIME_CARDID_LEN, SC_MAX_SERIALNR);
847
0
  memcpy(serial->value, buf, serial->len);
848
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
849
0
}
850
851
static int idprime_get_token_name(sc_card_t* card, char** tname)
852
0
{
853
0
  idprime_private_data_t * priv = card->drv_data;
854
0
  sc_path_t tinfo_path = {"\x00\x00", 2, 0, 0, SC_PATH_TYPE_PATH, {"", 0}};
855
0
  sc_file_t *file = NULL;
856
0
  u8 buf[2];
857
0
  char *name;
858
0
  int r;
859
860
0
  LOG_FUNC_CALLED(card->ctx);
861
862
0
  if (tname == NULL) {
863
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
864
0
  }
865
866
0
  if (!priv->tinfo_present) {
867
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
868
0
  }
869
870
0
  memcpy(tinfo_path.value, priv->tinfo_df, 2);
871
0
  r = iso_ops->select_file(card, &tinfo_path, &file);
872
0
  if (r != SC_SUCCESS || file->size == 0) {
873
0
    sc_file_free(file);
874
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
875
0
  }
876
877
  /* First two bytes lists 0x01, the second indicates length */
878
0
  r = iso_ops->read_binary(card, 0, buf, 2, 0);
879
0
  if (r < 2 || buf[1] > file->size) { /* make sure we do not overrun */
880
0
    sc_file_free(file);
881
0
    LOG_FUNC_RETURN(card->ctx, r);
882
0
  }
883
0
  sc_file_free(file);
884
885
0
  name = malloc(buf[1]);
886
0
  if (name == NULL) {
887
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
888
0
  }
889
890
0
  r = iso_ops->read_binary(card, 2, (unsigned char *)name, buf[1], 0);
891
0
  if (r < 1) {
892
0
    free(name);
893
0
    LOG_FUNC_RETURN(card->ctx, r);
894
0
  }
895
896
0
  if (name[r-1] != '\0') {
897
0
    name[r-1] = '\0';
898
0
  }
899
0
  *tname = name;
900
901
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
902
0
}
903
904
static int idprime_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
905
0
{
906
0
  idprime_private_data_t * priv = card->drv_data;
907
908
0
  LOG_FUNC_CALLED(card->ctx);
909
0
  sc_log(card->ctx, "cmd=%ld ptr=%p", cmd, ptr);
910
911
0
  if (priv == NULL) {
912
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
913
0
  }
914
0
  switch (cmd) {
915
0
    case SC_CARDCTL_GET_SERIALNR:
916
0
      return idprime_get_serial(card, (sc_serial_number_t *) ptr);
917
0
    case SC_CARDCTL_IDPRIME_GET_TOKEN_NAME:
918
0
      return idprime_get_token_name(card, (char **) ptr);
919
0
    case SC_CARDCTL_IDPRIME_INIT_GET_OBJECTS:
920
0
      return idprime_get_init_and_get_count(&priv->pki_list, &priv->pki_current,
921
0
        (int *)ptr);
922
0
    case SC_CARDCTL_IDPRIME_GET_NEXT_OBJECT:
923
0
      return idprime_fill_prkey_info(&priv->pki_list, &priv->pki_current,
924
0
        (sc_pkcs15_prkey_info_t *)ptr);
925
0
    case SC_CARDCTL_IDPRIME_FINAL_GET_OBJECTS:
926
0
      return idprime_final_iterator(&priv->pki_list);
927
0
    case SC_CARDCTL_IDPRIME_GET_PIN_ID:
928
0
      return idprime_get_pin_id(&priv->pki_list, &priv->pki_current,
929
0
        (const char **)ptr);
930
0
  }
931
932
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
933
0
}
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
0
{
939
0
  int r;
940
0
  idprime_private_data_t * priv = card->drv_data;
941
942
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
943
944
  /* forget any old cached values */
945
0
  if (priv->cache_buf) {
946
0
    free(priv->cache_buf);
947
0
    priv->cache_buf = NULL;
948
0
  }
949
0
  priv->cache_buf_len = 0;
950
0
  priv->cached = 0;
951
952
0
  r = iso_ops->select_file(card, in_path, file_out);
953
0
  if (r == SC_SUCCESS && file_out != NULL) {
954
    /* Cache the real file size for the caching read_binary() */
955
0
    priv->file_size = (*file_out)->size;
956
0
  }
957
  /* Return the exit code of the select command */
958
0
  return r;
959
0
}
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
0
{
965
0
  struct idprime_private_data *priv = card->drv_data;
966
0
  int r = 0;
967
0
  int size;
968
0
  size_t sz;
969
970
0
  sc_log(card->ctx, "called; %"SC_FORMAT_LEN_SIZE_T"u bytes at offset %d",
971
0
    count, offset);
972
973
0
  if (!priv->cached && offset == 0) {
974
    /* Read what was reported by FCI from select command */
975
0
    size_t left = priv->file_size;
976
0
    unsigned read = 0;
977
978
    // this function is called to read and uncompress the certificate
979
0
    u8 buffer[SC_MAX_EXT_APDU_BUFFER_SIZE];
980
0
    u8 *data_buffer = buffer;
981
0
    if (sizeof(buffer) < count || sizeof(buffer) < priv->file_size) {
982
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
983
0
    }
984
0
    while (left > 0) {
985
0
      r = iso_ops->read_binary(card, read, buffer + read, priv->file_size - read, flags);
986
0
      if (r <= 0) {
987
0
        LOG_FUNC_RETURN(card->ctx, r);
988
0
      }
989
0
      left -= r;
990
0
      read += r;
991
0
    }
992
0
    if (read < 4 || read != priv->file_size) {
993
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
994
0
    }
995
0
    if (buffer[0] == 1 && buffer[1] == 0) {
996
      /* Data will be decompressed later */
997
0
      data_buffer += 4;
998
0
      sz = priv->file_size - 4;
999
0
      if (flags)
1000
0
        *flags |= SC_FILE_FLAG_COMPRESSED_AUTO;
1001
0
    } else {
1002
0
      sz = priv->file_size;
1003
0
    }
1004
0
    priv->cache_buf = malloc(sz);
1005
0
    if (priv->cache_buf == NULL) {
1006
0
      return SC_ERROR_OUT_OF_MEMORY;
1007
0
    }
1008
0
    memcpy(priv->cache_buf, data_buffer, sz);
1009
0
    priv->cache_buf_len = sz;
1010
0
    priv->cached = 1;
1011
0
  }
1012
0
  if (offset >= priv->cache_buf_len) {
1013
0
    return 0;
1014
0
  }
1015
0
  size = (int) MIN((priv->cache_buf_len - offset), count);
1016
0
  memcpy(buf, priv->cache_buf + offset, size);
1017
0
  return size;
1018
0
}
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
478
{
1225
478
  u8 rbuf[16];
1226
478
  size_t out_len;
1227
478
  struct sc_apdu apdu;
1228
478
  int r;
1229
1230
478
  LOG_FUNC_CALLED(card->ctx);
1231
1232
478
  if (len <= 8) {
1233
    /* official closed driver always calls this regardless the length */
1234
71
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x01);
1235
71
    apdu.le = apdu.resplen = 8;
1236
407
  } else {
1237
    /* this was discovered accidentally - all 16 bytes seem random */
1238
407
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x84, 0x00, 0x00);
1239
407
    apdu.le = apdu.resplen = 16;
1240
407
  }
1241
478
  apdu.resp = rbuf;
1242
1243
478
  r = sc_transmit_apdu(card, &apdu);
1244
478
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1245
1246
477
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1247
477
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE failed");
1248
1249
261
  out_len = len < apdu.resplen ? len : apdu.resplen;
1250
261
  memcpy(rnd, rbuf, out_len);
1251
1252
261
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
1253
261
}
1254
1255
static struct sc_card_driver * sc_get_driver(void)
1256
8.81k
{
1257
8.81k
  if (iso_ops == NULL) {
1258
1
    iso_ops = sc_get_iso7816_driver()->ops;
1259
1
  }
1260
1261
8.81k
  idprime_ops = *iso_ops;
1262
8.81k
  idprime_ops.match_card = idprime_match_card;
1263
8.81k
  idprime_ops.init = idprime_init;
1264
8.81k
  idprime_ops.finish = idprime_finish;
1265
1266
8.81k
  idprime_ops.read_binary = idprime_read_binary;
1267
8.81k
  idprime_ops.select_file = idprime_select_file;
1268
8.81k
  idprime_ops.card_ctl = idprime_card_ctl;
1269
8.81k
  idprime_ops.set_security_env = idprime_set_security_env;
1270
8.81k
  idprime_ops.compute_signature = idprime_compute_signature;
1271
8.81k
  idprime_ops.decipher = idprime_decipher;
1272
1273
8.81k
  idprime_ops.get_challenge = idprime_get_challenge;
1274
1275
8.81k
  return &idprime_drv;
1276
8.81k
}
1277
1278
struct sc_card_driver * sc_get_idprime_driver(void)
1279
8.81k
{
1280
8.81k
  return sc_get_driver();
1281
8.81k
}