blob: 343e36341eb94eefcab31212c46dc05a271d737b [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
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
47 /** \brief undo clock advancement of mockNetworkOperations()
48 */
49 void
50 rewindClockAfterValidation()
Alexander Afanasyev7e721412017-01-11 13:36:08 -080051 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050052 m_systemClock->advance(s_mockPeriod * s_mockTimes * -1);
Alexander Afanasyev7e721412017-01-11 13:36:08 -080053 }
54
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050055 /**
56 * @brief Issues a certificate for @p subIdentityName signed by @p issuer
57 *
58 * If the identity does not exist, it is created.
59 * A new key is generated as the default key for the identity.
60 * A default certificate for the key is signed by the issuer using its default certificate.
61 *
62 * @return The sub-identity
63 */
64 Identity
65 addSubCertificate(const Name& subIdentityName, const Identity& issuer);
66
67protected:
68 util::DummyClientFace face{m_io, {true, true}};
69 std::function<void(const Interest&)> processInterest;
70 CertificateCache cache{100_days};
71 ValidationError lastError{ValidationError::Code::NO_ERROR};
72
73private:
74 const static time::milliseconds s_mockPeriod;
75 const static int s_mockTimes;
76};
77
78template<class ValidationPolicyT, class CertificateFetcherT = CertificateFetcherFromNetwork>
79class ValidatorFixture : public ValidatorFixtureBase
80{
81protected:
82 ValidatorFixture()
83 : validator(make_unique<ValidationPolicyT>(), make_unique<CertificateFetcherT>(face))
84 , policy(static_cast<ValidationPolicyT&>(validator.getPolicy()))
85 {
86 }
Alexander Afanasyev7e721412017-01-11 13:36:08 -080087
88 template<class Packet>
89 void
90 validate(const Packet& packet, const std::string& msg, bool expectSuccess, int line)
91 {
92 std::string detailedInfo = msg + " on line " + to_string(line);
93 size_t nCallbacks = 0;
94 this->validator.validate(packet,
Alexander Afanasyev93338872017-01-30 22:37:00 -080095 [&] (const Packet&) {
96 ++nCallbacks;
97 BOOST_CHECK_MESSAGE(expectSuccess,
98 (expectSuccess ? "OK: " : "FAILED: ") + detailedInfo);
99 },
100 [&] (const Packet&, const ValidationError& error) {
Alexander Afanasyev1660d002019-03-18 10:45:39 -0400101 lastError = error;
Alexander Afanasyev93338872017-01-30 22:37:00 -0800102 ++nCallbacks;
103 BOOST_CHECK_MESSAGE(!expectSuccess,
104 (!expectSuccess ? "OK: " : "FAILED: ") + detailedInfo +
105 (expectSuccess ? " (" + boost::lexical_cast<std::string>(error) + ")" : ""));
106 });
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800107
108 mockNetworkOperations();
109 BOOST_CHECK_EQUAL(nCallbacks, 1);
110 }
111
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500112protected:
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800113 Validator validator;
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500114 ValidationPolicyT& policy;
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800115};
116
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500117template<class ValidationPolicyT, class CertificateFetcherT = CertificateFetcherFromNetwork>
118class HierarchicalValidatorFixture : public ValidatorFixture<ValidationPolicyT, CertificateFetcherT>
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800119{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500120protected:
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800121 HierarchicalValidatorFixture()
122 {
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500123 identity = this->m_keyChain.createIdentity("/Security/ValidatorFixture");
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400124 subIdentity = this->addSubCertificate("/Security/ValidatorFixture/Sub1", identity);
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500125 subSelfSignedIdentity = this->m_keyChain.createIdentity("/Security/ValidatorFixture/Sub1/Sub2");
126 otherIdentity = this->m_keyChain.createIdentity("/Security/OtherIdentity");
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800127
128 this->validator.loadAnchor("", Certificate(identity.getDefaultKey().getDefaultCertificate()));
129
130 this->cache.insert(identity.getDefaultKey().getDefaultCertificate());
131 this->cache.insert(subIdentity.getDefaultKey().getDefaultCertificate());
132 this->cache.insert(subSelfSignedIdentity.getDefaultKey().getDefaultCertificate());
133 this->cache.insert(otherIdentity.getDefaultKey().getDefaultCertificate());
134 }
135
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500136protected:
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800137 Identity identity;
138 Identity subIdentity;
139 Identity subSelfSignedIdentity;
140 Identity otherIdentity;
141};
142
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500143#define VALIDATE_SUCCESS(packet, message) this->validate(packet, message, true, __LINE__)
144#define VALIDATE_FAILURE(packet, message) this->validate(packet, message, false, __LINE__)
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800145
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800146class DummyValidationState : public ValidationState
147{
148public:
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500149 ~DummyValidationState() override
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800150 {
151 m_outcome = false;
152 }
153
154 void
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500155 fail(const ValidationError&) override
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800156 {
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800157 m_outcome = false;
158 }
159
160private:
161 void
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500162 verifyOriginalPacket(const Certificate&) override
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800163 {
164 // do nothing
165 }
166
167 void
168 bypassValidation() override
169 {
170 // do nothing
171 }
172};
173
Eric Newberry17d7c472020-06-18 21:29:22 -0700174struct DataPkt
175{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500176 static constexpr uint32_t
Eric Newberry17d7c472020-06-18 21:29:22 -0700177 getType()
178 {
179 return tlv::Data;
180 }
181
182 static Name
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500183 makeName(Name name, KeyChain&)
Eric Newberry17d7c472020-06-18 21:29:22 -0700184 {
185 return name;
186 }
187
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500188 static Data
189 makePacket(const Name& name)
190 {
191 return Data(name);
192 }
193
Eric Newberry17d7c472020-06-18 21:29:22 -0700194 static shared_ptr<ValidationState>
195 makeState()
196 {
197 return make_shared<DummyValidationState>();
198 }
199};
200
201struct InterestV02Pkt
202{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500203 static constexpr uint32_t
Eric Newberry17d7c472020-06-18 21:29:22 -0700204 getType()
205 {
206 return tlv::Interest;
207 }
208
209 static Name
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500210 makeName(Name name, KeyChain& keyChain);
Eric Newberry17d7c472020-06-18 21:29:22 -0700211
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500212 static Interest
213 makePacket(const Name& name)
214 {
215 return Interest(name).setCanBePrefix(false);
216 }
217
Eric Newberry17d7c472020-06-18 21:29:22 -0700218 static shared_ptr<ValidationState>
219 makeState()
220 {
221 auto state = make_shared<DummyValidationState>();
222 state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V02));
223 return state;
224 }
225};
226
227struct InterestV03Pkt
228{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500229 static constexpr uint32_t
Eric Newberry17d7c472020-06-18 21:29:22 -0700230 getType()
231 {
232 return tlv::Interest;
233 }
234
235 static Name
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500236 makeName(Name name, KeyChain& keyChain);
Eric Newberry17d7c472020-06-18 21:29:22 -0700237
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500238 static Interest
239 makePacket(const Name& name)
240 {
241 return Interest(name).setCanBePrefix(false);
242 }
243
Eric Newberry17d7c472020-06-18 21:29:22 -0700244 static shared_ptr<ValidationState>
245 makeState()
246 {
247 auto state = make_shared<DummyValidationState>();
248 state->setTag(make_shared<SignedInterestFormatTag>(SignedInterestFormat::V03));
249 return state;
250 }
251};
252
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800253} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400254} // inline namespace v2
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800255} // namespace security
256} // namespace ndn
257
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500258#endif // NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP