summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/pkcs11
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/pkcs11')
-rw-r--r--src/libstrongswan/plugins/pkcs11/Makefile.in4
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_creds.c23
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.c67
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_library.h21
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_manager.c5
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c14
-rw-r--r--src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c18
7 files changed, 118 insertions, 34 deletions
diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in
index c27310910..6c03b0497 100644
--- a/src/libstrongswan/plugins/pkcs11/Makefile.in
+++ b/src/libstrongswan/plugins/pkcs11/Makefile.in
@@ -223,9 +223,7 @@ includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
ipsecdir = @ipsecdir@
-ipsecgid = @ipsecgid@
ipsecgroup = @ipsecgroup@
-ipsecuid = @ipsecuid@
ipsecuser = @ipsecuser@
libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
@@ -264,6 +262,8 @@ sbindir = @sbindir@
scepclient_plugins = @scepclient_plugins@
scripts_plugins = @scripts_plugins@
sharedstatedir = @sharedstatedir@
+soup_CFLAGS = @soup_CFLAGS@
+soup_LIBS = @soup_LIBS@
srcdir = @srcdir@
strongswan_conf = @strongswan_conf@
sysconfdir = @sysconfdir@
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
index 1b1448c6a..a81ec1147 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c
@@ -55,19 +55,20 @@ struct private_pkcs11_creds_t {
* Find certificates, optionally trusted
*/
static void find_certificates(private_pkcs11_creds_t *this,
- CK_SESSION_HANDLE session, CK_BBOOL trusted)
+ CK_SESSION_HANDLE session)
{
CK_OBJECT_CLASS class = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE type = CKC_X_509;
+ CK_BBOOL trusted = TRUE;
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},
+ {CKA_TRUSTED, &trusted, sizeof(trusted)}
};
enumerator_t *enumerator;
linked_list_t *raw;
@@ -75,11 +76,19 @@ static void find_certificates(private_pkcs11_creds_t *this,
struct {
chunk_t value;
chunk_t label;
+ bool trusted;
} *entry;
+ int count = countof(attr);
+ /* store result in a temporary list, avoid recursive operation */
raw = linked_list_create();
+ /* do not use trusted argument if not supported */
+ if (!(this->lib->get_features(this->lib) & PKCS11_TRUSTED_CERTS))
+ {
+ count--;
+ }
enumerator = this->lib->create_object_enumerator(this->lib,
- session, tmpl, countof(tmpl), attr, countof(attr));
+ session, tmpl, countof(tmpl), attr, count);
while (enumerator->enumerate(enumerator, &object))
{
entry = malloc(sizeof(*entry));
@@ -87,6 +96,7 @@ static void find_certificates(private_pkcs11_creds_t *this,
chunk_create(attr[0].pValue, attr[0].ulValueLen));
entry->label = chunk_clone(
chunk_create(attr[1].pValue, attr[1].ulValueLen));
+ entry->trusted = trusted;
raw->insert_last(raw, entry);
}
enumerator->destroy(enumerator);
@@ -99,10 +109,10 @@ static void find_certificates(private_pkcs11_creds_t *this,
if (cert)
{
DBG1(DBG_CFG, " loaded %strusted cert '%.*s'",
- trusted ? "" : "un", entry->label.len, entry->label.ptr);
+ entry->trusted ? "" : "un", entry->label.len, entry->label.ptr);
/* trusted certificates are also returned as untrusted */
this->untrusted->insert_last(this->untrusted, cert);
- if (trusted)
+ if (entry->trusted)
{
this->trusted->insert_last(this->trusted, cert->get_ref(cert));
}
@@ -135,8 +145,7 @@ static bool load_certificates(private_pkcs11_creds_t *this)
return FALSE;
}
- find_certificates(this, session, CK_TRUE);
- find_certificates(this, session, CK_FALSE);
+ find_certificates(this, session);
this->lib->f->C_CloseSession(session);
return TRUE;
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
index 9fb1b7769..6f7926808 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c
@@ -466,6 +466,11 @@ struct private_pkcs11_library_t {
* Name as passed to the constructor
*/
char *name;
+
+ /**
+ * Supported feature set
+ */
+ pkcs11_feature_t features;
};
METHOD(pkcs11_library_t, get_name, char*,
@@ -474,6 +479,12 @@ METHOD(pkcs11_library_t, get_name, char*,
return this->name;
}
+METHOD(pkcs11_library_t, get_features, pkcs11_feature_t,
+ private_pkcs11_library_t *this)
+{
+ return this->features;
+}
+
/**
* Object enumerator
*/
@@ -766,19 +777,45 @@ static CK_RV UnlockMutex(CK_VOID_PTR data)
}
/**
+ * Check if the library has at least a given cryptoki version
+ */
+static bool has_version(CK_INFO *info, int major, int minor)
+{
+ return info->cryptokiVersion.major > major ||
+ (info->cryptokiVersion.major == major &&
+ info->cryptokiVersion.minor >= minor);
+}
+
+/**
+ * Check for optional PKCS#11 library functionality
+ */
+static void check_features(private_pkcs11_library_t *this, CK_INFO *info)
+{
+ if (has_version(info, 2, 20))
+ {
+ this->features |= PKCS11_TRUSTED_CERTS;
+ this->features |= PKCS11_ALWAYS_AUTH_KEYS;
+ }
+}
+
+/**
* Initialize a PKCS#11 library
*/
-static bool initialize(private_pkcs11_library_t *this, char *name, char *file)
+static bool initialize(private_pkcs11_library_t *this, char *name, char *file,
+ bool os_locking)
{
CK_C_GetFunctionList pC_GetFunctionList;
CK_INFO info;
CK_RV rv;
- CK_C_INITIALIZE_ARGS args = {
+ static CK_C_INITIALIZE_ARGS args = {
.CreateMutex = CreateMutex,
.DestroyMutex = DestroyMutex,
.LockMutex = LockMutex,
.UnlockMutex = UnlockMutex,
};
+ static CK_C_INITIALIZE_ARGS args_os = {
+ .flags = CKF_OS_LOCKING_OK,
+ };
pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList");
if (!pC_GetFunctionList)
@@ -793,14 +830,19 @@ static bool initialize(private_pkcs11_library_t *this, char *name, char *file)
name, ck_rv_names, rv);
return FALSE;
}
-
- rv = this->public.f->C_Initialize(&args);
- if (rv == CKR_CANT_LOCK)
- { /* try OS locking */
- memset(&args, 0, sizeof(args));
- args.flags = CKF_OS_LOCKING_OK;
+ if (os_locking)
+ {
+ rv = CKR_CANT_LOCK;
+ }
+ else
+ {
rv = this->public.f->C_Initialize(&args);
}
+ if (rv == CKR_CANT_LOCK)
+ { /* fallback to OS locking */
+ os_locking = TRUE;
+ rv = this->public.f->C_Initialize(&args_os);
+ }
if (rv != CKR_OK)
{
DBG1(DBG_CFG, "C_Initialize() error for '%s': %N",
@@ -826,23 +868,26 @@ static bool initialize(private_pkcs11_library_t *this, char *name, char *file)
DBG1(DBG_CFG, " %s: %s v%d.%d",
info.manufacturerID, info.libraryDescription,
info.libraryVersion.major, info.libraryVersion.minor);
- if (args.flags & CKF_OS_LOCKING_OK)
+ if (os_locking)
{
DBG1(DBG_CFG, " uses OS locking functions");
}
+
+ check_features(this, &info);
return TRUE;
}
/**
* See header
*/
-pkcs11_library_t *pkcs11_library_create(char *name, char *file)
+pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_locking)
{
private_pkcs11_library_t *this;
INIT(this,
.public = {
.get_name = _get_name,
+ .get_features = _get_features,
.create_object_enumerator = _create_object_enumerator,
.create_mechanism_enumerator = _create_mechanism_enumerator,
.destroy = _destroy,
@@ -858,7 +903,7 @@ pkcs11_library_t *pkcs11_library_create(char *name, char *file)
return NULL;
}
- if (!initialize(this, name, file))
+ if (!initialize(this, name, file, os_locking))
{
dlclose(this->handle);
free(this);
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
index 1457d24d4..abe023448 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h
@@ -21,6 +21,7 @@
#ifndef PKCS11_LIBRARY_H_
#define PKCS11_LIBRARY_H_
+typedef enum pkcs11_feature_t pkcs11_feature_t;
typedef struct pkcs11_library_t pkcs11_library_t;
#include "pkcs11.h"
@@ -29,6 +30,16 @@ typedef struct pkcs11_library_t pkcs11_library_t;
#include <utils/enumerator.h>
/**
+ * Optional PKCS#11 features some libraries support, some not
+ */
+enum pkcs11_feature_t {
+ /** CKA_TRUSTED attribute supported for certificate objects */
+ PKCS11_TRUSTED_CERTS = (1<<0),
+ /** CKA_ALWAYS_AUTHENTICATE attribute supported for private keys */
+ PKCS11_ALWAYS_AUTH_KEYS = (1<<1),
+};
+
+/**
* A loaded and initialized PKCS#11 library.
*/
struct pkcs11_library_t {
@@ -46,6 +57,13 @@ struct pkcs11_library_t {
char* (*get_name)(pkcs11_library_t *this);
/**
+ * Get the feature set supported by this library.
+ *
+ * @return ORed set of features supported
+ */
+ pkcs11_feature_t (*get_features)(pkcs11_library_t *this);
+
+ /**
* Create an enumerator over CK_OBJECT_HANDLE using a search template.
*
* An optional attribute array is automatically filled in with the
@@ -103,8 +121,9 @@ void pkcs11_library_trim(char *str, int len);
*
* @param name an arbitrary name, for debugging
* @param file pkcs11 library file to dlopen()
+ * @param os_lock enforce OS Locking for this library
* @return library abstraction
*/
-pkcs11_library_t *pkcs11_library_create(char *name, char *file);
+pkcs11_library_t *pkcs11_library_create(char *name, char *file, bool os_lock);
#endif /** PKCS11_LIBRARY_H_ @}*/
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
index 0c27600a6..9308e9c25 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c
@@ -373,7 +373,10 @@ pkcs11_manager_t *pkcs11_manager_create(pkcs11_manager_token_event_t cb,
free(entry);
continue;
}
- entry->lib = pkcs11_library_create(module, entry->path);
+ entry->lib = pkcs11_library_create(module, entry->path,
+ lib->settings->get_bool(lib->settings,
+ "libstrongswan.plugins.pkcs11.modules.%s.os_locking",
+ FALSE, module));
if (!entry->lib)
{
free(entry);
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c
index ace405c23..071d2f782 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c
@@ -26,6 +26,8 @@
#include "pkcs11_public_key.h"
#include "pkcs11_hasher.h"
+static const char *plugin_name = "pkcs11";
+
typedef struct private_pkcs11_plugin_t private_pkcs11_plugin_t;
/**
@@ -146,17 +148,17 @@ plugin_t *pkcs11_plugin_create()
if (lib->settings->get_bool(lib->settings,
"libstrongswan.plugins.pkcs11.use_hasher", FALSE))
{
- lib->crypto->add_hasher(lib->crypto, HASH_MD2,
+ lib->crypto->add_hasher(lib->crypto, HASH_MD2, plugin_name,
(hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_MD5,
+ lib->crypto->add_hasher(lib->crypto, HASH_MD5, plugin_name,
(hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1, plugin_name,
(hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA256,
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA256, plugin_name,
(hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA384,
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA384, plugin_name,
(hasher_constructor_t)pkcs11_hasher_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA512,
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA512, plugin_name,
(hasher_constructor_t)pkcs11_hasher_create);
}
diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
index cabca3f54..b4cc7a805 100644
--- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
+++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c
@@ -401,30 +401,36 @@ static bool find_key(private_pkcs11_private_key_t *this, chunk_t keyid)
};
CK_OBJECT_HANDLE object;
CK_KEY_TYPE type;
- CK_BBOOL reauth;
+ CK_BBOOL reauth = FALSE;
CK_ATTRIBUTE attr[] = {
{CKA_KEY_TYPE, &type, sizeof(type)},
- {CKA_ALWAYS_AUTHENTICATE, &reauth, sizeof(reauth)},
{CKA_MODULUS, NULL, 0},
{CKA_PUBLIC_EXPONENT, NULL, 0},
+ {CKA_ALWAYS_AUTHENTICATE, &reauth, sizeof(reauth)},
};
enumerator_t *enumerator;
chunk_t modulus, pubexp;
+ int count = countof(attr);
+ /* do not use CKA_ALWAYS_AUTHENTICATE if not supported */
+ if (!(this->lib->get_features(this->lib) & PKCS11_ALWAYS_AUTH_KEYS))
+ {
+ count--;
+ }
enumerator = this->lib->create_object_enumerator(this->lib,
- this->session, tmpl, countof(tmpl), attr, countof(attr));
+ this->session, tmpl, countof(tmpl), attr, count);
if (enumerator->enumerate(enumerator, &object))
{
switch (type)
{
case CKK_RSA:
- if (attr[2].ulValueLen == -1 || attr[3].ulValueLen == -1)
+ if (attr[1].ulValueLen == -1 || attr[2].ulValueLen == -1)
{
DBG1(DBG_CFG, "reading modulus/exponent from PKCS#1 failed");
break;
}
- modulus = chunk_create(attr[2].pValue, attr[2].ulValueLen);
- pubexp = chunk_create(attr[3].pValue, attr[3].ulValueLen);
+ modulus = chunk_create(attr[1].pValue, attr[1].ulValueLen);
+ pubexp = chunk_create(attr[2].pValue, attr[2].ulValueLen);
this->pubkey = lib->creds->create(lib->creds, CRED_PUBLIC_KEY,
KEY_RSA, BUILD_RSA_MODULUS, modulus,
BUILD_RSA_PUB_EXP, pubexp, BUILD_END);