From: Martin Willi Date: Wed, 14 Jul 2010 07:47:37 +0000 (+0200) Subject: Implemented an abstraction layer for PKCS#11 module loading X-Git-Tag: 4.5.0~631 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=34454dc39e95102a4189e1fd50148094bec5818c;p=thirdparty%2Fstrongswan.git Implemented an abstraction layer for PKCS#11 module loading --- diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.am b/src/libstrongswan/plugins/pkcs11/Makefile.am index 036b9b4a92..9df812e12b 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.am +++ b/src/libstrongswan/plugins/pkcs11/Makefile.am @@ -10,6 +10,7 @@ plugin_LTLIBRARIES = libstrongswan-pkcs11.la endif libstrongswan_pkcs11_la_SOURCES = \ - pkcs11_plugin.h pkcs11_plugin.c pkcs11.h + pkcs11_plugin.h pkcs11_plugin.c pkcs11.h \ + pkcs11_library.h pkcs11_library.c libstrongswan_pkcs11_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c new file mode 100644 index 0000000000..7c46c17c64 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "pkcs11_library.h" + +#include + +#include +#include + +typedef struct private_pkcs11_library_t private_pkcs11_library_t; + +/** + * Private data of an pkcs11_library_t object. + */ +struct private_pkcs11_library_t { + + /** + * Public pkcs11_library_t interface. + */ + pkcs11_library_t public; + + /** + * dlopen() handle + */ + void *handle; +}; + +METHOD(pkcs11_library_t, destroy, void, + private_pkcs11_library_t *this) +{ + this->public.f->C_Finalize(NULL); + dlclose(this->handle); + free(this); +} + +/** + * Trim a string + */ +static void trim(char *str, int len) +{ + int i; + + for (i = len - 1; i > 0; i--) + { + if (str[i] == ' ') + { + str[i] = '\0'; + continue; + } + break; + } +} + +/** + * Initialize a PKCS#11 library + */ +static bool initialize(private_pkcs11_library_t *this, char *name, char *file) +{ + CK_C_GetFunctionList pC_GetFunctionList; + CK_INFO info; + CK_RV rv; + + pC_GetFunctionList = dlsym(this->handle, "C_GetFunctionList"); + if (!pC_GetFunctionList) + { + DBG1(DBG_CFG, "C_GetFunctionList not found for '%s': %s", name, dlerror()); + return FALSE; + } + rv = pC_GetFunctionList(&this->public.f); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetFunctionList() error for '%s': %d", name, rv); + return FALSE; + } + + rv = this->public.f->C_Initialize(NULL); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_Initialize() error for '%s': %d", name, rv); + return FALSE; + } + rv = this->public.f->C_GetInfo(&info); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetInfo() error for '%s': %d", name, rv); + this->public.f->C_Finalize(NULL); + return FALSE; + } + + trim(info.manufacturerID, + strnlen(info.manufacturerID, sizeof(info.manufacturerID))); + trim(info.libraryDescription, + strnlen(info.libraryDescription, sizeof(info.libraryDescription))); + + DBG1(DBG_CFG, "loaded PKCS#11 v%d.%d library '%s' (%s)", + info.cryptokiVersion.major, info.cryptokiVersion.minor, name, file); + DBG1(DBG_CFG, " %.*s: %.*s v%d.%d", + sizeof(info.manufacturerID), info.manufacturerID, + sizeof(info.libraryDescription), info.libraryDescription, + info.libraryVersion.major, info.libraryVersion.minor); + return TRUE; +} + +/** + * See header + */ +pkcs11_library_t *pkcs11_library_create(char *name, char *file) +{ + private_pkcs11_library_t *this; + + INIT(this, + .public = { + .destroy = _destroy, + }, + .handle = dlopen(file, RTLD_LAZY), + ); + + if (!this->handle) + { + DBG1(DBG_CFG, "opening PKCS#11 library failed: %s", dlerror()); + free(this); + return NULL; + } + + if (!initialize(this, name, file)) + { + dlclose(this->handle); + free(this); + return NULL; + } + + return &this->public; +} diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h new file mode 100644 index 0000000000..8e572865d7 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup pkcs11_library pkcs11_library + * @{ @ingroup pkcs11 + */ + +#ifndef PKCS11_LIBRARY_H_ +#define PKCS11_LIBRARY_H_ + +typedef struct pkcs11_library_t pkcs11_library_t; + +#include "pkcs11.h" + +/** + * A loaded and initialized PKCS#11 library. + */ +struct pkcs11_library_t { + + /** + * PKCS#11 function list, as returned by C_GetFunctionList + */ + CK_FUNCTION_LIST_PTR f; + + /** + * Destroy a pkcs11_library_t. + */ + void (*destroy)(pkcs11_library_t *this); +}; + +/** + * Create a pkcs11_library instance. + * + * @param name an arbitrary name, for debugging + * @param file pkcs11 library file to dlopen() + * @return library abstraction + */ +pkcs11_library_t *pkcs11_library_create(char *name, char *file); + +#endif /** PKCS11_LIBRARY_H_ @}*/