2003-10-31 12:27:14 +00:00
|
|
|
/*
|
2003-12-02 17:51:37 +00:00
|
|
|
* pkcs15-syn.c: PKCS #15 emulation of non-pkcs15 cards
|
2003-10-31 12:27:14 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 2003 Olaf Kirch <okir@suse.de>
|
2004-10-08 21:29:55 +00:00
|
|
|
* 2004 Nils Larsch <nlarsch@betrusted.com>
|
2003-10-31 12:27:14 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
#include "pkcs15.h"
|
|
|
|
#include "asn1.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <assert.h>
|
2005-09-01 14:01:58 +00:00
|
|
|
#include <ltdl.h>
|
2004-10-17 15:59:38 +00:00
|
|
|
|
2004-10-08 21:29:55 +00:00
|
|
|
extern int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *,
|
|
|
|
sc_pkcs15emu_opt_t *);
|
|
|
|
extern int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *,
|
|
|
|
sc_pkcs15emu_opt_t *);
|
|
|
|
extern int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *,
|
|
|
|
sc_pkcs15emu_opt_t *);
|
2005-09-09 19:51:38 +00:00
|
|
|
extern int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *,
|
2004-10-08 21:29:55 +00:00
|
|
|
sc_pkcs15emu_opt_t *);
|
|
|
|
extern int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *,
|
|
|
|
sc_pkcs15emu_opt_t *);
|
2004-11-24 17:00:53 +00:00
|
|
|
extern int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *,
|
|
|
|
sc_pkcs15emu_opt_t *);
|
2006-02-14 22:09:10 +00:00
|
|
|
extern int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card,
|
|
|
|
sc_pkcs15emu_opt_t *opts);
|
2007-11-12 09:59:57 +00:00
|
|
|
extern int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card,
|
2005-04-16 10:40:00 +00:00
|
|
|
sc_pkcs15emu_opt_t *opts);
|
2007-11-12 10:18:54 +00:00
|
|
|
extern int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *p15card,
|
|
|
|
sc_pkcs15emu_opt_t *opts);
|
2005-05-08 21:30:06 +00:00
|
|
|
extern int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *p15card,
|
|
|
|
sc_pkcs15emu_opt_t *opts);
|
2005-07-01 08:26:55 +00:00
|
|
|
extern int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card,
|
|
|
|
sc_pkcs15emu_opt_t *opts);
|
2005-09-16 08:55:09 +00:00
|
|
|
extern int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
2003-10-31 12:27:14 +00:00
|
|
|
|
2008-08-20 05:41:20 +00:00
|
|
|
extern int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
|
|
|
|
2003-10-31 12:27:14 +00:00
|
|
|
static struct {
|
|
|
|
const char * name;
|
2004-10-08 21:29:55 +00:00
|
|
|
int (*handler)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
2003-10-31 12:27:14 +00:00
|
|
|
} builtin_emulators[] = {
|
2004-11-24 17:00:53 +00:00
|
|
|
{ "openpgp", sc_pkcs15emu_openpgp_init_ex },
|
|
|
|
{ "infocamere", sc_pkcs15emu_infocamere_init_ex },
|
|
|
|
{ "starcert", sc_pkcs15emu_starcert_init_ex },
|
2005-09-09 19:51:38 +00:00
|
|
|
{ "tcos", sc_pkcs15emu_tcos_init_ex },
|
2004-11-24 17:00:53 +00:00
|
|
|
{ "esteid", sc_pkcs15emu_esteid_init_ex },
|
2005-04-16 10:40:00 +00:00
|
|
|
{ "postecert", sc_pkcs15emu_postecert_init_ex },
|
2006-02-14 22:09:10 +00:00
|
|
|
{ "PIV-II", sc_pkcs15emu_piv_init_ex },
|
2007-11-12 09:59:57 +00:00
|
|
|
{ "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex },
|
2007-11-12 10:18:54 +00:00
|
|
|
{ "gemsafeV1", sc_pkcs15emu_gemsafeV1_init_ex },
|
2005-05-08 21:30:06 +00:00
|
|
|
{ "actalis", sc_pkcs15emu_actalis_init_ex },
|
2005-07-01 08:26:55 +00:00
|
|
|
{ "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
|
2005-09-16 08:55:09 +00:00
|
|
|
{ "tccardos", sc_pkcs15emu_tccardos_init_ex },
|
2008-08-20 05:41:20 +00:00
|
|
|
{ "entersafe", sc_pkcs15emu_entersafe_init_ex },
|
2007-06-21 10:07:01 +00:00
|
|
|
{ NULL, NULL }
|
2003-10-31 12:27:14 +00:00
|
|
|
};
|
|
|
|
|
2004-10-08 21:29:55 +00:00
|
|
|
static int parse_emu_block(sc_pkcs15_card_t *, scconf_block *);
|
2005-08-05 16:24:35 +00:00
|
|
|
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
|
|
|
|
unsigned int type);
|
2004-10-08 21:29:55 +00:00
|
|
|
|
|
|
|
static const char *builtin_name = "builtin";
|
|
|
|
static const char *func_name = "sc_pkcs15_init_func";
|
|
|
|
static const char *exfunc_name = "sc_pkcs15_init_func_ex";
|
|
|
|
|
2003-10-31 12:27:14 +00:00
|
|
|
|
2007-01-05 16:20:50 +00:00
|
|
|
int sc_pkcs15_is_emulation_only(sc_card_t *card)
|
|
|
|
{
|
|
|
|
switch (card->type) {
|
|
|
|
case SC_CARD_TYPE_MCRD_ESTEID:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-10-31 12:27:14 +00:00
|
|
|
int
|
2004-10-08 21:29:55 +00:00
|
|
|
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
2003-10-31 12:27:14 +00:00
|
|
|
{
|
|
|
|
sc_context_t *ctx = p15card->card->ctx;
|
|
|
|
scconf_block *conf_block, **blocks, *blk;
|
2004-10-08 21:29:55 +00:00
|
|
|
sc_pkcs15emu_opt_t opts;
|
|
|
|
int i, r = SC_ERROR_WRONG_CARD;
|
2003-10-31 12:27:14 +00:00
|
|
|
|
|
|
|
SC_FUNC_CALLED(ctx, 1);
|
2004-10-08 21:29:55 +00:00
|
|
|
memset(&opts, 0, sizeof(opts));
|
2003-10-31 12:27:14 +00:00
|
|
|
conf_block = NULL;
|
2005-02-20 08:26:27 +00:00
|
|
|
|
2009-01-15 21:08:30 +00:00
|
|
|
conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
|
2003-10-31 12:27:14 +00:00
|
|
|
|
2004-10-08 21:29:55 +00:00
|
|
|
if (!conf_block) {
|
2009-01-15 21:08:30 +00:00
|
|
|
/* no conf file found => try bultin drivers */
|
|
|
|
sc_debug(ctx, "no conf file (or section), trying all builtin emulators\n");
|
2004-10-08 21:29:55 +00:00
|
|
|
for (i = 0; builtin_emulators[i].name; i++) {
|
|
|
|
sc_debug(ctx, "trying %s\n", builtin_emulators[i].name);
|
|
|
|
r = builtin_emulators[i].handler(p15card, &opts);
|
|
|
|
if (r == SC_SUCCESS)
|
|
|
|
/* we got a hit */
|
|
|
|
goto out;
|
2003-10-31 12:27:14 +00:00
|
|
|
}
|
2004-10-08 21:29:55 +00:00
|
|
|
} else {
|
|
|
|
/* we have a conf file => let's use it */
|
2009-01-15 21:08:30 +00:00
|
|
|
int builtin_enabled;
|
2004-10-08 21:29:55 +00:00
|
|
|
const scconf_list *list, *item;
|
2005-02-20 08:26:27 +00:00
|
|
|
|
2009-01-15 21:08:30 +00:00
|
|
|
builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
|
|
|
|
list = scconf_find_list(conf_block, "builtin_emulators"); /* FIXME: rename to enabled_emulators */
|
|
|
|
|
|
|
|
if (builtin_enabled && list) {
|
|
|
|
/* get the list of enabled emulation drivers */
|
2004-10-08 21:29:55 +00:00
|
|
|
for (item = list; item; item = item->next) {
|
2009-01-15 21:08:30 +00:00
|
|
|
/* go through the list of builtin drivers */
|
2004-10-08 21:29:55 +00:00
|
|
|
const char *name = item->data;
|
|
|
|
|
|
|
|
sc_debug(ctx, "trying %s\n", name);
|
|
|
|
for (i = 0; builtin_emulators[i].name; i++)
|
|
|
|
if (!strcmp(builtin_emulators[i].name, name)) {
|
|
|
|
r = builtin_emulators[i].handler(p15card, &opts);
|
|
|
|
if (r == SC_SUCCESS)
|
2009-01-15 21:08:30 +00:00
|
|
|
/* we got a hit */
|
2004-10-08 21:29:55 +00:00
|
|
|
goto out;
|
|
|
|
}
|
2009-01-15 21:08:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (builtin_enabled) {
|
|
|
|
sc_debug(ctx, "no emulator list in config file, trying all builtin emulators\n");
|
|
|
|
for (i = 0; builtin_emulators[i].name; i++) {
|
|
|
|
sc_debug(ctx, "trying %s\n", builtin_emulators[i].name);
|
|
|
|
r = builtin_emulators[i].handler(p15card, &opts);
|
|
|
|
if (r == SC_SUCCESS)
|
|
|
|
/* we got a hit */
|
|
|
|
goto out;
|
2004-10-08 21:29:55 +00:00
|
|
|
}
|
|
|
|
}
|
2005-02-20 08:26:27 +00:00
|
|
|
|
2004-10-08 21:29:55 +00:00
|
|
|
/* search for 'emulate foo { ... }' entries in the conf file */
|
|
|
|
sc_debug(ctx, "searching for 'emulate foo { ... }' blocks\n");
|
|
|
|
blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
|
2005-12-05 21:48:43 +00:00
|
|
|
for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
|
2004-10-08 21:29:55 +00:00
|
|
|
const char *name = blk->name->data;
|
|
|
|
sc_debug(ctx, "trying %s\n", name);
|
|
|
|
r = parse_emu_block(p15card, blk);
|
|
|
|
if (r == SC_SUCCESS) {
|
|
|
|
free(blocks);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (blocks)
|
|
|
|
free(blocks);
|
2003-10-31 12:27:14 +00:00
|
|
|
}
|
2004-10-08 21:29:55 +00:00
|
|
|
|
2003-10-31 12:27:14 +00:00
|
|
|
/* Total failure */
|
|
|
|
return SC_ERROR_WRONG_CARD;
|
|
|
|
|
|
|
|
out: if (r == SC_SUCCESS) {
|
2005-02-07 17:03:47 +00:00
|
|
|
p15card->magic = SC_PKCS15_CARD_MAGIC;
|
2009-01-15 21:08:30 +00:00
|
|
|
p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
|
2003-10-31 12:27:14 +00:00
|
|
|
} else if (r != SC_ERROR_WRONG_CARD) {
|
|
|
|
sc_error(ctx, "Failed to load card emulator: %s\n",
|
|
|
|
sc_strerror(r));
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2005-04-10 21:58:31 +00:00
|
|
|
static int emu_detect_card(sc_card_t *card, const scconf_block *blk, int *force)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
/* TBD */
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2004-10-08 21:29:55 +00:00
|
|
|
static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
|
|
|
|
{
|
|
|
|
sc_card_t *card = p15card->card;
|
|
|
|
sc_context_t *ctx = card->ctx;
|
|
|
|
sc_pkcs15emu_opt_t opts;
|
2005-09-01 14:01:58 +00:00
|
|
|
lt_dlhandle handle = NULL;
|
2004-10-08 21:29:55 +00:00
|
|
|
int (*init_func)(sc_pkcs15_card_t *);
|
|
|
|
int (*init_func_ex)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
2005-04-10 21:58:31 +00:00
|
|
|
int r, force = 0;
|
|
|
|
const char *driver, *module_name;
|
2004-10-08 21:29:55 +00:00
|
|
|
|
2005-02-20 08:26:27 +00:00
|
|
|
driver = conf->name->data;
|
2005-04-10 21:58:31 +00:00
|
|
|
|
|
|
|
r = emu_detect_card(card, conf, &force);
|
|
|
|
if (r < 0)
|
|
|
|
return SC_ERROR_INTERNAL;
|
2004-10-08 21:29:55 +00:00
|
|
|
|
|
|
|
init_func = NULL;
|
|
|
|
init_func_ex = NULL;
|
2005-02-20 08:26:27 +00:00
|
|
|
|
|
|
|
memset(&opts, 0, sizeof(opts));
|
2004-10-08 21:29:55 +00:00
|
|
|
opts.blk = conf;
|
2005-04-10 21:58:31 +00:00
|
|
|
if (force != 0)
|
|
|
|
opts.flags = SC_PKCS15EMU_FLAGS_NO_CHECK;
|
2004-10-08 21:29:55 +00:00
|
|
|
|
|
|
|
module_name = scconf_get_str(conf, "module", builtin_name);
|
2003-10-31 12:27:14 +00:00
|
|
|
if (!strcmp(module_name, "builtin")) {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* This function is built into libopensc itself.
|
|
|
|
* Look it up in the table of emulators */
|
2005-02-20 08:26:27 +00:00
|
|
|
module_name = driver;
|
2003-10-31 12:27:14 +00:00
|
|
|
for (i = 0; builtin_emulators[i].name; i++) {
|
|
|
|
if (!strcmp(builtin_emulators[i].name, module_name)) {
|
2004-10-08 21:29:55 +00:00
|
|
|
init_func_ex = builtin_emulators[i].handler;
|
2003-10-31 12:27:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2004-10-08 21:29:55 +00:00
|
|
|
const char *(*get_version)(void);
|
|
|
|
const char *name = NULL;
|
2003-10-31 12:27:14 +00:00
|
|
|
void *address;
|
|
|
|
|
2004-10-08 21:29:55 +00:00
|
|
|
sc_debug(ctx, "Loading %s\n", module_name);
|
|
|
|
|
2003-10-31 12:27:14 +00:00
|
|
|
/* try to open dynamic library */
|
2005-09-01 14:01:58 +00:00
|
|
|
handle = lt_dlopen(module_name);
|
|
|
|
if (!handle) {
|
2005-09-16 20:31:06 +00:00
|
|
|
sc_debug(ctx, "unable to open dynamic library '%s': %s\n",
|
|
|
|
module_name, lt_dlerror());
|
2004-10-17 15:59:38 +00:00
|
|
|
return SC_ERROR_INTERNAL;
|
|
|
|
}
|
2004-10-08 21:29:55 +00:00
|
|
|
/* try to get version of the driver/api */
|
2005-09-01 14:01:58 +00:00
|
|
|
get_version = (const char *(*)(void)) lt_dlsym(handle, "sc_driver_version");
|
2004-10-08 21:29:55 +00:00
|
|
|
if (!get_version || strcmp(get_version(), "0.9.3") < 0) {
|
|
|
|
/* no sc_driver_version function => assume old style
|
|
|
|
* init function (note: this should later give an error
|
|
|
|
*/
|
|
|
|
/* get the init function name */
|
|
|
|
name = scconf_get_str(conf, "function", func_name);
|
|
|
|
|
2005-09-01 14:01:58 +00:00
|
|
|
address = lt_dlsym(handle, name);
|
2004-10-17 15:59:38 +00:00
|
|
|
if (address)
|
2004-10-08 21:29:55 +00:00
|
|
|
init_func = (int (*)(sc_pkcs15_card_t *)) address;
|
|
|
|
} else {
|
|
|
|
name = scconf_get_str(conf, "function", exfunc_name);
|
|
|
|
|
2005-09-01 14:01:58 +00:00
|
|
|
address = lt_dlsym(handle, name);
|
2004-11-26 08:43:44 +00:00
|
|
|
if (address)
|
2004-10-08 21:29:55 +00:00
|
|
|
init_func_ex = (int (*)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *)) address;
|
|
|
|
}
|
2003-10-31 12:27:14 +00:00
|
|
|
}
|
2004-10-08 21:29:55 +00:00
|
|
|
/* try to initialize the pkcs15 structures */
|
|
|
|
if (init_func_ex)
|
|
|
|
r = init_func_ex(p15card, &opts);
|
|
|
|
else if (init_func)
|
|
|
|
r = init_func(p15card);
|
|
|
|
else
|
|
|
|
r = SC_ERROR_WRONG_CARD;
|
2003-10-31 12:27:14 +00:00
|
|
|
|
|
|
|
if (r >= 0) {
|
|
|
|
sc_debug(card->ctx, "%s succeeded, card bound\n",
|
|
|
|
module_name);
|
2005-09-01 14:01:58 +00:00
|
|
|
p15card->dll_handle = handle;
|
2003-10-31 12:27:14 +00:00
|
|
|
} else if (ctx->debug >= 4) {
|
|
|
|
sc_debug(card->ctx, "%s failed: %s\n",
|
|
|
|
module_name, sc_strerror(r));
|
2004-10-08 21:29:55 +00:00
|
|
|
/* clear pkcs15 card */
|
|
|
|
sc_pkcs15_card_clear(p15card);
|
2005-09-01 14:01:58 +00:00
|
|
|
if (handle)
|
|
|
|
lt_dlclose(handle);
|
2003-10-31 12:27:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2005-08-05 16:24:35 +00:00
|
|
|
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
|
|
|
|
unsigned int type)
|
2004-03-08 13:59:27 +00:00
|
|
|
{
|
|
|
|
sc_pkcs15_df_t *df;
|
|
|
|
sc_file_t *file;
|
|
|
|
int created = 0;
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
for (df = p15card->df_list; df; df = df->next) {
|
|
|
|
if (df->type == type) {
|
|
|
|
if (created)
|
|
|
|
df->enumerated = 1;
|
|
|
|
return df;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(created == 0);
|
|
|
|
|
|
|
|
file = sc_file_new();
|
2004-12-08 20:57:37 +00:00
|
|
|
if (!file)
|
|
|
|
return NULL;
|
2004-03-08 13:59:27 +00:00
|
|
|
sc_format_path("11001101", &file->path);
|
|
|
|
sc_pkcs15_add_df(p15card, type, &file->path, file);
|
2004-12-08 20:57:37 +00:00
|
|
|
sc_file_free(file);
|
2004-03-08 13:59:27 +00:00
|
|
|
created++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-02 21:18:54 +00:00
|
|
|
int sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t *p15card,
|
|
|
|
const sc_pkcs15_object_t *obj, const sc_pkcs15_pin_info_t *in_pin)
|
|
|
|
{
|
|
|
|
sc_pkcs15_pin_info_t pin = *in_pin;
|
|
|
|
|
|
|
|
pin.magic = SC_PKCS15_PIN_MAGIC;
|
|
|
|
|
|
|
|
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_AUTH_PIN, obj, &pin);
|
|
|
|
}
|
|
|
|
|
|
|
|
int sc_pkcs15emu_add_rsa_prkey(sc_pkcs15_card_t *p15card,
|
|
|
|
const sc_pkcs15_object_t *obj, const sc_pkcs15_prkey_info_t *in_key)
|
|
|
|
{
|
|
|
|
sc_pkcs15_prkey_info_t key = *in_key;
|
|
|
|
|
|
|
|
if (key.access_flags == 0)
|
|
|
|
key.access_flags = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
|
|
|
|
| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
|
|
|
|
| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
|
|
|
|
| SC_PKCS15_PRKEY_ACCESS_LOCAL;
|
|
|
|
|
|
|
|
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PRKEY_RSA, obj, &key);
|
|
|
|
}
|
|
|
|
|
|
|
|
int sc_pkcs15emu_add_rsa_pubkey(sc_pkcs15_card_t *p15card,
|
|
|
|
const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
|
|
|
|
{
|
|
|
|
sc_pkcs15_pubkey_info_t key = *in_key;
|
|
|
|
|
|
|
|
if (key.access_flags == 0)
|
|
|
|
key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
|
|
|
|
|
2005-02-06 21:32:54 +00:00
|
|
|
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
|
2005-02-02 21:18:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int sc_pkcs15emu_add_x509_cert(sc_pkcs15_card_t *p15card,
|
|
|
|
const sc_pkcs15_object_t *obj, const sc_pkcs15_cert_info_t *cert)
|
|
|
|
{
|
|
|
|
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_CERT_X509, obj, cert);
|
|
|
|
}
|
|
|
|
|
2005-10-30 19:55:21 +00:00
|
|
|
int sc_pkcs15emu_add_data_object(sc_pkcs15_card_t *p15card,
|
|
|
|
const sc_pkcs15_object_t *obj, const sc_pkcs15_data_info_t *data)
|
|
|
|
{
|
|
|
|
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, obj, data);
|
|
|
|
}
|
|
|
|
|
2005-02-02 21:18:54 +00:00
|
|
|
int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type,
|
|
|
|
const sc_pkcs15_object_t *in_obj, const void *data)
|
|
|
|
{
|
|
|
|
sc_pkcs15_object_t *obj;
|
|
|
|
unsigned int df_type;
|
|
|
|
size_t data_len;
|
|
|
|
|
|
|
|
obj = (sc_pkcs15_object_t *) calloc(1, sizeof(*obj));
|
|
|
|
if (!obj)
|
|
|
|
return SC_ERROR_OUT_OF_MEMORY;
|
|
|
|
memcpy(obj, in_obj, sizeof(*obj));
|
|
|
|
obj->type = type;
|
|
|
|
|
|
|
|
switch (type & SC_PKCS15_TYPE_CLASS_MASK) {
|
|
|
|
case SC_PKCS15_TYPE_AUTH:
|
|
|
|
df_type = SC_PKCS15_AODF;
|
|
|
|
data_len = sizeof(struct sc_pkcs15_pin_info);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY:
|
|
|
|
df_type = SC_PKCS15_PRKDF;
|
|
|
|
data_len = sizeof(struct sc_pkcs15_prkey_info);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PUBKEY:
|
|
|
|
df_type = SC_PKCS15_PUKDF;
|
|
|
|
data_len = sizeof(struct sc_pkcs15_pubkey_info);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_CERT:
|
|
|
|
df_type = SC_PKCS15_CDF;
|
|
|
|
data_len = sizeof(struct sc_pkcs15_cert_info);
|
|
|
|
break;
|
2005-10-30 19:55:21 +00:00
|
|
|
case SC_PKCS15_TYPE_DATA_OBJECT:
|
|
|
|
df_type = SC_PKCS15_DODF;
|
|
|
|
data_len = sizeof(struct sc_pkcs15_data_info);
|
|
|
|
break;
|
2005-02-02 21:18:54 +00:00
|
|
|
default:
|
|
|
|
sc_error(p15card->card->ctx,
|
|
|
|
"Unknown PKCS15 object type %d\n", type);
|
2005-12-05 21:48:43 +00:00
|
|
|
free(obj);
|
2005-02-02 21:18:54 +00:00
|
|
|
return SC_ERROR_INVALID_ARGUMENTS;
|
|
|
|
}
|
|
|
|
|
|
|
|
obj->data = calloc(1, data_len);
|
|
|
|
if (obj->data == NULL) {
|
|
|
|
free(obj);
|
|
|
|
return SC_ERROR_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
memcpy(obj->data, data, data_len);
|
|
|
|
|
|
|
|
obj->df = sc_pkcs15emu_get_df(p15card, df_type);
|
|
|
|
sc_pkcs15_add_object(p15card, obj);
|
|
|
|
|
|
|
|
return SC_SUCCESS;
|
|
|
|
}
|
|
|
|
|