blob: 3b08c622a908cb022d4a020316a5634cd6ee2821 [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;
124 ConstBufferPtr pubKeyBits = key->derivePublicKey();
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400125 pubKey.loadPkcs8(pubKeyBits->data(), pubKeyBits->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700126
Eric Newberry6d024ba2020-06-14 16:10:34 -0700127 // Sign using single buffer API
128 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
129 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, content1, sizeof(content1));
130 BOOST_REQUIRE(sigValueSingle != nullptr);
131
132 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700133 {
134 using namespace transform;
Eric Newberry6d024ba2020-06-14 16:10:34 -0700135 bufferSource(content1, sizeof(content1)) >>
136 verifierFilter(DigestAlgorithm::SHA256, pubKey,
137 sigValueSingle->data(), sigValueSingle->size()) >>
138 boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700139 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700140 BOOST_CHECK_EQUAL(resultSingle, true);
141
142 // Sign using vectored API
143 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
144 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {{content1, sizeof(content1)},
145 {content2, sizeof(content2)}});
146 BOOST_REQUIRE(sigValueVector != nullptr);
147
148 bool resultVector;
149 {
150 using namespace transform;
151 bufferSource({{content1, sizeof(content1)}, {content2, sizeof(content2)}}) >>
152 verifierFilter(DigestAlgorithm::SHA256, pubKey,
153 sigValueVector->data(), sigValueVector->size()) >>
154 boolSink(resultVector);
155 }
156 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700157
158 tpm.deleteKey(keyName);
159 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
160}
161
162BOOST_AUTO_TEST_CASE_TEMPLATE(RsaDecryption, T, TestBackEnds)
163{
164 T wrapper;
165 BackEnd& tpm = wrapper.getTpm();
166
Davide Pesavento13fffa32018-09-30 16:21:33 -0400167 // create an RSA key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700168 Name identity("/Test/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700169 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
170 Name keyName = key->getKeyName();
171
172 const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
173
174 transform::PublicKey pubKey;
175 ConstBufferPtr pubKeyBits = key->derivePublicKey();
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400176 pubKey.loadPkcs8(pubKeyBits->data(), pubKeyBits->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700177
178 ConstBufferPtr cipherText = pubKey.encrypt(content, sizeof(content));
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400179 ConstBufferPtr plainText = key->decrypt(cipherText->data(), cipherText->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700180
181 BOOST_CHECK_EQUAL_COLLECTIONS(content, content + sizeof(content),
182 plainText->begin(), plainText->end());
183
184 tpm.deleteKey(keyName);
185 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
186}
187
188BOOST_AUTO_TEST_CASE_TEMPLATE(EcdsaSigning, T, TestBackEnds)
189{
190 T wrapper;
191 BackEnd& tpm = wrapper.getTpm();
192
Davide Pesavento13fffa32018-09-30 16:21:33 -0400193 // create an EC key
laqinfancf0baa22019-06-03 15:33:58 -0500194 Name identity("/Test/EC/KeyName");
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700195 unique_ptr<KeyHandle> key = tpm.createKey(identity, EcKeyParams());
196 Name ecKeyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700197
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700198 transform::PublicKey pubKey;
199 ConstBufferPtr pubKeyBits = key->derivePublicKey();
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400200 pubKey.loadPkcs8(pubKeyBits->data(), pubKeyBits->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700201
Eric Newberry6d024ba2020-06-14 16:10:34 -0700202 // Sign using single buffer API
203 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
204 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, content1, sizeof(content1));
205 BOOST_REQUIRE(sigValueSingle != nullptr);
206
207 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700208 {
209 using namespace transform;
Eric Newberry6d024ba2020-06-14 16:10:34 -0700210 bufferSource(content1, sizeof(content1)) >>
211 verifierFilter(DigestAlgorithm::SHA256, pubKey,
212 sigValueSingle->data(), sigValueSingle->size()) >>
213 boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700214 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700215 BOOST_CHECK_EQUAL(resultSingle, true);
216
217 // Sign using vectored API
218 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
219 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {{content1, sizeof(content1)},
220 {content2, sizeof(content2)}});
221 BOOST_REQUIRE(sigValueVector != nullptr);
222
223 bool resultVector;
224 {
225 using namespace transform;
226 bufferSource({{content1, sizeof(content1)}, {content2, sizeof(content2)}}) >>
227 verifierFilter(DigestAlgorithm::SHA256, pubKey,
228 sigValueVector->data(), sigValueVector->size()) >>
229 boolSink(resultVector);
230 }
231 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700232
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700233 tpm.deleteKey(ecKeyName);
234 BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700235}
236
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400237#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
laqinfancf0baa22019-06-03 15:33:58 -0500238BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
239{
240 BackEndWrapperMem wrapper;
241 BackEnd& tpm = wrapper.getTpm();
242
243 // create an HMAC key
244 Name identity("/Test/HMAC/KeyName");
245 unique_ptr<KeyHandle> key = tpm.createKey(identity, HmacKeyParams());
246 Name hmacKeyName = key->getKeyName();
247
Eric Newberry6d024ba2020-06-14 16:10:34 -0700248 // Sign and verify using single buffer API
249 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
250 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, content1, sizeof(content1));
251 BOOST_REQUIRE(sigValueSingle != nullptr);
252 bool resultSingle = key->verify(DigestAlgorithm::SHA256, content1, sizeof(content1),
253 sigValueSingle->data(), sigValueSingle->size());
254 BOOST_CHECK_EQUAL(resultSingle, true);
laqinfancf0baa22019-06-03 15:33:58 -0500255
Eric Newberry6d024ba2020-06-14 16:10:34 -0700256 // Sign and verify using vectored API
257 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
258 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {{content1, sizeof(content1)},
259 {content2, sizeof(content2)}});
260 BOOST_REQUIRE(sigValueVector != nullptr);
261 bool resultVector = key->verify(DigestAlgorithm::SHA256,
262 {{content1, sizeof(content1)},
263 {content2, sizeof(content2)}},
264 sigValueVector->data(), sigValueVector->size());
265 BOOST_CHECK_EQUAL(resultVector, true);
laqinfancf0baa22019-06-03 15:33:58 -0500266
267 tpm.deleteKey(hmacKeyName);
268 BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
269}
Davide Pesavento94dfcf12021-09-26 14:18:45 -0400270#endif
laqinfancf0baa22019-06-03 15:33:58 -0500271
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700272BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
273{
Davide Pesavento13fffa32018-09-30 16:21:33 -0400274 const std::string privKeyPkcs1 =
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700275 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
276 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
277 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
278 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
279 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
280 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
281 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
282 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
283 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
284 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
285 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
286 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
287 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
288 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
289 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
290 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
291 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
292 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
293 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
294 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
295 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
296 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
297 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
298 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
299 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Davide Pesavento13fffa32018-09-30 16:21:33 -0400300 const std::string password("password");
301 const std::string wrongPassword("wrong");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700302
303 T wrapper;
304 BackEnd& tpm = wrapper.getTpm();
305
306 Name keyName("/Test/KeyName/KEY/1");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700307 tpm.deleteKey(keyName);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400308 BOOST_REQUIRE_EQUAL(tpm.hasKey(keyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700309
310 transform::PrivateKey sKey;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400311 sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(privKeyPkcs1.data()), privKeyPkcs1.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700312 OBufferStream os;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400313 sKey.savePkcs8(os, password.data(), password.size());
314 auto pkcs8 = os.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700315
Davide Pesavento13fffa32018-09-30 16:21:33 -0400316 // import with wrong password
317 BOOST_CHECK_THROW(tpm.importKey(keyName, pkcs8->data(), pkcs8->size(), wrongPassword.data(), wrongPassword.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400318 Tpm::Error);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400319 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
320
321 // import with correct password
322 tpm.importKey(keyName, pkcs8->data(), pkcs8->size(), password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700323 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400324
325 // import already present key
326 BOOST_CHECK_THROW(tpm.importKey(keyName, pkcs8->data(), pkcs8->size(), password.data(), password.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400327 Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700328
Davide Pesavento13fffa32018-09-30 16:21:33 -0400329 // test derivePublicKey with the imported key
330 auto keyHdl = tpm.getKeyHandle(keyName);
331 auto pubKey = keyHdl->derivePublicKey();
332 BOOST_CHECK(pubKey != nullptr);
333
334 // export
335 auto exportedKey = tpm.exportKey(keyName, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700336 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
337
338 transform::PrivateKey sKey2;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400339 sKey2.loadPkcs8(exportedKey->data(), exportedKey->size(), password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700340 OBufferStream os2;
341 sKey.savePkcs1Base64(os2);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400342 auto pkcs1 = os2.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700343
Davide Pesavento13fffa32018-09-30 16:21:33 -0400344 // verify that the exported key is identical to the key that was imported
345 BOOST_CHECK_EQUAL_COLLECTIONS(privKeyPkcs1.begin(), privKeyPkcs1.end(),
346 pkcs1->begin(), pkcs1->end());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700347
Davide Pesavento13fffa32018-09-30 16:21:33 -0400348 // export nonexistent key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700349 tpm.deleteKey(keyName);
350 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
Davide Pesavento12cef872019-10-31 02:24:03 -0400351 BOOST_CHECK_THROW(tpm.exportKey(keyName, password.data(), password.size()), Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700352}
353
354BOOST_AUTO_TEST_CASE(RandomKeyId)
355{
356 BackEndWrapperMem wrapper;
357 BackEnd& tpm = wrapper.getTpm();
358 Name identity("/Test/KeyName");
359
360 std::set<Name> keyNames;
361 for (int i = 0; i < 100; i++) {
362 auto key = tpm.createKey(identity, RsaKeyParams());
363 Name keyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700364 BOOST_CHECK(keyNames.insert(keyName).second);
365 }
366}
367
368BOOST_AUTO_TEST_SUITE_END() // TestBackEnd
369BOOST_AUTO_TEST_SUITE_END() // Tpm
370BOOST_AUTO_TEST_SUITE_END() // Security
371
372} // namespace tests
373} // namespace tpm
374} // namespace security
375} // namespace ndn