pkcs15-init etc. support for pkcs15 data objects
patch supplied by Victor Tarasov <vtarasov@idealx.com> git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1877 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
1e13a2e011
commit
bfd5b49436
@ -106,9 +106,20 @@ struct pkcs15_pubkey_object {
|
||||
#define is_pubkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PUBKEY_RSA)
|
||||
#define is_cert(obj) (__p15_type(obj) == SC_PKCS15_TYPE_CERT_X509)
|
||||
|
||||
struct pkcs15_data_object {
|
||||
struct pkcs15_any_object base;
|
||||
|
||||
struct sc_pkcs15_data_info *info;
|
||||
struct sc_pkcs15_data *value;
|
||||
};
|
||||
#define data_flags base.base.flags
|
||||
#define data_p15obj base.p15_object
|
||||
#define is_data(obj) (__p15_type(obj) == SC_PKCS15_TYPE_DATA_OBJECT)
|
||||
|
||||
extern struct sc_pkcs11_object_ops pkcs15_cert_ops;
|
||||
extern struct sc_pkcs11_object_ops pkcs15_prkey_ops;
|
||||
extern struct sc_pkcs11_object_ops pkcs15_pubkey_ops;
|
||||
extern struct sc_pkcs11_object_ops pkcs15_dobj_ops;
|
||||
|
||||
|
||||
static int __pkcs15_release_object(struct pkcs15_any_object *);
|
||||
@ -321,6 +332,28 @@ __pkcs15_create_prkey_object(struct pkcs15_fw_data *fw_data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__pkcs15_create_data_object(struct pkcs15_fw_data *fw_data,
|
||||
struct sc_pkcs15_object *object, struct pkcs15_any_object **data_object)
|
||||
{
|
||||
struct pkcs15_data_object *dobj = NULL;
|
||||
int rv;
|
||||
|
||||
rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &dobj,
|
||||
object, &pkcs15_dobj_ops,
|
||||
sizeof(struct pkcs15_data_object));
|
||||
if (rv >= 0) {
|
||||
dobj->info = (struct sc_pkcs15_data_info *) object->data;
|
||||
dobj->value = NULL;
|
||||
}
|
||||
|
||||
if (data_object != NULL)
|
||||
*data_object = (struct pkcs15_any_object *) dobj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pkcs15_create_pkcs11_objects(struct pkcs15_fw_data *fw_data,
|
||||
int p15_type, const char *name,
|
||||
@ -590,6 +623,13 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card)
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, reader);
|
||||
|
||||
rv = pkcs15_create_pkcs11_objects(fw_data,
|
||||
SC_PKCS15_TYPE_DATA_OBJECT,
|
||||
"data object",
|
||||
__pkcs15_create_data_object);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, reader);
|
||||
|
||||
/* Match up related keys and certificates */
|
||||
pkcs15_bind_related_objects(fw_data);
|
||||
|
||||
@ -610,14 +650,21 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card)
|
||||
for (j=0; j < fw_data->num_objects; j++) {
|
||||
struct pkcs15_any_object *obj = fw_data->objects[j];
|
||||
|
||||
if (!is_privkey(obj)
|
||||
|| !sc_pkcs15_compare_id(&pin_info->auth_id,
|
||||
if (__p15_type(obj) == -1)
|
||||
continue;
|
||||
else if (!sc_pkcs15_compare_id(&pin_info->auth_id,
|
||||
&obj->p15_object->auth_id))
|
||||
continue;
|
||||
|
||||
if (is_privkey(obj)) {
|
||||
sc_debug(context, "Adding private key %d to PIN %d\n", j, i);
|
||||
pkcs15_add_object(slot, obj, NULL);
|
||||
}
|
||||
else if (is_data(obj)) {
|
||||
sc_debug(context, "Adding data object %d to PIN %d\n", j, i);
|
||||
pkcs15_add_object(slot, obj, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add all public objects to a virtual slot without pin protection */
|
||||
@ -1329,7 +1376,7 @@ CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *
|
||||
|
||||
rc = __pkcs15_create_prkey_object(fw_data, priv_key_obj, &priv_any_obj);
|
||||
if (rc == 0)
|
||||
__pkcs15_create_pubkey_object(fw_data, pub_key_obj, &pub_any_obj);
|
||||
rc = __pkcs15_create_pubkey_object(fw_data, pub_key_obj, &pub_any_obj);
|
||||
if (rc != 0) {
|
||||
sc_debug(context, "__pkcs15_create_pr/pubkey_object returned %d\n", rc);
|
||||
rv = sc_to_cryptoki_error(rc, p11card->reader);
|
||||
@ -2008,6 +2055,148 @@ struct sc_pkcs11_object_ops pkcs15_pubkey_ops = {
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* PKCS#15 Data Object*/
|
||||
|
||||
void pkcs15_dobj_release(void *object)
|
||||
{
|
||||
__pkcs15_release_object((struct pkcs15_any_object *) object);
|
||||
}
|
||||
|
||||
CK_RV pkcs15_dobj_set_attribute(struct sc_pkcs11_session *session,
|
||||
void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs15_data_object *dobj = (struct pkcs15_data_object*) object;
|
||||
|
||||
return pkcs15_set_attrib(session, dobj->base.p15_object, attr);
|
||||
}
|
||||
|
||||
|
||||
int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
|
||||
struct pkcs15_data_object *dobj,
|
||||
struct sc_pkcs15_data **out_data)
|
||||
{
|
||||
int rv;
|
||||
struct pkcs15_fw_data *fw_data =
|
||||
(struct pkcs15_fw_data *) session->slot->card->fw_data;
|
||||
struct pkcs15_slot_data *data = slot_data(session->slot->fw_data);
|
||||
struct sc_card *card = session->slot->card->card;
|
||||
int reader = session->slot->card->reader;
|
||||
|
||||
if (!out_data)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
rv = sc_lock(card);
|
||||
if (rv < 0)
|
||||
return sc_to_cryptoki_error(rv, reader);
|
||||
|
||||
if (slot_data_pin_info(data)) {
|
||||
rv = revalidate_pin(data, session);
|
||||
if (rv < 0)
|
||||
goto done;
|
||||
}
|
||||
|
||||
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)
|
||||
return sc_to_cryptoki_error(rv, reader);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CK_RV pkcs15_dobj_get_attribute(struct sc_pkcs11_session *session,
|
||||
void *object,
|
||||
CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs15_data_object *dobj = (struct pkcs15_data_object*) object;
|
||||
size_t len;
|
||||
|
||||
switch (attr->type) {
|
||||
case CKA_CLASS:
|
||||
check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS));
|
||||
*(CK_OBJECT_CLASS*)attr->pValue = CKO_DATA;
|
||||
break;
|
||||
case CKA_TOKEN:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue = TRUE;
|
||||
break;
|
||||
case CKA_PRIVATE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue =
|
||||
(dobj->base.p15_object->flags & 0x01) != 0;
|
||||
break;
|
||||
case CKA_MODIFIABLE:
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue =
|
||||
(dobj->base.p15_object->flags & 0x02) != 0;
|
||||
break;
|
||||
case CKA_LABEL:
|
||||
len = strlen(dobj->base.p15_object->label);
|
||||
check_attribute_buffer(attr, len);
|
||||
memcpy(attr->pValue, dobj->base.p15_object->label, len);
|
||||
break;
|
||||
case CKA_APPLICATION:
|
||||
len = strlen(dobj->info->app_label);
|
||||
check_attribute_buffer(attr, len);
|
||||
memcpy(attr->pValue, dobj->info->app_label, len);
|
||||
break;
|
||||
#if 0
|
||||
case CKA_ID:
|
||||
check_attribute_buffer(attr, dobj->info->id.len);
|
||||
memcpy(attr->pValue, dobj->info->id.value, dobj->info->id.len);
|
||||
break;
|
||||
#endif
|
||||
case CKA_OBJECT_ID:
|
||||
{
|
||||
int len = sizeof(dobj->info->app_oid);
|
||||
|
||||
check_attribute_buffer(attr, len);
|
||||
memcpy(attr->pValue, dobj->info->app_oid.value, len);
|
||||
}
|
||||
break;
|
||||
case CKA_VALUE:
|
||||
{
|
||||
CK_RV rv;
|
||||
struct sc_pkcs15_data *data = NULL;
|
||||
|
||||
rv = pkcs15_dobj_get_value(session, dobj, &data);
|
||||
if (rv!=CKR_OK)
|
||||
return rv;
|
||||
else if (!data)
|
||||
return CKR_ATTRIBUTE_VALUE_INVALID;
|
||||
|
||||
sc_debug(context, "data %p\n", data);
|
||||
sc_debug(context, "data_len %i\n", data->data_len);
|
||||
check_attribute_buffer(attr, data->data_len);
|
||||
memcpy(attr->pValue, data->data, data->data_len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
|
||||
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,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* get_attribute helpers
|
||||
*/
|
||||
@ -2218,14 +2407,15 @@ register_mechanisms(struct sc_pkcs11_card *p11card)
|
||||
num = card->algorithm_count;
|
||||
alg_info = card->algorithms;
|
||||
while (num--) {
|
||||
if (alg_info->algorithm != SC_ALGORITHM_RSA)
|
||||
continue;
|
||||
if (alg_info->algorithm == SC_ALGORITHM_RSA) {
|
||||
if (alg_info->key_length < mech_info.ulMinKeySize)
|
||||
mech_info.ulMinKeySize = alg_info->key_length;
|
||||
if (alg_info->key_length > mech_info.ulMaxKeySize)
|
||||
mech_info.ulMaxKeySize = alg_info->key_length;
|
||||
|
||||
flags |= alg_info->flags;
|
||||
}
|
||||
|
||||
alg_info++;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,10 @@ CK_RV C_Initialize(CK_VOID_PTR pReserved)
|
||||
__card_detect_all(0);
|
||||
|
||||
rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pReserved);
|
||||
if (rv != CKR_OK) {
|
||||
sc_release_context(context);
|
||||
context = NULL;
|
||||
}
|
||||
|
||||
out: if (context != NULL)
|
||||
sc_debug(context, "C_Initialize: result = %d\n", rv);
|
||||
|
@ -70,7 +70,7 @@
|
||||
#define DEFAULT_PRKEY_FLAGS 0x03
|
||||
#define DEFAULT_PUBKEY_FLAGS 0x02
|
||||
#define DEFAULT_CERT_FLAGS 0x02
|
||||
#define DEFAULT_DATA_FLAGS 0x03
|
||||
#define DEFAULT_DATA_FLAGS 0x02
|
||||
|
||||
/* Handle encoding of PKCS15 on the card */
|
||||
typedef int (*pkcs15_encoder)(struct sc_context *,
|
||||
@ -2496,13 +2496,16 @@ set_user_pin_from_authid(struct sc_pkcs15_card *p15card,
|
||||
* Possible fix: store all file info from the profile on the card
|
||||
*/
|
||||
if (pin->path.len != 0) {
|
||||
sc_file_t *df;
|
||||
sc_file_t *df = NULL;
|
||||
|
||||
r = sc_profile_get_file_by_path(profile, &pin->path, &df);
|
||||
if (r == SC_ERROR_FILE_NOT_FOUND
|
||||
&& (r = sc_select_file(p15card->card, &pin->path, &df)) == 0) {
|
||||
sc_profile_add_file(profile, "pin-dir (auto)", df);
|
||||
}
|
||||
|
||||
if (df)
|
||||
sc_file_free(df);
|
||||
}
|
||||
|
||||
return sc_keycache_set_pin_name(&pin->path,
|
||||
|
@ -41,6 +41,7 @@ enum {
|
||||
OPT_MODULE = 0x100,
|
||||
OPT_SLOT,
|
||||
OPT_SLOT_LABEL,
|
||||
OPT_APPLICATION_ID,
|
||||
};
|
||||
|
||||
const struct option options[] = {
|
||||
@ -58,6 +59,8 @@ const struct option options[] = {
|
||||
{ "change-pin", 0, 0, 'c' },
|
||||
{ "keypairgen", 0, 0, 'k' },
|
||||
{ "write-object", 1, 0, 'w' },
|
||||
{ "read-object", 0, 0, 'r' },
|
||||
{ "application-id", 1, 0, OPT_APPLICATION_ID },
|
||||
{ "type", 1, 0, 'y' },
|
||||
{ "id", 1, 0, 'd' },
|
||||
{ "label", 1, 0, 'a' },
|
||||
@ -88,6 +91,8 @@ const char *option_help[] = {
|
||||
"Change your (user) PIN",
|
||||
"Key pair generation",
|
||||
"Write an object (key, cert) to the card",
|
||||
"Get object's CKA_VALUE attribute (use with --type)",
|
||||
"Specify the application id of the data object (use with --type data)",
|
||||
"Specify the type of object (e.g. cert, privkey, pubkey)",
|
||||
"Specify the id of the object",
|
||||
"Specify the label of the object",
|
||||
@ -119,6 +124,7 @@ static CK_BYTE opt_object_id[100], new_object_id[100];
|
||||
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_application_id = NULL;
|
||||
|
||||
static void *module = NULL;
|
||||
static CK_FUNCTION_LIST_PTR p11 = NULL;
|
||||
@ -145,12 +151,14 @@ static int change_pin(CK_SLOT_ID, CK_SESSION_HANDLE);
|
||||
static void show_object(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, int);
|
||||
static void show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
|
||||
static void sign_data(CK_SLOT_ID,
|
||||
CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void hash_data(CK_SLOT_ID, CK_SESSION_HANDLE);
|
||||
static int gen_keypair(CK_SLOT_ID, CK_SESSION_HANDLE,
|
||||
CK_OBJECT_HANDLE *, CK_OBJECT_HANDLE *);
|
||||
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 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,
|
||||
@ -173,6 +181,10 @@ static const char * CKR2Str(CK_ULONG res);
|
||||
static int p11_test(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
|
||||
static int hex_to_bin(const char *in, CK_BYTE *out, size_t *outlen);
|
||||
static void test_kpgen_certwrite(CK_SLOT_ID slot, CK_SESSION_HANDLE session);
|
||||
static CK_RV find_object_with_attributes(
|
||||
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out,
|
||||
CK_ATTRIBUTE *attrs, CK_ULONG attrsLen,
|
||||
CK_ULONG obj_index);
|
||||
|
||||
/* win32 needs this in open(2) */
|
||||
#ifndef O_BINARY
|
||||
@ -193,6 +205,7 @@ main(int argc, char * const argv[])
|
||||
int do_hash = 0;
|
||||
int do_gen_keypair = 0;
|
||||
int do_write_object = 0;
|
||||
int do_read_object = 0;
|
||||
int do_set_id = 0;
|
||||
int do_test = 0;
|
||||
int do_test_kpgen_certwrite = 0;
|
||||
@ -203,7 +216,7 @@ main(int argc, char * const argv[])
|
||||
CK_RV rv;
|
||||
|
||||
while (1) {
|
||||
c = getopt_long(argc, argv, "ILMOa:d:e:hi:klm:o:p:scvty:w:z:",
|
||||
c = getopt_long(argc, argv, "ILMOa:d:e:hi:klm:o:p:scvty:w:z:r",
|
||||
options, &long_optind);
|
||||
if (c == -1)
|
||||
break;
|
||||
@ -241,6 +254,11 @@ main(int argc, char * const argv[])
|
||||
opt_file_to_write = optarg;
|
||||
action_count++;
|
||||
break;
|
||||
case 'r':
|
||||
need_session |= NEED_SESSION_RO;
|
||||
do_read_object = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'e':
|
||||
need_session |= NEED_SESSION_RW;
|
||||
do_set_id = 1;
|
||||
@ -259,6 +277,8 @@ main(int argc, char * const argv[])
|
||||
opt_object_class = CKO_PRIVATE_KEY;
|
||||
else if (strcmp(optarg, "pubkey") == 0)
|
||||
opt_object_class = CKO_PUBLIC_KEY;
|
||||
else if (strcmp(optarg, "data") == 0)
|
||||
opt_object_class = CKO_DATA;
|
||||
else {
|
||||
printf("Unsupported object type \"%s\"\n", optarg);
|
||||
print_usage_and_die();
|
||||
@ -323,6 +343,9 @@ main(int argc, char * const argv[])
|
||||
case OPT_MODULE:
|
||||
opt_module = optarg;
|
||||
break;
|
||||
case OPT_APPLICATION_ID:
|
||||
opt_application_id = optarg;
|
||||
break;
|
||||
default:
|
||||
print_usage_and_die();
|
||||
}
|
||||
@ -448,6 +471,15 @@ main(int argc, char * const argv[])
|
||||
write_object(opt_slot, session);
|
||||
}
|
||||
|
||||
if (do_read_object) {
|
||||
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)
|
||||
fatal("You should specify at least one of the "
|
||||
"object ID, object label or application ID\n");
|
||||
read_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");
|
||||
@ -1041,6 +1073,43 @@ done: if (count == 0)
|
||||
return count;
|
||||
}
|
||||
|
||||
CK_RV find_object_with_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE *out,
|
||||
CK_ATTRIBUTE *attrs, CK_ULONG attrsLen,
|
||||
CK_ULONG obj_index)
|
||||
{
|
||||
CK_ULONG count, ii;
|
||||
CK_OBJECT_HANDLE ret;
|
||||
CK_RV rv;
|
||||
|
||||
if (!out || !attrs || !attrsLen)
|
||||
return CKR_ARGUMENTS_BAD;
|
||||
else
|
||||
*out = CK_INVALID_HANDLE;
|
||||
|
||||
rv = p11->C_FindObjectsInit(session, attrs, attrsLen);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
|
||||
for (ii = 0; ii < obj_index; ii++) {
|
||||
rv = p11->C_FindObjects(session, &ret, 1, &count);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
else if (!count)
|
||||
goto done;
|
||||
}
|
||||
|
||||
rv = p11->C_FindObjects(session, &ret, 1, &count);
|
||||
if (rv != CKR_OK)
|
||||
return rv;
|
||||
else if (count)
|
||||
*out = ret;
|
||||
|
||||
done:
|
||||
p11->C_FindObjectsFinal(session);
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
|
||||
CK_MECHANISM_TYPE
|
||||
find_mechanism(CK_SLOT_ID slot, CK_FLAGS flags, int stop_if_not_found)
|
||||
{
|
||||
@ -1120,7 +1189,9 @@ ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE);
|
||||
ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE);
|
||||
ATTR_METHOD(MODULUS_BITS, CK_ULONG);
|
||||
VARATTR_METHOD(LABEL, char);
|
||||
VARATTR_METHOD(APPLICATION, char);
|
||||
VARATTR_METHOD(ID, unsigned char);
|
||||
VARATTR_METHOD(OBJECT_ID, unsigned char);
|
||||
VARATTR_METHOD(MODULUS, unsigned char);
|
||||
VARATTR_METHOD(VALUE, unsigned char);
|
||||
|
||||
@ -1139,6 +1210,9 @@ show_object(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
case CKO_CERTIFICATE:
|
||||
show_cert(sess, obj);
|
||||
break;
|
||||
case CKO_DATA:
|
||||
show_dobj(sess, obj);
|
||||
break;
|
||||
default:
|
||||
printf("Object %u, type %u\n",
|
||||
(unsigned int) obj,
|
||||
@ -1250,6 +1324,59 @@ show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
int *app_oid;
|
||||
char *label;
|
||||
CK_ULONG size;
|
||||
|
||||
printf("Data object %u\n", (unsigned int) obj);
|
||||
printf(" label: ");
|
||||
if ((label = getLABEL(sess, obj, NULL)) != NULL) {
|
||||
printf("'%s'\n", label);
|
||||
free(label);
|
||||
}
|
||||
else {
|
||||
printf("<empty>\n");
|
||||
}
|
||||
|
||||
printf(" application: ");
|
||||
if ((label = getAPPLICATION(sess, obj, NULL)) != NULL) {
|
||||
printf("'%s'\n", label);
|
||||
free(label);
|
||||
}
|
||||
else {
|
||||
printf("<empty>\n");
|
||||
}
|
||||
|
||||
printf(" app_id: ");
|
||||
app_oid = (int *)getOBJECT_ID(sess, obj, &size);
|
||||
if (app_oid != NULL && size) {
|
||||
unsigned int n;
|
||||
|
||||
size /= sizeof(int);
|
||||
printf("%i", app_oid[0]);
|
||||
if (app_oid[0] >= 0)
|
||||
for (n = 1; (n < size) && (app_oid[n] >= 0); n++)
|
||||
printf(".%i", app_oid[n]);
|
||||
|
||||
printf("\n");
|
||||
free(app_oid);
|
||||
}
|
||||
else {
|
||||
printf("<empty>\n");
|
||||
}
|
||||
|
||||
printf(" flags: ");
|
||||
if (getMODIFIABLE(sess, obj))
|
||||
printf(" modifiable");
|
||||
if (getPRIVATE(sess, obj))
|
||||
printf(" private");
|
||||
printf ("\n");
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
get_token_info(CK_SLOT_ID slot, CK_TOKEN_INFO_PTR info)
|
||||
{
|
||||
@ -1294,6 +1421,73 @@ get_mechanisms(CK_SLOT_ID slot,
|
||||
return ulCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read object CKA_VALUE attribute's value.
|
||||
*/
|
||||
int
|
||||
read_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;
|
||||
unsigned char *value = NULL;
|
||||
CK_ULONG len;
|
||||
FILE *out;
|
||||
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_id != NULL) {
|
||||
parse_application_id(&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");
|
||||
|
||||
value = getVALUE(session, obj, &len);
|
||||
if (value == NULL)
|
||||
fatal("get CKA_VALUE failed\n");
|
||||
|
||||
if (opt_output) {
|
||||
out = fopen(opt_output, "wb");
|
||||
if (out==NULL)
|
||||
fatal("cannot open '%s'\n", opt_output);
|
||||
}
|
||||
else
|
||||
out = stdout;
|
||||
|
||||
if (fwrite(value, 1, len, out) != len)
|
||||
fatal("cannot write to '%s'\n", opt_output);
|
||||
if (opt_output)
|
||||
fclose(out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
test_digest(CK_SLOT_ID slot)
|
||||
{
|
||||
|
@ -114,6 +114,7 @@ enum {
|
||||
OPT_SECRET,
|
||||
OPT_PUBKEY_LABEL,
|
||||
OPT_CERT_LABEL,
|
||||
OPT_APPLICATION_ID,
|
||||
|
||||
OPT_PIN1 = 0x10000, /* don't touch these values */
|
||||
OPT_PUK1 = 0x10001,
|
||||
@ -146,6 +147,7 @@ const struct option options[] = {
|
||||
{ "label", required_argument, 0, 'l' },
|
||||
{ "public-key-label", required_argument, 0, OPT_PUBKEY_LABEL },
|
||||
{ "cert-label", required_argument, 0, OPT_CERT_LABEL },
|
||||
{ "application-id", required_argument, 0, OPT_APPLICATION_ID },
|
||||
{ "output-file", required_argument, 0, 'o' },
|
||||
{ "format", required_argument, 0, 'f' },
|
||||
{ "passphrase", required_argument, 0, OPT_PASSPHRASE },
|
||||
@ -195,6 +197,7 @@ const char * option_help[] = {
|
||||
"Specify label of PIN/key",
|
||||
"Specify public key label (use with --generate-key)",
|
||||
"Specify user cert label (use with --store-private-key)",
|
||||
"Specify application id of data object (use with --store-data-object)",
|
||||
"Output public portion of generated key to file",
|
||||
"Specify key file format (default PEM)",
|
||||
"Specify passphrase for unlocking secret key",
|
||||
@ -287,6 +290,7 @@ static char * opt_serial = 0;
|
||||
static char * opt_passphrase = 0;
|
||||
static char * opt_newkey = 0;
|
||||
static char * opt_outkey = 0;
|
||||
static char * opt_application_id = 0;
|
||||
static unsigned int opt_x509_usage = 0;
|
||||
static int ignore_cmdline_pins = 0;
|
||||
static struct secret opt_secrets[MAX_SECRETS];
|
||||
@ -872,6 +876,9 @@ do_store_data_object(struct sc_profile *profile)
|
||||
if (opt_authid)
|
||||
sc_pkcs15_format_id(opt_authid, &args.auth_id);
|
||||
args.label = opt_label;
|
||||
args.app_label = "pkcs15-init";
|
||||
|
||||
parse_application_id(&args.app_oid, opt_application_id);
|
||||
|
||||
r = do_read_data_object(opt_infile, &data, &datalen);
|
||||
if (r >= 0) {
|
||||
@ -1913,6 +1920,9 @@ handle_option(const struct option *opt)
|
||||
case OPT_SOFT_KEYGEN:
|
||||
opt_softkeygen = 1;
|
||||
break;
|
||||
case OPT_APPLICATION_ID:
|
||||
opt_application_id = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
opt_use_defkeys = 1;
|
||||
break;
|
||||
|
@ -270,3 +270,24 @@ warn(const char *fmt, ...)
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
void parse_application_id(struct sc_object_id *oid, char *oid_str)
|
||||
{
|
||||
int ii;
|
||||
char *nb;
|
||||
|
||||
if (!oid)
|
||||
return;
|
||||
|
||||
for (ii=0; ii<SC_MAX_OBJECT_ID_OCTETS; ii++)
|
||||
oid->value[ii] = -1;
|
||||
|
||||
nb = strtok(oid_str, ".");
|
||||
for (ii=0; nb && ii < SC_MAX_OBJECT_ID_OCTETS; ii++) {
|
||||
oid->value[ii] = strtol(nb, NULL, 10);
|
||||
nb = strtok(NULL, ".");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@ void fatal(const char *fmt, ...);
|
||||
/* All singing all dancing card connect routine */
|
||||
int connect_card(struct sc_context *, struct sc_card **,
|
||||
int reader_id, int slot_id, int wait, int verbose);
|
||||
void parse_application_id(struct sc_object_id *oid, char *oid_str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user