Coverage Report

Created: 2025-07-01 06:08

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