blob: 842f2f57b2140b7b3a7a495e5fae9169c7e51902 [file] [log] [blame]
Alexander Afanasyev7e721412017-01-11 13:36:08 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev6aff0242017-08-29 17:14:44 -04002/*
Davide Pesaventoaee2ada2022-02-18 14:43:02 -05003 * Copyright (c) 2013-2022 Regents of the University of California.
Alexander Afanasyev7e721412017-01-11 13:36:08 -08004 *
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/validator.hpp"
23#include "ndn-cxx/security/validation-policy-simple-hierarchy.hpp"
Alexander Afanasyev7e721412017-01-11 13:36:08 -080024
Davide Pesavento2acce252022-09-08 22:03:03 -040025#include "tests/test-common.hpp"
Alexander Afanasyev09236c22020-06-03 13:42:38 -040026#include "tests/unit/security/validator-fixture.hpp"
Alexander Afanasyev7e721412017-01-11 13:36:08 -080027
28namespace ndn {
29namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040030inline namespace v2 {
Alexander Afanasyev7e721412017-01-11 13:36:08 -080031namespace tests {
32
33using namespace ndn::tests;
34
35BOOST_AUTO_TEST_SUITE(Security)
Alexander Afanasyev7e721412017-01-11 13:36:08 -080036BOOST_FIXTURE_TEST_SUITE(TestValidator, HierarchicalValidatorFixture<ValidationPolicySimpleHierarchy>)
37
Alexander Afanasyevb54aa572017-03-21 19:40:49 -050038BOOST_AUTO_TEST_CASE(ConstructorSetValidator)
39{
40 auto middlePolicy = make_unique<ValidationPolicySimpleHierarchy>();
41 auto innerPolicy = make_unique<ValidationPolicySimpleHierarchy>();
42
43 validator.getPolicy().setInnerPolicy(std::move(middlePolicy));
44 validator.getPolicy().setInnerPolicy(std::move(innerPolicy));
45
46 BOOST_CHECK(validator.getPolicy().m_validator != nullptr);
47 BOOST_CHECK(validator.getPolicy().getInnerPolicy().m_validator != nullptr);
48 BOOST_CHECK(validator.getPolicy().getInnerPolicy().getInnerPolicy().m_validator != nullptr);
Davide Pesavento2acce252022-09-08 22:03:03 -040049
50 BOOST_CHECK_THROW(validator.getPolicy().setInnerPolicy(nullptr), std::invalid_argument);
Alexander Afanasyevb54aa572017-03-21 19:40:49 -050051}
52
Davide Pesavento2acce252022-09-08 22:03:03 -040053BOOST_AUTO_TEST_CASE(BadSignatureInfo)
Alexander Afanasyev7e721412017-01-11 13:36:08 -080054{
Davide Pesavento2acce252022-09-08 22:03:03 -040055 Interest interest("/Security/ValidatorFixture/Sub1/Sub2/Interest");
56 m_keyChain.sign(interest, signingByIdentity(subIdentity)
57 .setSignedInterestFormat(SignedInterestFormat::V03));
58
59 // add an unrecognized critical element inside InterestSignatureInfo
60 auto si = interest.getSignatureInfo().value();
61 si.addCustomTlv("7F00"_block);
62 interest.setSignatureInfo(si);
63 BOOST_REQUIRE_THROW(interest.getSignatureInfo(), tlv::Error);
64 BOOST_REQUIRE_NO_THROW(interest.getSignatureValue());
65
66 VALIDATE_FAILURE(interest, "InterestSignatureInfo decoding should fail");
67 BOOST_TEST(lastError.getCode() == ValidationError::NO_SIGNATURE);
68 BOOST_TEST(face.sentInterests.size() == 0);
69}
70
71BOOST_AUTO_TEST_CASE(BadSignatureValue)
72{
73 const uint8_t sv[] = {0x12, 0x34, 0x56, 0x78};
74
75 Interest interest("/Security/ValidatorFixture/Sub1/Sub2/Interest");
76 m_keyChain.sign(interest, signingByIdentity(subIdentity)
77 .setSignedInterestFormat(SignedInterestFormat::V03));
78 interest.setSignatureValue(sv);
79
80 VALIDATE_FAILURE(interest, "Signature check should fail");
81 BOOST_TEST(lastError.getCode() == ValidationError::INVALID_SIGNATURE);
82 BOOST_TEST(face.sentInterests.size() == 1);
83
84 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
85 m_keyChain.sign(data, signingByIdentity(subIdentity));
86 data.setSignatureValue(sv);
87
88 VALIDATE_FAILURE(data, "Signature check should fail");
89 BOOST_TEST(lastError.getCode() == ValidationError::INVALID_SIGNATURE);
90 BOOST_TEST(face.sentInterests.size() == 1);
91}
92
93BOOST_AUTO_TEST_CASE(Timeout)
94{
95 processInterest = nullptr; // no response for any interest
Alexander Afanasyev7e721412017-01-11 13:36:08 -080096
Alexander Afanasyev09236c22020-06-03 13:42:38 -040097 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -080098 m_keyChain.sign(data, signingByIdentity(subIdentity));
99
100 VALIDATE_FAILURE(data, "Should fail to retrieve certificate");
Davide Pesavento2acce252022-09-08 22:03:03 -0400101 BOOST_TEST(lastError.getCode() == ValidationError::CANNOT_RETRIEVE_CERT);
102 BOOST_TEST(face.sentInterests.size() == 4);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800103}
104
Davide Pesavento2acce252022-09-08 22:03:03 -0400105BOOST_AUTO_TEST_CASE(Nack)
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800106{
107 processInterest = [this] (const Interest& interest) {
Davide Pesavento2acce252022-09-08 22:03:03 -0400108 face.receive(makeNack(interest, lp::NackReason::NO_ROUTE));
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800109 };
110
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400111 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800112 m_keyChain.sign(data, signingByIdentity(subIdentity));
113
114 VALIDATE_FAILURE(data, "All interests should get NACKed");
Davide Pesavento2acce252022-09-08 22:03:03 -0400115 BOOST_TEST(lastError.getCode() == ValidationError::CANNOT_RETRIEVE_CERT);
Ashlesh Gawande3e39a4d2018-08-30 16:49:13 -0500116 // 1 for the first interest, 3 for the retries on nack
Davide Pesavento2acce252022-09-08 22:03:03 -0400117 BOOST_TEST(face.sentInterests.size() == 4);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800118}
119
120BOOST_AUTO_TEST_CASE(MalformedCert)
121{
122 Data malformedCert = subIdentity.getDefaultKey().getDefaultCertificate();
123 malformedCert.setContentType(tlv::ContentType_Blob);
124 m_keyChain.sign(malformedCert, signingByIdentity(identity));
125 // wrong content type & missing ValidityPeriod
126 BOOST_REQUIRE_THROW(Certificate(malformedCert.wireEncode()), tlv::Error);
127
128 auto originalProcessInterest = processInterest;
Davide Pesavento2acce252022-09-08 22:03:03 -0400129 processInterest = [&] (const Interest& interest) {
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800130 if (interest.getName().isPrefixOf(malformedCert.getName())) {
131 face.receive(malformedCert);
132 }
133 else {
134 originalProcessInterest(interest);
135 }
136 };
137
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400138 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800139 m_keyChain.sign(data, signingByIdentity(subIdentity));
140
141 VALIDATE_FAILURE(data, "Signed by a malformed certificate");
Davide Pesavento2acce252022-09-08 22:03:03 -0400142 BOOST_TEST(lastError.getCode() == ValidationError::MALFORMED_CERT);
143 BOOST_TEST(face.sentInterests.size() == 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800144}
145
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800146BOOST_AUTO_TEST_CASE(ExpiredCert)
147{
148 Data expiredCert = subIdentity.getDefaultKey().getDefaultCertificate();
149 SignatureInfo info;
Davide Pesavento2acce252022-09-08 22:03:03 -0400150 info.setValidityPeriod(ValidityPeriod::makeRelative(-2_h, -1_h));
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800151 m_keyChain.sign(expiredCert, signingByIdentity(identity).setSignatureInfo(info));
152 BOOST_REQUIRE_NO_THROW(Certificate(expiredCert.wireEncode()));
153
154 auto originalProcessInterest = processInterest;
Davide Pesavento2acce252022-09-08 22:03:03 -0400155 processInterest = [&] (const Interest& interest) {
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800156 if (interest.getName().isPrefixOf(expiredCert.getName())) {
157 face.receive(expiredCert);
158 }
159 else {
Davide Pesaventob88c6bf2017-09-11 20:15:28 -0400160 originalProcessInterest(interest);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800161 }
162 };
163
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400164 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800165 m_keyChain.sign(data, signingByIdentity(subIdentity));
166
167 VALIDATE_FAILURE(data, "Signed by an expired certificate");
Davide Pesavento2acce252022-09-08 22:03:03 -0400168 BOOST_TEST(lastError.getCode() == ValidationError::EXPIRED_CERT);
169 BOOST_TEST(face.sentInterests.size() == 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800170}
171
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400172BOOST_AUTO_TEST_CASE(ResetAnchors)
173{
174 validator.resetAnchors();
175
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400176 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400177 m_keyChain.sign(data, signingByIdentity(subIdentity));
178 VALIDATE_FAILURE(data, "Should fail, as no anchors configured");
Davide Pesavento2acce252022-09-08 22:03:03 -0400179 BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400180}
181
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800182BOOST_AUTO_TEST_CASE(TrustedCertCaching)
183{
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400184 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800185 m_keyChain.sign(data, signingByIdentity(subIdentity));
186
187 VALIDATE_SUCCESS(data, "Should get accepted, as signed by the policy-compliant cert");
Davide Pesavento2acce252022-09-08 22:03:03 -0400188 BOOST_TEST(face.sentInterests.size() == 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800189 face.sentInterests.clear();
190
191 processInterest = nullptr; // disable data responses from mocked network
192
193 VALIDATE_SUCCESS(data, "Should get accepted, based on the cached trusted cert");
Davide Pesavento2acce252022-09-08 22:03:03 -0400194 BOOST_TEST(face.sentInterests.size() == 0);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800195 face.sentInterests.clear();
196
Davide Pesavento0f830802018-01-16 23:58:58 -0500197 advanceClocks(1_h, 2); // expire trusted cache
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800198
199 VALIDATE_FAILURE(data, "Should try and fail to retrieve certs");
Davide Pesavento2acce252022-09-08 22:03:03 -0400200 BOOST_TEST(lastError.getCode() == ValidationError::CANNOT_RETRIEVE_CERT);
201 BOOST_TEST(face.sentInterests.size() > 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800202}
203
Davide Pesavento2acce252022-09-08 22:03:03 -0400204BOOST_AUTO_TEST_CASE(ResetVerifiedCerts)
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400205{
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400206 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400207 m_keyChain.sign(data, signingByIdentity(subIdentity));
208 VALIDATE_SUCCESS(data, "Should get accepted, as signed by the policy-compliant cert");
209
210 // reset anchors
211 validator.resetAnchors();
212 VALIDATE_SUCCESS(data, "Should get accepted, as signed by the cert in trusted cache");
213
214 // reset trusted cache
215 validator.resetVerifiedCertificates();
216 VALIDATE_FAILURE(data, "Should fail, as no trusted cache or anchors");
Davide Pesavento2acce252022-09-08 22:03:03 -0400217 BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400218}
219
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800220BOOST_AUTO_TEST_CASE(UntrustedCertCaching)
221{
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400222 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800223 m_keyChain.sign(data, signingByIdentity(subSelfSignedIdentity));
224
225 VALIDATE_FAILURE(data, "Should fail, as signed by the policy-violating cert");
Davide Pesavento2acce252022-09-08 22:03:03 -0400226 BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);
227 BOOST_TEST(face.sentInterests.size() == 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800228 face.sentInterests.clear();
229
230 processInterest = nullptr; // disable data responses from mocked network
231
232 VALIDATE_FAILURE(data, "Should fail again, but no network operations expected");
Davide Pesavento2acce252022-09-08 22:03:03 -0400233 BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);
234 BOOST_TEST(face.sentInterests.size() == 0);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800235 face.sentInterests.clear();
236
Davide Pesavento0f830802018-01-16 23:58:58 -0500237 advanceClocks(10_min, 2); // expire untrusted cache
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800238
239 VALIDATE_FAILURE(data, "Should try and fail to retrieve certs");
Davide Pesavento2acce252022-09-08 22:03:03 -0400240 BOOST_TEST(lastError.getCode() == ValidationError::CANNOT_RETRIEVE_CERT);
241 BOOST_TEST(face.sentInterests.size() > 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800242}
243
244class ValidationPolicySimpleHierarchyForInterestOnly : public ValidationPolicySimpleHierarchy
245{
246public:
247 void
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500248 checkPolicy(const Data&, const shared_ptr<ValidationState>& state,
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800249 const ValidationContinuation& continueValidation) override
250 {
251 continueValidation(nullptr, state);
252 }
253};
254
255BOOST_FIXTURE_TEST_CASE(ValidateInterestsButBypassForData,
256 HierarchicalValidatorFixture<ValidationPolicySimpleHierarchyForInterestOnly>)
257{
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400258 Interest interest("/Security/ValidatorFixture/Sub1/Sub2/Interest");
Davide Pesavento2acce252022-09-08 22:03:03 -0400259 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800260
261 VALIDATE_FAILURE(interest, "Unsigned");
Davide Pesavento2acce252022-09-08 22:03:03 -0400262 BOOST_TEST(lastError.getCode() == ValidationError::NO_SIGNATURE);
263 VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
264 BOOST_TEST(face.sentInterests.size() == 0);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800265 face.sentInterests.clear();
266
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400267 interest = Interest("/Security/ValidatorFixture/Sub1/Sub2/Interest");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800268 m_keyChain.sign(interest, signingWithSha256());
269 m_keyChain.sign(data, signingWithSha256());
270 VALIDATE_FAILURE(interest, "Required KeyLocator/Name missing (not passed to policy)");
Davide Pesavento2acce252022-09-08 22:03:03 -0400271 BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
272 VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
273 BOOST_TEST(face.sentInterests.size() == 0);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800274 face.sentInterests.clear();
275
276 m_keyChain.sign(interest, signingByIdentity(identity));
277 m_keyChain.sign(data, signingByIdentity(identity));
278 VALIDATE_SUCCESS(interest, "Should get accepted, as signed by the anchor");
Davide Pesavento2acce252022-09-08 22:03:03 -0400279 VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
280 BOOST_TEST(face.sentInterests.size() == 0);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800281 face.sentInterests.clear();
282
283 m_keyChain.sign(interest, signingByIdentity(subIdentity));
284 m_keyChain.sign(data, signingByIdentity(subIdentity));
285 VALIDATE_FAILURE(interest, "Should fail, as policy is not allowed to create new trust anchors");
Davide Pesavento2acce252022-09-08 22:03:03 -0400286 BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
287 VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
288 BOOST_TEST(face.sentInterests.size() == 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800289 face.sentInterests.clear();
290
291 m_keyChain.sign(interest, signingByIdentity(otherIdentity));
292 m_keyChain.sign(data, signingByIdentity(otherIdentity));
293 VALIDATE_FAILURE(interest, "Should fail, as signed by the policy-violating cert");
Davide Pesavento2acce252022-09-08 22:03:03 -0400294 BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
295 VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800296 // no network operations expected, as certificate is not validated by the policy
Davide Pesavento2acce252022-09-08 22:03:03 -0400297 BOOST_TEST(face.sentInterests.size() == 0);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800298 face.sentInterests.clear();
299
Davide Pesavento0f830802018-01-16 23:58:58 -0500300 advanceClocks(1_h, 2); // expire trusted cache
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800301
302 m_keyChain.sign(interest, signingByIdentity(subSelfSignedIdentity));
303 m_keyChain.sign(data, signingByIdentity(subSelfSignedIdentity));
304 VALIDATE_FAILURE(interest, "Should fail, as policy is not allowed to create new trust anchors");
Davide Pesavento2acce252022-09-08 22:03:03 -0400305 BOOST_TEST(lastError.getCode() == ValidationError::POLICY_ERROR);
306 VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
307 BOOST_TEST(face.sentInterests.size() == 1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800308 face.sentInterests.clear();
309}
310
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800311BOOST_AUTO_TEST_CASE(InfiniteCertChain)
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800312{
313 processInterest = [this] (const Interest& interest) {
314 // create another key for the same identity and sign it properly
315 Key parentKey = m_keyChain.createKey(subIdentity);
316 Key requestedKey = subIdentity.getKey(interest.getName());
Junxiao Shi9ee770b2022-04-25 23:33:33 +0000317
318 SignatureInfo sigInfo;
319 sigInfo.setKeyLocator(parentKey.getName());
320 auto si = signingByKey(parentKey).setSignatureInfo(sigInfo);
321
322 auto cert = m_keyChain.makeCertificate(requestedKey, si);
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500323 face.receive(cert);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800324 };
325
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400326 Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
Davide Pesavento2acce252022-09-08 22:03:03 -0400327 m_keyChain.sign(data, signingByIdentity(subIdentity)
328 .setSignatureInfo(SignatureInfo()
329 .setKeyLocator(subIdentity.getDefaultKey().getName())));
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800330
331 validator.setMaxDepth(40);
332 BOOST_CHECK_EQUAL(validator.getMaxDepth(), 40);
333 VALIDATE_FAILURE(data, "Should fail, as certificate should be looped");
Davide Pesavento2acce252022-09-08 22:03:03 -0400334 BOOST_TEST(lastError.getCode() == ValidationError::EXCEEDED_DEPTH_LIMIT);
335 BOOST_TEST(face.sentInterests.size() == 40);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800336 face.sentInterests.clear();
337
Davide Pesavento0f830802018-01-16 23:58:58 -0500338 advanceClocks(1_h, 5); // expire caches
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800339
340 validator.setMaxDepth(30);
341 BOOST_CHECK_EQUAL(validator.getMaxDepth(), 30);
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800342 VALIDATE_FAILURE(data, "Should fail, as certificate chain is infinite");
Davide Pesavento2acce252022-09-08 22:03:03 -0400343 BOOST_TEST(lastError.getCode() == ValidationError::EXCEEDED_DEPTH_LIMIT);
344 BOOST_TEST(face.sentInterests.size() == 30);
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800345}
346
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800347BOOST_AUTO_TEST_CASE(LoopedCertChain)
348{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500349 auto s1 = m_keyChain.createIdentity("/loop");
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800350 auto k1 = m_keyChain.createKey(s1, RsaKeyParams(name::Component("key1")));
351 auto k2 = m_keyChain.createKey(s1, RsaKeyParams(name::Component("key2")));
352 auto k3 = m_keyChain.createKey(s1, RsaKeyParams(name::Component("key3")));
353
Junxiao Shi7d728682022-04-01 01:21:13 +0000354 auto makeLoopCert = [this] (Key& key, const Key& signer) {
Junxiao Shi9ee770b2022-04-25 23:33:33 +0000355 SignatureInfo sigInfo;
356 sigInfo.setKeyLocator(signer.getName());
357 auto si = signingByKey(signer).setSignatureInfo(sigInfo);
358
359 auto cert = m_keyChain.makeCertificate(key, si);
Junxiao Shi7d728682022-04-01 01:21:13 +0000360 m_keyChain.setDefaultCertificate(key, cert);
361 cache.insert(cert);
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800362 };
363
Junxiao Shi7d728682022-04-01 01:21:13 +0000364 makeLoopCert(k1, k2);
365 makeLoopCert(k2, k3);
366 makeLoopCert(k3, k1);
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800367
368 Data data("/loop/Data");
369 m_keyChain.sign(data, signingByKey(k1));
370 VALIDATE_FAILURE(data, "Should fail, as certificate chain loops");
Davide Pesavento2acce252022-09-08 22:03:03 -0400371 BOOST_TEST(lastError.getCode() == ValidationError::LOOP_DETECTED);
372 BOOST_TEST_REQUIRE(face.sentInterests.size() == 3);
Junxiao Shi7d728682022-04-01 01:21:13 +0000373 BOOST_CHECK_EQUAL(face.sentInterests[0].getName(), k1.getDefaultCertificate().getName());
374 BOOST_CHECK_EQUAL(face.sentInterests[1].getName(), k2.getName());
375 BOOST_CHECK_EQUAL(face.sentInterests[2].getName(), k3.getName());
Alexander Afanasyev5af04a72017-01-30 22:41:23 -0800376}
377
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800378BOOST_AUTO_TEST_SUITE_END() // TestValidator
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800379BOOST_AUTO_TEST_SUITE_END() // Security
380
381} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400382} // inline namespace v2
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800383} // namespace security
384} // namespace ndn