summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/pkcs11/pkcs11_library.c')
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.c203
1 files changed, 194 insertions, 9 deletions
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
index 6f7926808..97c3d2fcf 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (C) 2011 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
@@ -447,6 +450,123 @@ ENUM_NEXT(ck_mech_names, CKM_DSA_PARAMETER_GEN, CKM_X9_42_DH_PARAMETER_GEN,
"X9_42_DH_PARAMETER_GEN");
ENUM_END(ck_mech_names, CKM_X9_42_DH_PARAMETER_GEN);
+
+ENUM_BEGIN(ck_attr_names, CKA_CLASS, CKA_LABEL,
+ "CLASS",
+ "TOKEN",
+ "PRIVATE",
+ "LABEL");
+ENUM_NEXT(ck_attr_names, CKA_APPLICATION, CKA_OBJECT_ID, CKA_LABEL,
+ "APPLICATION",
+ "VALUE",
+ "OBJECT_ID");
+ENUM_NEXT(ck_attr_names, CKA_CERTIFICATE_TYPE, CKA_HASH_OF_ISSUER_PUBLIC_KEY,
+ CKA_OBJECT_ID,
+ "CERTIFICATE_TYPE",
+ "ISSUER",
+ "SERIAL_NUMBER",
+ "AC_ISSUER",
+ "OWNER",
+ "ATTR_TYPES",
+ "TRUSTED",
+ "CERTIFICATE_CATEGORY",
+ "JAVA_MIDP_SECURITY_DOMAIN",
+ "URL",
+ "HASH_OF_SUBJECT_PUBLIC_KEY",
+ "HASH_OF_ISSUER_PUBLIC_KEY");
+ENUM_NEXT(ck_attr_names, CKA_CHECK_VALUE, CKA_CHECK_VALUE,
+ CKA_HASH_OF_ISSUER_PUBLIC_KEY,
+ "CHECK_VALUE");
+ENUM_NEXT(ck_attr_names, CKA_KEY_TYPE, CKA_DERIVE, CKA_CHECK_VALUE,
+ "KEY_TYPE",
+ "SUBJECT",
+ "ID",
+ "SENSITIVE",
+ "ENCRYPT",
+ "DECRYPT",
+ "WRAP",
+ "UNWRAP",
+ "SIGN",
+ "SIGN_RECOVER",
+ "VERIFY",
+ "VERIFY_RECOVER",
+ "DERIVE");
+ENUM_NEXT(ck_attr_names, CKA_START_DATE, CKA_END_DATE, CKA_DERIVE,
+ "START_DATE",
+ "END_DATE");
+ENUM_NEXT(ck_attr_names, CKA_MODULUS, CKA_COEFFICIENT, CKA_END_DATE,
+ "MODULUS",
+ "MODULUS_BITS",
+ "PUBLIC_EXPONENT",
+ "PRIVATE_EXPONENT",
+ "PRIME_1",
+ "PRIME_2",
+ "EXPONENT_1",
+ "EXPONENT_2",
+ "COEFFICIENT");
+ENUM_NEXT(ck_attr_names, CKA_PRIME, CKA_SUB_PRIME_BITS, CKA_COEFFICIENT,
+ "PRIME",
+ "SUBPRIME",
+ "BASE",
+ "PRIME_BITS",
+ "SUB_PRIME_BITS");
+ENUM_NEXT(ck_attr_names, CKA_VALUE_BITS, CKA_KEY_GEN_MECHANISM,
+ CKA_SUB_PRIME_BITS,
+ "VALUE_BITS",
+ "VALUE_LEN",
+ "EXTRACTABLE",
+ "LOCAL",
+ "NEVER_EXTRACTABLE",
+ "ALWAYS_SENSITIVE",
+ "KEY_GEN_MECHANISM");
+ENUM_NEXT(ck_attr_names, CKA_MODIFIABLE, CKA_MODIFIABLE, CKA_KEY_GEN_MECHANISM,
+ "MODIFIABLE");
+ENUM_NEXT(ck_attr_names, CKA_EC_PARAMS, CKA_EC_POINT, CKA_MODIFIABLE,
+ "EC_PARAMS",
+ "EC_POINT");
+ENUM_NEXT(ck_attr_names, CKA_SECONDARY_AUTH, CKA_ALWAYS_AUTHENTICATE,
+ CKA_EC_POINT,
+ "SECONDARY_AUTH",
+ "AUTH_PIN_FLAGS",
+ "ALWAYS_AUTHENTICATE");
+ENUM_NEXT(ck_attr_names, CKA_WRAP_WITH_TRUSTED, CKA_WRAP_WITH_TRUSTED,
+ CKA_ALWAYS_AUTHENTICATE,
+ "WRAP_WITH_TRUSTED");
+ENUM_NEXT(ck_attr_names, CKA_HW_FEATURE_TYPE, CKA_HAS_RESET,
+ CKA_WRAP_WITH_TRUSTED,
+ "HW_FEATURE_TYPE",
+ "RESET_ON_INIT",
+ "HAS_RESET");
+ENUM_NEXT(ck_attr_names, CKA_PIXEL_X, CKA_BITS_PER_PIXEL, CKA_HAS_RESET,
+ "PIXEL_X",
+ "RESOLUTION",
+ "CHAR_ROWS",
+ "CHAR_COLUMNS",
+ "COLOR",
+ "BITS_PER_PIXEL");
+ENUM_NEXT(ck_attr_names, CKA_CHAR_SETS, CKA_MIME_TYPES, CKA_BITS_PER_PIXEL,
+ "CHAR_SETS",
+ "ENCODING_METHODS",
+ "MIME_TYPES");
+ENUM_NEXT(ck_attr_names, CKA_MECHANISM_TYPE, CKA_SUPPORTED_CMS_ATTRIBUTES,
+ CKA_MIME_TYPES,
+ "MECHANISM_TYPE",
+ "REQUIRED_CMS_ATTRIBUTES",
+ "DEFAULT_CMS_ATTRIBUTES",
+ "SUPPORTED_CMS_ATTRIBUTES");
+ENUM_NEXT(ck_attr_names, CKA_WRAP_TEMPLATE, CKA_UNWRAP_TEMPLATE,
+ CKA_SUPPORTED_CMS_ATTRIBUTES,
+ "WRAP_TEMPLATE",
+ "UNWRAP_TEMPLATE");
+ENUM_NEXT(ck_attr_names, CKA_ALLOWED_MECHANISMS, CKA_ALLOWED_MECHANISMS,
+ CKA_UNWRAP_TEMPLATE,
+ "ALLOWED_MECHANISMS");
+ENUM_END(ck_attr_names, CKA_ALLOWED_MECHANISMS);
+/* the values in an enum_name_t are stored as int, thus CKA_VENDOR_DEFINED
+ * will overflow and is thus not defined here */
+
+
+
/**
* Private data of an pkcs11_library_t object.
*/
@@ -495,10 +615,12 @@ typedef struct {
CK_SESSION_HANDLE session;
/* pkcs11 library */
pkcs11_library_t *lib;
- /* attributes to retreive */
+ /* attributes to retrieve */
CK_ATTRIBUTE_PTR attr;
/* number of attributes */
CK_ULONG count;
+ /* object handle in case of a single object */
+ CK_OBJECT_HANDLE object;
/* currently allocated attributes, to free */
linked_list_t *freelist;
} object_enumerator_t;
@@ -552,7 +674,7 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
if (rv != CKR_OK)
{
free_attrs(this);
- DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
+ DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
return FALSE;
}
return TRUE;
@@ -565,11 +687,19 @@ METHOD(enumerator_t, object_enumerate, bool,
CK_ULONG found;
CK_RV rv;
- rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
- if (rv != CKR_OK)
+ if (!this->object)
{
- DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
- return FALSE;
+ rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_FindObjects() failed: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ }
+ else
+ {
+ object = this->object;
+ found = 1;
}
if (found)
{
@@ -580,7 +710,10 @@ METHOD(enumerator_t, object_enumerate, bool,
return FALSE;
}
}
- *out = object;
+ if (out)
+ {
+ *out = object;
+ }
return TRUE;
}
return FALSE;
@@ -589,7 +722,10 @@ METHOD(enumerator_t, object_enumerate, bool,
METHOD(enumerator_t, object_destroy, void,
object_enumerator_t *this)
{
- this->lib->f->C_FindObjectsFinal(this->session);
+ if (!this->object)
+ {
+ this->lib->f->C_FindObjectsFinal(this->session);
+ }
free_attrs(this);
this->freelist->destroy(this->freelist);
free(this);
@@ -624,6 +760,27 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
return &enumerator->public;
}
+METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*,
+ private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attr, CK_ULONG count)
+{
+ object_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)_object_enumerate,
+ .destroy = _object_destroy,
+ },
+ .session = session,
+ .lib = &this->public,
+ .attr = attr,
+ .count = count,
+ .object = object,
+ .freelist = linked_list_create(),
+ );
+ return &enumerator->public;
+}
+
/**
* Enumerator over mechanisms
*/
@@ -707,6 +864,32 @@ METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*,
return &enumerator->public;
}
+METHOD(pkcs11_library_t, get_ck_attribute, bool,
+ private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE obj, CK_ATTRIBUTE_TYPE type, chunk_t *data)
+{
+ CK_ATTRIBUTE attr = { type, NULL, 0 };
+ CK_RV rv;
+ rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
+ ck_rv_names, rv);
+ return FALSE;
+ }
+ *data = chunk_alloc(attr.ulValueLen);
+ attr.pValue = data->ptr;
+ rv = this->public.f->C_GetAttributeValue(session, obj, &attr, 1);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GetAttributeValue(%N) error: %N", ck_attr_names, type,
+ ck_rv_names, rv);
+ chunk_free(data);
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(pkcs11_library_t, destroy, void,
private_pkcs11_library_t *this)
{
@@ -739,7 +922,7 @@ void pkcs11_library_trim(char *str, int len)
*/
static CK_RV CreateMutex(CK_VOID_PTR_PTR data)
{
- *data = mutex_create(MUTEX_TYPE_DEFAULT);
+ *data = mutex_create(MUTEX_TYPE_RECURSIVE);
return CKR_OK;
}
@@ -889,7 +1072,9 @@ pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
.get_name = _get_name,
.get_features = _get_features,
.create_object_enumerator = _create_object_enumerator,
+ .create_object_attr_enumerator = _create_object_attr_enumerator,
.create_mechanism_enumerator = _create_mechanism_enumerator,
+ .get_ck_attribute = _get_ck_attribute,
.destroy = _destroy,
},
.name = name,