pkcs15init: iasecc: create objects for minidriver support

- Create/delete the PKCS#15 'DATA' objects destinated to supply support of minidriver. For a while only 'Gemalto' style of such support is implemented.
- Declare epass2003 pkcs15init operations.
- include into OpenSC configuration the SM related sections
This commit is contained in:
Viktor Tarasov 2012-06-07 18:52:03 +02:00
parent 92e0c94c3b
commit 78fe16654e
4 changed files with 474 additions and 86 deletions

View File

@ -19,8 +19,16 @@ app default {
# Special values 'stdout' and 'stderr' are recognized.
# Default: stderr
#
# debug_file = /tmp/opensc-debug.log;
# debug_file = "C:\Documents and Settings\All Users\Documents\opensc-debug.log";
# debug_file = @DEBUG_FILE@
# Re-open debug file (used in WIN32)
#
# In Windows, file handles can not be shared between DLL-s,
# each DLL has a separate file handle table.
# For that reason reopen debug file before every debug message.
#
# Default: true
# reopen_debug_file = false;
# PKCS#15 initialization / personalization
# profiles directory for pkcs15-init.
@ -39,7 +47,7 @@ app default {
# CT-API module configuration.
reader_driver ctapi {
# module /usr/local/towitoko/lib/libtowitoko.so {
# module @libdir@/libtowitoko.so {
# CT-API ports:
# 0..3 COM1..4
# 4 Printer
@ -116,7 +124,7 @@ app default {
#
# card_driver customcos {
# The location of the driver library
# module = /usr/lib/opensc/drivers/card_customcos.so;
# module = @libdir@/card_customcos.so;
# }
# Force using specific card driver
@ -263,14 +271,34 @@ app default {
force_protocol = t0;
}
# Oberthur's AuthentIC v3.2.2
card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:00:70:0A:90:00:8B {
type = 11100;
driver = "authentic";
name = "AuthentIC v3.1";
# Name of SM configuration sub-section
# secure_messaging = local_authentic;
}
# IAS/ECC cards
#card_atr 3B:7F:96:00:00:00:31:B9:64:40:70:14:10:73:94:01:80:82:90:00 {
# type = 25001;
# driver = "iasecc";
# name = "Gemalto MultiApp IAS/ECC v1.0.1";
# # secure_messaging = local_gemalto_iam;
# # secure_messaging = local_adele;
#}
card_atr 3B:7F:96:00:00:00:31:B9:64:40:70:14:10:73:94:01:80:82:90:00 {
type = 25001;
driver = "iasecc";
name = "Gemalto MultiApp IAS/ECC v1.0.1";
secure_messaging = local_gemalto_iam;
# secure_messaging = local_adele;
md_read_only = false;
md_supports_X509_enrollment = true;
}
card_atr 3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00 {
type = 25001;
driver = "iasecc";
name = "Gemalto MultiApp IAS/ECC v1.0.1";
secure_messaging = local_gemalto_iam;
md_read_only = false;
md_supports_X509_enrollment = true;
}
#card_atr 3B:DD:18:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:08:00:07:90:00:FE {
# type = 25002;
# driver = "iasecc";
@ -283,6 +311,108 @@ app default {
# name = "Morpho YpsID S3 IAS/ECC";
# # secure_messaging = local_morpho_YpsID_S3;
#}
card_atr 3B:DF:18:FF:81:91:FE:1F:C3:00:31:B8:64:0C:01:EC:C1:73:94:01:80:82:90:00:B3 {
type = 25004;
driver = "iasecc";
name = "Amos IAS/ECC v1.0.1";
md_read_only = false;
md_supports_X509_enrollment = true;
secure_messaging = local_amos;
}
card_atr 3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:01:0B:03:52:00:05:38 {
type = 25004;
driver = "iasecc";
name = "Amos IAS/ECC v1.0.1";
md_read_only = false;
md_supports_X509_enrollment = true;
secure_messaging = local_amos_eid;
}
secure_messaging local_authentic {
#path to ans name of external SM module
#module_name = @DEFAULT_SM_MODULE@;
#module_path = @libdir@;
# specific data to tune the module initialization
#module_data = "Here can be your SM module init data";
# SM mode:
# 'transmit' -- in this mode the procedure to securize an APDU is called by the OpenSC general
# APDU transmit procedure.
# In this mode all APDUs, except the ones filtered by the card specific procedure,
# are securized.
# 'acl' -- in this mode APDU are securized only if needed by the ACLs of the command to be executed.
#
#mode = transmit;
# SM type specific flags
# flags = 0x78; # 0x78 -- level 3, channel 0
# Default KMC of the GP Card Manager for the Oberthur's Java cards
# kmc = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00";
}
secure_messaging local_gemalto_iam {
module_name = @DEFAULT_SM_MODULE@;
module_path = @libdir@;
#module_data = "";
type = acl; # transmit, acl
ifd_serial = "11:22:33:44:55:66:77:88";
# Keyset values from IAM profiles of the Gemalto IAS/ECC cards
keyset_02_enc = "RW_PRIV_ENC_TEST";
keyset_02_mac = "RW_PRIV_MAC_TEST";
keyset_E828BD080FD2504543432D654944_01_enc = "RO_ENC_TEST_KEY_";
keyset_E828BD080FD2504543432D654944_01_mac = "RO_MAC_TEST_KEY_";
keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST";
keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST";
}
secure_messaging local_amos {
module_name = @DEFAULT_SM_MODULE@;
module_path = @libdir@;
mode = acl;
ifd_serial = "11:22:33:44:55:66:77:88";
keyset_02_enc = "ENCROECHANTILLON";
keyset_02_mac = "MACROECHANTILLON";
}
secure_messaging local_amos_eid {
module_name = @DEFAULT_SM_MODULE@;
module_path = @libdir@;
mode = acl;
ifd_serial = "11:22:33:44:55:66:77:88";
keyset_E828BD080FD2504543432D654944_03_enc = "RW_PUBL_ENC_TEST";
keyset_E828BD080FD2504543432D654944_03_mac = "RW_PUBL_MAC_TEST";
}
secure_messaging local_adele {
module_name = @DEFAULT_SM_MODULE@;
module_path = @libdir@;
#module_data = "";
type = acl; # transmit, acl
ifd_serial = "11:22:33:44:55:66:77:88";
# Keyset values from 'Adele' profiles of the IAS/ECC cards
keyset_01_enc = "EMENCECHANTILLON";
keyset_01_mac = "EMMACECHANTILLON";
keyset_02_enc = "AAENCECHANTILLON";
keyset_02_mac = "AAMACECHANTILLON";
keyset_E828BD080FD2500000040301_02_enc = "E2ENCECHANTILLON";
keyset_E828BD080FD2500000040301_02_mac = "E2MACECHANTILLON";
keyset_D2500000044164E86C650101_02_enc = "E1ENCECHANTILLON";
keyset_D2500000044164E86C650101_02_mac = "E1MACECHANTILLON";
keyset_D2500000044164E86C650101_03_enc = "SIENCECHANTILLON";
keyset_D2500000044164E86C650101_03_mac = "SIMACECHANTILLON";
}
# Below are the framework specific configuration blocks.
@ -335,8 +465,34 @@ app default {
#
# emulate custom {
# The location of the driver library
# module = /usr/lib/opensc/drivers/p15emu_custom.so;
# module = @libdir@/p15emu_custom.so;
# }
# some additional application parameters:
# - type (generic, protected) used to distinguish the common access application
# and application for which authentication to perform some operation cannot be
# obtained with the common procedures (ex. object creation protected by secure messaging).
# Used by PKCS#11 module configurated to expose restricted number of slots.
# (for ex. configurated to expose only User PIN slot, User and Sign PINs slots, ...)
application E828BD080FD25047656E65726963 {
type = generic;
model = "ECC Generic PKI";
}
application E828BD080FD2500000040301 {
type = generic;
model = "Adèle Générique";
}
application E828BD080FD2504543432D654944 {
type = protected;
model = "ECC eID";
}
application E828BD080FD2500000040201 {
type = protected;
model = "Adèle Admin-2";
}
}
}

View File

@ -57,6 +57,7 @@
#define IASECC_TITLE "IASECC"
int iasecc_pkcs15_delete_file(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_file *df);
static int iasecc_md_gemalto_delete_prvkey(struct sc_pkcs15_card *, struct sc_profile *, struct sc_pkcs15_object *);
static void
iasecc_reference_to_pkcs15_id (unsigned int ref, struct sc_pkcs15_id *id)
@ -142,20 +143,34 @@ iasecc_pkcs15_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15c
obj_type = SC_PKCS15_TYPE_PUBKEY;
else if (df->type == SC_PKCS15_CDF)
obj_type = SC_PKCS15_TYPE_CERT;
else if (df->type == SC_PKCS15_DODF)
obj_type = SC_PKCS15_TYPE_DATA_OBJECT;
else
continue;
rv = sc_pkcs15_get_objects(p15card, obj_type, objs, 32);
LOG_TEST_RET(ctx, rv, "Failed to get PKCS#15 objects to remove");
for (ii=0; ii<rv; ii++)
for (ii=0; ii<rv; ii++) {
if (obj_type == SC_PKCS15_TYPE_CERT) {
struct sc_path path = ((struct sc_pkcs15_cert_info *)(objs[ii]->data))->path;
rv = sc_delete_file(p15card->card, &path);
}
else if (obj_type == SC_PKCS15_TYPE_DATA_OBJECT) {
struct sc_path path = ((struct sc_pkcs15_data_info *)(objs[ii]->data))->path;
rv = sc_delete_file(p15card->card, &path);
}
sc_pkcs15_remove_object(p15card, objs[ii]);
}
rv = sc_select_file(p15card->card, &df->path, &file);
if (rv == SC_ERROR_FILE_NOT_FOUND)
continue;
LOG_TEST_RET(ctx, rv, "Cannot select object file");
profile->dirty = 1;
rv = sc_erase_binary(p15card->card, 0, file->size, 0);
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
@ -899,14 +914,16 @@ iasecc_pkcs15_fix_private_key_attributes(struct sc_profile *profile, struct sc_p
rv = iasecc_pkcs15_add_access_rule(object, keys_access_modes[ii], &auth_id);
LOG_TEST_RET(ctx, rv, "Cannot add access rule");
if (ii == IASECC_ACLS_RSAKEY_PSO_SIGN
|| ii == IASECC_ACLS_RSAKEY_INTERNAL_AUTH
if (ii == IASECC_ACLS_RSAKEY_PSO_SIGN || ii == IASECC_ACLS_RSAKEY_INTERNAL_AUTH
|| ii == IASECC_ACLS_RSAKEY_PSO_DECIPHER) {
if (!sc_pkcs15_compare_id(&object->auth_id, &auth_id)) {
/* Sorry, this will silently overwrite the profile option.*/
sc_log(ctx, "Change object's authId for the one that really protects crypto operation.");
object->auth_id = auth_id;
}
rv = iasecc_pkcs15_add_access_rule(object, SC_PKCS15_ACCESS_RULE_MODE_EXECUTE, &auth_id);
LOG_TEST_RET(ctx, rv, "Cannot add 'EXECUTE' access rule");
}
}
@ -920,8 +937,10 @@ iasecc_pkcs15_fix_private_key_attributes(struct sc_profile *profile, struct sc_p
LOG_TEST_RET(ctx, rv, "Cannot add RSA_PKCS SHA2 supported mechanism");
key_info->usage |= SC_PKCS15_PRKEY_USAGE_SIGN;
if (sdo_prvkey->docp.non_repudiation.value && sdo_prvkey->docp.non_repudiation.value[0])
if (sdo_prvkey->docp.non_repudiation.value && sdo_prvkey->docp.non_repudiation.value[0]) {
key_info->usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
object->user_consent = 1;
}
}
else if (ii == IASECC_ACLS_RSAKEY_INTERNAL_AUTH) {
rv = iasecc_pkcs15_add_algorithm_reference(p15card, key_info, IASECC_ALGORITHM_RSA_PKCS);
@ -1264,7 +1283,7 @@ iasecc_pkcs15_delete_sdo (struct sc_profile *profile, struct sc_pkcs15_card *p15
int size = *(sdo->docp.size.value + 0) * 0x100 + *(sdo->docp.size.value + 1);
sc_log(ctx, "iasecc_pkcs15_delete_sdo() SDO size %i bytes", size);
memset(zeros, 0, sizeof(zeros));
memset(zeros, 0xA5, sizeof(zeros));
memset(&rsa, 0, sizeof(rsa));
rsa.modulus.data = rsa.exponent.data = zeros;
@ -1297,11 +1316,11 @@ iasecc_pkcs15_delete_object (struct sc_profile *profile, struct sc_pkcs15_card *
switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
case SC_PKCS15_TYPE_PUBKEY:
key_ref = ((sc_pkcs15_pubkey_info_t *)object->data)->key_reference;
key_ref = ((struct sc_pkcs15_pubkey_info *)object->data)->key_reference;
sc_log(ctx, "Ignore delete of the SDO-PUBLIC-KEY(ref:%X)", key_ref);
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
case SC_PKCS15_TYPE_PRKEY:
key_ref = ((sc_pkcs15_prkey_info_t *)object->data)->key_reference;
key_ref = ((struct sc_pkcs15_prkey_info *)object->data)->key_reference;
/* Delete both parts of the RSA key */
rv = iasecc_pkcs15_delete_sdo (profile, p15card, IASECC_SDO_CLASS_RSA_PRIVATE, key_ref);
@ -1310,6 +1329,11 @@ iasecc_pkcs15_delete_object (struct sc_profile *profile, struct sc_pkcs15_card *
rv = iasecc_pkcs15_delete_sdo (profile, p15card, IASECC_SDO_CLASS_RSA_PUBLIC, key_ref);
LOG_TEST_RET(ctx, rv, "Cannot delete RSA_PUBLIC SDO");
if (profile->md_style == SC_PKCS15INIT_MD_STYLE_GEMALTO) {
rv = iasecc_md_gemalto_delete_prvkey(p15card, profile, object);
LOG_TEST_RET(ctx, rv, "MD error: cannot delete private key");
}
LOG_FUNC_RETURN(ctx, rv);
case SC_PKCS15_TYPE_CERT:
break;
@ -1332,6 +1356,215 @@ iasecc_pkcs15_delete_object (struct sc_profile *profile, struct sc_pkcs15_card *
}
static int
iasecc_md_gemalto_set_default(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *key_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_object *data_obj = NULL;
struct sc_pkcs15init_dataargs data_args;
char guid[39];
int rv;
LOG_FUNC_CALLED(ctx);
rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", "Default Key Container", &data_obj);
if (rv != SC_ERROR_OBJECT_NOT_FOUND)
LOG_TEST_RET(ctx, rv, "Find 'Default Key Container' data object error");
rv = sc_pkcs15_get_guid(p15card, key_obj, 1, guid, sizeof(guid));
LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
if (!data_obj) {
memset(&data_args, 0, sizeof(data_args));
data_args.app_oid.value[0] = -1;
data_args.label = "Default Key Container";
data_args.app_label = "CSP";
data_args.der_encoded.value = (unsigned char *)guid;
data_args.der_encoded.len = strlen(guid);
rv = sc_pkcs15init_store_data_object(p15card, profile, &data_args, NULL);
LOG_TEST_RET(ctx, rv, "Failed to store 'CSP'/'Default Key Container' data object");
}
else {
struct sc_pkcs15_data_info *dinfo = (struct sc_pkcs15_data_info *)data_obj->data;
struct sc_file *file = NULL;
sc_log(ctx, "update data object content in '%s'\n", sc_print_path(&dinfo->path));
rv = sc_select_file(p15card->card, &dinfo->path, &file);
LOG_TEST_RET(ctx, rv, "Cannot select data object file");
rv = sc_pkcs15init_update_file(profile, p15card, file, guid, strlen(guid));
sc_file_free(file);
LOG_TEST_RET(ctx, rv, "Failed to update 'CSP'/'Default Key Container' data object");
}
LOG_FUNC_RETURN(ctx, rv);
}
static int
iasecc_md_gemalto_unset_default(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *key_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_object *data_obj = NULL;
struct sc_pkcs15_data *dod = NULL;
struct sc_pkcs15_object *key_objs[32];
struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
char guid[39];
int rv, ii, keys_num;
LOG_FUNC_CALLED(ctx);
rv = sc_pkcs15_get_guid(p15card, key_obj, 1, guid, sizeof(guid));
LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", "Default Key Container", &data_obj);
if (rv == SC_ERROR_OBJECT_NOT_FOUND)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)data_obj->data, &dod);
LOG_TEST_RET(ctx, rv, "Cannot read from 'CSP/'Default Key Container'");
if (strlen(guid) != dod->data_len || memcmp(guid, dod->data, strlen(guid)))
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, key_objs, 32);
LOG_TEST_RET(ctx, rv, "Get private key PKCS#15 objects error");
keys_num = rv;
if (keys_num) {
for (ii=0; ii<keys_num; ii++) {
struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)key_objs[ii]->data;
if (sc_pkcs15_compare_id(&key_info->id, &prkey_info->id))
continue;
/* TODO: keys with inappropriate key usages should also be ignored */
rv = iasecc_md_gemalto_set_default(p15card, profile, key_objs[ii]);
LOG_TEST_RET(ctx, rv, "Cannot set default container");
break;
}
if (ii == keys_num) {
/* No more default container */
rv = sc_pkcs15init_delete_object(p15card, profile, data_obj);
LOG_TEST_RET(ctx, rv, "Cannot delete 'CSP'/'Default Key Container' data object");
}
}
LOG_FUNC_RETURN(ctx, rv);
}
static int
iasecc_md_gemalto_new_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *key_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
struct sc_pkcs15init_dataargs data_args;
char guid[40];
unsigned char data[SC_PKCS15_MAX_ID_SIZE + 6];
size_t offs;
int rv;
LOG_FUNC_CALLED(ctx);
memset(guid, 0, sizeof(guid));
rv = sc_pkcs15_get_guid(p15card, key_obj, 1, guid, sizeof(guid) - 1);
LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
sc_log(ctx, "New key GUID: '%s'", guid);
offs = 0;
data[offs++] = 0x01;
data[offs++] = prkey_info->id.len;
memcpy(&data[offs], prkey_info->id.value, prkey_info->id.len);
offs += prkey_info->id.len;
data[offs++] = 0x02;
data[offs++] = 0x01;
data[offs++] = 0x01;
memset(&data_args, 0, sizeof(data_args));
data_args.app_oid.value[0] = -1;
data_args.label = guid;
data_args.app_label = "CSP";
data_args.der_encoded.value = data;
data_args.der_encoded.len = offs;
rv = sc_pkcs15init_store_data_object(p15card, profile, &data_args, NULL);
LOG_TEST_RET(ctx, rv, "Failed to store 'CSP' data object");
/* For a while default container is set for the first key.
* TODO: Key usage should be taken into consideration. */
if (sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0) == 1) {
rv = iasecc_md_gemalto_set_default(p15card, profile, key_obj);
LOG_TEST_RET(ctx, rv, "MD: cannot set default container");
}
LOG_FUNC_RETURN(ctx, rv);
}
static int
iasecc_md_gemalto_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *key_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_object *data_obj = NULL;
char guid[39];
int rv;
LOG_FUNC_CALLED(ctx);
rv = sc_pkcs15_get_guid(p15card, key_obj, 1, guid, sizeof(guid));
LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", guid, &data_obj);
if (rv == SC_ERROR_OBJECT_NOT_FOUND)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
LOG_TEST_RET(ctx, rv, "Find 'CSP'/<key> data object error");
rv = sc_pkcs15init_delete_object(p15card, profile, data_obj);
LOG_TEST_RET(ctx, rv, "Cannot delete 'CSP'/<key> data object");
/* For a while default container is set for the first key.
* TODO: Key usage should be taken into consideration. */
if (sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0) == 1) {
rv = iasecc_md_gemalto_unset_default(p15card, profile, key_obj);
LOG_TEST_RET(ctx, rv, "MD: cannot set default container");
}
LOG_FUNC_RETURN(ctx, rv);
}
static int
iasecc_store_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *object,
struct sc_pkcs15_der *data, struct sc_path *path)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)object->data;
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "Private Key id '%s'", sc_pkcs15_print_id(&prkey_info->id));
sc_log(ctx, "MD style '0x%X'", profile->md_style);
if (profile->md_style == SC_PKCS15INIT_MD_STYLE_NONE) {
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
else if (profile->md_style == SC_PKCS15INIT_MD_STYLE_GEMALTO) {
int rv = iasecc_md_gemalto_new_prvkey(p15card, profile, object);
LOG_TEST_RET(ctx, rv, "MD: cannot add new key");
}
else {
LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported MD style");
}
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
static int
iasecc_store_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile, struct sc_pkcs15_object *object,
struct sc_pkcs15_der *data, struct sc_path *path)
@ -1390,57 +1623,54 @@ iasecc_store_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
rv = iasecc_pkcs15_fix_file_access(p15card, pfile, object);
LOG_TEST_RET(ctx, rv, "encode file access rules failed");
if (pfile)
sc_file_free(pfile);
/* NOT_IMPLEMENTED error code indicates to the upper call to execute the default 'store data' procedure */
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_IMPLEMENTED);
}
/*
* FIXME: Implement 'store data object'
static int
iasecc_store_opaqueDO(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *object, struct sc_pkcs15_id *id,
iasecc_store_data_object(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *object,
struct sc_pkcs15_der *data, struct sc_path *path)
{
#define MAX_DATA_OBJS 32
struct sc_context *ctx = p15card->card->ctx;
struct sc_card *card = p15card->card;
struct sc_pkcs15_object *p15objects[0x40];
struct sc_file *cfile = NULL, *pfile = NULL, *parent = NULL;
struct sc_pkcs15_object *p15objects[MAX_DATA_OBJS];
struct sc_file *cfile = NULL, *file = NULL, *parent = NULL;
int rv, nn_objs, indx, ii;
LOG_FUNC_CALLED(ctx);
sc_log(ctx, "iasecc_store_opaqueDO() id '%s'", sc_pkcs15_print_id(id));
sc_log(ctx, "iasecc_store_opaqueDO() authID '%s'", sc_pkcs15_print_id(&object->auth_id));
nn_objs = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, p15objects, 0x40);
sc_log(ctx, "iasecc_store_data_object() authID '%s'", sc_pkcs15_print_id(&object->auth_id));
nn_objs = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, p15objects, MAX_DATA_OBJS);
LOG_TEST_RET(ctx, nn_objs, "IasEcc get pkcs15 DATA objects error");
for(indx = 1; indx < 0x40; indx++) {
for(indx = 1; indx < MAX_DATA_OBJS; indx++) {
struct sc_path fpath;
rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_DATA_OBJECT, indx, &pfile);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() pkcs15 new DATA file error");
fpath = pfile->path;
rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_DATA_OBJECT, indx, &file);
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() pkcs15 new DATA file error");
fpath = file->path;
for (ii=0; ii<nn_objs; ii++) {
struct sc_pkcs15_data_info *info = (struct sc_pkcs15_data_info *)p15objects[ii]->data;
int file_id = info->path.value[info->path.len - 2] * 0x100 + info->path.value[info->path.len - 1];
sc_log(ctx, "iasecc_store_opaqueDO() %i: file_id 0x%X, pfile->id 0x%X\n", ii, file_id, pfile->id);
if (pfile->id == file_id)
sc_log(ctx, "iasecc_store_data_object() %i: file_id 0x%X, pfile->id 0x%X\n", ii, file_id, file->id);
if (file->id == file_id)
break;
}
if (ii == nn_objs)
break;
if (pfile)
sc_file_free(pfile);
pfile = NULL;
sc_file_free(file);
}
if (indx == 0x40)
LOG_TEST_RET(ctx, SC_ERROR_TOO_MANY_OBJECTS, "iasecc_store_opaqueDO() too many DATA objects.");
if (indx == MAX_DATA_OBJS)
LOG_TEST_RET(ctx, SC_ERROR_TOO_MANY_OBJECTS, "iasecc_store_data_object() too many DATA objects.");
do {
const struct sc_acl_entry *acl;
@ -1448,71 +1678,75 @@ iasecc_store_opaqueDO(struct sc_pkcs15_card *p15card, struct sc_profile *profile
memset(object->access_rules, 0, sizeof(object->access_rules));
object->access_rules[0].access_mode = SC_PKCS15_ACCESS_RULE_MODE_READ;
acl = sc_file_get_acl_entry(pfile, SC_AC_OP_READ);
sc_log(ctx, "iasecc_store_opaqueDO() READ method %i", acl->method);
acl = sc_file_get_acl_entry(file, SC_AC_OP_READ);
sc_log(ctx, "iasecc_store_data_object() READ method %i", acl->method);
if (acl->method == SC_AC_IDA)
iasecc_reference_to_pkcs15_id (acl->key_ref, &object->access_rules[0].auth_id);
object->access_rules[1].access_mode = SC_PKCS15_ACCESS_RULE_MODE_UPDATE;
acl = sc_file_get_acl_entry(pfile, SC_AC_OP_UPDATE);
sc_log(ctx, "iasecc_store_opaqueDO() UPDATE method %i", acl->method);
acl = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE);
sc_log(ctx, "iasecc_store_data_object() UPDATE method %i", acl->method);
if (acl->method == SC_AC_IDA)
iasecc_reference_to_pkcs15_id (acl->key_ref, &object->access_rules[1].auth_id);
object->access_rules[2].access_mode = SC_PKCS15_ACCESS_RULE_MODE_DELETE;
acl = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
sc_log(ctx, "iasecc_store_data_object() UPDATE method %i", acl->method);
if (acl->method == SC_AC_IDA)
iasecc_reference_to_pkcs15_id (acl->key_ref, &object->access_rules[2].auth_id);
} while(0);
rv = iasecc_file_convert_acls(ctx, profile, pfile);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() cannot convert profile ACLs");
rv = iasecc_file_convert_acls(ctx, profile, file);
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot convert profile ACLs");
sc_log(ctx, "sc_pkcs15init_store_opaqueDO() indx %i; pfile->parent.len %i\n", indx, pfile->parent_path.len);
sc_log(ctx, "sc_pkcs15init_store_opaqueDO() profile parent path '%s'\n", sc_print_path(&pfile->parent_path));
rv = sc_profile_get_parent(profile, "public-data", &parent);
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot get object parent");
sc_log(ctx, "iasecc_store_data_object() parent path '%s'\n", sc_print_path(&parent->path));
rv = sc_select_file(card, &pfile->parent_path, &parent);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() cannot select DATA's parent");
sc_log(ctx, "iasecc_store_opaqueDO() parent path '%s'\n", sc_print_path(&parent->path));
rv = sc_select_file(card, &parent->path, NULL);
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot select parent");
sc_ctx_suppress_errors_on(ctx);
rv = sc_select_file(card, &pfile->path, &cfile);
sc_ctx_suppress_errors_off(ctx);
rv = sc_select_file(card, &file->path, &cfile);
if (!rv) {
rv = sc_pkcs15init_authenticate(profile, p15card, cfile, SC_AC_OP_DELETE);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() DELETE authentication failed");
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() DELETE authentication failed");
rv = iasecc_pkcs15_delete_file(p15card, profile, cfile);
LOG_TEST_RET(ctx, rv, "s_pkcs15init_store_opaqueDO() delete pkcs15 file error");
LOG_TEST_RET(ctx, rv, "s_pkcs15init_store_data_object() delete pkcs15 file error");
}
else if (rv != SC_ERROR_FILE_NOT_FOUND) {
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() select file error");
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() select file error");
}
rv = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_CREATE);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() parent CREATE authentication failed");
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() parent CREATE authentication failed");
pfile->size = data->len;
rv = sc_create_file(card, pfile);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() cannot create DATA file");
file->size = data->len;
rv = sc_create_file(card, file);
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() cannot create DATA file");
rv = sc_pkcs15init_authenticate(profile, p15card, pfile, SC_AC_OP_UPDATE);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() data file UPDATE authentication failed");
rv = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() data file UPDATE authentication failed");
rv = sc_update_binary(card, 0, data->value, data->len, 0);
LOG_TEST_RET(ctx, rv, "iasecc_store_opaqueDO() update DATA file failed");
LOG_TEST_RET(ctx, rv, "iasecc_store_data_object() update DATA file failed");
if (path)
*path = pfile->path;
*path = file->path;
if (parent)
sc_file_free(parent);
if (pfile)
sc_file_free(pfile);
if (file)
sc_file_free(file);
if (cfile)
sc_file_free(cfile);
LOG_FUNC_RETURN(ctx, rv);
#undef MAX_DATA_OBJS
}
*/
static int
@ -1527,17 +1761,21 @@ iasecc_emu_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile
LOG_FUNC_CALLED(ctx);
switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) {
case SC_PKCS15_TYPE_PRKEY:
rv = iasecc_store_prvkey(p15card, profile, object, data, path);
break;
case SC_PKCS15_TYPE_PUBKEY:
rv = iasecc_store_pubkey(p15card, profile, object, data, path);
break;
case SC_PKCS15_TYPE_CERT:
rv = iasecc_store_cert(p15card, profile, object, data, path);
break;
/*
case SC_PKCS15_TYPE_DATA_OBJECT:
rv = iasecc_store_opaqueDO(p15card, profile, object, id, data, path);
rv = iasecc_store_data_object(p15card, profile, object, data, path);
break;
default:
rv = SC_ERROR_NOT_IMPLEMENTED;
break;
*/
}
LOG_FUNC_RETURN(ctx, rv);
@ -1568,20 +1806,12 @@ sc_pkcs15init_iasecc_operations = {
NULL, /* encode public key */
NULL, /* finalize_card */
iasecc_pkcs15_delete_object,
/* pkcs15init emulation */
NULL,
NULL,
iasecc_emu_update_tokeninfo,
NULL,
NULL, /* pkcs15init emulation update_dir */
NULL, /* pkcs15init emulation update_any_df */
NULL, /* pkcs15init emulation update_tokeninfo */
NULL, /* pkcs15init emulation write_info */
iasecc_emu_store_data,
NULL, /* sanity_check */
/*
iasecc_pkcs15init_select_id,
iasecc_pkcs15init_set_pin,
iasecc_pkcs15init_erase_application
*/
NULL, /* sanity_check */
};

View File

@ -388,7 +388,7 @@ extern int sc_pkcs15_create_pin_domain(struct sc_profile *, struct sc_pkcs15_car
extern int sc_pkcs15init_get_pin_reference(struct sc_pkcs15_card *,
struct sc_profile *, unsigned, int);
extern int sc_pkcs15init_sanity_check(struct sc_pkcs15_card *, struct sc_profile *);
extern int sc_pkcs15init_sanity_check(struct sc_pkcs15_card *, struct sc_profile *);
extern int sc_pkcs15init_finalize_profile(struct sc_card *card, struct sc_profile *profile,
struct sc_aid *aid);
@ -407,6 +407,7 @@ extern struct sc_pkcs15init_operations *sc_pkcs15init_get_muscle_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_asepcos_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_rutoken_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_entersafe_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_epass2003_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_rtecp_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_westcos_ops(void);
extern struct sc_pkcs15init_operations *sc_pkcs15init_get_myeid_ops(void);

View File

@ -150,6 +150,7 @@ static struct profile_operations {
{ "muscle", (void*) sc_pkcs15init_get_muscle_ops },
{ "asepcos", (void*) sc_pkcs15init_get_asepcos_ops },
{ "entersafe",(void*) sc_pkcs15init_get_entersafe_ops },
{ "epass2003",(void*) sc_pkcs15init_get_epass2003_ops },
{ "rutoken_ecp", (void *) sc_pkcs15init_get_rtecp_ops },
{ "westcos", (void *) sc_pkcs15init_get_westcos_ops },
{ "myeid", (void *) sc_pkcs15init_get_myeid_ops },