diff options
Diffstat (limited to 'SoftHSMv2/src/lib/data_mgr/test')
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.cpp | 356 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.h | 71 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/Makefile.am | 27 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.cpp | 116 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.h | 56 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.cpp | 207 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.h | 56 | ||||
-rw-r--r-- | SoftHSMv2/src/lib/data_mgr/test/datamgrtest.cpp | 91 |
8 files changed, 980 insertions, 0 deletions
diff --git a/SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.cpp b/SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.cpp new file mode 100644 index 0000000..1c635a4 --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.cpp @@ -0,0 +1,356 @@ +/* + * 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. + */ + +/***************************************************************************** + ByteStringTests.cpp + + Contains test cases to test the ByteString class + *****************************************************************************/ + +#include <stdlib.h> +#include <stdio.h> +#include <cppunit/extensions/HelperMacros.h> +#include <string> +#include "ByteStringTests.h" +#include "ByteString.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(ByteStringTests); + +void ByteStringTests::setUp() +{ +} + +void ByteStringTests::tearDown() +{ + fflush(stdout); +} + +void ByteStringTests::testIntegrity() +{ + unsigned char testData[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; + + ByteString b(testData, sizeof(testData)); + + // Test if the right data is returned + CPPUNIT_ASSERT(memcmp(testData, b.byte_str(), sizeof(testData)) == 0); + + // Test size + CPPUNIT_ASSERT(b.size() == sizeof(testData)); + + // Test the copy constructor + ByteString b2(b); + + // Test using comparison operator + CPPUNIT_ASSERT(b == b2); + + // Test using memcmp + CPPUNIT_ASSERT(memcmp(b.byte_str(), b2.byte_str(), b.size()) == 0); + + // Modify the copied version and test again + b2[1] = 0x20; + + // Test using comparison operator + CPPUNIT_ASSERT(b != b2); + + // Test using memcmp directly + CPPUNIT_ASSERT(memcmp(b.byte_str(), b2.byte_str(), b.size()) != 0); + + // Verify that b was not affected + CPPUNIT_ASSERT(memcmp(b.byte_str(), testData, sizeof(testData)) == 0); + + // Modify the source data and check if the array operator has functioned correctly + testData[1] = 0x20; + + // Test if the right data is in b2 + CPPUNIT_ASSERT(memcmp(b2.byte_str(), testData, sizeof(testData)) == 0); +} + +void ByteStringTests::testAppend() +{ + unsigned char testData[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; + + ByteString b; + ByteString b1(testData, sizeof(testData)); + + // Test that b is empty and b1 is not + CPPUNIT_ASSERT((b.size() == 0) && (b1.size() == sizeof(testData))); + + // Append 1 byte to b + b += 0x01; + + // Check the contents of b + CPPUNIT_ASSERT(b.size() == 1); + CPPUNIT_ASSERT(b[0] == 0x01); + + // Append another byte to b + b += 0x02; + + // Check the contents of b + CPPUNIT_ASSERT(b.size() == 2); + CPPUNIT_ASSERT((b[0] == 0x01) && (b[1] == 0x02)); + + // Append b1 to b + b += b1; + + // Check the contents of b + CPPUNIT_ASSERT(b.size() == 2 + sizeof(testData)); + CPPUNIT_ASSERT((b[0] == 0x01) && (b[1] == 0x02)); + CPPUNIT_ASSERT(memcmp(&b[2], testData, sizeof(testData)) == 0); + + // Append b to b + b += b; + + // Check the contents of b + CPPUNIT_ASSERT(b.size() == 2 * (2 + sizeof(testData))); + CPPUNIT_ASSERT((b[0] == 0x01) && (b[1] == 0x02) && + (b[(2 + sizeof(testData)) + 0] == 0x01) && + (b[(2 + sizeof(testData)) + 1] == 0x02)); + CPPUNIT_ASSERT((memcmp(&b[2], testData, sizeof(testData)) == 0) && + (memcmp(&b[2 + 2 + sizeof(testData)], testData, sizeof(testData)) == 0)); +} + +void ByteStringTests::testSubstr() +{ + unsigned char testData[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; + + ByteString b; + ByteString b1(testData, sizeof(testData)); + + // Take a substring + b = b1.substr(8, 4); + + // Check b + CPPUNIT_ASSERT(b.size() == 4); + CPPUNIT_ASSERT(memcmp(b.byte_str(), &testData[8], 4) == 0); + + // Take another substring + b = b1.substr(8); + + // Check b + CPPUNIT_ASSERT(b.size() == 8); + CPPUNIT_ASSERT(memcmp(b.byte_str(), &testData[8], 8) == 0); + + // Two substrings added should yield the original string + b = b1.substr(0, 8) + b1.substr(8); + + // Check b + CPPUNIT_ASSERT(b.size() == sizeof(testData)); + CPPUNIT_ASSERT(memcmp(b.byte_str(), testData, sizeof(testData)) == 0); +} + +void ByteStringTests::testFromHexStr() +{ + unsigned char testData[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; + + ByteString b("0102030405060708090a0b0c0d0e0f10"); + ByteString b1("0102030405060708090A0B0C0D0E0F10"); + + CPPUNIT_ASSERT(memcmp(b.byte_str(), testData, sizeof(testData)) == 0); + CPPUNIT_ASSERT(memcmp(b1.byte_str(), testData, sizeof(testData)) == 0); +} + +void ByteStringTests::testXOR() +{ + unsigned char left[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; + unsigned char right[] = { 0x80, 0x70, 0x60, 0x50, 0x40, 0x30, 0x20, 0x10 }; + unsigned char xorred[] = { 0x81, 0x72, 0x63, 0x54, 0x45, 0x36, 0x27, 0x18 }; + + ByteString l(left, 8); + ByteString r(right, 8); + ByteString x(xorred, 8); + ByteString xed; + + xed = l ^ r; + + CPPUNIT_ASSERT(xed == x); + + ByteString l1(left, 8); + ByteString r1(right, 8); + + l1 ^= r1; + + CPPUNIT_ASSERT(l1 == x); + + l1 ^= l; + + CPPUNIT_ASSERT(l1 == r); + + ByteString l_(left, 7); + + xed = l_ ^ r; + + CPPUNIT_ASSERT((xed.size() == 7) && (xed == x.substr(0, 7))); + + ByteString r_(right, 7); + + xed = l ^ r_; + + CPPUNIT_ASSERT((xed.size() == 7) && (xed == x.substr(0, 7))); + + ByteString l1_(left, 8); + + l1_ ^= r_; + + CPPUNIT_ASSERT((l1.size() == 8) && (l1_.substr(0, 7) == x.substr(0,7)) && (l1_[7] == l[7])); + + ByteString l1__(left, 7); + + l1__ ^= r; + + CPPUNIT_ASSERT((l1__ == x.substr(0,7)) && (l1__.size() == 7)); +} + +void ByteStringTests::testToHexStr() +{ + ByteString b("0102030405060708090A0B0C0D0E0F"); + ByteString b1("DEADBEEF"); + ByteString b2("deadC0FFEE"); + + std::string s = b.hex_str(); + std::string s1 = b1.hex_str(); + std::string s2 = b2.hex_str(); + + CPPUNIT_ASSERT(s.compare("0102030405060708090A0B0C0D0E0F") == 0); + CPPUNIT_ASSERT(s1.compare("DEADBEEF") == 0); + CPPUNIT_ASSERT(s2.compare("DEADC0FFEE") == 0); +} + +void ByteStringTests::testLongValues() +{ + unsigned long ul1 = 0x00112233; + unsigned long ul2 = 0x10203040; + unsigned long ul3 = 0xF0E0D0C0; + + ByteString b1(ul1); + ByteString b2(ul2); + ByteString b3(ul3); + + CPPUNIT_ASSERT(b1 == ByteString("0000000000112233")); + CPPUNIT_ASSERT(b2 == ByteString("0000000010203040")); + CPPUNIT_ASSERT(b3 == ByteString("00000000F0E0D0C0")); + + CPPUNIT_ASSERT(b1.long_val() == ul1); + CPPUNIT_ASSERT(b2.long_val() == ul2); + CPPUNIT_ASSERT(b3.long_val() == ul3); + + ByteString concat = b1 + b2 + b3; + + CPPUNIT_ASSERT(concat == ByteString("0000000000112233000000001020304000000000F0E0D0C0")); + + unsigned long ulr1 = concat.firstLong(); + + CPPUNIT_ASSERT(ulr1 == ul1); + CPPUNIT_ASSERT(concat == ByteString("000000001020304000000000F0E0D0C0")); + + unsigned long ulr2 = concat.firstLong(); + + CPPUNIT_ASSERT(ulr2 == ul2); + CPPUNIT_ASSERT(concat == ByteString("00000000F0E0D0C0")); + + unsigned long ulr3 = concat.firstLong(); + + CPPUNIT_ASSERT(ulr3 == ul3); + CPPUNIT_ASSERT(concat.size() == 0); + + ByteString b4("ABCDEF"); + + CPPUNIT_ASSERT(b4.long_val() == 0xABCDEF); + CPPUNIT_ASSERT(b4.size() == 3); + CPPUNIT_ASSERT(b4.firstLong() == 0xABCDEF); + CPPUNIT_ASSERT(b4.size() == 0); +} + +void ByteStringTests::testSplitting() +{ + ByteString b("AABBCCDDEEFF112233445566"); + + ByteString b1 = b.split(6); + + CPPUNIT_ASSERT(b == ByteString("112233445566")); + CPPUNIT_ASSERT(b1 == ByteString("AABBCCDDEEFF")); + + ByteString b2 = b1.split(8); + + CPPUNIT_ASSERT(b2 == ByteString("AABBCCDDEEFF")); + CPPUNIT_ASSERT(b1.size() == 0); +} + +void ByteStringTests::testBits() +{ + ByteString b1("0"); + ByteString b2("08"); + ByteString b3("00FFFFF"); + ByteString b4("123456"); + + CPPUNIT_ASSERT(b1.bits() == 0); + CPPUNIT_ASSERT(b2.bits() == 4); + CPPUNIT_ASSERT(b3.bits() == 20); + CPPUNIT_ASSERT(b4.bits() == 21); +} + +void ByteStringTests::testSerialising() +{ + ByteString b1("AA11AA11AA11AA11AA11AA11AA11"); + ByteString b2("BB22BB22BB22BB22BB22BB22"); + ByteString b3("CC33CC33CC33CC33CC33CC33CC33CC33"); + + ByteString s1 = b1.serialise(); + + CPPUNIT_ASSERT(s1.size() == b1.size() + 8); + + ByteString d1 = ByteString::chainDeserialise(s1); + + CPPUNIT_ASSERT(s1.size() == 0); + CPPUNIT_ASSERT(d1 == b1); + + ByteString s2 = b3.serialise() + b2.serialise() + b1.serialise(); + + CPPUNIT_ASSERT(s2.size() == b1.size() + b2.size() + b3.size() + (3*8)); + + d1 = ByteString::chainDeserialise(s2); + + CPPUNIT_ASSERT(d1.size() == b3.size()); + CPPUNIT_ASSERT(s2.size() == b1.size() + b2.size() + (2*8)); + + ByteString d2 = ByteString::chainDeserialise(s2); + + CPPUNIT_ASSERT(d2.size() == b2.size()); + CPPUNIT_ASSERT(s2.size() == b1.size() + 8); + + ByteString d3 = ByteString::chainDeserialise(s2); + + CPPUNIT_ASSERT(d3.size() == b1.size()); + CPPUNIT_ASSERT(s2.size() == 0); + + CPPUNIT_ASSERT(d1 == b3); + CPPUNIT_ASSERT(d2 == b2); + CPPUNIT_ASSERT(d3 == b1); +} + diff --git a/SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.h b/SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.h new file mode 100644 index 0000000..b1dd967 --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/ByteStringTests.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. + */ + +/***************************************************************************** + ByteStringTests.h + + Contains test cases to test the ByteString class + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_BYTESTRINGTESTS_H +#define _SOFTHSM_V2_BYTESTRINGTESTS_H + +#include <cppunit/extensions/HelperMacros.h> + +class ByteStringTests : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(ByteStringTests); + CPPUNIT_TEST(testIntegrity); + CPPUNIT_TEST(testAppend); + CPPUNIT_TEST(testSubstr); + CPPUNIT_TEST(testFromHexStr); + CPPUNIT_TEST(testXOR); + CPPUNIT_TEST(testToHexStr); + CPPUNIT_TEST(testLongValues); + CPPUNIT_TEST(testSplitting); + CPPUNIT_TEST(testBits); + CPPUNIT_TEST(testSerialising); + CPPUNIT_TEST_SUITE_END(); + +public: + void testIntegrity(); + void testAppend(); + void testSubstr(); + void testFromHexStr(); + void testXOR(); + void testToHexStr(); + void testLongValues(); + void testSplitting(); + void testBits(); + void testSerialising(); + + void setUp(); + void tearDown(); + +}; + +#endif // !_SOFTHSM_V2_BYTESTRINGTESTS_H + diff --git a/SoftHSMv2/src/lib/data_mgr/test/Makefile.am b/SoftHSMv2/src/lib/data_mgr/test/Makefile.am new file mode 100644 index 0000000..e1ebcdd --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/Makefile.am @@ -0,0 +1,27 @@ +MAINTAINERCLEANFILES = $(srcdir)/Makefile.in + +AM_CPPFLAGS = -I$(srcdir)/.. \ + -I$(srcdir)/../.. \ + -I$(srcdir)/../../common \ + -I$(srcdir)/../../crypto \ + -I$(srcdir)/../../object_store \ + -I$(srcdir)/../../pkcs11 \ + -I$(srcdir)/../../session_mgr \ + -I$(srcdir)/../../slot_mgr \ + @CPPUNIT_CFLAGS@ \ + @CRYPTO_INCLUDES@ + +check_PROGRAMS = datamgrtest + +datamgrtest_SOURCES = datamgrtest.cpp \ + ByteStringTests.cpp \ + RFC4880Tests.cpp \ + SecureDataMgrTests.cpp + +datamgrtest_LDADD = ../../libsofthsm_convarch.la + +datamgrtest_LDFLAGS = @CRYPTO_LIBS@ @CPPUNIT_LIBS@ -no-install + +TESTS = datamgrtest + +EXTRA_DIST = $(srcdir)/*.h diff --git a/SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.cpp b/SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.cpp new file mode 100644 index 0000000..6fcfd94 --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.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. + */ + +/***************************************************************************** + RFC4880Tests.cpp + + Contains test cases to test the RFC4880 implementation + *****************************************************************************/ + +#include <stdlib.h> +#include <string.h> +#include <cppunit/extensions/HelperMacros.h> +#include "RFC4880Tests.h" +#include "RFC4880.h" +#include "ByteString.h" +#include "CryptoFactory.h" +#include "AESKey.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(RFC4880Tests); + +void RFC4880Tests::setUp() +{ + CPPUNIT_ASSERT((rng = CryptoFactory::i()->getRNG()) != NULL); +} + +void RFC4880Tests::tearDown() +{ +} + +void RFC4880Tests::testRFC4880() +{ + const unsigned char* pwd1String = (const unsigned char*) "monkey"; + const unsigned char* pwd2String = (const unsigned char*) "bicycle"; + ByteString pwd1(pwd1String, strlen("monkey")); + ByteString pwd2(pwd2String, strlen("bicycle")); + + // Generate salt and make sure that two different salt values are generated and + // that the last byte is also different (resulting in a different iteration jitter + // when computing a PBE key using both salt values) + ByteString salt1, salt2; + + do + { + CPPUNIT_ASSERT(rng->generateRandom(salt1, 8) && rng->generateRandom(salt2, 8)); + } + while ((salt1 == salt2) || (salt1[salt1.size() - 1] == salt2[salt2.size() - 1])); + + // Create a password-based encryption key from the first and second password + AESKey* key1; + AESKey* key2; + + CPPUNIT_ASSERT(RFC4880::PBEDeriveKey(pwd1, salt1, &key1)); + CPPUNIT_ASSERT(RFC4880::PBEDeriveKey(pwd2, salt2, &key2)); + + // Check that the output keys differ and have the correct length + CPPUNIT_ASSERT(key1->getKeyBits().size() == 32); + CPPUNIT_ASSERT(key2->getKeyBits().size() == 32); + CPPUNIT_ASSERT(key1->getKeyBits() != key2->getKeyBits()); + + // Rederive the keys to check that the same output is generated every time + AESKey* key1_; + AESKey* key2_; + + CPPUNIT_ASSERT(RFC4880::PBEDeriveKey(pwd1, salt1, &key1_)); + CPPUNIT_ASSERT(RFC4880::PBEDeriveKey(pwd2, salt2, &key2_)); + + CPPUNIT_ASSERT(key1->getKeyBits() == key1_->getKeyBits()); + CPPUNIT_ASSERT(key2->getKeyBits() == key2_->getKeyBits()); + + // Now reverse the salts and derive new keys + AESKey* key3; + AESKey* key4; + + CPPUNIT_ASSERT(RFC4880::PBEDeriveKey(pwd1, salt2, &key3)); + CPPUNIT_ASSERT(RFC4880::PBEDeriveKey(pwd2, salt1, &key4)); + + // Check that the keys are different and that they differ from the + // original keys (because different salts were used) + CPPUNIT_ASSERT(key3->getKeyBits() != key4->getKeyBits()); + CPPUNIT_ASSERT(key1->getKeyBits() != key3->getKeyBits()); + CPPUNIT_ASSERT(key1->getKeyBits() != key4->getKeyBits()); + CPPUNIT_ASSERT(key2->getKeyBits() != key3->getKeyBits()); + CPPUNIT_ASSERT(key2->getKeyBits() != key4->getKeyBits()); + + // Clean up + delete key1; + delete key2; + delete key1_; + delete key2_; + delete key3; + delete key4; +} + diff --git a/SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.h b/SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.h new file mode 100644 index 0000000..4663626 --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/RFC4880Tests.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +/***************************************************************************** + RFC4880Tests.h + + Contains test cases to test the RFC4880 implementation + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_RFC4880TESTS_H +#define _SOFTHSM_V2_RFC4880TESTS_H + +#include <cppunit/extensions/HelperMacros.h> +#include "RNG.h" + +class RFC4880Tests : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(RFC4880Tests); + CPPUNIT_TEST(testRFC4880); + CPPUNIT_TEST_SUITE_END(); + +public: + void testRFC4880(); + + void setUp(); + void tearDown(); + +private: + RNG* rng; +}; + +#endif // !_SOFTHSM_V2_RFC4880TESTS_H + diff --git a/SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.cpp b/SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.cpp new file mode 100644 index 0000000..7ef4816 --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.cpp @@ -0,0 +1,207 @@ +/* + * 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. + */ + +/***************************************************************************** + SecureDataMgrTests.cpp + + Contains test cases to test the secure data manager + *****************************************************************************/ + +#include <stdlib.h> +#include <string.h> +#include <cppunit/extensions/HelperMacros.h> +#include "SecureDataMgrTests.h" +#include "SecureDataManager.h" +#include "CryptoFactory.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(SecureDataMgrTests); + +void SecureDataMgrTests::setUp() +{ + CPPUNIT_ASSERT((rng = CryptoFactory::i()->getRNG()) != NULL); +} + +void SecureDataMgrTests::tearDown() +{ +} + +void SecureDataMgrTests::testSecureDataManager() +{ + ByteString soPIN = "3132333435363738"; // "12345678" + ByteString userPIN = "4041424344454647"; // "ABCDEFGH" + ByteString newSOPIN = "3837363534333231"; // "87654321" + ByteString newUserPIN = "4746454443424140"; // "HGFEDCBA" + + // Instantiate a blank secure data manager + SecureDataManager s1; + ByteString plaintext = "010203040506070809"; + ByteString emptyPlaintext = ""; + ByteString encrypted; + + // Verify that no function other than setting the SO PIN works + CPPUNIT_ASSERT(!s1.setUserPIN(userPIN)); + CPPUNIT_ASSERT(!s1.loginSO(soPIN)); + CPPUNIT_ASSERT(!s1.loginUser(userPIN)); + CPPUNIT_ASSERT(!s1.reAuthenticateSO(soPIN)); + CPPUNIT_ASSERT(!s1.reAuthenticateUser(userPIN)); + CPPUNIT_ASSERT(!s1.encrypt(plaintext, encrypted)); + CPPUNIT_ASSERT(!s1.decrypt(encrypted, plaintext)); + CPPUNIT_ASSERT(s1.getSOPINBlob().size() == 0); + CPPUNIT_ASSERT(s1.getUserPINBlob().size() == 0); + + // Now set the SO PIN + CPPUNIT_ASSERT(s1.setSOPIN(soPIN)); + + // Check that it is still not possible to set the user PIN + CPPUNIT_ASSERT(!s1.setUserPIN(userPIN)); + + // Check that it is possible to log in with the SO PIN + CPPUNIT_ASSERT(s1.loginSO(soPIN)); + + // Check that it is now possible to also set the user PIN + CPPUNIT_ASSERT(s1.setUserPIN(userPIN)); + + // Check that is is now also possible to log in with the user PIN + CPPUNIT_ASSERT(s1.loginUser(userPIN)); + + // Check that it is possible to encrypt and decrypt some data + ByteString decrypted; + + CPPUNIT_ASSERT(s1.encrypt(plaintext, encrypted)); + CPPUNIT_ASSERT(encrypted != plaintext); + + CPPUNIT_ASSERT(s1.decrypt(encrypted, decrypted)); + CPPUNIT_ASSERT(decrypted == plaintext); + + // Log out + s1.logout(); + + // Check that it is no longer possible to set the SO PIN + CPPUNIT_ASSERT(!s1.setSOPIN(soPIN)); + + // Check that it is no longer possible to set the user PIN + CPPUNIT_ASSERT(!s1.setUserPIN(userPIN)); + + // Check that encrypting/decrypting no longer works + CPPUNIT_ASSERT(!s1.encrypt(plaintext, encrypted)); + CPPUNIT_ASSERT(!s1.decrypt(encrypted, plaintext)); + + // Export the key blobs + ByteString soPINBlob = s1.getSOPINBlob(); + ByteString userPINBlob = s1.getUserPINBlob(); + + // Create a new instance with the exported key blobs + SecureDataManager s2(soPINBlob, userPINBlob); + + // Check that the key blobs match + CPPUNIT_ASSERT(s1.getSOPINBlob() == s2.getSOPINBlob()); + CPPUNIT_ASSERT(s1.getUserPINBlob() == s2.getUserPINBlob()); + + // Check that it is not possible to set the SO PIN + CPPUNIT_ASSERT(!s2.setSOPIN(soPIN)); + + // Check that it is possible to log in with the SO PIN + CPPUNIT_ASSERT(s2.loginSO(soPIN)); + + // Check that is is now also possible to log in with the user PIN + CPPUNIT_ASSERT(s2.loginUser(userPIN)); + + // Check that encrypting the data results in different ciphertext because of the random IV + ByteString encrypted2; + + CPPUNIT_ASSERT(s2.encrypt(plaintext, encrypted2)); + CPPUNIT_ASSERT(encrypted != encrypted2); + + // Check that decrypting earlier data can be done with the recreated key + CPPUNIT_ASSERT(s2.decrypt(encrypted, decrypted)); + CPPUNIT_ASSERT(decrypted == plaintext); + + // Log in with the SO PIN + CPPUNIT_ASSERT(s2.loginSO(soPIN)); + + // Check that the SO PIN can be changed + CPPUNIT_ASSERT(s2.setSOPIN(newSOPIN)); + + // Check that it is no longer possible to log in with the old SO PIN + CPPUNIT_ASSERT(!s2.loginSO(soPIN)); + + // Check that encrypting/decrypting no longer works + CPPUNIT_ASSERT(!s2.encrypt(plaintext, encrypted)); + CPPUNIT_ASSERT(!s2.decrypt(encrypted, plaintext)); + + // Check that the key blobs differ + CPPUNIT_ASSERT(s1.getSOPINBlob() != s2.getSOPINBlob()); + + // Check that it is possible to log in with the new SO PIN + CPPUNIT_ASSERT(s2.loginSO(newSOPIN)); + + // Log in with the user PIN + CPPUNIT_ASSERT(s2.loginUser(userPIN)); + + // Check that it is possible to change the user PIN + CPPUNIT_ASSERT(s2.setUserPIN(newUserPIN)); + + // Check that it is no longer possible to log in with the old user PIN + CPPUNIT_ASSERT(!s2.loginUser(userPIN)); + + // Check that encrypting/decrypting no longer works + CPPUNIT_ASSERT(!s2.encrypt(plaintext, encrypted)); + CPPUNIT_ASSERT(!s2.decrypt(encrypted, plaintext)); + + // Check that it is possible to log in with the new user PIN + CPPUNIT_ASSERT(s2.loginUser(newUserPIN)); + + // Check that encrypting the data results in the different ciphertext because of the random IV + CPPUNIT_ASSERT(s2.encrypt(plaintext, encrypted2)); + CPPUNIT_ASSERT(encrypted != encrypted2); + + // Check that decrypting earlier data can be done with the recreated key + CPPUNIT_ASSERT(s2.decrypt(encrypted, decrypted)); + CPPUNIT_ASSERT(decrypted == plaintext); + + // Check that empty plaintext can be handled + CPPUNIT_ASSERT(s2.encrypt(emptyPlaintext, encrypted)); + CPPUNIT_ASSERT(s2.decrypt(encrypted, decrypted)); + CPPUNIT_ASSERT(decrypted == emptyPlaintext); + + // Check that is is possible to log in with the SO PIN and re-authenticate + CPPUNIT_ASSERT(s1.loginSO(soPIN)); + CPPUNIT_ASSERT(!s1.reAuthenticateSO(userPIN)); + CPPUNIT_ASSERT(s1.reAuthenticateSO(soPIN)); + + // Check that is is possible to log in with the user PIN and re-authenticate + CPPUNIT_ASSERT(s1.loginUser(userPIN)); + CPPUNIT_ASSERT(!s1.reAuthenticateUser(soPIN)); + CPPUNIT_ASSERT(s1.reAuthenticateUser(userPIN)); + + // Check that it is possible to encrypt and decrypt some data + CPPUNIT_ASSERT(s1.encrypt(plaintext, encrypted)); + CPPUNIT_ASSERT(encrypted != plaintext); + + CPPUNIT_ASSERT(s1.decrypt(encrypted, decrypted)); + CPPUNIT_ASSERT(decrypted == plaintext); +} + diff --git a/SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.h b/SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.h new file mode 100644 index 0000000..743a01b --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/SecureDataMgrTests.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +/***************************************************************************** + SecureDataMgrTests.h + + Contains test cases to test the secure data manager + *****************************************************************************/ + +#ifndef _SOFTHSM_V2_SECUREDATAMGRTESTS_H +#define _SOFTHSM_V2_SECUREDATAMGRTESTS_H + +#include <cppunit/extensions/HelperMacros.h> +#include "RNG.h" + +class SecureDataMgrTests : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(SecureDataMgrTests); + CPPUNIT_TEST(testSecureDataManager); + CPPUNIT_TEST_SUITE_END(); + +public: + void testSecureDataManager(); + + void setUp(); + void tearDown(); + +private: + RNG* rng; +}; + +#endif // !_SOFTHSM_V2_SECUREDATAMGRTESTS_H + diff --git a/SoftHSMv2/src/lib/data_mgr/test/datamgrtest.cpp b/SoftHSMv2/src/lib/data_mgr/test/datamgrtest.cpp new file mode 100644 index 0000000..49fa535 --- /dev/null +++ b/SoftHSMv2/src/lib/data_mgr/test/datamgrtest.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. + */ + +/***************************************************************************** + datamgrtest.cpp + + The main test executor for tests on the secure data 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; +} |