blob: cb0ec5d2ad21828aa23bba18d40f092283b53a72 [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 Pesavento334516a2024-02-09 18:02:36 -05003 * Copyright (c) 2013-2024 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
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070040#include <set>
Davide Pesavento49e1e872023-11-11 00:45:23 -050041#include <boost/mp11/list.hpp>
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070042
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040043namespace ndn::tests {
44
45using namespace ndn::security;
46using ndn::security::tpm::BackEnd;
47using ndn::security::tpm::KeyHandle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070048
49BOOST_AUTO_TEST_SUITE(Security)
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040050BOOST_AUTO_TEST_SUITE(TestTpmBackEnd)
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070051
Davide Pesavento49e1e872023-11-11 00:45:23 -050052using TestBackEnds = boost::mp11::mp_list<
Davide Pesaventodc3575f2022-07-30 21:10:34 -040053#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS) && defined(NDN_CXX_WITH_OSX_KEYCHAIN)
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070054 BackEndWrapperOsx,
Davide Pesaventodc3575f2022-07-30 21:10:34 -040055#endif
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070056 BackEndWrapperMem,
Davide Pesaventocafa4022017-09-15 23:20:20 -040057 BackEndWrapperFile>;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070058
59BOOST_AUTO_TEST_CASE_TEMPLATE(KeyManagement, T, TestBackEnds)
60{
61 T wrapper;
62 BackEnd& tpm = wrapper.getTpm();
63
64 Name identity("/Test/KeyName");
65 name::Component keyId("1");
Davide Pesaventof2cae612021-03-24 18:47:05 -040066 Name keyName = constructKeyName(identity, keyId);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070067
68 // key should not exist
69 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
70 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
71
72 // create key, should exist
73 BOOST_CHECK(tpm.createKey(identity, RsaKeyParams(keyId)) != nullptr);
74 BOOST_CHECK(tpm.hasKey(keyName));
75 BOOST_CHECK(tpm.getKeyHandle(keyName) != nullptr);
76
77 // create a key with the same name, should throw error
78 BOOST_CHECK_THROW(tpm.createKey(identity, RsaKeyParams(keyId)), Tpm::Error);
79
80 // delete key, should not exist
81 tpm.deleteKey(keyName);
82 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
83 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
84}
85
laqinfan56a812d2019-06-03 15:33:58 -050086BOOST_AUTO_TEST_CASE(CreateHmacKey)
87{
88 Name identity("/Test/Identity/HMAC");
89
90 BackEndWrapperMem mem;
91 BackEnd& memTpm = mem.getTpm();
92 auto key = memTpm.createKey(identity, HmacKeyParams());
93 BOOST_REQUIRE(key != nullptr);
94 BOOST_CHECK(!key->getKeyName().empty());
95 BOOST_CHECK(memTpm.hasKey(key->getKeyName()));
96
97 BackEndWrapperFile file;
98 BackEnd& fileTpm = file.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -040099 BOOST_CHECK_THROW(fileTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500100
101#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
102 BackEndWrapperOsx osx;
103 BackEnd& osxTpm = osx.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400104 BOOST_CHECK_THROW(osxTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500105#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
106}
107
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700108BOOST_AUTO_TEST_CASE_TEMPLATE(RsaSigning, T, TestBackEnds)
109{
110 T wrapper;
111 BackEnd& tpm = wrapper.getTpm();
112
Davide Pesavento13fffa32018-09-30 16:21:33 -0400113 // create an RSA key
laqinfancf0baa22019-06-03 15:33:58 -0500114 Name identity("/Test/RSA/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700115 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
116 Name keyName = key->getKeyName();
117
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700118 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500119 auto pubKeyBits = key->derivePublicKey();
120 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700121
Davide Pesavento765abc92021-12-27 00:44:04 -0500122 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700123 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500124 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700125 BOOST_REQUIRE(sigValueSingle != nullptr);
126
127 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700128 {
129 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500130 bufferSource(content1)
Davide Pesavento35c63792022-01-17 02:06:03 -0500131 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueSingle)
Davide Pesavento765abc92021-12-27 00:44:04 -0500132 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700133 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700134 BOOST_CHECK_EQUAL(resultSingle, true);
135
Davide Pesavento765abc92021-12-27 00:44:04 -0500136 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700137 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500138 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700139 BOOST_REQUIRE(sigValueVector != nullptr);
140
141 bool resultVector;
142 {
143 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500144 bufferSource(InputBuffers{content1, content2})
Davide Pesavento35c63792022-01-17 02:06:03 -0500145 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueVector)
Davide Pesavento765abc92021-12-27 00:44:04 -0500146 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700147 }
148 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700149
150 tpm.deleteKey(keyName);
151 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
152}
153
154BOOST_AUTO_TEST_CASE_TEMPLATE(RsaDecryption, T, TestBackEnds)
155{
156 T wrapper;
157 BackEnd& tpm = wrapper.getTpm();
158
Davide Pesavento13fffa32018-09-30 16:21:33 -0400159 // create an RSA key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700160 Name identity("/Test/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700161 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
162 Name keyName = key->getKeyName();
163
164 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
165
166 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500167 auto pubKeyBits = key->derivePublicKey();
168 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700169
Davide Pesavento765abc92021-12-27 00:44:04 -0500170 ConstBufferPtr cipherText = pubKey.encrypt(content);
171 ConstBufferPtr plainText = key->decrypt(*cipherText);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700172
173 BOOST_CHECK_EQUAL_COLLECTIONS(content, content + sizeof(content),
174 plainText->begin(), plainText->end());
175
176 tpm.deleteKey(keyName);
177 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
178}
179
180BOOST_AUTO_TEST_CASE_TEMPLATE(EcdsaSigning, T, TestBackEnds)
181{
182 T wrapper;
183 BackEnd& tpm = wrapper.getTpm();
184
Davide Pesavento13fffa32018-09-30 16:21:33 -0400185 // create an EC key
laqinfancf0baa22019-06-03 15:33:58 -0500186 Name identity("/Test/EC/KeyName");
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700187 unique_ptr<KeyHandle> key = tpm.createKey(identity, EcKeyParams());
188 Name ecKeyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700189
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700190 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500191 auto pubKeyBits = key->derivePublicKey();
192 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700193
Davide Pesavento765abc92021-12-27 00:44:04 -0500194 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700195 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500196 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700197 BOOST_REQUIRE(sigValueSingle != nullptr);
198
199 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700200 {
201 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500202 bufferSource(content1)
Davide Pesavento35c63792022-01-17 02:06:03 -0500203 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueSingle)
Davide Pesavento765abc92021-12-27 00:44:04 -0500204 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700205 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700206 BOOST_CHECK_EQUAL(resultSingle, true);
207
Davide Pesavento765abc92021-12-27 00:44:04 -0500208 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700209 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500210 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700211 BOOST_REQUIRE(sigValueVector != nullptr);
212
213 bool resultVector;
214 {
215 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500216 bufferSource(InputBuffers{content1, content2})
Davide Pesavento35c63792022-01-17 02:06:03 -0500217 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueVector)
Davide Pesavento765abc92021-12-27 00:44:04 -0500218 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700219 }
220 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700221
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700222 tpm.deleteKey(ecKeyName);
223 BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700224}
225
laqinfancf0baa22019-06-03 15:33:58 -0500226BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
227{
228 BackEndWrapperMem wrapper;
229 BackEnd& tpm = wrapper.getTpm();
230
231 // create an HMAC key
232 Name identity("/Test/HMAC/KeyName");
233 unique_ptr<KeyHandle> key = tpm.createKey(identity, HmacKeyParams());
234 Name hmacKeyName = key->getKeyName();
235
Davide Pesavento765abc92021-12-27 00:44:04 -0500236 // Sign and verify a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700237 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500238 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700239 BOOST_REQUIRE(sigValueSingle != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500240 bool resultSingle = key->verify(DigestAlgorithm::SHA256, {content1}, *sigValueSingle);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700241 BOOST_CHECK_EQUAL(resultSingle, true);
laqinfancf0baa22019-06-03 15:33:58 -0500242
Davide Pesavento765abc92021-12-27 00:44:04 -0500243 // Sign and verify multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700244 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500245 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700246 BOOST_REQUIRE(sigValueVector != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500247 bool resultVector = key->verify(DigestAlgorithm::SHA256, {content1, content2}, *sigValueVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700248 BOOST_CHECK_EQUAL(resultVector, true);
laqinfancf0baa22019-06-03 15:33:58 -0500249
250 tpm.deleteKey(hmacKeyName);
251 BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
252}
253
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700254BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
255{
Davide Pesavento13fffa32018-09-30 16:21:33 -0400256 const std::string privKeyPkcs1 =
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700257 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
258 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
259 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
260 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
261 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
262 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
263 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
264 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
265 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
266 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
267 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
268 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
269 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
270 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
271 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
272 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
273 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
274 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
275 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
276 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
277 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
278 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
279 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
280 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
281 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Davide Pesavento13fffa32018-09-30 16:21:33 -0400282 const std::string password("password");
283 const std::string wrongPassword("wrong");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700284
285 T wrapper;
286 BackEnd& tpm = wrapper.getTpm();
287
288 Name keyName("/Test/KeyName/KEY/1");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700289 tpm.deleteKey(keyName);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400290 BOOST_REQUIRE_EQUAL(tpm.hasKey(keyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700291
292 transform::PrivateKey sKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500293 sKey.loadPkcs1Base64({reinterpret_cast<const uint8_t*>(privKeyPkcs1.data()), privKeyPkcs1.size()});
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700294 OBufferStream os;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400295 sKey.savePkcs8(os, password.data(), password.size());
296 auto pkcs8 = os.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700297
Davide Pesavento13fffa32018-09-30 16:21:33 -0400298 // import with wrong password
Davide Pesavento765abc92021-12-27 00:44:04 -0500299 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, wrongPassword.data(), wrongPassword.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400300 Tpm::Error);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400301 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
302
303 // import with correct password
Davide Pesavento765abc92021-12-27 00:44:04 -0500304 tpm.importKey(keyName, *pkcs8, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700305 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400306
307 // import already present key
Davide Pesavento765abc92021-12-27 00:44:04 -0500308 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, password.data(), password.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400309 Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700310
Davide Pesavento13fffa32018-09-30 16:21:33 -0400311 // test derivePublicKey with the imported key
312 auto keyHdl = tpm.getKeyHandle(keyName);
313 auto pubKey = keyHdl->derivePublicKey();
314 BOOST_CHECK(pubKey != nullptr);
315
316 // export
317 auto exportedKey = tpm.exportKey(keyName, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700318 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
319
320 transform::PrivateKey sKey2;
Davide Pesavento765abc92021-12-27 00:44:04 -0500321 sKey2.loadPkcs8(*exportedKey, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700322 OBufferStream os2;
323 sKey.savePkcs1Base64(os2);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400324 auto pkcs1 = os2.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700325
Davide Pesavento13fffa32018-09-30 16:21:33 -0400326 // verify that the exported key is identical to the key that was imported
327 BOOST_CHECK_EQUAL_COLLECTIONS(privKeyPkcs1.begin(), privKeyPkcs1.end(),
328 pkcs1->begin(), pkcs1->end());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700329
Davide Pesavento13fffa32018-09-30 16:21:33 -0400330 // export nonexistent key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700331 tpm.deleteKey(keyName);
332 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
Davide Pesavento12cef872019-10-31 02:24:03 -0400333 BOOST_CHECK_THROW(tpm.exportKey(keyName, password.data(), password.size()), Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700334}
335
336BOOST_AUTO_TEST_CASE(RandomKeyId)
337{
338 BackEndWrapperMem wrapper;
339 BackEnd& tpm = wrapper.getTpm();
340 Name identity("/Test/KeyName");
341
342 std::set<Name> keyNames;
343 for (int i = 0; i < 100; i++) {
344 auto key = tpm.createKey(identity, RsaKeyParams());
345 Name keyName = key->getKeyName();
Davide Pesavento334516a2024-02-09 18:02:36 -0500346 BOOST_TEST_INFO_SCOPE("KeyName = " << keyName);
347 BOOST_TEST(keyNames.insert(keyName).second);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700348 }
349}
350
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400351BOOST_AUTO_TEST_SUITE_END() // TestTpmBackEnd
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700352BOOST_AUTO_TEST_SUITE_END() // Security
353
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400354} // namespace ndn::tests