diff options
author | NingSun <ning.sun@intel.com> | 2018-02-08 08:34:03 -0800 |
---|---|---|
committer | NingSun <ning.sun@intel.com> | 2018-02-08 09:14:52 -0800 |
commit | 0c89b3ccba7c9b7332ab67ae1936aff51ca62367 (patch) | |
tree | 70c1b1d160d4c6d0a83395ca9a87c1264d0d3439 /SoftHSMv2/src/lib/slot_mgr | |
parent | 945613b4db4e07f75d2bc7463db580ddfaa700fd (diff) |
Initial sshsm project structure
Issue-ID: AAF-94
Change-Id: I5e82fff418e7567b161acf9b98013a9b85ffc5b4
Signed-off-by: NingSun <ning.sun@intel.com>
Diffstat (limited to 'SoftHSMv2/src/lib/slot_mgr')
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/Makefile.am | 18 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/Slot.cpp | 116 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/Slot.h | 81 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/SlotManager.cpp | 179 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/SlotManager.h | 71 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/Token.cpp | 573 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/Token.h | 112 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/test/Makefile.am | 25 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.cpp | 485 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.h | 60 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/slot_mgr/test/slotmgrtest.cpp | 91 |
11 files changed, 1811 insertions, 0 deletions
diff --git a/SoftHSMv2/src/lib/slot_mgr/Makefile.am b/SoftHSMv2/src/lib/slot_mgr/Makefile.am new file mode 100644 index 0000000..1e8cf33 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/Makefile.am @@ -0,0 +1,18 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +AM_CPPFLAGS = -I$(srcdir)/.. \ + -I$(srcdir)/../common \ + -I$(srcdir)/../crypto \ + -I$(srcdir)/../data_mgr \ + -I$(srcdir)/../object_store \ + -I$(srcdir)/../pkcs11 \ + -I$(srcdir)/../session_mgr + +noinst_LTLIBRARIES = libsofthsm_slotmgr.la +libsofthsm_slotmgr_la_SOURCES = SlotManager.cpp \ + Slot.cpp \ + Token.cpp + +SUBDIRS = test + +EXTRA_DIST = $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/slot_mgr/Slot.cpp b/SoftHSMv2/src/lib/slot_mgr/Slot.cpp new file mode 100644 index 0000000..fea260b --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/Slot.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + Slot.h + + This class represents a single PKCS #11 slot + *****************************************************************************/ + +#include "config.h" +#include "log.h" +#include "SessionManager.h" +#include "SlotManager.h" +#include "Token.h" +#include <stdio.h> +#include <string.h> +#include <sstream> + +// Constructor +Slot::Slot(ObjectStore* inObjectStore, CK_SLOT_ID inSlotID, ObjectStoreToken* inToken /* = NULL */) +{ + objectStore = inObjectStore; + slotID = inSlotID; + + if (inToken != NULL) + { + token = new Token(inToken); + } + else + { + token = new Token(); + } +} + +// Destructor +Slot::~Slot() +{ + delete token; +} + +// Retrieve the token in the slot +Token* Slot::getToken() +{ + return token; +} + +// Initialise the token in the slot +CK_RV Slot::initToken(ByteString& soPIN, CK_UTF8CHAR_PTR label) +{ + return token->createToken(objectStore, soPIN, label); +} + +// Retrieve slot information for the slot +CK_RV Slot::getSlotInfo(CK_SLOT_INFO_PTR info) +{ + if (info == NULL) + { + return CKR_ARGUMENTS_BAD; + } + + std::ostringstream osDescription; + osDescription << "SoftHSM slot ID 0x" << std::hex << slotID; + const std::string sDescription(osDescription.str()); + + char mfgID[33]; + snprintf(mfgID, 33, "SoftHSM project"); + + memset(info->slotDescription, ' ', 64); + memset(info->manufacturerID, ' ', 32); + memcpy(info->slotDescription, sDescription.data(), sDescription.size()); + memcpy(info->manufacturerID, mfgID, strlen(mfgID)); + + info->flags = CKF_TOKEN_PRESENT; + + info->hardwareVersion.major = VERSION_MAJOR; + info->hardwareVersion.minor = VERSION_MINOR; + info->firmwareVersion.major = VERSION_MAJOR; + info->firmwareVersion.minor = VERSION_MINOR; + + return CKR_OK; +} + +// Get the slot ID +CK_SLOT_ID Slot::getSlotID() +{ + return slotID; +} + +// Is a token present? +bool Slot::isTokenPresent() +{ + return true; +} diff --git a/SoftHSMv2/src/lib/slot_mgr/Slot.h b/SoftHSMv2/src/lib/slot_mgr/Slot.h new file mode 100644 index 0000000..6ab07c6 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/Slot.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + Slot.h + + This class represents a single PKCS #11 slot + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_SLOT_H +#define _SOFTHSM_V2_SLOT_H + +#include "config.h" +#include "ByteString.h" +#include "ObjectStore.h" +#include "ObjectStoreToken.h" +#include "Token.h" +#include "cryptoki.h" +#include <string> +#include <vector> + +class Slot +{ +public: + // Constructor + Slot(ObjectStore* inObjectStore, CK_SLOT_ID inSlotID, ObjectStoreToken *inToken = NULL); + + // Destructor + virtual ~Slot(); + + // Retrieve the token in the slot + Token* getToken(); + + // Initialise the token in the slot + CK_RV initToken(ByteString& pin, CK_UTF8CHAR_PTR label); + + // Retrieve slot information for the slot + CK_RV getSlotInfo(CK_SLOT_INFO_PTR info); + + // Get the slot ID + CK_SLOT_ID getSlotID(); + + // Is a token present? + bool isTokenPresent(); + +private: + // A reference to the object store + ObjectStore* objectStore; + + // The token in the slot + Token* token; + + // The slot ID + CK_SLOT_ID slotID; +}; + +#endif // !_SOFTHSM_V2_SLOT_H + diff --git a/SoftHSMv2/src/lib/slot_mgr/SlotManager.cpp b/SoftHSMv2/src/lib/slot_mgr/SlotManager.cpp new file mode 100644 index 0000000..1f96909 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/SlotManager.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + SlotManager.cpp + + The slot manager is a class that forms part of the PKCS #11 core. It manages + all the slots that SoftHSM is aware of. To make it possible to add new + tokens, SoftHSM always has one slot available that contains an uninitialised + token. Users can choose to initialise this token to create a new token. + *****************************************************************************/ + +#include "config.h" +#include "log.h" +#include "SlotManager.h" +#include <cassert> +#include <stdexcept> +typedef std::pair<CK_SLOT_ID, Slot*> SlotMapElement; +typedef std::pair<SlotMap::iterator, bool> InsertResult; + +// Constructor +SlotManager::SlotManager(ObjectStore*const objectStore) +{ + // Add a slot for each token that already exists + for (size_t i = 0; i < objectStore->getTokenCount(); i++) + { + ObjectStoreToken*const pToken(objectStore->getToken(i)); + ByteString bs; + pToken->getTokenSerial(bs); + const std::string s((const char*)bs.const_byte_str(), bs.size()); + + // parse serial string that is expected to have only hex digits. + CK_SLOT_ID l; + if (s.size() < 8) + { + l = strtoul(s.c_str(), NULL, 16); + } + else + { + l = strtoul(s.substr(s.size() - 8).c_str(), NULL, 16); + } + + // mask for 31 bits. + // this since sunpkcs11 java wrapper is parsing the slot ID to a java int that needs to be positive. + // java int is 32 bit and the the sign bit is removed. + const CK_SLOT_ID mask( ((CK_SLOT_ID)1<<31)-1 ); + const CK_SLOT_ID slotID(mask&l); + + insertToken(objectStore, slotID, pToken); + } + + // Add an empty slot + insertToken(objectStore, objectStore->getTokenCount(), NULL); +} + +void SlotManager::insertToken(ObjectStore*const objectStore, const CK_SLOT_ID slotID, ObjectStoreToken*const pToken) { + Slot*const newSlot( new Slot(objectStore, slotID, pToken) ); + const InsertResult result( slots.insert(SlotMapElement(slotID, newSlot)) ); + assert(result.second);// fails if there is already a token on this slot +} + +// Destructor +SlotManager::~SlotManager() +{ + SlotMap toDelete = slots; + slots.clear(); + + for (SlotMap::iterator i = toDelete.begin(); i != toDelete.end(); i++) + { + delete i->second; + } +} + +// Get the slot list +CK_RV SlotManager::getSlotList(ObjectStore* objectStore, CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) +{ + size_t size( 0 ); + + if (pulCount == NULL) return CKR_ARGUMENTS_BAD; + + // Calculate the size of the list + bool uninitialized = false; + for (SlotMap::iterator i = slots.begin(); i != slots.end(); i++) + { + if ((tokenPresent == CK_FALSE) || i->second->isTokenPresent()) + { + size++; + } + + if (i->second->getToken() != NULL && i->second->getToken()->isInitialized() == false) + { + uninitialized = true; + } + } + + // The user wants the size of the list + if (pSlotList == NULL) + { + // Always have an uninitialized token + if (uninitialized == false) + { + insertToken(objectStore, objectStore->getTokenCount(), NULL); + size++; + } + + *pulCount = size; + + return CKR_OK; + } + + // Is the given buffer too small? + if (*pulCount < size) + { + *pulCount = size; + + return CKR_BUFFER_TOO_SMALL; + } + + size_t startIx( 0 ); + size_t endIx( size-1 ); + + for (SlotMap::iterator i = slots.begin(); i != slots.end(); i++) + { + if ((tokenPresent == CK_TRUE) && !i->second->isTokenPresent()) + {// only show token if present on slot. But this slot has no token so we continue + continue; + } + // put uninitialized last. After all initialized or slots without tokens. + if ( i->second->isTokenPresent() && !i->second->getToken()->isInitialized() ) { + pSlotList[endIx--] = i->second->getSlotID(); + } else { + pSlotList[startIx++] = i->second->getSlotID(); + } + } + assert(startIx==endIx+1); + *pulCount = size; + + return CKR_OK; +} + +// Get the slots +SlotMap SlotManager::getSlots() +{ + return slots; +} + +// Get one slot +Slot* SlotManager::getSlot(CK_SLOT_ID slotID) +{ + try { + return slots.at(slotID); + } catch( const std::out_of_range &oor) { + DEBUG_MSG("slotID is out of range: %s", oor.what()); + return NULL_PTR; + } +} diff --git a/SoftHSMv2/src/lib/slot_mgr/SlotManager.h b/SoftHSMv2/src/lib/slot_mgr/SlotManager.h new file mode 100644 index 0000000..04f51c0 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/SlotManager.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + SlotManager.h + + The slot manager is a class that forms part of the PKCS #11 core. It manages + all the slots that SoftHSM is aware of. To make it possible to add new + tokens, SoftHSM always has one slot available that contains an uninitialised + token. Users can choose to initialise this token to create a new token. + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_SLOTMANAGER_H +#define _SOFTHSM_V2_SLOTMANAGER_H + +#include "config.h" +#include "ByteString.h" +#include "ObjectStore.h" +#include "Slot.h" +#include <string> +#include <map> +typedef std::map<const CK_SLOT_ID, Slot*const> SlotMap; + +class SlotManager +{ +public: + // Constructor + SlotManager(ObjectStore* objectStore); + + // Destructor + virtual ~SlotManager(); + + // Get the slots + SlotMap getSlots(); + + // Get the slot list + CK_RV getSlotList(ObjectStore* objectStore, CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount); + + // Get one slot + Slot* getSlot(CK_SLOT_ID slotID); +private: + void insertToken(ObjectStore* objectStore, CK_SLOT_ID slotID, ObjectStoreToken* pToken); + // The slots + SlotMap slots; +}; + +#endif // !_SOFTHSM_V2_SLOTMANAGER_H + diff --git a/SoftHSMv2/src/lib/slot_mgr/Token.cpp b/SoftHSMv2/src/lib/slot_mgr/Token.cpp new file mode 100644 index 0000000..b4c9401 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/Token.cpp @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "log.h" +#include "ObjectStore.h" +#include "Token.h" +#include "OSAttribute.h" +#include "ByteString.h" +#include "SecureDataManager.h" +#include <cstdio> + +#ifndef _WIN32 +#include <sys/time.h> +#else +#include <time.h> +#endif + +// Constructor +Token::Token() +{ + tokenMutex = MutexFactory::i()->getMutex(); + + token = NULL; + sdm = NULL; + valid = false; +} + +// Constructor +Token::Token(ObjectStoreToken* inToken) +{ + tokenMutex = MutexFactory::i()->getMutex(); + + token = inToken; + + ByteString soPINBlob, userPINBlob; + + valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob); + + sdm = new SecureDataManager(soPINBlob, userPINBlob); +} + +// Destructor +Token::~Token() +{ + if (sdm != NULL) delete sdm; + + MutexFactory::i()->recycleMutex(tokenMutex); +} + +// Check if the token is still valid +bool Token::isValid() +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + return (valid && token->isValid()); +} + +// Check if the token is initialized +bool Token::isInitialized() +{ + if (token == NULL) return false; + + return true; +} + +// Check if SO is logged in +bool Token::isSOLoggedIn() +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return false; + + return sdm->isSOLoggedIn(); +} + +// Check if user is logged in +bool Token::isUserLoggedIn() +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return false; + + return sdm->isUserLoggedIn(); +} + +// Login SO +CK_RV Token::loginSO(ByteString& pin) +{ + CK_ULONG flags; + + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return CKR_GENERAL_ERROR; + + // User cannot be logged in + if (sdm->isUserLoggedIn()) return CKR_USER_ANOTHER_ALREADY_LOGGED_IN; + + // SO cannot be logged in + if (sdm->isSOLoggedIn()) return CKR_USER_ALREADY_LOGGED_IN; + + // Get token flags + if (!token->getTokenFlags(flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + // Login + if (!sdm->loginSO(pin)) + { + flags |= CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_PIN_INCORRECT; + } + + flags &= ~CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_OK; +} + +// Login user +CK_RV Token::loginUser(ByteString& pin) +{ + CK_ULONG flags; + + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return CKR_GENERAL_ERROR; + + // SO cannot be logged in + if (sdm->isSOLoggedIn()) return CKR_USER_ANOTHER_ALREADY_LOGGED_IN; + + // User cannot be logged in + if (sdm->isUserLoggedIn()) return CKR_USER_ALREADY_LOGGED_IN; + + // The user PIN has to be initialized; + if (sdm->getUserPINBlob().size() == 0) return CKR_USER_PIN_NOT_INITIALIZED; + + // Get token flags + if (!token->getTokenFlags(flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + // Login + if (!sdm->loginUser(pin)) + { + flags |= CKF_USER_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_PIN_INCORRECT; + } + + flags &= ~CKF_USER_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_OK; +} + +CK_RV Token::reAuthenticate(ByteString& pin) +{ + CK_ULONG flags; + + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return CKR_GENERAL_ERROR; + + // Get token flags + if (!token->getTokenFlags(flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + if (sdm->isSOLoggedIn()) + { + // Login + if (!sdm->reAuthenticateSO(pin)) + { + flags |= CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_PIN_INCORRECT; + } + else + { + flags &= ~CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + } + } + else if (sdm->isUserLoggedIn()) + { + // Login + if (!sdm->reAuthenticateUser(pin)) + { + flags |= CKF_USER_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_PIN_INCORRECT; + } + else + { + flags &= ~CKF_USER_PIN_COUNT_LOW; + token->setTokenFlags(flags); + } + } + else + { + return CKR_OPERATION_NOT_INITIALIZED; + } + + return CKR_OK; +} + +// Logout any user on this token; +void Token::logout() +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return; + + sdm->logout(); +} + +// Change SO PIN +CK_RV Token::setSOPIN(ByteString& oldPIN, ByteString& newPIN) +{ + CK_ULONG flags; + + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return CKR_GENERAL_ERROR; + + // Get token flags + if (!token->getTokenFlags(flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + // Verify oldPIN + SecureDataManager* verifier = new SecureDataManager(sdm->getSOPINBlob(), sdm->getUserPINBlob()); + bool result = verifier->loginSO(oldPIN); + delete verifier; + if (result == false) + { + flags |= CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + return CKR_PIN_INCORRECT; + } + + if (sdm->setSOPIN(newPIN) == false) return CKR_GENERAL_ERROR; + + // Save PIN to token file + if (token->setSOPIN(sdm->getSOPINBlob()) == false) return CKR_GENERAL_ERROR; + + ByteString soPINBlob, userPINBlob; + valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob); + + flags &= ~CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + + return CKR_OK; +} + +// Change the user PIN +CK_RV Token::setUserPIN(ByteString& oldPIN, ByteString& newPIN) +{ + CK_ULONG flags; + + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return CKR_GENERAL_ERROR; + + // Check if user should stay logged in + bool stayLoggedIn = sdm->isUserLoggedIn(); + + // Get token flags + if (!token->getTokenFlags(flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + // Verify oldPIN + SecureDataManager* newSdm = new SecureDataManager(sdm->getSOPINBlob(), sdm->getUserPINBlob()); + if (newSdm->loginUser(oldPIN) == false) + { + flags |= CKF_USER_PIN_COUNT_LOW; + token->setTokenFlags(flags); + delete newSdm; + return CKR_PIN_INCORRECT; + } + + // Set the new user PIN + if (newSdm->setUserPIN(newPIN) == false) + { + delete newSdm; + return CKR_GENERAL_ERROR; + } + + // Save PIN to token file + if (token->setUserPIN(newSdm->getUserPINBlob()) == false) + { + delete newSdm; + return CKR_GENERAL_ERROR; + } + + // Restore previous login state + if (!stayLoggedIn) newSdm->logout(); + + // Switch sdm + delete sdm; + sdm = newSdm; + + ByteString soPINBlob, userPINBlob; + valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob); + + flags &= ~CKF_USER_PIN_COUNT_LOW; + token->setTokenFlags(flags); + + return CKR_OK; +} + +// Init the user PIN +CK_RV Token::initUserPIN(ByteString& pin) +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return CKR_GENERAL_ERROR; + + if (sdm->setUserPIN(pin) == false) return CKR_GENERAL_ERROR; + + // Save PIN to token file + if (token->setUserPIN(sdm->getUserPINBlob()) == false) return CKR_GENERAL_ERROR; + + ByteString soPINBlob, userPINBlob; + valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob); + + return CKR_OK; +} + +// Create a new token +CK_RV Token::createToken(ObjectStore* objectStore, ByteString& soPIN, CK_UTF8CHAR_PTR label) +{ + CK_ULONG flags; + + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (objectStore == NULL) return CKR_GENERAL_ERROR; + if (label == NULL_PTR) return CKR_ARGUMENTS_BAD; + + // Convert the label + ByteString labelByteStr((const unsigned char*) label, 32); + + if (token != NULL) + { + // Get token flags + if (!token->getTokenFlags(flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + // Verify SO PIN + if (sdm->getSOPINBlob().size() > 0 && !sdm->loginSO(soPIN)) + { + flags |= CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + + ERROR_MSG("Incorrect SO PIN"); + return CKR_PIN_INCORRECT; + } + flags &= ~CKF_SO_PIN_COUNT_LOW; + token->setTokenFlags(flags); + + // Reset the token + if (!token->resetToken(labelByteStr)) + { + ERROR_MSG("Could not reset the token"); + return CKR_DEVICE_ERROR; + } + } + else + { + // Generate the SO PIN blob + SecureDataManager soPINBlobGen; + + if (!soPINBlobGen.setSOPIN(soPIN)) + { + return CKR_GENERAL_ERROR; + } + + // Create the token + ObjectStoreToken* newToken = objectStore->newToken(labelByteStr); + + if (newToken == NULL) + { + ERROR_MSG("Could not create the token"); + return CKR_DEVICE_ERROR; + } + + // Set the SO PIN on the token + if (!newToken->setSOPIN(soPINBlobGen.getSOPINBlob())) + { + ERROR_MSG("Failed to set SO PIN on new token"); + + if (!objectStore->destroyToken(newToken)) + { + ERROR_MSG("Failed to destroy incomplete token"); + } + + return CKR_DEVICE_ERROR; + } + + token = newToken; + } + + ByteString soPINBlob, userPINBlob; + + valid = token->getSOPIN(soPINBlob) && token->getUserPIN(userPINBlob); + + if (sdm != NULL) delete sdm; + sdm = new SecureDataManager(soPINBlob, userPINBlob); + + return CKR_OK; +} + +// Retrieve token information for the token +CK_RV Token::getTokenInfo(CK_TOKEN_INFO_PTR info) +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + ByteString label, serial; + + if (info == NULL) + { + return CKR_ARGUMENTS_BAD; + } + + memset(info->label, ' ', 32); + memset(info->serialNumber, ' ', 16); + + // Token specific information + if (token) + { + if (!token->getTokenFlags(info->flags)) + { + ERROR_MSG("Could not get the token flags"); + return CKR_GENERAL_ERROR; + } + + if (token->getTokenLabel(label)) + { + strncpy((char*) info->label, (char*) label.byte_str(), label.size()); + } + + if (token->getTokenSerial(serial)) + { + strncpy((char*) info->serialNumber, (char*) serial.byte_str(), serial.size()); + } + } + else + { + info->flags = CKF_RNG | + CKF_LOGIN_REQUIRED | + CKF_RESTORE_KEY_NOT_NEEDED | + CKF_SO_PIN_LOCKED | + CKF_SO_PIN_TO_BE_CHANGED; + } + + // Information shared by all tokens + char mfgID[33]; + char model[17]; + + snprintf(mfgID, 33, "SoftHSM project"); + snprintf(model, 17, "SoftHSM v2"); + + memset(info->manufacturerID, ' ', 32); + memset(info->model, ' ', 16); + memcpy(info->manufacturerID, mfgID, strlen(mfgID)); + memcpy(info->model, model, strlen(model)); + + // TODO: Can we set these? + info->ulSessionCount = CK_UNAVAILABLE_INFORMATION; + info->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION; + + info->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE; + info->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE; + info->ulMaxPinLen = MAX_PIN_LEN; + info->ulMinPinLen = MIN_PIN_LEN; + info->ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION; + info->ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION; + info->ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION; + info->ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION; + info->hardwareVersion.major = VERSION_MAJOR; + info->hardwareVersion.minor = VERSION_MINOR; + info->firmwareVersion.major = VERSION_MAJOR; + info->firmwareVersion.minor = VERSION_MINOR; + + // Current time + time_t rawtime; + time(&rawtime); + char dateTime[17]; + strftime(dateTime, 17, "%Y%m%d%H%M%S00", gmtime(&rawtime)); + memcpy(info->utcTime, dateTime, 16); + + return CKR_OK; +} + +// Create an object +OSObject* Token::createObject() +{ + return token->createObject(); +} + +void Token::getObjects(std::set<OSObject *> &objects) +{ + token->getObjects(objects); +} + +bool Token::decrypt(const ByteString &encrypted, ByteString &plaintext) +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return false; + + return sdm->decrypt(encrypted,plaintext); +} + +bool Token::encrypt(const ByteString &plaintext, ByteString &encrypted) +{ + // Lock access to the token + MutexLocker lock(tokenMutex); + + if (sdm == NULL) return false; + + return sdm->encrypt(plaintext,encrypted); +} diff --git a/SoftHSMv2/src/lib/slot_mgr/Token.h b/SoftHSMv2/src/lib/slot_mgr/Token.h new file mode 100644 index 0000000..8f67433 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/Token.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + Token.h + + This class represents a single PKCS #11 token + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_TOKEN_H +#define _SOFTHSM_V2_TOKEN_H + +#include "config.h" +#include "ByteString.h" +#include "ObjectStore.h" +#include "ObjectStoreToken.h" +#include "SecureDataManager.h" +#include "cryptoki.h" +#include <string> +#include <vector> + +class Token +{ +public: + // Constructor + Token(); + Token(ObjectStoreToken *inToken); + + // Destructor + virtual ~Token(); + + // Create a new token + CK_RV createToken(ObjectStore* objectStore, ByteString& soPIN, CK_UTF8CHAR_PTR label); + + // Is the token valid? + bool isValid(); + + // Is the token initialized? + bool isInitialized(); + + // Is SO or user logged in? + bool isSOLoggedIn(); + bool isUserLoggedIn(); + + // Login + CK_RV loginSO(ByteString& pin); + CK_RV loginUser(ByteString& pin); + + // Re-authentication + CK_RV reAuthenticate(ByteString& pin); + + // Logout any user on this token; + void logout(); + + // Change PIN + CK_RV setSOPIN(ByteString& oldPIN, ByteString& newPIN); + CK_RV setUserPIN(ByteString& oldPIN, ByteString& newPIN); + CK_RV initUserPIN(ByteString& pin); + + // Retrieve token information for the token + CK_RV getTokenInfo(CK_TOKEN_INFO_PTR info); + + // Create object + OSObject *createObject(); + + // Insert all token objects into the given set. + void getObjects(std::set<OSObject *> &objects); + + // Decrypt the supplied data + bool decrypt(const ByteString& encrypted, ByteString& plaintext); + + // Encrypt the supplied data + bool encrypt(const ByteString& plaintext, ByteString& encrypted); + +private: + // Token validity + bool valid; + + // A reference to the object store token + ObjectStoreToken* token; + + // The secure data manager for this token + SecureDataManager* sdm; + + Mutex* tokenMutex; +}; + +#endif // !_SOFTHSM_V2_TOKEN_H + diff --git a/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am b/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am new file mode 100644 index 0000000..8e2d161 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/test/Makefile.am @@ -0,0 +1,25 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +AM_CPPFLAGS = -I$(srcdir)/.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/../../common \ + -I$(srcdir)/../../crypto \ + -I$(srcdir)/../../data_mgr \ + -I$(srcdir)/../../object_store \ + -I$(srcdir)/../../pkcs11 \ + -I$(srcdir)/../../session_mgr \ + @CPPUNIT_CFLAGS@ \ + @CRYPTO_INCLUDES@ + +check_PROGRAMS = slotmgrtest + +slotmgrtest_SOURCES = slotmgrtest.cpp \ + SlotManagerTests.cpp + +slotmgrtest_LDADD = ../../libsofthsm_convarch.la + +slotmgrtest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install -pthread + +TESTS = slotmgrtest + +EXTRA_DIST = $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.cpp b/SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.cpp new file mode 100644 index 0000000..c5f6687 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.cpp @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + SlotManagerTests.cpp + + Contains test cases to test the object store implementation + *****************************************************************************/ + +#include <stdlib.h> +#include <string.h> +#include <cppunit/extensions/HelperMacros.h> +#include "SlotManagerTests.h" +#include "SlotManager.h" +#include "Token.h" +#include "ObjectStore.h" +#include "ObjectFile.h" +#include "File.h" +#include "Directory.h" +#include "OSAttribute.h" +#include "OSAttributes.h" +#include "CryptoFactory.h" +#include "cryptoki.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(SlotManagerTests); + +void SlotManagerTests::setUp() +{ + CPPUNIT_ASSERT(!system("mkdir testdir")); +} + +void SlotManagerTests::tearDown() +{ +#ifndef _WIN32 + CPPUNIT_ASSERT(!system("rm -rf testdir")); +#else + CPPUNIT_ASSERT(!system("rmdir /s /q testdir 2> nul")); +#endif +} + +void SlotManagerTests::testNoExistingTokens() +{ + // Create an empty object store +#ifndef _WIN32 + ObjectStore store("./testdir"); +#else + ObjectStore store(".\\testdir"); +#endif + + // Create the slot manager + SlotManager slotManager(&store); + + CPPUNIT_ASSERT(slotManager.getSlots().size() == 1); + + // Test C_GetSlotList + CK_SLOT_ID testList[10]; + CK_ULONG ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + + ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotID() == testList[0]); + + // Retrieve slot information about the first slot + CK_SLOT_INFO slotInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CK_TOKEN_INFO tokenInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); +} + +void SlotManagerTests::testExistingTokens() +{ + // Create an empty object store +#ifndef _WIN32 + ObjectStore store("./testdir"); +#else + ObjectStore store(".\\testdir"); +#endif + + // Create two tokens + ByteString label1 = "DEADBEEF"; + ByteString label2 = "DEADC0FFEE"; + + CPPUNIT_ASSERT(store.newToken(label1) != NULL); + CPPUNIT_ASSERT(store.newToken(label2) != NULL); + + // Now attach the slot manager + SlotManager slotManager(&store); + + CPPUNIT_ASSERT(slotManager.getSlots().size() == 3); + + // Test C_GetSlotList + CK_SLOT_ID testList[10]; + CK_ULONG ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + + ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotID() == testList[0]); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotID() == testList[1]); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getSlotID() == testList[2]); + + // Retrieve slot information about the first slot + CK_SLOT_INFO slotInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CK_TOKEN_INFO tokenInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, &label1[0], label1.size()) || + !memcmp(tokenInfo.label, &label2[0], label2.size())); + + // Retrieve slot information about the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, &label1[0], label1.size()) || + !memcmp(tokenInfo.label, &label2[0], label2.size())); + + // Retrieve slot information about the third slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the third slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); +} + +void SlotManagerTests::testInitialiseTokenInLastSlot() +{ + { + // Create an empty object store +#ifndef _WIN32 + ObjectStore store("./testdir"); +#else + ObjectStore store(".\\testdir"); +#endif + + // Create the slot manager + SlotManager slotManager(&store); + + CPPUNIT_ASSERT(slotManager.getSlots().size() == 1); + + // Test C_GetSlotList + CK_SLOT_ID testList[10]; + CK_ULONG ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + + ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotID() == testList[0]); + + // Retrieve slot information about the first slot + CK_SLOT_INFO slotInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CK_TOKEN_INFO tokenInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); + + // Now initialise the token in the first slot + ByteString soPIN((unsigned char*)"1234", 4); + CK_UTF8CHAR label[33] = "My test token "; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->initToken(soPIN, label) == CKR_OK); + + // Retrieve slot information about the first slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, label, 32)); + } + + // Attach a fresh slot manager +#ifndef _WIN32 + ObjectStore store("./testdir"); +#else + ObjectStore store(".\\testdir"); +#endif + SlotManager slotManager(&store); + + CPPUNIT_ASSERT(slotManager.getSlots().size() == 2); + + // Test C_GetSlotList + CK_SLOT_ID testList[10]; + CK_ULONG ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + + ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotID() == testList[0]); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotID() == testList[1]); + + // Retrieve slot information about the first slot + CK_SLOT_INFO slotInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CK_TOKEN_INFO tokenInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + + CK_UTF8CHAR label[33] = "My test token "; + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, label, 32)); + + // Retrieve slot information about the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); +} + +void SlotManagerTests::testReinitialiseExistingToken() +{ + // Create an empty object store +#ifndef _WIN32 + ObjectStore store("./testdir"); +#else + ObjectStore store(".\\testdir"); +#endif + + // Create two tokens + ByteString label1 = "DEADBEEF"; + ByteString label2 = "DEADC0FFEE"; + + CPPUNIT_ASSERT(store.newToken(label1) != NULL); + CPPUNIT_ASSERT(store.newToken(label2) != NULL); + + // Now attach the slot manager + SlotManager slotManager(&store); + + CPPUNIT_ASSERT(slotManager.getSlots().size() == 3); + + // Test C_GetSlotList + CK_SLOT_ID testList[10]; + CK_ULONG ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + + ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotID() == testList[0]); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotID() == testList[1]); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getSlotID() == testList[2]); + + // Retrieve slot information about the first slot + CK_SLOT_INFO slotInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CK_TOKEN_INFO tokenInfo; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, &label1[0], label1.size()) || + !memcmp(tokenInfo.label, &label2[0], label2.size())); + + // Retrieve slot information about the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, &label1[0], label1.size()) || + !memcmp(tokenInfo.label, &label2[0], label2.size())); + + // Retrieve slot information about the third slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the third slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); + + // Now reinitialise the token in the second slot + ByteString soPIN((unsigned char*)"1234", 4); + CK_UTF8CHAR label[33] = "My test token "; + + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->initToken(soPIN, label) == CKR_OK); + + // Retrieve slot information about the first slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getSlotInfo(&slotInfo) == CKR_OK); + + CPPUNIT_ASSERT((slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT); + + // Retrieve token information about the token in the first slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(!memcmp(tokenInfo.label, label, 32)); +} + +void SlotManagerTests::testUninitialisedToken() +{ + // Create an empty object store +#ifndef _WIN32 + ObjectStore store("./testdir"); +#else + ObjectStore store(".\\testdir"); +#endif + + // Now attach the slot manager + SlotManager slotManager(&store); + + CPPUNIT_ASSERT(slotManager.getSlots().size() == 1); + + // Test C_GetSlotList + CK_SLOT_ID testList[10]; + CK_ULONG ulCount = 10; + + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + + // Initialise the token in the first slot + ByteString soPIN((unsigned char*)"1234", 4); + CK_UTF8CHAR label[33] = "My test token "; + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->initToken(soPIN, label) == CKR_OK); + + // Check if a new slot is added + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 1); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, NULL_PTR, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, NULL_PTR, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + + // get new list + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + + // Retrieve token information about the tokens + CK_TOKEN_INFO tokenInfo; + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); + + // Initialise the token in the second slot + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->initToken(soPIN, label) == CKR_OK); + + // Check if a new slot is added + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 2); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_FALSE, NULL_PTR, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + ulCount = 10; + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, NULL_PTR, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + + // get new list + CPPUNIT_ASSERT(slotManager.getSlotList(&store, CK_TRUE, testList, &ulCount) == CKR_OK); + CPPUNIT_ASSERT(ulCount == 3); + + // Retrieve token information about the tokens + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[0]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[1]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) == CKF_TOKEN_INITIALIZED); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getToken() != NULL); + CPPUNIT_ASSERT(slotManager.getSlots()[testList[2]]->getToken()->getTokenInfo(&tokenInfo) == CKR_OK); + CPPUNIT_ASSERT((tokenInfo.flags & CKF_TOKEN_INITIALIZED) != CKF_TOKEN_INITIALIZED); +} + diff --git a/SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.h b/SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.h new file mode 100644 index 0000000..8d4e57f --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/test/SlotManagerTests.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + SlotManagerTests.h + + Contains test cases to test the slot manager implementation + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_SLOTMANAGERTESTS_H +#define _SOFTHSM_V2_SLOTMANAGERTESTS_H + +#include <cppunit/extensions/HelperMacros.h> + +class SlotManagerTests : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(SlotManagerTests); + CPPUNIT_TEST(testNoExistingTokens); + CPPUNIT_TEST(testExistingTokens); + CPPUNIT_TEST(testInitialiseTokenInLastSlot); + CPPUNIT_TEST(testReinitialiseExistingToken); + CPPUNIT_TEST(testUninitialisedToken); + CPPUNIT_TEST_SUITE_END(); + +public: + void testNoExistingTokens(); + void testExistingTokens(); + void testInitialiseTokenInLastSlot(); + void testReinitialiseExistingToken(); + void testUninitialisedToken(); + + void setUp(); + void tearDown(); +}; + +#endif // !_SOFTHSM_V2_SLOTMANAGERTESTS_H + diff --git a/SoftHSMv2/src/lib/slot_mgr/test/slotmgrtest.cpp b/SoftHSMv2/src/lib/slot_mgr/test/slotmgrtest.cpp new file mode 100644 index 0000000..4172b63 --- /dev/null +++ b/SoftHSMv2/src/lib/slot_mgr/test/slotmgrtest.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2010 SURFnet bv + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/***************************************************************************** + slotmgrtest.cpp + + The main test executor for tests on the slot manager in SoftHSM v2 + *****************************************************************************/ + +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <cppunit/ui/text/TestRunner.h> +#include <cppunit/TestResult.h> +#include <cppunit/TestResultCollector.h> +#include <cppunit/XmlOutputter.h> +#include <fstream> + +#include "config.h" +#include "MutexFactory.h" +#include "SecureMemoryRegistry.h" + +#if defined(WITH_OPENSSL) +#include "OSSLCryptoFactory.h" +#else +#include "BotanCryptoFactory.h" +#endif + +// Initialise the one-and-only instance +#ifdef HAVE_CXX11 + +std::unique_ptr<MutexFactory> MutexFactory::instance(nullptr); +std::unique_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(nullptr); +#if defined(WITH_OPENSSL) +std::unique_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(nullptr); +#else +std::unique_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(nullptr); +#endif + +#else + +std::auto_ptr<MutexFactory> MutexFactory::instance(NULL); +std::auto_ptr<SecureMemoryRegistry> SecureMemoryRegistry::instance(NULL); +#if defined(WITH_OPENSSL) +std::auto_ptr<OSSLCryptoFactory> OSSLCryptoFactory::instance(NULL); +#else +std::auto_ptr<BotanCryptoFactory> BotanCryptoFactory::instance(NULL); +#endif + +#endif + +int main(int /*argc*/, char** /*argv*/) +{ + CppUnit::TestResult controller; + CppUnit::TestResultCollector result; + CppUnit::TextUi::TestRunner runner; + controller.addListener(&result); + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + + runner.addTest(registry.makeTest()); + runner.run(controller); + + std::ofstream xmlFileOut("test-results.xml"); + CppUnit::XmlOutputter xmlOut(&result, xmlFileOut); + xmlOut.write(); + + CryptoFactory::reset(); + + return result.wasSuccessful() ? 0 : 1; +} |