pkcs15init: in select_object_path() look for the template also outside the 'key-domain'.
To use New API with the cards that do not have 'key-domain' in their profile, when setting object data path, the object template has to be also looked for outside the 'key-domain'. ;migrate Oberthur to the New API; ;use macros SC_CALLED, SC_TEST_.., SC_RETURN in pkcs15-lib.c git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3940 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
986309db79
commit
bc140126e9
|
@ -1206,7 +1206,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card,
|
||||||
}
|
}
|
||||||
|
|
||||||
r = select_object_path(p15card, profile, object, &key_info->id, &key_info->path);
|
r = select_object_path(p15card, profile, object, &key_info->id, &key_info->path);
|
||||||
SC_TEST_RET(ctx, r, "Failed to select object path");
|
SC_TEST_RET(ctx, r, "Failed to select private key object path");
|
||||||
|
|
||||||
/* See if we need to select a key reference for this object */
|
/* See if we need to select a key reference for this object */
|
||||||
if (profile->ops->select_key_reference) {
|
if (profile->ops->select_key_reference) {
|
||||||
|
@ -1234,6 +1234,7 @@ sc_pkcs15init_init_prkdf(struct sc_pkcs15_card *p15card,
|
||||||
SC_FUNC_RETURN(ctx, 3, SC_SUCCESS);
|
SC_FUNC_RETURN(ctx, 3, SC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a new private key
|
* Generate a new private key
|
||||||
*/
|
*/
|
||||||
|
@ -1244,42 +1245,41 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
||||||
unsigned int keybits,
|
unsigned int keybits,
|
||||||
struct sc_pkcs15_object **res_obj)
|
struct sc_pkcs15_object **res_obj)
|
||||||
{
|
{
|
||||||
|
struct sc_context *ctx = p15card->card->ctx;
|
||||||
struct sc_pkcs15init_pubkeyargs pubkey_args;
|
struct sc_pkcs15init_pubkeyargs pubkey_args;
|
||||||
struct sc_pkcs15_object *object;
|
struct sc_pkcs15_object *object;
|
||||||
struct sc_pkcs15_prkey_info *key_info;
|
struct sc_pkcs15_prkey_info *key_info;
|
||||||
int r, caller_supplied_id = 0;
|
int r, caller_supplied_id = 0;
|
||||||
|
|
||||||
|
SC_FUNC_CALLED(ctx, 3);
|
||||||
/* check supported key size */
|
/* check supported key size */
|
||||||
r = check_key_size(p15card->card, keygen_args->prkey_args.key.algorithm, keybits);
|
r = check_key_size(p15card->card, keygen_args->prkey_args.key.algorithm, keybits);
|
||||||
if (r != SC_SUCCESS)
|
SC_TEST_RET(ctx, r, "Invalid key size");
|
||||||
return r;
|
|
||||||
|
|
||||||
/* For now, we support just RSA and GOST key pair generation */
|
/* For now, we support just RSA and GOST key pair generation */
|
||||||
if (!check_key_compatibility(p15card, &keygen_args->prkey_args.key,
|
if (!check_key_compatibility(p15card, &keygen_args->prkey_args.key,
|
||||||
keygen_args->prkey_args.x509_usage,
|
keygen_args->prkey_args.x509_usage,
|
||||||
keybits, SC_ALGORITHM_ONBOARD_KEY_GEN))
|
keybits, SC_ALGORITHM_ONBOARD_KEY_GEN))
|
||||||
return SC_ERROR_NOT_SUPPORTED;
|
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generation of RSA and GOST keys is only supported");
|
||||||
|
|
||||||
if (profile->ops->generate_key == NULL && profile->ops->old_generate_key == NULL)
|
if (profile->ops->generate_key == NULL && profile->ops->old_generate_key == NULL)
|
||||||
return SC_ERROR_NOT_SUPPORTED;
|
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key generation not supported");
|
||||||
|
|
||||||
/* Set the USER PIN reference from args */
|
/* Set the USER PIN reference from args */
|
||||||
r = set_user_pin_from_authid(p15card, profile,
|
r = set_user_pin_from_authid(p15card, profile, &keygen_args->prkey_args.auth_id);
|
||||||
&keygen_args->prkey_args.auth_id);
|
SC_TEST_RET(ctx, r, "Cannot set User PIN from auth. ID");
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* Set the SO PIN reference from card */
|
/* Set the SO PIN reference from card */
|
||||||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
r = set_so_pin_from_card(p15card, profile);
|
||||||
return r;
|
SC_TEST_RET(ctx, r, "Cannot set SO PIN from card");
|
||||||
|
|
||||||
caller_supplied_id = keygen_args->prkey_args.id.len != 0;
|
caller_supplied_id = keygen_args->prkey_args.id.len != 0;
|
||||||
|
|
||||||
/* Set up the PrKDF object */
|
/* Set up the PrKDF object */
|
||||||
r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args,
|
r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args,
|
||||||
&keygen_args->prkey_args.key, keybits, &object);
|
&keygen_args->prkey_args.key, keybits, &object);
|
||||||
if (r < 0)
|
SC_TEST_RET(ctx, r, "Set up private key object error");
|
||||||
return r;
|
|
||||||
key_info = (struct sc_pkcs15_prkey_info *) object->data;
|
key_info = (struct sc_pkcs15_prkey_info *) object->data;
|
||||||
|
|
||||||
/* Set up the PuKDF info. The public key will be filled in
|
/* Set up the PuKDF info. The public key will be filled in
|
||||||
|
@ -1298,23 +1298,20 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
||||||
if (profile->ops->create_key) {
|
if (profile->ops->create_key) {
|
||||||
/* New API */
|
/* New API */
|
||||||
r = profile->ops->create_key(profile, p15card->card, object);
|
r = profile->ops->create_key(profile, p15card->card, object);
|
||||||
if (r < 0)
|
SC_TEST_RET(ctx, r, "Cannot generate key: create key failed");
|
||||||
return r;
|
|
||||||
|
|
||||||
r = profile->ops->generate_key(profile, p15card->card,
|
r = profile->ops->generate_key(profile, p15card->card, object, &pubkey_args.key);
|
||||||
object, &pubkey_args.key);
|
SC_TEST_RET(ctx, r, "Failed to generate key");
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
} else {
|
} else {
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
idx = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0);
|
idx = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0);
|
||||||
r = profile->ops->old_generate_key(profile, p15card->card, idx, keybits,
|
r = profile->ops->old_generate_key(profile, p15card->card, idx, keybits,
|
||||||
&pubkey_args.key, key_info);
|
&pubkey_args.key, key_info);
|
||||||
|
SC_TEST_RET(ctx, r, "Failed to generate key in an old manner");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update PrKDF entry */
|
/* update PrKDF entry */
|
||||||
if (r >= 0) {
|
|
||||||
if (!caller_supplied_id) {
|
if (!caller_supplied_id) {
|
||||||
struct sc_pkcs15_id iid;
|
struct sc_pkcs15_id iid;
|
||||||
|
|
||||||
|
@ -1322,8 +1319,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
||||||
* if intrinsic ID can be calculated -- overwrite the native one */
|
* if intrinsic ID can be calculated -- overwrite the native one */
|
||||||
memset(&iid, 0, sizeof(iid));
|
memset(&iid, 0, sizeof(iid));
|
||||||
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key);
|
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key);
|
||||||
if (r < 0)
|
SC_TEST_RET(ctx, r, "Select intrinsic ID error");
|
||||||
return r;
|
|
||||||
|
|
||||||
if (iid.len) {
|
if (iid.len) {
|
||||||
key_info->id = iid;
|
key_info->id = iid;
|
||||||
|
@ -1332,23 +1328,19 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object);
|
r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object);
|
||||||
}
|
SC_TEST_RET(ctx, r, "Failed to add generated private key object");
|
||||||
|
|
||||||
if (r >= 0) {
|
r = sc_pkcs15init_store_public_key(p15card, profile, &pubkey_args, NULL);
|
||||||
sc_pkcs15_object_t *pub_object;
|
SC_TEST_RET(ctx, r, "Failed to store public key");
|
||||||
|
|
||||||
r = sc_pkcs15init_store_public_key(p15card, profile,
|
if (res_obj)
|
||||||
&pubkey_args, &pub_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r >= 0 && res_obj)
|
|
||||||
*res_obj = object;
|
*res_obj = object;
|
||||||
|
|
||||||
sc_pkcs15_erase_pubkey(&pubkey_args.key);
|
sc_pkcs15_erase_pubkey(&pubkey_args.key);
|
||||||
|
|
||||||
profile->dirty = 1;
|
profile->dirty = 1;
|
||||||
|
|
||||||
return r;
|
SC_FUNC_RETURN(ctx, 3, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1506,6 +1498,8 @@ sc_pkcs15init_store_split_key(struct sc_pkcs15_card *p15card,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store a public key
|
* Store a public key
|
||||||
|
*
|
||||||
|
* TODO: set public key reference
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
|
sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
|
||||||
|
@ -1525,7 +1519,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card,
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
SC_FUNC_CALLED(ctx, 3);
|
SC_FUNC_CALLED(ctx, 3);
|
||||||
if (!res_obj || !keyargs)
|
if (!keyargs)
|
||||||
SC_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store public key aborted");
|
SC_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store public key aborted");
|
||||||
|
|
||||||
/* Create a copy of the key first */
|
/* Create a copy of the key first */
|
||||||
|
@ -1629,12 +1623,14 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
||||||
struct sc_pkcs15init_certargs *args,
|
struct sc_pkcs15init_certargs *args,
|
||||||
struct sc_pkcs15_object **res_obj)
|
struct sc_pkcs15_object **res_obj)
|
||||||
{
|
{
|
||||||
|
struct sc_context *ctx = p15card->card->ctx;
|
||||||
struct sc_pkcs15_cert_info *cert_info;
|
struct sc_pkcs15_cert_info *cert_info;
|
||||||
struct sc_pkcs15_object *object;
|
struct sc_pkcs15_object *object;
|
||||||
unsigned int usage;
|
unsigned int usage;
|
||||||
const char *label;
|
const char *label;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
SC_FUNC_CALLED(ctx, 3);
|
||||||
usage = SC_PKCS15_PRKEY_USAGE_SIGN;
|
usage = SC_PKCS15_PRKEY_USAGE_SIGN;
|
||||||
if (args->x509_usage)
|
if (args->x509_usage)
|
||||||
usage = sc_pkcs15init_map_usage(args->x509_usage, 0);
|
usage = sc_pkcs15init_map_usage(args->x509_usage, 0);
|
||||||
|
@ -1642,17 +1638,16 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
||||||
label = "Certificate";
|
label = "Certificate";
|
||||||
|
|
||||||
/* Set the SO PIN reference from card */
|
/* Set the SO PIN reference from card */
|
||||||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
r = set_so_pin_from_card(p15card, profile);
|
||||||
return r;
|
SC_TEST_RET(ctx, r, "Set SO PIN from card error");
|
||||||
|
|
||||||
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &args->id, &args->der_encoded);
|
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &args->id, &args->der_encoded);
|
||||||
if (r < 0)
|
SC_TEST_RET(ctx, r, "Get certificate 'intrinsic ID' error");
|
||||||
return r;
|
|
||||||
|
|
||||||
/* Select an ID if the user didn't specify one, otherwise
|
/* Select an ID if the user didn't specify one, otherwise
|
||||||
* make sure it's unique */
|
* make sure it's unique */
|
||||||
if ((r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id)) < 0)
|
r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id);
|
||||||
return r;
|
SC_TEST_RET(ctx, r, "Select certificate ID error");
|
||||||
|
|
||||||
if (profile->protect_certificates) {
|
if (profile->protect_certificates) {
|
||||||
/* If there is a private key corresponding to the ID given
|
/* If there is a private key corresponding to the ID given
|
||||||
|
@ -1663,12 +1658,8 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
||||||
if (args->id.len != 0
|
if (args->id.len != 0
|
||||||
&& sc_pkcs15_find_prkey_by_id(p15card, &args->id, &object) == 0) {
|
&& sc_pkcs15_find_prkey_by_id(p15card, &args->id, &object) == 0) {
|
||||||
r = set_user_pin_from_authid(p15card, profile, &object->auth_id);
|
r = set_user_pin_from_authid(p15card, profile, &object->auth_id);
|
||||||
if (r < 0) {
|
SC_TEST_RET(ctx, r, "Failed to assign user pin reference "
|
||||||
sc_debug(p15card->card->ctx,
|
"(copied from private key auth_id)");
|
||||||
"Failed to assign user pin reference "
|
|
||||||
"(copied from private key auth_id)\n");
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (r == -1) /* User pin ref not yet set */
|
if (r == -1) /* User pin ref not yet set */
|
||||||
set_user_pin_from_authid(p15card, profile, NULL);
|
set_user_pin_from_authid(p15card, profile, NULL);
|
||||||
|
@ -1676,7 +1667,7 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
||||||
|
|
||||||
object = sc_pkcs15init_new_object(SC_PKCS15_TYPE_CERT_X509, label, NULL, NULL);
|
object = sc_pkcs15init_new_object(SC_PKCS15_TYPE_CERT_X509, label, NULL, NULL);
|
||||||
if (object == NULL)
|
if (object == NULL)
|
||||||
return SC_ERROR_OUT_OF_MEMORY;
|
SC_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Failed to allocate certificate object");
|
||||||
cert_info = (sc_pkcs15_cert_info_t *) object->data;
|
cert_info = (sc_pkcs15_cert_info_t *) object->data;
|
||||||
cert_info->id = args->id;
|
cert_info->id = args->id;
|
||||||
cert_info->authority = args->authority;
|
cert_info->authority = args->authority;
|
||||||
|
@ -1711,7 +1702,7 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
|
||||||
|
|
||||||
profile->dirty = 1;
|
profile->dirty = 1;
|
||||||
|
|
||||||
return r;
|
SC_FUNC_RETURN(ctx, 3, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1801,9 +1792,10 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card,
|
||||||
static int
|
static int
|
||||||
sc_pkcs15init_store_data(struct sc_pkcs15_card *p15card,
|
sc_pkcs15init_store_data(struct sc_pkcs15_card *p15card,
|
||||||
struct sc_profile *profile,
|
struct sc_profile *profile,
|
||||||
sc_pkcs15_object_t *object, sc_pkcs15_id_t *id,
|
struct sc_pkcs15_object *object,
|
||||||
sc_pkcs15_der_t *data,
|
struct sc_pkcs15_id *id,
|
||||||
sc_path_t *path)
|
struct sc_pkcs15_der *data,
|
||||||
|
struct sc_path *path)
|
||||||
{
|
{
|
||||||
struct sc_context *ctx = p15card->card->ctx;
|
struct sc_context *ctx = p15card->card->ctx;
|
||||||
struct sc_file *file = NULL;
|
struct sc_file *file = NULL;
|
||||||
|
@ -2423,6 +2415,14 @@ select_object_path(sc_pkcs15_card_t *p15card, sc_profile_t *profile,
|
||||||
for (indx = TEMPLATE_INSTANTIATE_MIN_INDEX; indx <= TEMPLATE_INSTANTIATE_MAX_INDEX; indx++) {
|
for (indx = TEMPLATE_INSTANTIATE_MIN_INDEX; indx <= TEMPLATE_INSTANTIATE_MAX_INDEX; indx++) {
|
||||||
indx_id.value[0] = indx;
|
indx_id.value[0] = indx;
|
||||||
r = sc_profile_instantiate_template(profile, "key-domain", path, name, &indx_id, &file);
|
r = sc_profile_instantiate_template(profile, "key-domain", path, name, &indx_id, &file);
|
||||||
|
if (r == SC_ERROR_TEMPLATE_NOT_FOUND) {
|
||||||
|
/* No template in 'key-domain' -- try to instantiate the template
|
||||||
|
* outside of the 'key-domain' scope. */
|
||||||
|
char t_name[0x40];
|
||||||
|
|
||||||
|
snprintf(t_name, sizeof(t_name), "template-%s", name);
|
||||||
|
r = sc_profile_get_file_instance(profile, t_name, indx, &file);
|
||||||
|
}
|
||||||
if (r == SC_ERROR_TEMPLATE_NOT_FOUND)
|
if (r == SC_ERROR_TEMPLATE_NOT_FOUND)
|
||||||
SC_FUNC_RETURN(ctx, 3, SC_SUCCESS);
|
SC_FUNC_RETURN(ctx, 3, SC_SUCCESS);
|
||||||
SC_TEST_RET(ctx, r, "Template instantiation error");
|
SC_TEST_RET(ctx, r, "Template instantiation error");
|
||||||
|
|
|
@ -433,6 +433,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_card *card,
|
||||||
SC_FUNC_RETURN(card->ctx, 1, rv);
|
SC_FUNC_RETURN(card->ctx, 1, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Update PIN
|
* Update PIN
|
||||||
*/
|
*/
|
||||||
|
@ -629,60 +630,86 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RSA key generation
|
|
||||||
*/
|
|
||||||
static int
|
static int
|
||||||
cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card,
|
cosm_get_temporary_public_key_file(struct sc_card *card,
|
||||||
unsigned int idx, unsigned int keybits,
|
struct sc_file *prvkey_file, struct sc_file **pubkey_file)
|
||||||
struct sc_pkcs15_pubkey *pubkey,
|
|
||||||
struct sc_pkcs15_prkey_info *info)
|
|
||||||
{
|
{
|
||||||
struct sc_cardctl_oberthur_genkey_info args;
|
struct sc_context *ctx = card->ctx;
|
||||||
struct sc_file *prkf = NULL, *tmpf = NULL;
|
const struct sc_acl_entry *entry = NULL;
|
||||||
struct sc_path path;
|
struct sc_file *file = NULL;
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
SC_FUNC_CALLED(card->ctx, 1);
|
SC_FUNC_CALLED(card->ctx, 1);
|
||||||
sc_debug(card->ctx, "cosm_generate_key() index %i; nn %i\n", idx, keybits);
|
if (!pubkey_file || !prvkey_file)
|
||||||
if (keybits < 512 || keybits > 2048 || (keybits%0x20)) {
|
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
|
||||||
sc_debug(card->ctx, "Unsupported key size %u\n", keybits);
|
|
||||||
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get private key file from profile. */
|
file = sc_file_new();
|
||||||
rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &prkf);
|
if (!file)
|
||||||
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() cannot allocate new file SC_PKCS15_TYPE_PRKEY_RSA");
|
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY);
|
||||||
prkf->size = keybits;
|
|
||||||
|
|
||||||
/* Access condition of private object DF. */
|
file->status = SC_FILE_STATUS_ACTIVATED;
|
||||||
path = prkf->path;
|
file->type = SC_FILE_TYPE_INTERNAL_EF;
|
||||||
|
file->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
|
||||||
|
file->id = 0x1012;
|
||||||
|
memcpy(&file->path, &prvkey_file->path, sizeof(file->path));
|
||||||
|
file->path.value[file->path.len - 2] = 0x10;
|
||||||
|
file->path.value[file->path.len - 1] = 0x12;
|
||||||
|
file->size = prvkey_file->size;
|
||||||
|
|
||||||
|
entry = sc_file_get_acl_entry(prvkey_file, SC_AC_OP_UPDATE);
|
||||||
|
rv = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, entry->method, entry->key_ref);
|
||||||
|
if (!rv)
|
||||||
|
rv = sc_file_add_acl_entry(file, SC_AC_OP_PSO_ENCRYPT, SC_AC_NONE, 0);
|
||||||
|
if (!rv)
|
||||||
|
rv = sc_file_add_acl_entry(file, SC_AC_OP_PSO_VERIFY_SIGNATURE, SC_AC_NONE, 0);
|
||||||
|
if (!rv)
|
||||||
|
rv = sc_file_add_acl_entry(file, SC_AC_OP_EXTERNAL_AUTHENTICATE, SC_AC_NONE, 0);
|
||||||
|
SC_TEST_RET(ctx, rv, "Failed to add ACL entry to the temporary public key file");
|
||||||
|
|
||||||
|
*pubkey_file = file;
|
||||||
|
|
||||||
|
SC_FUNC_RETURN(card->ctx, 1, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
cosm_generate_key(struct sc_profile *profile, struct sc_card *card,
|
||||||
|
struct sc_pkcs15_object *object,
|
||||||
|
struct sc_pkcs15_pubkey *pubkey)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
|
||||||
|
struct sc_file *file = NULL;
|
||||||
|
struct sc_cardctl_oberthur_genkey_info args;
|
||||||
|
struct sc_file *prkf = NULL, *tmpf = NULL;
|
||||||
|
struct sc_path path;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
SC_FUNC_CALLED(card->ctx, 1);
|
||||||
|
|
||||||
|
if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
|
||||||
|
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Generate key failed: RSA only supported");
|
||||||
|
|
||||||
|
path = key_info->path;
|
||||||
path.len -= 2;
|
path.len -= 2;
|
||||||
|
|
||||||
rv = sc_select_file(card, &path, &tmpf);
|
rv = sc_select_file(card, &path, &tmpf);
|
||||||
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() no private object DF");
|
SC_TEST_RET(card->ctx, rv, "Cannot generate key: failed to select private object DF");
|
||||||
|
|
||||||
rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CRYPTO);
|
rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CRYPTO);
|
||||||
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed");
|
SC_TEST_RET(card->ctx, rv, "Cannot generate key: 'CRYPTO' authentication failed");
|
||||||
|
|
||||||
rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CREATE);
|
rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CREATE);
|
||||||
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() pkcs15init_authenticate(SC_AC_OP_CREATE) failed");
|
SC_TEST_RET(card->ctx, rv, "Cannot generate key: 'CREATE' authentication failed");
|
||||||
|
|
||||||
sc_file_free(tmpf);
|
sc_file_free(tmpf);
|
||||||
|
|
||||||
/* In the private key DF create the temporary public RSA file. */
|
rv = sc_select_file(card, &key_info->path, &prkf);
|
||||||
sc_debug(card->ctx, "cosm_generate_key() ready to create temporary public key\n");
|
SC_TEST_RET(card->ctx, rv, "Failed to generate key: cannot select private key file");
|
||||||
sc_file_dup(&tmpf, prkf);
|
|
||||||
if (!tmpf)
|
|
||||||
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot duplicate private key file");
|
|
||||||
tmpf->type = SC_FILE_TYPE_INTERNAL_EF;
|
|
||||||
tmpf->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC;
|
|
||||||
tmpf->id = 0x1012;
|
|
||||||
tmpf->path.value[tmpf->path.len - 2] = 0x10;
|
|
||||||
tmpf->path.value[tmpf->path.len - 1] = 0x12;
|
|
||||||
|
|
||||||
rv = sc_pkcs15init_create_file(profile, card, prkf);
|
/* In the private key DF create the temporary public RSA file. */
|
||||||
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create private key EF");
|
rv = cosm_get_temporary_public_key_file(card, prkf, &tmpf);
|
||||||
|
SC_TEST_RET(card->ctx, rv, "Error while getting temporary public key file");
|
||||||
|
|
||||||
rv = sc_pkcs15init_create_file(profile, card, tmpf);
|
rv = sc_pkcs15init_create_file(profile, card, tmpf);
|
||||||
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create temporary public key EF");
|
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create temporary public key EF");
|
||||||
|
@ -691,9 +718,9 @@ cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card,
|
||||||
args.id_prv = prkf->id;
|
args.id_prv = prkf->id;
|
||||||
args.id_pub = tmpf->id;
|
args.id_pub = tmpf->id;
|
||||||
args.exponent = 0x10001;
|
args.exponent = 0x10001;
|
||||||
args.key_bits = keybits;
|
args.key_bits = key_info->modulus_length;
|
||||||
args.pubkey_len = keybits/8;
|
args.pubkey_len = key_info->modulus_length / 8;
|
||||||
args.pubkey = (unsigned char *) malloc(keybits/8);
|
args.pubkey = (unsigned char *) malloc(key_info->modulus_length / 8);
|
||||||
if (!args.pubkey)
|
if (!args.pubkey)
|
||||||
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey");
|
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey");
|
||||||
|
|
||||||
|
@ -702,8 +729,8 @@ cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card,
|
||||||
|
|
||||||
/* extract public key */
|
/* extract public key */
|
||||||
pubkey->algorithm = SC_ALGORITHM_RSA;
|
pubkey->algorithm = SC_ALGORITHM_RSA;
|
||||||
pubkey->u.rsa.modulus.len = keybits / 8;
|
pubkey->u.rsa.modulus.len = key_info->modulus_length / 8;
|
||||||
pubkey->u.rsa.modulus.data = (unsigned char *) malloc(keybits / 8);
|
pubkey->u.rsa.modulus.data = (unsigned char *) malloc(key_info->modulus_length / 8);
|
||||||
if (!pubkey->u.rsa.modulus.data)
|
if (!pubkey->u.rsa.modulus.data)
|
||||||
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf");
|
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf");
|
||||||
|
|
||||||
|
@ -715,95 +742,112 @@ cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card,
|
||||||
memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3);
|
memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3);
|
||||||
memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len);
|
memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len);
|
||||||
|
|
||||||
info->key_reference = 1;
|
key_info->key_reference = 1;
|
||||||
info->path = prkf->path;
|
key_info->path = prkf->path;
|
||||||
|
|
||||||
sc_debug(card->ctx, "cosm_generate_key() now delete temporary public key\n");
|
sc_debug(card->ctx, "cosm_generate_key() now delete temporary public key\n");
|
||||||
rv = cosm_delete_file(card, profile, tmpf);
|
rv = cosm_delete_file(card, profile, tmpf);
|
||||||
|
|
||||||
if (tmpf)
|
|
||||||
sc_file_free(tmpf);
|
sc_file_free(tmpf);
|
||||||
if (prkf)
|
|
||||||
sc_file_free(prkf);
|
sc_file_free(prkf);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, 1, rv);
|
SC_FUNC_RETURN(card->ctx, 1, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create private key file
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cosm_create_key(struct sc_profile *profile, struct sc_card *card,
|
||||||
|
struct sc_pkcs15_object *object)
|
||||||
|
{
|
||||||
|
struct sc_context *ctx = card->ctx;
|
||||||
|
struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
|
||||||
|
struct sc_file *file = NULL;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
SC_FUNC_CALLED(ctx, 1);
|
||||||
|
if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
|
||||||
|
SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Create key failed: RSA only supported");
|
||||||
|
|
||||||
|
sc_debug(ctx, "create private key ID:%s\n", sc_pkcs15_print_id(&key_info->id));
|
||||||
|
/* Here, the path of private key file should be defined.
|
||||||
|
* Neverthelles, we need to instanciate private key to get the ACLs. */
|
||||||
|
rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file);
|
||||||
|
SC_TEST_RET(ctx, rv, "Cannot create key: failed to allocate new key object");
|
||||||
|
|
||||||
|
file->size = key_info->modulus_length;
|
||||||
|
memcpy(&file->path, &key_info->path, sizeof(file->path));
|
||||||
|
file->id = file->path.value[file->path.len - 2] * 0x100
|
||||||
|
+ file->path.value[file->path.len - 1];
|
||||||
|
|
||||||
|
sc_debug(ctx, "Path of private key file to create %s\n", sc_print_path(&file->path));
|
||||||
|
|
||||||
|
rv = sc_select_file(card, &file->path, NULL);
|
||||||
|
if (rv == 0) {
|
||||||
|
rv = cosm_delete_file(card, profile, file);
|
||||||
|
SC_TEST_RET(ctx, rv, "Failed to delete private key file");
|
||||||
|
}
|
||||||
|
else if (rv != SC_ERROR_FILE_NOT_FOUND) {
|
||||||
|
SC_TEST_RET(ctx, rv, "Select private key file error");
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = sc_pkcs15init_create_file(profile, card, file);
|
||||||
|
SC_TEST_RET(ctx, rv, "Failed to create private key file");
|
||||||
|
|
||||||
|
key_info->key_reference = file->path.value[file->path.len - 1];
|
||||||
|
|
||||||
|
sc_file_free(file);
|
||||||
|
|
||||||
|
SC_FUNC_RETURN(ctx, 1, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store a private key
|
* Store a private key
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
cosm_new_key(struct sc_profile *profile, struct sc_card *card,
|
cosm_store_key(struct sc_profile *profile, struct sc_card *card,
|
||||||
struct sc_pkcs15_prkey *key, unsigned int idx,
|
struct sc_pkcs15_object *object,
|
||||||
struct sc_pkcs15_prkey_info *info)
|
struct sc_pkcs15_prkey *prkey)
|
||||||
{
|
{
|
||||||
struct sc_file *prvfile = NULL;
|
struct sc_context *ctx = card->ctx;
|
||||||
struct sc_pkcs15_prkey_rsa *rsa = NULL;
|
struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
|
||||||
|
struct sc_file *file = NULL;
|
||||||
struct sc_cardctl_oberthur_updatekey_info update_info;
|
struct sc_cardctl_oberthur_updatekey_info update_info;
|
||||||
char pbuf[SC_MAX_PATH_STRING_SIZE];
|
int rv = 0;
|
||||||
int rv;
|
|
||||||
|
|
||||||
SC_FUNC_CALLED(card->ctx, 1);
|
SC_FUNC_CALLED(ctx, 1);
|
||||||
sc_debug(card->ctx, "index %i; id %s\n", idx, sc_pkcs15_print_id(&info->id));
|
if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || prkey->algorithm != SC_ALGORITHM_RSA)
|
||||||
if (key->algorithm != SC_ALGORITHM_RSA)
|
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");
|
||||||
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
|
|
||||||
|
|
||||||
/* Create and populate the private part. */
|
sc_debug(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id),
|
||||||
rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx,
|
sc_print_path(&key_info->path));
|
||||||
&prvfile);
|
|
||||||
SC_TEST_RET(card->ctx, rv, "Update RSA: cosm_new_file failed");
|
|
||||||
|
|
||||||
rv = sc_path_print(pbuf, sizeof(pbuf), &prvfile->path);
|
rv = sc_select_file(card, &key_info->path, &file);
|
||||||
sc_debug(card->ctx, "rv %i\n", rv);
|
SC_TEST_RET(ctx, rv, "Cannot store key: select key file failed");
|
||||||
if (rv != SC_SUCCESS)
|
|
||||||
pbuf[0] = '\0';
|
|
||||||
sc_debug(card->ctx, " prvfile->id %i; path=%s\n", prvfile->id, pbuf);
|
|
||||||
|
|
||||||
rsa = &key->u.rsa;
|
rv = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_UPDATE);
|
||||||
|
SC_TEST_RET(ctx, rv, "No authorisation to store private key");
|
||||||
|
|
||||||
prvfile->size = rsa->modulus.len << 3;
|
if (key_info->id.len > sizeof(update_info.id))
|
||||||
|
|
||||||
rv = sc_select_file(card, &prvfile->path, NULL);
|
|
||||||
sc_debug(card->ctx, "rv %i", rv);
|
|
||||||
if (rv == SC_ERROR_FILE_NOT_FOUND) {
|
|
||||||
sc_debug(card->ctx, "Before create file");
|
|
||||||
rv = sc_pkcs15init_create_file(profile, card, prvfile);
|
|
||||||
}
|
|
||||||
SC_TEST_RET(card->ctx, rv, "Update RSA: select/create key file failed");
|
|
||||||
|
|
||||||
rv = sc_pkcs15init_authenticate(profile, card, prvfile, SC_AC_OP_UPDATE);
|
|
||||||
SC_TEST_RET(card->ctx, rv, "Update RSA: no authorisation");
|
|
||||||
|
|
||||||
#ifdef ENABLE_OPENSSL
|
|
||||||
/* Mozilla style ID */
|
|
||||||
if (!info->id.len) {
|
|
||||||
SHA1(rsa->modulus.data, rsa->modulus.len, info->id.value);
|
|
||||||
info->id.len = SHA_DIGEST_LENGTH;
|
|
||||||
sc_debug(card->ctx, "ID: %s\n", sc_pkcs15_print_id(&info->id));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (info->id.len > sizeof(update_info.id))
|
|
||||||
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
|
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
|
||||||
|
|
||||||
memset(&update_info, 0, sizeof(update_info));
|
memset(&update_info, 0, sizeof(update_info));
|
||||||
update_info.type = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT;
|
update_info.type = SC_CARDCTL_OBERTHUR_KEY_RSA_CRT;
|
||||||
update_info.data = (void *)rsa;
|
update_info.data = (void *)&prkey->u.rsa;
|
||||||
update_info.data_len = sizeof(void *);
|
update_info.data_len = sizeof(void *);
|
||||||
update_info.id_len = info->id.len;
|
update_info.id_len = key_info->id.len;
|
||||||
memcpy(update_info.id, info->id.value, update_info.id_len);
|
memcpy(update_info.id, key_info->id.value, update_info.id_len);
|
||||||
|
|
||||||
rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_UPDATE_KEY, &update_info);
|
rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_UPDATE_KEY, &update_info);
|
||||||
SC_TEST_RET(card->ctx, rv, "Update KEY failed");
|
SC_TEST_RET(ctx, rv, "Cannot update private key");
|
||||||
|
|
||||||
info->path = prvfile->path;
|
if (file)
|
||||||
info->modulus_length = rsa->modulus.len << 3;
|
sc_file_free(file);
|
||||||
|
|
||||||
if (prvfile)
|
SC_FUNC_RETURN(ctx, 1, rv);
|
||||||
sc_file_free(prvfile);
|
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, 1, rv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -816,17 +860,17 @@ sc_pkcs15init_oberthur_operations = {
|
||||||
cosm_select_pin_reference,
|
cosm_select_pin_reference,
|
||||||
cosm_create_pin,
|
cosm_create_pin,
|
||||||
NULL, /* select_key_reference */
|
NULL, /* select_key_reference */
|
||||||
NULL, /* create_key */
|
cosm_create_key, /* create_key */
|
||||||
NULL, /* store_key */
|
cosm_store_key, /* store_key */
|
||||||
NULL, /* generate_key */
|
cosm_generate_key, /* generate_key */
|
||||||
NULL,
|
NULL,
|
||||||
NULL, /* encode private/public key */
|
NULL, /* encode private/public key */
|
||||||
NULL, /* finalize_card */
|
NULL, /* finalize_card */
|
||||||
cosm_init_app, /* old */
|
cosm_init_app, /* old */
|
||||||
NULL, /* new_pin */
|
NULL, /* new_pin */
|
||||||
cosm_new_key,
|
NULL, /* cosm_new_key, */
|
||||||
cosm_new_file,
|
NULL, /* cosm_new_file, */
|
||||||
cosm_old_generate_key,
|
NULL, /* cosm_old_generate_key, */
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue