blob: 0c300b7400d1764f3b4bd73eaf64fc2bd0ccb431 [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 Pesavento4c1ad4c2020-11-16 21:12:02 -050026#include "tests/test-common.hpp"
Alexander Afanasyev09236c22020-06-03 13:42:38 -040027#include "tests/unit/security/validator-fixture.hpp"
Manika Mittal95c80702017-01-27 09:54:41 -080028
29namespace ndn {
30namespace security {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040031inline namespace v2 {
Manika Mittal95c80702017-01-27 09:54:41 -080032namespace tests {
33
34using namespace ndn::tests;
35
36BOOST_AUTO_TEST_SUITE(Security)
Manika Mittal95c80702017-01-27 09:54:41 -080037BOOST_AUTO_TEST_SUITE(TestCertificateBundleFetcher)
38
39class CertificateBundleFetcherWrapper : public CertificateBundleFetcher
40{
41public:
42 CertificateBundleFetcherWrapper(Face& face)
43 : CertificateBundleFetcher(make_unique<CertificateFetcherFromNetwork>(face), face)
44 {
45 }
46};
47
Davide Pesavento2ca5e792020-06-16 22:52:23 -040048class BundleWithFinalBlockId
Manika Mittal95c80702017-01-27 09:54:41 -080049{
50};
51
Davide Pesavento2ca5e792020-06-16 22:52:23 -040052class BundleWithoutFinalBlockId
Manika Mittal95c80702017-01-27 09:54:41 -080053{
54};
55
56class Timeout
57{
58};
59
60class Nack
61{
62};
63
64template<class Response>
65class CertificateBundleFetcherFixture : public HierarchicalValidatorFixture<ValidationPolicySimpleHierarchy,
66 CertificateBundleFetcherWrapper>
67{
68public:
69 CertificateBundleFetcherFixture()
Alexander Afanasyev09236c22020-06-03 13:42:38 -040070 : data("/Security/ValidatorFixture/Sub1/Sub3/Data")
Davide Pesavento2ca5e792020-06-16 22:52:23 -040071 , bundleRegexMatcher(std::make_shared<RegexPatternListMatcher>("<>*<_BUNDLE><>*", nullptr))
Manika Mittal95c80702017-01-27 09:54:41 -080072 {
Alexander Afanasyev09236c22020-06-03 13:42:38 -040073 subSubIdentity = addSubCertificate("/Security/ValidatorFixture/Sub1/Sub3", subIdentity);
Manika Mittal95c80702017-01-27 09:54:41 -080074 cache.insert(subSubIdentity.getDefaultKey().getDefaultCertificate());
Manika Mittal95c80702017-01-27 09:54:41 -080075 m_keyChain.sign(data, signingByIdentity(subSubIdentity));
Davide Pesavento2ca5e792020-06-16 22:52:23 -040076
Manika Mittal95c80702017-01-27 09:54:41 -080077 processInterest = [this] (const Interest& interest) {
Davide Pesavento2ca5e792020-06-16 22:52:23 -040078 // check if the interest is for bundle or individual certificates
Manika Mittal95c80702017-01-27 09:54:41 -080079 if (bundleRegexMatcher->match(interest.getName(), 0, interest.getName().size())) {
80 makeResponse(interest);
81 }
82 else {
83 auto cert = cache.find(interest);
Davide Pesavento2ca5e792020-06-16 22:52:23 -040084 if (cert) {
85 face.receive(*cert);
Manika Mittal95c80702017-01-27 09:54:41 -080086 }
Manika Mittal95c80702017-01-27 09:54:41 -080087 }
88 };
89 }
90
Davide Pesavento2ca5e792020-06-16 22:52:23 -040091private:
Manika Mittal95c80702017-01-27 09:54:41 -080092 void
93 makeResponse(const Interest& interest);
94
Davide Pesavento2ca5e792020-06-16 22:52:23 -040095 shared_ptr<Data>
96 makeBundle(const Interest& interest) const
97 {
98 Block certList(tlv::Content);
99 Name bundleName(interest.getName());
100
101 if (!bundleName.get(-1).isSegment() || bundleName.get(-1).toSegment() == 0) {
102 Block subSubCert = subSubIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
103 certList.push_back(std::move(subSubCert));
104
105 if (!bundleName.get(-1).isSegment()) {
106 bundleName
107 .appendVersion()
108 .appendSegment(0);
109 }
110 }
111 else {
112 Block subCert = subIdentity.getDefaultKey().getDefaultCertificate().wireEncode();
113 Block anchor = identity.getDefaultKey().getDefaultCertificate().wireEncode();
114 certList.push_back(std::move(subCert));
115 certList.push_back(std::move(anchor));
116 }
117
118 auto certBundle = make_shared<Data>();
119 certBundle->setName(bundleName);
120 certBundle->setFreshnessPeriod(100_s);
121 certBundle->setContent(certList);
122 return certBundle;
123 }
124
125protected:
Manika Mittal95c80702017-01-27 09:54:41 -0800126 Data data;
127 Identity subSubIdentity;
128 shared_ptr<RegexPatternListMatcher> bundleRegexMatcher;
129};
130
131template<>
132void
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400133CertificateBundleFetcherFixture<BundleWithFinalBlockId>::makeResponse(const Interest& interest)
Manika Mittal95c80702017-01-27 09:54:41 -0800134{
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400135 auto certBundle = makeBundle(interest);
Junxiao Shiebfe4a22018-04-01 23:53:40 +0000136 certBundle->setFinalBlock(name::Component::fromSegment(1));
Manika Mittal95c80702017-01-27 09:54:41 -0800137 m_keyChain.sign(*certBundle, signingWithSha256());
Manika Mittal95c80702017-01-27 09:54:41 -0800138 face.receive(*certBundle);
139}
140
141template<>
142void
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400143CertificateBundleFetcherFixture<BundleWithoutFinalBlockId>::makeResponse(const Interest& interest)
144{
145 auto certBundle = makeBundle(interest);
146 m_keyChain.sign(*certBundle, signingWithSha256());
147 face.receive(*certBundle);
148}
149
150template<>
151void
152CertificateBundleFetcherFixture<Timeout>::makeResponse(const Interest&)
Manika Mittal95c80702017-01-27 09:54:41 -0800153{
Davide Pesavento0f830802018-01-16 23:58:58 -0500154 this->advanceClocks(200_s);
Manika Mittal95c80702017-01-27 09:54:41 -0800155}
156
157template<>
158void
159CertificateBundleFetcherFixture<Nack>::makeResponse(const Interest& interest)
160{
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400161 face.receive(makeNack(interest, lp::NackReason::NO_ROUTE));
Manika Mittal95c80702017-01-27 09:54:41 -0800162}
163
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400164using SuccessWithBundle = boost::mpl::vector<BundleWithFinalBlockId, BundleWithoutFinalBlockId>;
165
166BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateSuccessWithBundle, T, SuccessWithBundle,
167 CertificateBundleFetcherFixture<T>)
Manika Mittal95c80702017-01-27 09:54:41 -0800168{
169 VALIDATE_SUCCESS(this->data, "Should get accepted, as interest brings the bundle segments");
170 BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 2); // produced bundle has 2 segments
171
172 for (const auto& sentInterest : this->face.sentInterests) {
173 BOOST_CHECK(this->bundleRegexMatcher->match(sentInterest.getName(), 0, sentInterest.getName().size()));
174 }
175}
176
177using SuccessWithoutBundle = boost::mpl::vector<Nack, Timeout>;
178
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400179BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateSuccessWithoutBundle, T, SuccessWithoutBundle,
180 CertificateBundleFetcherFixture<T>)
Manika Mittal95c80702017-01-27 09:54:41 -0800181{
182 VALIDATE_SUCCESS(this->data, "Should get accepted, as interest brings the certs");
Davide Pesavento2ca5e792020-06-16 22:52:23 -0400183 BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 4); // since interest for bundle fails, each cert is retrieved
Manika Mittal95c80702017-01-27 09:54:41 -0800184
185 bool toggle = true;
186 for (const auto& sentInterest : this->face.sentInterests) {
187 if (toggle) {
188 // every alternate interest is going to be that of a bundle
189 BOOST_CHECK(this->bundleRegexMatcher->match(sentInterest.getName(), 0, sentInterest.getName().size()));
190 }
191 else {
192 BOOST_CHECK(!this->bundleRegexMatcher->match(sentInterest.getName(), 0, sentInterest.getName().size()));
193 }
194 toggle = !toggle;
195 }
196}
197
198BOOST_AUTO_TEST_SUITE_END() // TestCertificateBundleFetcher
Manika Mittal95c80702017-01-27 09:54:41 -0800199BOOST_AUTO_TEST_SUITE_END() // Security
200
201} // namespace tests
Alexander Afanasyev09236c22020-06-03 13:42:38 -0400202} // inline namespace v2
Manika Mittal95c80702017-01-27 09:54:41 -0800203} // namespace security
204} // namespace ndn