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);
|
||||
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");
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue