blob: 293cff0b6e94596a1de213ecbae992b91533a102 [file] [log] [blame]
Shock Jiang0b165f42014-10-24 09:08:09 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yumin Xiaacd21332016-11-28 22:54:48 -08003 * Copyright (c) 2014-2017, Regents of the University of California.
Shock Jiang0b165f42014-10-24 09:08:09 -07004 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "validator.hpp"
Alexander Afanasyevfde570c2016-12-19 16:02:55 -080021
22#include "test-common.hpp"
Shock Jiang0b165f42014-10-24 09:08:09 -070023
24namespace ndn {
25namespace ndns {
26namespace tests {
Alexander Afanasyevc7c99002015-10-09 17:27:30 -070027
28NDNS_LOG_INIT("ValidatorTest")
Shock Jiang0b165f42014-10-24 09:08:09 -070029
30BOOST_AUTO_TEST_SUITE(Validator)
31
Alexander Afanasyevfde570c2016-12-19 16:02:55 -080032class Fixture : public IdentityManagementFixture
Shock Jiang0b165f42014-10-24 09:08:09 -070033{
34public:
35 Fixture()
36 : m_testId1("/test02")
37 , m_testId2("/test02/ndn")
38 , m_testId3("/test02/ndn/edu")
39 , m_randomId("/test03")
40 , m_version(name::Component::fromVersion(0))
Junxiao Shibbf7ac82016-07-14 14:45:15 +000041 , m_face(m_keyChain, {false, true})
Shock Jiang0b165f42014-10-24 09:08:09 -070042 {
Shock Jiang0b165f42014-10-24 09:08:09 -070043 m_randomDsk = createRoot(m_randomId); // generate a root cert
44
45 m_dsk1 = createRoot(m_testId1); // replace to root cert
46 m_dsk2 = createIdentity(m_testId2, m_dsk1);
47 m_dsk3 = createIdentity(m_testId3, m_dsk2);
48
49 m_selfSignCert = m_keyChain.generateRsaKeyPair(m_testId3, false);
50 shared_ptr<IdentityCertificate> cert = m_keyChain.selfSign(m_selfSignCert);
51 m_selfSignCert = cert->getName();
52 m_keyChain.addCertificate(*cert);
53 NDNS_LOG_TRACE("add cert: " << cert->getName() << " to KeyChain");
54
Junxiao Shibbf7ac82016-07-14 14:45:15 +000055 m_face.onSendInterest.connect(bind(&Fixture::respondInterest, this, _1));
Shock Jiang0b165f42014-10-24 09:08:09 -070056 }
57
58 ~Fixture()
59 {
Junxiao Shibbf7ac82016-07-14 14:45:15 +000060 m_face.getIoService().stop();
61 m_face.shutdown();
Shock Jiang0b165f42014-10-24 09:08:09 -070062 }
63
64 const Name
65 createIdentity(const Name& id, const Name& parentCertName)
66 {
67 Name kskCertName = m_keyChain.createIdentity(id);
68 Name kskName = m_keyChain.getDefaultKeyNameForIdentity(id);
69 m_keyChain.deleteCertificate(kskCertName);
70 auto kskCert = createCertificate(kskName, parentCertName);
71
72 Name dskName = m_keyChain.generateRsaKeyPair(id, false);
73 auto dskCert = createCertificate(dskName, kskCert);
74 return dskCert;
75 }
76
77 const Name
78 createRoot(const Name& root)
79 {
80 m_rootCert = m_keyChain.createIdentity(root);
81 ndn::io::save(*(m_keyChain.getCertificate(m_rootCert)), TEST_CONFIG_PATH "/anchors/root.cert");
82 NDNS_LOG_TRACE("save root cert "<< m_rootCert <<
83 " to: " << TEST_CONFIG_PATH "/anchors/root.cert");
84 Name dsk = m_keyChain.generateRsaKeyPair(root, false);
85 auto cert = createCertificate(dsk, m_rootCert);
86 return cert;
87 }
88
89
90 const Name
91 createCertificate(const Name& keyName, const Name& parentCertName)
92 {
93 std::vector<CertificateSubjectDescription> desc;
94 time::system_clock::TimePoint notBefore = time::system_clock::now();
95 time::system_clock::TimePoint notAfter = notBefore + time::days(365);
96 desc.push_back(CertificateSubjectDescription(oid::ATTRIBUTE_NAME,
97 "Signer: " + parentCertName.toUri()));
98 shared_ptr<IdentityCertificate> cert =
99 m_keyChain.prepareUnsignedIdentityCertificate(keyName, parentCertName,
100 notBefore, notAfter, desc);
101
102 Name tmp = cert->getName().getPrefix(-1).append(m_version);
103 cert->setName(tmp);
104 m_keyChain.sign(*cert, parentCertName);
105 m_keyChain.addCertificateAsKeyDefault(*cert);
106 NDNS_LOG_TRACE("add cert: " << cert->getName() << " to KeyChain");
107 return cert->getName();
108 }
109
110
111 void
Shock Jiang0e2aee02014-11-17 11:19:36 -0800112 respondInterest(const Interest& interest)
Shock Jiang0b165f42014-10-24 09:08:09 -0700113 {
114 Name certName = interest.getName();
115 if (certName.isPrefixOf(m_selfSignCert)) {
116 // self-sign cert's version number is not m_version
117 certName = m_selfSignCert;
118 } else {
119 certName.append(m_version);
120 }
121 NDNS_LOG_TRACE("validator needs: " << certName);
122 BOOST_CHECK_EQUAL(m_keyChain.doesCertificateExist(certName), true);
123 auto cert = m_keyChain.getCertificate(certName);
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000124 m_face.getIoService().post([this, cert] {
Yumin Xiaacd21332016-11-28 22:54:48 -0800125 m_face.receive(*cert);
Alexander Afanasyeva81266c2015-05-10 20:18:57 -0700126 });
Shock Jiang0b165f42014-10-24 09:08:09 -0700127 }
128
129public:
130 Name m_testId1;
131 Name m_testId2;
132 Name m_testId3;
133 Name m_randomId;
134
135 Name m_rootCert;
136
Shock Jiang0b165f42014-10-24 09:08:09 -0700137 Name m_dsk1;
138 Name m_dsk2;
139 Name m_dsk3;
140
141 Name m_selfSignCert;
142
143 Name m_randomDsk;
144
145 name::Component m_version;
146
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000147 ndn::util::DummyClientFace m_face;
Shock Jiang0b165f42014-10-24 09:08:09 -0700148};
149
150
151BOOST_FIXTURE_TEST_CASE(Basic, Fixture)
152{
153 // validator must be created after root key is saved to the target
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000154 ndns::Validator validator(m_face, TEST_CONFIG_PATH "/" "validator.conf");
Shock Jiang0b165f42014-10-24 09:08:09 -0700155
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800156 Name dataName;
157 dataName
158 .append(m_testId3)
159 .append("NDNS")
Shock Jiang0b165f42014-10-24 09:08:09 -0700160 .append("rrLabel")
161 .append("rrType")
162 .appendVersion();
163 shared_ptr<Data> data = make_shared<Data>(dataName);
164 m_keyChain.sign(*data, m_dsk3);
165
166 bool hasValidated = false;
167 validator.validate(*data,
168 [&] (const shared_ptr<const Data>& data) {
169 hasValidated = true;
170 BOOST_CHECK(true);
171 },
172 [&] (const shared_ptr<const Data>& data, const std::string& str) {
173 hasValidated = true;
174 BOOST_CHECK(false);
175 });
176
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000177 m_face.processEvents(time::milliseconds(-1));
Shock Jiang0b165f42014-10-24 09:08:09 -0700178
179 BOOST_CHECK_EQUAL(hasValidated, true);
180
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800181 dataName = Name();
182 dataName
183 .append(m_testId2)
184 .append("KEY")
Shock Jiang0b165f42014-10-24 09:08:09 -0700185 .append("rrLabel")
186 .append("ID-CERT")
187 .appendVersion();
188 data = make_shared<Data>(dataName);
189 m_keyChain.sign(*data, m_dsk3); // key's owner's name is longer than data owner's
190
191 hasValidated = false;
192 validator.validate(*data,
193 [&] (const shared_ptr<const Data>& data) {
194 hasValidated = true;
195 BOOST_CHECK(false);
196 },
197 [&] (const shared_ptr<const Data>& data, const std::string& str) {
198 hasValidated = true;
199 BOOST_CHECK(true);
200 });
201
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000202 m_face.processEvents(time::milliseconds(-1));
Shock Jiang0b165f42014-10-24 09:08:09 -0700203 // cannot pass verification due to key's owner's name is longer than data owner's
204 BOOST_CHECK_EQUAL(hasValidated, true);
205
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800206 dataName = Name();
207 dataName
208 .append(m_testId3)
209 .append("KEY")
Shock Jiang0b165f42014-10-24 09:08:09 -0700210 .append("rrLabel")
211 .append("ID-CERT")
212 .appendVersion();
213 data = make_shared<Data>(dataName);
214 m_keyChain.sign(*data, m_selfSignCert);
215
216 hasValidated = false;
217 validator.validate(*data,
218 [&] (const shared_ptr<const Data>& data) {
219 hasValidated = true;
220 BOOST_CHECK(false);
221 },
222 [&] (const shared_ptr<const Data>& data, const std::string& str) {
223 hasValidated = true;
224 BOOST_CHECK(true);
225 });
226
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000227 m_face.processEvents(time::milliseconds(-1));
Shock Jiang0b165f42014-10-24 09:08:09 -0700228 // cannot pass due to self-sign cert is used
229 BOOST_CHECK_EQUAL(hasValidated, true);
230
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800231 dataName = Name();
232 dataName
233 .append(m_testId2)
234 .append("KEY")
Shock Jiang0b165f42014-10-24 09:08:09 -0700235 .append("rrLabel")
236 .append("ID-CERT")
237 .appendVersion();
238 data = make_shared<Data>(dataName);
239 m_keyChain.sign(*data, m_randomDsk);
240
241 hasValidated = false;
242 validator.validate(*data,
243 [&] (const shared_ptr<const Data>& data) {
244 hasValidated = true;
245 BOOST_CHECK(false);
246 },
247 [&] (const shared_ptr<const Data>& data, const std::string& str) {
248 hasValidated = true;
249 BOOST_CHECK(true);
250 });
251
Junxiao Shibbf7ac82016-07-14 14:45:15 +0000252 m_face.processEvents(time::milliseconds(-1));
Shock Jiang0b165f42014-10-24 09:08:09 -0700253 // cannot pass due to a totally mismatched key
254 BOOST_CHECK_EQUAL(hasValidated, true);
255}
256
257BOOST_AUTO_TEST_SUITE_END()
258
259} // namespace tests
260} // namespace ndns
261} // namespace ndn