Added support for deleting pkcs15 objects, each card driver should implement its delete_object() operation in order to support it
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2506 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
b9efe849eb
commit
b5e2a2afff
|
@ -886,7 +886,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_cyberflex_operations = {
|
|||
cyberflex_encode_private_key,
|
||||
cyberflex_encode_public_key,
|
||||
NULL, /* finalize_card */
|
||||
NULL, NULL, NULL, NULL, NULL /* old style api */
|
||||
NULL, NULL, NULL, NULL, NULL, /* old style api */
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *
|
||||
|
|
|
@ -624,7 +624,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_etoken_operations = {
|
|||
etoken_generate_key,
|
||||
NULL, NULL, /* encode private/public key */
|
||||
NULL, /* finalize_card */
|
||||
NULL, NULL, NULL, NULL, NULL /* old style api */
|
||||
NULL, NULL, NULL, NULL, NULL, /* old style api */
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *
|
||||
|
|
|
@ -1131,7 +1131,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_gpk_operations = {
|
|||
gpk_generate_key,
|
||||
NULL, NULL, /* encode private/public key */
|
||||
NULL, /* finalize_card */
|
||||
NULL, NULL, NULL, NULL, NULL /* old style api */
|
||||
NULL, NULL, NULL, NULL, NULL, /* old style api */
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *sc_pkcs15init_get_gpk_ops(void)
|
||||
|
|
|
@ -159,6 +159,11 @@ struct sc_pkcs15init_operations {
|
|||
sc_pkcs15_pubkey_t *pubkey_res,
|
||||
struct sc_pkcs15_prkey_info *);
|
||||
|
||||
/*
|
||||
* Delete object
|
||||
*/
|
||||
int (*delete_object)(struct sc_profile *, struct sc_card *,
|
||||
unsigned int type, const void *data, const sc_path_t *path);
|
||||
};
|
||||
|
||||
/* Do not change these or reorder these */
|
||||
|
@ -317,6 +322,9 @@ extern int sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card,
|
|||
int new_attrib_type,
|
||||
void *new_value,
|
||||
int new_len);
|
||||
extern int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
|
||||
sc_profile_t *profile,
|
||||
sc_pkcs15_object_t *obj);
|
||||
|
||||
extern int sc_pkcs15init_create_file(struct sc_profile *,
|
||||
struct sc_card *, struct sc_file *);
|
||||
|
@ -344,6 +352,8 @@ extern int sc_pkcs15init_set_pin_data(struct sc_profile *, int,
|
|||
const u8 *, size_t);
|
||||
extern int sc_pkcs15init_verify_key(struct sc_profile *, struct sc_card *,
|
||||
sc_file_t *, unsigned int, unsigned int);
|
||||
extern int sc_pkcs15init_delete_by_path(struct sc_profile *,
|
||||
struct sc_card *, const sc_path_t *path);
|
||||
|
||||
/* Erasing the card structure via rm -rf */
|
||||
extern int sc_pkcs15init_erase_card_recursively(struct sc_card *,
|
||||
|
|
|
@ -357,7 +357,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_jcop_operations = {
|
|||
NULL, NULL, /* encode private/public key */
|
||||
NULL, /* finalize_card */
|
||||
jcop_init_app, /* old */
|
||||
NULL, NULL, NULL, NULL /* rest of old style api */
|
||||
NULL, NULL, NULL, NULL, /* rest of old style api */
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *sc_pkcs15init_get_jcop_ops(void)
|
||||
|
|
|
@ -447,6 +447,48 @@ out: /* Forget any cached keys, the objects on card are all gone. */
|
|||
return r;
|
||||
}
|
||||
|
||||
int sc_pkcs15init_delete_by_path(struct sc_profile *profile,
|
||||
struct sc_card *card, const sc_path_t *file_path)
|
||||
{
|
||||
sc_file_t *parent, *file;
|
||||
sc_path_t path;
|
||||
int r;
|
||||
|
||||
if (file_path->len >= 2) {
|
||||
/* Select the parent DF */
|
||||
path = *file_path;
|
||||
path.len -= 2;
|
||||
r = sc_select_file(card, &path, &parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_DELETE);
|
||||
sc_file_free(parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Select the file itself */
|
||||
path = *file_path;
|
||||
r = sc_select_file(card, &path, &file);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sc_pkcs15init_authenticate(profile, card, file, SC_AC_OP_DELETE);
|
||||
sc_file_free(file);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
memset(&path, 0, sizeof(path));
|
||||
path.type = SC_PATH_TYPE_FILE_ID;
|
||||
path.value[0] = file_path->value[file_path->len - 2];
|
||||
path.value[1] = file_path->value[file_path->len - 1];
|
||||
path.len = 2;
|
||||
|
||||
r = sc_delete_file(card, &path);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to delete a file (and, in the DF case, its contents).
|
||||
* Note that this will not work if a pkcs#15 file's ERASE AC
|
||||
|
@ -505,11 +547,13 @@ sc_pkcs15init_rmdir(sc_card_t *card, struct sc_profile *profile,
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_DELETE);
|
||||
if (r < 0) {
|
||||
sc_file_free(parent);
|
||||
return r;
|
||||
}
|
||||
r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_DELETE);
|
||||
sc_file_free(parent);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = sc_pkcs15init_authenticate(profile, card, df, SC_AC_OP_ERASE);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -2478,6 +2522,57 @@ sc_pkcs15init_change_attrib(struct sc_pkcs15_card *p15card,
|
|||
return r < 0 ? r : 0;
|
||||
}
|
||||
|
||||
int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
|
||||
sc_profile_t *profile, sc_pkcs15_object_t *obj)
|
||||
{
|
||||
sc_path_t path;
|
||||
struct sc_pkcs15_df *df;
|
||||
int r;
|
||||
|
||||
if (profile->ops->delete_object == NULL)
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
|
||||
switch(obj->type & SC_PKCS15_TYPE_CLASS_MASK)
|
||||
{
|
||||
case SC_PKCS15_TYPE_PUBKEY:
|
||||
path = ((sc_pkcs15_pubkey_info_t *)obj->data)->path;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_PRKEY:
|
||||
path = ((sc_pkcs15_prkey_info_t *)obj->data)->path;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_CERT:
|
||||
path = ((sc_pkcs15_cert_info_t *)obj->data)->path;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_DATA_OBJECT:
|
||||
path = ((sc_pkcs15_data_info_t *)obj->data)->path;
|
||||
break;
|
||||
default:
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/* Set the SO PIN reference from card */
|
||||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
||||
return r;
|
||||
|
||||
r = profile->ops->delete_object(profile, p15card->card,
|
||||
obj->type, obj->data, &path);
|
||||
if (r < 0) {
|
||||
sc_error(p15card->card->ctx, "ops->delete_object() failed: %d", r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Get the DF we're part of. If there's no DF, fine, we haven't
|
||||
* been added yet. */
|
||||
if ((df = obj->df) == NULL)
|
||||
return 0;
|
||||
|
||||
/* Unlink the object and update the DF */
|
||||
sc_pkcs15_remove_object(p15card, obj);
|
||||
r = sc_pkcs15init_update_any_df(p15card, profile, df, 0);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* PIN verification
|
||||
*/
|
||||
|
|
|
@ -218,7 +218,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_miocos_operations = {
|
|||
miocos_new_pin,
|
||||
miocos_new_key,
|
||||
miocos_new_file,
|
||||
NULL /* old_generate_key */
|
||||
NULL, /* old_generate_key */
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *sc_pkcs15init_get_miocos_ops(void)
|
||||
|
|
|
@ -707,7 +707,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_oberthur_operations = {
|
|||
NULL, /* new_pin */
|
||||
cosm_new_key,
|
||||
cosm_new_file,
|
||||
cosm_old_generate_key
|
||||
cosm_old_generate_key,
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *
|
||||
|
|
|
@ -566,6 +566,13 @@ static int setcos_puk_retries(sc_profile_t *profile, int pin_ref)
|
|||
return pin_info.tries_left;
|
||||
}
|
||||
|
||||
static int setcos_delete_object(struct sc_profile *profile, struct sc_card *card,
|
||||
unsigned int type, const void *data, const sc_path_t *path)
|
||||
{
|
||||
/* For Setcos, all objects are files that can be deleted in any order */
|
||||
return sc_pkcs15init_delete_by_path(profile, card, path);
|
||||
}
|
||||
|
||||
static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = {
|
||||
setcos_erase_card,
|
||||
NULL, /* init_card */
|
||||
|
@ -584,7 +591,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_setcos_operations = {
|
|||
NULL, /* old style api */
|
||||
setcos_new_key,
|
||||
setcos_new_file,
|
||||
setcos_old_generate_key
|
||||
setcos_old_generate_key,
|
||||
setcos_delete_object
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *
|
||||
|
|
|
@ -926,7 +926,8 @@ static struct sc_pkcs15init_operations sc_pkcs15init_starcos_operations = {
|
|||
starcos_generate_key,
|
||||
NULL, NULL, /* encode private/public key */
|
||||
starcos_finalize_card,
|
||||
NULL, NULL, NULL, NULL, NULL /* old style api */
|
||||
NULL, NULL, NULL, NULL, NULL, /* old style api */
|
||||
NULL /* delete_object */
|
||||
};
|
||||
|
||||
struct sc_pkcs15init_operations *sc_pkcs15init_get_starcos_ops(void)
|
||||
|
|
Loading…
Reference in New Issue