blob: 8abc745fbefdb6e26153e5a2b3c234eef8e225cd [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/*
Eric Newberry6d024ba2020-06-14 16:10:34 -07003 * Copyright (c) 2013-2020 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 Pesaventocafa4022017-09-15 23:20:20 -040040#include <boost/mpl/vector.hpp>
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070041#include <set>
42
43namespace ndn {
44namespace security {
45namespace tpm {
46namespace tests {
47
48BOOST_AUTO_TEST_SUITE(Security)
49BOOST_AUTO_TEST_SUITE(Tpm)
50BOOST_AUTO_TEST_SUITE(TestBackEnd)
51
52using tpm::Tpm;
53
Davide Pesaventocafa4022017-09-15 23:20:20 -040054using TestBackEnds = boost::mpl::vector<
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050055#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070056 BackEndWrapperOsx,
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050057#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070058 BackEndWrapperMem,
Davide Pesaventocafa4022017-09-15 23:20:20 -040059 BackEndWrapperFile>;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -070060
61BOOST_AUTO_TEST_CASE_TEMPLATE(KeyManagement, T, TestBackEnds)
62{
63 T wrapper;
64 BackEnd& tpm = wrapper.getTpm();
65
66 Name identity("/Test/KeyName");
67 name::Component keyId("1");
68 Name keyName = v2::constructKeyName(identity, keyId);
69
70 // key should not exist
71 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
72 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
73
74 // create key, should exist
75 BOOST_CHECK(tpm.createKey(identity, RsaKeyParams(keyId)) != nullptr);
76 BOOST_CHECK(tpm.hasKey(keyName));
77 BOOST_CHECK(tpm.getKeyHandle(keyName) != nullptr);
78
79 // create a key with the same name, should throw error
80 BOOST_CHECK_THROW(tpm.createKey(identity, RsaKeyParams(keyId)), Tpm::Error);
81
82 // delete key, should not exist
83 tpm.deleteKey(keyName);
84 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
85 BOOST_CHECK(tpm.getKeyHandle(keyName) == nullptr);
86}
87
laqinfan56a812d2019-06-03 15:33:58 -050088BOOST_AUTO_TEST_CASE(CreateHmacKey)
89{
90 Name identity("/Test/Identity/HMAC");
91
92 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()));
98
99 BackEndWrapperFile file;
100 BackEnd& fileTpm = file.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400101 BOOST_CHECK_THROW(fileTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500102
103#ifdef NDN_CXX_HAVE_OSX_FRAMEWORKS
104 BackEndWrapperOsx osx;
105 BackEnd& osxTpm = osx.getTpm();
Davide Pesavento12cef872019-10-31 02:24:03 -0400106 BOOST_CHECK_THROW(osxTpm.createKey(identity, HmacKeyParams()), std::invalid_argument);
laqinfan56a812d2019-06-03 15:33:58 -0500107#endif // NDN_CXX_HAVE_OSX_FRAMEWORKS
108}
109
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700110BOOST_AUTO_TEST_CASE_TEMPLATE(RsaSigning, T, TestBackEnds)
111{
112 T wrapper;
113 BackEnd& tpm = wrapper.getTpm();
114
Davide Pesavento13fffa32018-09-30 16:21:33 -0400115 // create an RSA key
laqinfancf0baa22019-06-03 15:33:58 -0500116 Name identity("/Test/RSA/KeyName");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700117 unique_ptr<KeyHandle> key = tpm.createKey(identity, RsaKeyParams());
118 Name keyName = key->getKeyName();
119
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700120 transform::PublicKey pubKey;
121 ConstBufferPtr pubKeyBits = key->derivePublicKey();
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400122 pubKey.loadPkcs8(pubKeyBits->data(), pubKeyBits->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700123
Eric Newberry6d024ba2020-06-14 16:10:34 -0700124 // Sign using single buffer API
125 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
126 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, content1, sizeof(content1));
127 BOOST_REQUIRE(sigValueSingle != nullptr);
128
129 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700130 {
131 using namespace transform;
Eric Newberry6d024ba2020-06-14 16:10:34 -0700132 bufferSource(content1, sizeof(content1)) >>
133 verifierFilter(DigestAlgorithm::SHA256, pubKey,
134 sigValueSingle->data(), sigValueSingle->size()) >>
135 boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700136 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700137 BOOST_CHECK_EQUAL(resultSingle, true);
138
139 // Sign using vectored API
140 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
141 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {{content1, sizeof(content1)},
142 {content2, sizeof(content2)}});
143 BOOST_REQUIRE(sigValueVector != nullptr);
144
145 bool resultVector;
146 {
147 using namespace transform;
148 bufferSource({{content1, sizeof(content1)}, {content2, sizeof(content2)}}) >>
149 verifierFilter(DigestAlgorithm::SHA256, pubKey,
150 sigValueVector->data(), sigValueVector->size()) >>
151 boolSink(resultVector);
152 }
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;
172 ConstBufferPtr pubKeyBits = key->derivePublicKey();
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400173 pubKey.loadPkcs8(pubKeyBits->data(), pubKeyBits->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700174
175 ConstBufferPtr cipherText = pubKey.encrypt(content, sizeof(content));
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400176 ConstBufferPtr plainText = key->decrypt(cipherText->data(), cipherText->size());
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;
196 ConstBufferPtr pubKeyBits = key->derivePublicKey();
Davide Pesavento5d0b0102017-10-07 13:43:16 -0400197 pubKey.loadPkcs8(pubKeyBits->data(), pubKeyBits->size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700198
Eric Newberry6d024ba2020-06-14 16:10:34 -0700199 // Sign using single buffer API
200 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
201 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, content1, sizeof(content1));
202 BOOST_REQUIRE(sigValueSingle != nullptr);
203
204 bool resultSingle;
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700205 {
206 using namespace transform;
Eric Newberry6d024ba2020-06-14 16:10:34 -0700207 bufferSource(content1, sizeof(content1)) >>
208 verifierFilter(DigestAlgorithm::SHA256, pubKey,
209 sigValueSingle->data(), sigValueSingle->size()) >>
210 boolSink(resultSingle);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700211 }
Eric Newberry6d024ba2020-06-14 16:10:34 -0700212 BOOST_CHECK_EQUAL(resultSingle, true);
213
214 // Sign using vectored API
215 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
216 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {{content1, sizeof(content1)},
217 {content2, sizeof(content2)}});
218 BOOST_REQUIRE(sigValueVector != nullptr);
219
220 bool resultVector;
221 {
222 using namespace transform;
223 bufferSource({{content1, sizeof(content1)}, {content2, sizeof(content2)}}) >>
224 verifierFilter(DigestAlgorithm::SHA256, pubKey,
225 sigValueVector->data(), sigValueVector->size()) >>
226 boolSink(resultVector);
227 }
228 BOOST_CHECK_EQUAL(resultVector, true);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700229
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700230 tpm.deleteKey(ecKeyName);
231 BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700232}
233
laqinfancf0baa22019-06-03 15:33:58 -0500234BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
235{
236 BackEndWrapperMem wrapper;
237 BackEnd& tpm = wrapper.getTpm();
238
239 // create an HMAC key
240 Name identity("/Test/HMAC/KeyName");
241 unique_ptr<KeyHandle> key = tpm.createKey(identity, HmacKeyParams());
242 Name hmacKeyName = key->getKeyName();
243
Eric Newberry6d024ba2020-06-14 16:10:34 -0700244 // Sign and verify using single buffer API
245 const uint8_t content1[] = {0x01, 0x02, 0x03, 0x04};
246 auto sigValueSingle = key->sign(DigestAlgorithm::SHA256, content1, sizeof(content1));
247 BOOST_REQUIRE(sigValueSingle != nullptr);
248 bool resultSingle = key->verify(DigestAlgorithm::SHA256, content1, sizeof(content1),
249 sigValueSingle->data(), sigValueSingle->size());
250 BOOST_CHECK_EQUAL(resultSingle, true);
laqinfancf0baa22019-06-03 15:33:58 -0500251
Eric Newberry6d024ba2020-06-14 16:10:34 -0700252 // Sign and verify using vectored API
253 const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
254 auto sigValueVector = key->sign(DigestAlgorithm::SHA256, {{content1, sizeof(content1)},
255 {content2, sizeof(content2)}});
256 BOOST_REQUIRE(sigValueVector != nullptr);
257 bool resultVector = key->verify(DigestAlgorithm::SHA256,
258 {{content1, sizeof(content1)},
259 {content2, sizeof(content2)}},
260 sigValueVector->data(), sigValueVector->size());
261 BOOST_CHECK_EQUAL(resultVector, true);
laqinfancf0baa22019-06-03 15:33:58 -0500262
263 tpm.deleteKey(hmacKeyName);
264 BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
265}
266
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700267BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
268{
Davide Pesavento13fffa32018-09-30 16:21:33 -0400269 const std::string privKeyPkcs1 =
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700270 "MIIEpAIBAAKCAQEAw0WM1/WhAxyLtEqsiAJgWDZWuzkYpeYVdeeZcqRZzzfRgBQT\n"
271 "sNozS5t4HnwTZhwwXbH7k3QN0kRTV826Xobws3iigohnM9yTK+KKiayPhIAm/+5H\n"
272 "GT6SgFJhYhqo1/upWdueojil6RP4/AgavHhopxlAVbk6G9VdVnlQcQ5Zv0OcGi73\n"
273 "c+EnYD/YgURYGSngUi/Ynsh779p2U69/te9gZwIL5PuE9BiO6I39cL9z7EK1SfZh\n"
274 "OWvDe/qH7YhD/BHwcWit8FjRww1glwRVTJsA9rH58ynaAix0tcR/nBMRLUX+e3rU\n"
275 "RHg6UbSjJbdb9qmKM1fTGHKUzL/5pMG6uBU0ywIDAQABAoIBADQkckOIl4IZMUTn\n"
276 "W8LFv6xOdkJwMKC8G6bsPRFbyY+HvC2TLt7epSvfS+f4AcYWaOPcDu2E49vt2sNr\n"
277 "cASly8hgwiRRAB3dHH9vcsboiTo8bi2RFvMqvjv9w3tK2yMxVDtmZamzrrnaV3YV\n"
278 "Q+5nyKo2F/PMDjQ4eUAKDOzjhBuKHsZBTFnA1MFNI+UKj5X4Yp64DFmKlxTX/U2b\n"
279 "wzVywo5hzx2Uhw51jmoLls4YUvMJXD0wW5ZtYRuPogXvXb/of9ef/20/wU11WFKg\n"
280 "Xb4gfR8zUXaXS1sXcnVm3+24vIs9dApUwykuoyjOqxWqcHRec2QT2FxVGkFEraze\n"
281 "CPa4rMECgYEA5Y8CywomIcTgerFGFCeMHJr8nQGqY2V/owFb3k9maczPnC9p4a9R\n"
282 "c5szLxA9FMYFxurQZMBWSEG2JS1HR2mnjigx8UKjYML/A+rvvjZOMe4M6Sy2ggh4\n"
283 "SkLZKpWTzjTe07ByM/j5v/SjNZhWAG7sw4/LmPGRQkwJv+KZhGojuOkCgYEA2cOF\n"
284 "T6cJRv6kvzTz9S0COZOVm+euJh/BXp7oAsAmbNfOpckPMzqHXy8/wpdKl6AAcB57\n"
285 "OuztlNfV1D7qvbz7JuRlYwQ0cEfBgbZPcz1p18HHDXhwn57ZPb8G33Yh9Omg0HNA\n"
286 "Imb4LsVuSqxA6NwSj7cpRekgTedrhLFPJ+Ydb5MCgYEAsM3Q7OjILcIg0t6uht9e\n"
287 "vrlwTsz1mtCV2co2I6crzdj9HeI2vqf1KAElDt6G7PUHhglcr/yjd8uEqmWRPKNX\n"
288 "ddnnfVZB10jYeP/93pac6z/Zmc3iU4yKeUe7U10ZFf0KkiiYDQd59CpLef/2XScS\n"
289 "HB0oRofnxRQjfjLc4muNT+ECgYEAlcDk06MOOTly+F8lCc1bA1dgAmgwFd2usDBd\n"
290 "Y07a3e0HGnGLN3Kfl7C5i0tZq64HvxLnMd2vgLVxQlXGPpdQrC1TH+XLXg+qnlZO\n"
291 "ivSH7i0/gx75bHvj75eH1XK65V8pDVDEoSPottllAIs21CxLw3N1ObOZWJm2EfmR\n"
292 "cuHICmsCgYAtFJ1idqMoHxES3mlRpf2JxyQudP3SCm2WpGmqVzhRYInqeatY5sUd\n"
293 "lPLHm/p77RT7EyxQHTlwn8FJPuM/4ZH1rQd/vB+Y8qAtYJCexDMsbvLW+Js+VOvk\n"
294 "jweEC0nrcL31j9mF0vz5E6tfRu4hhJ6L4yfWs0gSejskeVB/w8QY4g==\n";
Davide Pesavento13fffa32018-09-30 16:21:33 -0400295 const std::string password("password");
296 const std::string wrongPassword("wrong");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700297
298 T wrapper;
299 BackEnd& tpm = wrapper.getTpm();
300
301 Name keyName("/Test/KeyName/KEY/1");
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700302 tpm.deleteKey(keyName);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400303 BOOST_REQUIRE_EQUAL(tpm.hasKey(keyName), false);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700304
305 transform::PrivateKey sKey;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400306 sKey.loadPkcs1Base64(reinterpret_cast<const uint8_t*>(privKeyPkcs1.data()), privKeyPkcs1.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700307 OBufferStream os;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400308 sKey.savePkcs8(os, password.data(), password.size());
309 auto pkcs8 = os.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700310
Davide Pesavento13fffa32018-09-30 16:21:33 -0400311 // import with wrong password
312 BOOST_CHECK_THROW(tpm.importKey(keyName, pkcs8->data(), pkcs8->size(), wrongPassword.data(), wrongPassword.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400313 Tpm::Error);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400314 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
315
316 // import with correct password
317 tpm.importKey(keyName, pkcs8->data(), pkcs8->size(), password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700318 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400319
320 // import already present key
321 BOOST_CHECK_THROW(tpm.importKey(keyName, pkcs8->data(), pkcs8->size(), password.data(), password.size()),
Davide Pesavento12cef872019-10-31 02:24:03 -0400322 Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700323
Davide Pesavento13fffa32018-09-30 16:21:33 -0400324 // test derivePublicKey with the imported key
325 auto keyHdl = tpm.getKeyHandle(keyName);
326 auto pubKey = keyHdl->derivePublicKey();
327 BOOST_CHECK(pubKey != nullptr);
328
329 // export
330 auto exportedKey = tpm.exportKey(keyName, password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700331 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), true);
332
333 transform::PrivateKey sKey2;
Davide Pesavento13fffa32018-09-30 16:21:33 -0400334 sKey2.loadPkcs8(exportedKey->data(), exportedKey->size(), password.data(), password.size());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700335 OBufferStream os2;
336 sKey.savePkcs1Base64(os2);
Davide Pesavento13fffa32018-09-30 16:21:33 -0400337 auto pkcs1 = os2.buf();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700338
Davide Pesavento13fffa32018-09-30 16:21:33 -0400339 // verify that the exported key is identical to the key that was imported
340 BOOST_CHECK_EQUAL_COLLECTIONS(privKeyPkcs1.begin(), privKeyPkcs1.end(),
341 pkcs1->begin(), pkcs1->end());
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700342
Davide Pesavento13fffa32018-09-30 16:21:33 -0400343 // export nonexistent key
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700344 tpm.deleteKey(keyName);
345 BOOST_CHECK_EQUAL(tpm.hasKey(keyName), false);
Davide Pesavento12cef872019-10-31 02:24:03 -0400346 BOOST_CHECK_THROW(tpm.exportKey(keyName, password.data(), password.size()), Tpm::Error);
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700347}
348
349BOOST_AUTO_TEST_CASE(RandomKeyId)
350{
351 BackEndWrapperMem wrapper;
352 BackEnd& tpm = wrapper.getTpm();
353 Name identity("/Test/KeyName");
354
355 std::set<Name> keyNames;
356 for (int i = 0; i < 100; i++) {
357 auto key = tpm.createKey(identity, RsaKeyParams());
358 Name keyName = key->getKeyName();
Yingdi Yu0b60e7a2015-07-16 21:05:11 -0700359 BOOST_CHECK(keyNames.insert(keyName).second);
360 }
361}
362
363BOOST_AUTO_TEST_SUITE_END() // TestBackEnd
364BOOST_AUTO_TEST_SUITE_END() // Tpm
365BOOST_AUTO_TEST_SUITE_END() // Security
366
367} // namespace tests
368} // namespace tpm
369} // namespace security
370} // namespace ndn