blob: 800fc2a8dfa8559fce20cab5cddfa4c4b3ac0a1e [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <yingdi0@cs.ucla.edu>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070022 */
23
24#include "security/validator-config.hpp"
25
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070026#include "security/key-chain.hpp"
27#include "util/io.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070028#include "util/scheduler.hpp"
29
30#include <boost/asio.hpp>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070031
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070032#include "boost-test.hpp"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070033
34using namespace std;
35
36namespace ndn {
37
38BOOST_AUTO_TEST_SUITE(TestValidatorConfig)
39
40void
41onValidated(const shared_ptr<const Data>& data)
42{
43 BOOST_CHECK(true);
44}
45
46void
47onValidationFailed(const shared_ptr<const Data>& data, const string& failureInfo)
48{
49 std::cerr << "Failure Info: " << failureInfo << std::endl;
50 BOOST_CHECK(false);
51}
52
53void
54onIntentionalFailureValidated(const shared_ptr<const Data>& data)
55{
56 BOOST_CHECK(false);
57}
58
59void
60onIntentionalFailureInvalidated(const shared_ptr<const Data>& data, const string& failureInfo)
61{
62 BOOST_CHECK(true);
63}
64
65void
66onValidated2(const shared_ptr<const Interest>& interest)
67{
68 BOOST_CHECK(true);
69}
70
71void
72onValidationFailed2(const shared_ptr<const Interest>& interest, const string& failureInfo)
73{
74 std::cerr << "Interest Name: " << interest->getName() << std::endl;
75 std::cerr << "Failure Info: " << failureInfo << std::endl;
76 BOOST_CHECK(false);
77}
78
79void
80onIntentionalFailureValidated2(const shared_ptr<const Interest>& interest)
81{
82 BOOST_CHECK(false);
83}
84
85void
86onIntentionalFailureInvalidated2(const shared_ptr<const Interest>& interest,
87 const string& failureInfo)
88{
89 BOOST_CHECK(true);
90}
91
92BOOST_AUTO_TEST_CASE(NameFilter)
93{
94 KeyChain keyChain;
95
96 Name identity("/TestValidatorConfig/NameFilter");
97 identity.appendVersion();
98 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
99 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
100 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
101 io::save(*idCert, "trust-anchor-1.cert");
102
103 Name dataName1("/simple/equal");
104 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
105 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
106
107 Name dataName2("/simple/different");
108 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
109 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
110
111 std::string CONFIG_1 =
112 "rule\n"
113 "{\n"
114 " id \"Simple Rule\"\n"
115 " for data\n"
116 " filter"
117 " {\n"
118 " type name\n"
119 " name /simple/equal\n"
120 " relation equal\n"
121 " }\n"
122 " checker\n"
123 " {\n"
124 " type customized\n"
125 " sig-type rsa-sha256\n"
126 " key-locator\n"
127 " {\n"
128 " type name\n"
129 " name ";
130
131 std::string CONFIG_2 =
132 "\n"
133 " relation equal\n"
134 " }\n"
135 " }\n"
136 "}\n"
137 "trust-anchor\n"
138 "{\n"
139 " type file\n"
140 " file-name \"trust-anchor-1.cert\"\n"
141 "}\n";
142 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
143
144 const boost::filesystem::path CONFIG_PATH =
145 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
146
147
Yingdi Yu96e64062014-04-15 19:57:33 -0700148 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700149 ValidatorConfig validator(face);
150 validator.load(CONFIG, CONFIG_PATH.native());
151
152 validator.validate(*data1,
153 bind(&onValidated, _1),
154 bind(&onValidationFailed, _1, _2));
155
156 validator.validate(*data2,
157 bind(&onIntentionalFailureValidated, _1),
158 bind(&onIntentionalFailureInvalidated, _1, _2));
159
160 keyChain.deleteIdentity(identity);
161
162 const boost::filesystem::path CERT_PATH =
163 (boost::filesystem::current_path() / std::string("trust-anchor-1.cert"));
164 boost::filesystem::remove(CERT_PATH);
165}
166
167BOOST_AUTO_TEST_CASE(NameFilter2)
168{
169 KeyChain keyChain;
170
171 Name identity("/TestValidatorConfig/NameFilter2");
172 identity.appendVersion();
173 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
174 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
175 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
176 io::save(*idCert, "trust-anchor-2.cert");
177
178 Name dataName1("/simple/isPrefixOf");
179 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
180 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
181
182 Name dataName2("/simple/notPrefixOf");
183 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
184 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
185
186 Name dataName3("/simple/isPrefixOf/anotherLevel");
187 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
188 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
189
190 std::string CONFIG_1 =
191 "rule\n"
192 "{\n"
193 " id \"Simple2 Rule\"\n"
194 " for data\n"
195 " filter"
196 " {\n"
197 " type name\n"
198 " name /simple/isPrefixOf\n"
199 " relation is-prefix-of\n"
200 " }\n"
201 " checker\n"
202 " {\n"
203 " type customized\n"
204 " sig-type rsa-sha256\n"
205 " key-locator\n"
206 " {\n"
207 " type name\n"
208 " name ";
209
210 std::string CONFIG_2 =
211 "\n"
212 " relation equal\n"
213 " }\n"
214 " }\n"
215 "}\n"
216 "trust-anchor\n"
217 "{\n"
218 " type file\n"
219 " file-name \"trust-anchor-2.cert\"\n"
220 "}\n";
221 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
222
223 const boost::filesystem::path CONFIG_PATH =
224 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
225
226
Yingdi Yu96e64062014-04-15 19:57:33 -0700227 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700228 ValidatorConfig validator(face);
229 validator.load(CONFIG, CONFIG_PATH.native());
230
231 validator.validate(*data1,
232 bind(&onValidated, _1),
233 bind(&onValidationFailed, _1, _2));
234
235 validator.validate(*data2,
236 bind(&onIntentionalFailureValidated, _1),
237 bind(&onIntentionalFailureInvalidated, _1, _2));
238
239 validator.validate(*data3,
240 bind(&onValidated, _1),
241 bind(&onValidationFailed, _1, _2));
242
243 keyChain.deleteIdentity(identity);
244
245 const boost::filesystem::path CERT_PATH =
246 (boost::filesystem::current_path() / std::string("trust-anchor-2.cert"));
247 boost::filesystem::remove(CERT_PATH);
248}
249
250BOOST_AUTO_TEST_CASE(NameFilter3)
251{
252 KeyChain keyChain;
253
254 Name identity("/TestValidatorConfig/NameFilter3");
255 identity.appendVersion();
256 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
257 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
258 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
259 io::save(*idCert, "trust-anchor-3.cert");
260
261 Name dataName1("/simple/isStrictPrefixOf");
262 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
263 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
264
265 Name dataName2("/simple");
266 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
267 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
268
269 Name dataName3("/simple/isStrictPrefixOf/anotherLevel");
270 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
271 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
272
273 std::string CONFIG_1 =
274 "rule\n"
275 "{\n"
276 " id \"Simple3 Rule\"\n"
277 " for data\n"
278 " filter"
279 " {\n"
280 " type name\n"
281 " name /simple/isStrictPrefixOf\n"
282 " relation is-strict-prefix-of\n"
283 " }\n"
284 " checker\n"
285 " {\n"
286 " type customized\n"
287 " sig-type rsa-sha256\n"
288 " key-locator\n"
289 " {\n"
290 " type name\n"
291 " name ";
292
293 std::string CONFIG_2 =
294 "\n"
295 " relation equal\n"
296 " }\n"
297 " }\n"
298 "}\n"
299 "trust-anchor\n"
300 "{\n"
301 " type file\n"
302 " file-name \"trust-anchor-3.cert\"\n"
303 "}\n";
304 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
305
306 const boost::filesystem::path CONFIG_PATH =
307 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
308
309
Yingdi Yu96e64062014-04-15 19:57:33 -0700310 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700311 ValidatorConfig validator(face);
312 validator.load(CONFIG, CONFIG_PATH.native());
313
314 validator.validate(*data1,
315 bind(&onIntentionalFailureValidated, _1),
316 bind(&onIntentionalFailureInvalidated, _1, _2));
317
318 validator.validate(*data2,
319 bind(&onIntentionalFailureValidated, _1),
320 bind(&onIntentionalFailureInvalidated, _1, _2));
321
322 validator.validate(*data3,
323 bind(&onValidated, _1),
324 bind(&onValidationFailed, _1, _2));
325
326 keyChain.deleteIdentity(identity);
327
328 const boost::filesystem::path CERT_PATH =
329 (boost::filesystem::current_path() / std::string("trust-anchor-3.cert"));
330 boost::filesystem::remove(CERT_PATH);
331}
332
333BOOST_AUTO_TEST_CASE(NameFilter4)
334{
335 KeyChain keyChain;
336
337 Name identity("/TestValidatorConfig/NameFilter4");
338 identity.appendVersion();
339 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
340 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
341 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
342 io::save(*idCert, "trust-anchor-4.cert");
343
344 Name dataName1("/simple/regex");
345 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
346 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
347
348 Name dataName2("/simple/regex-wrong");
349 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
350 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
351
352 Name dataName3("/simple/regex/correct");
353 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
354 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
355
356 std::string CONFIG_1 =
357 "rule\n"
358 "{\n"
359 " id \"Simple3 Rule\"\n"
360 " for data\n"
361 " filter"
362 " {\n"
363 " type name\n"
364 " regex ^<simple><regex>\n"
365 " }\n"
366 " checker\n"
367 " {\n"
368 " type customized\n"
369 " sig-type rsa-sha256\n"
370 " key-locator\n"
371 " {\n"
372 " type name\n"
373 " name ";
374
375 std::string CONFIG_2 =
376 "\n"
377 " relation equal\n"
378 " }\n"
379 " }\n"
380 "}\n"
381 "trust-anchor\n"
382 "{\n"
383 " type file\n"
384 " file-name \"trust-anchor-4.cert\"\n"
385 "}\n";
386 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
387
388 const boost::filesystem::path CONFIG_PATH =
389 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
390
391
Yingdi Yu96e64062014-04-15 19:57:33 -0700392 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700393 ValidatorConfig validator(face);
394 validator.load(CONFIG, CONFIG_PATH.native());
395
396 validator.validate(*data1,
397 bind(&onValidated, _1),
398 bind(&onValidationFailed, _1, _2));
399
400 validator.validate(*data2,
401 bind(&onIntentionalFailureValidated, _1),
402 bind(&onIntentionalFailureInvalidated, _1, _2));
403
404 validator.validate(*data3,
405 bind(&onValidated, _1),
406 bind(&onValidationFailed, _1, _2));
407
408 keyChain.deleteIdentity(identity);
409
410 const boost::filesystem::path CERT_PATH =
411 (boost::filesystem::current_path() / std::string("trust-anchor-4.cert"));
412 boost::filesystem::remove(CERT_PATH);
413}
414
415BOOST_AUTO_TEST_CASE(KeyLocatorNameChecker1)
416{
417 KeyChain keyChain;
418
419 Name identity("/TestValidatorConfig/KeyLocatorNameChecker1");
420 identity.appendVersion();
421 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
422 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
423 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
424 io::save(*idCert, "trust-anchor-5.cert");
425
426 Name dataName1 = identity;
427 dataName1.append("1");
428 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
429 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
430
431 Name dataName2 = identity;
432 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
433 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
434
435 Name dataName3("/TestValidatorConfig/KeyLocatorNameChecker1");
436 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
437 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
438
439 const std::string CONFIG =
440 "rule\n"
441 "{\n"
442 " id \"Simple3 Rule\"\n"
443 " for data\n"
444 " checker\n"
445 " {\n"
446 " type customized\n"
447 " sig-type rsa-sha256\n"
448 " key-locator\n"
449 " {\n"
450 " type name\n"
451 " hyper-relation\n"
452 " {\n"
453 " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$\n"
454 " k-expand \\\\1\\\\2\n"
455 " h-relation is-strict-prefix-of\n"
456 " p-regex ^(<>*)$\n"
457 " p-expand \\\\1\n"
458 " }\n"
459 " }\n"
460 " }\n"
461 "}\n"
462 "trust-anchor\n"
463 "{\n"
464 " type file\n"
465 " file-name \"trust-anchor-5.cert\"\n"
466 "}\n";
467 const boost::filesystem::path CONFIG_PATH =
468 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
469
470
Yingdi Yu96e64062014-04-15 19:57:33 -0700471 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700472 ValidatorConfig validator(face);
473 validator.load(CONFIG, CONFIG_PATH.native());
474
475 validator.validate(*data1,
476 bind(&onValidated, _1),
477 bind(&onValidationFailed, _1, _2));
478
479 validator.validate(*data2,
480 bind(&onIntentionalFailureValidated, _1),
481 bind(&onIntentionalFailureInvalidated, _1, _2));
482
483 validator.validate(*data3,
484 bind(&onIntentionalFailureValidated, _1),
485 bind(&onIntentionalFailureInvalidated, _1, _2));
486
487 keyChain.deleteIdentity(identity);
488
489 const boost::filesystem::path CERT_PATH =
490 (boost::filesystem::current_path() / std::string("trust-anchor-5.cert"));
491 boost::filesystem::remove(CERT_PATH);
492}
493
494struct FacesFixture
495{
496 FacesFixture()
497 : regPrefixId(0)
498 , regPrefixId2(0)
499 {}
500
501 void
502 onInterest(shared_ptr<Face> face, shared_ptr<Data> data)
503 {
504 face->put(*data);
505 face->unsetInterestFilter(regPrefixId);
506 }
507
508 void
509 onInterest2(shared_ptr<Face> face, shared_ptr<Data> data)
510 {
511 face->put(*data);
512 face->unsetInterestFilter(regPrefixId2);
513 }
514
515 void
516 onRegFailed()
517 {}
518
519 void
520 validate1(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
521 {
522 validator->validate(*data,
523 bind(&onValidated, _1),
524 bind(&onValidationFailed, _1, _2));
525 }
526
527 void
528 validate2(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
529 {
530 validator->validate(*data,
531 bind(&onIntentionalFailureValidated, _1),
532 bind(&onIntentionalFailureInvalidated, _1, _2));
533 }
534
535 void
536 validate3(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
537 {
538 validator->validate(*interest,
539 bind(&onValidated2, _1),
540 bind(&onValidationFailed2, _1, _2));
541 }
542
543 void
544 validate4(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
545 {
546 validator->validate(*interest,
547 bind(&onIntentionalFailureValidated2, _1),
548 bind(&onIntentionalFailureInvalidated2, _1, _2));
549 }
550
551 void
552 terminate(shared_ptr<Face> face)
553 {
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700554 face->getIoService().stop();
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700555 }
556
557 const RegisteredPrefixId* regPrefixId;
558 const RegisteredPrefixId* regPrefixId2;
559};
560
561BOOST_FIXTURE_TEST_CASE(HierarchicalChecker, FacesFixture)
562{
563 KeyChain keyChain;
564 std::vector<CertificateSubjectDescription> subjectDescription;
565
566 Name root("/TestValidatorConfig");
567 Name rootCertName = keyChain.createIdentity(root);
568 shared_ptr<IdentityCertificate> rootCert =
569 keyChain.getCertificate(rootCertName);
570 io::save(*rootCert, "trust-anchor-6.cert");
571
572
573 Name sld("/TestValidatorConfig/HierarchicalChecker");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700574 Name sldKeyName = keyChain.generateRsaKeyPairAsDefault(sld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700575 shared_ptr<IdentityCertificate> sldCert =
576 keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
577 root,
578 time::system_clock::now(),
579 time::system_clock::now() + time::days(7300),
580 subjectDescription);
581 keyChain.signByIdentity(*sldCert, root);
582 keyChain.addCertificateAsIdentityDefault(*sldCert);
583
584 Name nld("/TestValidatorConfig/HierarchicalChecker/NextLevel");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700585 Name nldKeyName = keyChain.generateRsaKeyPairAsDefault(nld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700586 shared_ptr<IdentityCertificate> nldCert =
587 keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
588 sld,
589 time::system_clock::now(),
590 time::system_clock::now() + time::days(7300),
591 subjectDescription);
592 keyChain.signByIdentity(*nldCert, sld);
593 keyChain.addCertificateAsIdentityDefault(*nldCert);
594
595 shared_ptr<Face> face = make_shared<Face>();
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700596 Face face2(face->getIoService());
597 Scheduler scheduler(face->getIoService());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700598
599 scheduler.scheduleEvent(time::seconds(1),
600 bind(&FacesFixture::terminate, this, face));
601
602 regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700603 bind(&FacesFixture::onInterest, this, face, sldCert),
604 RegisterPrefixSuccessCallback(),
605 bind(&FacesFixture::onRegFailed, this));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700606
607 regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
608 bind(&FacesFixture::onInterest2, this, face, nldCert),
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700609 RegisterPrefixSuccessCallback(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700610 bind(&FacesFixture::onRegFailed, this));
611
612 Name dataName1 = nld;
613 dataName1.append("data1");
614 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
615 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, nld));
616
617 Name dataName2("/ConfValidatorTest");
618 dataName2.append("data1");
619 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
620 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, nld));
621
622
623 const std::string CONFIG =
624 "rule\n"
625 "{\n"
626 " id \"Simple3 Rule\"\n"
627 " for data\n"
628 " checker\n"
629 " {\n"
630 " type hierarchical\n"
631 " sig-type rsa-sha256\n"
632 " }\n"
633 "}\n"
634 "trust-anchor\n"
635 "{\n"
636 " type file\n"
637 " file-name \"trust-anchor-6.cert\"\n"
638 "}\n";
639 const boost::filesystem::path CONFIG_PATH =
640 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
641
642
643 shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
644 validator->load(CONFIG, CONFIG_PATH.native());
645
646 scheduler.scheduleEvent(time::milliseconds(200),
647 bind(&FacesFixture::validate1, this,
648 validator, data1));
649
650 scheduler.scheduleEvent(time::milliseconds(400),
651 bind(&FacesFixture::validate2, this,
652 validator, data2));
653
654 BOOST_REQUIRE_NO_THROW(face->processEvents());
655
656 keyChain.deleteIdentity(root);
657 keyChain.deleteIdentity(sld);
658 keyChain.deleteIdentity(nld);
659
660 const boost::filesystem::path CERT_PATH =
661 (boost::filesystem::current_path() / std::string("trust-anchor-6.cert"));
662 boost::filesystem::remove(CERT_PATH);
663}
664
665BOOST_AUTO_TEST_CASE(FixedSingerChecker)
666{
667 KeyChain keyChain;
668
669 Name identity("/TestValidatorConfig/FixedSingerChecker");
670
671 Name identity1 = identity;
672 identity1.append("1").appendVersion();
673 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity1));
674 Name certName1 = keyChain.getDefaultCertificateNameForIdentity(identity1);
675 shared_ptr<IdentityCertificate> idCert1 = keyChain.getCertificate(certName1);
676 io::save(*idCert1, "trust-anchor-7.cert");
677
678 Name identity2 = identity;
679 identity2.append("2").appendVersion();
680 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity2));
681
682 Name dataName1 = identity;
683 dataName1.append("data").appendVersion();
684 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
685 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity1));
686
687 Name dataName2 = identity;
688 dataName2.append("data").appendVersion();
689 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
690 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity2));
691
Yingdi Yu20a06962014-04-17 12:56:04 -0700692 Name interestName("/TestValidatorConfig/FixedSingerChecker/fakeSigInfo/fakeSigValue");
693 shared_ptr<Interest> interest = make_shared<Interest>(interestName);
694
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700695 const std::string CONFIG =
696 "rule\n"
697 "{\n"
Yingdi Yu20a06962014-04-17 12:56:04 -0700698 " id \"FixedSingerChecker Data Rule\"\n"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700699 " for data\n"
700 " filter"
701 " {\n"
702 " type name\n"
703 " name /TestValidatorConfig/FixedSingerChecker\n"
704 " relation is-strict-prefix-of\n"
705 " }\n"
706 " checker\n"
707 " {\n"
708 " type fixed-signer\n"
709 " sig-type rsa-sha256\n"
710 " signer\n"
711 " {\n"
712 " type file\n"
713 " file-name \"trust-anchor-7.cert\"\n"
714 " }\n"
715 " }\n"
Yingdi Yu20a06962014-04-17 12:56:04 -0700716 "}\n"
717 "rule\n"
718 "{\n"
719 " id \"FixedSingerChecker Interest Rule\"\n"
720 " for interest\n"
721 " filter"
722 " {\n"
723 " type name\n"
724 " name /TestValidatorConfig/FixedSingerChecker\n"
725 " relation is-strict-prefix-of\n"
726 " }\n"
727 " checker\n"
728 " {\n"
729 " type fixed-signer\n"
730 " sig-type rsa-sha256\n"
731 " signer\n"
732 " {\n"
733 " type file\n"
734 " file-name \"trust-anchor-7.cert\"\n"
735 " }\n"
736 " }\n"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700737 "}\n";
738 const boost::filesystem::path CONFIG_PATH =
739 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
740
741
Yingdi Yu96e64062014-04-15 19:57:33 -0700742 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700743 ValidatorConfig validator(face);
744 validator.load(CONFIG, CONFIG_PATH.native());
745
746 validator.validate(*data1,
747 bind(&onValidated, _1),
748 bind(&onValidationFailed, _1, _2));
749
750 validator.validate(*data2,
751 bind(&onIntentionalFailureValidated, _1),
752 bind(&onIntentionalFailureInvalidated, _1, _2));
753
Yingdi Yu20a06962014-04-17 12:56:04 -0700754 validator.validate(*interest,
755 bind(&onIntentionalFailureValidated2, _1),
756 bind(&onIntentionalFailureInvalidated2, _1, _2));
757
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700758
759 keyChain.deleteIdentity(identity1);
760 keyChain.deleteIdentity(identity2);
761
762 const boost::filesystem::path CERT_PATH =
763 (boost::filesystem::current_path() / std::string("trust-anchor-7.cert"));
764 boost::filesystem::remove(CERT_PATH);
765}
766
767
768BOOST_FIXTURE_TEST_CASE(Nrd, FacesFixture)
769{
770 KeyChain keyChain;
771 std::vector<CertificateSubjectDescription> subjectDescription;
772
773 Name root("/TestValidatorConfig");
774 Name rootCertName = keyChain.createIdentity(root);
775 shared_ptr<IdentityCertificate> rootCert =
776 keyChain.getCertificate(rootCertName);
777 io::save(*rootCert, "trust-anchor-8.cert");
778
779
780 Name sld("/TestValidatorConfig/Nrd-1");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700781 Name sldKeyName = keyChain.generateRsaKeyPairAsDefault(sld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700782 shared_ptr<IdentityCertificate> sldCert =
783 keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
784 root,
785 time::system_clock::now(),
786 time::system_clock::now() + time::days(7300),
787 subjectDescription);
788 keyChain.signByIdentity(*sldCert, root);
789 keyChain.addCertificateAsIdentityDefault(*sldCert);
790
791 Name nld("/TestValidatorConfig/Nrd-1/Nrd-2");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700792 Name nldKeyName = keyChain.generateRsaKeyPairAsDefault(nld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700793 shared_ptr<IdentityCertificate> nldCert =
794 keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
795 sld,
796 time::system_clock::now(),
797 time::system_clock::now() + time::days(7300),
798 subjectDescription);
799 keyChain.signByIdentity(*nldCert, sld);
800 keyChain.addCertificateAsIdentityDefault(*nldCert);
801
802 shared_ptr<Face> face = make_shared<Face>();
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700803 Face face2(face->getIoService());
804 Scheduler scheduler(face->getIoService());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700805
806 scheduler.scheduleEvent(time::seconds(1),
807 bind(&FacesFixture::terminate, this, face));
808
809 regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700810 bind(&FacesFixture::onInterest, this, face, sldCert),
811 RegisterPrefixSuccessCallback(),
812 bind(&FacesFixture::onRegFailed, this));
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700813
814 regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
815 bind(&FacesFixture::onInterest2, this, face, nldCert),
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700816 RegisterPrefixSuccessCallback(),
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700817 bind(&FacesFixture::onRegFailed, this));
818
819 Name interestName1("/localhost/nrd/register/option/timestamp/nonce");
820 shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
821 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest1, nld));
822
823 Name interestName2("/localhost/nrd/non-register");
824 shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
825 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest2, nld));
826
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700827 Name interestName3("/localhost/nrd/register/option/timestamp/nonce");
828 shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
829 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest3, root));
830
Yingdi Yu20a06962014-04-17 12:56:04 -0700831 Name interestName4("/localhost/nrd/register/option/timestamp/nonce/fakeSigInfo/fakeSigValue");
832 shared_ptr<Interest> interest4 = make_shared<Interest>(interestName4);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700833
834 const std::string CONFIG =
835 "rule\n"
836 "{\n"
837 " id \"NRD Prefix Registration Command Rule\"\n"
838 " for interest\n"
839 " filter\n"
840 " {\n"
841 " type name\n"
842 " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
843 " }\n"
844 " checker\n"
845 " {\n"
846 " type customized\n"
847 " sig-type rsa-sha256\n"
848 " key-locator\n"
849 " {\n"
850 " type name\n"
851 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
852 " }\n"
853 " }\n"
854 "}\n"
855 "rule\n"
856 "{\n"
857 " id \"Testbed Hierarchy Rule\"\n"
858 " for data\n"
859 " filter\n"
860 " {\n"
861 " type name\n"
862 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
863 " }\n"
864 " checker\n"
865 " {\n"
866 " type hierarchical\n"
867 " sig-type rsa-sha256\n"
868 " }\n"
869 "}\n"
870 "trust-anchor\n"
871 "{\n"
872 " type file\n"
873 " file-name \"trust-anchor-8.cert\"\n"
874 "}\n";
875 const boost::filesystem::path CONFIG_PATH =
876 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
877
878
879 shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
880 validator->load(CONFIG, CONFIG_PATH.native());
881
Yingdi Yu20a06962014-04-17 12:56:04 -0700882 // should succeed
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700883 scheduler.scheduleEvent(time::milliseconds(200),
884 bind(&FacesFixture::validate3, this,
885 validator, interest1));
Yingdi Yu20a06962014-04-17 12:56:04 -0700886 // should fail
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700887 scheduler.scheduleEvent(time::milliseconds(400),
888 bind(&FacesFixture::validate4, this,
889 validator, interest2));
Yingdi Yu20a06962014-04-17 12:56:04 -0700890 // should succeed
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700891 scheduler.scheduleEvent(time::milliseconds(600),
892 bind(&FacesFixture::validate3, this,
893 validator, interest3));
Yingdi Yu20a06962014-04-17 12:56:04 -0700894 // should fail
895 scheduler.scheduleEvent(time::milliseconds(600),
896 bind(&FacesFixture::validate4, this,
897 validator, interest4));
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700898
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700899 BOOST_REQUIRE_NO_THROW(face->processEvents());
900
901 keyChain.deleteIdentity(root);
902 keyChain.deleteIdentity(sld);
903 keyChain.deleteIdentity(nld);
904
905 const boost::filesystem::path CERT_PATH =
906 (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
907 boost::filesystem::remove(CERT_PATH);
908}
909
Yingdi Yu58f33712014-04-16 16:57:47 -0700910BOOST_AUTO_TEST_CASE(Reset)
911{
912 KeyChain keyChain;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700913
Yingdi Yu58f33712014-04-16 16:57:47 -0700914 Name root("/TestValidatorConfig/Reload");
915 Name rootCertName = keyChain.createIdentity(root);
916 shared_ptr<IdentityCertificate> rootCert =
917 keyChain.getCertificate(rootCertName);
918 io::save(*rootCert, "trust-anchor-8.cert");
919
920 Face face;
921
922 const std::string CONFIG =
923 "rule\n"
924 "{\n"
925 " id \"NRD Prefix Registration Command Rule\"\n"
926 " for interest\n"
927 " filter\n"
928 " {\n"
929 " type name\n"
930 " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
931 " }\n"
932 " checker\n"
933 " {\n"
934 " type customized\n"
935 " sig-type rsa-sha256\n"
936 " key-locator\n"
937 " {\n"
938 " type name\n"
939 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
940 " }\n"
941 " }\n"
942 "}\n"
943 "rule\n"
944 "{\n"
945 " id \"Testbed Hierarchy Rule\"\n"
946 " for data\n"
947 " filter\n"
948 " {\n"
949 " type name\n"
950 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
951 " }\n"
952 " checker\n"
953 " {\n"
954 " type hierarchical\n"
955 " sig-type rsa-sha256\n"
956 " }\n"
957 "}\n"
958 "trust-anchor\n"
959 "{\n"
960 " type file\n"
961 " file-name \"trust-anchor-8.cert\"\n"
962 "}\n";
963 const boost::filesystem::path CONFIG_PATH =
964 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
965
966
967 shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face));
968
969 validator->load(CONFIG, CONFIG_PATH.native());
970 BOOST_CHECK_EQUAL(validator->isEmpty(), false);
971
972 validator->reset();
973 BOOST_CHECK(validator->isEmpty());
974
975 keyChain.deleteIdentity(root);
976
977 const boost::filesystem::path CERT_PATH =
978 (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
979 boost::filesystem::remove(CERT_PATH);
980}
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700981
Yingdi Yub4650652014-04-17 10:19:59 -0700982BOOST_AUTO_TEST_CASE(TrustAnchorWildcard)
Yingdi Yu44d190c2014-04-16 17:05:46 -0700983{
984 KeyChain keyChain;
985
986 Name identity("/TestValidatorConfig/Wildcard");
987 identity.appendVersion();
988 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
989
990 Name dataName1("/any/data");
991 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
992 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
993
994 std::string CONFIG =
995 "trust-anchor\n"
996 "{\n"
997 " type any\n"
998 "}\n";
999
1000 const boost::filesystem::path CONFIG_PATH =
1001 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
1002
1003
1004 Face face;
1005 ValidatorConfig validator(face);
1006 validator.load(CONFIG, CONFIG_PATH.native());
1007
1008 validator.validate(*data1,
1009 bind(&onValidated, _1),
1010 bind(&onValidationFailed, _1, _2));
1011
1012 keyChain.deleteIdentity(identity);
1013}
1014
1015
Yingdi Yub4650652014-04-17 10:19:59 -07001016
1017struct DirTestFixture
1018{
1019 DirTestFixture()
1020 : m_scheduler(m_face.getIoService())
1021 , m_validator(m_face, ValidatorConfig::DEFAULT_CERTIFICATE_CACHE, 0)
1022 {
1023 m_certDirPath = (boost::filesystem::current_path() / std::string("test-cert-dir"));
1024 boost::filesystem::create_directory(m_certDirPath);
1025
1026 m_firstCertPath = (boost::filesystem::current_path() /
1027 std::string("test-cert-dir") /
1028 std::string("trust-anchor-1.cert"));
1029
1030 m_secondCertPath = (boost::filesystem::current_path() /
1031 std::string("test-cert-dir") /
1032 std::string("trust-anchor-2.cert"));
1033
1034 m_firstIdentity = Name("/TestValidatorConfig/Dir/First");
1035 BOOST_REQUIRE_NO_THROW(m_keyChain.createIdentity(m_firstIdentity));
1036 Name firstCertName = m_keyChain.getDefaultCertificateNameForIdentity(m_firstIdentity);
1037 m_firstCert = m_keyChain.getCertificate(firstCertName);
1038 io::save(*m_firstCert, m_firstCertPath.string());
1039
1040 m_secondIdentity = Name("/TestValidatorConfig/Dir/Second");
1041 BOOST_REQUIRE_NO_THROW(m_keyChain.createIdentity(m_secondIdentity));
1042 Name secondCertName = m_keyChain.getDefaultCertificateNameForIdentity(m_secondIdentity);
1043 m_secondCert = m_keyChain.getCertificate(secondCertName);
1044 }
1045
1046 ~DirTestFixture()
1047 {
1048 m_keyChain.deleteIdentity(m_firstIdentity);
1049 m_keyChain.deleteIdentity(m_secondIdentity);
1050
1051 boost::filesystem::remove_all(m_certDirPath);
1052 }
1053
1054 void
1055 insertSecondTrustAnchor()
1056 {
1057 io::save(*m_secondCert, m_secondCertPath.string());
1058 }
1059
1060 void
1061 validate(shared_ptr<Data> data)
1062 {
1063 m_validator.validate(*data,
1064 bind(&onValidated, _1),
1065 bind(&onValidationFailed, _1, _2));
1066 }
1067
1068 void
1069 invalidate(shared_ptr<Data> data)
1070 {
1071 m_validator.validate(*data,
1072 bind(&onIntentionalFailureValidated, _1),
1073 bind(&onIntentionalFailureInvalidated, _1, _2));
1074 }
1075
1076 void
1077 terminate()
1078 {
1079 m_face.getIoService().stop();
1080 }
1081
1082protected:
1083
1084 KeyChain m_keyChain;
1085
1086 boost::filesystem::path m_certDirPath;
1087 boost::filesystem::path m_firstCertPath;
1088 boost::filesystem::path m_secondCertPath;
1089
1090 Name m_firstIdentity;
1091 Name m_secondIdentity;
1092
1093 shared_ptr<IdentityCertificate> m_firstCert;
1094 shared_ptr<IdentityCertificate> m_secondCert;
1095
1096 Face m_face;
1097 Scheduler m_scheduler;
1098 ValidatorConfig m_validator;
1099};
1100
1101BOOST_FIXTURE_TEST_CASE(TrustAnchorDir, DirTestFixture)
1102{
1103 Name dataName1("/any/data/1");
1104 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
1105 BOOST_CHECK_NO_THROW(m_keyChain.signByIdentity(*data1, m_firstIdentity));
1106
1107 Name dataName2("/any/data/2");
1108 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
1109 BOOST_CHECK_NO_THROW(m_keyChain.signByIdentity(*data2, m_secondIdentity));
1110
1111 std::string CONFIG =
1112 "rule\n"
1113 "{\n"
1114 " id \"Any Rule\"\n"
1115 " for data\n"
1116 " filter\n"
1117 " {\n"
1118 " type name\n"
1119 " regex ^<>*$\n"
1120 " }\n"
1121 " checker\n"
1122 " {\n"
1123 " type customized\n"
1124 " sig-type rsa-sha256\n"
1125 " key-locator\n"
1126 " {\n"
1127 " type name\n"
1128 " regex ^<>*$\n"
1129 " }\n"
1130 " }\n"
1131 "}\n"
1132 "trust-anchor\n"
1133 "{\n"
1134 " type dir\n"
1135 " dir test-cert-dir\n"
1136 " refresh 1s\n"
1137 "}\n";
1138
1139 const boost::filesystem::path CONFIG_PATH =
1140 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
1141
1142
1143 m_validator.load(CONFIG, CONFIG_PATH.native());
1144
1145 m_scheduler.scheduleEvent(time::milliseconds(200),
1146 bind(&DirTestFixture::validate, this, data1));
1147 m_scheduler.scheduleEvent(time::milliseconds(200),
1148 bind(&DirTestFixture::invalidate, this, data2));
1149
1150 m_scheduler.scheduleEvent(time::milliseconds(500),
1151 bind(&DirTestFixture::insertSecondTrustAnchor, this));
1152
1153 m_scheduler.scheduleEvent(time::milliseconds(1500),
1154 bind(&DirTestFixture::validate, this, data1));
1155 m_scheduler.scheduleEvent(time::milliseconds(1500),
1156 bind(&DirTestFixture::validate, this, data2));
1157
1158 m_scheduler.scheduleEvent(time::milliseconds(2000),
1159 bind(&DirTestFixture::terminate, this));
1160
1161 BOOST_REQUIRE_NO_THROW(m_face.processEvents());
1162}
1163
1164
1165
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07001166BOOST_AUTO_TEST_SUITE_END()
1167
1168} // namespace ndn