pkcs11: Implement PKCS #11 3.0 Profile object and its handling in tools
This commit is contained in:
parent
7f9e8ba85c
commit
db18a72c64
|
@ -126,6 +126,12 @@ struct pkcs15_data_object {
|
|||
#define data_p15obj base.p15_object
|
||||
#define is_data(obj) (__p15_type(obj) == SC_PKCS15_TYPE_DATA_OBJECT)
|
||||
|
||||
struct pkcs15_profile_object {
|
||||
struct pkcs15_any_object base;
|
||||
|
||||
unsigned long profile_id;
|
||||
};
|
||||
|
||||
struct pkcs15_skey_object {
|
||||
struct pkcs15_any_object base;
|
||||
|
||||
|
@ -142,6 +148,7 @@ 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;
|
||||
extern struct sc_pkcs11_object_ops pkcs15_profile_ops;
|
||||
extern struct sc_pkcs11_object_ops pkcs15_skey_ops;
|
||||
|
||||
const CK_BYTE gostr3410_paramset_A_encoded_oid[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
|
||||
|
@ -811,6 +818,32 @@ __pkcs15_create_data_object(struct pkcs15_fw_data *fw_data,
|
|||
return rv;
|
||||
}
|
||||
|
||||
/* Note, that this is not actuall PKCS #15 object, but just bogus
|
||||
* structure to create PKCS #11 object. There is no corresponding
|
||||
* PKCS #15 object. */
|
||||
static int
|
||||
__pkcs15_create_profile_object(struct pkcs15_fw_data *fw_data,
|
||||
int public_certificates, struct pkcs15_any_object **profile_object)
|
||||
{
|
||||
struct pkcs15_profile_object *pobj = NULL;
|
||||
struct sc_pkcs15_object *obj = NULL;
|
||||
int rv;
|
||||
|
||||
obj = calloc(1, sizeof(struct sc_pkcs15_object));
|
||||
|
||||
rv = __pkcs15_create_object(fw_data, (struct pkcs15_any_object **) &pobj,
|
||||
obj, &pkcs15_profile_ops, sizeof(struct pkcs15_profile_object));
|
||||
if (rv >= 0) {
|
||||
pobj->profile_id = public_certificates ? CKP_PUBLIC_CERTIFICATES_TOKEN : CKP_AUTHENTICATION_TOKEN;
|
||||
}
|
||||
|
||||
if (profile_object != NULL)
|
||||
*profile_object = (struct pkcs15_any_object *) pobj;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
__pkcs15_create_secret_key_object(struct pkcs15_fw_data *fw_data,
|
||||
|
@ -1430,6 +1463,10 @@ _add_pin_related_objects(struct sc_pkcs11_slot *slot, struct sc_pkcs15_object *p
|
|||
static void
|
||||
_add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data)
|
||||
{
|
||||
/* Public Certificates Token in PKCS #11 3.0 */
|
||||
struct pkcs15_any_object *pobj = NULL;
|
||||
int public_certificates = 1;
|
||||
CK_RV rv;
|
||||
unsigned i;
|
||||
|
||||
if (slot == NULL || fw_data == NULL)
|
||||
|
@ -1446,8 +1483,15 @@ _add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data)
|
|||
if (obj->base.flags & SC_PKCS11_OBJECT_SEEN)
|
||||
continue;
|
||||
/* Ignore 'private' object */
|
||||
if (obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE)
|
||||
if (obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE) {
|
||||
/* If we found some non-accessible public object,
|
||||
* we can no longer claim Public Ceritificate Token conformance */
|
||||
if (obj->p15_object->type & SC_PKCS15_TYPE_PUBKEY ||
|
||||
obj->p15_object->type & SC_PKCS15_TYPE_CERT) {
|
||||
public_certificates = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* PKCS#15 4.1.3 is a little vague, but implies if not PRIVATE it is readable
|
||||
* even if there is an auth_id to allow writing for example.
|
||||
* See bug issue #291
|
||||
|
@ -1456,9 +1500,20 @@ _add_public_objects(struct sc_pkcs11_slot *slot, struct pkcs15_fw_data *fw_data)
|
|||
if (obj->p15_object->auth_id.len && !(is_pubkey(obj) || is_cert(obj)))
|
||||
continue;
|
||||
|
||||
sc_log(context, "Add public object(%p,%.*s,%x)", obj, (int) sizeof obj->p15_object->label, obj->p15_object->label, obj->p15_object->type);
|
||||
sc_log(context, "Add public object(%p,%.*s,%x)", obj,
|
||||
(int) sizeof obj->p15_object->label, obj->p15_object->label,
|
||||
obj->p15_object->type);
|
||||
pkcs15_add_object(slot, obj, NULL);
|
||||
}
|
||||
|
||||
/* If all certificates and public keys are visible, we can claim conformance
|
||||
* to Public Certificate Token profile, making life easier for many applications
|
||||
* saying, they do not need to login to see all keys available */
|
||||
rv = __pkcs15_create_profile_object(fw_data, public_certificates, &pobj);
|
||||
if (rv != CKR_OK || pobj == NULL) {
|
||||
return;
|
||||
}
|
||||
pkcs15_add_object(slot, pobj, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -4949,6 +5004,66 @@ struct sc_pkcs11_object_ops pkcs15_dobj_ops = {
|
|||
NULL /* wrap_key */
|
||||
};
|
||||
|
||||
/* PKCS#15 Data Object*/
|
||||
static void
|
||||
pkcs15_profile_release(void *object)
|
||||
{
|
||||
__pkcs15_release_object((struct pkcs15_any_object *) object);
|
||||
}
|
||||
|
||||
|
||||
static CK_RV
|
||||
pkcs15_profile_set_attribute(struct sc_pkcs11_session *session,
|
||||
void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
/* Profile object is not writable */
|
||||
return CKR_ACTION_PROHIBITED;
|
||||
}
|
||||
|
||||
static CK_RV
|
||||
pkcs15_profile_get_attribute(struct sc_pkcs11_session *session, void *object, CK_ATTRIBUTE_PTR attr)
|
||||
{
|
||||
struct pkcs15_profile_object *pobj = (struct pkcs15_profile_object*) object;
|
||||
|
||||
sc_log(context, "pkcs15_profile_get_attribute() called");
|
||||
switch (attr->type) {
|
||||
case CKA_CLASS:
|
||||
check_attribute_buffer(attr, sizeof(CK_OBJECT_CLASS));
|
||||
*(CK_OBJECT_CLASS*)attr->pValue = CKO_PROFILE;
|
||||
break;
|
||||
case CKA_PRIVATE:
|
||||
/* This is needed internally for the object to be visible */
|
||||
check_attribute_buffer(attr, sizeof(CK_BBOOL));
|
||||
*(CK_BBOOL*)attr->pValue = CK_FALSE;
|
||||
break;
|
||||
case CKA_PROFILE_ID:
|
||||
/* TODO */
|
||||
check_attribute_buffer(attr, sizeof(CK_ULONG));
|
||||
*(CK_ULONG*)attr->pValue = pobj->profile_id;
|
||||
break;
|
||||
default:
|
||||
return CKR_ATTRIBUTE_TYPE_INVALID;
|
||||
}
|
||||
|
||||
return CKR_OK;
|
||||
}
|
||||
struct sc_pkcs11_object_ops pkcs15_profile_ops = {
|
||||
pkcs15_profile_release,
|
||||
pkcs15_profile_set_attribute,
|
||||
pkcs15_profile_get_attribute,
|
||||
sc_pkcs11_any_cmp_attribute,
|
||||
pkcs15_any_destroy,
|
||||
NULL, /* get_size */
|
||||
NULL, /* sign */
|
||||
NULL, /* unwrap_key */
|
||||
NULL, /* decrypt */
|
||||
NULL, /* derive */
|
||||
NULL, /* can_do */
|
||||
NULL, /* init_params */
|
||||
NULL /* wrap_key */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* PKCS#15 Secret Key Objects */
|
||||
/* TODO Currently only session objects */
|
||||
|
|
|
@ -250,6 +250,7 @@ static enum_specs ck_cls_s[] = {
|
|||
{ CKO_PUBLIC_KEY , "CKO_PUBLIC_KEY " },
|
||||
{ CKO_PRIVATE_KEY , "CKO_PRIVATE_KEY " },
|
||||
{ CKO_SECRET_KEY , "CKO_SECRET_KEY " },
|
||||
{ CKO_PROFILE , "CKO_PROFILE " },
|
||||
{ CKO_HW_FEATURE , "CKO_HW_FEATURE " },
|
||||
{ CKO_DOMAIN_PARAMETERS, "CKO_DOMAIN_PARAMETERS" },
|
||||
{ CKO_NETSCAPE_CRL, "CKO_NETSCAPE_CRL " },
|
||||
|
@ -259,6 +260,15 @@ static enum_specs ck_cls_s[] = {
|
|||
{ CKO_VENDOR_DEFINED , "CKO_VENDOR_DEFINED " }
|
||||
};
|
||||
|
||||
enum_specs ck_profile_s[] = {
|
||||
{ CKP_INVALID_ID , "CKP_INVALID_ID " },
|
||||
{ CKP_BASELINE_PROVIDER , "CKP_BASELINE_PROVIDER " },
|
||||
{ CKP_EXTENDED_PROVIDER , "CKP_EXTENDED_PROVIDER " },
|
||||
{ CKP_AUTHENTICATION_TOKEN , "CKP_AUTHENTICATION_TOKEN " },
|
||||
{ CKP_PUBLIC_CERTIFICATES_TOKEN, "CKP_PUBLIC_CERTIFICATES_TOKEN" },
|
||||
{ CKP_VENDOR_DEFINED , "CKP_VENDOR_DEFINED " }
|
||||
};
|
||||
|
||||
static enum_specs ck_crt_s[] = {
|
||||
{ CKC_X_509, "CKC_X_509" },
|
||||
{ CKC_X_509_ATTR_CERT, "CKC_X_509_ATTR_CERT" },
|
||||
|
@ -657,6 +667,7 @@ static enum_specs ck_ckd_s[] = {
|
|||
|
||||
enum_spec ck_types[] = {
|
||||
{ OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" },
|
||||
{ PROFILE_T, ck_profile_s, sizeof(ck_profile_s)/SZ_SPECS, "CK_PROFILE"},
|
||||
{ KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" },
|
||||
{ CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" },
|
||||
{ MEC_T, ck_mec_s, sizeof(ck_mec_s) / SZ_SPECS, "CK_MECHANISM_TYPE" },
|
||||
|
@ -670,6 +681,7 @@ enum_spec ck_types[] = {
|
|||
static enum_spec ck_key_t[] = { { KEY_T, ck_key_s, sizeof(ck_key_s) / SZ_SPECS, "CK_KEY_TYPE" } };
|
||||
static enum_spec ck_cls_t[] = { { OBJ_T, ck_cls_s, sizeof(ck_cls_s) / SZ_SPECS, "CK_OBJECT_CLASS" } };
|
||||
static enum_spec ck_crt_t[] = { { CRT_T, ck_crt_s, sizeof(ck_crt_s) / SZ_SPECS, "CK_CERTIFICATE_TYPE" } };
|
||||
static enum_spec ck_profile_t[] = { { PROFILE_T, ck_profile_s, sizeof(ck_profile_s) / SZ_SPECS, "CK_PROFILE" } };
|
||||
|
||||
type_spec ck_attribute_specs[] = {
|
||||
{ CKA_CLASS , "CKA_CLASS ", print_enum, ck_cls_t },
|
||||
|
@ -781,6 +793,7 @@ type_spec ck_attribute_specs[] = {
|
|||
{ CKA_ENCODING_METHODS , "CKA_ENCODING_METHODS ", print_generic, NULL },
|
||||
{ CKA_MIME_TYPES , "CKA_MIME_TYPES ", print_generic, NULL },
|
||||
{ CKA_MECHANISM_TYPE , "CKA_MECHANISM_TYPE ", print_generic, NULL },
|
||||
{ CKA_PROFILE_ID , "CKA_PROFILE_ID ", print_enum, ck_profile_t },
|
||||
{ CKA_REQUIRED_CMS_ATTRIBUTES, "CKA_REQUIRED_CMS_ATTRIBUTES ", print_generic, NULL },
|
||||
{ CKA_DEFAULT_CMS_ATTRIBUTES, "CKA_DEFAULT_CMS_ATTRIBUTES ", print_generic, NULL },
|
||||
{ CKA_SUPPORTED_CMS_ATTRIBUTES, "CKA_SUPPORTED_CMS_ATTRIBUTES ", print_generic, NULL },
|
||||
|
|
|
@ -53,6 +53,7 @@ typedef struct {
|
|||
|
||||
enum ck_type{
|
||||
OBJ_T,
|
||||
PROFILE_T,
|
||||
KEY_T,
|
||||
CRT_T,
|
||||
MEC_T,
|
||||
|
|
|
@ -321,8 +321,16 @@ typedef unsigned long ck_object_class_t;
|
|||
#define CKO_HW_FEATURE (5UL)
|
||||
#define CKO_DOMAIN_PARAMETERS (6UL)
|
||||
#define CKO_MECHANISM (7UL)
|
||||
#define CKO_OTP_KEY (8UL)
|
||||
#define CKO_PROFILE (9UL)
|
||||
#define CKO_VENDOR_DEFINED (1UL << 31)
|
||||
|
||||
#define CKP_INVALID_ID (0UL)
|
||||
#define CKP_BASELINE_PROVIDER (1UL)
|
||||
#define CKP_EXTENDED_PROVIDER (2UL)
|
||||
#define CKP_AUTHENTICATION_TOKEN (3UL)
|
||||
#define CKP_PUBLIC_CERTIFICATES_TOKEN (4UL)
|
||||
#define CKP_VENDOR_DEFINED (1UL << 31)
|
||||
|
||||
typedef unsigned long ck_hw_feature_type_t;
|
||||
|
||||
|
@ -482,6 +490,7 @@ typedef unsigned long ck_attribute_type_t;
|
|||
#define CKA_OTP_COUNTER (0x22EUL)
|
||||
#define CKA_OTP_TIME (0x22FUL)
|
||||
#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL)
|
||||
#define CKA_PROFILE_ID (0x601UL)
|
||||
#define CKA_VENDOR_DEFINED (1UL << 31)
|
||||
|
||||
|
||||
|
@ -1506,6 +1515,7 @@ struct ck_c_initialize_args
|
|||
#define CKR_ATTRIBUTE_SENSITIVE (0x11UL)
|
||||
#define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL)
|
||||
#define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL)
|
||||
#define CKR_ACTION_PROHIBITED (0x1BUL)
|
||||
#define CKR_DATA_INVALID (0x20UL)
|
||||
#define CKR_DATA_LEN_RANGE (0x21UL)
|
||||
#define CKR_DEVICE_ERROR (0x30UL)
|
||||
|
|
|
@ -437,6 +437,7 @@ static void show_object(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
|||
static void show_key(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void show_cert(CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
|
||||
static void show_profile(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj);
|
||||
static void sign_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void verify_signature(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
static void decrypt_data(CK_SLOT_ID, CK_SESSION_HANDLE, CK_OBJECT_HANDLE);
|
||||
|
@ -554,6 +555,7 @@ ATTR_METHOD(KEY_TYPE, CK_KEY_TYPE); /* getKEY_TYPE */
|
|||
ATTR_METHOD(CERTIFICATE_TYPE, CK_CERTIFICATE_TYPE); /* getCERTIFICATE_TYPE */
|
||||
ATTR_METHOD(MODULUS_BITS, CK_ULONG); /* getMODULUS_BITS */
|
||||
ATTR_METHOD(VALUE_LEN, CK_ULONG); /* getVALUE_LEN */
|
||||
ATTR_METHOD(PROFILE_ID, CK_ULONG); /* getPROFILE_ID */
|
||||
VARATTR_METHOD(LABEL, char); /* getLABEL */
|
||||
VARATTR_METHOD(APPLICATION, char); /* getAPPLICATION */
|
||||
VARATTR_METHOD(ID, unsigned char); /* getID */
|
||||
|
@ -3740,6 +3742,9 @@ static void show_object(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
|||
case CKO_DATA:
|
||||
show_dobj(sess, obj);
|
||||
break;
|
||||
case CKO_PROFILE:
|
||||
show_profile(sess, obj);
|
||||
break;
|
||||
default:
|
||||
printf("Object %u, type %u\n",
|
||||
(unsigned int) obj,
|
||||
|
@ -4303,6 +4308,20 @@ static void show_dobj(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
|||
}
|
||||
|
||||
|
||||
static void show_profile(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj)
|
||||
{
|
||||
CK_ULONG id = 0;
|
||||
|
||||
printf("Profile object %u\n", (unsigned int) obj);
|
||||
printf(" profile_id: ");
|
||||
if ((id = getPROFILE_ID(sess, obj)) != 0) {
|
||||
printf("'%lu'\n", id);
|
||||
} else {
|
||||
printf("<empty>\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_token_info(CK_SLOT_ID slot, CK_TOKEN_INFO_PTR info)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue