blob: 406ef0c6532f25e3b4b4d0ac30c1f646bde87f2e [file] [log] [blame]
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, The University of Memphis,
Vince Lehmanc2acdcb2015-04-29 11:14:35 -05004 * Regents of the University of California,
5 * Arizona Board of Regents.
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -07006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070020 **/
21
22#include "validator.hpp"
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050023
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070024#include <ndn-cxx/security/certificate-cache-ttl.hpp>
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050025#include <ndn-cxx/security/key-chain.hpp>
26#include <ndn-cxx/util/scheduler.hpp>
27
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070028#include "boost-test.hpp"
Vince Lehman0a7da612014-10-29 14:39:29 -050029#include "common.hpp"
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050030#include "security/certificate-store.hpp"
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070031
32namespace nlsr {
33
34namespace test {
35
36BOOST_AUTO_TEST_SUITE(TestValidator)
37
38struct ValidatorFixture
39{
40 ValidatorFixture()
41 : m_face2(m_face.getIoService())
42 , m_scheduler(m_face.getIoService())
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050043 , m_keyPrefix("/ndn/broadcast/KEYS")
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070044 , m_certificateCache(new ndn::CertificateCacheTtl(m_face.getIoService()))
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050045 , m_validator(m_face2, ndn::Name("/ndn/broadcast"), m_certificateCache, m_certStore)
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070046 , m_identity("/TestValidator/NLSR")
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050047 , m_wasValidated(false)
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070048 {
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050049 m_face.setInterestFilter(m_keyPrefix,
dmcoomes9f936662017-03-02 10:33:09 -060050 std::bind(&ValidatorFixture::onKeyInterest, this, _1, _2),
51 std::bind(&ValidatorFixture::onKeyPrefixRegSuccess, this, _1),
52 std::bind(&ValidatorFixture::registrationFailed, this, _1, _2));
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070053
54 m_keyChain.createIdentity(m_identity);
55 ndn::Name certName = m_keyChain.getDefaultCertificateNameForIdentity(m_identity);
56 m_cert = m_keyChain.getCertificate(certName);
57 ndn::io::save(*m_cert, "trust-anchor.cert");
58
59 const std::string CONFIG =
60 "rule\n"
61 "{\n"
62 " id \"NSLR Hello Rule\"\n"
63 " for data\n"
64 " filter\n"
65 " {\n"
66 " type name\n"
67 " regex ^[^<NLSR><INFO>]*<NLSR><INFO><><>$\n"
68 " }\n"
69 " checker\n"
70 " {\n"
71 " type customized\n"
72 " sig-type rsa-sha256\n"
73 " key-locator\n"
74 " {\n"
75 " type name\n"
76 " hyper-relation\n"
77 " {\n"
78 " k-regex ^([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><ID-CERT>$\n"
79 " k-expand \\\\1\n"
80 " h-relation equal\n"
81 " p-regex ^([^<NLSR><INFO>]*)<NLSR><INFO><><>$\n"
82 " p-expand \\\\1\n"
83 " }\n"
84 " }\n"
85 " }\n"
86 "}\n"
87 "rule\n"
88 "{\n"
89 " id \"Single Rule\"\n"
90 " for data\n"
91 " filter\n"
92 " {\n"
93 " type name\n"
Vince Lehmanc2acdcb2015-04-29 11:14:35 -050094 " regex ^<TestValidator>([^<KEY><NLSR>]*)<NLSR><KEY><ksk-.*><><>$\n"
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -070095 " }\n"
96 " checker\n"
97 " {\n"
98 " type fixed-signer\n"
99 " sig-type rsa-sha256\n"
100 " signer\n"
101 " {\n"
102 " type file\n"
103 " file-name \"trust-anchor.cert\"\n"
104 " }\n"
105 " }\n"
106 "}\n";
107
108 const boost::filesystem::path CONFIG_PATH =
109 (boost::filesystem::current_path() / std::string("unit-test.conf"));
110
111 m_validator.load(CONFIG, CONFIG_PATH.native());
112 }
113
114 ~ValidatorFixture()
115 {
116 m_keyChain.deleteIdentity(m_identity);
117
118 const boost::filesystem::path CERT_PATH =
119 (boost::filesystem::current_path() / std::string("trust-anchor.cert"));
120 boost::filesystem::remove(CERT_PATH);
121 }
122
123 void
124 onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
125 {
126 const ndn::Name& interestName = interest.getName();
127
128 ndn::Name certName = interestName.getSubName(name.size());
129
130 if (certName[-2].toUri() == "ID-CERT")
131 {
132 certName = certName.getPrefix(-1);
133 }
134 else if (certName[-1].toUri() != "ID-CERT")
135 return; //Wrong key interest.
136
137 if (certName != m_cert->getName().getPrefix(-1))
138 return; //No such a cert
139
dmcoomes9f936662017-03-02 10:33:09 -0600140 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(interestName);
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500141 data->setContent(m_cert->wireEncode());
142 m_keyChain.signWithSha256(*data);
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700143
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500144 m_face.put(*data);
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700145 }
146
147 void
148 onKeyPrefixRegSuccess(const ndn::Name& name)
149 {
150 BOOST_REQUIRE(true);
151 }
152
153 void
154 registrationFailed(const ndn::Name& name, const std::string& msg)
155 {
156 std::cerr << "Failure Info: " << msg << std::endl;
157 BOOST_REQUIRE(false);
158 }
159
160 void
dmcoomes9f936662017-03-02 10:33:09 -0600161 onValidated(const std::shared_ptr<const ndn::Data>& data)
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700162 {
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500163 m_wasValidated = true;
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700164 }
165
166 void
dmcoomes9f936662017-03-02 10:33:09 -0600167 onValidationFailed(const std::shared_ptr<const ndn::Data>& data,
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700168 const std::string& failureInfo)
169 {
170 std::cerr << "Failure Info: " << failureInfo << std::endl;
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500171 m_wasValidated = false;
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700172 }
173
174 void
dmcoomes9f936662017-03-02 10:33:09 -0600175 validate(const std::shared_ptr<const ndn::Data>& data)
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700176 {
177 m_validator.validate(*data,
dmcoomes9f936662017-03-02 10:33:09 -0600178 std::bind(&ValidatorFixture::onValidated, this, _1),
179 std::bind(&ValidatorFixture::onValidationFailed, this, _1, _2));
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700180 }
181
182 void
183 terminate()
184 {
185 m_face.getIoService().stop();
186 }
187
188protected:
189 ndn::Face m_face;
190 ndn::Face m_face2;
191 ndn::Scheduler m_scheduler;
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500192 const ndn::Name m_keyPrefix;
dmcoomes9f936662017-03-02 10:33:09 -0600193 std::shared_ptr<ndn::CertificateCacheTtl> m_certificateCache;
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500194 security::CertificateStore m_certStore;
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700195 nlsr::Validator m_validator;
196
197 ndn::KeyChain m_keyChain;
198 ndn::Name m_identity;
dmcoomes9f936662017-03-02 10:33:09 -0600199 std::shared_ptr<ndn::IdentityCertificate> m_cert;
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500200
201 bool m_wasValidated;
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700202};
203
204BOOST_FIXTURE_TEST_CASE(InfoCertFetch, ValidatorFixture)
205{
206 ndn::Name dataName = m_identity;
207 dataName.append("INFO").append("neighbor").append("version");
dmcoomes9f936662017-03-02 10:33:09 -0600208 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700209 m_keyChain.signByIdentity(*data, m_identity);
210
211 m_scheduler.scheduleEvent(ndn::time::milliseconds(200),
dmcoomes9f936662017-03-02 10:33:09 -0600212 std::bind(&ValidatorFixture::validate, this, data));
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700213 m_scheduler.scheduleEvent(ndn::time::milliseconds(1000),
dmcoomes9f936662017-03-02 10:33:09 -0600214 std::bind(&ValidatorFixture::terminate, this));
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700215 BOOST_REQUIRE_NO_THROW(m_face.processEvents());
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500216
217 BOOST_CHECK(m_wasValidated);
218}
219
220BOOST_FIXTURE_TEST_CASE(CertificateStorage, ValidatorFixture)
221{
Alexander Afanasyev4c2bb362017-03-14 12:29:19 -0700222 std::vector<ndn::security::v1::CertificateSubjectDescription> subjectDescription;
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500223
224 // Create an operator identity
225 ndn::Name opIdentity("/TestValidator/operator/NLSR");
226 m_keyChain.createIdentity(opIdentity);
227
228 // Create an operator cert signed by the trust anchor
229 ndn::Name keyName = m_keyChain.generateRsaKeyPairAsDefault(opIdentity, true);
dmcoomes9f936662017-03-02 10:33:09 -0600230 std::shared_ptr<ndn::IdentityCertificate> opCert =
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500231 m_keyChain.prepareUnsignedIdentityCertificate(keyName,
232 m_identity,
233 ndn::time::system_clock::now(),
234 ndn::time::system_clock::now()
235 + ndn::time::days(1),
236 subjectDescription);
237 m_keyChain.signByIdentity(*opCert, m_identity);
238 m_keyChain.addCertificateAsIdentityDefault(*opCert);
239
240 // Sign data with operator cert
241 ndn::Name dataName = opIdentity;
242 dataName.append("INFO").append("neighbor").append("version");
dmcoomes9f936662017-03-02 10:33:09 -0600243 std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500244 m_keyChain.signByIdentity(*data, opIdentity);
245
246 // Check without cert in CertificateStore
247 m_scheduler.scheduleEvent(ndn::time::milliseconds(200),
dmcoomes9f936662017-03-02 10:33:09 -0600248 std::bind(&ValidatorFixture::validate, this, data));
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500249 m_scheduler.scheduleEvent(ndn::time::milliseconds(1000),
dmcoomes9f936662017-03-02 10:33:09 -0600250 std::bind(&ValidatorFixture::terminate, this));
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500251
252 BOOST_REQUIRE_NO_THROW(m_face.processEvents());
253 BOOST_CHECK_EQUAL(m_wasValidated, false);
254
255 // Check with cert in CertificateStore
256 m_certStore.insert(opCert);
257
258 m_scheduler.scheduleEvent(ndn::time::milliseconds(200),
dmcoomes9f936662017-03-02 10:33:09 -0600259 std::bind(&ValidatorFixture::validate, this, data));
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500260 m_scheduler.scheduleEvent(ndn::time::milliseconds(1000),
dmcoomes9f936662017-03-02 10:33:09 -0600261 std::bind(&ValidatorFixture::terminate, this));
Vince Lehmanc2acdcb2015-04-29 11:14:35 -0500262
263 BOOST_REQUIRE_NO_THROW(m_face.processEvents());
264 BOOST_CHECK(m_wasValidated);
265
266 // Cleanup
267 m_keyChain.deleteIdentity(opIdentity);
Yingdi Yu6a3a4dd2014-06-20 14:10:39 -0700268}
269
270BOOST_AUTO_TEST_SUITE_END()
271
272} // namespace test
273} // namespace nlsr