blob: da2202968ef56b770dcb1a2db6c41625c1f1c1af [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
91 BackEndWrapperMem mem;
92 BackEnd& memTpm = mem.getTpm();
93 auto key = memTpm.createKey(identity, HmacKeyParams());
94 BOOST_REQUIRE(key != nullptr);
95 BOOST_CHECK(!key->getKeyName().empty());
96 BOOST_CHECK(memTpm.hasKey(key->getKeyName()));
97
98 BackEndWrapperFile file;
99 BackEnd& fileTpm = file.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400100 BOOST_CHECK_THROW(fileTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500101
102#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
103 BackEndWrapperOsx osx;
104 BackEnd& osxTpm = osx.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400105 BOOST_CHECK_THROW(osxTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500106#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
107}
108
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700109BOOST_AUTO_TEST_CASE_TEMPLATE(RsaSigning, T, TestBackEnds)
110{
111 T wrapper;
112 BackEnd& tpm = wrapper.getTpm();
113
Davide Pesavento13fffa32018-09-30 16:21:33 -0400114 // create an RSA key
laqinfancf0baa22019-06-03 15:33:58 -0500115 Name identity("/Test/RSA/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700116 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
117 Name keyName = key->getKeyName();
118
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700119 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500120 auto pubKeyBits = key->derivePublicKey();
121 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700122
Davide Pesavento765abc92021-12-27 00:44:04 -0500123 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700124 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500125 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700126 BOOST_REQUIRE(sigValueSingle != nullptr);
127
128 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700129 {
130 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500131 bufferSource(content1)
Davide Pesavento35c63792022-01-17 02:06:03 -0500132 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueSingle)
Davide Pesavento765abc92021-12-27 00:44:04 -0500133 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700134 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700135 BOOST_CHECK_EQUAL(resultSingle, true);
136
Davide Pesavento765abc92021-12-27 00:44:04 -0500137 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700138 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500139 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700140 BOOST_REQUIRE(sigValueVector != nullptr);
141
142 bool resultVector;
143 {
144 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500145 bufferSource(InputBuffers{content1, content2})
Davide Pesavento35c63792022-01-17 02:06:03 -0500146 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueVector)
Davide Pesavento765abc92021-12-27 00:44:04 -0500147 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700148 }
149 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700150
151 tpm.deleteKey(keyName);
152 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
153}
154
155BOOST_AUTO_TEST_CASE_TEMPLATE(RsaDecryption, T, TestBackEnds)
156{
157 T wrapper;
158 BackEnd& tpm = wrapper.getTpm();
159
Davide Pesavento13fffa32018-09-30 16:21:33 -0400160 // create an RSA key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700161 Name identity("/Test/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700162 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
163 Name keyName = key->getKeyName();
164
165 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
166
167 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500168 auto pubKeyBits = key->derivePublicKey();
169 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700170
Davide Pesavento765abc92021-12-27 00:44:04 -0500171 ConstBufferPtr cipherText = pubKey.encrypt(content);
172 ConstBufferPtr plainText = key->decrypt(*cipherText);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700173
174 BOOST_CHECK_EQUAL_COLLECTIONS(content, content + sizeof(content),
175 plainText->begin(), plainText->end());
176
177 tpm.deleteKey(keyName);
178 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
179}
180
181BOOST_AUTO_TEST_CASE_TEMPLATE(EcdsaSigning, T, TestBackEnds)
182{
183 T wrapper;
184 BackEnd& tpm = wrapper.getTpm();
185
Davide Pesavento13fffa32018-09-30 16:21:33 -0400186 // create an EC key
laqinfancf0baa22019-06-03 15:33:58 -0500187 Name identity("/Test/EC/KeyName");
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700188 unique_ptr<KeyHandle> key = tpm.createKey(identity, EcKeyParams());
189 Name ecKeyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700190
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700191 transform::PublicKey pubKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500192 auto pubKeyBits = key->derivePublicKey();
193 pubKey.loadPkcs8(*pubKeyBits);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700194
Davide Pesavento765abc92021-12-27 00:44:04 -0500195 // Sign a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700196 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500197 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700198 BOOST_REQUIRE(sigValueSingle != nullptr);
199
200 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700201 {
202 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500203 bufferSource(content1)
Davide Pesavento35c63792022-01-17 02:06:03 -0500204 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueSingle)
Davide Pesavento765abc92021-12-27 00:44:04 -0500205 >> boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700206 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700207 BOOST_CHECK_EQUAL(resultSingle, true);
208
Davide Pesavento765abc92021-12-27 00:44:04 -0500209 // Sign multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700210 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500211 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700212 BOOST_REQUIRE(sigValueVector != nullptr);
213
214 bool resultVector;
215 {
216 using namespace transform;
Davide Pesavento765abc92021-12-27 00:44:04 -0500217 bufferSource(InputBuffers{content1, content2})
Davide Pesavento35c63792022-01-17 02:06:03 -0500218 >> verifierFilter(DigestAlgorithm::SHA256, pubKey, *sigValueVector)
Davide Pesavento765abc92021-12-27 00:44:04 -0500219 >> boolSink(resultVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700220 }
221 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700222
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700223 tpm.deleteKey(ecKeyName);
224 BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700225}
226
laqinfancf0baa22019-06-03 15:33:58 -0500227BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
228{
229 BackEndWrapperMem wrapper;
230 BackEnd& tpm = wrapper.getTpm();
231
232 // create an HMAC key
233 Name identity("/Test/HMAC/KeyName");
234 unique_ptr<KeyHandle> key = tpm.createKey(identity, HmacKeyParams());
235 Name hmacKeyName = key->getKeyName();
236
Davide Pesavento765abc92021-12-27 00:44:04 -0500237 // Sign and verify a single buffer
Eric Newberry6d024ba2020-06-14 16:10:34 -0700238 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
Davide Pesavento765abc92021-12-27 00:44:04 -0500239 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, {content1});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700240 BOOST_REQUIRE(sigValueSingle != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500241 bool resultSingle = key->verify(DigestAlgorithm::SHA256, {content1}, *sigValueSingle);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700242 BOOST_CHECK_EQUAL(resultSingle, true);
laqinfancf0baa22019-06-03 15:33:58 -0500243
Davide Pesavento765abc92021-12-27 00:44:04 -0500244 // Sign and verify multiple buffers
Eric Newberry6d024ba2020-06-14 16:10:34 -0700245 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
Davide Pesavento765abc92021-12-27 00:44:04 -0500246 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {content1, content2});
Eric Newberry6d024ba2020-06-14 16:10:34 -0700247 BOOST_REQUIRE(sigValueVector != nullptr);
Davide Pesavento765abc92021-12-27 00:44:04 -0500248 bool resultVector = key->verify(DigestAlgorithm::SHA256, {content1, content2}, *sigValueVector);
Eric Newberry6d024ba2020-06-14 16:10:34 -0700249 BOOST_CHECK_EQUAL(resultVector, true);
laqinfancf0baa22019-06-03 15:33:58 -0500250
251 tpm.deleteKey(hmacKeyName);
252 BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
253}
254
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700255BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
256{
Davide Pesavento13fffa32018-09-30 16:21:33 -0400257 const std::string privKeyPkcs1 =
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700258 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
259 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
260 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
261 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
262 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
263 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
264 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
265 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
266 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
267 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
268 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
269 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
270 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
271 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
272 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
273 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
274 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
275 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
276 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
277 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
278 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
279 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
280 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
281 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
282 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Davide Pesavento13fffa32018-09-30 16:21:33 -0400283 const std::string password("password");
284 const std::string wrongPassword("wrong");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700285
286 T wrapper;
287 BackEnd& tpm = wrapper.getTpm();
288
289 Name keyName("/Test/KeyName/KEY/1");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700290 tpm.deleteKey(keyName);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400291 BOOST_REQUIRE_EQUAL(tpm.hasKey(keyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700292
293 transform::PrivateKey sKey;
Davide Pesavento765abc92021-12-27 00:44:04 -0500294 sKey.loadPkcs1Base64({reinterpret_cast<const uint8_t*>(privKeyPkcs1.data()), privKeyPkcs1.size()});
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700295 OBufferStream os;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400296 sKey.savePkcs8(os, password.data(), password.size());
297 auto pkcs8 = os.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700298
Davide Pesavento13fffa32018-09-30 16:21:33 -0400299 // import with wrong password
Davide Pesavento765abc92021-12-27 00:44:04 -0500300 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, wrongPassword.data(), wrongPassword.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400301 Tpm::Error);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400302 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
303
304 // import with correct password
Davide Pesavento765abc92021-12-27 00:44:04 -0500305 tpm.importKey(keyName, *pkcs8, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700306 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400307
308 // import already present key
Davide Pesavento765abc92021-12-27 00:44:04 -0500309 BOOST_CHECK_THROW(tpm.importKey(keyName, *pkcs8, password.data(), password.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400310 Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700311
Davide Pesavento13fffa32018-09-30 16:21:33 -0400312 // test derivePublicKey with the imported key
313 auto keyHdl = tpm.getKeyHandle(keyName);
314 auto pubKey = keyHdl->derivePublicKey();
315 BOOST_CHECK(pubKey != nullptr);
316
317 // export
318 auto exportedKey = tpm.exportKey(keyName, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700319 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
320
321 transform::PrivateKey sKey2;
Davide Pesavento765abc92021-12-27 00:44:04 -0500322 sKey2.loadPkcs8(*exportedKey, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700323 OBufferStream os2;
324 sKey.savePkcs1Base64(os2);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400325 auto pkcs1 = os2.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700326
Davide Pesavento13fffa32018-09-30 16:21:33 -0400327 // verify that the exported key is identical to the key that was imported
328 BOOST_CHECK_EQUAL_COLLECTIONS(privKeyPkcs1.begin(), privKeyPkcs1.end(),
329 pkcs1->begin(), pkcs1->end());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700330
Davide Pesavento13fffa32018-09-30 16:21:33 -0400331 // export nonexistent key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700332 tpm.deleteKey(keyName);
333 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
Davide Pesavento12cef872019-10-31 02:24:03 -0400334 BOOST_CHECK_THROW(tpm.exportKey(keyName, password.data(), password.size()), Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700335}
336
337BOOST_AUTO_TEST_CASE(RandomKeyId)
338{
339 BackEndWrapperMem wrapper;
340 BackEnd& tpm = wrapper.getTpm();
341 Name identity("/Test/KeyName");
342
343 std::set<Name> keyNames;
344 for (int i = 0; i < 100; i++) {
345 auto key = tpm.createKey(identity, RsaKeyParams());
346 Name keyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700347 BOOST_CHECK(keyNames.insert(keyName).second);
348 }
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