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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 
22 #if 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 
37 struct sc_pkcs15_emulator_handler builtin_emulators[] = {
38 	{ "westcos",	sc_pkcs15emu_westcos_init_ex	},
39 	{ "openpgp",	sc_pkcs15emu_openpgp_init_ex	},
40 	{ "starcert",	sc_pkcs15emu_starcert_init_ex	},
41 	{ "tcos",	sc_pkcs15emu_tcos_init_ex	},
42 	{ "esteid",	sc_pkcs15emu_esteid_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 	{ "gemsafeGPK",	sc_pkcs15emu_gemsafeGPK_init_ex	},
48 	{ "gemsafeV1",	sc_pkcs15emu_gemsafeV1_init_ex	},
49 	{ "actalis",	sc_pkcs15emu_actalis_init_ex	},
50 	{ "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
51 	{ "tccardos",	sc_pkcs15emu_tccardos_init_ex	},
52 	{ "entersafe",  sc_pkcs15emu_entersafe_init_ex	},
53 	{ "pteid",	sc_pkcs15emu_pteid_init_ex	},
54 	{ "oberthur",   sc_pkcs15emu_oberthur_init_ex	},
55 	{ "sc-hsm",	sc_pkcs15emu_sc_hsm_init_ex	},
56 	{ "dnie",       sc_pkcs15emu_dnie_init_ex	},
57 	{ "gids",       sc_pkcs15emu_gids_init_ex	},
58 	{ "iasecc",	sc_pkcs15emu_iasecc_init_ex	},
59 	{ "jpki",	sc_pkcs15emu_jpki_init_ex	},
60 	{ "coolkey",    sc_pkcs15emu_coolkey_init_ex	},
61 	{ "din66291",   sc_pkcs15emu_din_66291_init_ex	},
62 	{ "esteid2018", sc_pkcs15emu_esteid2018_init_ex	},
63 	{ "cardos",     sc_pkcs15emu_cardos_init_ex	},
64 
65 	{ NULL, NULL }
66 };
67 
68 static int parse_emu_block(sc_pkcs15_card_t *, struct sc_aid *, scconf_block *);
69 static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
70 	unsigned int type);
71 
72 static const char *builtin_name = "builtin";
73 static const char *func_name    = "sc_pkcs15_init_func";
74 static const char *exfunc_name  = "sc_pkcs15_init_func_ex";
75 
76 // FIXME: have a flag in card->flags to indicate the same
sc_pkcs15_is_emulation_only(sc_card_t * card)77 int sc_pkcs15_is_emulation_only(sc_card_t *card)
78 {
79 	switch (card->type) {
80 		case SC_CARD_TYPE_MCRD_ESTEID_V30:
81 		case SC_CARD_TYPE_GEMSAFEV1_PTEID:
82 		case SC_CARD_TYPE_OPENPGP_V1:
83 		case SC_CARD_TYPE_OPENPGP_V2:
84 		case SC_CARD_TYPE_OPENPGP_GNUK:
85 		case SC_CARD_TYPE_OPENPGP_V3:
86 		case SC_CARD_TYPE_SC_HSM:
87 		case SC_CARD_TYPE_SC_HSM_SOC:
88 		case SC_CARD_TYPE_DNIE_BASE:
89 		case SC_CARD_TYPE_DNIE_BLANK:
90 		case SC_CARD_TYPE_DNIE_ADMIN:
91 		case SC_CARD_TYPE_DNIE_USER:
92 		case SC_CARD_TYPE_DNIE_TERMINATED:
93 		case SC_CARD_TYPE_IASECC_GEMALTO:
94 		case SC_CARD_TYPE_IASECC_CPX:
95 		case SC_CARD_TYPE_IASECC_CPXCL:
96 		case SC_CARD_TYPE_PIV_II_GENERIC:
97 		case SC_CARD_TYPE_PIV_II_HIST:
98 		case SC_CARD_TYPE_PIV_II_NEO:
99 		case SC_CARD_TYPE_PIV_II_YUBIKEY4:
100 		case SC_CARD_TYPE_ESTEID_2018:
101 		case SC_CARD_TYPE_CARDOS_V5_0:
102 		case SC_CARD_TYPE_CARDOS_V5_3:
103 
104 			return 1;
105 		default:
106 			return 0;
107 	}
108 }
109 
110 int
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t * p15card,struct sc_aid * aid)111 sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
112 {
113 	sc_context_t		*ctx = p15card->card->ctx;
114 	scconf_block		*conf_block, **blocks, *blk;
115 	int			i, r = SC_ERROR_WRONG_CARD;
116 
117 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
118 	conf_block = NULL;
119 
120 	conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
121 
122 	if (!conf_block) {
123 		/* no conf file found => try builtin drivers  */
124 		sc_log(ctx, "no conf file (or section), trying all builtin emulators");
125 		for (i = 0; builtin_emulators[i].name; i++) {
126 			sc_log(ctx, "trying %s", builtin_emulators[i].name);
127 			r = builtin_emulators[i].handler(p15card, aid);
128 			if (r == SC_SUCCESS)
129 				/* we got a hit */
130 				goto out;
131 		}
132 	} else {
133 		/* we have a conf file => let's use it */
134 		int builtin_enabled;
135 		const scconf_list *list, *item;
136 
137 		builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
138 		list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */
139 
140 		if (builtin_enabled && list) {
141 			/* get the list of enabled emulation drivers */
142 			for (item = list; item; item = item->next) {
143 				/* go through the list of builtin drivers */
144 				const char *name = item->data;
145 
146 				sc_log(ctx, "trying %s", name);
147 				for (i = 0; builtin_emulators[i].name; i++)
148 					if (!strcmp(builtin_emulators[i].name, name)) {
149 						r = builtin_emulators[i].handler(p15card, aid);
150 						if (r == SC_SUCCESS)
151 							/* we got a hit */
152 							goto out;
153 					}
154 			}
155 		}
156 		else if (builtin_enabled) {
157 			sc_log(ctx, "no emulator list in config file, trying all builtin emulators");
158 			for (i = 0; builtin_emulators[i].name; i++) {
159 				sc_log(ctx, "trying %s", builtin_emulators[i].name);
160 				r = builtin_emulators[i].handler(p15card, aid);
161 				if (r == SC_SUCCESS)
162 					/* we got a hit */
163 					goto out;
164 			}
165 		}
166 
167 		/* search for 'emulate foo { ... }' entries in the conf file */
168 		sc_log(ctx, "searching for 'emulate foo { ... }' blocks");
169 		blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
170 		sc_log(ctx, "Blocks: %p", blocks);
171 		for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
172 			const char *name = blk->name->data;
173 			sc_log(ctx, "trying %s", name);
174 			r = parse_emu_block(p15card, aid, blk);
175 			if (r == SC_SUCCESS) {
176 				free(blocks);
177 				goto out;
178 			}
179 		}
180 		if (blocks)
181 			free(blocks);
182 	}
183 
184 out:
185 	if (r == SC_SUCCESS) {
186 		p15card->magic  = SC_PKCS15_CARD_MAGIC;
187 		p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
188 	} else {
189 		if (r != SC_ERROR_WRONG_CARD)
190 			sc_log(ctx, "Failed to load card emulator: %s", sc_strerror(r));
191 	}
192 
193 	LOG_FUNC_RETURN(ctx, r);
194 }
195 
196 
parse_emu_block(sc_pkcs15_card_t * p15card,struct sc_aid * aid,scconf_block * conf)197 static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf_block *conf)
198 {
199 	sc_card_t	*card = p15card->card;
200 	sc_context_t	*ctx = card->ctx;
201 	void *handle = NULL;
202 	int		(*init_func)(sc_pkcs15_card_t *);
203 	int		(*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *);
204 	int		r;
205 	const char	*driver, *module_name;
206 
207 	driver = conf->name->data;
208 
209 	init_func    = NULL;
210 	init_func_ex = NULL;
211 
212 	module_name = scconf_get_str(conf, "module", builtin_name);
213 	if (!strcmp(module_name, "builtin")) {
214 		int	i;
215 
216 		/* This function is built into libopensc itself.
217 		 * Look it up in the table of emulators */
218 		module_name = driver;
219 		for (i = 0; builtin_emulators[i].name; i++) {
220 			if (!strcmp(builtin_emulators[i].name, module_name)) {
221 				init_func_ex = builtin_emulators[i].handler;
222 				break;
223 			}
224 		}
225 	} else {
226 		const char *(*get_version)(void);
227 		const char *name = NULL;
228 		void	*address;
229 		unsigned int major = 0, minor = 0, fix = 0;
230 
231 		sc_log(ctx, "Loading %s", module_name);
232 
233 		/* try to open dynamic library */
234 		handle = sc_dlopen(module_name);
235 		if (!handle) {
236 			sc_log(ctx, "unable to open dynamic library '%s': %s",
237 					module_name, sc_dlerror());
238 			return SC_ERROR_INTERNAL;
239 		}
240 
241 		/* try to get version of the driver/api */
242 		get_version =  (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version");
243 		if (get_version) {
244 			if (3 != sscanf(get_version(), "%u.%u.%u", &major, &minor, &fix)) {
245 				sc_log(ctx, "unable to get modules version number");
246 				sc_dlclose(handle);
247 				return SC_ERROR_INTERNAL;
248 			}
249 		}
250 
251 		if (!get_version || (major == 0 && minor <= 9 && fix < 3)) {
252 			/* no sc_driver_version function => assume old style
253 			 * init function (note: this should later give an error
254 			 */
255 			/* get the init function name */
256 			name = scconf_get_str(conf, "function", func_name);
257 
258 			address = sc_dlsym(handle, name);
259 			if (address)
260 				init_func = (int (*)(sc_pkcs15_card_t *)) address;
261 		} else {
262 			name = scconf_get_str(conf, "function", exfunc_name);
263 
264 			address = sc_dlsym(handle, name);
265 			if (address)
266 				init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *)) address;
267 		}
268 	}
269 	/* try to initialize the pkcs15 structures */
270 	if (init_func_ex)
271 		r = init_func_ex(p15card, aid);
272 	else if (init_func)
273 		r = init_func(p15card);
274 	else
275 		r = SC_ERROR_WRONG_CARD;
276 
277 	if (r >= 0) {
278 		sc_log(card->ctx, "%s succeeded, card bound", module_name);
279 		p15card->dll_handle = handle;
280 	} else {
281 		sc_log(card->ctx, "%s failed: %s", module_name, sc_strerror(r));
282 		/* clear pkcs15 card */
283 		sc_pkcs15_card_clear(p15card);
284 		if (handle)
285 			sc_dlclose(handle);
286 	}
287 
288 	return r;
289 }
290 
sc_pkcs15emu_get_df(sc_pkcs15_card_t * p15card,unsigned int type)291 static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
292 	unsigned int type)
293 {
294 	sc_pkcs15_df_t	*df;
295 	sc_file_t	*file;
296 	int		created = 0;
297 
298 	while (1) {
299 		for (df = p15card->df_list; df; df = df->next) {
300 			if (df->type == type) {
301 				if (created)
302 					df->enumerated = 1;
303 				return df;
304 			}
305 		}
306 
307 		assert(created == 0);
308 
309 		file = sc_file_new();
310 		if (!file)
311 			return NULL;
312 		sc_format_path("11001101", &file->path);
313 		sc_pkcs15_add_df(p15card, type, &file->path);
314 		sc_file_free(file);
315 		created++;
316 	}
317 }
318 
sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_auth_info_t * in_pin)319 int sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t *p15card,
320 	const sc_pkcs15_object_t *obj, const sc_pkcs15_auth_info_t *in_pin)
321 {
322 	sc_pkcs15_auth_info_t pin = *in_pin;
323 
324 	pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
325 	if(!pin.auth_method) /* or SC_AC_NONE */
326 		pin.auth_method = SC_AC_CHV;
327 
328 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_AUTH_PIN, obj, &pin);
329 }
330 
sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_prkey_info_t * in_key)331 int sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t *p15card,
332 	const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
333 {
334 	sc_pkcs15_prkey_info_t key = *in_key;
335 
336 	if (key.access_flags == 0)
337 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
338 				| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
339 				| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
340 				| SC_PKCS15_PRKEY_ACCESS_LOCAL;
341 
342 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_RSA, obj, &key);
343 }
344 
sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_pubkey_info_t * in_key)345 int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *p15card,
346 	const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
347 {
348 	sc_pkcs15_pubkey_info_t key = *in_key;
349 
350 	if (key.access_flags == 0)
351 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
352 
353 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
354 }
355 
sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_prkey_info_t * in_key)356 int sc_pkcs15emu_add_ec_prkey(sc_pkcs15_card_t *p15card,
357 	const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
358 {
359 	sc_pkcs15_prkey_info_t key = *in_key;
360 
361 	if (key.access_flags == 0)
362 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
363 				| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
364 				| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
365 				| SC_PKCS15_PRKEY_ACCESS_LOCAL;
366 
367 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EC, obj, &key);
368 }
369 
sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_pubkey_info_t * in_key)370 int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
371 	const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
372 {
373 	sc_pkcs15_pubkey_info_t key = *in_key;
374 
375 	if (key.access_flags == 0)
376 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
377 
378 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
379 }
380 
sc_pkcs15emu_add_eddsa_prkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_prkey_info_t * in_key)381 int sc_pkcs15emu_add_eddsa_prkey(sc_pkcs15_card_t *p15card,
382 	const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
383 {
384 	sc_pkcs15_prkey_info_t key = *in_key;
385 
386 	if (key.access_flags == 0)
387 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
388 				| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
389 				| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
390 				| SC_PKCS15_PRKEY_ACCESS_LOCAL;
391 
392 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_EDDSA, obj, &key);
393 }
394 
sc_pkcs15emu_add_eddsa_pubkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_pubkey_info_t * in_key)395 int sc_pkcs15emu_add_eddsa_pubkey(sc_pkcs15_card_t *p15card,
396 	const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
397 {
398 	sc_pkcs15_pubkey_info_t key = *in_key;
399 
400 	if (key.access_flags == 0)
401 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
402 
403 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EDDSA, obj, &key);
404 }
405 
sc_pkcs15emu_add_xeddsa_prkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_prkey_info_t * in_key)406 int sc_pkcs15emu_add_xeddsa_prkey(sc_pkcs15_card_t *p15card,
407 	const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
408 {
409 	sc_pkcs15_prkey_info_t key = *in_key;
410 
411 	if (key.access_flags == 0)
412 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
413 				| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
414 				| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
415 				| SC_PKCS15_PRKEY_ACCESS_LOCAL;
416 
417 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_XEDDSA, obj, &key);
418 }
419 
sc_pkcs15emu_add_xeddsa_pubkey(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_pubkey_info_t * in_key)420 int sc_pkcs15emu_add_xeddsa_pubkey(sc_pkcs15_card_t *p15card,
421 	const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
422 {
423 	sc_pkcs15_pubkey_info_t key = *in_key;
424 
425 	if (key.access_flags == 0)
426 		key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
427 
428 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_XEDDSA, obj, &key);
429 }
430 
sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_cert_info_t * cert)431 int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *p15card,
432 	const sc_pkcs15_object_t *obj, const sc_pkcs15_cert_info_t *cert)
433 {
434 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_CERT_X509, obj, cert);
435 }
436 
sc_pkcs15emu_add_data_object(sc_pkcs15_card_t * p15card,const sc_pkcs15_object_t * obj,const sc_pkcs15_data_info_t * data)437 int sc_pkcs15emu_add_data_object(sc_pkcs15_card_t *p15card,
438 	const sc_pkcs15_object_t *obj, const sc_pkcs15_data_info_t *data)
439 {
440 	return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, obj, data);
441 }
442 
sc_pkcs15emu_object_add(sc_pkcs15_card_t * p15card,unsigned int type,const sc_pkcs15_object_t * in_obj,const void * data)443 int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type,
444 	const sc_pkcs15_object_t *in_obj, const void *data)
445 {
446 	sc_pkcs15_object_t *obj;
447 	unsigned int	df_type;
448 	size_t		data_len;
449 
450 	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
451 
452 	obj = calloc(1, sizeof(*obj));
453 	if (!obj) {
454 		LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
455 	}
456 
457 	memcpy(obj, in_obj, sizeof(*obj));
458 	obj->type = type;
459 
460 	switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
461 	case SC_PKCS15_TYPE_AUTH:
462 		df_type  = SC_PKCS15_AODF;
463 		data_len = sizeof(struct sc_pkcs15_auth_info);
464 		break;
465 	case SC_PKCS15_TYPE_PRKEY:
466 		df_type  = SC_PKCS15_PRKDF;
467 		data_len = sizeof(struct sc_pkcs15_prkey_info);
468 		break;
469 	case SC_PKCS15_TYPE_PUBKEY:
470 		df_type = SC_PKCS15_PUKDF;
471 		data_len = sizeof(struct sc_pkcs15_pubkey_info);
472 		break;
473 	case SC_PKCS15_TYPE_CERT:
474 		df_type = SC_PKCS15_CDF;
475 		data_len = sizeof(struct sc_pkcs15_cert_info);
476 		break;
477 	case SC_PKCS15_TYPE_DATA_OBJECT:
478 		df_type = SC_PKCS15_DODF;
479 		data_len = sizeof(struct sc_pkcs15_data_info);
480 		break;
481 	default:
482 		sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
483 		free(obj);
484 		LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
485 	}
486 
487 	obj->data = calloc(1, data_len);
488 	if (obj->data == NULL) {
489 		free(obj);
490 		LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
491 	}
492 	memcpy(obj->data, data, data_len);
493 
494 	obj->df = sc_pkcs15emu_get_df(p15card, df_type);
495 	sc_pkcs15_add_object(p15card, obj);
496 
497 	LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
498 }
499 
500