Alessandro Premoli:
add support for reading, writing and deleting private (require cache_pins) and public data objects in PKCS11. updated the pkcs11-tool and fixed a few bugs in the code. Tested on an aladdin etoken. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3176 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
a4cd33e77f
commit
4cc1a50a49
|
@ -1286,6 +1286,88 @@ static CK_RV pkcs15_create_certificate(struct sc_pkcs11_card *p11card,
|
|||
out: return rv;
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_create_data(struct sc_pkcs11_card *p11card,
|
||||
struct sc_pkcs11_slot *slot,
|
||||
struct sc_profile *profile,
|
||||
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
|
||||
CK_OBJECT_HANDLE_PTR phObject)
|
||||
{
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
|
||||
struct sc_pkcs15init_dataargs args;
|
||||
struct pkcs15_any_object *data_any_obj;
|
||||
struct sc_pkcs15_object *data_obj;
|
||||
struct sc_pkcs15_pin_info *pin;
|
||||
CK_BBOOL bValue;
|
||||
int rc, rv;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.app_oid.value[0] = -1;
|
||||
|
||||
rv = CKR_OK;
|
||||
while (ulCount--) {
|
||||
CK_ATTRIBUTE_PTR attr = pTemplate++;
|
||||
|
||||
switch (attr->type) {
|
||||
/* Skip attrs we already know or don't care for */
|
||||
case CKA_CLASS:
|
||||
break;
|
||||
case CKA_PRIVATE:
|
||||
rv = attr_extract(attr, &bValue, NULL);
|
||||
if (bValue) {
|
||||
pin = slot_data_pin_info(slot->fw_data);
|
||||
if (pin == NULL) {
|
||||
rv = CKR_TEMPLATE_INCOMPLETE;
|
||||
goto out;
|
||||
}
|
||||
args.auth_id = pin->auth_id;
|
||||
}
|
||||
break;
|
||||
case CKA_LABEL:
|
||||
args.label = (char *) attr->pValue;
|
||||
break;
|
||||
case CKA_ID:
|
||||
args.id.len = sizeof(args.id.value);
|
||||
rv = attr_extract(attr, args.id.value, &args.id.len);
|
||||
if (rv != CKR_OK)
|
||||
goto out;
|
||||
break;
|
||||
case CKA_APPLICATION:
|
||||
args.app_label = (char *) attr->pValue;
|
||||
break;
|
||||
case CKA_OBJECT_ID:
|
||||
rv = attr_extract(attr, args.app_oid.value, NULL);
|
||||
if (rv != CKR_OK)
|
||||
goto out;
|
||||
break;
|
||||
case CKA_VALUE:
|
||||
args.der_encoded.len = attr->ulValueLen;
|
||||
args.der_encoded.value = (u8 *) attr->pValue;
|
||||
break;
|
||||
default:
|
||||
/* ignore unknown attrs, or flag error? */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (args.der_encoded.len == 0) {
|
||||
rv = CKR_TEMPLATE_INCOMPLETE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = sc_pkcs15init_store_data_object(fw_data->p15_card, profile, &args, &data_obj);
|
||||
if (rc < 0) {
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
goto out;
|
||||
}
|
||||
/* Create a new pkcs11 object for it */
|
||||
__pkcs15_create_data_object(fw_data, data_obj, &data_any_obj);
|
||||
pkcs15_add_object(slot, data_any_obj, phObject);
|
||||
|
||||
rv = CKR_OK;
|
||||
|
||||
out: return rv;
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card,
|
||||
struct sc_pkcs11_slot *slot,
|
||||
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
|
||||
|
@ -1326,6 +1408,10 @@ static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card,
|
|||
rv = pkcs15_create_certificate(p11card, slot, profile,
|
||||
pTemplate, ulCount, phObject);
|
||||
break;
|
||||
case CKO_DATA:
|
||||
rv = pkcs15_create_data(p11card, slot, profile,
|
||||
pTemplate, ulCount, phObject);
|
||||
break;
|
||||
default:
|
||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -2338,15 +2424,14 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
|
|||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, reader);
|
||||
|
||||
if (slot_data_pin_info(data)) {
|
||||
rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data);
|
||||
|
||||
/* Do we have to try a re-login and then try to sign again? */
|
||||
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
|
||||
rv = revalidate_pin(data, session);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
if (rv == 0)
|
||||
rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data);
|
||||
}
|
||||
|
||||
if ((rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data)) < 0)
|
||||
goto done;
|
||||
|
||||
done:
|
||||
sc_unlock(card);
|
||||
if (rv < 0)
|
||||
|
@ -2432,12 +2517,55 @@ static CK_RV pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session,
|
|||
return CKR_OK;
|
||||
}
|
||||
|
||||
static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object)
|
||||
{
|
||||
struct pkcs15_data_object *obj = (struct pkcs15_data_object*) object;
|
||||
struct sc_pkcs11_card *card = session->slot->card;
|
||||
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) card->fw_data;
|
||||
struct pkcs15_slot_data *data = slot_data(session->slot->fw_data);
|
||||
struct sc_profile *profile = NULL;
|
||||
int reader = session->slot->card->reader;
|
||||
int rv;
|
||||
|
||||
rv = sc_lock(card->card);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, card->reader);
|
||||
|
||||
/* Bind the profile */
|
||||
rv = sc_pkcs15init_bind(card->card, "pkcs15", NULL, &profile);
|
||||
if (rv < 0) {
|
||||
sc_unlock(card->card);
|
||||
return sc_to_cryptoki_error(rv, card->reader);
|
||||
}
|
||||
|
||||
/* Add the PINs the user presented so far to the keycache */
|
||||
add_pins_to_keycache(card, session->slot);
|
||||
|
||||
/* Delete object in smartcard */
|
||||
rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object);
|
||||
|
||||
/* Do we have to try a re-login and then try to delete again? */
|
||||
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
|
||||
rv = revalidate_pin(data, session);
|
||||
if (rv == 0)
|
||||
rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object);
|
||||
}
|
||||
|
||||
sc_pkcs15init_unbind(profile);
|
||||
sc_unlock(card->card);
|
||||
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, reader);
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
struct sc_pkcs11_object_ops pkcs15_dobj_ops = {
|
||||
pkcs15_dobj_release,
|
||||
pkcs15_dobj_set_attribute,
|
||||
pkcs15_dobj_get_attribute,
|
||||
sc_pkcs11_any_cmp_attribute,
|
||||
NULL,
|
||||
pkcs15_dobj_destroy,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
|
|
@ -236,6 +236,8 @@ CK_RV attr_extract(CK_ATTRIBUTE_PTR pAttr, void *ptr, size_t *sizep)
|
|||
size = sizeof(CKA_CERTIFICATE_TYPE); break;
|
||||
case CKA_MODULUS_BITS:
|
||||
size = sizeof(CK_ULONG); break;
|
||||
case CKA_OBJECT_ID:
|
||||
size = sizeof(struct sc_object_id); break;
|
||||
default:
|
||||
return CKR_FUNCTION_FAILED;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,34 @@ CK_RV C_CopyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
|||
CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
CK_OBJECT_HANDLE hObject) /* the object's handle */
|
||||
{
|
||||
return CKR_FUNCTION_NOT_SUPPORTED;
|
||||
struct sc_pkcs11_session *session;
|
||||
struct sc_pkcs11_object *object;
|
||||
char object_name[64];
|
||||
int rv;
|
||||
|
||||
rv = sc_pkcs11_lock();
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
snprintf(object_name, sizeof(object_name), "C_DestroyObject : Object %lu",
|
||||
(unsigned long) hObject);
|
||||
sc_debug( context, object_name );
|
||||
|
||||
rv = pool_find(&session_pool, hSession, (void**) &session);
|
||||
if (rv != CKR_OK)
|
||||
goto out;
|
||||
|
||||
rv = pool_find_and_delete(&session->slot->object_pool, hObject, (void**) &object);
|
||||
if (rv != CKR_OK)
|
||||
goto out;
|
||||
|
||||
if (object->ops->destroy_object == NULL)
|
||||
rv = CKR_FUNCTION_NOT_SUPPORTED;
|
||||
else
|
||||
rv = object->ops->destroy_object(session, object);
|
||||
|
||||
out: sc_pkcs11_unlock();
|
||||
return rv;
|
||||
}
|
||||
|
||||
CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, /* the session's handle */
|
||||
|
|
|
@ -1789,8 +1789,7 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card,
|
|||
int r, i;
|
||||
unsigned int tid = 0x01;
|
||||
|
||||
if ((label = args->label) == NULL)
|
||||
label = "Data Object";
|
||||
label = args->label;
|
||||
|
||||
if (!args->id.len) {
|
||||
/* Select an ID if the user didn't specify one, otherwise
|
||||
|
@ -1831,7 +1830,10 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card,
|
|||
if (object == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
data_object_info = (sc_pkcs15_data_info_t *) object->data;
|
||||
if (label != NULL) {
|
||||
if (args->app_label != NULL) {
|
||||
strlcpy(data_object_info->app_label, args->app_label,
|
||||
sizeof(data_object_info->app_label));
|
||||
} else if (label != NULL) {
|
||||
strlcpy(data_object_info->app_label, label,
|
||||
sizeof(data_object_info->app_label));
|
||||
}
|
||||
|
@ -2715,6 +2717,8 @@ sc_pkcs15init_new_object(int type, const char *label, sc_pkcs15_id_t *auth_id, v
|
|||
break;
|
||||
case SC_PKCS15_TYPE_DATA_OBJECT:
|
||||
object->flags = DEFAULT_DATA_FLAGS;
|
||||
if (auth_id->len != 0)
|
||||
object->flags |= SC_PKCS15_CO_FLAG_PRIVATE;
|
||||
data_size = sizeof(sc_pkcs15_data_info_t);
|
||||
break;
|
||||
}
|
||||
|
@ -2803,21 +2807,25 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
|
|||
{
|
||||
sc_path_t path;
|
||||
struct sc_pkcs15_df *df;
|
||||
int r;
|
||||
int r, stored_in_ef = 0;
|
||||
|
||||
switch(obj->type & SC_PKCS15_TYPE_CLASS_MASK)
|
||||
{
|
||||
case SC_PKCS15_TYPE_PUBKEY:
|
||||
path = ((sc_pkcs15_pubkey_info_t *)obj->data)->path;
|
||||
stored_in_ef = 1;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_PRKEY:
|
||||
path = ((sc_pkcs15_prkey_info_t *)obj->data)->path;
|
||||
stored_in_ef = 1;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_CERT:
|
||||
path = ((sc_pkcs15_cert_info_t *)obj->data)->path;
|
||||
stored_in_ef = 1;
|
||||
break;
|
||||
case SC_PKCS15_TYPE_DATA_OBJECT:
|
||||
path = ((sc_pkcs15_data_info_t *)obj->data)->path;
|
||||
stored_in_ef = 1;
|
||||
break;
|
||||
default:
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
|
@ -2827,13 +2835,26 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
|
|||
if ((r = set_so_pin_from_card(p15card, profile)) < 0)
|
||||
return r;
|
||||
|
||||
/* If there's a card-specific way to delete objects, use it.
|
||||
* Otherwise, just set its label to "deleted" to indicate
|
||||
* that we can re-used it when we have to make a next
|
||||
* object in the future. */
|
||||
if (profile->ops->delete_object != NULL) {
|
||||
r = profile->ops->delete_object(profile, p15card->card,
|
||||
obj->type, obj->data, &path);
|
||||
/* if the object is stored in a normal EF try to
|
||||
* delete the EF */
|
||||
if (stored_in_ef != 0) {
|
||||
r = sc_pkcs15init_delete_by_path(profile, p15card->card, &path);
|
||||
if (r != SC_SUCCESS) {
|
||||
sc_error(p15card->card->ctx, "sc_pkcs15init_delete_by_path 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) {
|
||||
/* Unlink the object and update the DF */
|
||||
sc_pkcs15_remove_object(p15card, obj);
|
||||
}
|
||||
} else if (profile->ops->delete_object != NULL) {
|
||||
/* If there's a card-specific way to delete objects, use it.
|
||||
* Otherwise, just set its label to "deleted" to indicate
|
||||
* that we can re-used it when we have to make a next
|
||||
* object in the future. */
|
||||
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;
|
||||
|
@ -2844,18 +2865,16 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
|
|||
if ((df = obj->df) != NULL) {
|
||||
/* Unlink the object and update the DF */
|
||||
sc_pkcs15_remove_object(p15card, obj);
|
||||
r = sc_pkcs15init_update_any_df(p15card, profile, df, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Get the DF we're part of. If there's no DF, fine, we haven't
|
||||
* been added yet. */
|
||||
if ((df = obj->df) != NULL) {
|
||||
/*Change the label into "deleted" and update the DF */
|
||||
strcpy(obj->label, "deleted");
|
||||
r = sc_pkcs15init_update_any_df(p15card, profile, df, 0);
|
||||
}
|
||||
}
|
||||
r = sc_pkcs15init_update_any_df(p15card, profile, df, 0);
|
||||
|
||||
/* mark card as dirty */
|
||||
profile->dirty = 1;
|
||||
|
|
|
@ -46,6 +46,7 @@ enum {
|
|||
OPT_MODULE = 0x100,
|
||||
OPT_SLOT,
|
||||
OPT_SLOT_LABEL,
|
||||
OPT_APPLICATION_LABEL,
|
||||
OPT_APPLICATION_ID,
|
||||
OPT_SO_PIN,
|
||||
OPT_INIT_TOKEN,
|
||||
|
@ -75,6 +76,8 @@ const struct option options[] = {
|
|||
{ "key-type", 1, 0, OPT_KEY_TYPE },
|
||||
{ "write-object", 1, 0, 'w' },
|
||||
{ "read-object", 0, 0, 'r' },
|
||||
{ "delete-object", 0, 0, 'b' },
|
||||
{ "application-label", 1, 0, OPT_APPLICATION_LABEL },
|
||||
{ "application-id", 1, 0, OPT_APPLICATION_ID },
|
||||
{ "type", 1, 0, 'y' },
|
||||
{ "id", 1, 0, 'd' },
|
||||
|
@ -112,8 +115,9 @@ const char *option_help[] = {
|
|||
"Change your User PIN",
|
||||
"Key pair generation",
|
||||
"Specify the type and length of the key to create, for example rsa:1024",
|
||||
"Write an object (key, cert) to the card",
|
||||
"Write an object (key, cert, data) to the card",
|
||||
"Get object's CKA_VALUE attribute (use with --type)",
|
||||
"Specify the application label of the data object (use with --type data)",
|
||||
"Specify the application id of the data object (use with --type data)",
|
||||
"Specify the type of object (e.g. cert, privkey, pubkey, data)",
|
||||
"Specify the id of the object",
|
||||
|
@ -150,6 +154,7 @@ static size_t opt_object_id_len = 0, new_object_id_len = 0;
|
|||
static char * opt_object_label = NULL;
|
||||
static char * opt_pin = NULL;
|
||||
static char * opt_so_pin = NULL;
|
||||
static char * opt_application_label = NULL;
|
||||
static char * opt_application_id = NULL;
|
||||
static char * opt_key_type = NULL;
|
||||
static int opt_is_private = 0;
|
||||
|
@ -215,6 +220,7 @@ static int gen_keypair(CK_SLOT_ID, CK_SESSION_HANDLE,
|
|||
CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *, const char *);
|
||||
static int write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
|
||||
static int read_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
|
||||
static int delete_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
|
||||
static void set_id_attr(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
|
||||
static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS,
|
||||
CK_OBJECT_HANDLE_PTR,
|
||||
|
@ -264,6 +270,7 @@ main(int argc, char * argv[])
|
|||
int do_gen_keypair = 0;
|
||||
int do_write_object = 0;
|
||||
int do_read_object = 0;
|
||||
int do_delete_object = 0;
|
||||
int do_set_id = 0;
|
||||
int do_test = 0;
|
||||
int do_test_kpgen_certwrite = 0;
|
||||
|
@ -277,7 +284,7 @@ main(int argc, char * argv[])
|
|||
CK_RV rv;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "ILMOa:d:e:hi:klm:o:p:scvty:w:z:r",
|
||||
c = getopt_long(argc, argv, "ILMOa:bd:e:hi:klm:o:p:scvty:w:z:r",
|
||||
options, &long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
@ -320,6 +327,11 @@ main(int argc, char * argv[])
|
|||
do_read_object = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'b':
|
||||
need_session |= NEED_SESSION_RW;
|
||||
do_delete_object = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'e':
|
||||
need_session |= NEED_SESSION_RW;
|
||||
do_set_id = 1;
|
||||
|
@ -407,6 +419,9 @@ main(int argc, char * argv[])
|
|||
case OPT_MODULE:
|
||||
opt_module = optarg;
|
||||
break;
|
||||
case OPT_APPLICATION_LABEL:
|
||||
opt_application_label = optarg;
|
||||
break;
|
||||
case OPT_APPLICATION_ID:
|
||||
opt_application_id = optarg;
|
||||
break;
|
||||
|
@ -572,11 +587,22 @@ main(int argc, char * argv[])
|
|||
if (opt_object_class_str == NULL)
|
||||
fatal("You should specify type of the object to read");
|
||||
if (opt_object_id_len == 0 && opt_object_label == NULL &&
|
||||
opt_application_id == NULL)
|
||||
opt_application_label == NULL && opt_application_id == NULL)
|
||||
fatal("You should specify at least one of the "
|
||||
"object ID, object label or application ID\n");
|
||||
"object ID, object label, application label or application ID\n");
|
||||
read_object(opt_slot, session);
|
||||
}
|
||||
|
||||
if (do_delete_object) {
|
||||
if (opt_object_class_str == NULL)
|
||||
fatal("You should specify type of the object to delete");
|
||||
if (opt_object_id_len == 0 && opt_object_label == NULL &&
|
||||
opt_application_label == NULL && opt_application_id == NULL)
|
||||
fatal("You should specify at least one of the "
|
||||
"object ID, object label, application label or application ID\n");
|
||||
delete_object(opt_slot, session);
|
||||
}
|
||||
|
||||
if (do_set_id) {
|
||||
if (opt_object_class_str == NULL)
|
||||
fatal("You should specify the object type with the -y option\n");
|
||||
|
@ -1162,8 +1188,9 @@ static void parse_rsa_private_key(struct rsakey_info *rsa,
|
|||
|
||||
#define MAX_OBJECT_SIZE 5000
|
||||
|
||||
/* Currently only for certificates (-type cert) and private keys
|
||||
(-type privkey). Note: only RSA private keys are supported. */
|
||||
/* Currently only for certificates (-type cert),
|
||||
private keys (-type privkey) and data objetcs (-type data).
|
||||
Note: only RSA private keys are supported. */
|
||||
int
|
||||
write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
||||
{
|
||||
|
@ -1176,6 +1203,7 @@ write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
|||
CK_OBJECT_HANDLE cert_obj, privkey_obj, data_obj;
|
||||
CK_ATTRIBUTE cert_templ[20], privkey_templ[20], data_templ[20];
|
||||
int n_cert_attr = 0, n_privkey_attr = 0, n_data_attr = 0;
|
||||
struct sc_object_id oid;
|
||||
#if 0
|
||||
CK_ATTRIBUTE pubkey_templ[20];
|
||||
CK_OBJECT_HANDLE pubkey_obj;
|
||||
|
@ -1328,13 +1356,22 @@ write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
|||
if (opt_is_private != 0) {
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_PRIVATE,
|
||||
&_true, sizeof(_true));
|
||||
n_data_attr++;
|
||||
}
|
||||
|
||||
if (opt_application_label != NULL) {
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_APPLICATION,
|
||||
opt_application_label, strlen(opt_application_label));
|
||||
n_data_attr++;
|
||||
}
|
||||
|
||||
if (opt_application_id != NULL) {
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_APPLICATION,
|
||||
opt_application_id, strlen(opt_application_id));
|
||||
sc_format_oid(&oid, opt_application_id);
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID,
|
||||
(unsigned char *)oid.value, sizeof(oid.value));
|
||||
n_data_attr++;
|
||||
}
|
||||
|
||||
if (opt_object_label != NULL) {
|
||||
FILL_ATTR(data_templ[n_data_attr], CKA_LABEL,
|
||||
opt_object_label, strlen(opt_object_label));
|
||||
|
@ -1868,6 +1905,12 @@ read_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
|||
nn_attrs++;
|
||||
}
|
||||
|
||||
if (opt_application_label != NULL) {
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_APPLICATION,
|
||||
opt_application_label, strlen(opt_application_label));
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
if (opt_application_id != NULL) {
|
||||
sc_format_oid(&oid, opt_application_id);
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID,
|
||||
|
@ -1900,6 +1943,62 @@ read_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete object.
|
||||
*/
|
||||
int
|
||||
delete_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
|
||||
{
|
||||
CK_RV rv;
|
||||
CK_ATTRIBUTE attrs[20];
|
||||
CK_OBJECT_CLASS clazz = opt_object_class;
|
||||
CK_OBJECT_HANDLE obj = CK_INVALID_HANDLE;
|
||||
int nn_attrs = 0;
|
||||
struct sc_object_id oid;
|
||||
|
||||
if (opt_object_class_str != NULL) {
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_CLASS,
|
||||
&clazz, sizeof(clazz));
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
if (opt_object_id_len != 0) {
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_ID,
|
||||
opt_object_id, opt_object_id_len);
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
if (opt_object_label != NULL) {
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_LABEL,
|
||||
opt_object_label, strlen(opt_object_label));
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
if (opt_application_label != NULL) {
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_APPLICATION,
|
||||
opt_application_label, strlen(opt_application_label));
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
if (opt_application_id != NULL) {
|
||||
sc_format_oid(&oid, opt_application_id);
|
||||
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_ID,
|
||||
(unsigned char *)oid.value, sizeof(oid.value));
|
||||
nn_attrs++;
|
||||
}
|
||||
|
||||
rv = find_object_with_attributes(session, &obj, attrs, nn_attrs, 0);
|
||||
if (rv != CKR_OK)
|
||||
p11_fatal("find_object_with_attributes()", rv);
|
||||
else if (obj==CK_INVALID_HANDLE)
|
||||
fatal("object not found\n");
|
||||
rv = p11->C_DestroyObject(session, obj);
|
||||
if (rv != CKR_OK)
|
||||
p11_fatal("C_DestroyObject()", rv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static CK_ULONG get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE prkey)
|
||||
{
|
||||
unsigned char *id;
|
||||
|
|
Loading…
Reference in New Issue