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:
viktor.tarasov 2010-01-25 16:42:22 +00:00
parent 986309db79
commit bc140126e9
2 changed files with 225 additions and 181 deletions

View File

@ -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);
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 */
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);
}
/*
* Generate a new private key
*/
@ -1244,42 +1245,41 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
unsigned int keybits,
struct sc_pkcs15_object **res_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15init_pubkeyargs pubkey_args;
struct sc_pkcs15_object *object;
struct sc_pkcs15_prkey_info *key_info;
int r, caller_supplied_id = 0;
SC_FUNC_CALLED(ctx, 3);
/* check supported key size */
r = check_key_size(p15card->card, keygen_args->prkey_args.key.algorithm, keybits);
if (r != SC_SUCCESS)
return r;
SC_TEST_RET(ctx, r, "Invalid key size");
/* For now, we support just RSA and GOST key pair generation */
if (!check_key_compatibility(p15card, &keygen_args->prkey_args.key,
keygen_args->prkey_args.x509_usage,
keybits, SC_ALGORITHM_ONBOARD_KEY_GEN))
return SC_ERROR_NOT_SUPPORTED;
keygen_args->prkey_args.x509_usage,
keybits, SC_ALGORITHM_ONBOARD_KEY_GEN))
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)
return SC_ERROR_NOT_SUPPORTED;
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key generation not supported");
/* Set the USER PIN reference from args */
r = set_user_pin_from_authid(p15card, profile,
&keygen_args->prkey_args.auth_id);
if (r < 0)
return r;
r = set_user_pin_from_authid(p15card, profile, &keygen_args->prkey_args.auth_id);
SC_TEST_RET(ctx, r, "Cannot set User PIN from auth. ID");
/* Set the SO PIN reference from card */
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
return r;
r = set_so_pin_from_card(p15card, profile);
SC_TEST_RET(ctx, r, "Cannot set SO PIN from card");
caller_supplied_id = keygen_args->prkey_args.id.len != 0;
/* Set up the PrKDF object */
r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args,
&keygen_args->prkey_args.key, keybits, &object);
if (r < 0)
return r;
SC_TEST_RET(ctx, r, "Set up private key object error");
key_info = (struct sc_pkcs15_prkey_info *) object->data;
/* Set up the PuKDF info. The public key will be filled in
@ -1298,57 +1298,49 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card,
if (profile->ops->create_key) {
/* New API */
r = profile->ops->create_key(profile, p15card->card, object);
if (r < 0)
return r;
SC_TEST_RET(ctx, r, "Cannot generate key: create key failed");
r = profile->ops->generate_key(profile, p15card->card,
object, &pubkey_args.key);
if (r < 0)
return r;
r = profile->ops->generate_key(profile, p15card->card, object, &pubkey_args.key);
SC_TEST_RET(ctx, r, "Failed to generate key");
} else {
int idx;
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);
SC_TEST_RET(ctx, r, "Failed to generate key in an old manner");
}
/* update PrKDF entry */
if (r >= 0) {
if (!caller_supplied_id) {
struct sc_pkcs15_id iid;
if (!caller_supplied_id) {
struct sc_pkcs15_id iid;
/* Caller not supplied ID, so,
* if intrinsic ID can be calculated -- overwrite the native one */
memset(&iid, 0, sizeof(iid));
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key);
if (r < 0)
return r;
/* Caller not supplied ID, so,
* if intrinsic ID can be calculated -- overwrite the native one */
memset(&iid, 0, sizeof(iid));
r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key);
SC_TEST_RET(ctx, r, "Select intrinsic ID error");
if (iid.len) {
key_info->id = iid;
pubkey_args.id = iid;
}
if (iid.len) {
key_info->id = iid;
pubkey_args.id = iid;
}
r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object);
}
if (r >= 0) {
sc_pkcs15_object_t *pub_object;
r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object);
SC_TEST_RET(ctx, r, "Failed to add generated private key object");
r = sc_pkcs15init_store_public_key(p15card, profile,
&pubkey_args, &pub_object);
}
r = sc_pkcs15init_store_public_key(p15card, profile, &pubkey_args, NULL);
SC_TEST_RET(ctx, r, "Failed to store public key");
if (r >= 0 && res_obj)
if (res_obj)
*res_obj = object;
sc_pkcs15_erase_pubkey(&pubkey_args.key);
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
*
* TODO: set public key reference
*/
int
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;
SC_FUNC_CALLED(ctx, 3);
if (!res_obj || !keyargs)
if (!keyargs)
SC_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Store public key aborted");
/* 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_pkcs15_object **res_obj)
{
struct sc_context *ctx = p15card->card->ctx;
struct sc_pkcs15_cert_info *cert_info;
struct sc_pkcs15_object *object;
unsigned int usage;
const char *label;
int r;
SC_FUNC_CALLED(ctx, 3);
usage = SC_PKCS15_PRKEY_USAGE_SIGN;
if (args->x509_usage)
usage = sc_pkcs15init_map_usage(args->x509_usage, 0);
@ -1642,17 +1638,16 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
label = "Certificate";
/* Set the SO PIN reference from card */
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
return r;
r = set_so_pin_from_card(p15card, profile);
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);
if (r < 0)
return r;
SC_TEST_RET(ctx, r, "Get certificate 'intrinsic ID' error");
/* Select an ID if the user didn't specify one, otherwise
* make sure it's unique */
if ((r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id)) < 0)
return r;
r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id);
SC_TEST_RET(ctx, r, "Select certificate ID error");
if (profile->protect_certificates) {
/* 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
&& sc_pkcs15_find_prkey_by_id(p15card, &args->id, &object) == 0) {
r = set_user_pin_from_authid(p15card, profile, &object->auth_id);
if (r < 0) {
sc_debug(p15card->card->ctx,
"Failed to assign user pin reference "
"(copied from private key auth_id)\n");
return r;
}
SC_TEST_RET(ctx, r, "Failed to assign user pin reference "
"(copied from private key auth_id)");
}
if (r == -1) /* User pin ref not yet set */
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);
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->id = args->id;
cert_info->authority = args->authority;
@ -1711,7 +1702,7 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card,
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
sc_pkcs15init_store_data(struct sc_pkcs15_card *p15card,
struct sc_profile *profile,
sc_pkcs15_object_t *object, sc_pkcs15_id_t *id,
sc_pkcs15_der_t *data,
sc_path_t *path)
struct sc_pkcs15_object *object,
struct sc_pkcs15_id *id,
struct sc_pkcs15_der *data,
struct sc_path *path)
{
struct sc_context *ctx = p15card->card->ctx;
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++) {
indx_id.value[0] = indx;
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)
SC_FUNC_RETURN(ctx, 3, SC_SUCCESS);
SC_TEST_RET(ctx, r, "Template instantiation error");

View File

@ -433,6 +433,7 @@ cosm_create_reference_data(struct sc_profile *profile, struct sc_card *card,
SC_FUNC_RETURN(card->ctx, 1, rv);
}
/*
* Update PIN
*/
@ -629,61 +630,87 @@ cosm_new_file(struct sc_profile *profile, struct sc_card *card,
}
/*
* RSA key generation
*/
static int
cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card,
unsigned int idx, unsigned int keybits,
struct sc_pkcs15_pubkey *pubkey,
struct sc_pkcs15_prkey_info *info)
cosm_get_temporary_public_key_file(struct sc_card *card,
struct sc_file *prvkey_file, struct sc_file **pubkey_file)
{
struct sc_cardctl_oberthur_genkey_info args;
struct sc_file *prkf = NULL, *tmpf = NULL;
struct sc_path path;
int rv;
struct sc_context *ctx = card->ctx;
const struct sc_acl_entry *entry = NULL;
struct sc_file *file = NULL;
int rv;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "cosm_generate_key() index %i; nn %i\n", idx, keybits);
if (keybits < 512 || keybits > 2048 || (keybits%0x20)) {
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. */
rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &prkf);
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() cannot allocate new file SC_PKCS15_TYPE_PRKEY_RSA");
prkf->size = keybits;
/* Access condition of private object DF. */
path = prkf->path;
if (!pubkey_file || !prvkey_file)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
file = sc_file_new();
if (!file)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY);
file->status = SC_FILE_STATUS_ACTIVATED;
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;
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);
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);
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);
rv = sc_select_file(card, &key_info->path, &prkf);
SC_TEST_RET(card->ctx, rv, "Failed to generate key: cannot select private key file");
/* In the private key DF create the temporary public RSA file. */
sc_debug(card->ctx, "cosm_generate_key() ready to create temporary public key\n");
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 = 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, prkf);
SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create private key EF");
rv = sc_pkcs15init_create_file(profile, card, tmpf);
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_pub = tmpf->id;
args.exponent = 0x10001;
args.key_bits = keybits;
args.pubkey_len = keybits/8;
args.pubkey = (unsigned char *) malloc(keybits/8);
args.key_bits = key_info->modulus_length;
args.pubkey_len = key_info->modulus_length / 8;
args.pubkey = (unsigned char *) malloc(key_info->modulus_length / 8);
if (!args.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 */
pubkey->algorithm = SC_ALGORITHM_RSA;
pubkey->u.rsa.modulus.len = keybits / 8;
pubkey->u.rsa.modulus.data = (unsigned char *) malloc(keybits / 8);
pubkey->u.rsa.modulus.len = key_info->modulus_length / 8;
pubkey->u.rsa.modulus.data = (unsigned char *) malloc(key_info->modulus_length / 8);
if (!pubkey->u.rsa.modulus.data)
SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf");
@ -715,118 +742,135 @@ 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.modulus.data, args.pubkey, args.pubkey_len);
info->key_reference = 1;
info->path = prkf->path;
key_info->key_reference = 1;
key_info->path = prkf->path;
sc_debug(card->ctx, "cosm_generate_key() now delete temporary public key\n");
rv = cosm_delete_file(card, profile, tmpf);
if (tmpf)
sc_file_free(tmpf);
if (prkf)
sc_file_free(prkf);
sc_file_free(tmpf);
sc_file_free(prkf);
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
*/
static int
cosm_new_key(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_prkey *key, unsigned int idx,
struct sc_pkcs15_prkey_info *info)
cosm_store_key(struct sc_profile *profile, struct sc_card *card,
struct sc_pkcs15_object *object,
struct sc_pkcs15_prkey *prkey)
{
struct sc_file *prvfile = NULL;
struct sc_pkcs15_prkey_rsa *rsa = NULL;
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_updatekey_info update_info;
char pbuf[SC_MAX_PATH_STRING_SIZE];
int rv;
int rv = 0;
SC_FUNC_CALLED(card->ctx, 1);
sc_debug(card->ctx, "index %i; id %s\n", idx, sc_pkcs15_print_id(&info->id));
if (key->algorithm != SC_ALGORITHM_RSA)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
SC_FUNC_CALLED(ctx, 1);
if (object->type != SC_PKCS15_TYPE_PRKEY_RSA || prkey->algorithm != SC_ALGORITHM_RSA)
SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");
/* Create and populate the private part. */
rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx,
&prvfile);
SC_TEST_RET(card->ctx, rv, "Update RSA: cosm_new_file failed");
sc_debug(ctx, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id),
sc_print_path(&key_info->path));
rv = sc_select_file(card, &key_info->path, &file);
SC_TEST_RET(ctx, rv, "Cannot store key: select key file failed");
rv = sc_path_print(pbuf, sizeof(pbuf), &prvfile->path);
sc_debug(card->ctx, "rv %i\n", rv);
if (rv != SC_SUCCESS)
pbuf[0] = '\0';
sc_debug(card->ctx, " prvfile->id %i; path=%s\n", prvfile->id, pbuf);
rv = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_UPDATE);
SC_TEST_RET(ctx, rv, "No authorisation to store private key");
rsa = &key->u.rsa;
prvfile->size = rsa->modulus.len << 3;
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))
if (key_info->id.len > sizeof(update_info.id))
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
memset(&update_info, 0, sizeof(update_info));
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.id_len = info->id.len;
memcpy(update_info.id, info->id.value, update_info.id_len);
update_info.id_len = key_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);
SC_TEST_RET(card->ctx, rv, "Update KEY failed");
SC_TEST_RET(ctx, rv, "Cannot update private key");
info->path = prvfile->path;
info->modulus_length = rsa->modulus.len << 3;
if (file)
sc_file_free(file);
if (prvfile)
sc_file_free(prvfile);
SC_FUNC_RETURN(card->ctx, 1, rv);
SC_FUNC_RETURN(ctx, 1, rv);
}
static struct sc_pkcs15init_operations
sc_pkcs15init_oberthur_operations = {
cosm_erase_card,
NULL, /* init_card */
NULL, /* create_dir */
NULL, /* create_domain */
NULL, /* init_card */
NULL, /* create_dir */
NULL, /* create_domain */
cosm_select_pin_reference,
cosm_create_pin,
NULL, /* select_key_reference */
NULL, /* create_key */
NULL, /* store_key */
NULL, /* generate_key */
NULL, /* select_key_reference */
cosm_create_key, /* create_key */
cosm_store_key, /* store_key */
cosm_generate_key, /* generate_key */
NULL,
NULL, /* encode private/public key */
NULL, /* finalize_card */
cosm_init_app, /* old */
NULL, /* new_pin */
cosm_new_key,
cosm_new_file,
cosm_old_generate_key,
NULL, /* encode private/public key */
NULL, /* finalize_card */
cosm_init_app, /* old */
NULL, /* new_pin */
NULL, /* cosm_new_key, */
NULL, /* cosm_new_file, */
NULL, /* cosm_old_generate_key, */
NULL
};