aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-07-15 16:25:30 +0200
committerMartin Willi <martin@revosec.ch>2010-08-04 09:26:20 +0200
commitd007ce320626ea504be547afef79851142b24c41 (patch)
tree7d0747fb32d34808582e72310f0e6bbf2a5bb76b
parentddbac66028254bda0bd2aaedac44e16728ca564d (diff)
downloadstrongswan-d007ce320626ea504be547afef79851142b24c41.tar.bz2
strongswan-d007ce320626ea504be547afef79851142b24c41.tar.xz
Extended the PKCS#11 object enumerator by attribute retrieval
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_creds.c90
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.c79
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.h11
3 files changed, 111 insertions, 69 deletions
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
index 2984c70d3..f46161488 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
@@ -52,68 +52,6 @@ struct private_pkcs11_creds_t {
};
/**
- * Handle a certificate object, optionally trusted
- */
-static void handle_certificate(private_pkcs11_creds_t *this,
- CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
- CK_BBOOL trusted)
-{
- CK_ATTRIBUTE attrs[] = {
- {CKA_VALUE, NULL, 0},
- {CKA_LABEL, NULL, 0},
- };
- CK_RV rv;
- certificate_t *cert;
-
- rv = this->lib->f->C_GetAttributeValue(session, object,
- attrs, countof(attrs));
- if (rv != CKR_OK)
- {
- DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
- return;
- }
- if (attrs[0].ulValueLen)
- {
- attrs[0].pValue = malloc(attrs[0].ulValueLen);
- }
- if (attrs[1].ulValueLen)
- {
- attrs[1].pValue = malloc(attrs[1].ulValueLen);
- }
- rv = this->lib->f->C_GetAttributeValue(session, object,
- attrs, countof(attrs));
- if (rv == CKR_OK)
- {
- cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER,
- chunk_create(attrs[0].pValue, attrs[0].ulValueLen),
- BUILD_END);
- if (cert)
- {
- DBG1(DBG_CFG, " loaded %strusted cert '%.*s'",
- trusted ? "" : "un", attrs[1].ulValueLen, attrs[1].pValue);
- /* trusted certificates are also returned as untrusted */
- this->untrusted->insert_last(this->untrusted, cert);
- if (trusted)
- {
- this->trusted->insert_last(this->trusted, cert->get_ref(cert));
- }
- }
- else
- {
- DBG1(DBG_CFG, " loading cert '%.*s' failed",
- attrs[1].ulValueLen, attrs[1].pValue);
- }
- }
- else
- {
- DBG1(DBG_CFG, "C_GetAttributeValue() error: %N", ck_rv_names, rv);
- }
- free(attrs[0].pValue);
- free(attrs[1].pValue);
-}
-
-/**
* Find certificates, optionally trusted
*/
static void find_certificates(private_pkcs11_creds_t *this,
@@ -121,19 +59,41 @@ static void find_certificates(private_pkcs11_creds_t *this,
{
CK_OBJECT_CLASS class = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE type = CKC_X_509;
- CK_ATTRIBUTE template[] = {
+ CK_ATTRIBUTE tmpl[] = {
{CKA_CLASS, &class, sizeof(class)},
{CKA_CERTIFICATE_TYPE, &type, sizeof(type)},
{CKA_TRUSTED, &trusted, sizeof(trusted)},
};
CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attr[] = {
+ {CKA_VALUE, NULL, 0},
+ {CKA_LABEL, NULL, 0},
+ };
enumerator_t *enumerator;
+ certificate_t *cert;
enumerator = this->lib->create_object_enumerator(this->lib,
- session, template, countof(template));
+ session, tmpl, countof(tmpl), attr, countof(attr));
while (enumerator->enumerate(enumerator, &object))
{
- handle_certificate(this, session, object, trusted);
+ cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
+ BUILD_BLOB_ASN1_DER,
+ chunk_create(attr[0].pValue, attr[0].ulValueLen),
+ BUILD_END);
+ if (!cert)
+ {
+ DBG1(DBG_CFG, " loading cert '%.*s' failed",
+ attr[1].ulValueLen, attr[1].pValue);
+ continue;
+ }
+ DBG1(DBG_CFG, " loaded %strusted cert '%.*s'",
+ trusted ? "" : "un", attr[1].ulValueLen, attr[1].pValue);
+ /* trusted certificates are also returned as untrusted */
+ this->untrusted->insert_last(this->untrusted, cert);
+ if (trusted)
+ {
+ this->trusted->insert_last(this->trusted, cert->get_ref(cert));
+ }
}
enumerator->destroy(enumerator);
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
index 286b807ed..d3335dd21 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
@@ -20,6 +20,7 @@
#include <library.h>
#include <debug.h>
#include <threading/mutex.h>
+#include <utils/linked_list.h>
typedef struct private_pkcs11_library_t private_pkcs11_library_t;
@@ -483,8 +484,69 @@ typedef struct {
CK_SESSION_HANDLE session;
/* pkcs11 library */
pkcs11_library_t *lib;
+ /* attributes to retreive */
+ CK_ATTRIBUTE_PTR attr;
+ /* number of attributes */
+ CK_ULONG count;
+ /* currently allocated attributes, to free */
+ linked_list_t *freelist;
} object_enumerator_t;
+/**
+ * Free contents of attributes in a list
+ */
+static void free_attrs(object_enumerator_t *this)
+{
+ CK_ATTRIBUTE_PTR attr;
+
+ while (this->freelist->remove_last(this->freelist, (void**)&attr) == SUCCESS)
+ {
+ free(attr->pValue);
+ attr->pValue = NULL;
+ attr->ulValueLen = 0;
+ }
+}
+
+/**
+ * Get attributes for a given object during enumeration
+ */
+static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object)
+{
+ CK_RV rv;
+ int i;
+
+ free_attrs(this);
+
+ /* get length of objects first */
+ rv = this->lib->f->C_GetAttributeValue(this->session, object,
+ this->attr, this->count);
+ if (rv != CKR_OK)
+ {
+ DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ /* allocate required chunks */
+ for (i = 0; i < this->count; i++)
+ {
+ if (this->attr[i].pValue == NULL &&
+ this->attr[i].ulValueLen != 0 && this->attr[i].ulValueLen != -1)
+ {
+ this->attr[i].pValue = malloc(this->attr[i].ulValueLen);
+ this->freelist->insert_last(this->freelist, &this->attr[i]);
+ }
+ }
+ /* get the data */
+ rv = this->lib->f->C_GetAttributeValue(this->session, object,
+ this->attr, this->count);
+ if (rv != CKR_OK)
+ {
+ free_attrs(this);
+ DBG1(DBG_CFG, "C_GetAttributeValue(NULL) error: %N", ck_rv_names, rv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
METHOD(enumerator_t, object_enumerate, bool,
object_enumerator_t *this, CK_OBJECT_HANDLE *out)
{
@@ -500,6 +562,13 @@ METHOD(enumerator_t, object_enumerate, bool,
}
if (found)
{
+ if (this->attr)
+ {
+ if (!get_attributes(this, object))
+ {
+ return FALSE;
+ }
+ }
*out = object;
return TRUE;
}
@@ -510,17 +579,20 @@ METHOD(enumerator_t, object_destroy, void,
object_enumerator_t *this)
{
this->lib->f->C_FindObjectsFinal(this->session);
+ free_attrs(this);
+ this->freelist->destroy(this->freelist);
free(this);
}
METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
private_pkcs11_library_t *this, CK_SESSION_HANDLE session,
- CK_ATTRIBUTE_PTR tmpl, CK_ULONG count)
+ CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount,
+ CK_ATTRIBUTE_PTR attr, CK_ULONG acount)
{
object_enumerator_t *enumerator;
CK_RV rv;
- rv = this->public.f->C_FindObjectsInit(session, tmpl, count);
+ rv = this->public.f->C_FindObjectsInit(session, tmpl, tcount);
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_FindObjectsInit() failed: %N", ck_rv_names, rv);
@@ -534,6 +606,9 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*,
},
.session = session,
.lib = &this->public,
+ .attr = attr,
+ .count = acount,
+ .freelist = linked_list_create(),
);
return &enumerator->public;
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
index c1f7de0e6..3cca06678 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
@@ -48,12 +48,19 @@ struct pkcs11_library_t {
/**
* Create an enumerator over CK_OBJECT_HANDLE using a search template.
*
+ * An optional attribute array is automatically filled in with the
+ * objects associated attributes. If the value of an output attribute
+ * is NULL, the value gets allocated/freed during enumeration.
+ *
* @param session session to use
* @param tmpl search template
- * @param count number of attributes in the search template
+ * @param tcount number of attributes in the search template
+ * @param attr attributes to read from object
+ * @param acount number of attributes to read
*/
enumerator_t* (*create_object_enumerator)(pkcs11_library_t *this,
- CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR tmpl, CK_ULONG count);
+ CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount,
+ CK_ATTRIBUTE_PTR attr, CK_ULONG acount);
/**
* Destroy a pkcs11_library_t.