blob: 32fbf01889c459d50c1c4b52bf0857ef18efd184 [file] [log] [blame]
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesaventoaee2ada2022-02-18 14:43:02 -05003 * Copyright (c) 2013-2022 Regents of the University of California.
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -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/validation-policy-config.hpp"
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050023
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "ndn-cxx/security/transform/base64-encode.hpp"
25#include "ndn-cxx/security/transform/buffer-source.hpp"
26#include "ndn-cxx/security/transform/stream-sink.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050027#include "ndn-cxx/util/io.hpp"
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080028
Davide Pesavento7e780642018-11-24 15:51:34 -050029#include "tests/boost-test.hpp"
Alexander Afanasyev09236c22020-06-03 13:42:38 -040030#include "tests/unit/security/validator-config/common.hpp"
31#include "tests/unit/security/validator-fixture.hpp"
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080032
33namespace ndn {
34namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040035inline namespace v2 {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080036namespace validator_config {
37namespace tests {
38
39using namespace ndn::tests;
Davide Pesaventof2cae612021-03-24 18:47:05 -040040using namespace ndn::security::tests;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080041
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080042BOOST_AUTO_TEST_SUITE(Security)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080043BOOST_AUTO_TEST_SUITE(TestValidationPolicyConfig)
44
Davide Pesavento0a6456c2019-11-14 00:33:11 -050045BOOST_FIXTURE_TEST_CASE(EmptyConfig, HierarchicalValidatorFixture<ValidationPolicyConfig>)
46{
47 this->policy.load(ConfigSection{}, "<empty>");
48
49 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
50 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
51 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
52 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
53
Alexander Afanasyev09236c22020-06-03 13:42:38 -040054 Data d("/Security/ValidationPolicyConfig/D");
Davide Pesavento0a6456c2019-11-14 00:33:11 -050055 this->m_keyChain.sign(d, signingByIdentity(this->identity));
56 VALIDATE_FAILURE(d, "Empty policy should reject everything");
57
Alexander Afanasyev09236c22020-06-03 13:42:38 -040058 Interest i("/Security/ValidationPolicyConfig/I");
Davide Pesavento0a6456c2019-11-14 00:33:11 -050059 this->m_keyChain.sign(i, signingByIdentity(this->identity));
60 VALIDATE_FAILURE(i, "Empty policy should reject everything");
61}
62
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080063template<typename Packet>
64class PacketName;
65
66template<>
67class PacketName<Interest>
68{
69public:
70 static std::string
71 getName()
72 {
73 return "interest";
74 }
75};
76
77template<>
78class PacketName<Data>
79{
80public:
81 static std::string
82 getName()
83 {
84 return "data";
85 }
86};
87
88template<typename PacketType>
89class ValidationPolicyConfigFixture : public HierarchicalValidatorFixture<ValidationPolicyConfig>
90{
91public:
92 ValidationPolicyConfigFixture()
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050093 : path(boost::filesystem::path(UNIT_TESTS_TMPDIR) / "security" / "validation-policy-config")
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080094 {
95 boost::filesystem::create_directories(path);
96 baseConfig = R"CONF(
97 rule
98 {
99 id test-rule-id
100 for )CONF" + PacketName<Packet>::getName() + R"CONF(
101 filter
102 {
103 type name
104 name )CONF" + identity.getName().toUri() + R"CONF(
105 relation is-prefix-of
106 }
107 checker
108 {
109 type hierarchical
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400110 sig-type ecdsa-sha256
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800111 }
112 }
113 )CONF";
114 }
115
116 ~ValidationPolicyConfigFixture()
117 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500118 boost::filesystem::remove_all(path);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800119 }
120
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500121protected:
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800122 using Packet = PacketType;
123
124 const boost::filesystem::path path;
125 std::string baseConfig;
126};
127
128template<typename PacketType>
129class LoadStringWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
130{
131public:
132 LoadStringWithFileAnchor()
133 {
134 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
135
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500136 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800137 this->policy.load(this->baseConfig + R"CONF(
138 trust-anchor
139 {
140 type file
141 file-name "trust-anchor.ndncert"
142 }
143 )CONF", (this->path / "test-config").string());
144
145 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
146 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
147 }
148};
149
150template<typename PacketType>
151class LoadFileWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
152{
153public:
154 LoadFileWithFileAnchor()
155 {
156 std::string configFile = (this->path / "config.conf").string();
157 {
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500158 std::ofstream config(configFile);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800159 config << this->baseConfig << R"CONF(
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500160 trust-anchor
161 {
162 type file
163 file-name "trust-anchor.ndncert"
164 }
165 )CONF";
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800166 }
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500167
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500168 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800169
170 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
171
172 this->policy.load(configFile);
173
174 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
175 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
176 }
177};
178
179template<typename PacketType>
Varun Patil574c3f92020-11-25 09:07:33 +0530180class LoadFileWithMultipleFileAnchors : public ValidationPolicyConfigFixture<PacketType>
181{
182public:
183 LoadFileWithMultipleFileAnchors()
184 {
185 std::string configFile = (this->path / "config.conf").string();
186 {
187 std::ofstream config(configFile);
188 config << this->baseConfig << R"CONF(
189 trust-anchor
190 {
191 type file
192 file-name "identity.ndncert"
193 }
194 trust-anchor
195 {
196 type file
197 file-name "trust-anchor.ndncert"
198 }
199 )CONF";
200 }
201
202 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
203
204 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
205
206 this->policy.load(configFile);
207
208 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
209 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
210 }
211};
212
213template<typename PacketType>
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800214class LoadSectionWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
215{
216public:
217 LoadSectionWithFileAnchor()
218 {
219 auto section = makeSection(this->baseConfig + R"CONF(
220 trust-anchor
221 {
222 type file
223 file-name "trust-anchor.ndncert"
224 }
225 )CONF");
226
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500227 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800228
229 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
230
231 this->policy.load(section, (this->path / "test-config").string());
232
233 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
234 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
235 }
236};
237
238template<typename PacketType>
239class LoadStringWithBase64Anchor : public ValidationPolicyConfigFixture<PacketType>
240{
241public:
242 LoadStringWithBase64Anchor()
243 {
244 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
245
246 std::ostringstream os;
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500247 {
248 using namespace ndn::security::transform;
249 const auto& cert = this->identity.getDefaultKey().getDefaultCertificate().wireEncode();
Davide Pesavento765abc92021-12-27 00:44:04 -0500250 bufferSource(make_span(cert.wire(), cert.size())) >> base64Encode(false) >> streamSink(os);
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500251 }
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800252
253 this->policy.load(this->baseConfig + R"CONF(
254 trust-anchor
255 {
256 type base64
257 base64-string ")CONF" + os.str() + R"CONF("
258 }
259 )CONF", (this->path / "test-config").string());
260
261 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
262 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
263 }
264};
265
266class NoRefresh
267{
268public:
269 static std::string
270 getRefreshString()
271 {
272 return "";
273 }
274};
275
276class Refresh1h
277{
278public:
279 static std::string
280 getRefreshString()
281 {
282 return "refresh 1h";
283 }
284
285 static time::milliseconds
286 getRefreshTime()
287 {
Davide Pesavento0f830802018-01-16 23:58:58 -0500288 return 1_h;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800289 }
290};
291
292class Refresh1m
293{
294public:
295 static std::string
296 getRefreshString()
297 {
298 return "refresh 1m";
299 }
300
301 static time::milliseconds
302 getRefreshTime()
303 {
Davide Pesavento0f830802018-01-16 23:58:58 -0500304 return 1_min;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800305 }
306};
307
308class Refresh1s
309{
310public:
311 static std::string
312 getRefreshString()
313 {
314 return "refresh 1s";
315 }
316
317 static time::milliseconds
318 getRefreshTime()
319 {
Davide Pesavento0f830802018-01-16 23:58:58 -0500320 return 1_s;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800321 }
322};
323
324template<typename PacketType, typename Refresh = NoRefresh>
325class LoadStringWithDirAnchor : public ValidationPolicyConfigFixture<PacketType>
326{
327public:
328 LoadStringWithDirAnchor()
329 {
330 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
331
332 boost::filesystem::create_directories(this->path / "keys");
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500333 this->saveIdentityCert(this->identity, (this->path / "keys" / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800334
335 this->policy.load(this->baseConfig + R"CONF(
336 trust-anchor
337 {
338 type dir
339 dir keys
340 )CONF" + Refresh::getRefreshString() + R"CONF(
341 }
342 )CONF", (this->path / "test-config").string());
343
344 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
345 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
346 }
347};
348
349using DataPolicies = boost::mpl::vector<LoadStringWithFileAnchor<Data>,
350 LoadFileWithFileAnchor<Data>,
Varun Patil574c3f92020-11-25 09:07:33 +0530351 LoadFileWithMultipleFileAnchors<Data>,
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800352 LoadSectionWithFileAnchor<Data>,
353 LoadStringWithBase64Anchor<Data>,
354 LoadStringWithDirAnchor<Data>,
355 LoadStringWithDirAnchor<Data, Refresh1h>,
356 LoadStringWithDirAnchor<Data, Refresh1m>,
357 LoadStringWithDirAnchor<Data, Refresh1s>
358 >;
359
360using InterestPolicies = boost::mpl::vector<LoadStringWithFileAnchor<Interest>,
361 LoadFileWithFileAnchor<Interest>,
Varun Patil574c3f92020-11-25 09:07:33 +0530362 LoadFileWithMultipleFileAnchors<Interest>,
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800363 LoadSectionWithFileAnchor<Interest>,
364 LoadStringWithBase64Anchor<Interest>,
365 LoadStringWithDirAnchor<Interest>,
366 LoadStringWithDirAnchor<Interest, Refresh1h>,
367 LoadStringWithDirAnchor<Interest, Refresh1m>,
368 LoadStringWithDirAnchor<Interest, Refresh1s>
369 >;
370
371BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateData, Policy, DataPolicies, Policy)
372{
373 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 1);
374 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
375
376 using Packet = typename Policy::Packet;
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400377 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800378
379 Packet packet = unsignedPacket;
380 VALIDATE_FAILURE(packet, "Unsigned");
381
382 packet = unsignedPacket;
383 this->m_keyChain.sign(packet, signingWithSha256());
Justin Labryaef53b62021-03-10 06:07:27 +0000384 VALIDATE_FAILURE(packet, "Should not be accepted, doesn't pass checker /localhost/identity/digest-sha256");
385
386 packet = Packet("/localhost/identity/digest-sha256/foobar");
387 this->m_keyChain.sign(packet, signingWithSha256());
388 VALIDATE_FAILURE(packet, "Should not be accepted, no rule for the name /localhost/identity/digest-sha256");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800389
390 packet = unsignedPacket;
391 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
392 VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");
393
394 packet = unsignedPacket;
395 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
396 VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the policy-compliant cert");
397
398 packet = unsignedPacket;
399 this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
400 VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
401
402 packet = unsignedPacket;
403 this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
404 VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
405}
406
407BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateInterest, Policy, InterestPolicies, Policy)
408{
409 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
410 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 1);
411
412 using Packet = typename Policy::Packet;
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400413 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800414
415 Packet packet = unsignedPacket;
416 VALIDATE_FAILURE(packet, "Unsigned");
417
418 packet = unsignedPacket;
419 this->m_keyChain.sign(packet, signingWithSha256());
Justin Labryaef53b62021-03-10 06:07:27 +0000420 VALIDATE_FAILURE(packet, "Should not be accepted, doesn't pass checker /localhost/identity/digest-sha256");
421
422 packet = Packet("/localhost/identity/digest-sha256/foobar");
423 this->m_keyChain.sign(packet, signingWithSha256());
424 VALIDATE_FAILURE(packet, "Should not be accepted, no rule for the name /localhost/identity/digest-sha256");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800425
426 packet = unsignedPacket;
427 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
428 VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");
429
430 packet = unsignedPacket;
431 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
432 VALIDATE_FAILURE(packet, "Should fail, as there is no matching rule for data");
433
434 packet = unsignedPacket;
435 this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
436 VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
437
438 packet = unsignedPacket;
439 this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
440 VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
441}
442
Justin Labryaef53b62021-03-10 06:07:27 +0000443BOOST_FIXTURE_TEST_CASE(DigestSha256, HierarchicalValidatorFixture<ValidationPolicyConfig>)
444{
445 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
446 this->policy.load(R"CONF(
447 rule
448 {
449 id test-rule-data-id
450 for data
451 filter
452 {
453 type name
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400454 name /Security/ValidatorFixture
455 relation is-prefix-of
456 }
457 checker
458 {
459 type customized
460 sig-type sha256
461 }
462 }
463 rule
464 {
465 id test-rule-interest-id
466 for interest
467 filter
468 {
469 type name
470 name /Security/ValidatorFixture
471 relation is-prefix-of
472 }
473 checker
474 {
475 type customized
476 sig-type sha256
477 }
478 }
479 )CONF", "test-config");
480
481
482 Interest interest("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400483 this->m_keyChain.sign(interest, signingWithSha256());
484 VALIDATE_SUCCESS(interest, "Should be accepted");
485
486 Data data("/Security/ValidatorFixture/Sub1/Sub2/Packet");
487 this->m_keyChain.sign(data, signingWithSha256());
488 VALIDATE_SUCCESS(data, "Should be accepted");
489}
490
491BOOST_FIXTURE_TEST_CASE(DigestSha256WithKeyLocator, HierarchicalValidatorFixture<ValidationPolicyConfig>)
492{
493 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
494 this->policy.load(R"CONF(
495 rule
496 {
497 id test-rule-data-id
498 for data
499 filter
500 {
501 type name
Justin Labryaef53b62021-03-10 06:07:27 +0000502 name /localhost/identity/digest-sha256
503 relation is-prefix-of
504 }
505 checker
506 {
507 type customized
508 sig-type sha256
509 key-locator
510 {
511 type name
512 hyper-relation
513 {
514 k-regex ^(<>*)$
515 k-expand \\1
516 h-relation is-prefix-of
517 p-regex ^(<>*)$
518 p-expand \\1
519 }
520 }
521 }
522 }
523 rule
524 {
525 id test-rule-interest-id
526 for interest
527 filter
528 {
529 type name
530 name /localhost/identity/digest-sha256
531 relation is-prefix-of
532 }
533 checker
534 {
535 type customized
536 sig-type sha256
537 key-locator
538 {
539 type name
540 hyper-relation
541 {
542 k-regex ^(<>*)$
543 k-expand \\1
544 h-relation is-prefix-of
545 p-regex ^(<>*)$
546 p-expand \\1
547 }
548 }
549 }
550 }
551 )CONF", "test-config");
552
553
554 Interest interest("/localhost/identity/digest-sha256/foobar");
Justin Labryaef53b62021-03-10 06:07:27 +0000555 this->m_keyChain.sign(interest, signingWithSha256());
556 VALIDATE_SUCCESS(interest, "Should be accepted");
557
558 Data data("/localhost/identity/digest-sha256/foobar");
559 this->m_keyChain.sign(data, signingWithSha256());
560 VALIDATE_SUCCESS(data, "Should be accepted");
561}
562
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400563BOOST_FIXTURE_TEST_CASE(SigTypeCheck, HierarchicalValidatorFixture<ValidationPolicyConfig>)
564{
565 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
566 this->policy.load(R"CONF(
567 rule
568 {
569 id test-rule-data-id
570 for data
571 filter
572 {
573 type name
574 name /localhost/identity/digest-sha256
575 relation is-prefix-of
576 }
577 checker
578 {
579 type customized
580 sig-type ecdsa-sha256
581 key-locator
582 {
583 type name
584 hyper-relation
585 {
586 k-regex ^(<>*)$
587 k-expand \\1
588 h-relation is-prefix-of
589 p-regex ^(<>*)$
590 p-expand \\1
591 }
592 }
593 }
594 }
595 rule
596 {
597 id test-rule-interest-id
598 for interest
599 filter
600 {
601 type name
602 name /localhost/identity/digest-sha256
603 relation is-prefix-of
604 }
605 checker
606 {
607 type customized
608 sig-type ecdsa-sha256
609 key-locator
610 {
611 type name
612 hyper-relation
613 {
614 k-regex ^(<>*)$
615 k-expand \\1
616 h-relation is-prefix-of
617 p-regex ^(<>*)$
618 p-expand \\1
619 }
620 }
621 }
622 }
623 )CONF", "test-config");
624
625
626 Interest interest("/localhost/identity/digest-sha256/foobar");
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400627 this->m_keyChain.sign(interest, signingWithSha256());
628 VALIDATE_FAILURE(interest, "Signature type check should fail");
629
630 Data data("/localhost/identity/digest-sha256/foobar");
631 this->m_keyChain.sign(data, signingWithSha256());
632 VALIDATE_FAILURE(data, "Signature type check should fail");
633}
634
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400635BOOST_FIXTURE_TEST_CASE(Reload, HierarchicalValidatorFixture<ValidationPolicyConfig>)
636{
637 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
638 this->policy.load(R"CONF(
639 rule
640 {
641 id test-rule-data-id
642 for data
643 filter
644 {
645 type name
646 name /foo/bar
647 relation is-prefix-of
648 }
649 checker
650 {
651 type hierarchical
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400652 sig-type ecdsa-sha256
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400653 }
654 }
655 rule
656 {
657 id test-rule-interest-id
658 for interest
659 filter
660 {
661 type name
662 name /foo/bar
663 relation is-prefix-of
664 }
665 checker
666 {
667 type hierarchical
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400668 sig-type ecdsa-sha256
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400669 }
670 }
671 trust-anchor
672 {
673 type dir
674 dir keys
675 refresh 1h
676 }
677 )CONF", "test-config");
678 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
679 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
680 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 1);
681 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 1);
682
683 this->policy.load(R"CONF(
684 trust-anchor
685 {
686 type any
687 }
688 )CONF", "test-config");
689 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
690 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, true);
691 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
692 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
693}
694
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800695using Packets = boost::mpl::vector<Interest, Data>;
696
697BOOST_FIXTURE_TEST_CASE_TEMPLATE(TrustAnchorWildcard, Packet, Packets, ValidationPolicyConfigFixture<Packet>)
698{
699 this->policy.load(R"CONF(
700 trust-anchor
701 {
702 type any
703 }
704 )CONF", "test-config");
705
706 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
707 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, true);
708 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
709 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
710
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400711 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800712
713 Packet packet = unsignedPacket;
714 VALIDATE_SUCCESS(packet, "Policy should accept everything");
715
716 packet = unsignedPacket;
717 this->m_keyChain.sign(packet, signingWithSha256());
718 VALIDATE_SUCCESS(packet, "Policy should accept everything");
719
720 packet = unsignedPacket;
721 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
722 VALIDATE_SUCCESS(packet, "Policy should accept everything");
723
724 packet = unsignedPacket;
725 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
726 VALIDATE_SUCCESS(packet, "Policy should accept everything");
727
728 packet = unsignedPacket;
729 this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
730 VALIDATE_SUCCESS(packet, "Policy should accept everything");
731
732 packet = unsignedPacket;
733 this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
734 VALIDATE_SUCCESS(packet, "Policy should accept everything");
735}
736
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400737using RefreshPolicies = boost::mpl::vector<Refresh1h, Refresh1m, Refresh1s>;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800738
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400739template<typename RefreshPolicy>
740class RefreshPolicyFixture : public LoadStringWithDirAnchor<Data, RefreshPolicy>
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800741{
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800742};
743
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400744BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateRefresh, Refresh, RefreshPolicies, RefreshPolicyFixture<Refresh>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800745{
746 using Packet = Data;
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400747 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800748
749 boost::filesystem::remove(this->path / "keys" / "identity.ndncert");
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400750 this->advanceClocks(Refresh::getRefreshTime(), 3);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800751
752 Packet packet = unsignedPacket;
753 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
754 VALIDATE_FAILURE(packet, "Should fail, as the trust anchor should no longer exist");
755
756 packet = unsignedPacket;
757 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
758 VALIDATE_FAILURE(packet, "Should fail, as the trust anchor should no longer exist");
759}
760
Alexander Afanasyev7b112462018-10-17 11:51:52 -0400761BOOST_FIXTURE_TEST_CASE(OrphanedPolicyLoad, HierarchicalValidatorFixture<ValidationPolicyConfig>) // Bug #4758
762{
763 ValidationPolicyConfig policy1;
764 BOOST_CHECK_THROW(policy1.load("trust-anchor { type any }", "test-config"), Error);
765
766 // Reloading would have triggered a segfault
767 BOOST_CHECK_THROW(policy1.load("trust-anchor { type any }", "test-config"), Error);
768
769 ValidationPolicyConfig policy2;
770
771 std::string config = R"CONF(
772 trust-anchor
773 {
774 type dir
775 dir keys
776 refresh 1h
777 }
778 )CONF";
779
780 // Inserting trust anchor would have triggered a segfault
781 BOOST_CHECK_THROW(policy2.load(config, "test-config"), Error);
782}
783
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800784BOOST_AUTO_TEST_SUITE_END() // TestValidationPolicyConfig
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800785BOOST_AUTO_TEST_SUITE_END() // Security
786
787} // namespace tests
788} // namespace validator_config
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400789} // inline namespace v2
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800790} // namespace security
791} // namespace ndn