From: Tobias Brunner Date: Mon, 24 Oct 2011 14:39:59 +0000 (+0200) Subject: pkcs11: Added support to generate random numbers on a token. X-Git-Tag: 4.6.0~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1bb522bc34af72091613650bc4cae75adcfc1c1d;p=thirdparty%2Fstrongswan.git pkcs11: Added support to generate random numbers on a token. --- diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.am b/src/libstrongswan/plugins/pkcs11/Makefile.am index 199039d953..fbe6a707af 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.am +++ b/src/libstrongswan/plugins/pkcs11/Makefile.am @@ -16,6 +16,7 @@ libstrongswan_pkcs11_la_SOURCES = \ pkcs11_private_key.h pkcs11_private_key.c \ pkcs11_public_key.h pkcs11_public_key.c \ pkcs11_hasher.h pkcs11_hasher.c \ + pkcs11_rng.h pkcs11_rng.c \ pkcs11_manager.h pkcs11_manager.c libstrongswan_pkcs11_la_LDFLAGS = -module -avoid-version diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c index 7a35a5773b..824da9dc49 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_plugin.c @@ -1,4 +1,7 @@ /* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * @@ -25,6 +28,7 @@ #include "pkcs11_private_key.h" #include "pkcs11_public_key.h" #include "pkcs11_hasher.h" +#include "pkcs11_rng.h" typedef struct private_pkcs11_plugin_t private_pkcs11_plugin_t; @@ -121,6 +125,7 @@ METHOD(plugin_t, destroy, void, } lib->crypto->remove_hasher(lib->crypto, (hasher_constructor_t)pkcs11_hasher_create); + lib->crypto->remove_rng(lib->crypto, (rng_constructor_t)pkcs11_rng_create); this->creds->destroy(this->creds); lib->set(lib, "pkcs11-manager", NULL); this->manager->destroy(this->manager); @@ -171,6 +176,17 @@ plugin_t *pkcs11_plugin_create() (hasher_constructor_t)pkcs11_hasher_create); } + if (lib->settings->get_bool(lib->settings, + "libstrongswan.plugins.pkcs11.use_rng", FALSE)) + { + lib->crypto->add_rng(lib->crypto, RNG_TRUE, get_name(this), + (rng_constructor_t)pkcs11_rng_create); + lib->crypto->add_rng(lib->crypto, RNG_STRONG, get_name(this), + (rng_constructor_t)pkcs11_rng_create); + lib->crypto->add_rng(lib->crypto, RNG_WEAK, get_name(this), + (rng_constructor_t)pkcs11_rng_create); + } + lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY, KEY_ANY, FALSE, (builder_function_t)pkcs11_private_key_connect); lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY, KEY_RSA, TRUE, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c new file mode 100644 index 0000000000..45cf0b7c2a --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.c @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * 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_rng.h" + +#include + +#include "pkcs11_manager.h" + +typedef struct private_pkcs11_rng_t private_pkcs11_rng_t; + +/** + * Private data of an pkcs11_rng_t object. + */ +struct private_pkcs11_rng_t { + + /** + * Public interface. + */ + pkcs11_rng_t public; + + /** + * PKCS#11 library + */ + pkcs11_library_t *lib; + + /** + * Mechanism for this rng + */ + CK_SESSION_HANDLE session; + +}; + +METHOD(rng_t, get_bytes, void, + private_pkcs11_rng_t *this, size_t bytes, u_int8_t *buffer) +{ + CK_RV rv; + rv = this->lib->f->C_GenerateRandom(this->session, buffer, bytes); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GenerateRandom() failed: %N", ck_rv_names, rv); + abort(); + } +} + +METHOD(rng_t, allocate_bytes, void, + private_pkcs11_rng_t *this, size_t bytes, chunk_t *chunk) +{ + *chunk = chunk_alloc(bytes); + get_bytes(this, chunk->len, chunk->ptr); +} + +METHOD(rng_t, destroy, void, + private_pkcs11_rng_t *this) +{ + this->lib->f->C_CloseSession(this->session); + free(this); +} + +/** + * Find a token with its own RNG + */ +static pkcs11_library_t *find_token(CK_SESSION_HANDLE *session) +{ + enumerator_t *tokens; + pkcs11_manager_t *manager; + pkcs11_library_t *current, *found = NULL; + CK_SLOT_ID slot; + + manager = lib->get(lib, "pkcs11-manager"); + if (!manager) + { + return NULL; + } + tokens = manager->create_token_enumerator(manager); + while (tokens->enumerate(tokens, ¤t, &slot)) + { + CK_TOKEN_INFO info; + CK_RV rv; + rv = current->f->C_GetTokenInfo(slot, &info); + if (rv != CKR_OK) + { + continue; + } + if (info.flags & CKF_RNG) + { + if (current->f->C_OpenSession(slot, CKF_SERIAL_SESSION, + NULL, NULL, session) == CKR_OK) + { + found = current; + break; + } + } + } + tokens->destroy(tokens); + return found; +} + +/* + * Described in header. + */ +pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality) +{ + private_pkcs11_rng_t *this; + + INIT(this, + .public = { + .rng = { + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .destroy = _destroy, + }, + }, + ); + + this->lib = find_token(&this->session); + if (!this->lib) + { + free(this); + return NULL; + } + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h new file mode 100644 index 0000000000..998631f7e6 --- /dev/null +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_rng.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * 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_rng pkcs11_rng + * @{ @ingroup pkcs11 + */ + +#ifndef PKCS11_RNG_H_ +#define PKCS11_RNG_H_ + +typedef struct pkcs11_rng_t pkcs11_rng_t; + +#include + +/** + * rng_t implementation via PKCS#11 + */ +struct pkcs11_rng_t { + + /** + * Implements rng_t. + */ + rng_t rng; +}; + +/** + * Creates a pkcs11_rng_t instance. + * + * @param quality required quality of randomness + * @return created pkcs11_rng_t + */ +pkcs11_rng_t *pkcs11_rng_create(rng_quality_t quality); + +#endif /** PKCS11_RNG_H_ @} */