blob: a9e1eaf877f5ced50e9fe603927657e911ea5970 [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
Alexander Afanasyev09236c22020-06-03 13:42:38 -040022#include "ndn-cxx/security/key-chain.hpp"
laqinfan56a812d2019-06-03 15:33:58 -050023#include "ndn-cxx/security/transform/private-key.hpp"
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050024#include "ndn-cxx/security/verification-helpers.hpp"
Yingdi Yufe4733a2015-10-22 14:24:12 -070025
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "tests/boost-test.hpp"
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050027#include "tests/key-chain-fixture.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050028#include "tests/unit/test-home-env-saver.hpp"
Yingdi Yufe4733a2015-10-22 14:24:12 -070029
30namespace ndn {
31namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040032inline namespace v2 {
Yingdi Yufe4733a2015-10-22 14:24:12 -070033namespace tests {
34
35using namespace ndn::tests;
36
37BOOST_AUTO_TEST_SUITE(Security)
Yingdi Yufe4733a2015-10-22 14:24:12 -070038BOOST_FIXTURE_TEST_SUITE(TestKeyChain, TestHomeEnvSaver)
39
40template<class Path>
41class TestHomeAndPibFixture : public TestHomeFixture<Path>
42{
43public:
44 TestHomeAndPibFixture()
45 {
46 unsetenv("NDN_CLIENT_PIB");
47 unsetenv("NDN_CLIENT_TPM");
48 }
Alexander Afanasyev80782e02017-01-04 13:16:54 -080049
50 ~TestHomeAndPibFixture()
51 {
Alexander Afanasyev57d02b62018-06-15 18:19:50 -040052 try {
53 const_cast<std::string&>(KeyChain::getDefaultPibLocator()).clear();
54 }
55 catch (const KeyChain::Error&) {
56 // ignore
57 }
58
59 try {
60 const_cast<std::string&>(KeyChain::getDefaultTpmLocator()).clear();
61 }
62 catch (const KeyChain::Error&) {
63 // ignore
64 }
Alexander Afanasyev80782e02017-01-04 13:16:54 -080065 }
Yingdi Yufe4733a2015-10-22 14:24:12 -070066};
67
68struct PibPathConfigFileHome
69{
70 const std::string PATH = "build/config-file-home/";
71};
72
73BOOST_FIXTURE_TEST_CASE(ConstructorNormalConfig, TestHomeAndPibFixture<PibPathConfigFileHome>)
74{
75 createClientConf({"pib=pib-memory:", "tpm=tpm-memory:"});
76
77 BOOST_REQUIRE_NO_THROW(KeyChain());
78
79 KeyChain keyChain;
80 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-memory:");
81 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-memory:");
82 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
83}
84
85struct PibPathConfigFileEmptyHome
86{
87 const std::string PATH = "build/config-file-empty-home/";
88};
89
90BOOST_FIXTURE_TEST_CASE(ConstructorEmptyConfig, TestHomeAndPibFixture<PibPathConfigFileEmptyHome>)
91{
92 createClientConf({"pib=pib-memory:"});
93
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -050094#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
Yingdi Yufe4733a2015-10-22 14:24:12 -070095 std::string oldHOME;
96 if (std::getenv("OLD_HOME"))
97 oldHOME = std::getenv("OLD_HOME");
98
99 std::string HOME;
100 if (std::getenv("HOME"))
101 HOME = std::getenv("HOME");
102
103 if (!oldHOME.empty())
104 setenv("HOME", oldHOME.c_str(), 1);
105 else
106 unsetenv("HOME");
107#endif
108
109 BOOST_REQUIRE_NO_THROW(KeyChain());
110 KeyChain keyChain;
111 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-memory:");
112
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -0500113#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700114 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-osxkeychain:");
115 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-osxkeychain:");
116#else
117 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-file:");
118 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:");
119#endif
120
Alexander Afanasyev0cf887d2017-03-26 16:58:59 -0500121#if defined(NDN_CXX_HAVE_OSX_FRAMEWORKS)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700122 if (!HOME.empty())
123 setenv("HOME", HOME.c_str(), 1);
124 else
125 unsetenv("HOME");
126
127 if (!oldHOME.empty())
128 setenv("OLD_HOME", oldHOME.c_str(), 1);
129 else
130 unsetenv("OLD_HOME");
131#endif
132}
133
134struct PibPathConfigFileEmpty2Home
135{
136 const std::string PATH = "build/config-file-empty2-home/";
137};
138
139BOOST_FIXTURE_TEST_CASE(ConstructorEmpty2Config, TestHomeAndPibFixture<PibPathConfigFileEmpty2Home>)
140{
141 createClientConf({"tpm=tpm-memory:"});
142
143 BOOST_REQUIRE_NO_THROW(KeyChain());
144
145 KeyChain keyChain;
146 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:");
147 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-memory:");
148 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
149}
150
151struct PibPathConfigFileMalformedHome
152{
153 const std::string PATH = "build/config-file-malformed-home/";
154};
155
156BOOST_FIXTURE_TEST_CASE(ConstructorMalConfig, TestHomeAndPibFixture<PibPathConfigFileMalformedHome>)
157{
158 createClientConf({"pib=lord", "tpm=ring"});
159
160 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
161}
162
163struct PibPathConfigFileMalformed2Home
164{
165 const std::string PATH = "build/config-file-malformed2-home/";
166};
167
168BOOST_FIXTURE_TEST_CASE(ConstructorMal2Config, TestHomeAndPibFixture<PibPathConfigFileMalformed2Home>)
169{
170 createClientConf({"pib=pib-sqlite3:%PATH%", "tpm=just-wrong"});
171
172 BOOST_REQUIRE_THROW(KeyChain(), KeyChain::Error); // Wrong configuration. Error expected.
173}
174
Alexander Afanasyev57d02b62018-06-15 18:19:50 -0400175struct PibPathConfigFileNonCanonicalTpm
176{
177 const std::string PATH = "build/config-file-non-canonical-tpm/";
178};
179
180BOOST_FIXTURE_TEST_CASE(ConstructorNonCanonicalTpm, TestHomeAndPibFixture<PibPathConfigFileNonCanonicalTpm>) // Bug 4297
181{
182 createClientConf({"pib=pib-sqlite3:", "tpm=tpm-file"});
183
184 {
185 KeyChain keyChain;
186 keyChain.createIdentity("/test");
187 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:");
188 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:");
189 }
190
191 {
192 KeyChain keyChain;
193 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-sqlite3:");
194 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-file:");
195 BOOST_CHECK(keyChain.getPib().getIdentities().find("/test") != keyChain.getPib().getIdentities().end());
196 }
197}
198
Yingdi Yufe4733a2015-10-22 14:24:12 -0700199BOOST_AUTO_TEST_CASE(KeyChainWithCustomTpmAndPib)
200{
201 BOOST_REQUIRE_NO_THROW((KeyChain("pib-memory", "tpm-memory")));
202 BOOST_REQUIRE_NO_THROW((KeyChain("pib-memory:", "tpm-memory:")));
203 BOOST_REQUIRE_NO_THROW((KeyChain("pib-memory:/something", "tpm-memory:/something")));
204
205 KeyChain keyChain("pib-memory", "tpm-memory");
206 BOOST_CHECK_EQUAL(keyChain.getPib().getPibLocator(), "pib-memory:");
207 BOOST_CHECK_EQUAL(keyChain.getPib().getTpmLocator(), "tpm-memory:");
208 BOOST_CHECK_EQUAL(keyChain.getTpm().getTpmLocator(), "tpm-memory:");
209}
210
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500211BOOST_FIXTURE_TEST_CASE(SigningWithCorruptedPibTpm, KeyChainFixture)
Alexander Afanasyevf601e192020-06-02 16:41:07 -0400212{
213 Identity id = m_keyChain.createIdentity("/test");
214
215 Data data("/foobar");
216 BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id)));
217
218 // now, "corrupting TPM"
219 const_cast<Tpm&>(m_keyChain.getTpm()).deleteKey(id.getDefaultKey().getName());
220
221 BOOST_CHECK_NO_THROW(id.getDefaultKey());
222 BOOST_CHECK_THROW(m_keyChain.sign(data, signingByIdentity(id)), KeyChain::InvalidSigningInfoError);
223}
224
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500225BOOST_FIXTURE_TEST_CASE(Management, KeyChainFixture)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700226{
227 Name identityName("/test/id");
228 Name identity2Name("/test/id2");
229
230 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 0);
231 BOOST_REQUIRE_THROW(m_keyChain.getPib().getDefaultIdentity(), Pib::Error);
232
233 // Create identity
234 Identity id = m_keyChain.createIdentity(identityName);
235 BOOST_CHECK(id);
236 BOOST_CHECK(m_keyChain.getPib().getIdentities().find(identityName) != m_keyChain.getPib().getIdentities().end());
237 // The first added identity becomes the default identity
laqinfan56a812d2019-06-03 15:33:58 -0500238 BOOST_CHECK_NO_THROW(m_keyChain.getPib().getDefaultIdentity());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700239 // The default key of the added identity must exist
laqinfan56a812d2019-06-03 15:33:58 -0500240 Key key = id.getDefaultKey();
Yingdi Yufe4733a2015-10-22 14:24:12 -0700241 // The default certificate of the default key must exist
laqinfan56a812d2019-06-03 15:33:58 -0500242 BOOST_CHECK_NO_THROW(key.getDefaultCertificate());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700243
244 // Delete key
245 Name key1Name = key.getName();
246 BOOST_CHECK_NO_THROW(id.getKey(key1Name));
247 BOOST_CHECK_EQUAL(id.getKeys().size(), 1);
248 m_keyChain.deleteKey(id, key);
249 // The key instance should not be valid any more
250 BOOST_CHECK(!key);
251 BOOST_CHECK_THROW(id.getKey(key1Name), Pib::Error);
252 BOOST_CHECK_EQUAL(id.getKeys().size(), 0);
253
254 // Create another key
255 m_keyChain.createKey(id);
256 // The added key becomes the default key.
Yingdi Yufe4733a2015-10-22 14:24:12 -0700257 Key key2 = id.getDefaultKey();
258 BOOST_REQUIRE(key2);
259 BOOST_CHECK_NE(key2.getName(), key1Name);
260 BOOST_CHECK_EQUAL(id.getKeys().size(), 1);
laqinfan56a812d2019-06-03 15:33:58 -0500261 BOOST_CHECK_NO_THROW(key2.getDefaultCertificate());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700262
263 // Create the third key
264 Key key3 = m_keyChain.createKey(id);
Junxiao Shi72c0c642018-04-20 15:41:09 +0000265 BOOST_CHECK_NE(key3.getName(), key2.getName());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700266 // The added key will not be the default key, because the default key already exists
Junxiao Shi72c0c642018-04-20 15:41:09 +0000267 BOOST_CHECK_EQUAL(id.getDefaultKey().getName(), key2.getName());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700268 BOOST_CHECK_EQUAL(id.getKeys().size(), 2);
laqinfan56a812d2019-06-03 15:33:58 -0500269 BOOST_CHECK_NO_THROW(key3.getDefaultCertificate());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700270
271 // Delete cert
272 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 1);
273 Certificate key3Cert1 = *key3.getCertificates().begin();
274 Name key3CertName = key3Cert1.getName();
275 m_keyChain.deleteCertificate(key3, key3CertName);
276 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 0);
277 BOOST_REQUIRE_THROW(key3.getDefaultCertificate(), Pib::Error);
278
279 // Add cert
280 m_keyChain.addCertificate(key3, key3Cert1);
281 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 1);
laqinfan56a812d2019-06-03 15:33:58 -0500282 BOOST_CHECK_NO_THROW(key3.getDefaultCertificate());
Alexander Afanasyeva10b2ff2017-01-30 12:44:15 -0800283 m_keyChain.addCertificate(key3, key3Cert1); // overwriting the cert should work
Yingdi Yufe4733a2015-10-22 14:24:12 -0700284 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 1);
285 // Add another cert
286 Certificate key3Cert2 = key3Cert1;
287 Name key3Cert2Name = key3.getName();
288 key3Cert2Name.append("Self");
289 key3Cert2Name.appendVersion();
290 key3Cert2.setName(key3Cert2Name);
291 m_keyChain.addCertificate(key3, key3Cert2);
292 BOOST_CHECK_EQUAL(key3.getCertificates().size(), 2);
Davide Pesavento81bd6962020-06-17 16:03:23 -0400293 // Add empty cert
294 Certificate key3Cert3 = key3Cert1;
295 key3Cert3.unsetContent();
296 BOOST_CHECK_THROW(m_keyChain.addCertificate(key3, key3Cert3), std::invalid_argument);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700297
298 // Default certificate setting
299 BOOST_CHECK_EQUAL(key3.getDefaultCertificate().getName(), key3CertName);
300 m_keyChain.setDefaultCertificate(key3, key3Cert2);
301 BOOST_CHECK_EQUAL(key3.getDefaultCertificate().getName(), key3Cert2Name);
302
303 // Default key setting
304 BOOST_CHECK_EQUAL(id.getDefaultKey().getName(), key2.getName());
305 m_keyChain.setDefaultKey(id, key3);
306 BOOST_CHECK_EQUAL(id.getDefaultKey().getName(), key3.getName());
307
308 // Default identity setting
309 Identity id2 = m_keyChain.createIdentity(identity2Name);
310 BOOST_CHECK_EQUAL(m_keyChain.getPib().getDefaultIdentity().getName(), id.getName());
311 m_keyChain.setDefaultIdentity(id2);
312 BOOST_CHECK_EQUAL(m_keyChain.getPib().getDefaultIdentity().getName(), id2.getName());
313
314 // Delete identity
315 m_keyChain.deleteIdentity(id);
316 // The identity instance should not be valid any more
317 BOOST_CHECK(!id);
318 BOOST_REQUIRE_THROW(m_keyChain.getPib().getIdentity(identityName), Pib::Error);
319 BOOST_CHECK(m_keyChain.getPib().getIdentities().find(identityName) == m_keyChain.getPib().getIdentities().end());
320}
321
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500322BOOST_FIXTURE_TEST_CASE(GeneralSigningInterface, KeyChainFixture)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700323{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500324 Identity id = m_keyChain.createIdentity("/id");
Yingdi Yufe4733a2015-10-22 14:24:12 -0700325 Key key = id.getDefaultKey();
326 Certificate cert = key.getDefaultCertificate();
327
laqinfan56a812d2019-06-03 15:33:58 -0500328 Name hmacKeyName = m_keyChain.createHmacKey();
329 const Tpm& tpm = m_keyChain.getTpm();
330
331 std::vector<SigningInfo> signingInfos = {
Eric Newberryb74bbda2020-06-18 19:33:58 -0700332 // New signed Interest format
333 SigningInfo().setSignedInterestFormat(SignedInterestFormat::V03),
334
335 SigningInfo(SigningInfo::SIGNER_TYPE_ID, id.getName())
336 .setSignedInterestFormat(SignedInterestFormat::V03),
337 signingByIdentity(id.getName()).setSignedInterestFormat(SignedInterestFormat::V03),
338
339 SigningInfo(id).setSignedInterestFormat(SignedInterestFormat::V03),
340 signingByIdentity(id).setSignedInterestFormat(SignedInterestFormat::V03),
341
342 SigningInfo(SigningInfo::SIGNER_TYPE_KEY, key.getName())
343 .setSignedInterestFormat(SignedInterestFormat::V03),
344 signingByKey(key.getName()).setSignedInterestFormat(SignedInterestFormat::V03),
345
346 SigningInfo(key).setSignedInterestFormat(SignedInterestFormat::V03),
347 signingByKey(key).setSignedInterestFormat(SignedInterestFormat::V03),
348
349 SigningInfo(SigningInfo::SIGNER_TYPE_CERT, cert.getName())
350 .setSignedInterestFormat(SignedInterestFormat::V03),
351 signingByCertificate(cert.getName()).setSignedInterestFormat(SignedInterestFormat::V03),
352 signingByCertificate(cert).setSignedInterestFormat(SignedInterestFormat::V03),
353
354 SigningInfo(SigningInfo::SIGNER_TYPE_HMAC, hmacKeyName)
355 .setSignedInterestFormat(SignedInterestFormat::V03),
356 SigningInfo("hmac-sha256:QjM3NEEyNkE3MTQ5MDQzN0FBMDI0RTRGQURENUI0OTdGREZGMUE4RUE2RkYxMkY2RkI2NUFGMjcyMEI1OUNDRg==")
357 .setSignedInterestFormat(SignedInterestFormat::V03),
358
359 SigningInfo(SigningInfo::SIGNER_TYPE_SHA256)
360 .setSignedInterestFormat(SignedInterestFormat::V03),
361 signingWithSha256().setSignedInterestFormat(SignedInterestFormat::V03),
362
363 // Deprecated signed Interest format
Yingdi Yufe4733a2015-10-22 14:24:12 -0700364 SigningInfo(),
365
366 SigningInfo(SigningInfo::SIGNER_TYPE_ID, id.getName()),
367 signingByIdentity(id.getName()),
368
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800369 SigningInfo(id),
370 signingByIdentity(id),
371
Yingdi Yufe4733a2015-10-22 14:24:12 -0700372 SigningInfo(SigningInfo::SIGNER_TYPE_KEY, key.getName()),
373 signingByKey(key.getName()),
374
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800375 SigningInfo(key),
376 signingByKey(key),
377
Yingdi Yufe4733a2015-10-22 14:24:12 -0700378 SigningInfo(SigningInfo::SIGNER_TYPE_CERT, cert.getName()),
379 signingByCertificate(cert.getName()),
Alexander Afanasyevd6d78aa2017-01-02 18:14:23 -0800380 signingByCertificate(cert),
Yingdi Yufe4733a2015-10-22 14:24:12 -0700381
laqinfan56a812d2019-06-03 15:33:58 -0500382 SigningInfo(SigningInfo::SIGNER_TYPE_HMAC, hmacKeyName),
383 SigningInfo("hmac-sha256:QjM3NEEyNkE3MTQ5MDQzN0FBMDI0RTRGQURENUI0OTdGREZGMUE4RUE2RkYxMkY2RkI2NUFGMjcyMEI1OUNDRg=="),
384
Yingdi Yufe4733a2015-10-22 14:24:12 -0700385 SigningInfo(SigningInfo::SIGNER_TYPE_SHA256),
386 signingWithSha256()
387 };
388
389 for (const auto& signingInfo : signingInfos) {
390 BOOST_TEST_MESSAGE("SigningInfo: " << signingInfo);
391 Data data("/data");
392 Interest interest("/interest");
Eric Newberryb74bbda2020-06-18 19:33:58 -0700393 interest.setCanBePrefix(false);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700394
Eric Newberryb74bbda2020-06-18 19:33:58 -0700395 m_keyChain.sign(data, signingInfo);
396 m_keyChain.sign(interest, signingInfo);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700397
398 if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_SHA256) {
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400399 BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::DigestSha256);
Eric Newberryb74bbda2020-06-18 19:33:58 -0700400
401 if (signingInfo.getSignedInterestFormat() == SignedInterestFormat::V03) {
402 BOOST_REQUIRE(interest.getSignatureInfo() != nullopt);
403 BOOST_CHECK_EQUAL(interest.getSignatureInfo()->getSignatureType(), tlv::DigestSha256);
404 }
405 else {
406 SignatureInfo sigInfo(interest.getName()[signed_interest::POS_SIG_INFO].blockFromValue());
407 BOOST_CHECK_EQUAL(sigInfo.getSignatureType(), tlv::DigestSha256);
408 }
Yingdi Yufe4733a2015-10-22 14:24:12 -0700409
Alexander Afanasyev574aa862017-01-10 19:53:28 -0800410 BOOST_CHECK(verifyDigest(data, DigestAlgorithm::SHA256));
411 BOOST_CHECK(verifyDigest(interest, DigestAlgorithm::SHA256));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700412 }
laqinfan56a812d2019-06-03 15:33:58 -0500413 else if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_HMAC) {
414 Name keyName = signingInfo.getSignerName();
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400415 BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::SignatureHmacWithSha256);
laqinfan56a812d2019-06-03 15:33:58 -0500416
Eric Newberryb74bbda2020-06-18 19:33:58 -0700417 if (signingInfo.getSignedInterestFormat() == SignedInterestFormat::V03) {
418 BOOST_REQUIRE(interest.getSignatureInfo() != nullopt);
419 BOOST_CHECK_EQUAL(interest.getSignatureInfo()->getSignatureType(),
420 tlv::SignatureHmacWithSha256);
421 }
422 else {
423 SignatureInfo sigInfo(interest.getName()[signed_interest::POS_SIG_INFO].blockFromValue());
424 BOOST_CHECK_EQUAL(sigInfo.getSignatureType(), tlv::SignatureHmacWithSha256);
425 }
426
427 BOOST_CHECK(verifySignature(data, tpm, keyName, DigestAlgorithm::SHA256));
428 BOOST_CHECK(verifySignature(interest, tpm, keyName, DigestAlgorithm::SHA256));
laqinfan56a812d2019-06-03 15:33:58 -0500429 }
Yingdi Yufe4733a2015-10-22 14:24:12 -0700430 else {
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400431 BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::SignatureSha256WithEcdsa);
Eric Newberryb74bbda2020-06-18 19:33:58 -0700432
433 if (signingInfo.getSignedInterestFormat() == SignedInterestFormat::V03) {
434 BOOST_REQUIRE(interest.getSignatureInfo() != nullopt);
435 BOOST_CHECK_EQUAL(interest.getSignatureInfo()->getSignatureType(),
436 tlv::SignatureSha256WithEcdsa);
437 }
438 else {
439 SignatureInfo sigInfo(interest.getName()[signed_interest::POS_SIG_INFO].blockFromValue());
440 BOOST_CHECK_EQUAL(sigInfo.getSignatureType(), tlv::SignatureSha256WithEcdsa);
441 }
Yingdi Yufe4733a2015-10-22 14:24:12 -0700442
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400443 BOOST_CHECK_EQUAL(data.getKeyLocator()->getName(), cert.getName().getPrefix(-2));
Eric Newberryb74bbda2020-06-18 19:33:58 -0700444
445 if (signingInfo.getSignedInterestFormat() == SignedInterestFormat::V03) {
446 BOOST_CHECK_EQUAL(interest.getSignatureInfo()->getKeyLocator().getName(),
447 cert.getName().getPrefix(-2));
448 }
449 else {
450 SignatureInfo sigInfo(interest.getName()[signed_interest::POS_SIG_INFO].blockFromValue());
451 BOOST_CHECK_EQUAL(sigInfo.getKeyLocator().getName(), cert.getName().getPrefix(-2));
452 }
Yingdi Yufe4733a2015-10-22 14:24:12 -0700453
Alexander Afanasyev574aa862017-01-10 19:53:28 -0800454 BOOST_CHECK(verifySignature(data, key));
455 BOOST_CHECK(verifySignature(interest, key));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700456 }
457 }
458}
459
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500460BOOST_FIXTURE_TEST_CASE(PublicKeySigningDefaults, KeyChainFixture)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700461{
462 Data data("/test/data");
463
464 // Identity will be created with generated key and self-signed cert with default parameters
465 BOOST_CHECK_THROW(m_keyChain.sign(data, signingByIdentity("/non-existing/identity")), KeyChain::InvalidSigningInfoError);
466
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700467 // Create identity with EC key and the corresponding self-signed certificate
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500468 Identity id = m_keyChain.createIdentity("/ndn/test/ec", EcKeyParams());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700469 BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id.getName())));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400470 BOOST_CHECK_EQUAL(data.getSignatureType(),
Spyridon Mastorakis1ece2e32015-08-27 18:52:21 -0700471 KeyChain::getSignatureType(EcKeyParams().getKeyType(), DigestAlgorithm::SHA256));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400472 BOOST_REQUIRE(data.getKeyLocator().has_value());
473 BOOST_CHECK(id.getName().isPrefixOf(data.getKeyLocator()->getName()));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700474
475 // Create identity with RSA key and the corresponding self-signed certificate
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500476 id = m_keyChain.createIdentity("/ndn/test/rsa", RsaKeyParams());
Yingdi Yufe4733a2015-10-22 14:24:12 -0700477 BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id.getName())));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400478 BOOST_CHECK_EQUAL(data.getSignatureType(),
Yingdi Yufe4733a2015-10-22 14:24:12 -0700479 KeyChain::getSignatureType(RsaKeyParams().getKeyType(), DigestAlgorithm::SHA256));
Davide Pesavento14c56cd2020-05-21 01:44:03 -0400480 BOOST_REQUIRE(data.getKeyLocator().has_value());
481 BOOST_CHECK(id.getName().isPrefixOf(data.getKeyLocator()->getName()));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700482}
483
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500484BOOST_FIXTURE_TEST_CASE(ImportPrivateKey, KeyChainFixture)
laqinfan56a812d2019-06-03 15:33:58 -0500485{
486 Name keyName("/test/device2");
487 std::string rawKey("nPSNOHyZKsg2WLqHAs7MXGb0sjQb4zCT");
488 auto key = make_shared<transform::PrivateKey>();
489 key->loadRaw(KeyType::HMAC, reinterpret_cast<const uint8_t*>(rawKey.data()), rawKey.size());
490
491 m_keyChain.importPrivateKey(keyName, key);
492 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(keyName), true);
493 BOOST_CHECK_THROW(m_keyChain.importPrivateKey(keyName, key), KeyChain::Error);
494}
495
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500496BOOST_FIXTURE_TEST_CASE(ExportImport, KeyChainFixture)
Yingdi Yufe4733a2015-10-22 14:24:12 -0700497{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500498 Identity id = m_keyChain.createIdentity("/TestKeyChain/ExportIdentity");
Yingdi Yufe4733a2015-10-22 14:24:12 -0700499 Certificate cert = id.getDefaultKey().getDefaultCertificate();
500
501 shared_ptr<SafeBag> exported = m_keyChain.exportSafeBag(cert, "1234", 4);
502 Block block = exported->wireEncode();
503
504 m_keyChain.deleteIdentity(id);
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500505 BOOST_CHECK_THROW(m_keyChain.exportSafeBag(cert, "1234", 4), KeyChain::Error);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700506
507 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(cert.getKeyName()), false);
508 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 0);
509
510 SafeBag imported;
511 imported.wireDecode(block);
512 m_keyChain.importSafeBag(imported, "1234", 4);
Davide Pesavento82d6a4c2017-12-23 19:47:20 -0500513 BOOST_CHECK_THROW(m_keyChain.importSafeBag(imported, "1234", 4), KeyChain::Error);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700514
515 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(cert.getKeyName()), true);
516 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 1);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700517 Identity newId = m_keyChain.getPib().getIdentity(cert.getIdentity());
518 BOOST_CHECK_EQUAL(newId.getKeys().size(), 1);
Yingdi Yufe4733a2015-10-22 14:24:12 -0700519 Key newKey = newId.getKey(cert.getKeyName());
520 BOOST_CHECK_EQUAL(newKey.getCertificates().size(), 1);
laqinfan56a812d2019-06-03 15:33:58 -0500521 BOOST_CHECK_NO_THROW(newKey.getCertificate(cert.getName()));
Yingdi Yufe4733a2015-10-22 14:24:12 -0700522
523 m_keyChain.deleteIdentity(newId);
524 BOOST_CHECK_EQUAL(m_keyChain.getPib().getIdentities().size(), 0);
525 BOOST_CHECK_EQUAL(m_keyChain.getTpm().hasKey(cert.getKeyName()), false);
526}
527
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500528BOOST_FIXTURE_TEST_CASE(SelfSignedCertValidity, KeyChainFixture)
Alexander Afanasyevf8379172017-01-11 16:56:04 -0800529{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500530 Certificate cert = m_keyChain.createIdentity("/Security/TestKeyChain/SelfSignedCertValidity")
Alexander Afanasyevf8379172017-01-11 16:56:04 -0800531 .getDefaultKey()
532 .getDefaultCertificate();
533 BOOST_CHECK(cert.isValid());
Davide Pesavento0f830802018-01-16 23:58:58 -0500534 BOOST_CHECK(cert.isValid(time::system_clock::now() + 10 * 365_days));
535 BOOST_CHECK_GT(cert.getValidityPeriod().getPeriod().second, time::system_clock::now() + 10 * 365_days);
Alexander Afanasyevf8379172017-01-11 16:56:04 -0800536}
537
Yingdi Yufe4733a2015-10-22 14:24:12 -0700538BOOST_AUTO_TEST_SUITE_END() // TestKeyChain
Yingdi Yufe4733a2015-10-22 14:24:12 -0700539BOOST_AUTO_TEST_SUITE_END() // Security
540
541} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400542} // inline namespace v2
Yingdi Yufe4733a2015-10-22 14:24:12 -0700543} // namespace security
544} // namespace ndn