blob: e9e5d5b94696e9370f9e3a884127934f25116b8e [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/*
Alexander Afanasyev09236c22020-06-03 13:42:38 -04003 * Copyright (c) 2013-2020 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
Alexander Afanasyev09236c22020-06-03 13:42:38 -040022#ifndef NDN_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP
23#define NDN_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"
30#include "tests/unit/identity-management-time-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
Alexander Afanasyev7bc10fa2017-01-13 16:56:26 -080039template<class ValidationPolicy, class CertificateFetcher = CertificateFetcherFromNetwork>
Alexander Afanasyev7e721412017-01-11 13:36:08 -080040class ValidatorFixture : public ndn::tests::IdentityManagementTimeFixture
41{
42public:
43 ValidatorFixture()
44 : face(io, {true, true})
Alexander Afanasyev7bc10fa2017-01-13 16:56:26 -080045 , validator(make_unique<ValidationPolicy>(), make_unique<CertificateFetcher>(face))
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -080046 , policy(static_cast<ValidationPolicy&>(validator.getPolicy()))
Davide Pesavento0f830802018-01-16 23:58:58 -050047 , cache(100_days)
Alexander Afanasyev1660d002019-03-18 10:45:39 -040048 , lastError(ValidationError::Code::NO_ERROR)
Alexander Afanasyev7e721412017-01-11 13:36:08 -080049 {
50 processInterest = [this] (const Interest& interest) {
51 auto cert = cache.find(interest);
52 if (cert != nullptr) {
53 face.receive(*cert);
54 }
55 };
56 }
57
58 virtual
59 ~ValidatorFixture() = default;
60
61 template<class Packet>
62 void
63 validate(const Packet& packet, const std::string& msg, bool expectSuccess, int line)
64 {
65 std::string detailedInfo = msg + " on line " + to_string(line);
66 size_t nCallbacks = 0;
67 this->validator.validate(packet,
Alexander Afanasyev93338872017-01-30 22:37:00 -080068 [&] (const Packet&) {
69 ++nCallbacks;
70 BOOST_CHECK_MESSAGE(expectSuccess,
71 (expectSuccess ? "OK: " : "FAILED: ") + detailedInfo);
72 },
73 [&] (const Packet&, const ValidationError& error) {
Alexander Afanasyev1660d002019-03-18 10:45:39 -040074 lastError = error;
Alexander Afanasyev93338872017-01-30 22:37:00 -080075 ++nCallbacks;
76 BOOST_CHECK_MESSAGE(!expectSuccess,
77 (!expectSuccess ? "OK: " : "FAILED: ") + detailedInfo +
78 (expectSuccess ? " (" + boost::lexical_cast<std::string>(error) + ")" : ""));
79 });
Alexander Afanasyev7e721412017-01-11 13:36:08 -080080
81 mockNetworkOperations();
82 BOOST_CHECK_EQUAL(nCallbacks, 1);
83 }
84
85 void
86 mockNetworkOperations()
87 {
88 util::signal::ScopedConnection connection = face.onSendInterest.connect([this] (const Interest& interest) {
89 if (processInterest != nullptr) {
90 io.post(bind(processInterest, interest));
91 }
92 });
Alexander Afanasyev93338872017-01-30 22:37:00 -080093 advanceClocks(time::milliseconds(s_mockPeriod), s_mockTimes);
94 }
95
96 /** \brief undo clock advancement of mockNetworkOperations
97 */
98 void
99 rewindClockAfterValidation()
100 {
101 this->systemClock->advance(time::milliseconds(s_mockPeriod * s_mockTimes * -1));
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800102 }
103
104public:
105 util::DummyClientFace face;
106 std::function<void(const Interest& interest)> processInterest;
107 Validator validator;
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800108 ValidationPolicy& policy;
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800109
110 CertificateCache cache;
Alexander Afanasyev1660d002019-03-18 10:45:39 -0400111 ValidationError lastError;
Alexander Afanasyev93338872017-01-30 22:37:00 -0800112
113private:
114 const static int s_mockPeriod;
115 const static int s_mockTimes;
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800116};
117
Alexander Afanasyev93338872017-01-30 22:37:00 -0800118template<class ValidationPolicy, class CertificateFetcher>
119const int ValidatorFixture<ValidationPolicy, CertificateFetcher>::s_mockPeriod = 250;
120
121template<class ValidationPolicy, class CertificateFetcher>
122const int ValidatorFixture<ValidationPolicy, CertificateFetcher>::s_mockTimes = 200;
123
Alexander Afanasyev7bc10fa2017-01-13 16:56:26 -0800124template<class ValidationPolicy, class CertificateFetcher = CertificateFetcherFromNetwork>
125class HierarchicalValidatorFixture : public ValidatorFixture<ValidationPolicy, CertificateFetcher>
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800126{
127public:
128 HierarchicalValidatorFixture()
129 {
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400130 identity = this->addIdentity("/Security/ValidatorFixture");
131 subIdentity = this->addSubCertificate("/Security/ValidatorFixture/Sub1", identity);
132 subSelfSignedIdentity = this->addIdentity("/Security/ValidatorFixture/Sub1/Sub2");
133 otherIdentity = this->addIdentity("/Security/OtherIdentity");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800134
135 this->validator.loadAnchor("", Certificate(identity.getDefaultKey().getDefaultCertificate()));
136
137 this->cache.insert(identity.getDefaultKey().getDefaultCertificate());
138 this->cache.insert(subIdentity.getDefaultKey().getDefaultCertificate());
139 this->cache.insert(subSelfSignedIdentity.getDefaultKey().getDefaultCertificate());
140 this->cache.insert(otherIdentity.getDefaultKey().getDefaultCertificate());
141 }
142
143public:
144 Identity identity;
145 Identity subIdentity;
146 Identity subSelfSignedIdentity;
147 Identity otherIdentity;
148};
149
150#define VALIDATE_SUCCESS(packet, message) this->template validate(packet, message, true, __LINE__)
151#define VALIDATE_FAILURE(packet, message) this->template validate(packet, message, false, __LINE__)
152
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800153class DummyValidationState : public ValidationState
154{
155public:
156 ~DummyValidationState()
157 {
158 m_outcome = false;
159 }
160
161 void
162 fail(const ValidationError& error) override
163 {
164 // BOOST_TEST_MESSAGE(error);
165 m_outcome = false;
166 }
167
168private:
169 void
170 verifyOriginalPacket(const Certificate& trustedCert) override
171 {
172 // do nothing
173 }
174
175 void
176 bypassValidation() override
177 {
178 // do nothing
179 }
180};
181
Eric Newberry17d7c472020-06-18 21:29:22 -0700182
183struct DataPkt
184{
185 static uint32_t
186 getType()
187 {
188 return tlv::Data;
189 }
190
191 static Name
192 makeName(Name name, KeyChain& keyChain)
193 {
194 return name;
195 }
196
197 static shared_ptr<ValidationState>
198 makeState()
199 {
200 return make_shared<DummyValidationState>();
201 }
202};
203
204struct InterestV02Pkt
205{
206 static uint32_t
207 getType()
208 {
209 return tlv::Interest;
210 }
211
212 static Name
213 makeName(Name name, KeyChain& keyChain)
214 {
215 Interest interest(name);
216 interest.setCanBePrefix(false);
217 SigningInfo params;
218 params.setSignedInterestFormat(SignedInterestFormat::V02);
219 keyChain.sign(interest, params);
220 return interest.getName();
221 }
222
223 static shared_ptr<ValidationState>
224 makeState()
225 {
226 auto state = make_shared<DummyValidationState>();
227 state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V02));
228 return state;
229 }
230};
231
232struct InterestV03Pkt
233{
234 static uint32_t
235 getType()
236 {
237 return tlv::Interest;
238 }
239
240 static Name
241 makeName(Name name, KeyChain& keyChain)
242 {
243 Interest interest(name);
244 interest.setCanBePrefix(false);
245 SigningInfo params;
246 params.setSignedInterestFormat(SignedInterestFormat::V03);
247 keyChain.sign(interest, params);
248 return interest.getName();
249 }
250
251 static shared_ptr<ValidationState>
252 makeState()
253 {
254 auto state = make_shared<DummyValidationState>();
255 state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V03));
256 return state;
257 }
258};
259
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800260} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400261} // inline namespace v2
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800262} // namespace security
263} // namespace ndn
264
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400265#endif // NDN_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP