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:
aj 2007-06-21 09:37:18 +00:00
parent a4cd33e77f
commit 4cc1a50a49
5 changed files with 308 additions and 33 deletions

View File

@ -1286,6 +1286,88 @@ static CK_RV pkcs15_create_certificate(struct sc_pkcs11_card *p11card,
out: return rv; 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, static CK_RV pkcs15_create_object(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot, struct sc_pkcs11_slot *slot,
CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, 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, rv = pkcs15_create_certificate(p11card, slot, profile,
pTemplate, ulCount, phObject); pTemplate, ulCount, phObject);
break; break;
case CKO_DATA:
rv = pkcs15_create_data(p11card, slot, profile,
pTemplate, ulCount, phObject);
break;
default: default:
rv = CKR_FUNCTION_NOT_SUPPORTED; rv = CKR_FUNCTION_NOT_SUPPORTED;
} }
@ -2338,15 +2424,14 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
if (rv < 0) if (rv < 0)
return sc_to_cryptoki_error(rv, reader); 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); rv = revalidate_pin(data, session);
if (rv < 0) if (rv == 0)
goto done; 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: done:
sc_unlock(card); sc_unlock(card);
if (rv < 0) if (rv < 0)
@ -2432,12 +2517,55 @@ static CK_RV pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session,
return CKR_OK; 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 = { struct sc_pkcs11_object_ops pkcs15_dobj_ops = {
pkcs15_dobj_release, pkcs15_dobj_release,
pkcs15_dobj_set_attribute, pkcs15_dobj_set_attribute,
pkcs15_dobj_get_attribute, pkcs15_dobj_get_attribute,
sc_pkcs11_any_cmp_attribute, sc_pkcs11_any_cmp_attribute,
NULL, pkcs15_dobj_destroy,
NULL, NULL,
NULL, NULL,
NULL, NULL,

View File

@ -236,6 +236,8 @@ CK_RV attr_extract(CK_ATTRIBUTE_PTR pAttr, void *ptr, size_t *sizep)
size = sizeof(CKA_CERTIFICATE_TYPE); break; size = sizeof(CKA_CERTIFICATE_TYPE); break;
case CKA_MODULUS_BITS: case CKA_MODULUS_BITS:
size = sizeof(CK_ULONG); break; size = sizeof(CK_ULONG); break;
case CKA_OBJECT_ID:
size = sizeof(struct sc_object_id); break;
default: default:
return CKR_FUNCTION_FAILED; return CKR_FUNCTION_FAILED;
} }

View File

@ -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_RV C_DestroyObject(CK_SESSION_HANDLE hSession, /* the session's handle */
CK_OBJECT_HANDLE hObject) /* the object'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 */ CK_RV C_GetObjectSize(CK_SESSION_HANDLE hSession, /* the session's handle */

View File

@ -1789,8 +1789,7 @@ sc_pkcs15init_store_data_object(struct sc_pkcs15_card *p15card,
int r, i; int r, i;
unsigned int tid = 0x01; unsigned int tid = 0x01;
if ((label = args->label) == NULL) label = args->label;
label = "Data Object";
if (!args->id.len) { if (!args->id.len) {
/* Select an ID if the user didn't specify one, otherwise /* 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) if (object == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
data_object_info = (sc_pkcs15_data_info_t *) object->data; 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, strlcpy(data_object_info->app_label, label,
sizeof(data_object_info->app_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; break;
case SC_PKCS15_TYPE_DATA_OBJECT: case SC_PKCS15_TYPE_DATA_OBJECT:
object->flags = DEFAULT_DATA_FLAGS; 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); data_size = sizeof(sc_pkcs15_data_info_t);
break; break;
} }
@ -2803,21 +2807,25 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
{ {
sc_path_t path; sc_path_t path;
struct sc_pkcs15_df *df; struct sc_pkcs15_df *df;
int r; int r, stored_in_ef = 0;
switch(obj->type & SC_PKCS15_TYPE_CLASS_MASK) switch(obj->type & SC_PKCS15_TYPE_CLASS_MASK)
{ {
case SC_PKCS15_TYPE_PUBKEY: case SC_PKCS15_TYPE_PUBKEY:
path = ((sc_pkcs15_pubkey_info_t *)obj->data)->path; path = ((sc_pkcs15_pubkey_info_t *)obj->data)->path;
stored_in_ef = 1;
break; break;
case SC_PKCS15_TYPE_PRKEY: case SC_PKCS15_TYPE_PRKEY:
path = ((sc_pkcs15_prkey_info_t *)obj->data)->path; path = ((sc_pkcs15_prkey_info_t *)obj->data)->path;
stored_in_ef = 1;
break; break;
case SC_PKCS15_TYPE_CERT: case SC_PKCS15_TYPE_CERT:
path = ((sc_pkcs15_cert_info_t *)obj->data)->path; path = ((sc_pkcs15_cert_info_t *)obj->data)->path;
stored_in_ef = 1;
break; break;
case SC_PKCS15_TYPE_DATA_OBJECT: case SC_PKCS15_TYPE_DATA_OBJECT:
path = ((sc_pkcs15_data_info_t *)obj->data)->path; path = ((sc_pkcs15_data_info_t *)obj->data)->path;
stored_in_ef = 1;
break; break;
default: default:
return SC_ERROR_NOT_SUPPORTED; 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) if ((r = set_so_pin_from_card(p15card, profile)) < 0)
return r; return r;
/* If there's a card-specific way to delete objects, use it. /* if the object is stored in a normal EF try to
* Otherwise, just set its label to "deleted" to indicate * delete the EF */
* that we can re-used it when we have to make a next if (stored_in_ef != 0) {
* object in the future. */ r = sc_pkcs15init_delete_by_path(profile, p15card->card, &path);
if (profile->ops->delete_object != NULL) { if (r != SC_SUCCESS) {
r = profile->ops->delete_object(profile, p15card->card, sc_error(p15card->card->ctx, "sc_pkcs15init_delete_by_path failed: %d", r);
obj->type, obj->data, &path); 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) { if (r < 0) {
sc_error(p15card->card->ctx, "ops->delete_object() failed: %d", r); sc_error(p15card->card->ctx, "ops->delete_object() failed: %d", r);
return r; return r;
@ -2844,18 +2865,16 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card,
if ((df = obj->df) != NULL) { if ((df = obj->df) != NULL) {
/* Unlink the object and update the DF */ /* Unlink the object and update the DF */
sc_pkcs15_remove_object(p15card, obj); 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 /* Get the DF we're part of. If there's no DF, fine, we haven't
* been added yet. */ * been added yet. */
if ((df = obj->df) != NULL) { if ((df = obj->df) != NULL) {
/*Change the label into "deleted" and update the DF */ /*Change the label into "deleted" and update the DF */
strcpy(obj->label, "deleted"); 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 */ /* mark card as dirty */
profile->dirty = 1; profile->dirty = 1;

View File

@ -46,6 +46,7 @@ enum {
OPT_MODULE = 0x100, OPT_MODULE = 0x100,
OPT_SLOT, OPT_SLOT,
OPT_SLOT_LABEL, OPT_SLOT_LABEL,
OPT_APPLICATION_LABEL,
OPT_APPLICATION_ID, OPT_APPLICATION_ID,
OPT_SO_PIN, OPT_SO_PIN,
OPT_INIT_TOKEN, OPT_INIT_TOKEN,
@ -75,6 +76,8 @@ const struct option options[] = {
{ "key-type", 1, 0, OPT_KEY_TYPE }, { "key-type", 1, 0, OPT_KEY_TYPE },
{ "write-object", 1, 0, 'w' }, { "write-object", 1, 0, 'w' },
{ "read-object", 0, 0, 'r' }, { "read-object", 0, 0, 'r' },
{ "delete-object", 0, 0, 'b' },
{ "application-label", 1, 0, OPT_APPLICATION_LABEL },
{ "application-id", 1, 0, OPT_APPLICATION_ID }, { "application-id", 1, 0, OPT_APPLICATION_ID },
{ "type", 1, 0, 'y' }, { "type", 1, 0, 'y' },
{ "id", 1, 0, 'd' }, { "id", 1, 0, 'd' },
@ -112,8 +115,9 @@ const char *option_help[] = {
"Change your User PIN", "Change your User PIN",
"Key pair generation", "Key pair generation",
"Specify the type and length of the key to create, for example rsa:1024", "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)", "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 application id of the data object (use with --type data)",
"Specify the type of object (e.g. cert, privkey, pubkey, data)", "Specify the type of object (e.g. cert, privkey, pubkey, data)",
"Specify the id of the object", "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_object_label = NULL;
static char * opt_pin = NULL; static char * opt_pin = NULL;
static char * opt_so_pin = NULL; static char * opt_so_pin = NULL;
static char * opt_application_label = NULL;
static char * opt_application_id = NULL; static char * opt_application_id = NULL;
static char * opt_key_type = NULL; static char * opt_key_type = NULL;
static int opt_is_private = 0; 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 *); CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *, const char *);
static int write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session); 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 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 void set_id_attr(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS, static int find_object(CK_SESSION_HANDLE, CK_OBJECT_CLASS,
CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR,
@ -264,6 +270,7 @@ main(int argc, char * argv[])
int do_gen_keypair = 0; int do_gen_keypair = 0;
int do_write_object = 0; int do_write_object = 0;
int do_read_object = 0; int do_read_object = 0;
int do_delete_object = 0;
int do_set_id = 0; int do_set_id = 0;
int do_test = 0; int do_test = 0;
int do_test_kpgen_certwrite = 0; int do_test_kpgen_certwrite = 0;
@ -277,7 +284,7 @@ main(int argc, char * argv[])
CK_RV rv; CK_RV rv;
while (1) { 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); options, &long_optind);
if (c == -1) if (c == -1)
break; break;
@ -320,6 +327,11 @@ main(int argc, char * argv[])
do_read_object = 1; do_read_object = 1;
action_count++; action_count++;
break; break;
case 'b':
need_session |= NEED_SESSION_RW;
do_delete_object = 1;
action_count++;
break;
case 'e': case 'e':
need_session |= NEED_SESSION_RW; need_session |= NEED_SESSION_RW;
do_set_id = 1; do_set_id = 1;
@ -407,6 +419,9 @@ main(int argc, char * argv[])
case OPT_MODULE: case OPT_MODULE:
opt_module = optarg; opt_module = optarg;
break; break;
case OPT_APPLICATION_LABEL:
opt_application_label = optarg;
break;
case OPT_APPLICATION_ID: case OPT_APPLICATION_ID:
opt_application_id = optarg; opt_application_id = optarg;
break; break;
@ -572,11 +587,22 @@ main(int argc, char * argv[])
if (opt_object_class_str == NULL) if (opt_object_class_str == NULL)
fatal("You should specify type of the object to read"); fatal("You should specify type of the object to read");
if (opt_object_id_len == 0 && opt_object_label == NULL && 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 " 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); 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 (do_set_id) {
if (opt_object_class_str == NULL) if (opt_object_class_str == NULL)
fatal("You should specify the object type with the -y option\n"); 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 #define MAX_OBJECT_SIZE 5000
/* Currently only for certificates (-type cert) and private keys /* Currently only for certificates (-type cert),
(-type privkey). Note: only RSA private keys are supported. */ private keys (-type privkey) and data objetcs (-type data).
Note: only RSA private keys are supported. */
int int
write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session) 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_OBJECT_HANDLE cert_obj, privkey_obj, data_obj;
CK_ATTRIBUTE cert_templ[20], privkey_templ[20], data_templ[20]; CK_ATTRIBUTE cert_templ[20], privkey_templ[20], data_templ[20];
int n_cert_attr = 0, n_privkey_attr = 0, n_data_attr = 0; int n_cert_attr = 0, n_privkey_attr = 0, n_data_attr = 0;
struct sc_object_id oid;
#if 0 #if 0
CK_ATTRIBUTE pubkey_templ[20]; CK_ATTRIBUTE pubkey_templ[20];
CK_OBJECT_HANDLE pubkey_obj; CK_OBJECT_HANDLE pubkey_obj;
@ -1328,13 +1356,22 @@ write_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
if (opt_is_private != 0) { if (opt_is_private != 0) {
FILL_ATTR(data_templ[n_data_attr], CKA_PRIVATE, FILL_ATTR(data_templ[n_data_attr], CKA_PRIVATE,
&_true, sizeof(_true)); &_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) { if (opt_application_id != NULL) {
FILL_ATTR(data_templ[n_data_attr], CKA_APPLICATION, sc_format_oid(&oid, opt_application_id);
opt_application_id, strlen(opt_application_id)); FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID,
(unsigned char *)oid.value, sizeof(oid.value));
n_data_attr++; n_data_attr++;
} }
if (opt_object_label != NULL) { if (opt_object_label != NULL) {
FILL_ATTR(data_templ[n_data_attr], CKA_LABEL, FILL_ATTR(data_templ[n_data_attr], CKA_LABEL,
opt_object_label, strlen(opt_object_label)); opt_object_label, strlen(opt_object_label));
@ -1868,6 +1905,12 @@ read_object(CK_SLOT_ID slot, CK_SESSION_HANDLE session)
nn_attrs++; 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) { if (opt_application_id != NULL) {
sc_format_oid(&oid, opt_application_id); sc_format_oid(&oid, opt_application_id);
FILL_ATTR(attrs[nn_attrs], CKA_OBJECT_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; 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) static CK_ULONG get_private_key_length(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE prkey)
{ {
unsigned char *id; unsigned char *id;