Coverage Report

Created: 2025-10-10 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-syn.c
Line
Count
Source
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
14.5k
{
88
14.5k
  switch (card->type) {
89
606
    case SC_CARD_TYPE_GEMSAFEV1_PTEID:
90
613
    case SC_CARD_TYPE_OPENPGP_V1:
91
620
    case SC_CARD_TYPE_OPENPGP_V2:
92
624
    case SC_CARD_TYPE_OPENPGP_GNUK:
93
633
    case SC_CARD_TYPE_OPENPGP_V3:
94
633
    case SC_CARD_TYPE_SC_HSM:
95
636
    case SC_CARD_TYPE_SC_HSM_SOC:
96
636
    case SC_CARD_TYPE_DNIE_BASE:
97
636
    case SC_CARD_TYPE_DNIE_BLANK:
98
636
    case SC_CARD_TYPE_DNIE_ADMIN:
99
1.19k
    case SC_CARD_TYPE_DNIE_USER:
100
1.19k
    case SC_CARD_TYPE_DNIE_TERMINATED:
101
1.21k
    case SC_CARD_TYPE_IASECC_GEMALTO:
102
1.33k
    case SC_CARD_TYPE_IASECC_CPX:
103
1.35k
    case SC_CARD_TYPE_IASECC_CPXCL:
104
1.35k
    case SC_CARD_TYPE_PIV_II_GENERIC:
105
1.35k
    case SC_CARD_TYPE_PIV_II_HIST:
106
1.43k
    case SC_CARD_TYPE_PIV_II_NEO:
107
1.52k
    case SC_CARD_TYPE_PIV_II_YUBIKEY4:
108
1.52k
    case SC_CARD_TYPE_PIV_II_SWISSBIT:
109
1.52k
    case SC_CARD_TYPE_ESTEID_2018:
110
1.53k
    case SC_CARD_TYPE_CARDOS_V5_0:
111
2.32k
    case SC_CARD_TYPE_CARDOS_V5_3:
112
2.44k
    case SC_CARD_TYPE_NQ_APPLET:
113
2.44k
    case SC_CARD_TYPE_NQ_APPLET_RFID:
114
2.52k
    case SC_CARD_TYPE_STARCOS_V3_4_ESIGN:
115
2.53k
    case SC_CARD_TYPE_STARCOS_V3_5_ESIGN:
116
2.54k
    case SC_CARD_TYPE_SKEID_V3:
117
2.56k
    case SC_CARD_TYPE_EOI:
118
2.56k
    case SC_CARD_TYPE_EOI_CONTACTLESS:
119
2.56k
    case SC_CARD_TYPE_DTRUST_V4_1_STD:
120
2.56k
    case SC_CARD_TYPE_DTRUST_V4_4_STD:
121
2.56k
    case SC_CARD_TYPE_DTRUST_V4_1_MULTI:
122
2.56k
    case SC_CARD_TYPE_DTRUST_V4_1_M100:
123
2.56k
    case SC_CARD_TYPE_DTRUST_V4_4_MULTI:
124
2.56k
    case SC_CARD_TYPE_DTRUST_V5_1_STD:
125
2.56k
    case SC_CARD_TYPE_DTRUST_V5_4_STD:
126
2.56k
    case SC_CARD_TYPE_DTRUST_V5_1_MULTI:
127
2.56k
    case SC_CARD_TYPE_DTRUST_V5_1_M100:
128
2.56k
    case SC_CARD_TYPE_DTRUST_V5_4_MULTI:
129
2.56k
      return 1;
130
11.9k
    default:
131
11.9k
      return 0;
132
14.5k
  }
133
14.5k
}
134
135
int
136
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
137
14.0k
{
138
14.0k
  sc_context_t    *ctx = p15card->card->ctx;
139
14.0k
  scconf_block    *conf_block, **blocks, *blk;
140
14.0k
  int     i, r = SC_ERROR_WRONG_CARD;
141
142
14.0k
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
143
14.0k
  conf_block = NULL;
144
145
14.0k
  conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
146
147
14.0k
  if (!conf_block) {
148
    /* no conf file found => try builtin drivers  */
149
14.0k
    sc_log(ctx, "no conf file (or section), trying all builtin emulators");
150
299k
    for (i = 0; builtin_emulators[i].name; i++) {
151
290k
      sc_log(ctx, "trying %s", builtin_emulators[i].name);
152
290k
      r = builtin_emulators[i].handler(p15card, aid);
153
290k
      if (r == SC_SUCCESS)
154
        /* we got a hit */
155
4.99k
        goto out;
156
290k
    }
157
14.0k
  } else {
158
    /* we have a conf file => let's use it */
159
0
    int builtin_enabled;
160
0
    const scconf_list *list;
161
162
0
    builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
163
0
    list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */
164
165
0
    if (builtin_enabled && list) {
166
      /* filter enabled emulation drivers from conf file */
167
0
      struct _sc_pkcs15_emulators filtered_emulators;
168
0
      struct sc_pkcs15_emulator_handler** lst;
169
0
      int ret;
170
171
0
      filtered_emulators.ccount = 0;
172
0
      ret = set_emulators(ctx, &filtered_emulators, list, builtin_emulators, old_emulators);
173
0
      if (ret == SC_SUCCESS || ret == SC_ERROR_TOO_MANY_OBJECTS) {
174
0
        lst = filtered_emulators.list_of_handlers;
175
176
0
        if (ret == SC_ERROR_TOO_MANY_OBJECTS)
177
0
          sc_log(ctx, "trying first %d emulators from conf file", SC_MAX_PKCS15_EMULATORS);
178
179
0
        for (i = 0; lst[i]; i++) {
180
0
          sc_log(ctx, "trying %s", lst[i]->name);
181
0
          r = lst[i]->handler(p15card, aid);
182
0
          if (r == SC_SUCCESS)
183
            /* we got a hit */
184
0
            goto out;
185
0
        }
186
0
      } else {
187
0
        sc_log(ctx, "failed to filter enabled card emulators: %s", sc_strerror(ret));
188
0
      }
189
0
    }
190
0
    else if (builtin_enabled) {
191
0
      sc_log(ctx, "no emulator list in config file, trying all builtin emulators");
192
0
      for (i = 0; builtin_emulators[i].name; i++) {
193
0
        sc_log(ctx, "trying %s", builtin_emulators[i].name);
194
0
        r = builtin_emulators[i].handler(p15card, aid);
195
0
        if (r == SC_SUCCESS)
196
          /* we got a hit */
197
0
          goto out;
198
0
      }
199
0
    }
200
201
    /* search for 'emulate foo { ... }' entries in the conf file */
202
0
    sc_log(ctx, "searching for 'emulate foo { ... }' blocks");
203
0
    blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
204
0
    sc_log(ctx, "Blocks: %p", blocks);
205
0
    for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
206
0
      const char *name = blk->name->data;
207
0
      sc_log(ctx, "trying %s", name);
208
0
      r = parse_emu_block(p15card, aid, blk);
209
0
      if (r == SC_SUCCESS) {
210
0
        free(blocks);
211
0
        goto out;
212
0
      }
213
0
    }
214
0
    if (blocks)
215
0
      free(blocks);
216
0
  }
217
218
14.0k
out:
219
14.0k
  if (r == SC_SUCCESS) {
220
4.99k
    p15card->magic  = SC_PKCS15_CARD_MAGIC;
221
4.99k
    p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
222
9.03k
  } else {
223
9.03k
    if (r != SC_ERROR_WRONG_CARD)
224
0
      sc_log(ctx, "Failed to load card emulator: %s", sc_strerror(r));
225
9.03k
  }
226
227
14.0k
  LOG_FUNC_RETURN(ctx, r);
228
14.0k
}
229
230
231
static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf_block *conf)
232
0
{
233
0
  sc_card_t *card = p15card->card;
234
0
  sc_context_t  *ctx = card->ctx;
235
0
  void *handle = NULL;
236
0
  int   (*init_func)(sc_pkcs15_card_t *);
237
0
  int   (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *);
238
0
  int   r;
239
0
  const char  *driver, *module_name;
240
241
0
  driver = conf->name->data;
242
243
0
  init_func    = NULL;
244
0
  init_func_ex = NULL;
245
246
0
  module_name = scconf_get_str(conf, "module", builtin_name);
247
0
  if (!strcmp(module_name, "builtin")) {
248
0
    int i;
249
250
    /* This function is built into libopensc itself.
251
     * Look it up in the table of emulators */
252
0
    module_name = driver;
253
0
    for (i = 0; builtin_emulators[i].name; i++) {
254
0
      if (!strcmp(builtin_emulators[i].name, module_name)) {
255
0
        init_func_ex = builtin_emulators[i].handler;
256
0
        break;
257
0
      }
258
0
    }
259
0
    if (init_func_ex == NULL) {
260
0
      for (i = 0; old_emulators[i].name; i++) {
261
0
        if (!strcmp(old_emulators[i].name, module_name)) {
262
0
          init_func_ex = old_emulators[i].handler;
263
0
          break;
264
0
        }
265
0
      }
266
0
    }
267
0
  } else {
268
0
    const char *(*get_version)(void);
269
0
    const char *name = NULL;
270
0
    void  *address;
271
0
    unsigned int major = 0, minor = 0, fix = 0;
272
273
0
    sc_log(ctx, "Loading %s", module_name);
274
275
    /* try to open dynamic library */
276
0
    handle = sc_dlopen(module_name);
277
0
    if (!handle) {
278
0
      sc_log(ctx, "unable to open dynamic library '%s': %s",
279
0
          module_name, sc_dlerror());
280
0
      return SC_ERROR_INTERNAL;
281
0
    }
282
283
    /* try to get version of the driver/api */
284
0
    get_version =  (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version");
285
0
    if (get_version) {
286
0
      if (3 != sscanf(get_version(), "%u.%u.%u", &major, &minor, &fix)) {
287
0
        sc_log(ctx, "unable to get modules version number");
288
0
        sc_dlclose(handle);
289
0
        return SC_ERROR_INTERNAL;
290
0
      }
291
0
    }
292
293
0
    if (!get_version || (major == 0 && minor <= 9 && fix < 3)) {
294
      /* no sc_driver_version function => assume old style
295
       * init function (note: this should later give an error
296
       */
297
      /* get the init function name */
298
0
      name = scconf_get_str(conf, "function", func_name);
299
300
0
      address = sc_dlsym(handle, name);
301
0
      if (address)
302
0
        init_func = (int (*)(sc_pkcs15_card_t *)) address;
303
0
    } else {
304
0
      name = scconf_get_str(conf, "function", exfunc_name);
305
306
0
      address = sc_dlsym(handle, name);
307
0
      if (address)
308
0
        init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *)) address;
309
0
    }
310
0
  }
311
  /* try to initialize the pkcs15 structures */
312
0
  if (init_func_ex)
313
0
    r = init_func_ex(p15card, aid);
314
0
  else if (init_func)
315
0
    r = init_func(p15card);
316
0
  else
317
0
    r = SC_ERROR_WRONG_CARD;
318
319
0
  if (r >= 0) {
320
0
    sc_log(card->ctx, "%s succeeded, card bound", module_name);
321
0
    p15card->dll_handle = handle;
322
0
  } else {
323
0
    sc_log(card->ctx, "%s failed: %s", module_name, sc_strerror(r));
324
    /* clear pkcs15 card */
325
0
    sc_pkcs15_card_clear(p15card);
326
0
    if (handle)
327
0
      sc_dlclose(handle);
328
0
  }
329
330
0
  return r;
331
0
}
332
333
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
334
  unsigned int type)
335
34.6k
{
336
34.6k
  sc_pkcs15_df_t  *df;
337
34.6k
  sc_file_t *file;
338
34.6k
  int   created = 0;
339
340
43.1k
  while (1) {
341
65.5k
    for (df = p15card->df_list; df; df = df->next) {
342
57.0k
      if (df->type == type) {
343
34.6k
        if (created)
344
8.51k
          df->enumerated = 1;
345
34.6k
        return df;
346
34.6k
      }
347
57.0k
    }
348
349
43.1k
    assert(created == 0);
350
351
8.51k
    file = sc_file_new();
352
8.51k
    if (!file)
353
0
      return NULL;
354
8.51k
    sc_format_path("11001101", &file->path);
355
8.51k
    sc_pkcs15_add_df(p15card, type, &file->path);
356
8.51k
    sc_file_free(file);
357
8.51k
    created++;
358
8.51k
  }
359
34.6k
}
360
361
int sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t *p15card,
362
  const sc_pkcs15_object_t *obj, const sc_pkcs15_auth_info_t *in_pin)
363
5.94k
{
364
5.94k
  sc_pkcs15_auth_info_t pin = *in_pin;
365
366
5.94k
  pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
367
5.94k
  if(!pin.auth_method) /* or SC_AC_NONE */
368
5.46k
    pin.auth_method = SC_AC_CHV;
369
370
5.94k
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_AUTH_PIN, obj, &pin);
371
5.94k
}
372
373
int sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t *p15card,
374
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
375
1.14k
{
376
1.14k
  sc_pkcs15_prkey_info_t key = *in_key;
377
378
1.14k
  if (key.access_flags == 0)
379
1.14k
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
380
1.14k
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
381
1.14k
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
382
1.14k
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
383
384
1.14k
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_RSA, obj, &key);
385
1.14k
}
386
387
int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *p15card,
388
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
389
249
{
390
249
  sc_pkcs15_pubkey_info_t key = *in_key;
391
392
249
  if (key.access_flags == 0)
393
249
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
394
395
249
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
396
249
}
397
398
int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *p15card,
399
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
400
961
{
401
961
  sc_pkcs15_prkey_info_t key = *in_key;
402
403
961
  if (key.access_flags == 0)
404
961
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
405
961
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
406
961
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
407
961
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
408
409
961
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EC, obj, &key);
410
961
}
411
412
int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
413
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
414
973
{
415
973
  sc_pkcs15_pubkey_info_t key = *in_key;
416
417
973
  if (key.access_flags == 0)
418
973
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
419
420
973
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
421
973
}
422
423
int sc_pkcs15emu_add_eddsa_prkey(sc_pkcs15_card_t *p15card,
424
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
425
0
{
426
0
  sc_pkcs15_prkey_info_t key = *in_key;
427
428
0
  if (key.access_flags == 0)
429
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
430
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
431
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
432
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
433
434
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EDDSA, obj, &key);
435
0
}
436
437
int sc_pkcs15emu_add_eddsa_pubkey(sc_pkcs15_card_t *p15card,
438
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
439
0
{
440
0
  sc_pkcs15_pubkey_info_t key = *in_key;
441
442
0
  if (key.access_flags == 0)
443
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
444
445
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EDDSA, obj, &key);
446
0
}
447
448
int sc_pkcs15emu_add_xeddsa_prkey(sc_pkcs15_card_t *p15card,
449
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
450
0
{
451
0
  sc_pkcs15_prkey_info_t key = *in_key;
452
453
0
  if (key.access_flags == 0)
454
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
455
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
456
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
457
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
458
459
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_XEDDSA, obj, &key);
460
0
}
461
462
int sc_pkcs15emu_add_xeddsa_pubkey(sc_pkcs15_card_t *p15card,
463
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
464
0
{
465
0
  sc_pkcs15_pubkey_info_t key = *in_key;
466
467
0
  if (key.access_flags == 0)
468
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
469
470
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_XEDDSA, obj, &key);
471
0
}
472
473
int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *p15card,
474
  const sc_pkcs15_object_t *obj, const sc_pkcs15_cert_info_t *cert)
475
2.11k
{
476
2.11k
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_CERT_X509, obj, cert);
477
2.11k
}
478
479
int sc_pkcs15emu_add_data_object(sc_pkcs15_card_t *p15card,
480
  const sc_pkcs15_object_t *obj, const sc_pkcs15_data_info_t *data)
481
3.58k
{
482
3.58k
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, obj, data);
483
3.58k
}
484
485
int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type,
486
  const sc_pkcs15_object_t *in_obj, const void *data)
487
34.6k
{
488
34.6k
  sc_pkcs15_object_t *obj;
489
34.6k
  unsigned int  df_type;
490
34.6k
  size_t    data_len;
491
492
34.6k
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
493
494
34.6k
  obj = calloc(1, sizeof(*obj));
495
34.6k
  if (!obj) {
496
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
497
0
  }
498
499
34.6k
  memcpy(obj, in_obj, sizeof(*obj));
500
34.6k
  obj->type = type;
501
502
34.6k
  switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
503
5.94k
  case SC_PKCS15_TYPE_AUTH:
504
5.94k
    df_type  = SC_PKCS15_AODF;
505
5.94k
    data_len = sizeof(struct sc_pkcs15_auth_info);
506
5.94k
    break;
507
3.38k
  case SC_PKCS15_TYPE_PRKEY:
508
3.38k
    df_type  = SC_PKCS15_PRKDF;
509
3.38k
    data_len = sizeof(struct sc_pkcs15_prkey_info);
510
3.38k
    break;
511
1.22k
  case SC_PKCS15_TYPE_PUBKEY:
512
1.22k
    df_type = SC_PKCS15_PUKDF;
513
1.22k
    data_len = sizeof(struct sc_pkcs15_pubkey_info);
514
1.22k
    break;
515
2.40k
  case SC_PKCS15_TYPE_CERT:
516
2.40k
    df_type = SC_PKCS15_CDF;
517
2.40k
    data_len = sizeof(struct sc_pkcs15_cert_info);
518
2.40k
    break;
519
21.6k
  case SC_PKCS15_TYPE_DATA_OBJECT:
520
21.6k
    df_type = SC_PKCS15_DODF;
521
21.6k
    data_len = sizeof(struct sc_pkcs15_data_info);
522
21.6k
    break;
523
0
  default:
524
0
    sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
525
0
    free(obj);
526
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
527
34.6k
  }
528
529
34.6k
  obj->data = calloc(1, data_len);
530
34.6k
  if (obj->data == NULL) {
531
0
    free(obj);
532
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
533
0
  }
534
34.6k
  memcpy(obj->data, data, data_len);
535
536
34.6k
  obj->df = sc_pkcs15emu_get_df(p15card, df_type);
537
34.6k
  sc_pkcs15_add_object(p15card, obj);
538
539
34.6k
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
540
34.6k
}
541