blob: 1d0cee953cadc00b1827e4d09e33e4d4775b366f [file] [log] [blame]
Manika Mittal95c80702017-01-27 09:54:41 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento0f830802018-01-16 23:58:58 -05002/*
Alexander Afanasyev09236c22020-06-03 13:42:38 -04003 * Copyright (c) 2013-2020 Regents of the University of California.
Manika Mittal95c80702017-01-27 09:54:41 -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/certificate-bundle-fetcher.hpp"
23#include "ndn-cxx/security/validation-policy-simple-hierarchy.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050024#include "ndn-cxx/util/regex/regex-pattern-list-matcher.hpp"
Manika Mittal95c80702017-01-27 09:54:41 -080025
Davide Pesavento7e780642018-11-24 15:51:34 -050026#include "tests/boost-test.hpp"
Davide Pesavento2ca5e792020-06-16 22:52:23 -040027#include "tests/make-interest-data.hpp"
Alexander Afanasyev09236c22020-06-03 13:42:38 -040028#include "tests/unit/security/validator-fixture.hpp"
Manika Mittal95c80702017-01-27 09:54:41 -080029
30namespace ndn {
31namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040032inline namespace v2 {
Manika Mittal95c80702017-01-27 09:54:41 -080033namespace tests {
34
35using namespace ndn::tests;
36
37BOOST_AUTO_TEST_SUITE(Security)
Manika Mittal95c80702017-01-27 09:54:41 -080038BOOST_AUTO_TEST_SUITE(TestCertificateBundleFetcher)
39
40class CertificateBundleFetcherWrapper : public CertificateBundleFetcher
41{
42public:
43 CertificateBundleFetcherWrapper(Face& face)
44 : CertificateBundleFetcher(make_unique<CertificateFetcherFromNetwork>(face), face)
45 {
46 }
47};
48
Davide Pesavento2ca5e792020-06-16 22:52:23 -040049class BundleWithFinalBlockId
Manika Mittal95c80702017-01-27 09:54:41 -080050{
51};
52
Davide Pesavento2ca5e792020-06-16 22:52:23 -040053class BundleWithoutFinalBlockId
Manika Mittal95c80702017-01-27 09:54:41 -080054{
55};
56
57class Timeout
58{
59};
60
61class Nack
62{
63};
64
65template<class Response>
66class CertificateBundleFetcherFixture : public HierarchicalValidatorFixture<ValidationPolicySimpleHierarchy,
67 CertificateBundleFetcherWrapper>
68{
69public:
70 CertificateBundleFetcherFixture()
Alexander Afanasyev09236c22020-06-03 13:42:38 -040071 : data("/Security/ValidatorFixture/Sub1/Sub3/Data")
Davide Pesavento2ca5e792020-06-16 22:52:23 -040072 , bundleRegexMatcher(std::make_shared<RegexPatternListMatcher>("<>*<_BUNDLE><>*", nullptr))
Manika Mittal95c80702017-01-27 09:54:41 -080073 {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040074 subSubIdentity = addSubCertificate("/Security/ValidatorFixture/Sub1/Sub3", subIdentity);
Manika Mittal95c80702017-01-27 09:54:41 -080075 cache.insert(subSubIdentity.getDefaultKey().getDefaultCertificate());
Manika Mittal95c80702017-01-27 09:54:41 -080076 m_keyChain.sign(data, signingByIdentity(subSubIdentity));
Davide Pesavento2ca5e792020-06-16 22:52:23 -040077
Manika Mittal95c80702017-01-27 09:54:41 -080078 processInterest = [this] (const Interest& interest) {
Davide Pesavento2ca5e792020-06-16 22:52:23 -040079 // check if the interest is for bundle or individual certificates
Manika Mittal95c80702017-01-27 09:54:41 -080080 if (bundleRegexMatcher->match(interest.getName(), 0, interest.getName().size())) {
81 makeResponse(interest);
82 }
83 else {
84 auto cert = cache.find(interest);
Davide Pesavento2ca5e792020-06-16 22:52:23 -040085 if (cert) {
86 face.receive(*cert);
Manika Mittal95c80702017-01-27 09:54:41 -080087 }
Manika Mittal95c80702017-01-27 09:54:41 -080088 }
89 };
90 }
91
Davide Pesavento2ca5e792020-06-16 22:52:23 -040092private:
Manika Mittal95c80702017-01-27 09:54:41 -080093 void
94 makeResponse(const Interest& interest);
95
Davide Pesavento2ca5e792020-06-16 22:52:23 -040096 shared_ptr<Data>
97 makeBundle(const Interest& interest) const
98 {
99 Block certList(tlv::Content);
100 Name bundleName(interest.getName());
101
102 if (!bundleName.get(-1).isSegment() || bundleName.get(-1).toSegment() == 0) {
103 Block subSubCert = subSubIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
104 certList.push_back(std::move(subSubCert));
105
106 if (!bundleName.get(-1).isSegment()) {
107 bundleName
108 .appendVersion()
109 .appendSegment(0);
110 }
111 }
112 else {
113 Block subCert = subIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
114 Block anchor = identity.getDefaultKey().getDefaultCertificate().wireEncode();
115 certList.push_back(std::move(subCert));
116 certList.push_back(std::move(anchor));
117 }
118
119 auto certBundle = make_shared<Data>();
120 certBundle->setName(bundleName);
121 certBundle->setFreshnessPeriod(100_s);
122 certBundle->setContent(certList);
123 return certBundle;
124 }
125
126protected:
Manika Mittal95c80702017-01-27 09:54:41 -0800127 Data data;
128 Identity subSubIdentity;
129 shared_ptr<RegexPatternListMatcher> bundleRegexMatcher;
130};
131
132template<>
133void
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400134CertificateBundleFetcherFixture<BundleWithFinalBlockId>::makeResponse(const Interest& interest)
Manika Mittal95c80702017-01-27 09:54:41 -0800135{
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400136 auto certBundle = makeBundle(interest);
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000137 certBundle->setFinalBlock(name::Component::fromSegment(1));
Manika Mittal95c80702017-01-27 09:54:41 -0800138 m_keyChain.sign(*certBundle, signingWithSha256());
Manika Mittal95c80702017-01-27 09:54:41 -0800139 face.receive(*certBundle);
140}
141
142template<>
143void
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400144CertificateBundleFetcherFixture<BundleWithoutFinalBlockId>::makeResponse(const Interest& interest)
145{
146 auto certBundle = makeBundle(interest);
147 m_keyChain.sign(*certBundle, signingWithSha256());
148 face.receive(*certBundle);
149}
150
151template<>
152void
153CertificateBundleFetcherFixture<Timeout>::makeResponse(const Interest&)
Manika Mittal95c80702017-01-27 09:54:41 -0800154{
Davide Pesavento0f830802018-01-16 23:58:58 -0500155 this->advanceClocks(200_s);
Manika Mittal95c80702017-01-27 09:54:41 -0800156}
157
158template<>
159void
160CertificateBundleFetcherFixture<Nack>::makeResponse(const Interest& interest)
161{
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400162 face.receive(makeNack(interest, lp::NackReason::NO_ROUTE));
Manika Mittal95c80702017-01-27 09:54:41 -0800163}
164
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400165using SuccessWithBundle = boost::mpl::vector<BundleWithFinalBlockId, BundleWithoutFinalBlockId>;
166
167BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateSuccessWithBundle, T, SuccessWithBundle,
168 CertificateBundleFetcherFixture<T>)
Manika Mittal95c80702017-01-27 09:54:41 -0800169{
170 VALIDATE_SUCCESS(this->data, "Should get accepted, as interest brings the bundle segments");
171 BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 2); // produced bundle has 2 segments
172
173 for (const auto& sentInterest : this->face.sentInterests) {
174 BOOST_CHECK(this->bundleRegexMatcher->match(sentInterest.getName(), 0, sentInterest.getName().size()));
175 }
176}
177
178using SuccessWithoutBundle = boost::mpl::vector<Nack, Timeout>;
179
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400180BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateSuccessWithoutBundle, T, SuccessWithoutBundle,
181 CertificateBundleFetcherFixture<T>)
Manika Mittal95c80702017-01-27 09:54:41 -0800182{
183 VALIDATE_SUCCESS(this->data, "Should get accepted, as interest brings the certs");
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400184 BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 4); // since interest for bundle fails, each cert is retrieved
Manika Mittal95c80702017-01-27 09:54:41 -0800185
186 bool toggle = true;
187 for (const auto& sentInterest : this->face.sentInterests) {
188 if (toggle) {
189 // every alternate interest is going to be that of a bundle
190 BOOST_CHECK(this->bundleRegexMatcher->match(sentInterest.getName(), 0, sentInterest.getName().size()));
191 }
192 else {
193 BOOST_CHECK(!this->bundleRegexMatcher->match(sentInterest.getName(), 0, sentInterest.getName().size()));
194 }
195 toggle = !toggle;
196 }
197}
198
199BOOST_AUTO_TEST_SUITE_END() // TestCertificateBundleFetcher
Manika Mittal95c80702017-01-27 09:54:41 -0800200BOOST_AUTO_TEST_SUITE_END() // Security
201
202} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400203} // inline namespace v2
Manika Mittal95c80702017-01-27 09:54:41 -0800204} // namespace security
205} // namespace ndn