blob: 34d79b46859b5e9b667e48e77f806fbf77c573d5 [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 Pesavento47ce2ee2023-05-09 01:33:33 -04003 * Copyright (c) 2013-2023 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"
25#include "ndn-cxx/security/pib/key.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "ndn-cxx/security/transform/bool-sink.hpp"
27#include "ndn-cxx/security/transform/buffer-source.hpp"
28#include "ndn-cxx/security/transform/private-key.hpp"
29#include "ndn-cxx/security/transform/public-key.hpp"
30#include "ndn-cxx/security/transform/verifier-filter.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070031
Davide Pesavento7e780642018-11-24 15:51:34 -050032#include "tests/unit/security/tpm/back-end-wrapper-file.hpp"
33#include "tests/unit/security/tpm/back-end-wrapper-mem.hpp"
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050034#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
Davide Pesavento7e780642018-11-24 15:51:34 -050035#include "tests/unit/security/tpm/back-end-wrapper-osx.hpp"
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050036#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
Davide Pesaventocafa4022017-09-15 23:20:20 -040037
Davide Pesavento7e780642018-11-24 15:51:34 -050038#include "tests/boost-test.hpp"
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070039
Davide Pesavento80d671f2022-06-08 04:04:52 -040040#include <openssl/opensslv.h>
Davide Pesaventocafa4022017-09-15 23:20:20 -040041#include <boost/mpl/vector.hpp>
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070042#include <set>
43
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040044namespace ndn::tests {
45
46using namespace ndn::security;
47using ndn::security::tpm::BackEnd;
48using ndn::security::tpm::KeyHandle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070049
50BOOST_AUTO_TEST_SUITE(Security)
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040051BOOST_AUTO_TEST_SUITE(TestTpmBackEnd)
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070052
Davide Pesaventocafa4022017-09-15 23:20:20 -040053using TestBackEnds = boost::mpl::vector<
Davide Pesaventodc3575f2022-07-30 21:10:34 -040054#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070055 BackEndWrapperOsx,
Davide Pesaventodc3575f2022-07-30 21:10:34 -040056#endif
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070057 BackEndWrapperMem,
Davide Pesaventocafa4022017-09-15 23:20:20 -040058 BackEndWrapperFile>;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070059
60BOOST_AUTO_TEST_CASE_TEMPLATE(KeyManagement, T, TestBackEnds)
61{
62 T wrapper;
63 BackEnd& tpm = wrapper.getTpm();
64
65 Name identity("/Test/KeyName");
66 name::Component keyId("1");
Davide Pesaventof2cae612021-03-24 18:47:05 -040067 Name keyName = constructKeyName(identity, keyId);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070068
69 // key should not exist
70 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
71 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
72
73 // create key, should exist
74 BOOST_CHECK(tpm.createKey(identity, RsaKeyParams(keyId)) != nullptr);
75 BOOST_CHECK(tpm.hasKey(keyName));
76 BOOST_CHECK(tpm.getKeyHandle(keyName) != nullptr);
77
78 // create a key with the same name, should throw error
79 BOOST_CHECK_THROW(tpm.createKey(identity, RsaKeyParams(keyId)), Tpm::Error);
80
81 // delete key, should not exist
82 tpm.deleteKey(keyName);
83 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
84 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
85}
86
laqinfan56a812d2019-06-03 15:33:58 -050087BOOST_AUTO_TEST_CASE(CreateHmacKey)
88{
89 Name identity("/Test/Identity/HMAC");
90
Davide Pesavento94dfcf12021-09-26 14:18:45 -040091#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
laqinfan56a812d2019-06-03 15:33:58 -050092 BackEndWrapperMem mem;
93 BackEnd& memTpm = mem.getTpm();
94 auto key = memTpm.createKey(identity, HmacKeyParams());
95 BOOST_REQUIRE(key != nullptr);
96 BOOST_CHECK(!key->getKeyName().empty());
97 BOOST_CHECK(memTpm.hasKey(key->getKeyName()));
Davide Pesavento94dfcf12021-09-26 14:18:45 -040098#endif
laqinfan56a812d2019-06-03 15:33:58 -050099
100 BackEndWrapperFile file;
101 BackEnd& fileTpm = file.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400102 BOOST_CHECK_THROW(fileTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500103
104#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
105 BackEndWrapperOsx osx;
106 BackEnd& osxTpm = osx.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400107 BOOST_CHECK_THROW(osxTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500108#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
109}
110
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700111BOOST_AUTO_TEST_CASE_TEMPLATE(RsaSigning, T, TestBackEnds)
112{
113 T wrapper;
114 BackEnd& tpm = wrapper.getTpm();
115
Davide Pesavento13fffa32018-09-30 16:21:33 -0400116 // create an RSA key
laqinfancf0baa22019-06-03 15:33:58 -0500117 Name identity("/Test/RSA/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700118 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
119 Name keyName = key->getKeyName();
120
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700121 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500122 auto pubKeyBits = key->derivePublicKey();
123 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700124
Davide Pesavento765abc92021-12-27 00:44:04 -0500125 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700126 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500127 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700128 BOOST_REQUIRE(sigValueSingle != nullptr);
129
130 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700131 {
132 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500133 bufferSource(content1)
Davide Pesavento35c63792022-01-17 02:06:03 -0500134 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueSingle)
Davide Pesavento765abc92021-12-27 00:44:04 -0500135 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700136 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700137 BOOST_CHECK_EQUAL(resultSingle, true);
138
Davide Pesavento765abc92021-12-27 00:44:04 -0500139 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700140 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500141 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700142 BOOST_REQUIRE(sigValueVector != nullptr);
143
144 bool resultVector;
145 {
146 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500147 bufferSource(InputBuffers{content1, content2})
Davide Pesavento35c63792022-01-17 02:06:03 -0500148 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueVector)
Davide Pesavento765abc92021-12-27 00:44:04 -0500149 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700150 }
151 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700152
153 tpm.deleteKey(keyName);
154 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
155}
156
157BOOST_AUTO_TEST_CASE_TEMPLATE(RsaDecryption, T, TestBackEnds)
158{
159 T wrapper;
160 BackEnd& tpm = wrapper.getTpm();
161
Davide Pesavento13fffa32018-09-30 16:21:33 -0400162 // create an RSA key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700163 Name identity("/Test/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700164 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
165 Name keyName = key->getKeyName();
166
167 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
168
169 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500170 auto pubKeyBits = key->derivePublicKey();
171 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700172
Davide Pesavento765abc92021-12-27 00:44:04 -0500173 ConstBufferPtr cipherText = pubKey.encrypt(content);
174 ConstBufferPtr plainText = key->decrypt(*cipherText);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700175
176 BOOST_CHECK_EQUAL_COLLECTIONS(content, content + sizeof(content),
177 plainText->begin(), plainText->end());
178
179 tpm.deleteKey(keyName);
180 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
181}
182
183BOOST_AUTO_TEST_CASE_TEMPLATE(EcdsaSigning, T, TestBackEnds)
184{
185 T wrapper;
186 BackEnd& tpm = wrapper.getTpm();
187
Davide Pesavento13fffa32018-09-30 16:21:33 -0400188 // create an EC key
laqinfancf0baa22019-06-03 15:33:58 -0500189 Name identity("/Test/EC/KeyName");
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700190 unique_ptr<KeyHandle> key = tpm.createKey(identity, EcKeyParams());
191 Name ecKeyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700192
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700193 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500194 auto pubKeyBits = key->derivePublicKey();
195 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700196
Davide Pesavento765abc92021-12-27 00:44:04 -0500197 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700198 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500199 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700200 BOOST_REQUIRE(sigValueSingle != nullptr);
201
202 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700203 {
204 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500205 bufferSource(content1)
Davide Pesavento35c63792022-01-17 02:06:03 -0500206 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueSingle)
Davide Pesavento765abc92021-12-27 00:44:04 -0500207 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700208 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700209 BOOST_CHECK_EQUAL(resultSingle, true);
210
Davide Pesavento765abc92021-12-27 00:44:04 -0500211 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700212 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500213 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700214 BOOST_REQUIRE(sigValueVector != nullptr);
215
216 bool resultVector;
217 {
218 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500219 bufferSource(InputBuffers{content1, content2})
Davide Pesavento35c63792022-01-17 02:06:03 -0500220 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueVector)
Davide Pesavento765abc92021-12-27 00:44:04 -0500221 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700222 }
223 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700224
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700225 tpm.deleteKey(ecKeyName);
226 BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700227}
228
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400229#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
laqinfancf0baa22019-06-03 15:33:58 -0500230BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
231{
232 BackEndWrapperMem wrapper;
233 BackEnd& tpm = wrapper.getTpm();
234
235 // create an HMAC key
236 Name identity("/Test/HMAC/KeyName");
237 unique_ptr<KeyHandle> key = tpm.createKey(identity, HmacKeyParams());
238 Name hmacKeyName = key->getKeyName();
239
Davide Pesavento765abc92021-12-27 00:44:04 -0500240 // Sign and verify a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700241 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500242 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700243 BOOST_REQUIRE(sigValueSingle != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500244 bool resultSingle = key->verify(DigestAlgorithm::SHA256, {content1}, *sigValueSingle);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700245 BOOST_CHECK_EQUAL(resultSingle, true);
laqinfancf0baa22019-06-03 15:33:58 -0500246
Davide Pesavento765abc92021-12-27 00:44:04 -0500247 // Sign and verify multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700248 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500249 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700250 BOOST_REQUIRE(sigValueVector != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500251 bool resultVector = key->verify(DigestAlgorithm::SHA256, {content1, content2}, *sigValueVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700252 BOOST_CHECK_EQUAL(resultVector, true);
laqinfancf0baa22019-06-03 15:33:58 -0500253
254 tpm.deleteKey(hmacKeyName);
255 BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
256}
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400257#endif
laqinfancf0baa22019-06-03 15:33:58 -0500258
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700259BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
260{
Davide Pesavento13fffa32018-09-30 16:21:33 -0400261 const std::string privKeyPkcs1 =
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700262 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
263 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
264 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
265 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
266 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
267 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
268 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
269 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
270 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
271 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
272 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
273 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
274 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
275 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
276 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
277 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
278 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
279 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
280 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
281 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
282 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
283 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
284 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
285 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
286 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Davide Pesavento13fffa32018-09-30 16:21:33 -0400287 const std::string password("password");
288 const std::string wrongPassword("wrong");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700289
290 T wrapper;
291 BackEnd& tpm = wrapper.getTpm();
292
293 Name keyName("/Test/KeyName/KEY/1");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700294 tpm.deleteKey(keyName);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400295 BOOST_REQUIRE_EQUAL(tpm.hasKey(keyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700296
297 transform::PrivateKey sKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500298 sKey.loadPkcs1Base64({reinterpret_cast<const uint8_t*>(privKeyPkcs1.data()), privKeyPkcs1.size()});
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700299 OBufferStream os;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400300 sKey.savePkcs8(os, password.data(), password.size());
301 auto pkcs8 = os.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700302
Davide Pesavento13fffa32018-09-30 16:21:33 -0400303 // import with wrong password
Davide Pesavento765abc92021-12-27 00:44:04 -0500304 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, wrongPassword.data(), wrongPassword.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400305 Tpm::Error);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400306 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
307
308 // import with correct password
Davide Pesavento765abc92021-12-27 00:44:04 -0500309 tpm.importKey(keyName, *pkcs8, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700310 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400311
312 // import already present key
Davide Pesavento765abc92021-12-27 00:44:04 -0500313 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, password.data(), password.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400314 Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700315
Davide Pesavento13fffa32018-09-30 16:21:33 -0400316 // test derivePublicKey with the imported key
317 auto keyHdl = tpm.getKeyHandle(keyName);
318 auto pubKey = keyHdl->derivePublicKey();
319 BOOST_CHECK(pubKey != nullptr);
320
321 // export
322 auto exportedKey = tpm.exportKey(keyName, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700323 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
324
325 transform::PrivateKey sKey2;
Davide Pesavento765abc92021-12-27 00:44:04 -0500326 sKey2.loadPkcs8(*exportedKey, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700327 OBufferStream os2;
328 sKey.savePkcs1Base64(os2);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400329 auto pkcs1 = os2.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700330
Davide Pesavento13fffa32018-09-30 16:21:33 -0400331 // verify that the exported key is identical to the key that was imported
332 BOOST_CHECK_EQUAL_COLLECTIONS(privKeyPkcs1.begin(), privKeyPkcs1.end(),
333 pkcs1->begin(), pkcs1->end());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700334
Davide Pesavento13fffa32018-09-30 16:21:33 -0400335 // export nonexistent key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700336 tpm.deleteKey(keyName);
337 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
Davide Pesavento12cef872019-10-31 02:24:03 -0400338 BOOST_CHECK_THROW(tpm.exportKey(keyName, password.data(), password.size()), Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700339}
340
341BOOST_AUTO_TEST_CASE(RandomKeyId)
342{
343 BackEndWrapperMem wrapper;
344 BackEnd& tpm = wrapper.getTpm();
345 Name identity("/Test/KeyName");
346
347 std::set<Name> keyNames;
348 for (int i = 0; i < 100; i++) {
349 auto key = tpm.createKey(identity, RsaKeyParams());
350 Name keyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700351 BOOST_CHECK(keyNames.insert(keyName).second);
352 }
353}
354
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400355BOOST_AUTO_TEST_SUITE_END() // TestTpmBackEnd
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700356BOOST_AUTO_TEST_SUITE_END() // Security
357
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400358} // namespace ndn::tests