blob: 49fdde2b73bf5e2d0ebe7f3c51c01ea5fea58187 [file] [log] [blame]
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento0c526032024-01-31 21:14:01 -05003 * Copyright (c) 2013-2024 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
Davide Pesavento49e1e872023-11-11 00:45:23 -050028#include <boost/mp11/list.hpp>
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080029
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040030namespace ndn::tests {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080031
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040032using namespace ndn::security::validator_config;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080033
34BOOST_AUTO_TEST_SUITE(Security)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080035BOOST_AUTO_TEST_SUITE(ValidatorConfig)
36
Eric Newberry17d7c472020-06-18 21:29:22 -070037template<class Packet>
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050038class RuleFixture : public KeyChainFixture
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080039{
40public:
41 RuleFixture()
Eric Newberry17d7c472020-06-18 21:29:22 -070042 : rule(ruleId, Packet::getType())
43 , pktName(Packet::makeName("/foo/bar", m_keyChain))
44 , state(Packet::makeState())
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080045 {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080046 }
47
48public:
49 const std::string ruleId = "rule-id";
50 Rule rule;
51 Name pktName;
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040052 shared_ptr<security::ValidationState> state;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080053};
54
Davide Pesavento49e1e872023-11-11 00:45:23 -050055using PktTypes = boost::mp11::mp_list<DataPkt, InterestV02Pkt, InterestV03Pkt>;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080056
57BOOST_AUTO_TEST_SUITE(TestRule)
58
Eric Newberry17d7c472020-06-18 21:29:22 -070059BOOST_FIXTURE_TEST_CASE(Errors, RuleFixture<DataPkt>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080060{
Eric Newberry17d7c472020-06-18 21:29:22 -070061 BOOST_CHECK_THROW(rule.match(tlv::Interest, this->pktName, state), Error);
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040062 BOOST_CHECK_THROW(rule.check(tlv::Interest, tlv::SignatureSha256WithRsa,
63 this->pktName, "/foo/bar", state), Error);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080064}
65
Eric Newberry17d7c472020-06-18 21:29:22 -070066BOOST_FIXTURE_TEST_CASE_TEMPLATE(Constructor, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080067{
68 BOOST_CHECK_EQUAL(this->rule.getId(), this->ruleId);
Eric Newberry17d7c472020-06-18 21:29:22 -070069 BOOST_CHECK_EQUAL(this->rule.getPktType(), PktType::getType());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080070}
71
Eric Newberry17d7c472020-06-18 21:29:22 -070072BOOST_FIXTURE_TEST_CASE_TEMPLATE(EmptyRule, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080073{
Eric Newberry17d7c472020-06-18 21:29:22 -070074 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040075 BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
76 this->pktName, "/foo/bar", this->state), false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080077}
78
Eric Newberry17d7c472020-06-18 21:29:22 -070079BOOST_FIXTURE_TEST_CASE_TEMPLATE(Filters, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080080{
81 this->rule.addFilter(make_unique<RegexNameFilter>(Regex("^<foo><bar>$")));
82
Eric Newberry17d7c472020-06-18 21:29:22 -070083 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
84 BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), "/not" + this->pktName.toUri(), this->state), false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080085
86 this->rule.addFilter(make_unique<RegexNameFilter>(Regex("^<not><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), true);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080090
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040091 BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
92 this->pktName, "/foo/bar", this->state), false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080093}
94
Eric Newberry17d7c472020-06-18 21:29:22 -070095BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checkers, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080096{
Junxiao Shi58b9e0f2021-03-18 15:54:07 -060097 auto testChecker = [this] (const Name& klName, bool expectedOutcome) {
Davide Pesavento0c526032024-01-31 21:14:01 -050098 BOOST_TEST_INFO_SCOPE("Name = " << klName);
99 BOOST_TEST_INFO_SCOPE("Expected = " << expectedOutcome);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800100
Davide Pesavento0c526032024-01-31 21:14:01 -0500101 this->state = PktType::makeState(); // reset state
102 BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
103 this->pktName, klName, this->state),
104 expectedOutcome);
105
106 auto outcome = this->state->getOutcome();
107 if (expectedOutcome) {
108 BOOST_CHECK(boost::logic::indeterminate(outcome));
109 }
110 else {
111 BOOST_CHECK(!boost::logic::indeterminate(outcome));
112 BOOST_CHECK(!bool(outcome));
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600113 }
114 };
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800115
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400116 this->rule.addChecker(make_unique<HyperRelationChecker>(tlv::SignatureSha256WithRsa,
117 "^(<>+)$", "\\1",
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600118 "^<always>(<>+)$", "\\1",
119 NameRelation::EQUAL));
120 testChecker("/always/foo/bar", true);
121 testChecker("/seldomly/foo/bar", false);
122 testChecker("/never/foo/bar", false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800123
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400124 this->rule.addChecker(make_unique<HyperRelationChecker>(tlv::SignatureSha256WithRsa,
125 "^(<>+)$", "\\1",
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600126 "^<seldomly>(<>+)$", "\\1",
127 NameRelation::EQUAL));
128 testChecker("/always/foo/bar", true);
129 testChecker("/seldomly/foo/bar", true);
130 testChecker("/never/foo/bar", false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800131}
132
133BOOST_AUTO_TEST_SUITE(Create)
134
135BOOST_AUTO_TEST_CASE(Errors)
136{
137 BOOST_CHECK_THROW(Rule::create(makeSection(""), "test-config"), Error);
138
139 std::string config = R"CONF(
140 id rule-id
141 for something
142 )CONF";
143 BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error);
144
145 config = R"CONF(
146 id rule-id
147 for data
148 )CONF";
149 BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error); // at least one checker required
150
151 config = R"CONF(
152 id rule-id
153 for data
154 checker
155 {
156 type hierarchical
157 sig-type rsa-sha256
158 }
159 other stuff
160 )CONF";
161 BOOST_CHECK_THROW(Rule::create(makeSection(config), "test-config"), Error);
162}
163
Eric Newberry17d7c472020-06-18 21:29:22 -0700164BOOST_FIXTURE_TEST_CASE_TEMPLATE(FilterAndChecker, PktType, PktTypes, RuleFixture<PktType>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800165{
Davide Pesaventodb4da5e2018-06-15 11:37:52 -0400166 std::string config = R"CONF(
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800167 id rule-id
Eric Newberry17d7c472020-06-18 21:29:22 -0700168 for )CONF" + (PktType::getType() == tlv::Data ? "data"s : "interest"s) + R"CONF(
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800169 filter
170 {
171 type name
172 regex ^<foo><bar>$
173 }
174 checker
175 {
176 type customized
177 sig-type rsa-sha256
178 key-locator
179 {
180 type name
181 hyper-relation
182 {
183 k-regex ^(<>+)$
184 k-expand \\1
185 h-relation equal
186 p-regex ^(<>+)$
187 p-expand \\1
188 }
189 }
190 }
191 )CONF";
192 auto rule = Rule::create(makeSection(config), "test-config");
193
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400194 BOOST_CHECK(rule->match(PktType::getType(), this->pktName, this->state));
195 BOOST_CHECK(!rule->match(PktType::getType(), "/not" + this->pktName.toUri(), this->state));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800196
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400197 BOOST_CHECK(rule->check(PktType::getType(), tlv::SignatureSha256WithRsa, this->pktName, "/foo/bar", this->state));
198 BOOST_CHECK(!rule->check(PktType::getType(), tlv::SignatureSha256WithEcdsa, this->pktName, "/foo/bar", this->state));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800199
Eric Newberry17d7c472020-06-18 21:29:22 -0700200 this->state = PktType::makeState(); // reset state
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400201 BOOST_CHECK(!rule->check(PktType::getType(), tlv::SignatureSha256WithRsa, this->pktName, "/not/foo/bar", this->state));
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800202}
203
204BOOST_AUTO_TEST_SUITE_END() // Create
205
206BOOST_AUTO_TEST_SUITE_END() // TestRule
207BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800208BOOST_AUTO_TEST_SUITE_END() // Security
209
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400210} // namespace ndn::tests