blob: e340b265a63df592df61bd708245c882277edd81 [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/checker.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/algorithm.hpp>
29
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)
Junxiao Shi5dc75602021-02-19 11:33:00 -070036BOOST_AUTO_TEST_SUITE(TestChecker)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080037
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050038class CheckerFixture : public KeyChainFixture
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080039{
40public:
41 CheckerFixture()
42 {
Davide Pesavento334516a2024-02-09 18:02:36 -050043 names.emplace_back("/foo/bar");
44 names.emplace_back("/foo/bar/bar");
45 names.emplace_back("/foo");
46 names.emplace_back("/other/prefix");
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080047 }
48
Davide Pesavento5437aa22019-03-24 14:02:37 -040049 static Name
Junxiao Shi5dc75602021-02-19 11:33:00 -070050 makeKeyLocatorKeyName(const Name& name)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080051 {
Junxiao Shi5dc75602021-02-19 11:33:00 -070052 static PartialName suffix("KEY/keyid");
53 return Name(name).append(suffix);
54 }
55
56 static Name
57 makeKeyLocatorCertName(const Name& name)
58 {
59 static PartialName suffix("KEY/keyid/issuer/v=1");
60 return Name(name).append(suffix);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080061 }
62
63public:
64 std::vector<Name> names;
65};
66
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080067class NameRelationEqual : public CheckerFixture
68{
69public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040070 NameRelationChecker checker{tlv::SignatureSha256WithRsa, "/foo/bar", NameRelation::EQUAL};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080071 std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
72 {true, false, false, false},
73 {true, false, false, false},
74 {true, false, false, false}};
75};
76
77class NameRelationIsPrefixOf : public CheckerFixture
78{
79public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040080 NameRelationChecker checker{tlv::SignatureSha256WithRsa, "/foo/bar", NameRelation::IS_PREFIX_OF};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080081 std::vector<std::vector<bool>> outcomes = {{true, true, false, false},
82 {true, true, false, false},
83 {true, true, false, false},
84 {true, true, false, false}};
85};
86
87class NameRelationIsStrictPrefixOf : public CheckerFixture
88{
89public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -040090 NameRelationChecker checker{tlv::SignatureSha256WithRsa, "/foo/bar", NameRelation::IS_STRICT_PREFIX_OF};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080091 std::vector<std::vector<bool>> outcomes = {{false, true, false, false},
92 {false, true, false, false},
93 {false, true, false, false},
94 {false, true, false, false}};
95};
96
97class RegexEqual : public CheckerFixture
98{
99public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400100 RegexChecker checker{tlv::SignatureSha256WithRsa, Regex("^<foo><bar><KEY><>{1,3}$")};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800101 std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
102 {true, false, false, false},
103 {true, false, false, false},
104 {true, false, false, false}};
105};
106
107class RegexIsPrefixOf : public CheckerFixture
108{
109public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400110 RegexChecker checker{tlv::SignatureSha256WithRsa, Regex("^<foo><bar><>*<KEY><>{1,3}$")};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800111 std::vector<std::vector<bool>> outcomes = {{true, true, false, false},
112 {true, true, false, false},
113 {true, true, false, false},
114 {true, true, false, false}};
115};
116
117class RegexIsStrictPrefixOf : public CheckerFixture
118{
119public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400120 RegexChecker checker{tlv::SignatureSha256WithRsa, Regex("^<foo><bar><>+<KEY><>{1,3}$")};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800121 std::vector<std::vector<bool>> outcomes = {{false, true, false, false},
122 {false, true, false, false},
123 {false, true, false, false},
124 {false, true, false, false}};
125};
126
127class HyperRelationEqual : public CheckerFixture
128{
129public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400130 HyperRelationChecker checker{tlv::SignatureSha256WithRsa,
131 "^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::EQUAL};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800132 std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
133 {false, true, false, false},
134 {false, false, true, false},
135 {false, false, false, true}};
136};
137
138class HyperRelationIsPrefixOf : public CheckerFixture
139{
140public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400141 HyperRelationChecker checker{tlv::SignatureSha256WithRsa,
142 "^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::IS_PREFIX_OF};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800143 std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
144 {true, true, true, false},
145 {false, false, true, false},
146 {false, false, false, true}};
147};
148
149class HyperRelationIsStrictPrefixOf : public CheckerFixture
150{
151public:
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400152 HyperRelationChecker checker{tlv::SignatureSha256WithRsa,
153 "^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::IS_STRICT_PREFIX_OF};
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800154 std::vector<std::vector<bool>> outcomes = {{false, false, true, false},
155 {true, false, true, false},
156 {false, false, false, false},
157 {false, false, false, false}};
158};
159
160class Hierarchical : public CheckerFixture
161{
162public:
163 Hierarchical()
164 : checkerPtr(Checker::create(makeSection(R"CONF(
165 type hierarchical
166 sig-type rsa-sha256
167 )CONF"), "test-config"))
168 , checker(*checkerPtr)
169 {
170 }
171
172public:
173 std::unique_ptr<Checker> checkerPtr;
174 Checker& checker;
175
176 std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
177 {true, true, true, false},
178 {false, false, true, false},
179 {false, false, false, true}};
180};
181
182class CustomizedNameRelation : public CheckerFixture
183{
184public:
185 CustomizedNameRelation()
186 : checkerPtr(Checker::create(makeSection(R"CONF(
187 type customized
188 sig-type rsa-sha256
189 key-locator
190 {
191 type name
192 name /foo/bar
193 relation equal
194 }
195 )CONF"), "test-config"))
196 , checker(*checkerPtr)
197 {
198 }
199
200public:
201 std::unique_ptr<Checker> checkerPtr;
202 Checker& checker;
203
204 std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
205 {true, false, false, false},
206 {true, false, false, false},
207 {true, false, false, false}};
208};
209
210class CustomizedRegex : public CheckerFixture
211{
212public:
213 CustomizedRegex()
214 : checkerPtr(Checker::create(makeSection(R"CONF(
215 type customized
216 sig-type rsa-sha256
217 key-locator
218 {
219 type name
Junxiao Shi5dc75602021-02-19 11:33:00 -0700220 regex ^<foo><bar><KEY><>{1,3}$
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800221 }
222 )CONF"), "test-config"))
223 , checker(*checkerPtr)
224 {
225 }
226
227public:
228 std::unique_ptr<Checker> checkerPtr;
229 Checker& checker;
230
231 std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
232 {true, false, false, false},
233 {true, false, false, false},
234 {true, false, false, false}};
235};
236
237class CustomizedHyperRelation : public CheckerFixture
238{
239public:
240 CustomizedHyperRelation()
241 : checkerPtr(Checker::create(makeSection(R"CONF(
242 type customized
243 sig-type rsa-sha256
244 key-locator
245 {
246 type name
247 hyper-relation
248 {
Junxiao Shi5dc75602021-02-19 11:33:00 -0700249 k-regex ^(<>+)<KEY><>{1,3}$
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800250 k-expand \\1
251 h-relation is-prefix-of
252 p-regex ^(<>+)$
253 p-expand \\1
254 }
255 }
256 )CONF"), "test-config"))
257 , checker(*checkerPtr)
258 {
259 }
260
261public:
262 std::unique_ptr<Checker> checkerPtr;
263 Checker& checker;
264
265 std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
266 {true, true, true, false},
267 {false, false, true, false},
268 {false, false, false, true}};
269};
270
Davide Pesavento49e1e872023-11-11 00:45:23 -0500271using CheckerFixtures = boost::mp11::mp_list<
Junxiao Shi5dc75602021-02-19 11:33:00 -0700272 NameRelationEqual,
273 NameRelationIsPrefixOf,
274 NameRelationIsStrictPrefixOf,
275 RegexEqual,
276 RegexIsPrefixOf,
277 RegexIsStrictPrefixOf,
278 HyperRelationEqual,
279 HyperRelationIsPrefixOf,
280 HyperRelationIsStrictPrefixOf,
281 Hierarchical,
282 CustomizedNameRelation,
283 CustomizedRegex,
284 CustomizedHyperRelation
285>;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800286
Junxiao Shi5dc75602021-02-19 11:33:00 -0700287// Cartesian product of [DataPkt, InterestV02Pkt, InterestV03Pkt] and CheckerFixtures.
Davide Pesavento49e1e872023-11-11 00:45:23 -0500288// Each element is an mp_list<PktType, Fixture>.
289using Tests = boost::mp11::mp_product<
290 boost::mp11::mp_list,
291 boost::mp11::mp_list<DataPkt, InterestV02Pkt, InterestV03Pkt>,
292 CheckerFixtures
293>;
Junxiao Shi5dc75602021-02-19 11:33:00 -0700294
Davide Pesavento334516a2024-02-09 18:02:36 -0500295template<typename PktType, typename C>
296static void
297testChecker(C& checker, tlv::SignatureTypeValue sigType, const Name& pktName, const Name& klName, bool expectedOutcome)
298{
299 BOOST_TEST_INFO_SCOPE("Packet = " << pktName);
300 BOOST_TEST_INFO_SCOPE("SignatureType = " << sigType);
301 BOOST_TEST_INFO_SCOPE("KeyLocator = " << klName);
302
303 auto state = PktType::makeState();
304 auto result = checker.check(PktType::getType(), sigType, pktName, klName, *state);
305 BOOST_TEST(bool(result) == expectedOutcome);
306 BOOST_TEST(boost::logic::indeterminate(state->getOutcome()));
307 if (!result) {
308 BOOST_TEST(!result.getErrorMessage().empty());
309 }
310}
311
Davide Pesavento49e1e872023-11-11 00:45:23 -0500312BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checks, T, Tests, boost::mp11::mp_second<T>)
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800313{
Davide Pesavento49e1e872023-11-11 00:45:23 -0500314 using PktType = boost::mp11::mp_first<T>;
Davide Pesavento5437aa22019-03-24 14:02:37 -0400315
316 BOOST_REQUIRE_EQUAL(this->outcomes.size(), this->names.size());
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800317 for (size_t i = 0; i < this->names.size(); ++i) {
Davide Pesavento5437aa22019-03-24 14:02:37 -0400318 BOOST_REQUIRE_EQUAL(this->outcomes[i].size(), this->names.size());
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600319
320 auto pktName = PktType::makeName(this->names[i], this->m_keyChain);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800321 for (size_t j = 0; j < this->names.size(); ++j) {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800322 bool expectedOutcome = this->outcomes[i][j];
323
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600324 auto klName = this->makeKeyLocatorKeyName(this->names[j]);
Davide Pesavento334516a2024-02-09 18:02:36 -0500325 testChecker<PktType>(this->checker, tlv::SignatureSha256WithRsa, pktName, klName, expectedOutcome);
326 testChecker<PktType>(this->checker, tlv::SignatureSha256WithEcdsa, pktName, klName, false);
Alexander Afanasyev17d4b932021-03-17 17:58:40 -0400327
Junxiao Shi58b9e0f2021-03-18 15:54:07 -0600328 klName = this->makeKeyLocatorCertName(this->names[j]);
Davide Pesavento334516a2024-02-09 18:02:36 -0500329 testChecker<PktType>(this->checker, tlv::SignatureSha256WithRsa, pktName, klName, expectedOutcome);
330 testChecker<PktType>(this->checker, tlv::SignatureSha256WithEcdsa, pktName, klName, false);
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800331 }
332 }
333}
334
335BOOST_AUTO_TEST_SUITE_END() // TestChecker
336BOOST_AUTO_TEST_SUITE_END() // ValidatorConfig
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800337BOOST_AUTO_TEST_SUITE_END() // Security
338
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400339} // namespace ndn::tests