blob: 8b846ff732a2dd8e79908749eccff31e271a1846 [file] [log] [blame]
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Junxiao Shi58b9e0f2021-03-18 15:54:07 -06003 * 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/validator-config/rule.hpp"
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080023
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "tests/boost-test.hpp"
Alexander Afanasyev09236c22020-06-03 13:42:38 -040025#include "tests/unit/security/validator-fixture.hpp"
26#include "tests/unit/security/validator-config/common.hpp"
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080027
28#include <boost/mpl/vector_c.hpp>
29
30namespace ndn {
31namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040032inline namespace v2 {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080033namespace validator_config {
34namespace tests {
35
36using namespace ndn::tests;
37using namespace ndn::security::v2::tests;
38
39BOOST_AUTO_TEST_SUITE(Security)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080040BOOST_AUTO_TEST_SUITE(ValidatorConfig)
41
Eric Newberry17d7c472020-06-18 21:29:22 -070042template<class Packet>
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050043class RuleFixture : public KeyChainFixture
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080044{
45public:
46 RuleFixture()
Eric Newberry17d7c472020-06-18 21:29:22 -070047 : rule(ruleId, Packet::getType())
48 , pktName(Packet::makeName("/foo/bar", m_keyChain))
49 , state(Packet::makeState())
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080050 {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080051 }
52
53public:
54 const std::string ruleId = "rule-id";
55 Rule rule;
56 Name pktName;
Eric Newberry17d7c472020-06-18 21:29:22 -070057 shared_ptr<ValidationState> state;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080058};
59
Eric Newberry17d7c472020-06-18 21:29:22 -070060using PktTypes = boost::mpl::vector<DataPkt, InterestV02Pkt, InterestV03Pkt>;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080061
62BOOST_AUTO_TEST_SUITE(TestRule)
63
Eric Newberry17d7c472020-06-18 21:29:22 -070064BOOST_FIXTURE_TEST_CASE(Errors, RuleFixture<DataPkt>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080065{
Eric Newberry17d7c472020-06-18 21:29:22 -070066 BOOST_CHECK_THROW(rule.match(tlv::Interest, this->pktName, state), Error);
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040067 BOOST_CHECK_THROW(rule.check(tlv::Interest, tlv::SignatureSha256WithRsa,
68 this->pktName, "/foo/bar", state), Error);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080069}
70
Eric Newberry17d7c472020-06-18 21:29:22 -070071BOOST_FIXTURE_TEST_CASE_TEMPLATE(Constructor, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080072{
73 BOOST_CHECK_EQUAL(this->rule.getId(), this->ruleId);
Eric Newberry17d7c472020-06-18 21:29:22 -070074 BOOST_CHECK_EQUAL(this->rule.getPktType(), PktType::getType());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080075}
76
Eric Newberry17d7c472020-06-18 21:29:22 -070077BOOST_FIXTURE_TEST_CASE_TEMPLATE(EmptyRule, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080078{
Eric Newberry17d7c472020-06-18 21:29:22 -070079 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040080 BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
81 this->pktName, "/foo/bar", this->state), false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080082}
83
Eric Newberry17d7c472020-06-18 21:29:22 -070084BOOST_FIXTURE_TEST_CASE_TEMPLATE(Filters, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080085{
86 this->rule.addFilter(make_unique<RegexNameFilter>(Regex("^<foo><bar>$")));
87
Eric Newberry17d7c472020-06-18 21:29:22 -070088 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
89 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), "/not" + this->pktName.toUri(), this->state), false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080090
91 this->rule.addFilter(make_unique<RegexNameFilter>(Regex("^<not><foo><bar>$")));
92
Eric Newberry17d7c472020-06-18 21:29:22 -070093 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
94 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), "/not" + this->pktName.toUri(), this->state), true);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080095
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040096 BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
97 this->pktName, "/foo/bar", this->state), false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080098}
99
Eric Newberry17d7c472020-06-18 21:29:22 -0700100BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checkers, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800101{
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600102 auto testChecker = [this] (const Name& klName, bool expectedOutcome) {
103 BOOST_TEST_CONTEXT(klName << " expected=" << expectedOutcome) {
104 this->state = PktType::makeState(); // reset state
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400105 BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
106 this->pktName, klName, this->state),
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600107 expectedOutcome);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800108
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600109 auto outcome = this->state->getOutcome();
110 if (expectedOutcome) {
111 BOOST_CHECK(boost::logic::indeterminate(outcome));
112 }
113 else {
114 BOOST_CHECK(!boost::logic::indeterminate(outcome));
115 BOOST_CHECK(!bool(outcome));
116 }
117 }
118 };
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800119
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400120 this->rule.addChecker(make_unique<HyperRelationChecker>(tlv::SignatureSha256WithRsa,
121 "^(<>+)$", "\\1",
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600122 "^<always>(<>+)$", "\\1",
123 NameRelation::EQUAL));
124 testChecker("/always/foo/bar", true);
125 testChecker("/seldomly/foo/bar", false);
126 testChecker("/never/foo/bar", false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800127
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400128 this->rule.addChecker(make_unique<HyperRelationChecker>(tlv::SignatureSha256WithRsa,
129 "^(<>+)$", "\\1",
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600130 "^<seldomly>(<>+)$", "\\1",
131 NameRelation::EQUAL));
132 testChecker("/always/foo/bar", true);
133 testChecker("/seldomly/foo/bar", true);
134 testChecker("/never/foo/bar", false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800135}
136
137BOOST_AUTO_TEST_SUITE(Create)
138
139BOOST_AUTO_TEST_CASE(Errors)
140{
141 BOOST_CHECK_THROW(Rule::create(makeSection(""), "test-config"), Error);
142
143 std::string config = R"CONF(
144 id rule-id
145 for something
146 )CONF";
147 BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error);
148
149 config = R"CONF(
150 id rule-id
151 for data
152 )CONF";
153 BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error); // at least one checker required
154
155 config = R"CONF(
156 id rule-id
157 for data
158 checker
159 {
160 type hierarchical
161 sig-type rsa-sha256
162 }
163 other stuff
164 )CONF";
165 BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error);
166}
167
Eric Newberry17d7c472020-06-18 21:29:22 -0700168BOOST_FIXTURE_TEST_CASE_TEMPLATE(FilterAndChecker, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800169{
Davide Pesaventodb4da5e2018-06-15 11:37:52 -0400170 std::string config = R"CONF(
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800171 id rule-id
Eric Newberry17d7c472020-06-18 21:29:22 -0700172 for )CONF" + (PktType::getType() == tlv::Data ? "data"s : "interest"s) + R"CONF(
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800173 filter
174 {
175 type name
176 regex ^<foo><bar>$
177 }
178 checker
179 {
180 type customized
181 sig-type rsa-sha256
182 key-locator
183 {
184 type name
185 hyper-relation
186 {
187 k-regex ^(<>+)$
188 k-expand \\1
189 h-relation equal
190 p-regex ^(<>+)$
191 p-expand \\1
192 }
193 }
194 }
195 )CONF";
196 auto rule = Rule::create(makeSection(config), "test-config");
197
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400198 BOOST_CHECK(rule->match(PktType::getType(), this->pktName, this->state));
199 BOOST_CHECK(!rule->match(PktType::getType(), "/not" + this->pktName.toUri(), this->state));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800200
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400201 BOOST_CHECK(rule->check(PktType::getType(), tlv::SignatureSha256WithRsa, this->pktName, "/foo/bar", this->state));
202 BOOST_CHECK(!rule->check(PktType::getType(), tlv::SignatureSha256WithEcdsa, this->pktName, "/foo/bar", this->state));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800203
Eric Newberry17d7c472020-06-18 21:29:22 -0700204 this->state = PktType::makeState(); // reset state
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400205 BOOST_CHECK(!rule->check(PktType::getType(), tlv::SignatureSha256WithRsa, this->pktName, "/not/foo/bar", this->state));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800206}
207
208BOOST_AUTO_TEST_SUITE_END() // Create
209
210BOOST_AUTO_TEST_SUITE_END() // TestRule
211BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800212BOOST_AUTO_TEST_SUITE_END() // Security
213
214} // namespace tests
215} // namespace validator_config
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400216} // inline namespace v2
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800217} // namespace security
218} // namespace ndn