Coverage Report

Created: 2025-07-18 06:10

/src/opensc/src/libopensc/pkcs15-syn.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkcs15-syn.c: PKCS #15 emulation of non-pkcs15 cards
3
 *
4
 * Copyright (C) 2003 Olaf Kirch <okir@suse.de>
5
 *     2004 Nils Larsch <nlarsch@betrusted.com>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
26
#include <stdlib.h>
27
#include <string.h>
28
#include <stdio.h>
29
#include <assert.h>
30
31
#include "common/libscdl.h"
32
#include "internal.h"
33
#include "asn1.h"
34
#include "pkcs15.h"
35
#include "pkcs15-syn.h"
36
#include "pkcs15-emulator-filter.h"
37
38
// clang-format off
39
struct sc_pkcs15_emulator_handler builtin_emulators[] = {
40
  { "openpgp",  sc_pkcs15emu_openpgp_init_ex  },
41
  { "starcert", sc_pkcs15emu_starcert_init_ex },
42
  { "tcos", sc_pkcs15emu_tcos_init_ex },
43
  { "itacns", sc_pkcs15emu_itacns_init_ex },
44
  { "PIV-II",     sc_pkcs15emu_piv_init_ex  },
45
  { "cac",        sc_pkcs15emu_cac_init_ex  },
46
  { "idprime",    sc_pkcs15emu_idprime_init_ex  },
47
  { "gemsafeV1",  sc_pkcs15emu_gemsafeV1_init_ex  },
48
  { "entersafe",  sc_pkcs15emu_entersafe_init_ex  },
49
  { "pteid",  sc_pkcs15emu_pteid_init_ex  },
50
  { "oberthur",   sc_pkcs15emu_oberthur_init_ex },
51
  { "sc-hsm", sc_pkcs15emu_sc_hsm_init_ex },
52
  { "dnie",       sc_pkcs15emu_dnie_init_ex },
53
  { "gids",       sc_pkcs15emu_gids_init_ex },
54
  { "iasecc", sc_pkcs15emu_iasecc_init_ex },
55
  { "jpki", sc_pkcs15emu_jpki_init_ex },
56
  { "coolkey",    sc_pkcs15emu_coolkey_init_ex  },
57
  { "din66291",   sc_pkcs15emu_din_66291_init_ex  },
58
  { "esteid2018", sc_pkcs15emu_esteid2018_init_ex },
59
  { "esteid2025", sc_pkcs15emu_esteid2025_init_ex },
60
  { "skeid",      sc_pkcs15emu_skeid_init_ex      },
61
  { "cardos",     sc_pkcs15emu_cardos_init_ex },
62
  { "nqapplet",   sc_pkcs15emu_nqapplet_init_ex },
63
  { "esign",      sc_pkcs15emu_starcos_esign_init_ex },
64
  { "eOI",        sc_pkcs15emu_eoi_init_ex },
65
  { "dtrust",     sc_pkcs15emu_dtrust_init_ex },
66
  { NULL, NULL }
67
};
68
69
struct sc_pkcs15_emulator_handler old_emulators[] = {
70
  { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
71
  { "actalis",  sc_pkcs15emu_actalis_init_ex  },
72
  { "tccardos", sc_pkcs15emu_tccardos_init_ex },
73
  { NULL, NULL }
74
};
75
// clang-format on
76
77
static int parse_emu_block(sc_pkcs15_card_t *, struct sc_aid *, scconf_block *);
78
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
79
  unsigned int type);
80
81
static const char *builtin_name = "builtin";
82
static const char *func_name    = "sc_pkcs15_init_func";
83
static const char *exfunc_name  = "sc_pkcs15_init_func_ex";
84
85
// FIXME: have a flag in card->flags to indicate the same
86
int sc_pkcs15_is_emulation_only(sc_card_t *card)
87
0
{
88
0
  switch (card->type) {
89
0
    case SC_CARD_TYPE_GEMSAFEV1_PTEID:
90
0
    case SC_CARD_TYPE_OPENPGP_V1:
91
0
    case SC_CARD_TYPE_OPENPGP_V2:
92
0
    case SC_CARD_TYPE_OPENPGP_GNUK:
93
0
    case SC_CARD_TYPE_OPENPGP_V3:
94
0
    case SC_CARD_TYPE_SC_HSM:
95
0
    case SC_CARD_TYPE_SC_HSM_SOC:
96
0
    case SC_CARD_TYPE_DNIE_BASE:
97
0
    case SC_CARD_TYPE_DNIE_BLANK:
98
0
    case SC_CARD_TYPE_DNIE_ADMIN:
99
0
    case SC_CARD_TYPE_DNIE_USER:
100
0
    case SC_CARD_TYPE_DNIE_TERMINATED:
101
0
    case SC_CARD_TYPE_IASECC_GEMALTO:
102
0
    case SC_CARD_TYPE_IASECC_CPX:
103
0
    case SC_CARD_TYPE_IASECC_CPXCL:
104
0
    case SC_CARD_TYPE_PIV_II_GENERIC:
105
0
    case SC_CARD_TYPE_PIV_II_HIST:
106
0
    case SC_CARD_TYPE_PIV_II_NEO:
107
0
    case SC_CARD_TYPE_PIV_II_YUBIKEY4:
108
0
    case SC_CARD_TYPE_PIV_II_SWISSBIT:
109
0
    case SC_CARD_TYPE_ESTEID_2018:
110
0
    case SC_CARD_TYPE_CARDOS_V5_0:
111
0
    case SC_CARD_TYPE_CARDOS_V5_3:
112
0
    case SC_CARD_TYPE_NQ_APPLET:
113
0
    case SC_CARD_TYPE_STARCOS_V3_4_ESIGN:
114
0
    case SC_CARD_TYPE_STARCOS_V3_5_ESIGN:
115
0
    case SC_CARD_TYPE_SKEID_V3:
116
0
    case SC_CARD_TYPE_EOI:
117
0
    case SC_CARD_TYPE_EOI_CONTACTLESS:
118
0
    case SC_CARD_TYPE_DTRUST_V4_1_STD:
119
0
    case SC_CARD_TYPE_DTRUST_V4_4_STD:
120
0
    case SC_CARD_TYPE_DTRUST_V4_1_MULTI:
121
0
    case SC_CARD_TYPE_DTRUST_V4_1_M100:
122
0
    case SC_CARD_TYPE_DTRUST_V4_4_MULTI:
123
0
      return 1;
124
0
    default:
125
0
      return 0;
126
0
  }
127
0
}
128
129
int
130
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
131
0
{
132
0
  sc_context_t    *ctx = p15card->card->ctx;
133
0
  scconf_block    *conf_block, **blocks, *blk;
134
0
  int     i, r = SC_ERROR_WRONG_CARD;
135
136
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
137
0
  conf_block = NULL;
138
139
0
  conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
140
141
0
  if (!conf_block) {
142
    /* no conf file found => try builtin drivers  */
143
0
    sc_log(ctx, "no conf file (or section), trying all builtin emulators");
144
0
    for (i = 0; builtin_emulators[i].name; i++) {
145
0
      sc_log(ctx, "trying %s", builtin_emulators[i].name);
146
0
      r = builtin_emulators[i].handler(p15card, aid);
147
0
      if (r == SC_SUCCESS)
148
        /* we got a hit */
149
0
        goto out;
150
0
    }
151
0
  } else {
152
    /* we have a conf file => let's use it */
153
0
    int builtin_enabled;
154
0
    const scconf_list *list;
155
156
0
    builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
157
0
    list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */
158
159
0
    if (builtin_enabled && list) {
160
      /* filter enabled emulation drivers from conf file */
161
0
      struct _sc_pkcs15_emulators filtered_emulators;
162
0
      struct sc_pkcs15_emulator_handler** lst;
163
0
      int ret;
164
165
0
      filtered_emulators.ccount = 0;
166
0
      ret = set_emulators(ctx, &filtered_emulators, list, builtin_emulators, old_emulators);
167
0
      if (ret == SC_SUCCESS || ret == SC_ERROR_TOO_MANY_OBJECTS) {
168
0
        lst = filtered_emulators.list_of_handlers;
169
170
0
        if (ret == SC_ERROR_TOO_MANY_OBJECTS)
171
0
          sc_log(ctx, "trying first %d emulators from conf file", SC_MAX_PKCS15_EMULATORS);
172
173
0
        for (i = 0; lst[i]; i++) {
174
0
          sc_log(ctx, "trying %s", lst[i]->name);
175
0
          r = lst[i]->handler(p15card, aid);
176
0
          if (r == SC_SUCCESS)
177
            /* we got a hit */
178
0
            goto out;
179
0
        }
180
0
      } else {
181
0
        sc_log(ctx, "failed to filter enabled card emulators: %s", sc_strerror(ret));
182
0
      }
183
0
    }
184
0
    else if (builtin_enabled) {
185
0
      sc_log(ctx, "no emulator list in config file, trying all builtin emulators");
186
0
      for (i = 0; builtin_emulators[i].name; i++) {
187
0
        sc_log(ctx, "trying %s", builtin_emulators[i].name);
188
0
        r = builtin_emulators[i].handler(p15card, aid);
189
0
        if (r == SC_SUCCESS)
190
          /* we got a hit */
191
0
          goto out;
192
0
      }
193
0
    }
194
195
    /* search for 'emulate foo { ... }' entries in the conf file */
196
0
    sc_log(ctx, "searching for 'emulate foo { ... }' blocks");
197
0
    blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
198
0
    sc_log(ctx, "Blocks: %p", blocks);
199
0
    for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
200
0
      const char *name = blk->name->data;
201
0
      sc_log(ctx, "trying %s", name);
202
0
      r = parse_emu_block(p15card, aid, blk);
203
0
      if (r == SC_SUCCESS) {
204
0
        free(blocks);
205
0
        goto out;
206
0
      }
207
0
    }
208
0
    if (blocks)
209
0
      free(blocks);
210
0
  }
211
212
0
out:
213
0
  if (r == SC_SUCCESS) {
214
0
    p15card->magic  = SC_PKCS15_CARD_MAGIC;
215
0
    p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
216
0
  } else {
217
0
    if (r != SC_ERROR_WRONG_CARD)
218
0
      sc_log(ctx, "Failed to load card emulator: %s", sc_strerror(r));
219
0
  }
220
221
0
  LOG_FUNC_RETURN(ctx, r);
222
0
}
223
224
225
static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf_block *conf)
226
0
{
227
0
  sc_card_t *card = p15card->card;
228
0
  sc_context_t  *ctx = card->ctx;
229
0
  void *handle = NULL;
230
0
  int   (*init_func)(sc_pkcs15_card_t *);
231
0
  int   (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *);
232
0
  int   r;
233
0
  const char  *driver, *module_name;
234
235
0
  driver = conf->name->data;
236
237
0
  init_func    = NULL;
238
0
  init_func_ex = NULL;
239
240
0
  module_name = scconf_get_str(conf, "module", builtin_name);
241
0
  if (!strcmp(module_name, "builtin")) {
242
0
    int i;
243
244
    /* This function is built into libopensc itself.
245
     * Look it up in the table of emulators */
246
0
    module_name = driver;
247
0
    for (i = 0; builtin_emulators[i].name; i++) {
248
0
      if (!strcmp(builtin_emulators[i].name, module_name)) {
249
0
        init_func_ex = builtin_emulators[i].handler;
250
0
        break;
251
0
      }
252
0
    }
253
0
    if (init_func_ex == NULL) {
254
0
      for (i = 0; old_emulators[i].name; i++) {
255
0
        if (!strcmp(old_emulators[i].name, module_name)) {
256
0
          init_func_ex = old_emulators[i].handler;
257
0
          break;
258
0
        }
259
0
      }
260
0
    }
261
0
  } else {
262
0
    const char *(*get_version)(void);
263
0
    const char *name = NULL;
264
0
    void  *address;
265
0
    unsigned int major = 0, minor = 0, fix = 0;
266
267
0
    sc_log(ctx, "Loading %s", module_name);
268
269
    /* try to open dynamic library */
270
0
    handle = sc_dlopen(module_name);
271
0
    if (!handle) {
272
0
      sc_log(ctx, "unable to open dynamic library '%s': %s",
273
0
          module_name, sc_dlerror());
274
0
      return SC_ERROR_INTERNAL;
275
0
    }
276
277
    /* try to get version of the driver/api */
278
0
    get_version =  (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version");
279
0
    if (get_version) {
280
0
      if (3 != sscanf(get_version(), "%u.%u.%u", &major, &minor, &fix)) {
281
0
        sc_log(ctx, "unable to get modules version number");
282
0
        sc_dlclose(handle);
283
0
        return SC_ERROR_INTERNAL;
284
0
      }
285
0
    }
286
287
0
    if (!get_version || (major == 0 && minor <= 9 && fix < 3)) {
288
      /* no sc_driver_version function => assume old style
289
       * init function (note: this should later give an error
290
       */
291
      /* get the init function name */
292
0
      name = scconf_get_str(conf, "function", func_name);
293
294
0
      address = sc_dlsym(handle, name);
295
0
      if (address)
296
0
        init_func = (int (*)(sc_pkcs15_card_t *)) address;
297
0
    } else {
298
0
      name = scconf_get_str(conf, "function", exfunc_name);
299
300
0
      address = sc_dlsym(handle, name);
301
0
      if (address)
302
0
        init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *)) address;
303
0
    }
304
0
  }
305
  /* try to initialize the pkcs15 structures */
306
0
  if (init_func_ex)
307
0
    r = init_func_ex(p15card, aid);
308
0
  else if (init_func)
309
0
    r = init_func(p15card);
310
0
  else
311
0
    r = SC_ERROR_WRONG_CARD;
312
313
0
  if (r >= 0) {
314
0
    sc_log(card->ctx, "%s succeeded, card bound", module_name);
315
0
    p15card->dll_handle = handle;
316
0
  } else {
317
0
    sc_log(card->ctx, "%s failed: %s", module_name, sc_strerror(r));
318
    /* clear pkcs15 card */
319
0
    sc_pkcs15_card_clear(p15card);
320
0
    if (handle)
321
0
      sc_dlclose(handle);
322
0
  }
323
324
0
  return r;
325
0
}
326
327
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
328
  unsigned int type)
329
0
{
330
0
  sc_pkcs15_df_t  *df;
331
0
  sc_file_t *file;
332
0
  int   created = 0;
333
334
0
  while (1) {
335
0
    for (df = p15card->df_list; df; df = df->next) {
336
0
      if (df->type == type) {
337
0
        if (created)
338
0
          df->enumerated = 1;
339
0
        return df;
340
0
      }
341
0
    }
342
343
0
    assert(created == 0);
344
345
0
    file = sc_file_new();
346
0
    if (!file)
347
0
      return NULL;
348
0
    sc_format_path("11001101", &file->path);
349
0
    sc_pkcs15_add_df(p15card, type, &file->path);
350
0
    sc_file_free(file);
351
0
    created++;
352
0
  }
353
0
}
354
355
int sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t *p15card,
356
  const sc_pkcs15_object_t *obj, const sc_pkcs15_auth_info_t *in_pin)
357
0
{
358
0
  sc_pkcs15_auth_info_t pin = *in_pin;
359
360
0
  pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
361
0
  if(!pin.auth_method) /* or SC_AC_NONE */
362
0
    pin.auth_method = SC_AC_CHV;
363
364
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_AUTH_PIN, obj, &pin);
365
0
}
366
367
int sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t *p15card,
368
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
369
0
{
370
0
  sc_pkcs15_prkey_info_t key = *in_key;
371
372
0
  if (key.access_flags == 0)
373
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
374
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
375
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
376
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
377
378
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_RSA, obj, &key);
379
0
}
380
381
int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *p15card,
382
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
383
0
{
384
0
  sc_pkcs15_pubkey_info_t key = *in_key;
385
386
0
  if (key.access_flags == 0)
387
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
388
389
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
390
0
}
391
392
int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *p15card,
393
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
394
0
{
395
0
  sc_pkcs15_prkey_info_t key = *in_key;
396
397
0
  if (key.access_flags == 0)
398
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
399
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
400
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
401
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
402
403
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EC, obj, &key);
404
0
}
405
406
int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
407
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
408
0
{
409
0
  sc_pkcs15_pubkey_info_t key = *in_key;
410
411
0
  if (key.access_flags == 0)
412
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
413
414
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
415
0
}
416
417
int sc_pkcs15emu_add_eddsa_prkey(sc_pkcs15_card_t *p15card,
418
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
419
0
{
420
0
  sc_pkcs15_prkey_info_t key = *in_key;
421
422
0
  if (key.access_flags == 0)
423
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
424
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
425
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
426
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
427
428
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EDDSA, obj, &key);
429
0
}
430
431
int sc_pkcs15emu_add_eddsa_pubkey(sc_pkcs15_card_t *p15card,
432
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
433
0
{
434
0
  sc_pkcs15_pubkey_info_t key = *in_key;
435
436
0
  if (key.access_flags == 0)
437
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
438
439
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EDDSA, obj, &key);
440
0
}
441
442
int sc_pkcs15emu_add_xeddsa_prkey(sc_pkcs15_card_t *p15card,
443
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
444
0
{
445
0
  sc_pkcs15_prkey_info_t key = *in_key;
446
447
0
  if (key.access_flags == 0)
448
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
449
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
450
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
451
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
452
453
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_XEDDSA, obj, &key);
454
0
}
455
456
int sc_pkcs15emu_add_xeddsa_pubkey(sc_pkcs15_card_t *p15card,
457
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
458
0
{
459
0
  sc_pkcs15_pubkey_info_t key = *in_key;
460
461
0
  if (key.access_flags == 0)
462
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
463
464
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_XEDDSA, obj, &key);
465
0
}
466
467
int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *p15card,
468
  const sc_pkcs15_object_t *obj, const sc_pkcs15_cert_info_t *cert)
469
0
{
470
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_CERT_X509, obj, cert);
471
0
}
472
473
int sc_pkcs15emu_add_data_object(sc_pkcs15_card_t *p15card,
474
  const sc_pkcs15_object_t *obj, const sc_pkcs15_data_info_t *data)
475
0
{
476
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, obj, data);
477
0
}
478
479
int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type,
480
  const sc_pkcs15_object_t *in_obj, const void *data)
481
0
{
482
0
  sc_pkcs15_object_t *obj;
483
0
  unsigned int  df_type;
484
0
  size_t    data_len;
485
486
0
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
487
488
0
  obj = calloc(1, sizeof(*obj));
489
0
  if (!obj) {
490
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
491
0
  }
492
493
0
  memcpy(obj, in_obj, sizeof(*obj));
494
0
  obj->type = type;
495
496
0
  switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
497
0
  case SC_PKCS15_TYPE_AUTH:
498
0
    df_type  = SC_PKCS15_AODF;
499
0
    data_len = sizeof(struct sc_pkcs15_auth_info);
500
0
    break;
501
0
  case SC_PKCS15_TYPE_PRKEY:
502
0
    df_type  = SC_PKCS15_PRKDF;
503
0
    data_len = sizeof(struct sc_pkcs15_prkey_info);
504
0
    break;
505
0
  case SC_PKCS15_TYPE_PUBKEY:
506
0
    df_type = SC_PKCS15_PUKDF;
507
0
    data_len = sizeof(struct sc_pkcs15_pubkey_info);
508
0
    break;
509
0
  case SC_PKCS15_TYPE_CERT:
510
0
    df_type = SC_PKCS15_CDF;
511
0
    data_len = sizeof(struct sc_pkcs15_cert_info);
512
0
    break;
513
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
514
0
    df_type = SC_PKCS15_DODF;
515
0
    data_len = sizeof(struct sc_pkcs15_data_info);
516
0
    break;
517
0
  default:
518
0
    sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
519
0
    free(obj);
520
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
521
0
  }
522
523
0
  obj->data = calloc(1, data_len);
524
0
  if (obj->data == NULL) {
525
0
    free(obj);
526
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
527
0
  }
528
0
  memcpy(obj->data, data, data_len);
529
530
0
  obj->df = sc_pkcs15emu_get_df(p15card, df_type);
531
0
  sc_pkcs15_add_object(p15card, obj);
532
533
0
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
534
0
}
535