Coverage Report

Created: 2026-07-10 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-gemsafeV1.c
Line
Count
Source
1
/*
2
 * This library is free software; you can redistribute it and/or
3
 * modify it under the terms of the GNU Lesser General Public
4
 * License as published by the Free Software Foundation; either
5
 * version 2.1 of the License, or (at your option) any later version.
6
 *
7
 * This library is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10
 * Lesser General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU Lesser General Public
13
 * License along with this library; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
*/
16
17
/* Initially written by David Mattes <david.mattes@boeing.com> */
18
/* Support for multiple key containers by Lukas Wunner <lukas@wunner.de> */
19
20
#ifdef HAVE_CONFIG_H
21
#include "config.h"
22
#endif
23
24
#include <stdlib.h>
25
#include <string.h>
26
#include <stdio.h>
27
28
#include "internal.h"
29
#include "pkcs15.h"
30
31
896
#define MANU_ID     "Gemplus"
32
3.48k
#define APPLET_NAME   "GemSAFE V1"
33
3.48k
#define DRIVER_SERIAL_NUMBER  "v0.9"
34
228
#define GEMSAFE_APP_PATH  "3F001600"
35
896
#define GEMSAFE_PATH    "3F0016000004"
36
37
/* Apparently, the Applet max read "quanta" is 248 bytes
38
 * Gemalto ClassicClient reads files in chunks of 238 bytes
39
 */
40
775
#define GEMSAFE_READ_QUANTUM    248
41
707
#define GEMSAFE_MAX_OBJLEN      28672
42
43
static int
44
sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card,
45
  int type, int authority,
46
  const sc_path_t *path,
47
  const sc_pkcs15_id_t *id,
48
  const char *label, int obj_flags);
49
50
static int
51
sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card,
52
  const sc_pkcs15_id_t *id, const char *label,
53
  const sc_path_t *path, int ref, int type,
54
  unsigned int min_length,
55
  unsigned int max_length,
56
  int flags, int tries_left, const char pad_char, int obj_flags);
57
58
static int
59
sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card,
60
  const sc_pkcs15_id_t *id,
61
  const char *label,
62
  int type, unsigned int modulus_length, int usage,
63
  const sc_path_t *path, int ref,
64
  const sc_pkcs15_id_t *auth_id, int obj_flags);
65
66
typedef struct cdata_st {
67
  char     *label;
68
  int     authority;
69
  const char *path;
70
  int     index;
71
  int     count;
72
  const char *id;
73
  int         obj_flags;
74
} cdata;
75
76
const unsigned int gemsafe_cert_max = 12;
77
78
cdata gemsafe_cert[] = {
79
  {"DS certificate #1",  0, GEMSAFE_PATH, 0, 0, "45", SC_PKCS15_CO_FLAG_MODIFIABLE},
80
  {"DS certificate #2",  0, GEMSAFE_PATH, 0, 0, "46", SC_PKCS15_CO_FLAG_MODIFIABLE},
81
  {"DS certificate #3",  0, GEMSAFE_PATH, 0, 0, "47", SC_PKCS15_CO_FLAG_MODIFIABLE},
82
  {"DS certificate #4",  0, GEMSAFE_PATH, 0, 0, "48", SC_PKCS15_CO_FLAG_MODIFIABLE},
83
  {"DS certificate #5",  0, GEMSAFE_PATH, 0, 0, "49", SC_PKCS15_CO_FLAG_MODIFIABLE},
84
  {"DS certificate #6",  0, GEMSAFE_PATH, 0, 0, "50", SC_PKCS15_CO_FLAG_MODIFIABLE},
85
  {"DS certificate #7",  0, GEMSAFE_PATH, 0, 0, "51", SC_PKCS15_CO_FLAG_MODIFIABLE},
86
  {"DS certificate #8",  0, GEMSAFE_PATH, 0, 0, "52", SC_PKCS15_CO_FLAG_MODIFIABLE},
87
  {"DS certificate #9",  0, GEMSAFE_PATH, 0, 0, "53", SC_PKCS15_CO_FLAG_MODIFIABLE},
88
  {"DS certificate #10", 0, GEMSAFE_PATH, 0, 0, "54", SC_PKCS15_CO_FLAG_MODIFIABLE},
89
  {"DS certificate #11", 0, GEMSAFE_PATH, 0, 0, "55", SC_PKCS15_CO_FLAG_MODIFIABLE},
90
  {"DS certificate #12", 0, GEMSAFE_PATH, 0, 0, "56", SC_PKCS15_CO_FLAG_MODIFIABLE},
91
};
92
93
typedef struct pdata_st {
94
  const u8    atr[SC_MAX_ATR_SIZE];
95
  const size_t atr_len;
96
  const char *id;
97
  const char *label;
98
  const char *path;
99
  const int   ref;
100
  const int   type;
101
  const unsigned int maxlen;
102
  const unsigned int minlen;
103
  const int   flags;
104
  const int   tries_left;
105
  const char  pad_char;
106
  const int   obj_flags;
107
} pindata;
108
109
const unsigned int gemsafe_pin_max = 2;
110
111
const pindata gemsafe_pin[] = {
112
  /* ATR-specific PIN policies, first match found is used: */
113
  { {0x3B, 0x7D, 0x96, 0x00, 0x00, 0x80, 0x31, 0x80, 0x65,
114
     0xB0, 0x83, 0x11, 0x48, 0xC8, 0x83, 0x00, 0x90, 0x00}, 18,
115
    "01", "DS pin", GEMSAFE_PATH, 0x01, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
116
    8, 4, SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_LOCAL,
117
    3, 0x00, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE },
118
  /* default PIN policy comes last: */
119
  { { 0 }, 0,
120
    "01", "DS pin", GEMSAFE_PATH, 0x01, SC_PKCS15_PIN_TYPE_BCD,
121
    16, 6, SC_PKCS15_PIN_FLAG_NEEDS_PADDING | SC_PKCS15_PIN_FLAG_LOCAL,
122
    3, 0xFF, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE }
123
};
124
125
typedef struct prdata_st {
126
  const char *id;
127
  char     *label;
128
  unsigned int modulus_len;
129
  int         usage;
130
  const char *path;
131
  int         ref;
132
  const char *auth_id;
133
  int         obj_flags;
134
} prdata;
135
136
#define USAGE_NONREP  SC_PKCS15_PRKEY_USAGE_NONREPUDIATION
137
#define USAGE_KE  SC_PKCS15_PRKEY_USAGE_ENCRYPT | \
138
      SC_PKCS15_PRKEY_USAGE_DECRYPT | \
139
      SC_PKCS15_PRKEY_USAGE_WRAP    | \
140
      SC_PKCS15_PRKEY_USAGE_UNWRAP
141
#define USAGE_AUT SC_PKCS15_PRKEY_USAGE_ENCRYPT | \
142
      SC_PKCS15_PRKEY_USAGE_DECRYPT | \
143
      SC_PKCS15_PRKEY_USAGE_WRAP    | \
144
      SC_PKCS15_PRKEY_USAGE_UNWRAP  | \
145
      SC_PKCS15_PRKEY_USAGE_SIGN
146
147
prdata gemsafe_prkeys[] = {
148
  { "45", "DS key #1",  1024, USAGE_AUT, GEMSAFE_PATH, 0x03, "01", SC_PKCS15_CO_FLAG_PRIVATE},
149
  { "46", "DS key #2",  1024, USAGE_AUT, GEMSAFE_PATH, 0x04, "01", SC_PKCS15_CO_FLAG_PRIVATE},
150
  { "47", "DS key #3",  1024, USAGE_AUT, GEMSAFE_PATH, 0x05, "01", SC_PKCS15_CO_FLAG_PRIVATE},
151
  { "48", "DS key #4",  1024, USAGE_AUT, GEMSAFE_PATH, 0x06, "01", SC_PKCS15_CO_FLAG_PRIVATE},
152
  { "49", "DS key #5",  1024, USAGE_AUT, GEMSAFE_PATH, 0x07, "01", SC_PKCS15_CO_FLAG_PRIVATE},
153
  { "50", "DS key #6",  1024, USAGE_AUT, GEMSAFE_PATH, 0x08, "01", SC_PKCS15_CO_FLAG_PRIVATE},
154
  { "51", "DS key #7",  1024, USAGE_AUT, GEMSAFE_PATH, 0x09, "01", SC_PKCS15_CO_FLAG_PRIVATE},
155
  { "52", "DS key #8",  1024, USAGE_AUT, GEMSAFE_PATH, 0x0a, "01", SC_PKCS15_CO_FLAG_PRIVATE},
156
  { "53", "DS key #9",  1024, USAGE_AUT, GEMSAFE_PATH, 0x0b, "01", SC_PKCS15_CO_FLAG_PRIVATE},
157
  { "54", "DS key #10", 1024, USAGE_AUT, GEMSAFE_PATH, 0x0c, "01", SC_PKCS15_CO_FLAG_PRIVATE},
158
  { "55", "DS key #11", 1024, USAGE_AUT, GEMSAFE_PATH, 0x0d, "01", SC_PKCS15_CO_FLAG_PRIVATE},
159
  { "56", "DS key #12", 1024, USAGE_AUT, GEMSAFE_PATH, 0x0e, "01", SC_PKCS15_CO_FLAG_PRIVATE},
160
};
161
162
static int gemsafe_get_cert_len(sc_card_t *card)
163
896
{
164
896
  int r;
165
896
  u8  ibuf[GEMSAFE_MAX_OBJLEN];
166
896
  u8 *iptr;
167
896
  struct sc_path path;
168
896
  struct sc_file *file;
169
896
  size_t objlen;
170
896
  int certlen;
171
896
  unsigned int ind, i=0;
172
896
  int read_len;
173
174
896
  sc_format_path(GEMSAFE_PATH, &path);
175
896
  r = sc_select_file(card, &path, &file);
176
896
  if (r != SC_SUCCESS || !file)
177
121
    return SC_ERROR_INTERNAL;
178
775
  sc_file_free(file);
179
180
  /* Initial read */
181
775
  read_len = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0);
182
775
  if (read_len <= 2) {
183
61
    sc_log(card->ctx, "Invalid size of object data: %d", read_len);
184
61
    return SC_ERROR_INTERNAL;
185
61
  }
186
187
  /* Actual stored object size is encoded in first 2 bytes
188
   * (allocated EF space is much greater!)
189
   */
190
714
  objlen = (((size_t) ibuf[0]) << 8) | ibuf[1];
191
714
  sc_log(card->ctx, "Stored object is of size: %"SC_FORMAT_LEN_SIZE_T"u",
192
714
         objlen);
193
714
  if (objlen < 1 || objlen > GEMSAFE_MAX_OBJLEN) {
194
58
      sc_log(card->ctx, "Invalid object size: %"SC_FORMAT_LEN_SIZE_T"u",
195
58
       objlen);
196
58
      return SC_ERROR_INTERNAL;
197
58
  }
198
199
  /* It looks like the first thing in the block is a table of
200
   * which keys are allocated. The table is small and is in the
201
   * first 248 bytes. Example for a card with 10 key containers:
202
   * 01 f0 00 03 03 b0 00 03     <=  1st key unallocated
203
   * 01 f0 00 04 03 b0 00 04     <=  2nd key unallocated
204
   * 01 fe 14 00 05 03 b0 00 05  <=  3rd key allocated
205
   * 01 fe 14 01 06 03 b0 00 06  <=  4th key allocated
206
   * 01 f0 00 07 03 b0 00 07     <=  5th key unallocated
207
   * ...
208
   * 01 f0 00 0c 03 b0 00 0c     <= 10th key unallocated
209
   * For allocated keys, the fourth byte seems to indicate the
210
   * default key and the fifth byte indicates the key_ref of
211
   * the private key.
212
   */
213
656
  ind = 2; /* skip length */
214
1.14k
  while (ind + 1 < (size_t)read_len && ibuf[ind] == 0x01 && i < gemsafe_cert_max) {
215
492
    if (ibuf[ind+1] == 0xFE) {
216
103
      gemsafe_prkeys[i].ref = ibuf[ind+4];
217
103
      sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d",
218
103
          i+1, gemsafe_prkeys[i].ref);
219
103
      ind += 9;
220
103
    }
221
389
    else {
222
389
      gemsafe_prkeys[i].label = NULL;
223
389
      gemsafe_cert[i].label = NULL;
224
389
      sc_log(card->ctx, "Key container %d is unallocated", i+1);
225
389
      ind += 8;
226
389
    }
227
492
    i++;
228
492
  }
229
230
  /* Delete additional key containers from the data structures if
231
   * this card can't accommodate them.
232
   */
233
8.03k
  for (; i < gemsafe_cert_max; i++) {
234
7.38k
    gemsafe_prkeys[i].label = NULL;
235
7.38k
    gemsafe_cert[i].label = NULL;
236
7.38k
  }
237
238
  /* Read entire file, then dissect in memory.
239
   * Gemalto ClassicClient seems to do it the same way.
240
   */
241
656
  iptr = ibuf + read_len;
242
10.5k
  while ((size_t)(iptr - ibuf) < objlen) {
243
10.2k
    r = sc_read_binary(card, (unsigned)(iptr - ibuf), iptr,
244
10.2k
           MIN(GEMSAFE_READ_QUANTUM, objlen - (iptr - ibuf)), 0);
245
10.2k
    if (r < 0) {
246
374
      sc_log(card->ctx, "Could not read cert object");
247
374
      return SC_ERROR_INTERNAL;
248
374
    }
249
9.91k
    if (r == 0)
250
54
      break;
251
9.86k
    read_len += r;
252
9.86k
    iptr += r;
253
9.86k
  }
254
282
  if ((size_t)read_len < objlen) {
255
54
    sc_log(card->ctx, "Could not read cert object");
256
54
    return SC_ERROR_INTERNAL;
257
54
  }
258
259
  /* Search buffer for certificates, they start with 0x3082. */
260
228
  i = 0;
261
169k
  while (ind < objlen - 1) {
262
169k
    if (ibuf[ind] == 0x30 && ibuf[ind+1] == 0x82) {
263
      /* Find next allocated key container */
264
65
      while (i < gemsafe_cert_max && gemsafe_cert[i].label == NULL)
265
60
        i++;
266
5
      if (i == gemsafe_cert_max) {
267
5
        sc_log(card->ctx, "Warning: Found orphaned certificate at offset %d", ind);
268
5
        return SC_SUCCESS;
269
5
      }
270
      /* DER cert len is encoded this way */
271
0
      if (ind+3 >= sizeof ibuf)
272
0
        return SC_ERROR_INVALID_DATA;
273
0
      certlen = ((((int)ibuf[ind + 2]) << 8) | ibuf[ind + 3]) + 4;
274
0
      sc_log(card->ctx,
275
0
             "Found certificate of key container %d at offset %d, len %d",
276
0
             i+1, ind, certlen);
277
0
      gemsafe_cert[i].index = ind;
278
0
      gemsafe_cert[i].count = certlen;
279
0
      ind += certlen;
280
0
      i++;
281
0
    } else
282
169k
      ind++;
283
169k
  }
284
285
  /* Delete additional key containers from the data structures if
286
   * they're missing on the card.
287
   */
288
2.89k
  for (; i < gemsafe_cert_max; i++) {
289
2.67k
    if (gemsafe_cert[i].label) {
290
0
      sc_log(card->ctx, "Warning: Certificate of key container %d is missing", i+1);
291
0
      gemsafe_prkeys[i].label = NULL;
292
0
      gemsafe_cert[i].label = NULL;
293
0
    }
294
2.67k
  }
295
296
223
  return SC_SUCCESS;
297
228
}
298
299
static int gemsafe_detect_card( sc_pkcs15_card_t *p15card)
300
58.5k
{
301
58.5k
  if (strcmp(p15card->card->name, "GemSAFE V1"))
302
55.1k
    return SC_ERROR_WRONG_CARD;
303
304
3.48k
  return SC_SUCCESS;
305
58.5k
}
306
307
static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card)
308
3.48k
{
309
3.48k
  int       r;
310
3.48k
  unsigned int    i;
311
3.48k
  struct sc_path  path;
312
3.48k
  struct sc_file *file = NULL;
313
3.48k
  struct sc_card *card = p15card->card;
314
3.48k
  struct sc_apdu  apdu;
315
3.48k
  u8        rbuf[SC_MAX_APDU_BUFFER_SIZE];
316
317
3.48k
  sc_log(p15card->card->ctx, "Setting pkcs15 parameters");
318
319
3.48k
  set_string(&p15card->tokeninfo->label, APPLET_NAME);
320
3.48k
  if (!p15card->tokeninfo->label)
321
0
    return SC_ERROR_INTERNAL;
322
323
3.48k
  set_string(&p15card->tokeninfo->serial_number, DRIVER_SERIAL_NUMBER);
324
3.48k
  if (!p15card->tokeninfo->serial_number) {
325
0
    free(p15card->tokeninfo->label);
326
0
    p15card->tokeninfo->label = NULL;
327
0
    return SC_ERROR_INTERNAL;
328
0
  }
329
330
  /* the GemSAFE applet version number */
331
3.48k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03);
332
3.48k
  apdu.cla = 0x80;
333
3.48k
  apdu.resp = rbuf;
334
3.48k
  apdu.resplen = sizeof(rbuf);
335
  /* Manual says Le=0x05, but should be 0x08 to return full version number */
336
3.48k
  apdu.le = 0x08;
337
3.48k
  apdu.lc = 0;
338
3.48k
  apdu.datalen = 0;
339
3.48k
  r = sc_transmit_apdu(card, &apdu);
340
3.48k
  if (r < 0)
341
44
    sc_pkcs15_card_clear(p15card);
342
3.48k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
343
344
3.44k
  if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || r != SC_SUCCESS) {
345
2.54k
    sc_pkcs15_card_clear(p15card);
346
2.54k
    return SC_ERROR_INTERNAL;
347
2.54k
  }
348
349
  /* the manufacturer ID, in this case GemPlus */
350
896
  set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
351
896
  if (!p15card->tokeninfo->manufacturer_id) {
352
0
    sc_pkcs15_card_clear(p15card);
353
0
    return SC_ERROR_INTERNAL;
354
0
  }
355
356
  /* determine allocated key containers and length of certificates */
357
896
  r = gemsafe_get_cert_len(card);
358
896
  if (r != SC_SUCCESS) {
359
668
    sc_pkcs15_card_clear(p15card);
360
668
    return SC_ERROR_INTERNAL;
361
668
  }
362
363
  /* set certs */
364
228
  sc_log(p15card->card->ctx, "Setting certificates");
365
2.96k
  for (i = 0; i < gemsafe_cert_max; i++) {
366
2.73k
    struct sc_pkcs15_id p15Id;
367
2.73k
    struct sc_path path;
368
369
2.73k
    if (gemsafe_cert[i].label == NULL)
370
2.73k
      continue;
371
0
    sc_format_path(gemsafe_cert[i].path, &path);
372
0
    sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id);
373
0
    path.index = gemsafe_cert[i].index;
374
0
    path.count = gemsafe_cert[i].count;
375
0
    sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509,
376
0
              gemsafe_cert[i].authority, &path, &p15Id,
377
0
              gemsafe_cert[i].label, gemsafe_cert[i].obj_flags);
378
0
  }
379
380
  /* set gemsafe_pin */
381
228
  sc_log(p15card->card->ctx, "Setting PIN");
382
454
  for (i=0; i < gemsafe_pin_max; i++) {
383
454
    struct sc_pkcs15_id p15Id;
384
454
    struct sc_path path;
385
386
454
    sc_pkcs15_format_id(gemsafe_pin[i].id, &p15Id);
387
454
    sc_format_path(gemsafe_pin[i].path, &path);
388
454
    if (gemsafe_pin[i].atr_len == 0 ||
389
228
       (gemsafe_pin[i].atr_len == p15card->card->atr.len &&
390
14
        memcmp(p15card->card->atr.value, gemsafe_pin[i].atr,
391
228
         p15card->card->atr.len) == 0)) {
392
228
      sc_pkcs15emu_add_pin(p15card, &p15Id, gemsafe_pin[i].label,
393
228
               &path, gemsafe_pin[i].ref, gemsafe_pin[i].type,
394
228
               gemsafe_pin[i].minlen, gemsafe_pin[i].maxlen,
395
228
               gemsafe_pin[i].flags, gemsafe_pin[i].tries_left,
396
228
               gemsafe_pin[i].pad_char, gemsafe_pin[i].obj_flags);
397
228
      break;
398
228
    }
399
454
  };
400
401
  /* set private keys */
402
228
  sc_log(p15card->card->ctx, "Setting private keys");
403
2.96k
  for (i = 0; i < gemsafe_cert_max; i++) {
404
2.73k
    struct sc_pkcs15_id p15Id, authId, *pauthId;
405
2.73k
    struct sc_path path;
406
2.73k
    int key_ref = 0x03;
407
408
2.73k
    if (gemsafe_prkeys[i].label == NULL)
409
2.73k
      continue;
410
0
    sc_pkcs15_format_id(gemsafe_prkeys[i].id, &p15Id);
411
0
    if (gemsafe_prkeys[i].auth_id) {
412
0
      sc_pkcs15_format_id(gemsafe_prkeys[i].auth_id, &authId);
413
0
      pauthId = &authId;
414
0
    } else
415
0
      pauthId = NULL;
416
0
    sc_format_path(gemsafe_prkeys[i].path, &path);
417
    /*
418
     * The key ref may be different for different sites;
419
     * by adding flags=n where the low order 4 bits can be
420
     * the key ref we can force it.
421
     */
422
0
    if ( p15card->card->flags & 0x0F) {
423
0
      key_ref = p15card->card->flags & 0x0F;
424
0
      sc_log(p15card->card->ctx,
425
0
         "Overriding key_ref %d with %d\n",
426
0
         gemsafe_prkeys[i].ref, key_ref);
427
0
    } else
428
0
      key_ref = gemsafe_prkeys[i].ref;
429
0
    sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label,
430
0
               SC_PKCS15_TYPE_PRKEY_RSA,
431
0
               gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage,
432
0
               &path, key_ref, pauthId,
433
0
               gemsafe_prkeys[i].obj_flags);
434
0
  }
435
436
  /* select the application DF */
437
228
  sc_log(p15card->card->ctx, "Selecting application DF");
438
228
  sc_format_path(GEMSAFE_APP_PATH, &path);
439
228
  r = sc_select_file(card, &path, &file);
440
228
  if (r != SC_SUCCESS || !file) {
441
194
    sc_pkcs15_card_clear(p15card);
442
194
    return SC_ERROR_INTERNAL;
443
194
  }
444
  /* set the application DF */
445
34
  sc_file_free(p15card->file_app);
446
34
  p15card->file_app = file;
447
448
34
  return SC_SUCCESS;
449
228
}
450
451
int sc_pkcs15emu_gemsafeV1_init_ex( sc_pkcs15_card_t *p15card,
452
      struct sc_aid *aid)
453
58.5k
{
454
58.5k
  if (gemsafe_detect_card(p15card))
455
55.1k
    return SC_ERROR_WRONG_CARD;
456
3.48k
  return sc_pkcs15emu_gemsafeV1_init(p15card);
457
58.5k
}
458
459
static sc_pkcs15_df_t *
460
sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type)
461
228
{
462
228
  sc_pkcs15_df_t  *df;
463
228
  sc_file_t *file;
464
228
  int   created = 0;
465
466
456
  while (1) {
467
456
    for (df = p15card->df_list; df; df = df->next) {
468
228
      if (df->type == type) {
469
228
        if (created)
470
228
          df->enumerated = 1;
471
228
        return df;
472
228
      }
473
228
    }
474
475
228
    if (created != 0)
476
0
      return NULL;
477
478
228
    file = sc_file_new();
479
228
    if (!file)
480
0
      return NULL;
481
228
    sc_format_path("11001101", &file->path);
482
228
    sc_pkcs15_add_df(p15card, type, &file->path);
483
228
    sc_file_free(file);
484
228
    created++;
485
228
  }
486
228
}
487
488
static int
489
sc_pkcs15emu_add_object(sc_pkcs15_card_t *p15card, int type,
490
    const char *label, void *data,
491
    const sc_pkcs15_id_t *auth_id, int obj_flags)
492
228
{
493
228
  sc_pkcs15_object_t *obj;
494
228
  int   df_type;
495
496
228
  obj = calloc(1, sizeof(*obj));
497
228
  if (!obj) {
498
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
499
0
  }
500
501
228
  obj->type  = type;
502
228
  obj->data  = data;
503
504
228
  if (label)
505
228
    strncpy(obj->label, label, sizeof(obj->label)-1);
506
507
228
  obj->flags = obj_flags;
508
228
  if (auth_id)
509
0
    obj->auth_id = *auth_id;
510
511
228
  switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
512
228
  case SC_PKCS15_TYPE_AUTH:
513
228
    df_type = SC_PKCS15_AODF;
514
228
    break;
515
0
  case SC_PKCS15_TYPE_PRKEY:
516
0
    df_type = SC_PKCS15_PRKDF;
517
0
    break;
518
0
  case SC_PKCS15_TYPE_PUBKEY:
519
0
    df_type = SC_PKCS15_PUKDF;
520
0
    break;
521
0
  case SC_PKCS15_TYPE_CERT:
522
0
    df_type = SC_PKCS15_CDF;
523
0
    break;
524
0
  default:
525
0
    sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
526
0
    free(obj);
527
0
    return SC_ERROR_INVALID_ARGUMENTS;
528
228
  }
529
530
228
  obj->df = sc_pkcs15emu_get_df(p15card, df_type);
531
228
  sc_pkcs15_add_object(p15card, obj);
532
533
228
  return 0;
534
228
}
535
536
static int
537
sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card,
538
                const sc_pkcs15_id_t *id, const char *label,
539
                const sc_path_t *path, int ref, int type,
540
                unsigned int min_length,
541
                unsigned int max_length,
542
                int flags, int tries_left, const char pad_char, int obj_flags)
543
228
{
544
228
  sc_pkcs15_auth_info_t *info;
545
546
228
  info = calloc(1, sizeof(*info));
547
228
  if (!info)
548
228
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
549
550
228
  info->auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
551
228
  info->auth_method = SC_AC_CHV;
552
228
  info->auth_id           = *id;
553
228
  info->attrs.pin.min_length        = min_length;
554
228
  info->attrs.pin.max_length        = max_length;
555
228
  info->attrs.pin.stored_length     = max_length;
556
228
  info->attrs.pin.type              = type;
557
228
  info->attrs.pin.reference         = ref;
558
228
  info->attrs.pin.flags             = flags;
559
228
  info->attrs.pin.pad_char          = pad_char;
560
228
  info->tries_left        = tries_left;
561
228
  info->logged_in = SC_PIN_STATE_UNKNOWN;
562
563
228
  if (path)
564
228
    info->path = *path;
565
566
228
  return sc_pkcs15emu_add_object(p15card, SC_PKCS15_TYPE_AUTH_PIN, label, info, NULL, obj_flags);
567
228
}
568
569
static int
570
sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card,
571
    int type, int authority,
572
    const sc_path_t *path,
573
    const sc_pkcs15_id_t *id,
574
                const char *label, int obj_flags)
575
0
{
576
0
  sc_pkcs15_cert_info_t *info;
577
0
  info = calloc(1, sizeof(*info));
578
0
  if (!info)
579
0
  {
580
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
581
0
  }
582
0
  info->id    = *id;
583
0
  info->authority   = authority;
584
0
  if (path)
585
0
    info->path = *path;
586
587
0
  return sc_pkcs15emu_add_object(p15card, type, label, info, NULL, obj_flags);
588
0
}
589
590
static int
591
sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card,
592
                const sc_pkcs15_id_t *id,
593
                const char *label,
594
                int type, unsigned int modulus_length, int usage,
595
                const sc_path_t *path, int ref,
596
                const sc_pkcs15_id_t *auth_id, int obj_flags)
597
0
{
598
0
  sc_pkcs15_prkey_info_t *info;
599
600
0
  info = calloc(1, sizeof(*info));
601
0
  if (!info)
602
0
  {
603
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
604
0
  }
605
0
  info->id                = *id;
606
0
  info->modulus_length    = modulus_length;
607
0
  info->usage             = usage;
608
0
  info->native            = 1;
609
0
  info->access_flags      = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
610
0
                                | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
611
0
                                | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
612
0
                                | SC_PKCS15_PRKEY_ACCESS_LOCAL;
613
0
  info->key_reference     = ref;
614
615
0
  if (path)
616
0
    info->path = *path;
617
618
0
  return sc_pkcs15emu_add_object(p15card, type, label,
619
0
      info, auth_id, obj_flags);
620
0
}
621
622
/* SC_IMPLEMENT_DRIVER_VERSION("0.9.4") */