blob: 7f6abb0ab464d98114cbe2264634906a3b95aef4 [file] [log] [blame]
Yingdi Yufe4733a2015-10-22 14:24:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento82d6a4c2017-12-23 19:47:20 -05002/*
Eric Newberrya3c8bd12020-05-15 17:27:07 -07003 * Copyright (c) 2013-2020 Regents of the University of California.
Yingdi Yufe4733a2015-10-22 14:24:12 -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/v2/key-chain.hpp"
23#include "ndn-cxx/security/signing-helpers.hpp"
24#include "ndn-cxx/security/verification-helpers.hpp"
laqinfan56a812d2019-06-03 15:33:58 -050025#include "ndn-cxx/security/transform/private-key.hpp"
Yingdi Yufe4733a2015-10-22 14:24:12 -070026
Davide Pesavento7e780642018-11-24 15:51:34 -050027#include "tests/boost-test.hpp"
28#include "tests/identity-management-fixture.hpp"
29#include "tests/unit/test-home-env-saver.hpp"
Yingdi Yufe4733a2015-10-22 14:24:12 -070030
31namespace ndn {
32namespace security {
33namespace v2 {
34namespace tests {
35
36using namespace ndn::tests;
37
38BOOST_AUTO_TEST_SUITE(Security)
39BOOST_AUTO_TEST_SUITE(V2)
40BOOST_FIXTURE_TEST_SUITE(TestKeyChain, TestHomeEnvSaver)
41
42template<class Path>
43class TestHomeAndPibFixture : public TestHomeFixture<Path>
44{
45public:
46 TestHomeAndPibFixture()
47 {
48 unsetenv("NDN_CLIENT_PIB");
49 unsetenv("NDN_CLIENT_TPM");
50 }
Alexander Afanasyev80782e02017-01-04 13:16:54 -080051
52 ~TestHomeAndPibFixture()
53 {
Alexander Afanasyev57d02b62018-06-15 18:19:50 -040054 try {
55 const_cast<std::string&>(KeyChain::getDefaultPibLocator()).clear();
56 }
57 catch (const KeyChain::Error&) {
58 // ignore
59 }
60
61 try {
62 const_cast<std::string&>(KeyChain::getDefaultTpmLocator()).clear();
63 }
64 catch (const KeyChain::Error&) {
65 // ignore
66 }
Alexander Afanasyev80782e02017-01-04 13:16:54 -080067 }
Yingdi Yufe4733a2015-10-22 14:24:12 -070068};
69
70struct PibPathConfigFileHome
71{
72 const std::string PATH = "build/config-file-home/";
73};
74
75BOOST_FIXTURE_TEST_CASE(ConstructorNormalConfig, TestHomeAndPibFixture<PibPathConfigFileHome>)
76{
77 createClientConf({"pib=pib-memory:", "tpm=tpm-memory:"});
78
79 BOOST_REQUIRE_NO_THROW(KeyChain());
80
81 KeyChain keyChain;
82 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-memory:");
83 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-memory:");
84 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
85}
86
87struct PibPathConfigFileEmptyHome
88{
89 const std::string PATH = "build/config-file-empty-home/";
90};
91
92BOOST_FIXTURE_TEST_CASE(ConstructorEmptyConfig, TestHomeAndPibFixture<PibPathConfigFileEmptyHome>)
93{
94 createClientConf({"pib=pib-memory:"});
95
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050096#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
Yingdi Yufe4733a2015-10-22 14:24:12 -070097 std::string oldHOME;
98 if (std::getenv("OLD_HOME"))
99 oldHOME = std::getenv("OLD_HOME");
100
101 std::string HOME;
102 if (std::getenv("HOME"))
103 HOME = std::getenv("HOME");
104
105 if (!oldHOME.empty())
106 setenv("HOME", oldHOME.c_str(), 1);
107 else
108 unsetenv("HOME");
109#endif
110
111 BOOST_REQUIRE_NO_THROW(KeyChain());
112 KeyChain keyChain;
113 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-memory:");
114
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -0500115#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700116 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-osxkeychain:");
117 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-osxkeychain:");
118#else
119 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-file:");
120 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:");
121#endif
122
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -0500123#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700124 if (!HOME.empty())
125 setenv("HOME", HOME.c_str(), 1);
126 else
127 unsetenv("HOME");
128
129 if (!oldHOME.empty())
130 setenv("OLD_HOME", oldHOME.c_str(), 1);
131 else
132 unsetenv("OLD_HOME");
133#endif
134}
135
136struct PibPathConfigFileEmpty2Home
137{
138 const std::string PATH = "build/config-file-empty2-home/";
139};
140
141BOOST_FIXTURE_TEST_CASE(ConstructorEmpty2Config, TestHomeAndPibFixture<PibPathConfigFileEmpty2Home>)
142{
143 createClientConf({"tpm=tpm-memory:"});
144
145 BOOST_REQUIRE_NO_THROW(KeyChain());
146
147 KeyChain keyChain;
148 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:");
149 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-memory:");
150 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
151}
152
153struct PibPathConfigFileMalformedHome
154{
155 const std::string PATH = "build/config-file-malformed-home/";
156};
157
158BOOST_FIXTURE_TEST_CASE(ConstructorMalConfig, TestHomeAndPibFixture<PibPathConfigFileMalformedHome>)
159{
160 createClientConf({"pib=lord", "tpm=ring"});
161
162 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
163}
164
165struct PibPathConfigFileMalformed2Home
166{
167 const std::string PATH = "build/config-file-malformed2-home/";
168};
169
170BOOST_FIXTURE_TEST_CASE(ConstructorMal2Config, TestHomeAndPibFixture<PibPathConfigFileMalformed2Home>)
171{
172 createClientConf({"pib=pib-sqlite3:%PATH%", "tpm=just-wrong"});
173
174 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
175}
176
Alexander Afanasyev57d02b62018-06-15 18:19:50 -0400177struct PibPathConfigFileNonCanonicalTpm
178{
179 const std::string PATH = "build/config-file-non-canonical-tpm/";
180};
181
182BOOST_FIXTURE_TEST_CASE(ConstructorNonCanonicalTpm, TestHomeAndPibFixture<PibPathConfigFileNonCanonicalTpm>) // Bug 4297
183{
184 createClientConf({"pib=pib-sqlite3:", "tpm=tpm-file"});
185
186 {
187 KeyChain keyChain;
188 keyChain.createIdentity("/test");
189 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:");
190 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:");
191 }
192
193 {
194 KeyChain keyChain;
195 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:");
196 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:");
197 BOOST_CHECK(keyChain.getPib().getIdentities().find("/test") != keyChain.getPib().getIdentities().end());
198 }
199}
200
Yingdi Yufe4733a2015-10-22 14:24:12 -0700201BOOST_AUTO_TEST_CASE(KeyChainWithCustomTpmAndPib)
202{
203 BOOST_REQUIRE_NO_THROW((KeyChain("pib-memory", "tpm-memory")));
204 BOOST_REQUIRE_NO_THROW((KeyChain("pib-memory:", "tpm-memory:")));
205 BOOST_REQUIRE_NO_THROW((KeyChain("pib-memory:/something", "tpm-memory:/something")));
206
207 KeyChain keyChain("pib-memory", "tpm-memory");
208 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-memory:");
209 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-memory:");
210 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
211}
212
Alexander Afanasyevf601e192020-06-02 16:41:07 -0400213BOOST_FIXTURE_TEST_CASE(SigningWithCorruptedPibTpm, IdentityManagementFixture)
214{
215 Identity id = m_keyChain.createIdentity("/test");
216
217 Data data("/foobar");
218 BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id)));
219
220 // now, "corrupting TPM"
221 const_cast<Tpm&>(m_keyChain.getTpm()).deleteKey(id.getDefaultKey().getName());
222
223 BOOST_CHECK_NO_THROW(id.getDefaultKey());
224 BOOST_CHECK_THROW(m_keyChain.sign(data, signingByIdentity(id)), KeyChain::InvalidSigningInfoError);
225}
226
Yingdi Yufe4733a2015-10-22 14:24:12 -0700227BOOST_FIXTURE_TEST_CASE(Management, IdentityManagementFixture)
228{
229 Name identityName("/test/id");
230 Name identity2Name("/test/id2");
231
232 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 0);
233 BOOST_REQUIRE_THROW(m_keyChain.getPib().getDefaultIdentity(), Pib::Error);
234
235 // Create identity
236 Identity id = m_keyChain.createIdentity(identityName);
237 BOOST_CHECK(id);
238 BOOST_CHECK(m_keyChain.getPib().getIdentities().find(identityName) != m_keyChain.getPib().getIdentities().end());
239 // The first added identity becomes the default identity
laqinfan56a812d2019-06-03 15:33:58 -0500240 BOOST_CHECK_NO_THROW(m_keyChain.getPib().getDefaultIdentity());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700241 // The default key of the added identity must exist
laqinfan56a812d2019-06-03 15:33:58 -0500242 Key key = id.getDefaultKey();
Yingdi Yufe4733a2015-10-22 14:24:12 -0700243 // The default certificate of the default key must exist
laqinfan56a812d2019-06-03 15:33:58 -0500244 BOOST_CHECK_NO_THROW(key.getDefaultCertificate());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700245
246 // Delete key
247 Name key1Name = key.getName();
248 BOOST_CHECK_NO_THROW(id.getKey(key1Name));
249 BOOST_CHECK_EQUAL(id.getKeys().size(), 1);
250 m_keyChain.deleteKey(id, key);
251 // The key instance should not be valid any more
252 BOOST_CHECK(!key);
253 BOOST_CHECK_THROW(id.getKey(key1Name), Pib::Error);
254 BOOST_CHECK_EQUAL(id.getKeys().size(), 0);
255
256 // Create another key
257 m_keyChain.createKey(id);
258 // The added key becomes the default key.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700259 Key key2 = id.getDefaultKey();
260 BOOST_REQUIRE(key2);
261 BOOST_CHECK_NE(key2.getName(), key1Name);
262 BOOST_CHECK_EQUAL(id.getKeys().size(), 1);
laqinfan56a812d2019-06-03 15:33:58 -0500263 BOOST_CHECK_NO_THROW(key2.getDefaultCertificate());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700264
265 // Create the third key
266 Key key3 = m_keyChain.createKey(id);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000267 BOOST_CHECK_NE(key3.getName(), key2.getName());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700268 // The added key will not be the default key, because the default key already exists
Junxiao Shi72c0c642018-04-20 15:41:09 +0000269 BOOST_CHECK_EQUAL(id.getDefaultKey().getName(), key2.getName());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700270 BOOST_CHECK_EQUAL(id.getKeys().size(), 2);
laqinfan56a812d2019-06-03 15:33:58 -0500271 BOOST_CHECK_NO_THROW(key3.getDefaultCertificate());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700272
273 // Delete cert
274 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 1);
275 Certificate key3Cert1 = *key3.getCertificates().begin();
276 Name key3CertName = key3Cert1.getName();
277 m_keyChain.deleteCertificate(key3, key3CertName);
278 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 0);
279 BOOST_REQUIRE_THROW(key3.getDefaultCertificate(), Pib::Error);
280
281 // Add cert
282 m_keyChain.addCertificate(key3, key3Cert1);
283 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 1);
laqinfan56a812d2019-06-03 15:33:58 -0500284 BOOST_CHECK_NO_THROW(key3.getDefaultCertificate());
Alexander Afanasyeva10b2ff2017-01-30 12:44:15 -0800285 m_keyChain.addCertificate(key3, key3Cert1); // overwriting the cert should work
Yingdi Yufe4733a2015-10-22 14:24:12 -0700286 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 1);
287 // Add another cert
288 Certificate key3Cert2 = key3Cert1;
289 Name key3Cert2Name = key3.getName();
290 key3Cert2Name.append("Self");
291 key3Cert2Name.appendVersion();
292 key3Cert2.setName(key3Cert2Name);
293 m_keyChain.addCertificate(key3, key3Cert2);
294 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 2);
295
296 // Default certificate setting
297 BOOST_CHECK_EQUAL(key3.getDefaultCertificate().getName(), key3CertName);
298 m_keyChain.setDefaultCertificate(key3, key3Cert2);
299 BOOST_CHECK_EQUAL(key3.getDefaultCertificate().getName(), key3Cert2Name);
300
301 // Default key setting
302 BOOST_CHECK_EQUAL(id.getDefaultKey().getName(), key2.getName());
303 m_keyChain.setDefaultKey(id, key3);
304 BOOST_CHECK_EQUAL(id.getDefaultKey().getName(), key3.getName());
305
306 // Default identity setting
307 Identity id2 = m_keyChain.createIdentity(identity2Name);
308 BOOST_CHECK_EQUAL(m_keyChain.getPib().getDefaultIdentity().getName(), id.getName());
309 m_keyChain.setDefaultIdentity(id2);
310 BOOST_CHECK_EQUAL(m_keyChain.getPib().getDefaultIdentity().getName(), id2.getName());
311
312 // Delete identity
313 m_keyChain.deleteIdentity(id);
314 // The identity instance should not be valid any more
315 BOOST_CHECK(!id);
316 BOOST_REQUIRE_THROW(m_keyChain.getPib().getIdentity(identityName), Pib::Error);
317 BOOST_CHECK(m_keyChain.getPib().getIdentities().find(identityName) == m_keyChain.getPib().getIdentities().end());
318}
319
320BOOST_FIXTURE_TEST_CASE(GeneralSigningInterface, IdentityManagementFixture)
321{
322 Identity id = addIdentity("/id");
323 Key key = id.getDefaultKey();
324 Certificate cert = key.getDefaultCertificate();
325
laqinfan56a812d2019-06-03 15:33:58 -0500326 Name hmacKeyName = m_keyChain.createHmacKey();
327 const Tpm& tpm = m_keyChain.getTpm();
328
329 std::vector<SigningInfo> signingInfos = {
Yingdi Yufe4733a2015-10-22 14:24:12 -0700330 SigningInfo(),
331
332 SigningInfo(SigningInfo::SIGNER_TYPE_ID, id.getName()),
333 signingByIdentity(id.getName()),
334
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800335 SigningInfo(id),
336 signingByIdentity(id),
337
Yingdi Yufe4733a2015-10-22 14:24:12 -0700338 SigningInfo(SigningInfo::SIGNER_TYPE_KEY, key.getName()),
339 signingByKey(key.getName()),
340
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800341 SigningInfo(key),
342 signingByKey(key),
343
Yingdi Yufe4733a2015-10-22 14:24:12 -0700344 SigningInfo(SigningInfo::SIGNER_TYPE_CERT, cert.getName()),
345 signingByCertificate(cert.getName()),
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800346 signingByCertificate(cert),
Yingdi Yufe4733a2015-10-22 14:24:12 -0700347
laqinfan56a812d2019-06-03 15:33:58 -0500348 SigningInfo(SigningInfo::SIGNER_TYPE_HMAC, hmacKeyName),
349 SigningInfo("hmac-sha256:QjM3NEEyNkE3MTQ5MDQzN0FBMDI0RTRGQURENUI0OTdGREZGMUE4RUE2RkYxMkY2RkI2NUFGMjcyMEI1OUNDRg=="),
350
Yingdi Yufe4733a2015-10-22 14:24:12 -0700351 SigningInfo(SigningInfo::SIGNER_TYPE_SHA256),
352 signingWithSha256()
353 };
354
355 for (const auto& signingInfo : signingInfos) {
356 BOOST_TEST_MESSAGE("SigningInfo: " << signingInfo);
357 Data data("/data");
358 Interest interest("/interest");
359
360 if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_NULL) {
361 m_keyChain.sign(data);
362 m_keyChain.sign(interest);
363 }
364 else {
365 m_keyChain.sign(data, signingInfo);
366 m_keyChain.sign(interest, signingInfo);
367 }
368
369 Signature interestSignature(interest.getName()[-2].blockFromValue(), interest.getName()[-1].blockFromValue());
370
371 if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_SHA256) {
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400372 BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::DigestSha256);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700373 BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::DigestSha256);
374
Alexander Afanasyev574aa862017-01-10 19:53:28 -0800375 BOOST_CHECK(verifyDigest(data, DigestAlgorithm::SHA256));
376 BOOST_CHECK(verifyDigest(interest, DigestAlgorithm::SHA256));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700377 }
laqinfan56a812d2019-06-03 15:33:58 -0500378 else if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_HMAC) {
379 Name keyName = signingInfo.getSignerName();
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400380 BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::SignatureHmacWithSha256);
laqinfan56a812d2019-06-03 15:33:58 -0500381 BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::SignatureHmacWithSha256);
382
laqinfanbc997e52019-06-25 22:11:09 -0500383 BOOST_CHECK(bool(verifySignature(data, tpm, keyName, DigestAlgorithm::SHA256)));
384 BOOST_CHECK(bool(verifySignature(interest, tpm, keyName, DigestAlgorithm::SHA256)));
laqinfan56a812d2019-06-03 15:33:58 -0500385 }
Yingdi Yufe4733a2015-10-22 14:24:12 -0700386 else {
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400387 BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::SignatureSha256WithEcdsa);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700388 BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::SignatureSha256WithEcdsa);
389
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400390 BOOST_CHECK_EQUAL(data.getKeyLocator()->getName(), cert.getName().getPrefix(-2));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700391 BOOST_CHECK_EQUAL(interestSignature.getKeyLocator().getName(), cert.getName().getPrefix(-2));
392
Alexander Afanasyev574aa862017-01-10 19:53:28 -0800393 BOOST_CHECK(verifySignature(data, key));
394 BOOST_CHECK(verifySignature(interest, key));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700395 }
396 }
397}
398
399BOOST_FIXTURE_TEST_CASE(PublicKeySigningDefaults, IdentityManagementFixture)
400{
401 Data data("/test/data");
402
403 // Identity will be created with generated key and self-signed cert with default parameters
404 BOOST_CHECK_THROW(m_keyChain.sign(data, signingByIdentity("/non-existing/identity")), KeyChain::InvalidSigningInfoError);
405
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700406 // Create identity with EC key and the corresponding self-signed certificate
407 Identity id = addIdentity("/ndn/test/ec", EcKeyParams());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700408 BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id.getName())));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400409 BOOST_CHECK_EQUAL(data.getSignatureType(),
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700410 KeyChain::getSignatureType(EcKeyParams().getKeyType(), DigestAlgorithm::SHA256));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400411 BOOST_REQUIRE(data.getKeyLocator().has_value());
412 BOOST_CHECK(id.getName().isPrefixOf(data.getKeyLocator()->getName()));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700413
414 // Create identity with RSA key and the corresponding self-signed certificate
415 id = addIdentity("/ndn/test/rsa", RsaKeyParams());
416 BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id.getName())));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400417 BOOST_CHECK_EQUAL(data.getSignatureType(),
Yingdi Yufe4733a2015-10-22 14:24:12 -0700418 KeyChain::getSignatureType(RsaKeyParams().getKeyType(), DigestAlgorithm::SHA256));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400419 BOOST_REQUIRE(data.getKeyLocator().has_value());
420 BOOST_CHECK(id.getName().isPrefixOf(data.getKeyLocator()->getName()));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700421}
422
laqinfan56a812d2019-06-03 15:33:58 -0500423BOOST_FIXTURE_TEST_CASE(ImportPrivateKey, IdentityManagementFixture)
424{
425 Name keyName("/test/device2");
426 std::string rawKey("nPSNOHyZKsg2WLqHAs7MXGb0sjQb4zCT");
427 auto key = make_shared<transform::PrivateKey>();
428 key->loadRaw(KeyType::HMAC, reinterpret_cast<const uint8_t*>(rawKey.data()), rawKey.size());
429
430 m_keyChain.importPrivateKey(keyName, key);
431 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(keyName), true);
432 BOOST_CHECK_THROW(m_keyChain.importPrivateKey(keyName, key), KeyChain::Error);
433}
434
Yingdi Yufe4733a2015-10-22 14:24:12 -0700435BOOST_FIXTURE_TEST_CASE(ExportImport, IdentityManagementFixture)
436{
laqinfan56a812d2019-06-03 15:33:58 -0500437 Identity id = addIdentity("/TestKeyChain/ExportIdentity");
Yingdi Yufe4733a2015-10-22 14:24:12 -0700438 Certificate cert = id.getDefaultKey().getDefaultCertificate();
439
440 shared_ptr<SafeBag> exported = m_keyChain.exportSafeBag(cert, "1234", 4);
441 Block block = exported->wireEncode();
442
443 m_keyChain.deleteIdentity(id);
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500444 BOOST_CHECK_THROW(m_keyChain.exportSafeBag(cert, "1234", 4), KeyChain::Error);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700445
446 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(cert.getKeyName()), false);
447 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 0);
448
449 SafeBag imported;
450 imported.wireDecode(block);
451 m_keyChain.importSafeBag(imported, "1234", 4);
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500452 BOOST_CHECK_THROW(m_keyChain.importSafeBag(imported, "1234", 4), KeyChain::Error);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700453
454 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(cert.getKeyName()), true);
455 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 1);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700456 Identity newId = m_keyChain.getPib().getIdentity(cert.getIdentity());
457 BOOST_CHECK_EQUAL(newId.getKeys().size(), 1);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700458 Key newKey = newId.getKey(cert.getKeyName());
459 BOOST_CHECK_EQUAL(newKey.getCertificates().size(), 1);
laqinfan56a812d2019-06-03 15:33:58 -0500460 BOOST_CHECK_NO_THROW(newKey.getCertificate(cert.getName()));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700461
462 m_keyChain.deleteIdentity(newId);
463 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 0);
464 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(cert.getKeyName()), false);
465}
466
Alexander Afanasyevf8379172017-01-11 16:56:04 -0800467BOOST_FIXTURE_TEST_CASE(SelfSignedCertValidity, IdentityManagementFixture)
468{
469 Certificate cert = addIdentity("/Security/V2/TestKeyChain/SelfSignedCertValidity")
470 .getDefaultKey()
471 .getDefaultCertificate();
472 BOOST_CHECK(cert.isValid());
Davide Pesavento0f830802018-01-16 23:58:58 -0500473 BOOST_CHECK(cert.isValid(time::system_clock::now() + 10 * 365_days));
474 BOOST_CHECK_GT(cert.getValidityPeriod().getPeriod().second, time::system_clock::now() + 10 * 365_days);
Alexander Afanasyevf8379172017-01-11 16:56:04 -0800475}
476
Yingdi Yufe4733a2015-10-22 14:24:12 -0700477BOOST_AUTO_TEST_SUITE_END() // TestKeyChain
Alexander Afanasyevf8379172017-01-11 16:56:04 -0800478BOOST_AUTO_TEST_SUITE_END() // V2
Yingdi Yufe4733a2015-10-22 14:24:12 -0700479BOOST_AUTO_TEST_SUITE_END() // Security
480
481} // namespace tests
482} // namespace v2
483} // namespace security
484} // namespace ndn