blob: 39e4ed36dae2fd19a4ab7d367a2186dc84ab479f [file] [log] [blame]
Alexander Afanasyev7e721412017-01-11 13:36:08 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -08002/*
Davide Pesaventof6b45892023-03-13 15:00:51 -04003 * Copyright (c) 2013-2023 Regents of the University of California.
Alexander Afanasyev7e721412017-01-11 13:36:08 -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
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050022#ifndef NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP
23#define NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP
Alexander Afanasyev7e721412017-01-11 13:36:08 -080024
Alexander Afanasyev09236c22020-06-03 13:42:38 -040025#include "ndn-cxx/security/validator.hpp"
26#include "ndn-cxx/security/certificate-fetcher-from-network.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050027#include "ndn-cxx/util/dummy-client-face.hpp"
Alexander Afanasyev7e721412017-01-11 13:36:08 -080028
Davide Pesavento7e780642018-11-24 15:51:34 -050029#include "tests/boost-test.hpp"
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050030#include "tests/unit/io-key-chain-fixture.hpp"
Alexander Afanasyev7e721412017-01-11 13:36:08 -080031
32#include <boost/lexical_cast.hpp>
33
34namespace ndn {
35namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040036inline namespace v2 {
Alexander Afanasyev7e721412017-01-11 13:36:08 -080037namespace tests {
38
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050039class ValidatorFixtureBase : public ndn::tests::IoKeyChainFixture
Alexander Afanasyev7e721412017-01-11 13:36:08 -080040{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050041protected:
42 ValidatorFixtureBase();
43
44 void
45 mockNetworkOperations();
46
Davide Pesavento2acce252022-09-08 22:03:03 -040047 /**
48 * @brief Undo clock advancement of mockNetworkOperations()
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050049 */
50 void
Davide Pesavento2acce252022-09-08 22:03:03 -040051 rewindClockAfterValidation();
Alexander Afanasyev7e721412017-01-11 13:36:08 -080052
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050053 /**
54 * @brief Issues a certificate for @p subIdentityName signed by @p issuer
55 *
56 * If the identity does not exist, it is created.
57 * A new key is generated as the default key for the identity.
58 * A default certificate for the key is signed by the issuer using its default certificate.
59 *
60 * @return The sub-identity
61 */
62 Identity
63 addSubCertificate(const Name& subIdentityName, const Identity& issuer);
64
65protected:
66 util::DummyClientFace face{m_io, {true, true}};
67 std::function<void(const Interest&)> processInterest;
68 CertificateCache cache{100_days};
Davide Pesavento87208f92022-08-30 19:51:23 -040069 ValidationError lastError{ValidationError::NO_ERROR};
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050070
71private:
Davide Pesavento05ec0be2023-03-14 21:18:06 -040072 static constexpr time::milliseconds s_mockPeriod{250};
73 static constexpr int s_mockTimes{200};
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050074};
75
76template<class ValidationPolicyT, class CertificateFetcherT = CertificateFetcherFromNetwork>
77class ValidatorFixture : public ValidatorFixtureBase
78{
79protected:
80 ValidatorFixture()
81 : validator(make_unique<ValidationPolicyT>(), make_unique<CertificateFetcherT>(face))
82 , policy(static_cast<ValidationPolicyT&>(validator.getPolicy()))
83 {
84 }
Alexander Afanasyev7e721412017-01-11 13:36:08 -080085
86 template<class Packet>
87 void
88 validate(const Packet& packet, const std::string& msg, bool expectSuccess, int line)
89 {
90 std::string detailedInfo = msg + " on line " + to_string(line);
91 size_t nCallbacks = 0;
92 this->validator.validate(packet,
Alexander Afanasyev93338872017-01-30 22:37:00 -080093 [&] (const Packet&) {
Davide Pesavento2acce252022-09-08 22:03:03 -040094 lastError = ValidationError::NO_ERROR;
Alexander Afanasyev93338872017-01-30 22:37:00 -080095 ++nCallbacks;
96 BOOST_CHECK_MESSAGE(expectSuccess,
97 (expectSuccess ? "OK: " : "FAILED: ") + detailedInfo);
98 },
99 [&] (const Packet&, const ValidationError& error) {
Alexander Afanasyev1660d002019-03-18 10:45:39 -0400100 lastError = error;
Alexander Afanasyev93338872017-01-30 22:37:00 -0800101 ++nCallbacks;
102 BOOST_CHECK_MESSAGE(!expectSuccess,
103 (!expectSuccess ? "OK: " : "FAILED: ") + detailedInfo +
104 (expectSuccess ? " (" + boost::lexical_cast<std::string>(error) + ")" : ""));
105 });
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800106
107 mockNetworkOperations();
108 BOOST_CHECK_EQUAL(nCallbacks, 1);
109 }
110
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500111protected:
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800112 Validator validator;
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500113 ValidationPolicyT& policy;
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800114};
115
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500116template<class ValidationPolicyT, class CertificateFetcherT = CertificateFetcherFromNetwork>
117class HierarchicalValidatorFixture : public ValidatorFixture<ValidationPolicyT, CertificateFetcherT>
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800118{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500119protected:
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800120 HierarchicalValidatorFixture()
121 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500122 identity = this->m_keyChain.createIdentity("/Security/ValidatorFixture");
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400123 subIdentity = this->addSubCertificate("/Security/ValidatorFixture/Sub1", identity);
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500124 subSelfSignedIdentity = this->m_keyChain.createIdentity("/Security/ValidatorFixture/Sub1/Sub2");
125 otherIdentity = this->m_keyChain.createIdentity("/Security/OtherIdentity");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800126
127 this->validator.loadAnchor("", Certificate(identity.getDefaultKey().getDefaultCertificate()));
128
129 this->cache.insert(identity.getDefaultKey().getDefaultCertificate());
130 this->cache.insert(subIdentity.getDefaultKey().getDefaultCertificate());
131 this->cache.insert(subSelfSignedIdentity.getDefaultKey().getDefaultCertificate());
132 this->cache.insert(otherIdentity.getDefaultKey().getDefaultCertificate());
133 }
134
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500135protected:
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800136 Identity identity;
137 Identity subIdentity;
138 Identity subSelfSignedIdentity;
139 Identity otherIdentity;
140};
141
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500142#define VALIDATE_SUCCESS(packet, message) this->validate(packet, message, true, __LINE__)
143#define VALIDATE_FAILURE(packet, message) this->validate(packet, message, false, __LINE__)
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800144
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800145class DummyValidationState : public ValidationState
146{
147public:
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500148 ~DummyValidationState() override
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800149 {
150 m_outcome = false;
151 }
152
153 void
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500154 fail(const ValidationError&) override
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800155 {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800156 m_outcome = false;
157 }
158
159private:
160 void
Davide Pesaventof6b45892023-03-13 15:00:51 -0400161 verifyOriginalPacket(const std::optional<Certificate>&) override
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800162 {
163 // do nothing
164 }
165
166 void
167 bypassValidation() override
168 {
169 // do nothing
170 }
171};
172
Eric Newberry17d7c472020-06-18 21:29:22 -0700173struct DataPkt
174{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500175 static constexpr uint32_t
Eric Newberry17d7c472020-06-18 21:29:22 -0700176 getType()
177 {
178 return tlv::Data;
179 }
180
181 static Name
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500182 makeName(Name name, KeyChain&)
Eric Newberry17d7c472020-06-18 21:29:22 -0700183 {
184 return name;
185 }
186
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500187 static Data
188 makePacket(const Name& name)
189 {
190 return Data(name);
191 }
192
Eric Newberry17d7c472020-06-18 21:29:22 -0700193 static shared_ptr<ValidationState>
194 makeState()
195 {
196 return make_shared<DummyValidationState>();
197 }
198};
199
200struct InterestV02Pkt
201{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500202 static constexpr uint32_t
Eric Newberry17d7c472020-06-18 21:29:22 -0700203 getType()
204 {
205 return tlv::Interest;
206 }
207
208 static Name
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500209 makeName(Name name, KeyChain& keyChain);
Eric Newberry17d7c472020-06-18 21:29:22 -0700210
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500211 static Interest
212 makePacket(const Name& name)
213 {
Davide Pesaventoaee2ada2022-02-18 14:43:02 -0500214 return Interest(name);
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500215 }
216
Eric Newberry17d7c472020-06-18 21:29:22 -0700217 static shared_ptr<ValidationState>
218 makeState()
219 {
220 auto state = make_shared<DummyValidationState>();
221 state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V02));
222 return state;
223 }
224};
225
226struct InterestV03Pkt
227{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500228 static constexpr uint32_t
Eric Newberry17d7c472020-06-18 21:29:22 -0700229 getType()
230 {
231 return tlv::Interest;
232 }
233
234 static Name
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500235 makeName(Name name, KeyChain& keyChain);
Eric Newberry17d7c472020-06-18 21:29:22 -0700236
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500237 static Interest
238 makePacket(const Name& name)
239 {
Davide Pesaventoaee2ada2022-02-18 14:43:02 -0500240 return Interest(name);
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500241 }
242
Eric Newberry17d7c472020-06-18 21:29:22 -0700243 static shared_ptr<ValidationState>
244 makeState()
245 {
246 auto state = make_shared<DummyValidationState>();
247 state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V03));
248 return state;
249 }
250};
251
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800252} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400253} // inline namespace v2
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800254} // namespace security
255} // namespace ndn
256
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500257#endif // NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP