opensc/src/libopensc/pkcs15-syn.c

500 lines
15 KiB
C
Raw Normal View History

/*
* pkcs15-syn.c: PKCS #15 emulation of non-pkcs15 cards
*
* Copyright (C) 2003 Olaf Kirch <okir@suse.de>
* 2004 Nils Larsch <nlarsch@betrusted.com>
*
* 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
*/
2015-04-22 21:55:33 +00:00
#if HAVE_CONFIG_H
#include "config.h"
2015-04-22 21:55:33 +00:00
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "common/libscdl.h"
#include "internal.h"
#include "asn1.h"
#include "pkcs15.h"
#include "pkcs15-syn.h"
struct sc_pkcs15_emulator_handler builtin_emulators[] = {
{ "westcos", sc_pkcs15emu_westcos_init_ex },
{ "openpgp", sc_pkcs15emu_openpgp_init_ex },
{ "starcert", sc_pkcs15emu_starcert_init_ex },
{ "tcos", sc_pkcs15emu_tcos_init_ex },
{ "esteid", sc_pkcs15emu_esteid_init_ex },
{ "itacns", sc_pkcs15emu_itacns_init_ex },
{ "PIV-II", sc_pkcs15emu_piv_init_ex },
{ "cac", sc_pkcs15emu_cac_init_ex },
{ "idprime", sc_pkcs15emu_idprime_init_ex },
{ "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex },
{ "gemsafeV1", sc_pkcs15emu_gemsafeV1_init_ex },
{ "actalis", sc_pkcs15emu_actalis_init_ex },
{ "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
{ "tccardos", sc_pkcs15emu_tccardos_init_ex },
{ "entersafe", sc_pkcs15emu_entersafe_init_ex },
{ "pteid", sc_pkcs15emu_pteid_init_ex },
{ "oberthur", sc_pkcs15emu_oberthur_init_ex },
{ "sc-hsm", sc_pkcs15emu_sc_hsm_init_ex },
{ "dnie", sc_pkcs15emu_dnie_init_ex },
{ "gids", sc_pkcs15emu_gids_init_ex },
{ "iasecc", sc_pkcs15emu_iasecc_init_ex },
{ "jpki", sc_pkcs15emu_jpki_init_ex },
{ "coolkey", sc_pkcs15emu_coolkey_init_ex },
{ "din66291", sc_pkcs15emu_din_66291_init_ex },
{ "esteid2018", sc_pkcs15emu_esteid2018_init_ex },
Various CardOS V5_* improvements Treat CardOS V5_0 and V5_3 cards differently then older versions: Use card->dvr_data as a pointer to cardos_data_t to store private driver data to pass internally, especially between set security environment and the crypto operations. Sc_get_encoding_flags sets sec_flags from algo_info->flags in pkcs15-sec.c and it passed to decipher. Some cards when doing a decipher may drop leading 00 byte when returning data from RSA_RAW decipher. Add leading byte(s) as needed. Get Cryptographic Mechanism Reference from Key Reference: Key reference byte appears to be a 4 bit Cryptographic Mechanism Reference and a 4 bit key reference. This is only done if key reference & 0xF0 != 0 i.e. default Cryptographic mechanism reference is 0. which appears to be the case for RSA RAW. PKCS1 appears to be 0x10 and ECDSA 0x30 See iso 7816-4 table 55 for DST: 84 Reference of a private key 95 Usage qualifier byte - Table 57 - 40 looks OK 80 Cryptographic mechanism reference and referes to section 9.2 The 4 bit key reference limits card to 16 keys. In future this may not work, but we can derive a Cryptographic Mechanism Reference from what OpenSC thinks the card needs to do. Only know RSA RAW, PKCS1 and ECDSA. ECDSA code has not been tested, but expected to work. Allow setting CardOS type and flags from opensc.conf using card_atr stanza This is a fallback if newer cards are added or older cards have problems giving us time to make need changes in next release. It will help in identifying what flags are needed for each card. As user can report what combination of flags work for them. They do this by adding to opensc.conf with something like this. (Change the ATR to your card's ATR): card_atr 3b:d2:18:00:81:31:fe:58:c9:03:16 { driver = "cardos"; # type is decimal from cards.h: # SC_CARD_TYPE_CARDOS_V5_0 is 1009 # SC_CARD_TYPE_CARDOS_V5_3 is 1010 type = 1010; # flags is hex from opensc.h: #define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000 #define SC_ALGORITHM_NEED_USAGE 0x40000000 #define SC_ALGORITHM_RSA_RAW 0x00000001 /* RSA_RAW is PAD_NONE */ #define SC_ALGORITHM_RSA_PAD_NONE 0x00000001 #define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */ #define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004 #define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008 #define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */ #define SC_ALGORITHM_RSA_PAD_OAEP 0x00000020 /* PKCS#1 v2.0 OAEP */ #define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 /* only applies to PKCS1 padding */ # example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_RAW flags = 80000101; #example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_PAD_PKCS1 flags = 80000002; } For V5_0 and v5_3 cards, use sc_get_max_send_size and sc_get_max_recv_size which takes care or reader sizes even on Windows where SCardControl can not get PART_10 sizes. (commit eddea6f3c2d3dafc2c09eba6695c745a61b5186f on Windows forces reader sizes to 255, 256 in reader-pcsc.c if not already set. It should not do this, but leave that up to card drivers.) pkcs15-cardos.c added: New file, pkcs15-cardos.c, added as emulation only for CardOS V5_0 and V5_3 cards. sc_pkcs15_bind_internal is called to get tokenInfo as CardOS cards are substantially PKCS15 cards. But some V5_* cards have errors in the tokenInfo, Which are corrected. For older CardOS cards, card-cardos.c will create all the card->algorithms. Pkcs15-cardos.c will check for card->algorithms and if there are none, it will do the following: SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS is called twice. First to get the flags as set by user via opensc.conf card_atr or default flags set by the card driver. Then after determining from the tokenInfo what algorithms the card can support, the new flags are passed to card_cardos.c to create card->algorithms. https://atos.net/wp-content/uploads/2018/11/CT_181026_LPM_CardOS_V5-3_Multifunctionality_FS_en3_web.pdf says card supports: "“Command chaining” in accordance with ISO/IEC 7816-4" To take advantage of this with older readers, max_send_size and max_recv_size is now based on minimum of reader limits and "data_field_length" from card. This should allow card to work in older readers not capable of extended APDU. So far current cards we have seen do no appear to support “Command chaining”. Changes to be committed: modified: src/libopensc/Makefile.am modified: src/libopensc/Makefile.mak modified: src/libopensc/card-cardos.c modified: src/libopensc/cardctl.h modified: src/libopensc/cards.h new file: src/libopensc/pkcs15-cardos.c modified: src/libopensc/pkcs15-syn.c modified: src/libopensc/pkcs15-syn.h
2020-04-17 16:36:48 +00:00
{ "cardos", sc_pkcs15emu_cardos_init_ex },
{ NULL, NULL }
};
static int parse_emu_block(sc_pkcs15_card_t *, struct sc_aid *, scconf_block *);
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
unsigned int type);
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";
// FIXME: have a flag in card->flags to indicate the same
int sc_pkcs15_is_emulation_only(sc_card_t *card)
{
switch (card->type) {
case SC_CARD_TYPE_MCRD_ESTEID_V30:
case SC_CARD_TYPE_GEMSAFEV1_PTEID:
case SC_CARD_TYPE_OPENPGP_V1:
case SC_CARD_TYPE_OPENPGP_V2:
case SC_CARD_TYPE_OPENPGP_GNUK:
case SC_CARD_TYPE_OPENPGP_V3:
case SC_CARD_TYPE_SC_HSM:
case SC_CARD_TYPE_SC_HSM_SOC:
2013-06-13 15:12:07 +00:00
case SC_CARD_TYPE_DNIE_BASE:
case SC_CARD_TYPE_DNIE_BLANK:
case SC_CARD_TYPE_DNIE_ADMIN:
case SC_CARD_TYPE_DNIE_USER:
case SC_CARD_TYPE_DNIE_TERMINATED:
case SC_CARD_TYPE_IASECC_GEMALTO:
case SC_CARD_TYPE_IASECC_CPX:
case SC_CARD_TYPE_IASECC_CPXCL:
case SC_CARD_TYPE_PIV_II_GENERIC:
case SC_CARD_TYPE_PIV_II_HIST:
case SC_CARD_TYPE_PIV_II_NEO:
case SC_CARD_TYPE_PIV_II_YUBIKEY4:
case SC_CARD_TYPE_ESTEID_2018:
Various CardOS V5_* improvements Treat CardOS V5_0 and V5_3 cards differently then older versions: Use card->dvr_data as a pointer to cardos_data_t to store private driver data to pass internally, especially between set security environment and the crypto operations. Sc_get_encoding_flags sets sec_flags from algo_info->flags in pkcs15-sec.c and it passed to decipher. Some cards when doing a decipher may drop leading 00 byte when returning data from RSA_RAW decipher. Add leading byte(s) as needed. Get Cryptographic Mechanism Reference from Key Reference: Key reference byte appears to be a 4 bit Cryptographic Mechanism Reference and a 4 bit key reference. This is only done if key reference & 0xF0 != 0 i.e. default Cryptographic mechanism reference is 0. which appears to be the case for RSA RAW. PKCS1 appears to be 0x10 and ECDSA 0x30 See iso 7816-4 table 55 for DST: 84 Reference of a private key 95 Usage qualifier byte - Table 57 - 40 looks OK 80 Cryptographic mechanism reference and referes to section 9.2 The 4 bit key reference limits card to 16 keys. In future this may not work, but we can derive a Cryptographic Mechanism Reference from what OpenSC thinks the card needs to do. Only know RSA RAW, PKCS1 and ECDSA. ECDSA code has not been tested, but expected to work. Allow setting CardOS type and flags from opensc.conf using card_atr stanza This is a fallback if newer cards are added or older cards have problems giving us time to make need changes in next release. It will help in identifying what flags are needed for each card. As user can report what combination of flags work for them. They do this by adding to opensc.conf with something like this. (Change the ATR to your card's ATR): card_atr 3b:d2:18:00:81:31:fe:58:c9:03:16 { driver = "cardos"; # type is decimal from cards.h: # SC_CARD_TYPE_CARDOS_V5_0 is 1009 # SC_CARD_TYPE_CARDOS_V5_3 is 1010 type = 1010; # flags is hex from opensc.h: #define SC_ALGORITHM_ONBOARD_KEY_GEN 0x80000000 #define SC_ALGORITHM_NEED_USAGE 0x40000000 #define SC_ALGORITHM_RSA_RAW 0x00000001 /* RSA_RAW is PAD_NONE */ #define SC_ALGORITHM_RSA_PAD_NONE 0x00000001 #define SC_ALGORITHM_RSA_PAD_PKCS1 0x00000002 /* PKCS#1 v1.5 padding */ #define SC_ALGORITHM_RSA_PAD_ANSI 0x00000004 #define SC_ALGORITHM_RSA_PAD_ISO9796 0x00000008 #define SC_ALGORITHM_RSA_PAD_PSS 0x00000010 /* PKCS#1 v2.0 PSS */ #define SC_ALGORITHM_RSA_PAD_OAEP 0x00000020 /* PKCS#1 v2.0 OAEP */ #define SC_ALGORITHM_RSA_HASH_NONE 0x00000100 /* only applies to PKCS1 padding */ # example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_RAW flags = 80000101; #example: SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_PAD_PKCS1 flags = 80000002; } For V5_0 and v5_3 cards, use sc_get_max_send_size and sc_get_max_recv_size which takes care or reader sizes even on Windows where SCardControl can not get PART_10 sizes. (commit eddea6f3c2d3dafc2c09eba6695c745a61b5186f on Windows forces reader sizes to 255, 256 in reader-pcsc.c if not already set. It should not do this, but leave that up to card drivers.) pkcs15-cardos.c added: New file, pkcs15-cardos.c, added as emulation only for CardOS V5_0 and V5_3 cards. sc_pkcs15_bind_internal is called to get tokenInfo as CardOS cards are substantially PKCS15 cards. But some V5_* cards have errors in the tokenInfo, Which are corrected. For older CardOS cards, card-cardos.c will create all the card->algorithms. Pkcs15-cardos.c will check for card->algorithms and if there are none, it will do the following: SC_CARDCTL_CARDOS_PASS_ALGO_FLAGS is called twice. First to get the flags as set by user via opensc.conf card_atr or default flags set by the card driver. Then after determining from the tokenInfo what algorithms the card can support, the new flags are passed to card_cardos.c to create card->algorithms. https://atos.net/wp-content/uploads/2018/11/CT_181026_LPM_CardOS_V5-3_Multifunctionality_FS_en3_web.pdf says card supports: "“Command chaining” in accordance with ISO/IEC 7816-4" To take advantage of this with older readers, max_send_size and max_recv_size is now based on minimum of reader limits and "data_field_length" from card. This should allow card to work in older readers not capable of extended APDU. So far current cards we have seen do no appear to support “Command chaining”. Changes to be committed: modified: src/libopensc/Makefile.am modified: src/libopensc/Makefile.mak modified: src/libopensc/card-cardos.c modified: src/libopensc/cardctl.h modified: src/libopensc/cards.h new file: src/libopensc/pkcs15-cardos.c modified: src/libopensc/pkcs15-syn.c modified: src/libopensc/pkcs15-syn.h
2020-04-17 16:36:48 +00:00
case SC_CARD_TYPE_CARDOS_V5_0:
case SC_CARD_TYPE_CARDOS_V5_3:
return 1;
default:
return 0;
}
}
int
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
{
sc_context_t *ctx = p15card->card->ctx;
scconf_block *conf_block, **blocks, *blk;
int i, r = SC_ERROR_WRONG_CARD;
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
conf_block = NULL;
conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
if (!conf_block) {
/* no conf file found => try builtin drivers */
sc_log(ctx, "no conf file (or section), trying all builtin emulators");
for (i = 0; builtin_emulators[i].name; i++) {
sc_log(ctx, "trying %s", builtin_emulators[i].name);
r = builtin_emulators[i].handler(p15card, aid);
if (r == SC_SUCCESS)
/* we got a hit */
goto out;
}
} else {
/* we have a conf file => let's use it */
int builtin_enabled;
const scconf_list *list, *item;
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 */
for (item = list; item; item = item->next) {
/* go through the list of builtin drivers */
const char *name = item->data;
sc_log(ctx, "trying %s", name);
for (i = 0; builtin_emulators[i].name; i++)
if (!strcmp(builtin_emulators[i].name, name)) {
r = builtin_emulators[i].handler(p15card, aid);
if (r == SC_SUCCESS)
/* we got a hit */
goto out;
}
}
}
else if (builtin_enabled) {
sc_log(ctx, "no emulator list in config file, trying all builtin emulators");
for (i = 0; builtin_emulators[i].name; i++) {
sc_log(ctx, "trying %s", builtin_emulators[i].name);
r = builtin_emulators[i].handler(p15card, aid);
if (r == SC_SUCCESS)
/* we got a hit */
goto out;
}
}
/* search for 'emulate foo { ... }' entries in the conf file */
sc_log(ctx, "searching for 'emulate foo { ... }' blocks");
blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
sc_log(ctx, "Blocks: %p", blocks);
for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
const char *name = blk->name->data;
sc_log(ctx, "trying %s", name);
r = parse_emu_block(p15card, aid, blk);
if (r == SC_SUCCESS) {
free(blocks);
goto out;
}
}
if (blocks)
free(blocks);
}
2015-02-04 23:43:05 +00:00
out:
if (r == SC_SUCCESS) {
p15card->magic = SC_PKCS15_CARD_MAGIC;
p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
2015-02-04 23:43:05 +00:00
} else {
if (r != SC_ERROR_WRONG_CARD)
sc_log(ctx, "Failed to load card emulator: %s", sc_strerror(r));
}
LOG_FUNC_RETURN(ctx, r);
}
static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf_block *conf)
{
sc_card_t *card = p15card->card;
sc_context_t *ctx = card->ctx;
void *handle = NULL;
int (*init_func)(sc_pkcs15_card_t *);
int (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *);
2015-02-02 23:51:04 +00:00
int r;
const char *driver, *module_name;
driver = conf->name->data;
init_func = NULL;
init_func_ex = NULL;
module_name = scconf_get_str(conf, "module", builtin_name);
if (!strcmp(module_name, "builtin")) {
int i;
/* This function is built into libopensc itself.
* Look it up in the table of emulators */
module_name = driver;
for (i = 0; builtin_emulators[i].name; i++) {
if (!strcmp(builtin_emulators[i].name, module_name)) {
init_func_ex = builtin_emulators[i].handler;
break;
}
}
} else {
const char *(*get_version)(void);
const char *name = NULL;
void *address;
2014-06-26 19:09:16 +00:00
unsigned int major = 0, minor = 0, fix = 0;
sc_log(ctx, "Loading %s", module_name);
/* try to open dynamic library */
handle = sc_dlopen(module_name);
if (!handle) {
sc_log(ctx, "unable to open dynamic library '%s': %s",
module_name, sc_dlerror());
return SC_ERROR_INTERNAL;
}
2014-06-26 19:09:16 +00:00
/* try to get version of the driver/api */
get_version = (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version");
2014-06-26 19:09:16 +00:00
if (get_version) {
2015-01-28 03:45:08 +00:00
if (3 != sscanf(get_version(), "%u.%u.%u", &major, &minor, &fix)) {
sc_log(ctx, "unable to get modules version number");
2015-04-29 21:22:28 +00:00
sc_dlclose(handle);
2015-01-28 03:45:08 +00:00
return SC_ERROR_INTERNAL;
}
2014-06-26 19:09:16 +00:00
}
2015-02-04 07:52:30 +00:00
if (!get_version || (major == 0 && minor <= 9 && fix < 3)) {
/* 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);
address = sc_dlsym(handle, name);
if (address)
init_func = (int (*)(sc_pkcs15_card_t *)) address;
} else {
name = scconf_get_str(conf, "function", exfunc_name);
address = sc_dlsym(handle, name);
if (address)
init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *)) address;
}
}
/* try to initialize the pkcs15 structures */
if (init_func_ex)
r = init_func_ex(p15card, aid);
else if (init_func)
r = init_func(p15card);
else
r = SC_ERROR_WRONG_CARD;
if (r >= 0) {
sc_log(card->ctx, "%s succeeded, card bound", module_name);
p15card->dll_handle = handle;
} else {
sc_log(card->ctx, "%s failed: %s", module_name, sc_strerror(r));
/* clear pkcs15 card */
sc_pkcs15_card_clear(p15card);
if (handle)
sc_dlclose(handle);
}
return r;
}
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
unsigned int type)
{
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();
if (!file)
return NULL;
sc_format_path("11001101", &file->path);
sc_pkcs15_add_df(p15card, type, &file->path);
sc_file_free(file);
created++;
}
}
int sc_pkcs15emu_add_pin_obj(sc_pkcs15_card_t *p15card,
const sc_pkcs15_object_t *obj, const sc_pkcs15_auth_info_t *in_pin)
{
sc_pkcs15_auth_info_t pin = *in_pin;
pin.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
if(!pin.auth_method) /* or SC_AC_NONE */
pin.auth_method = SC_AC_CHV;
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;
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, obj, &key);
}
int sc_pkcs15emu_add_ec_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_EC, obj, &key);
}
2020-02-24 17:29:32 +00:00
int sc_pkcs15emu_add_ec_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;
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EC, obj, &key);
}
2020-02-24 17:29:32 +00:00
int sc_pkcs15emu_add_eddsa_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_EDDSA, obj, &key);
}
int sc_pkcs15emu_add_eddsa_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;
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_EDDSA, obj, &key);
}
int sc_pkcs15emu_add_xeddsa_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_XEDDSA, obj, &key);
}
int sc_pkcs15emu_add_xeddsa_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;
return sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_PUBKEY_XEDDSA, obj, &key);
}
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);
}
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);
}
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;
2019-12-09 15:04:05 +00:00
SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
Do not cast the return value of malloc(3) and calloc(3) From http://en.wikipedia.org/wiki/Malloc#Casting_and_type_safety " Casting and type safety malloc returns a void pointer (void *), which indicates that it is a pointer to a region of unknown data type. One may "cast" (see type conversion) this pointer to a specific type, as in int *ptr = (int*)malloc(10 * sizeof (int)); When using C, this is considered bad practice; it is redundant under the C standard. Moreover, putting in a cast may mask failure to include the header stdlib.h, in which the prototype for malloc is found. In the absence of a prototype for malloc, the C compiler will assume that malloc returns an int, and will issue a warning in a context such as the above, provided the error is not masked by a cast. On certain architectures and data models (such as LP64 on 64 bit systems, where long and pointers are 64 bit and int is 32 bit), this error can actually result in undefined behavior, as the implicitly declared malloc returns a 32 bit value whereas the actually defined function returns a 64 bit value. Depending on calling conventions and memory layout, this may result in stack smashing. The returned pointer need not be explicitly cast to a more specific pointer type, since ANSI C defines an implicit conversion between the void pointer type and other pointers to objects. An explicit cast of malloc's return value is sometimes performed because malloc originally returned a char *, but this cast is unnecessary in standard C code.[4][5] Omitting the cast, however, creates an incompatibility with C++, which does require it. The lack of a specific pointer type returned from malloc is type-unsafe behaviour: malloc allocates based on byte count but not on type. This distinguishes it from the C++ new operator that returns a pointer whose type relies on the operand. (see C Type Safety). " See also http://www.opensc-project.org/pipermail/opensc-devel/2010-August/014586.html git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4636 c6295689-39f2-0310-b995-f0e70906c6a9
2010-08-18 15:08:51 +00:00
obj = calloc(1, sizeof(*obj));
2019-12-09 15:04:05 +00:00
if (!obj) {
LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
}
memcpy(obj, in_obj, sizeof(*obj));
2019-12-09 15:04:05 +00:00
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_auth_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;
case SC_PKCS15_TYPE_DATA_OBJECT:
df_type = SC_PKCS15_DODF;
data_len = sizeof(struct sc_pkcs15_data_info);
break;
default:
sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
free(obj);
2019-12-09 15:04:05 +00:00
LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
}
obj->data = calloc(1, data_len);
if (obj->data == NULL) {
free(obj);
2019-12-09 15:04:05 +00:00
LOG_FUNC_RETURN(p15card->card->ctx, 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);
2019-12-09 15:04:05 +00:00
LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
}