blob: 0b22d540eb0f6e713aba9d97abfefbcfd4fe66fb [file] [log] [blame]
Yingdi Yu0b60e7a2015-07-16 21:05:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesaventocafa4022017-09-15 23:20:20 -04002/*
Davide Pesaventof2cae612021-03-24 18:47:05 -04003 * Copyright (c) 2013-2021 Regents of the University of California.
Yingdi Yu0b60e7a2015-07-16 21:05:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/security/tpm/back-end.hpp"
Davide Pesavento13fffa32018-09-30 16:21:33 -040023
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "ndn-cxx/encoding/buffer-stream.hpp"
Davide Pesavento94dfcf12021-09-26 14:18:45 -040025#include "ndn-cxx/security/impl/openssl.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "ndn-cxx/security/pib/key.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050027#include "ndn-cxx/security/transform/bool-sink.hpp"
28#include "ndn-cxx/security/transform/buffer-source.hpp"
29#include "ndn-cxx/security/transform/private-key.hpp"
30#include "ndn-cxx/security/transform/public-key.hpp"
31#include "ndn-cxx/security/transform/verifier-filter.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070032
Davide Pesavento7e780642018-11-24 15:51:34 -050033#include "tests/unit/security/tpm/back-end-wrapper-file.hpp"
34#include "tests/unit/security/tpm/back-end-wrapper-mem.hpp"
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050035#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
Davide Pesavento7e780642018-11-24 15:51:34 -050036#include "tests/unit/security/tpm/back-end-wrapper-osx.hpp"
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050037#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
Davide Pesaventocafa4022017-09-15 23:20:20 -040038
Davide Pesavento7e780642018-11-24 15:51:34 -050039#include "tests/boost-test.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070040
Davide Pesaventocafa4022017-09-15 23:20:20 -040041#include <boost/mpl/vector.hpp>
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070042#include <set>
43
44namespace ndn {
45namespace security {
46namespace tpm {
47namespace tests {
48
49BOOST_AUTO_TEST_SUITE(Security)
50BOOST_AUTO_TEST_SUITE(Tpm)
51BOOST_AUTO_TEST_SUITE(TestBackEnd)
52
53using tpm::Tpm;
54
Davide Pesaventocafa4022017-09-15 23:20:20 -040055using TestBackEnds = boost::mpl::vector<
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050056#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070057 BackEndWrapperOsx,
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050058#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070059 BackEndWrapperMem,
Davide Pesaventocafa4022017-09-15 23:20:20 -040060 BackEndWrapperFile>;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070061
62BOOST_AUTO_TEST_CASE_TEMPLATE(KeyManagement, T, TestBackEnds)
63{
64 T wrapper;
65 BackEnd& tpm = wrapper.getTpm();
66
67 Name identity("/Test/KeyName");
68 name::Component keyId("1");
Davide Pesaventof2cae612021-03-24 18:47:05 -040069 Name keyName = constructKeyName(identity, keyId);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070070
71 // key should not exist
72 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
73 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
74
75 // create key, should exist
76 BOOST_CHECK(tpm.createKey(identity, RsaKeyParams(keyId)) != nullptr);
77 BOOST_CHECK(tpm.hasKey(keyName));
78 BOOST_CHECK(tpm.getKeyHandle(keyName) != nullptr);
79
80 // create a key with the same name, should throw error
81 BOOST_CHECK_THROW(tpm.createKey(identity, RsaKeyParams(keyId)), Tpm::Error);
82
83 // delete key, should not exist
84 tpm.deleteKey(keyName);
85 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
86 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
87}
88
laqinfan56a812d2019-06-03 15:33:58 -050089BOOST_AUTO_TEST_CASE(CreateHmacKey)
90{
91 Name identity("/Test/Identity/HMAC");
92
Davide Pesavento94dfcf12021-09-26 14:18:45 -040093#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
laqinfan56a812d2019-06-03 15:33:58 -050094 BackEndWrapperMem mem;
95 BackEnd& memTpm = mem.getTpm();
96 auto key = memTpm.createKey(identity, HmacKeyParams());
97 BOOST_REQUIRE(key != nullptr);
98 BOOST_CHECK(!key->getKeyName().empty());
99 BOOST_CHECK(memTpm.hasKey(key->getKeyName()));
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400100#endif
laqinfan56a812d2019-06-03 15:33:58 -0500101
102 BackEndWrapperFile file;
103 BackEnd& fileTpm = file.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400104 BOOST_CHECK_THROW(fileTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500105
106#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
107 BackEndWrapperOsx osx;
108 BackEnd& osxTpm = osx.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400109 BOOST_CHECK_THROW(osxTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500110#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
111}
112
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700113BOOST_AUTO_TEST_CASE_TEMPLATE(RsaSigning, T, TestBackEnds)
114{
115 T wrapper;
116 BackEnd& tpm = wrapper.getTpm();
117
Davide Pesavento13fffa32018-09-30 16:21:33 -0400118 // create an RSA key
laqinfancf0baa22019-06-03 15:33:58 -0500119 Name identity("/Test/RSA/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700120 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
121 Name keyName = key->getKeyName();
122
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700123 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500124 auto pubKeyBits = key->derivePublicKey();
125 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700126
Davide Pesavento765abc92021-12-27 00:44:04 -0500127 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700128 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500129 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700130 BOOST_REQUIRE(sigValueSingle != nullptr);
131
132 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700133 {
134 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500135 bufferSource(content1)
136 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, sigValueSingle->data(), sigValueSingle->size())
137 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700138 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700139 BOOST_CHECK_EQUAL(resultSingle, true);
140
Davide Pesavento765abc92021-12-27 00:44:04 -0500141 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700142 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500143 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700144 BOOST_REQUIRE(sigValueVector != nullptr);
145
146 bool resultVector;
147 {
148 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500149 bufferSource(InputBuffers{content1, content2})
150 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, sigValueVector->data(), sigValueVector->size())
151 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700152 }
153 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700154
155 tpm.deleteKey(keyName);
156 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
157}
158
159BOOST_AUTO_TEST_CASE_TEMPLATE(RsaDecryption, T, TestBackEnds)
160{
161 T wrapper;
162 BackEnd& tpm = wrapper.getTpm();
163
Davide Pesavento13fffa32018-09-30 16:21:33 -0400164 // create an RSA key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700165 Name identity("/Test/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700166 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
167 Name keyName = key->getKeyName();
168
169 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
170
171 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500172 auto pubKeyBits = key->derivePublicKey();
173 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700174
Davide Pesavento765abc92021-12-27 00:44:04 -0500175 ConstBufferPtr cipherText = pubKey.encrypt(content);
176 ConstBufferPtr plainText = key->decrypt(*cipherText);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700177
178 BOOST_CHECK_EQUAL_COLLECTIONS(content, content + sizeof(content),
179 plainText->begin(), plainText->end());
180
181 tpm.deleteKey(keyName);
182 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
183}
184
185BOOST_AUTO_TEST_CASE_TEMPLATE(EcdsaSigning, T, TestBackEnds)
186{
187 T wrapper;
188 BackEnd& tpm = wrapper.getTpm();
189
Davide Pesavento13fffa32018-09-30 16:21:33 -0400190 // create an EC key
laqinfancf0baa22019-06-03 15:33:58 -0500191 Name identity("/Test/EC/KeyName");
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700192 unique_ptr<KeyHandle> key = tpm.createKey(identity, EcKeyParams());
193 Name ecKeyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700194
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700195 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500196 auto pubKeyBits = key->derivePublicKey();
197 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700198
Davide Pesavento765abc92021-12-27 00:44:04 -0500199 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700200 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500201 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700202 BOOST_REQUIRE(sigValueSingle != nullptr);
203
204 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700205 {
206 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500207 bufferSource(content1)
208 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, sigValueSingle->data(), sigValueSingle->size())
209 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700210 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700211 BOOST_CHECK_EQUAL(resultSingle, true);
212
Davide Pesavento765abc92021-12-27 00:44:04 -0500213 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700214 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500215 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700216 BOOST_REQUIRE(sigValueVector != nullptr);
217
218 bool resultVector;
219 {
220 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500221 bufferSource(InputBuffers{content1, content2})
222 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, sigValueVector->data(), sigValueVector->size())
223 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700224 }
225 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700226
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700227 tpm.deleteKey(ecKeyName);
228 BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700229}
230
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400231#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
laqinfancf0baa22019-06-03 15:33:58 -0500232BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
233{
234 BackEndWrapperMem wrapper;
235 BackEnd& tpm = wrapper.getTpm();
236
237 // create an HMAC key
238 Name identity("/Test/HMAC/KeyName");
239 unique_ptr<KeyHandle> key = tpm.createKey(identity, HmacKeyParams());
240 Name hmacKeyName = key->getKeyName();
241
Davide Pesavento765abc92021-12-27 00:44:04 -0500242 // Sign and verify a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700243 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500244 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700245 BOOST_REQUIRE(sigValueSingle != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500246 bool resultSingle = key->verify(DigestAlgorithm::SHA256, {content1}, *sigValueSingle);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700247 BOOST_CHECK_EQUAL(resultSingle, true);
laqinfancf0baa22019-06-03 15:33:58 -0500248
Davide Pesavento765abc92021-12-27 00:44:04 -0500249 // Sign and verify multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700250 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500251 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700252 BOOST_REQUIRE(sigValueVector != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500253 bool resultVector = key->verify(DigestAlgorithm::SHA256, {content1, content2}, *sigValueVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700254 BOOST_CHECK_EQUAL(resultVector, true);
laqinfancf0baa22019-06-03 15:33:58 -0500255
256 tpm.deleteKey(hmacKeyName);
257 BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
258}
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400259#endif
laqinfancf0baa22019-06-03 15:33:58 -0500260
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700261BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
262{
Davide Pesavento13fffa32018-09-30 16:21:33 -0400263 const std::string privKeyPkcs1 =
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700264 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
265 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
266 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
267 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
268 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
269 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
270 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
271 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
272 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
273 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
274 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
275 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
276 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
277 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
278 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
279 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
280 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
281 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
282 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
283 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
284 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
285 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
286 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
287 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
288 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Davide Pesavento13fffa32018-09-30 16:21:33 -0400289 const std::string password("password");
290 const std::string wrongPassword("wrong");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700291
292 T wrapper;
293 BackEnd& tpm = wrapper.getTpm();
294
295 Name keyName("/Test/KeyName/KEY/1");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700296 tpm.deleteKey(keyName);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400297 BOOST_REQUIRE_EQUAL(tpm.hasKey(keyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700298
299 transform::PrivateKey sKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500300 sKey.loadPkcs1Base64({reinterpret_cast<const uint8_t*>(privKeyPkcs1.data()), privKeyPkcs1.size()});
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700301 OBufferStream os;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400302 sKey.savePkcs8(os, password.data(), password.size());
303 auto pkcs8 = os.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700304
Davide Pesavento13fffa32018-09-30 16:21:33 -0400305 // import with wrong password
Davide Pesavento765abc92021-12-27 00:44:04 -0500306 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, wrongPassword.data(), wrongPassword.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400307 Tpm::Error);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400308 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
309
310 // import with correct password
Davide Pesavento765abc92021-12-27 00:44:04 -0500311 tpm.importKey(keyName, *pkcs8, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700312 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400313
314 // import already present key
Davide Pesavento765abc92021-12-27 00:44:04 -0500315 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, password.data(), password.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400316 Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700317
Davide Pesavento13fffa32018-09-30 16:21:33 -0400318 // test derivePublicKey with the imported key
319 auto keyHdl = tpm.getKeyHandle(keyName);
320 auto pubKey = keyHdl->derivePublicKey();
321 BOOST_CHECK(pubKey != nullptr);
322
323 // export
324 auto exportedKey = tpm.exportKey(keyName, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700325 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
326
327 transform::PrivateKey sKey2;
Davide Pesavento765abc92021-12-27 00:44:04 -0500328 sKey2.loadPkcs8(*exportedKey, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700329 OBufferStream os2;
330 sKey.savePkcs1Base64(os2);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400331 auto pkcs1 = os2.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700332
Davide Pesavento13fffa32018-09-30 16:21:33 -0400333 // verify that the exported key is identical to the key that was imported
334 BOOST_CHECK_EQUAL_COLLECTIONS(privKeyPkcs1.begin(), privKeyPkcs1.end(),
335 pkcs1->begin(), pkcs1->end());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700336
Davide Pesavento13fffa32018-09-30 16:21:33 -0400337 // export nonexistent key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700338 tpm.deleteKey(keyName);
339 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
Davide Pesavento12cef872019-10-31 02:24:03 -0400340 BOOST_CHECK_THROW(tpm.exportKey(keyName, password.data(), password.size()), Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700341}
342
343BOOST_AUTO_TEST_CASE(RandomKeyId)
344{
345 BackEndWrapperMem wrapper;
346 BackEnd& tpm = wrapper.getTpm();
347 Name identity("/Test/KeyName");
348
349 std::set<Name> keyNames;
350 for (int i = 0; i < 100; i++) {
351 auto key = tpm.createKey(identity, RsaKeyParams());
352 Name keyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700353 BOOST_CHECK(keyNames.insert(keyName).second);
354 }
355}
356
357BOOST_AUTO_TEST_SUITE_END() // TestBackEnd
358BOOST_AUTO_TEST_SUITE_END() // Tpm
359BOOST_AUTO_TEST_SUITE_END() // Security
360
361} // namespace tests
362} // namespace tpm
363} // namespace security
364} // namespace ndn