blob: 83de50e01a630419bbf1c21a1e3d6fa3361d9191 [file] [log] [blame]
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Justin Labryaef53b62021-03-10 06:07:27 +00003 * Copyright (c) 2013-2021 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");
Eric Newberryb74bbda2020-06-18 19:33:58 -070059 i.setCanBePrefix(false);
Davide Pesavento0a6456c2019-11-14 00:33:11 -050060 this->m_keyChain.sign(i, signingByIdentity(this->identity));
61 VALIDATE_FAILURE(i, "Empty policy should reject everything");
62}
63
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080064template<typename Packet>
65class PacketName;
66
67template<>
68class PacketName<Interest>
69{
70public:
71 static std::string
72 getName()
73 {
74 return "interest";
75 }
76};
77
78template<>
79class PacketName<Data>
80{
81public:
82 static std::string
83 getName()
84 {
85 return "data";
86 }
87};
88
89template<typename PacketType>
90class ValidationPolicyConfigFixture : public HierarchicalValidatorFixture<ValidationPolicyConfig>
91{
92public:
93 ValidationPolicyConfigFixture()
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050094 : path(boost::filesystem::path(UNIT_TESTS_TMPDIR) / "security" / "validation-policy-config")
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080095 {
96 boost::filesystem::create_directories(path);
97 baseConfig = R"CONF(
98 rule
99 {
100 id test-rule-id
101 for )CONF" + PacketName<Packet>::getName() + R"CONF(
102 filter
103 {
104 type name
105 name )CONF" + identity.getName().toUri() + R"CONF(
106 relation is-prefix-of
107 }
108 checker
109 {
110 type hierarchical
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400111 sig-type ecdsa-sha256
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800112 }
113 }
114 )CONF";
115 }
116
117 ~ValidationPolicyConfigFixture()
118 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500119 boost::filesystem::remove_all(path);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800120 }
121
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500122protected:
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800123 using Packet = PacketType;
124
125 const boost::filesystem::path path;
126 std::string baseConfig;
127};
128
129template<typename PacketType>
130class LoadStringWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
131{
132public:
133 LoadStringWithFileAnchor()
134 {
135 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
136
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500137 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800138 this->policy.load(this->baseConfig + R"CONF(
139 trust-anchor
140 {
141 type file
142 file-name "trust-anchor.ndncert"
143 }
144 )CONF", (this->path / "test-config").string());
145
146 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
147 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
148 }
149};
150
151template<typename PacketType>
152class LoadFileWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
153{
154public:
155 LoadFileWithFileAnchor()
156 {
157 std::string configFile = (this->path / "config.conf").string();
158 {
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500159 std::ofstream config(configFile);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800160 config << this->baseConfig << R"CONF(
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500161 trust-anchor
162 {
163 type file
164 file-name "trust-anchor.ndncert"
165 }
166 )CONF";
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800167 }
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500168
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500169 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800170
171 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
172
173 this->policy.load(configFile);
174
175 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
176 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
177 }
178};
179
180template<typename PacketType>
Varun Patil574c3f92020-11-25 09:07:33 +0530181class LoadFileWithMultipleFileAnchors : public ValidationPolicyConfigFixture<PacketType>
182{
183public:
184 LoadFileWithMultipleFileAnchors()
185 {
186 std::string configFile = (this->path / "config.conf").string();
187 {
188 std::ofstream config(configFile);
189 config << this->baseConfig << R"CONF(
190 trust-anchor
191 {
192 type file
193 file-name "identity.ndncert"
194 }
195 trust-anchor
196 {
197 type file
198 file-name "trust-anchor.ndncert"
199 }
200 )CONF";
201 }
202
203 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
204
205 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
206
207 this->policy.load(configFile);
208
209 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
210 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
211 }
212};
213
214template<typename PacketType>
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800215class LoadSectionWithFileAnchor : public ValidationPolicyConfigFixture<PacketType>
216{
217public:
218 LoadSectionWithFileAnchor()
219 {
220 auto section = makeSection(this->baseConfig + R"CONF(
221 trust-anchor
222 {
223 type file
224 file-name "trust-anchor.ndncert"
225 }
226 )CONF");
227
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500228 this->saveIdentityCert(this->identity, (this->path / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800229
230 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
231
232 this->policy.load(section, (this->path / "test-config").string());
233
234 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
235 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
236 }
237};
238
239template<typename PacketType>
240class LoadStringWithBase64Anchor : public ValidationPolicyConfigFixture<PacketType>
241{
242public:
243 LoadStringWithBase64Anchor()
244 {
245 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
246
247 std::ostringstream os;
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500248 {
249 using namespace ndn::security::transform;
250 const auto& cert = this->identity.getDefaultKey().getDefaultCertificate().wireEncode();
Davide Pesavento765abc92021-12-27 00:44:04 -0500251 bufferSource(make_span(cert.wire(), cert.size())) >> base64Encode(false) >> streamSink(os);
Davide Pesavento0a6456c2019-11-14 00:33:11 -0500252 }
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800253
254 this->policy.load(this->baseConfig + R"CONF(
255 trust-anchor
256 {
257 type base64
258 base64-string ")CONF" + os.str() + R"CONF("
259 }
260 )CONF", (this->path / "test-config").string());
261
262 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
263 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
264 }
265};
266
267class NoRefresh
268{
269public:
270 static std::string
271 getRefreshString()
272 {
273 return "";
274 }
275};
276
277class Refresh1h
278{
279public:
280 static std::string
281 getRefreshString()
282 {
283 return "refresh 1h";
284 }
285
286 static time::milliseconds
287 getRefreshTime()
288 {
Davide Pesavento0f830802018-01-16 23:58:58 -0500289 return 1_h;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800290 }
291};
292
293class Refresh1m
294{
295public:
296 static std::string
297 getRefreshString()
298 {
299 return "refresh 1m";
300 }
301
302 static time::milliseconds
303 getRefreshTime()
304 {
Davide Pesavento0f830802018-01-16 23:58:58 -0500305 return 1_min;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800306 }
307};
308
309class Refresh1s
310{
311public:
312 static std::string
313 getRefreshString()
314 {
315 return "refresh 1s";
316 }
317
318 static time::milliseconds
319 getRefreshTime()
320 {
Davide Pesavento0f830802018-01-16 23:58:58 -0500321 return 1_s;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800322 }
323};
324
325template<typename PacketType, typename Refresh = NoRefresh>
326class LoadStringWithDirAnchor : public ValidationPolicyConfigFixture<PacketType>
327{
328public:
329 LoadStringWithDirAnchor()
330 {
331 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
332
333 boost::filesystem::create_directories(this->path / "keys");
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500334 this->saveIdentityCert(this->identity, (this->path / "keys" / "identity.ndncert").string());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800335
336 this->policy.load(this->baseConfig + R"CONF(
337 trust-anchor
338 {
339 type dir
340 dir keys
341 )CONF" + Refresh::getRefreshString() + R"CONF(
342 }
343 )CONF", (this->path / "test-config").string());
344
345 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
346 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
347 }
348};
349
350using DataPolicies = boost::mpl::vector<LoadStringWithFileAnchor<Data>,
351 LoadFileWithFileAnchor<Data>,
Varun Patil574c3f92020-11-25 09:07:33 +0530352 LoadFileWithMultipleFileAnchors<Data>,
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800353 LoadSectionWithFileAnchor<Data>,
354 LoadStringWithBase64Anchor<Data>,
355 LoadStringWithDirAnchor<Data>,
356 LoadStringWithDirAnchor<Data, Refresh1h>,
357 LoadStringWithDirAnchor<Data, Refresh1m>,
358 LoadStringWithDirAnchor<Data, Refresh1s>
359 >;
360
361using InterestPolicies = boost::mpl::vector<LoadStringWithFileAnchor<Interest>,
362 LoadFileWithFileAnchor<Interest>,
Varun Patil574c3f92020-11-25 09:07:33 +0530363 LoadFileWithMultipleFileAnchors<Interest>,
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800364 LoadSectionWithFileAnchor<Interest>,
365 LoadStringWithBase64Anchor<Interest>,
366 LoadStringWithDirAnchor<Interest>,
367 LoadStringWithDirAnchor<Interest, Refresh1h>,
368 LoadStringWithDirAnchor<Interest, Refresh1m>,
369 LoadStringWithDirAnchor<Interest, Refresh1s>
370 >;
371
372BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateData, Policy, DataPolicies, Policy)
373{
374 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 1);
375 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
376
377 using Packet = typename Policy::Packet;
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400378 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800379
380 Packet packet = unsignedPacket;
381 VALIDATE_FAILURE(packet, "Unsigned");
382
383 packet = unsignedPacket;
384 this->m_keyChain.sign(packet, signingWithSha256());
Justin Labryaef53b62021-03-10 06:07:27 +0000385 VALIDATE_FAILURE(packet, "Should not be accepted, doesn't pass checker /localhost/identity/digest-sha256");
386
387 packet = Packet("/localhost/identity/digest-sha256/foobar");
388 this->m_keyChain.sign(packet, signingWithSha256());
389 VALIDATE_FAILURE(packet, "Should not be accepted, no rule for the name /localhost/identity/digest-sha256");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800390
391 packet = unsignedPacket;
392 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
393 VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");
394
395 packet = unsignedPacket;
396 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
397 VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the policy-compliant cert");
398
399 packet = unsignedPacket;
400 this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
401 VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
402
403 packet = unsignedPacket;
404 this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
405 VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
406}
407
408BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateInterest, Policy, InterestPolicies, Policy)
409{
410 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
411 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 1);
412
413 using Packet = typename Policy::Packet;
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400414 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Eric Newberryb74bbda2020-06-18 19:33:58 -0700415 // All of the packet types inputed to this test case template are Interests, so we can call
416 // setCanBePrefix
417 unsignedPacket.setCanBePrefix(false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800418
419 Packet packet = unsignedPacket;
420 VALIDATE_FAILURE(packet, "Unsigned");
421
422 packet = unsignedPacket;
423 this->m_keyChain.sign(packet, signingWithSha256());
Justin Labryaef53b62021-03-10 06:07:27 +0000424 VALIDATE_FAILURE(packet, "Should not be accepted, doesn't pass checker /localhost/identity/digest-sha256");
425
426 packet = Packet("/localhost/identity/digest-sha256/foobar");
427 this->m_keyChain.sign(packet, signingWithSha256());
428 VALIDATE_FAILURE(packet, "Should not be accepted, no rule for the name /localhost/identity/digest-sha256");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800429
430 packet = unsignedPacket;
431 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
432 VALIDATE_SUCCESS(packet, "Should get accepted, as signed by the anchor");
433
434 packet = unsignedPacket;
435 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
436 VALIDATE_FAILURE(packet, "Should fail, as there is no matching rule for data");
437
438 packet = unsignedPacket;
439 this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
440 VALIDATE_FAILURE(packet, "Should fail, as signed by the policy-violating cert");
441
442 packet = unsignedPacket;
443 this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
444 VALIDATE_FAILURE(packet, "Should fail, because subSelfSignedIdentity is not a trust anchor");
445}
446
Justin Labryaef53b62021-03-10 06:07:27 +0000447BOOST_FIXTURE_TEST_CASE(DigestSha256, HierarchicalValidatorFixture<ValidationPolicyConfig>)
448{
449 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
450 this->policy.load(R"CONF(
451 rule
452 {
453 id test-rule-data-id
454 for data
455 filter
456 {
457 type name
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400458 name /Security/ValidatorFixture
459 relation is-prefix-of
460 }
461 checker
462 {
463 type customized
464 sig-type sha256
465 }
466 }
467 rule
468 {
469 id test-rule-interest-id
470 for interest
471 filter
472 {
473 type name
474 name /Security/ValidatorFixture
475 relation is-prefix-of
476 }
477 checker
478 {
479 type customized
480 sig-type sha256
481 }
482 }
483 )CONF", "test-config");
484
485
486 Interest interest("/Security/ValidatorFixture/Sub1/Sub2/Packet");
487 interest.setCanBePrefix(false);
488 this->m_keyChain.sign(interest, signingWithSha256());
489 VALIDATE_SUCCESS(interest, "Should be accepted");
490
491 Data data("/Security/ValidatorFixture/Sub1/Sub2/Packet");
492 this->m_keyChain.sign(data, signingWithSha256());
493 VALIDATE_SUCCESS(data, "Should be accepted");
494}
495
496BOOST_FIXTURE_TEST_CASE(DigestSha256WithKeyLocator, HierarchicalValidatorFixture<ValidationPolicyConfig>)
497{
498 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
499 this->policy.load(R"CONF(
500 rule
501 {
502 id test-rule-data-id
503 for data
504 filter
505 {
506 type name
Justin Labryaef53b62021-03-10 06:07:27 +0000507 name /localhost/identity/digest-sha256
508 relation is-prefix-of
509 }
510 checker
511 {
512 type customized
513 sig-type sha256
514 key-locator
515 {
516 type name
517 hyper-relation
518 {
519 k-regex ^(<>*)$
520 k-expand \\1
521 h-relation is-prefix-of
522 p-regex ^(<>*)$
523 p-expand \\1
524 }
525 }
526 }
527 }
528 rule
529 {
530 id test-rule-interest-id
531 for interest
532 filter
533 {
534 type name
535 name /localhost/identity/digest-sha256
536 relation is-prefix-of
537 }
538 checker
539 {
540 type customized
541 sig-type sha256
542 key-locator
543 {
544 type name
545 hyper-relation
546 {
547 k-regex ^(<>*)$
548 k-expand \\1
549 h-relation is-prefix-of
550 p-regex ^(<>*)$
551 p-expand \\1
552 }
553 }
554 }
555 }
556 )CONF", "test-config");
557
558
559 Interest interest("/localhost/identity/digest-sha256/foobar");
560 interest.setCanBePrefix(false);
561 this->m_keyChain.sign(interest, signingWithSha256());
562 VALIDATE_SUCCESS(interest, "Should be accepted");
563
564 Data data("/localhost/identity/digest-sha256/foobar");
565 this->m_keyChain.sign(data, signingWithSha256());
566 VALIDATE_SUCCESS(data, "Should be accepted");
567}
568
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400569BOOST_FIXTURE_TEST_CASE(SigTypeCheck, HierarchicalValidatorFixture<ValidationPolicyConfig>)
570{
571 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
572 this->policy.load(R"CONF(
573 rule
574 {
575 id test-rule-data-id
576 for data
577 filter
578 {
579 type name
580 name /localhost/identity/digest-sha256
581 relation is-prefix-of
582 }
583 checker
584 {
585 type customized
586 sig-type ecdsa-sha256
587 key-locator
588 {
589 type name
590 hyper-relation
591 {
592 k-regex ^(<>*)$
593 k-expand \\1
594 h-relation is-prefix-of
595 p-regex ^(<>*)$
596 p-expand \\1
597 }
598 }
599 }
600 }
601 rule
602 {
603 id test-rule-interest-id
604 for interest
605 filter
606 {
607 type name
608 name /localhost/identity/digest-sha256
609 relation is-prefix-of
610 }
611 checker
612 {
613 type customized
614 sig-type ecdsa-sha256
615 key-locator
616 {
617 type name
618 hyper-relation
619 {
620 k-regex ^(<>*)$
621 k-expand \\1
622 h-relation is-prefix-of
623 p-regex ^(<>*)$
624 p-expand \\1
625 }
626 }
627 }
628 }
629 )CONF", "test-config");
630
631
632 Interest interest("/localhost/identity/digest-sha256/foobar");
633 interest.setCanBePrefix(false);
634 this->m_keyChain.sign(interest, signingWithSha256());
635 VALIDATE_FAILURE(interest, "Signature type check should fail");
636
637 Data data("/localhost/identity/digest-sha256/foobar");
638 this->m_keyChain.sign(data, signingWithSha256());
639 VALIDATE_FAILURE(data, "Signature type check should fail");
640}
641
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400642BOOST_FIXTURE_TEST_CASE(Reload, HierarchicalValidatorFixture<ValidationPolicyConfig>)
643{
644 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
645 this->policy.load(R"CONF(
646 rule
647 {
648 id test-rule-data-id
649 for data
650 filter
651 {
652 type name
653 name /foo/bar
654 relation is-prefix-of
655 }
656 checker
657 {
658 type hierarchical
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400659 sig-type ecdsa-sha256
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400660 }
661 }
662 rule
663 {
664 id test-rule-interest-id
665 for interest
666 filter
667 {
668 type name
669 name /foo/bar
670 relation is-prefix-of
671 }
672 checker
673 {
674 type hierarchical
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400675 sig-type ecdsa-sha256
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400676 }
677 }
678 trust-anchor
679 {
680 type dir
681 dir keys
682 refresh 1h
683 }
684 )CONF", "test-config");
685 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
686 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, false);
687 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 1);
688 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 1);
689
690 this->policy.load(R"CONF(
691 trust-anchor
692 {
693 type any
694 }
695 )CONF", "test-config");
696 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
697 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, true);
698 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
699 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
700}
701
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800702using Packets = boost::mpl::vector<Interest, Data>;
703
704BOOST_FIXTURE_TEST_CASE_TEMPLATE(TrustAnchorWildcard, Packet, Packets, ValidationPolicyConfigFixture<Packet>)
705{
706 this->policy.load(R"CONF(
707 trust-anchor
708 {
709 type any
710 }
711 )CONF", "test-config");
712
713 BOOST_CHECK_EQUAL(this->policy.m_isConfigured, true);
714 BOOST_CHECK_EQUAL(this->policy.m_shouldBypass, true);
715 BOOST_CHECK_EQUAL(this->policy.m_dataRules.size(), 0);
716 BOOST_CHECK_EQUAL(this->policy.m_interestRules.size(), 0);
717
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400718 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800719
720 Packet packet = unsignedPacket;
721 VALIDATE_SUCCESS(packet, "Policy should accept everything");
722
723 packet = unsignedPacket;
724 this->m_keyChain.sign(packet, signingWithSha256());
725 VALIDATE_SUCCESS(packet, "Policy should accept everything");
726
727 packet = unsignedPacket;
728 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
729 VALIDATE_SUCCESS(packet, "Policy should accept everything");
730
731 packet = unsignedPacket;
732 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
733 VALIDATE_SUCCESS(packet, "Policy should accept everything");
734
735 packet = unsignedPacket;
736 this->m_keyChain.sign(packet, signingByIdentity(this->otherIdentity));
737 VALIDATE_SUCCESS(packet, "Policy should accept everything");
738
739 packet = unsignedPacket;
740 this->m_keyChain.sign(packet, signingByIdentity(this->subSelfSignedIdentity));
741 VALIDATE_SUCCESS(packet, "Policy should accept everything");
742}
743
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400744using RefreshPolicies = boost::mpl::vector<Refresh1h, Refresh1m, Refresh1s>;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800745
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400746template<typename RefreshPolicy>
747class RefreshPolicyFixture : public LoadStringWithDirAnchor<Data, RefreshPolicy>
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800748{
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800749};
750
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400751BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateRefresh, Refresh, RefreshPolicies, RefreshPolicyFixture<Refresh>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800752{
753 using Packet = Data;
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400754 Packet unsignedPacket("/Security/ValidatorFixture/Sub1/Sub2/Packet");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800755
756 boost::filesystem::remove(this->path / "keys" / "identity.ndncert");
Alexander Afanasyev6aff0242017-08-29 17:14:44 -0400757 this->advanceClocks(Refresh::getRefreshTime(), 3);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800758
759 Packet packet = unsignedPacket;
760 this->m_keyChain.sign(packet, signingByIdentity(this->identity));
761 VALIDATE_FAILURE(packet, "Should fail, as the trust anchor should no longer exist");
762
763 packet = unsignedPacket;
764 this->m_keyChain.sign(packet, signingByIdentity(this->subIdentity));
765 VALIDATE_FAILURE(packet, "Should fail, as the trust anchor should no longer exist");
766}
767
Alexander Afanasyev7b112462018-10-17 11:51:52 -0400768BOOST_FIXTURE_TEST_CASE(OrphanedPolicyLoad, HierarchicalValidatorFixture<ValidationPolicyConfig>) // Bug #4758
769{
770 ValidationPolicyConfig policy1;
771 BOOST_CHECK_THROW(policy1.load("trust-anchor { type any }", "test-config"), Error);
772
773 // Reloading would have triggered a segfault
774 BOOST_CHECK_THROW(policy1.load("trust-anchor { type any }", "test-config"), Error);
775
776 ValidationPolicyConfig policy2;
777
778 std::string config = R"CONF(
779 trust-anchor
780 {
781 type dir
782 dir keys
783 refresh 1h
784 }
785 )CONF";
786
787 // Inserting trust anchor would have triggered a segfault
788 BOOST_CHECK_THROW(policy2.load(config, "test-config"), Error);
789}
790
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800791BOOST_AUTO_TEST_SUITE_END() // TestValidationPolicyConfig
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800792BOOST_AUTO_TEST_SUITE_END() // Security
793
794} // namespace tests
795} // namespace validator_config
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400796} // inline namespace v2
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800797} // namespace security
798} // namespace ndn