blob: 6d69a1e0f3a1b05f072a9d044d612487ba4f4226 [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
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040034namespace ndn::tests {
Alexander Afanasyev7e721412017-01-11 13:36:08 -080035
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040036using ndn::security::Certificate;
37using ndn::security::Identity;
38using ndn::security::ValidationError;
39
40class ValidatorFixtureBase : public IoKeyChainFixture
Alexander Afanasyev7e721412017-01-11 13:36:08 -080041{
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050042protected:
43 ValidatorFixtureBase();
44
45 void
46 mockNetworkOperations();
47
Davide Pesavento2acce252022-09-08 22:03:03 -040048 /**
49 * @brief Undo clock advancement of mockNetworkOperations()
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050050 */
51 void
Davide Pesavento2acce252022-09-08 22:03:03 -040052 rewindClockAfterValidation();
Alexander Afanasyev7e721412017-01-11 13:36:08 -080053
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050054 /**
55 * @brief Issues a certificate for @p subIdentityName signed by @p issuer
56 *
57 * If the identity does not exist, it is created.
58 * A new key is generated as the default key for the identity.
59 * A default certificate for the key is signed by the issuer using its default certificate.
60 *
61 * @return The sub-identity
62 */
63 Identity
64 addSubCertificate(const Name& subIdentityName, const Identity& issuer);
65
66protected:
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040067 DummyClientFace face{m_io, {true, true}};
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050068 std::function<void(const Interest&)> processInterest;
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040069 security::CertificateCache cache{100_days};
Davide Pesavento87208f92022-08-30 19:51:23 -040070 ValidationError lastError{ValidationError::NO_ERROR};
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050071
72private:
Davide Pesavento05ec0be2023-03-14 21:18:06 -040073 static constexpr time::milliseconds s_mockPeriod{250};
74 static constexpr int s_mockTimes{200};
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050075};
76
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040077template<class ValidationPolicyT, class CertificateFetcherT = security::CertificateFetcherFromNetwork>
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050078class ValidatorFixture : public ValidatorFixtureBase
79{
80protected:
81 ValidatorFixture()
82 : validator(make_unique<ValidationPolicyT>(), make_unique<CertificateFetcherT>(face))
83 , policy(static_cast<ValidationPolicyT&>(validator.getPolicy()))
84 {
85 }
Alexander Afanasyev7e721412017-01-11 13:36:08 -080086
87 template<class Packet>
88 void
89 validate(const Packet& packet, const std::string& msg, bool expectSuccess, int line)
90 {
91 std::string detailedInfo = msg + " on line " + to_string(line);
92 size_t nCallbacks = 0;
93 this->validator.validate(packet,
Alexander Afanasyev93338872017-01-30 22:37:00 -080094 [&] (const Packet&) {
Davide Pesavento2acce252022-09-08 22:03:03 -040095 lastError = ValidationError::NO_ERROR;
Alexander Afanasyev93338872017-01-30 22:37:00 -080096 ++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:
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400113 security::Validator validator;
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500114 ValidationPolicyT& policy;
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800115};
116
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400117template<class ValidationPolicyT, class CertificateFetcherT = security::CertificateFetcherFromNetwork>
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500118class 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
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400146class DummyValidationState : public security::ValidationState
Alexander Afanasyeve5a19b82017-01-30 22:30:46 -0800147{
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 Pesaventof6b45892023-03-13 15:00:51 -0400162 verifyOriginalPacket(const std::optional<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
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400194 static shared_ptr<security::ValidationState>
Eric Newberry17d7c472020-06-18 21:29:22 -0700195 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 {
Davide Pesaventoaee2ada2022-02-18 14:43:02 -0500215 return Interest(name);
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500216 }
217
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400218 static shared_ptr<security::ValidationState>
Eric Newberry17d7c472020-06-18 21:29:22 -0700219 makeState()
220 {
221 auto state = make_shared<DummyValidationState>();
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400222 state->setTag(make_shared<security::SignedInterestFormatTag>(security::SignedInterestFormat::V02));
Eric Newberry17d7c472020-06-18 21:29:22 -0700223 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 {
Davide Pesaventoaee2ada2022-02-18 14:43:02 -0500241 return Interest(name);
Davide Pesavento1a4a7bf2020-12-04 22:30:46 -0500242 }
243
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400244 static shared_ptr<security::ValidationState>
Eric Newberry17d7c472020-06-18 21:29:22 -0700245 makeState()
246 {
247 auto state = make_shared<DummyValidationState>();
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400248 state->setTag(make_shared<security::SignedInterestFormatTag>(security::SignedInterestFormat::V03));
Eric Newberry17d7c472020-06-18 21:29:22 -0700249 return state;
250 }
251};
252
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400253} // namespace ndn::tests
Alexander Afanasyev7e721412017-01-11 13:36:08 -0800254
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500255#endif // NDN_CXX_TESTS_UNIT_SECURITY_VALIDATOR_FIXTURE_HPP