Coverage Report

Created: 2026-09-14 06:06

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
  { "cedulauy", sc_pkcs15emu_cedulauy_init_ex },
55
  { "iasecc", sc_pkcs15emu_iasecc_init_ex },
56
  { "jpki", sc_pkcs15emu_jpki_init_ex },
57
  { "coolkey",    sc_pkcs15emu_coolkey_init_ex  },
58
  { "din66291",   sc_pkcs15emu_din_66291_init_ex  },
59
  { "esteid2018", sc_pkcs15emu_esteid2018_init_ex },
60
  { "esteid2025", sc_pkcs15emu_esteid2025_init_ex },
61
  { "skeid",      sc_pkcs15emu_skeid_init_ex      },
62
  { "cardos",     sc_pkcs15emu_cardos_init_ex },
63
  { "nqapplet",   sc_pkcs15emu_nqapplet_init_ex },
64
  { "esign",      sc_pkcs15emu_starcos_esign_init_ex },
65
  { "eOI",        sc_pkcs15emu_eoi_init_ex },
66
  { "dtrust",     sc_pkcs15emu_dtrust_init_ex },
67
  { "lteid",      sc_pkcs15emu_lteid_init_ex },
68
  { "srbeid",     sc_pkcs15emu_srbeid_init_ex },
69
  { NULL, NULL }
70
};
71
72
struct sc_pkcs15_emulator_handler old_emulators[] = {
73
  { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
74
  { "actalis",  sc_pkcs15emu_actalis_init_ex  },
75
  { "tccardos", sc_pkcs15emu_tccardos_init_ex },
76
  { NULL, NULL }
77
};
78
// clang-format on
79
80
static int parse_emu_block(sc_pkcs15_card_t *, struct sc_aid *, scconf_block *);
81
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
82
  unsigned int type);
83
84
static const char *builtin_name = "builtin";
85
static const char *func_name    = "sc_pkcs15_init_func";
86
static const char *exfunc_name  = "sc_pkcs15_init_func_ex";
87
88
// FIXME: have a flag in card->flags to indicate the same
89
int sc_pkcs15_is_emulation_only(sc_card_t *card)
90
12.0k
{
91
12.0k
  switch (card->type) {
92
965
    case SC_CARD_TYPE_GEMSAFEV1_PTEID:
93
968
    case SC_CARD_TYPE_OPENPGP_V1:
94
971
    case SC_CARD_TYPE_OPENPGP_V2:
95
988
    case SC_CARD_TYPE_OPENPGP_GNUK:
96
990
    case SC_CARD_TYPE_OPENPGP_V3:
97
990
    case SC_CARD_TYPE_SC_HSM:
98
990
    case SC_CARD_TYPE_SC_HSM_SOC:
99
990
    case SC_CARD_TYPE_DNIE_BASE:
100
990
    case SC_CARD_TYPE_DNIE_BLANK:
101
990
    case SC_CARD_TYPE_DNIE_ADMIN:
102
1.49k
    case SC_CARD_TYPE_DNIE_USER:
103
1.49k
    case SC_CARD_TYPE_DNIE_TERMINATED:
104
1.51k
    case SC_CARD_TYPE_IASECC_GEMALTO:
105
1.52k
    case SC_CARD_TYPE_IASECC_CPX:
106
1.71k
    case SC_CARD_TYPE_IASECC_CPXCL:
107
1.71k
    case SC_CARD_TYPE_PIV_II_GENERIC:
108
1.71k
    case SC_CARD_TYPE_PIV_II_HIST:
109
1.80k
    case SC_CARD_TYPE_PIV_II_NEO:
110
1.84k
    case SC_CARD_TYPE_PIV_II_YUBIKEY4:
111
1.84k
    case SC_CARD_TYPE_PIV_II_SWISSBIT:
112
1.86k
    case SC_CARD_TYPE_ESTEID_2018:
113
1.87k
    case SC_CARD_TYPE_CARDOS_V5_0:
114
2.22k
    case SC_CARD_TYPE_CARDOS_V5_3:
115
2.28k
    case SC_CARD_TYPE_NQ_APPLET:
116
2.28k
    case SC_CARD_TYPE_NQ_APPLET_RFID:
117
2.34k
    case SC_CARD_TYPE_STARCOS_V3_4_ESIGN:
118
2.34k
    case SC_CARD_TYPE_STARCOS_V3_5_ESIGN:
119
2.34k
    case SC_CARD_TYPE_SKEID_V3:
120
2.35k
    case SC_CARD_TYPE_EOI:
121
2.35k
    case SC_CARD_TYPE_EOI_CONTACTLESS:
122
2.35k
    case SC_CARD_TYPE_DTRUST_V4_1_STD:
123
2.35k
    case SC_CARD_TYPE_DTRUST_V4_4_STD:
124
2.35k
    case SC_CARD_TYPE_DTRUST_V4_1_MULTI:
125
2.35k
    case SC_CARD_TYPE_DTRUST_V4_1_M100:
126
2.35k
    case SC_CARD_TYPE_DTRUST_V4_4_MULTI:
127
2.35k
    case SC_CARD_TYPE_DTRUST_V5_1_STD:
128
2.35k
    case SC_CARD_TYPE_DTRUST_V5_4_STD:
129
2.35k
    case SC_CARD_TYPE_DTRUST_V5_1_MULTI:
130
2.35k
    case SC_CARD_TYPE_DTRUST_V5_1_M100:
131
2.35k
    case SC_CARD_TYPE_DTRUST_V5_4_MULTI:
132
2.35k
    case SC_CARD_TYPE_LTEID:
133
2.37k
    case SC_CARD_TYPE_CEDULAUY:
134
2.37k
      return 1;
135
9.68k
    default:
136
9.68k
      return 0;
137
12.0k
  }
138
12.0k
}
139
140
int
141
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
142
11.9k
{
143
11.9k
  sc_context_t    *ctx = p15card->card->ctx;
144
11.9k
  scconf_block    *conf_block, **blocks, *blk;
145
11.9k
  int     i, r = SC_ERROR_WRONG_CARD;
146
147
11.9k
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
148
11.9k
  conf_block = NULL;
149
150
11.9k
  conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
151
152
11.9k
  if (!conf_block) {
153
    /* no conf file found => try builtin drivers  */
154
11.9k
    sc_log(ctx, "no conf file (or section), trying all builtin emulators");
155
277k
    for (i = 0; builtin_emulators[i].name; i++) {
156
269k
      sc_log(ctx, "trying %s", builtin_emulators[i].name);
157
269k
      r = builtin_emulators[i].handler(p15card, aid);
158
269k
      if (r == SC_SUCCESS)
159
        /* we got a hit */
160
4.32k
        goto out;
161
269k
    }
162
11.9k
  } else {
163
    /* we have a conf file => let's use it */
164
0
    int builtin_enabled;
165
0
    const scconf_list *list;
166
167
0
    builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
168
0
    list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */
169
170
0
    if (builtin_enabled && list) {
171
      /* filter enabled emulation drivers from conf file */
172
0
      struct _sc_pkcs15_emulators filtered_emulators;
173
0
      struct sc_pkcs15_emulator_handler** lst;
174
0
      int ret;
175
176
0
      filtered_emulators.ccount = 0;
177
0
      ret = set_emulators(ctx, &filtered_emulators, list, builtin_emulators, old_emulators);
178
0
      if (ret == SC_SUCCESS || ret == SC_ERROR_TOO_MANY_OBJECTS) {
179
0
        lst = filtered_emulators.list_of_handlers;
180
181
0
        if (ret == SC_ERROR_TOO_MANY_OBJECTS)
182
0
          sc_log(ctx, "trying first %d emulators from conf file", SC_MAX_PKCS15_EMULATORS);
183
184
0
        for (i = 0; lst[i]; i++) {
185
0
          sc_log(ctx, "trying %s", lst[i]->name);
186
0
          r = lst[i]->handler(p15card, aid);
187
0
          if (r == SC_SUCCESS)
188
            /* we got a hit */
189
0
            goto out;
190
0
        }
191
0
      } else {
192
0
        sc_log(ctx, "failed to filter enabled card emulators: %s", sc_strerror(ret));
193
0
      }
194
0
    }
195
0
    else if (builtin_enabled) {
196
0
      sc_log(ctx, "no emulator list in config file, trying all builtin emulators");
197
0
      for (i = 0; builtin_emulators[i].name; i++) {
198
0
        sc_log(ctx, "trying %s", builtin_emulators[i].name);
199
0
        r = builtin_emulators[i].handler(p15card, aid);
200
0
        if (r == SC_SUCCESS)
201
          /* we got a hit */
202
0
          goto out;
203
0
      }
204
0
    }
205
206
    /* search for 'emulate foo { ... }' entries in the conf file */
207
0
    sc_log(ctx, "searching for 'emulate foo { ... }' blocks");
208
0
    blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
209
0
    sc_log(ctx, "Blocks: %p", blocks);
210
0
    for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
211
0
      const char *name = blk->name->data;
212
0
      sc_log(ctx, "trying %s", name);
213
0
      r = parse_emu_block(p15card, aid, blk);
214
0
      if (r == SC_SUCCESS) {
215
0
        free(blocks);
216
0
        goto out;
217
0
      }
218
0
    }
219
0
    if (blocks)
220
0
      free(blocks);
221
0
  }
222
223
11.9k
out:
224
11.9k
  if (r == SC_SUCCESS) {
225
4.32k
    p15card->magic  = SC_PKCS15_CARD_MAGIC;
226
4.32k
    p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
227
7.61k
  } else {
228
7.61k
    if (r != SC_ERROR_WRONG_CARD)
229
128
      sc_log(ctx, "Failed to load card emulator: %s", sc_strerror(r));
230
7.61k
  }
231
232
11.9k
  LOG_FUNC_RETURN(ctx, r);
233
11.9k
}
234
235
236
static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf_block *conf)
237
0
{
238
0
  sc_card_t *card = p15card->card;
239
0
  sc_context_t  *ctx = card->ctx;
240
0
  void *handle = NULL;
241
0
  int   (*init_func)(sc_pkcs15_card_t *);
242
0
  int   (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *);
243
0
  int   r;
244
0
  const char  *driver, *module_name;
245
246
0
  driver = conf->name->data;
247
248
0
  init_func    = NULL;
249
0
  init_func_ex = NULL;
250
251
0
  module_name = scconf_get_str(conf, "module", builtin_name);
252
0
  if (!strcmp(module_name, "builtin")) {
253
0
    int i;
254
255
    /* This function is built into libopensc itself.
256
     * Look it up in the table of emulators */
257
0
    module_name = driver;
258
0
    for (i = 0; builtin_emulators[i].name; i++) {
259
0
      if (!strcmp(builtin_emulators[i].name, module_name)) {
260
0
        init_func_ex = builtin_emulators[i].handler;
261
0
        break;
262
0
      }
263
0
    }
264
0
    if (init_func_ex == NULL) {
265
0
      for (i = 0; old_emulators[i].name; i++) {
266
0
        if (!strcmp(old_emulators[i].name, module_name)) {
267
0
          init_func_ex = old_emulators[i].handler;
268
0
          break;
269
0
        }
270
0
      }
271
0
    }
272
0
  } else {
273
0
    const char *(*get_version)(void);
274
0
    const char *name = NULL;
275
0
    void  *address;
276
0
    unsigned int major = 0, minor = 0, fix = 0;
277
278
0
    sc_log(ctx, "Loading %s", module_name);
279
280
    /* try to open dynamic library */
281
0
    handle = sc_dlopen(module_name);
282
0
    if (!handle) {
283
0
      sc_log(ctx, "unable to open dynamic library '%s': %s",
284
0
          module_name, sc_dlerror());
285
0
      return SC_ERROR_INTERNAL;
286
0
    }
287
288
    /* try to get version of the driver/api */
289
0
    get_version =  (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version");
290
0
    if (get_version) {
291
0
      if (3 != sscanf(get_version(), "%u.%u.%u", &major, &minor, &fix)) {
292
0
        sc_log(ctx, "unable to get modules version number");
293
0
        sc_dlclose(handle);
294
0
        return SC_ERROR_INTERNAL;
295
0
      }
296
0
    }
297
298
0
    if (!get_version || (major == 0 && minor <= 9 && fix < 3)) {
299
      /* no sc_driver_version function => assume old style
300
       * init function (note: this should later give an error
301
       */
302
      /* get the init function name */
303
0
      name = scconf_get_str(conf, "function", func_name);
304
305
0
      address = sc_dlsym(handle, name);
306
0
      if (address)
307
0
        init_func = (int (*)(sc_pkcs15_card_t *)) address;
308
0
    } else {
309
0
      name = scconf_get_str(conf, "function", exfunc_name);
310
311
0
      address = sc_dlsym(handle, name);
312
0
      if (address)
313
0
        init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *)) address;
314
0
    }
315
0
  }
316
  /* try to initialize the pkcs15 structures */
317
0
  if (init_func_ex)
318
0
    r = init_func_ex(p15card, aid);
319
0
  else if (init_func)
320
0
    r = init_func(p15card);
321
0
  else
322
0
    r = SC_ERROR_WRONG_CARD;
323
324
0
  if (r >= 0) {
325
0
    sc_log(card->ctx, "%s succeeded, card bound", module_name);
326
0
    p15card->dll_handle = handle;
327
0
  } else {
328
0
    sc_log(card->ctx, "%s failed: %s", module_name, sc_strerror(r));
329
    /* clear pkcs15 card */
330
0
    sc_pkcs15_card_clear(p15card);
331
0
    if (handle)
332
0
      sc_dlclose(handle);
333
0
  }
334
335
0
  return r;
336
0
}
337
338
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
339
  unsigned int type)
340
29.4k
{
341
29.4k
  sc_pkcs15_df_t  *df;
342
29.4k
  sc_file_t *file;
343
29.4k
  int   created = 0;
344
345
35.4k
  while (1) {
346
64.6k
    for (df = p15card->df_list; df; df = df->next) {
347
58.7k
      if (df->type == type) {
348
29.4k
        if (created)
349
5.94k
          df->enumerated = 1;
350
29.4k
        return df;
351
29.4k
      }
352
58.7k
    }
353
354
5.94k
    if (created != 0)
355
0
      return NULL;
356
357
5.94k
    file = sc_file_new();
358
5.94k
    if (!file)
359
0
      return NULL;
360
5.94k
    sc_format_path("11001101", &file->path);
361
5.94k
    sc_pkcs15_add_df(p15card, type, &file->path);
362
5.94k
    sc_file_free(file);
363
5.94k
    created++;
364
5.94k
  }
365
29.4k
}
366
367
int sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t *p15card,
368
  const sc_pkcs15_object_t *obj, const sc_pkcs15_auth_info_t *in_pin)
369
4.08k
{
370
4.08k
  sc_pkcs15_auth_info_t pin = *in_pin;
371
372
4.08k
  pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
373
4.08k
  if(!pin.auth_method) /* or SC_AC_NONE */
374
3.59k
    pin.auth_method = SC_AC_CHV;
375
376
4.08k
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_AUTH_PIN, obj, &pin);
377
4.08k
}
378
379
int sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t *p15card,
380
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
381
587
{
382
587
  sc_pkcs15_prkey_info_t key = *in_key;
383
384
587
  if (key.access_flags == 0)
385
587
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
386
587
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
387
587
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
388
587
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
389
390
587
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_RSA, obj, &key);
391
587
}
392
393
int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *p15card,
394
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
395
183
{
396
183
  sc_pkcs15_pubkey_info_t key = *in_key;
397
398
183
  if (key.access_flags == 0)
399
183
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
400
401
183
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
402
183
}
403
404
int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *p15card,
405
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
406
82
{
407
82
  sc_pkcs15_prkey_info_t key = *in_key;
408
409
82
  if (key.access_flags == 0)
410
82
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
411
82
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
412
82
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
413
82
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
414
415
82
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EC, obj, &key);
416
82
}
417
418
int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
419
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
420
83
{
421
83
  sc_pkcs15_pubkey_info_t key = *in_key;
422
423
83
  if (key.access_flags == 0)
424
83
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
425
426
83
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
427
83
}
428
429
int sc_pkcs15emu_add_eddsa_prkey(sc_pkcs15_card_t *p15card,
430
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
431
0
{
432
0
  sc_pkcs15_prkey_info_t key = *in_key;
433
434
0
  if (key.access_flags == 0)
435
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
436
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
437
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
438
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
439
440
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EDDSA, obj, &key);
441
0
}
442
443
int sc_pkcs15emu_add_eddsa_pubkey(sc_pkcs15_card_t *p15card,
444
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
445
0
{
446
0
  sc_pkcs15_pubkey_info_t key = *in_key;
447
448
0
  if (key.access_flags == 0)
449
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
450
451
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EDDSA, obj, &key);
452
0
}
453
454
int sc_pkcs15emu_add_xeddsa_prkey(sc_pkcs15_card_t *p15card,
455
  const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
456
0
{
457
0
  sc_pkcs15_prkey_info_t key = *in_key;
458
459
0
  if (key.access_flags == 0)
460
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
461
0
        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
462
0
        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
463
0
        | SC_PKCS15_PRKEY_ACCESS_LOCAL;
464
465
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_XEDDSA, obj, &key);
466
0
}
467
468
int sc_pkcs15emu_add_xeddsa_pubkey(sc_pkcs15_card_t *p15card,
469
  const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
470
0
{
471
0
  sc_pkcs15_pubkey_info_t key = *in_key;
472
473
0
  if (key.access_flags == 0)
474
0
    key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
475
476
0
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_XEDDSA, obj, &key);
477
0
}
478
479
int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *p15card,
480
  const sc_pkcs15_object_t *obj, const sc_pkcs15_cert_info_t *cert)
481
595
{
482
595
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_CERT_X509, obj, cert);
483
595
}
484
485
int sc_pkcs15emu_add_data_object(sc_pkcs15_card_t *p15card,
486
  const sc_pkcs15_object_t *obj, const sc_pkcs15_data_info_t *data)
487
1.87k
{
488
1.87k
  return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, obj, data);
489
1.87k
}
490
491
int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type,
492
  const sc_pkcs15_object_t *in_obj, const void *data)
493
29.4k
{
494
29.4k
  sc_pkcs15_object_t *obj;
495
29.4k
  unsigned int  df_type;
496
29.4k
  size_t    data_len;
497
498
29.4k
  SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
499
500
29.4k
  obj = calloc(1, sizeof(*obj));
501
29.4k
  if (!obj) {
502
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
503
0
  }
504
505
29.4k
  memcpy(obj, in_obj, sizeof(*obj));
506
29.4k
  obj->type = type;
507
508
29.4k
  switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
509
4.08k
  case SC_PKCS15_TYPE_AUTH:
510
4.08k
    df_type  = SC_PKCS15_AODF;
511
4.08k
    data_len = sizeof(struct sc_pkcs15_auth_info);
512
4.08k
    break;
513
1.79k
  case SC_PKCS15_TYPE_PRKEY:
514
1.79k
    df_type  = SC_PKCS15_PRKDF;
515
1.79k
    data_len = sizeof(struct sc_pkcs15_prkey_info);
516
1.79k
    break;
517
302
  case SC_PKCS15_TYPE_PUBKEY:
518
302
    df_type = SC_PKCS15_PUKDF;
519
302
    data_len = sizeof(struct sc_pkcs15_pubkey_info);
520
302
    break;
521
703
  case SC_PKCS15_TYPE_CERT:
522
703
    df_type = SC_PKCS15_CDF;
523
703
    data_len = sizeof(struct sc_pkcs15_cert_info);
524
703
    break;
525
22.5k
  case SC_PKCS15_TYPE_DATA_OBJECT:
526
22.5k
    df_type = SC_PKCS15_DODF;
527
22.5k
    data_len = sizeof(struct sc_pkcs15_data_info);
528
22.5k
    break;
529
0
  default:
530
0
    sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
531
0
    free(obj);
532
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
533
29.4k
  }
534
535
29.4k
  obj->data = calloc(1, data_len);
536
29.4k
  if (obj->data == NULL) {
537
0
    free(obj);
538
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
539
0
  }
540
29.4k
  memcpy(obj->data, data, data_len);
541
542
29.4k
  obj->df = sc_pkcs15emu_get_df(p15card, df_type);
543
29.4k
  sc_pkcs15_add_object(p15card, obj);
544
545
  /* release memory ownership of buffers that are now contained in `p15card` */
546
29.4k
  switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
547
4.08k
  default:
548
    /* `data`'s members copied by value, no buffer to release */
549
4.08k
    break;
550
4.08k
  case SC_PKCS15_TYPE_PRKEY:
551
1.79k
    ((struct sc_pkcs15_prkey_info *)data)->subject.value = NULL;
552
1.79k
    break;
553
302
  case SC_PKCS15_TYPE_PUBKEY:
554
302
    ((struct sc_pkcs15_pubkey_info *)data)->subject.value = NULL;
555
302
    ((struct sc_pkcs15_pubkey_info *)data)->direct.raw.value = NULL;
556
302
    ((struct sc_pkcs15_pubkey_info *)data)->direct.spki.value = NULL;
557
302
    break;
558
703
  case SC_PKCS15_TYPE_CERT:
559
703
    ((struct sc_pkcs15_cert_info *)data)->value.value = NULL;
560
703
    break;
561
22.5k
  case SC_PKCS15_TYPE_DATA_OBJECT:
562
22.5k
    ((struct sc_pkcs15_data_info *)data)->data.value = NULL;
563
22.5k
    break;
564
29.4k
  }
565
566
29.4k
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
567
29.4k
}