Coverage Report

Created: 2026-08-31 06:13

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
255
#define MANU_ID     "Gemplus"
32
772
#define APPLET_NAME   "GemSAFE V1"
33
772
#define DRIVER_SERIAL_NUMBER  "v0.9"
34
58
#define GEMSAFE_APP_PATH  "3F001600"
35
255
#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
211
#define GEMSAFE_READ_QUANTUM    248
41
182
#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
255
{
164
255
  int r;
165
255
  u8  ibuf[GEMSAFE_MAX_OBJLEN];
166
255
  u8 *iptr;
167
255
  struct sc_path path;
168
255
  struct sc_file *file;
169
255
  size_t objlen;
170
255
  int certlen;
171
255
  unsigned int ind, i=0;
172
255
  int read_len;
173
174
255
  sc_format_path(GEMSAFE_PATH, &path);
175
255
  r = sc_select_file(card, &path, &file);
176
255
  if (r != SC_SUCCESS || !file)
177
44
    return SC_ERROR_INTERNAL;
178
211
  sc_file_free(file);
179
180
  /* Initial read */
181
211
  read_len = sc_read_binary(card, 0, ibuf, GEMSAFE_READ_QUANTUM, 0);
182
211
  if (read_len <= 2) {
183
25
    sc_log(card->ctx, "Invalid size of object data: %d", read_len);
184
25
    return SC_ERROR_INTERNAL;
185
25
  }
186
187
  /* Actual stored object size is encoded in first 2 bytes
188
   * (allocated EF space is much greater!)
189
   */
190
186
  objlen = (((size_t) ibuf[0]) << 8) | ibuf[1];
191
186
  sc_log(card->ctx, "Stored object is of size: %zu", objlen);
192
186
  if (objlen < 1 || objlen > GEMSAFE_MAX_OBJLEN) {
193
16
    sc_log(card->ctx, "Invalid object size: %zu", objlen);
194
16
    return SC_ERROR_INTERNAL;
195
16
  }
196
197
  /* It looks like the first thing in the block is a table of
198
   * which keys are allocated. The table is small and is in the
199
   * first 248 bytes. Example for a card with 10 key containers:
200
   * 01 f0 00 03 03 b0 00 03     <=  1st key unallocated
201
   * 01 f0 00 04 03 b0 00 04     <=  2nd key unallocated
202
   * 01 fe 14 00 05 03 b0 00 05  <=  3rd key allocated
203
   * 01 fe 14 01 06 03 b0 00 06  <=  4th key allocated
204
   * 01 f0 00 07 03 b0 00 07     <=  5th key unallocated
205
   * ...
206
   * 01 f0 00 0c 03 b0 00 0c     <= 10th key unallocated
207
   * For allocated keys, the fourth byte seems to indicate the
208
   * default key and the fifth byte indicates the key_ref of
209
   * the private key.
210
   */
211
170
  ind = 2; /* skip length */
212
261
  while (ind + 1 < (size_t)read_len && ibuf[ind] == 0x01 && i < gemsafe_cert_max) {
213
91
    if (ibuf[ind+1] == 0xFE) {
214
20
      gemsafe_prkeys[i].ref = ibuf[ind+4];
215
20
      sc_log(card->ctx, "Key container %d is allocated and uses key_ref %d",
216
20
          i+1, gemsafe_prkeys[i].ref);
217
20
      ind += 9;
218
20
    }
219
71
    else {
220
71
      gemsafe_prkeys[i].label = NULL;
221
71
      gemsafe_cert[i].label = NULL;
222
71
      sc_log(card->ctx, "Key container %d is unallocated", i+1);
223
71
      ind += 8;
224
71
    }
225
91
    i++;
226
91
  }
227
228
  /* Delete additional key containers from the data structures if
229
   * this card can't accommodate them.
230
   */
231
2.11k
  for (; i < gemsafe_cert_max; i++) {
232
1.94k
    gemsafe_prkeys[i].label = NULL;
233
1.94k
    gemsafe_cert[i].label = NULL;
234
1.94k
  }
235
236
  /* Read entire file, then dissect in memory.
237
   * Gemalto ClassicClient seems to do it the same way.
238
   */
239
170
  iptr = ibuf + read_len;
240
2.57k
  while ((size_t)(iptr - ibuf) < objlen) {
241
2.51k
    r = sc_read_binary(card, (unsigned)(iptr - ibuf), iptr,
242
2.51k
           MIN(GEMSAFE_READ_QUANTUM, objlen - (iptr - ibuf)), 0);
243
2.51k
    if (r < 0) {
244
93
      sc_log(card->ctx, "Could not read cert object");
245
93
      return SC_ERROR_INTERNAL;
246
93
    }
247
2.42k
    if (r == 0)
248
19
      break;
249
2.40k
    read_len += r;
250
2.40k
    iptr += r;
251
2.40k
  }
252
77
  if ((size_t)read_len < objlen) {
253
19
    sc_log(card->ctx, "Could not read cert object");
254
19
    return SC_ERROR_INTERNAL;
255
19
  }
256
257
  /* Search buffer for certificates, they start with 0x3082. */
258
58
  i = 0;
259
114k
  while (ind < objlen - 1) {
260
114k
    if (ibuf[ind] == 0x30 && ibuf[ind+1] == 0x82) {
261
      /* Find next allocated key container */
262
13
      while (i < gemsafe_cert_max && gemsafe_cert[i].label == NULL)
263
12
        i++;
264
1
      if (i == gemsafe_cert_max) {
265
1
        sc_log(card->ctx, "Warning: Found orphaned certificate at offset %d", ind);
266
1
        return SC_SUCCESS;
267
1
      }
268
      /* DER cert len is encoded this way */
269
0
      if (ind+3 >= sizeof ibuf)
270
0
        return SC_ERROR_INVALID_DATA;
271
0
      certlen = ((((int)ibuf[ind + 2]) << 8) | ibuf[ind + 3]) + 4;
272
0
      sc_log(card->ctx,
273
0
             "Found certificate of key container %d at offset %d, len %d",
274
0
             i+1, ind, certlen);
275
0
      gemsafe_cert[i].index = ind;
276
0
      gemsafe_cert[i].count = certlen;
277
0
      ind += certlen;
278
0
      i++;
279
0
    } else
280
114k
      ind++;
281
114k
  }
282
283
  /* Delete additional key containers from the data structures if
284
   * they're missing on the card.
285
   */
286
741
  for (; i < gemsafe_cert_max; i++) {
287
684
    if (gemsafe_cert[i].label) {
288
0
      sc_log(card->ctx, "Warning: Certificate of key container %d is missing", i+1);
289
0
      gemsafe_prkeys[i].label = NULL;
290
0
      gemsafe_cert[i].label = NULL;
291
0
    }
292
684
  }
293
294
57
  return SC_SUCCESS;
295
58
}
296
297
static int gemsafe_detect_card( sc_pkcs15_card_t *p15card)
298
12.2k
{
299
12.2k
  if (strcmp(p15card->card->name, "GemSAFE V1"))
300
11.4k
    return SC_ERROR_WRONG_CARD;
301
302
772
  return SC_SUCCESS;
303
12.2k
}
304
305
static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card)
306
772
{
307
772
  int       r;
308
772
  unsigned int    i;
309
772
  struct sc_path  path;
310
772
  struct sc_file *file = NULL;
311
772
  struct sc_card *card = p15card->card;
312
772
  struct sc_apdu  apdu;
313
772
  u8        rbuf[SC_MAX_APDU_BUFFER_SIZE];
314
315
772
  sc_log(p15card->card->ctx, "Setting pkcs15 parameters");
316
317
772
  set_string(&p15card->tokeninfo->label, APPLET_NAME);
318
772
  if (!p15card->tokeninfo->label)
319
0
    return SC_ERROR_INTERNAL;
320
321
772
  set_string(&p15card->tokeninfo->serial_number, DRIVER_SERIAL_NUMBER);
322
772
  if (!p15card->tokeninfo->serial_number) {
323
0
    free(p15card->tokeninfo->label);
324
0
    p15card->tokeninfo->label = NULL;
325
0
    return SC_ERROR_INTERNAL;
326
0
  }
327
328
  /* the GemSAFE applet version number */
329
772
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03);
330
772
  apdu.cla = 0x80;
331
772
  apdu.resp = rbuf;
332
772
  apdu.resplen = sizeof(rbuf);
333
  /* Manual says Le=0x05, but should be 0x08 to return full version number */
334
772
  apdu.le = 0x08;
335
772
  apdu.lc = 0;
336
772
  apdu.datalen = 0;
337
772
  r = sc_transmit_apdu(card, &apdu);
338
772
  if (r < 0)
339
23
    sc_pkcs15_card_clear(p15card);
340
772
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
341
342
749
  if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || r != SC_SUCCESS) {
343
494
    sc_pkcs15_card_clear(p15card);
344
494
    return SC_ERROR_INTERNAL;
345
494
  }
346
347
  /* the manufacturer ID, in this case GemPlus */
348
255
  set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
349
255
  if (!p15card->tokeninfo->manufacturer_id) {
350
0
    sc_pkcs15_card_clear(p15card);
351
0
    return SC_ERROR_INTERNAL;
352
0
  }
353
354
  /* determine allocated key containers and length of certificates */
355
255
  r = gemsafe_get_cert_len(card);
356
255
  if (r != SC_SUCCESS) {
357
197
    sc_pkcs15_card_clear(p15card);
358
197
    return SC_ERROR_INTERNAL;
359
197
  }
360
361
  /* set certs */
362
58
  sc_log(p15card->card->ctx, "Setting certificates");
363
754
  for (i = 0; i < gemsafe_cert_max; i++) {
364
696
    struct sc_pkcs15_id p15Id;
365
696
    struct sc_path path;
366
367
696
    if (gemsafe_cert[i].label == NULL)
368
696
      continue;
369
0
    sc_format_path(gemsafe_cert[i].path, &path);
370
0
    sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id);
371
0
    path.index = gemsafe_cert[i].index;
372
0
    path.count = gemsafe_cert[i].count;
373
0
    sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509,
374
0
              gemsafe_cert[i].authority, &path, &p15Id,
375
0
              gemsafe_cert[i].label, gemsafe_cert[i].obj_flags);
376
0
  }
377
378
  /* set gemsafe_pin */
379
58
  sc_log(p15card->card->ctx, "Setting PIN");
380
116
  for (i=0; i < gemsafe_pin_max; i++) {
381
116
    struct sc_pkcs15_id p15Id;
382
116
    struct sc_path path;
383
384
116
    sc_pkcs15_format_id(gemsafe_pin[i].id, &p15Id);
385
116
    sc_format_path(gemsafe_pin[i].path, &path);
386
116
    if (gemsafe_pin[i].atr_len == 0 ||
387
58
       (gemsafe_pin[i].atr_len == p15card->card->atr.len &&
388
0
        memcmp(p15card->card->atr.value, gemsafe_pin[i].atr,
389
58
         p15card->card->atr.len) == 0)) {
390
58
      sc_pkcs15emu_add_pin(p15card, &p15Id, gemsafe_pin[i].label,
391
58
               &path, gemsafe_pin[i].ref, gemsafe_pin[i].type,
392
58
               gemsafe_pin[i].minlen, gemsafe_pin[i].maxlen,
393
58
               gemsafe_pin[i].flags, gemsafe_pin[i].tries_left,
394
58
               gemsafe_pin[i].pad_char, gemsafe_pin[i].obj_flags);
395
58
      break;
396
58
    }
397
116
  };
398
399
  /* set private keys */
400
58
  sc_log(p15card->card->ctx, "Setting private keys");
401
754
  for (i = 0; i < gemsafe_cert_max; i++) {
402
696
    struct sc_pkcs15_id p15Id, authId, *pauthId;
403
696
    struct sc_path path;
404
696
    int key_ref = 0x03;
405
406
696
    if (gemsafe_prkeys[i].label == NULL)
407
696
      continue;
408
0
    sc_pkcs15_format_id(gemsafe_prkeys[i].id, &p15Id);
409
0
    if (gemsafe_prkeys[i].auth_id) {
410
0
      sc_pkcs15_format_id(gemsafe_prkeys[i].auth_id, &authId);
411
0
      pauthId = &authId;
412
0
    } else
413
0
      pauthId = NULL;
414
0
    sc_format_path(gemsafe_prkeys[i].path, &path);
415
    /*
416
     * The key ref may be different for different sites;
417
     * by adding flags=n where the low order 4 bits can be
418
     * the key ref we can force it.
419
     */
420
0
    if ( p15card->card->flags & 0x0F) {
421
0
      key_ref = p15card->card->flags & 0x0F;
422
0
      sc_log(p15card->card->ctx,
423
0
         "Overriding key_ref %d with %d\n",
424
0
         gemsafe_prkeys[i].ref, key_ref);
425
0
    } else
426
0
      key_ref = gemsafe_prkeys[i].ref;
427
0
    sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label,
428
0
               SC_PKCS15_TYPE_PRKEY_RSA,
429
0
               gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage,
430
0
               &path, key_ref, pauthId,
431
0
               gemsafe_prkeys[i].obj_flags);
432
0
  }
433
434
  /* select the application DF */
435
58
  sc_log(p15card->card->ctx, "Selecting application DF");
436
58
  sc_format_path(GEMSAFE_APP_PATH, &path);
437
58
  r = sc_select_file(card, &path, &file);
438
58
  if (r != SC_SUCCESS || !file) {
439
37
    sc_pkcs15_card_clear(p15card);
440
37
    return SC_ERROR_INTERNAL;
441
37
  }
442
  /* set the application DF */
443
21
  sc_file_free(p15card->file_app);
444
21
  p15card->file_app = file;
445
446
21
  return SC_SUCCESS;
447
58
}
448
449
int sc_pkcs15emu_gemsafeV1_init_ex( sc_pkcs15_card_t *p15card,
450
      struct sc_aid *aid)
451
12.2k
{
452
12.2k
  if (gemsafe_detect_card(p15card))
453
11.4k
    return SC_ERROR_WRONG_CARD;
454
772
  return sc_pkcs15emu_gemsafeV1_init(p15card);
455
12.2k
}
456
457
static sc_pkcs15_df_t *
458
sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card, unsigned int type)
459
58
{
460
58
  sc_pkcs15_df_t  *df;
461
58
  sc_file_t *file;
462
58
  int   created = 0;
463
464
116
  while (1) {
465
116
    for (df = p15card->df_list; df; df = df->next) {
466
58
      if (df->type == type) {
467
58
        if (created)
468
58
          df->enumerated = 1;
469
58
        return df;
470
58
      }
471
58
    }
472
473
58
    if (created != 0)
474
0
      return NULL;
475
476
58
    file = sc_file_new();
477
58
    if (!file)
478
0
      return NULL;
479
58
    sc_format_path("11001101", &file->path);
480
58
    sc_pkcs15_add_df(p15card, type, &file->path);
481
58
    sc_file_free(file);
482
58
    created++;
483
58
  }
484
58
}
485
486
static int
487
sc_pkcs15emu_add_object(sc_pkcs15_card_t *p15card, int type,
488
    const char *label, void *data,
489
    const sc_pkcs15_id_t *auth_id, int obj_flags)
490
58
{
491
58
  sc_pkcs15_object_t *obj;
492
58
  int   df_type;
493
494
58
  obj = calloc(1, sizeof(*obj));
495
58
  if (!obj) {
496
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
497
0
  }
498
499
58
  obj->type  = type;
500
58
  obj->data  = data;
501
502
58
  if (label)
503
58
    strncpy(obj->label, label, sizeof(obj->label)-1);
504
505
58
  obj->flags = obj_flags;
506
58
  if (auth_id)
507
0
    obj->auth_id = *auth_id;
508
509
58
  switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
510
58
  case SC_PKCS15_TYPE_AUTH:
511
58
    df_type = SC_PKCS15_AODF;
512
58
    break;
513
0
  case SC_PKCS15_TYPE_PRKEY:
514
0
    df_type = SC_PKCS15_PRKDF;
515
0
    break;
516
0
  case SC_PKCS15_TYPE_PUBKEY:
517
0
    df_type = SC_PKCS15_PUKDF;
518
0
    break;
519
0
  case SC_PKCS15_TYPE_CERT:
520
0
    df_type = SC_PKCS15_CDF;
521
0
    break;
522
0
  default:
523
0
    sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
524
0
    free(obj);
525
0
    return SC_ERROR_INVALID_ARGUMENTS;
526
58
  }
527
528
58
  obj->df = sc_pkcs15emu_get_df(p15card, df_type);
529
58
  sc_pkcs15_add_object(p15card, obj);
530
531
58
  return 0;
532
58
}
533
534
static int
535
sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card,
536
                const sc_pkcs15_id_t *id, const char *label,
537
                const sc_path_t *path, int ref, int type,
538
                unsigned int min_length,
539
                unsigned int max_length,
540
                int flags, int tries_left, const char pad_char, int obj_flags)
541
58
{
542
58
  sc_pkcs15_auth_info_t *info;
543
544
58
  info = calloc(1, sizeof(*info));
545
58
  if (!info)
546
58
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
547
548
58
  info->auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
549
58
  info->auth_method = SC_AC_CHV;
550
58
  info->auth_id           = *id;
551
58
  info->attrs.pin.min_length        = min_length;
552
58
  info->attrs.pin.max_length        = max_length;
553
58
  info->attrs.pin.stored_length     = max_length;
554
58
  info->attrs.pin.type              = type;
555
58
  info->attrs.pin.reference         = ref;
556
58
  info->attrs.pin.flags             = flags;
557
58
  info->attrs.pin.pad_char          = pad_char;
558
58
  info->tries_left        = tries_left;
559
58
  info->logged_in = SC_PIN_STATE_UNKNOWN;
560
561
58
  if (path)
562
58
    info->path = *path;
563
564
58
  return sc_pkcs15emu_add_object(p15card, SC_PKCS15_TYPE_AUTH_PIN, label, info, NULL, obj_flags);
565
58
}
566
567
static int
568
sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card,
569
    int type, int authority,
570
    const sc_path_t *path,
571
    const sc_pkcs15_id_t *id,
572
                const char *label, int obj_flags)
573
0
{
574
0
  sc_pkcs15_cert_info_t *info;
575
0
  info = calloc(1, sizeof(*info));
576
0
  if (!info)
577
0
  {
578
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
579
0
  }
580
0
  info->id    = *id;
581
0
  info->authority   = authority;
582
0
  if (path)
583
0
    info->path = *path;
584
585
0
  return sc_pkcs15emu_add_object(p15card, type, label, info, NULL, obj_flags);
586
0
}
587
588
static int
589
sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card,
590
                const sc_pkcs15_id_t *id,
591
                const char *label,
592
                int type, unsigned int modulus_length, int usage,
593
                const sc_path_t *path, int ref,
594
                const sc_pkcs15_id_t *auth_id, int obj_flags)
595
0
{
596
0
  sc_pkcs15_prkey_info_t *info;
597
598
0
  info = calloc(1, sizeof(*info));
599
0
  if (!info)
600
0
  {
601
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
602
0
  }
603
0
  info->id                = *id;
604
0
  info->modulus_length    = modulus_length;
605
0
  info->usage             = usage;
606
0
  info->native            = 1;
607
0
  info->access_flags      = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
608
0
                                | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
609
0
                                | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
610
0
                                | SC_PKCS15_PRKEY_ACCESS_LOCAL;
611
0
  info->key_reference     = ref;
612
613
0
  if (path)
614
0
    info->path = *path;
615
616
0
  return sc_pkcs15emu_add_object(p15card, type, label,
617
0
      info, auth_id, obj_flags);
618
0
}
619
620
/* SC_IMPLEMENT_DRIVER_VERSION("0.9.4") */