blob: def5ae352efb18a1d608dcc2874cf9873599ff99 [file] [log] [blame]
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07002/**
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07003 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
5 *
6 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
8 *
9 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Yingdi Yu <yingdi0@cs.ucla.edu>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070013 */
14
15#include "security/validator-config.hpp"
16
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070017#include "security/key-chain.hpp"
18#include "util/io.hpp"
Alexander Afanasyev258ec2b2014-05-14 16:15:37 -070019#include "util/scheduler.hpp"
20
21#include <boost/asio.hpp>
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070022
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070023#include "boost-test.hpp"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070024
25using namespace std;
26
27namespace ndn {
28
29BOOST_AUTO_TEST_SUITE(TestValidatorConfig)
30
31void
32onValidated(const shared_ptr<const Data>& data)
33{
34 BOOST_CHECK(true);
35}
36
37void
38onValidationFailed(const shared_ptr<const Data>& data, const string& failureInfo)
39{
40 std::cerr << "Failure Info: " << failureInfo << std::endl;
41 BOOST_CHECK(false);
42}
43
44void
45onIntentionalFailureValidated(const shared_ptr<const Data>& data)
46{
47 BOOST_CHECK(false);
48}
49
50void
51onIntentionalFailureInvalidated(const shared_ptr<const Data>& data, const string& failureInfo)
52{
53 BOOST_CHECK(true);
54}
55
56void
57onValidated2(const shared_ptr<const Interest>& interest)
58{
59 BOOST_CHECK(true);
60}
61
62void
63onValidationFailed2(const shared_ptr<const Interest>& interest, const string& failureInfo)
64{
65 std::cerr << "Interest Name: " << interest->getName() << std::endl;
66 std::cerr << "Failure Info: " << failureInfo << std::endl;
67 BOOST_CHECK(false);
68}
69
70void
71onIntentionalFailureValidated2(const shared_ptr<const Interest>& interest)
72{
73 BOOST_CHECK(false);
74}
75
76void
77onIntentionalFailureInvalidated2(const shared_ptr<const Interest>& interest,
78 const string& failureInfo)
79{
80 BOOST_CHECK(true);
81}
82
83BOOST_AUTO_TEST_CASE(NameFilter)
84{
85 KeyChain keyChain;
86
87 Name identity("/TestValidatorConfig/NameFilter");
88 identity.appendVersion();
89 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
90 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
91 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
92 io::save(*idCert, "trust-anchor-1.cert");
93
94 Name dataName1("/simple/equal");
95 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
96 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
97
98 Name dataName2("/simple/different");
99 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
100 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
101
102 std::string CONFIG_1 =
103 "rule\n"
104 "{\n"
105 " id \"Simple Rule\"\n"
106 " for data\n"
107 " filter"
108 " {\n"
109 " type name\n"
110 " name /simple/equal\n"
111 " relation equal\n"
112 " }\n"
113 " checker\n"
114 " {\n"
115 " type customized\n"
116 " sig-type rsa-sha256\n"
117 " key-locator\n"
118 " {\n"
119 " type name\n"
120 " name ";
121
122 std::string CONFIG_2 =
123 "\n"
124 " relation equal\n"
125 " }\n"
126 " }\n"
127 "}\n"
128 "trust-anchor\n"
129 "{\n"
130 " type file\n"
131 " file-name \"trust-anchor-1.cert\"\n"
132 "}\n";
133 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
134
135 const boost::filesystem::path CONFIG_PATH =
136 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
137
138
Yingdi Yu96e64062014-04-15 19:57:33 -0700139 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700140 ValidatorConfig validator(face);
141 validator.load(CONFIG, CONFIG_PATH.native());
142
143 validator.validate(*data1,
144 bind(&onValidated, _1),
145 bind(&onValidationFailed, _1, _2));
146
147 validator.validate(*data2,
148 bind(&onIntentionalFailureValidated, _1),
149 bind(&onIntentionalFailureInvalidated, _1, _2));
150
151 keyChain.deleteIdentity(identity);
152
153 const boost::filesystem::path CERT_PATH =
154 (boost::filesystem::current_path() / std::string("trust-anchor-1.cert"));
155 boost::filesystem::remove(CERT_PATH);
156}
157
158BOOST_AUTO_TEST_CASE(NameFilter2)
159{
160 KeyChain keyChain;
161
162 Name identity("/TestValidatorConfig/NameFilter2");
163 identity.appendVersion();
164 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
165 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
166 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
167 io::save(*idCert, "trust-anchor-2.cert");
168
169 Name dataName1("/simple/isPrefixOf");
170 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
171 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
172
173 Name dataName2("/simple/notPrefixOf");
174 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
175 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
176
177 Name dataName3("/simple/isPrefixOf/anotherLevel");
178 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
179 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
180
181 std::string CONFIG_1 =
182 "rule\n"
183 "{\n"
184 " id \"Simple2 Rule\"\n"
185 " for data\n"
186 " filter"
187 " {\n"
188 " type name\n"
189 " name /simple/isPrefixOf\n"
190 " relation is-prefix-of\n"
191 " }\n"
192 " checker\n"
193 " {\n"
194 " type customized\n"
195 " sig-type rsa-sha256\n"
196 " key-locator\n"
197 " {\n"
198 " type name\n"
199 " name ";
200
201 std::string CONFIG_2 =
202 "\n"
203 " relation equal\n"
204 " }\n"
205 " }\n"
206 "}\n"
207 "trust-anchor\n"
208 "{\n"
209 " type file\n"
210 " file-name \"trust-anchor-2.cert\"\n"
211 "}\n";
212 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
213
214 const boost::filesystem::path CONFIG_PATH =
215 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
216
217
Yingdi Yu96e64062014-04-15 19:57:33 -0700218 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700219 ValidatorConfig validator(face);
220 validator.load(CONFIG, CONFIG_PATH.native());
221
222 validator.validate(*data1,
223 bind(&onValidated, _1),
224 bind(&onValidationFailed, _1, _2));
225
226 validator.validate(*data2,
227 bind(&onIntentionalFailureValidated, _1),
228 bind(&onIntentionalFailureInvalidated, _1, _2));
229
230 validator.validate(*data3,
231 bind(&onValidated, _1),
232 bind(&onValidationFailed, _1, _2));
233
234 keyChain.deleteIdentity(identity);
235
236 const boost::filesystem::path CERT_PATH =
237 (boost::filesystem::current_path() / std::string("trust-anchor-2.cert"));
238 boost::filesystem::remove(CERT_PATH);
239}
240
241BOOST_AUTO_TEST_CASE(NameFilter3)
242{
243 KeyChain keyChain;
244
245 Name identity("/TestValidatorConfig/NameFilter3");
246 identity.appendVersion();
247 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
248 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
249 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
250 io::save(*idCert, "trust-anchor-3.cert");
251
252 Name dataName1("/simple/isStrictPrefixOf");
253 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
254 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
255
256 Name dataName2("/simple");
257 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
258 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
259
260 Name dataName3("/simple/isStrictPrefixOf/anotherLevel");
261 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
262 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
263
264 std::string CONFIG_1 =
265 "rule\n"
266 "{\n"
267 " id \"Simple3 Rule\"\n"
268 " for data\n"
269 " filter"
270 " {\n"
271 " type name\n"
272 " name /simple/isStrictPrefixOf\n"
273 " relation is-strict-prefix-of\n"
274 " }\n"
275 " checker\n"
276 " {\n"
277 " type customized\n"
278 " sig-type rsa-sha256\n"
279 " key-locator\n"
280 " {\n"
281 " type name\n"
282 " name ";
283
284 std::string CONFIG_2 =
285 "\n"
286 " relation equal\n"
287 " }\n"
288 " }\n"
289 "}\n"
290 "trust-anchor\n"
291 "{\n"
292 " type file\n"
293 " file-name \"trust-anchor-3.cert\"\n"
294 "}\n";
295 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
296
297 const boost::filesystem::path CONFIG_PATH =
298 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
299
300
Yingdi Yu96e64062014-04-15 19:57:33 -0700301 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700302 ValidatorConfig validator(face);
303 validator.load(CONFIG, CONFIG_PATH.native());
304
305 validator.validate(*data1,
306 bind(&onIntentionalFailureValidated, _1),
307 bind(&onIntentionalFailureInvalidated, _1, _2));
308
309 validator.validate(*data2,
310 bind(&onIntentionalFailureValidated, _1),
311 bind(&onIntentionalFailureInvalidated, _1, _2));
312
313 validator.validate(*data3,
314 bind(&onValidated, _1),
315 bind(&onValidationFailed, _1, _2));
316
317 keyChain.deleteIdentity(identity);
318
319 const boost::filesystem::path CERT_PATH =
320 (boost::filesystem::current_path() / std::string("trust-anchor-3.cert"));
321 boost::filesystem::remove(CERT_PATH);
322}
323
324BOOST_AUTO_TEST_CASE(NameFilter4)
325{
326 KeyChain keyChain;
327
328 Name identity("/TestValidatorConfig/NameFilter4");
329 identity.appendVersion();
330 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
331 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
332 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
333 io::save(*idCert, "trust-anchor-4.cert");
334
335 Name dataName1("/simple/regex");
336 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
337 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
338
339 Name dataName2("/simple/regex-wrong");
340 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
341 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
342
343 Name dataName3("/simple/regex/correct");
344 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
345 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
346
347 std::string CONFIG_1 =
348 "rule\n"
349 "{\n"
350 " id \"Simple3 Rule\"\n"
351 " for data\n"
352 " filter"
353 " {\n"
354 " type name\n"
355 " regex ^<simple><regex>\n"
356 " }\n"
357 " checker\n"
358 " {\n"
359 " type customized\n"
360 " sig-type rsa-sha256\n"
361 " key-locator\n"
362 " {\n"
363 " type name\n"
364 " name ";
365
366 std::string CONFIG_2 =
367 "\n"
368 " relation equal\n"
369 " }\n"
370 " }\n"
371 "}\n"
372 "trust-anchor\n"
373 "{\n"
374 " type file\n"
375 " file-name \"trust-anchor-4.cert\"\n"
376 "}\n";
377 const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
378
379 const boost::filesystem::path CONFIG_PATH =
380 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
381
382
Yingdi Yu96e64062014-04-15 19:57:33 -0700383 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700384 ValidatorConfig validator(face);
385 validator.load(CONFIG, CONFIG_PATH.native());
386
387 validator.validate(*data1,
388 bind(&onValidated, _1),
389 bind(&onValidationFailed, _1, _2));
390
391 validator.validate(*data2,
392 bind(&onIntentionalFailureValidated, _1),
393 bind(&onIntentionalFailureInvalidated, _1, _2));
394
395 validator.validate(*data3,
396 bind(&onValidated, _1),
397 bind(&onValidationFailed, _1, _2));
398
399 keyChain.deleteIdentity(identity);
400
401 const boost::filesystem::path CERT_PATH =
402 (boost::filesystem::current_path() / std::string("trust-anchor-4.cert"));
403 boost::filesystem::remove(CERT_PATH);
404}
405
406BOOST_AUTO_TEST_CASE(KeyLocatorNameChecker1)
407{
408 KeyChain keyChain;
409
410 Name identity("/TestValidatorConfig/KeyLocatorNameChecker1");
411 identity.appendVersion();
412 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
413 Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
414 shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
415 io::save(*idCert, "trust-anchor-5.cert");
416
417 Name dataName1 = identity;
418 dataName1.append("1");
419 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
420 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
421
422 Name dataName2 = identity;
423 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
424 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
425
426 Name dataName3("/TestValidatorConfig/KeyLocatorNameChecker1");
427 shared_ptr<Data> data3 = make_shared<Data>(dataName3);
428 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
429
430 const std::string CONFIG =
431 "rule\n"
432 "{\n"
433 " id \"Simple3 Rule\"\n"
434 " for data\n"
435 " checker\n"
436 " {\n"
437 " type customized\n"
438 " sig-type rsa-sha256\n"
439 " key-locator\n"
440 " {\n"
441 " type name\n"
442 " hyper-relation\n"
443 " {\n"
444 " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$\n"
445 " k-expand \\\\1\\\\2\n"
446 " h-relation is-strict-prefix-of\n"
447 " p-regex ^(<>*)$\n"
448 " p-expand \\\\1\n"
449 " }\n"
450 " }\n"
451 " }\n"
452 "}\n"
453 "trust-anchor\n"
454 "{\n"
455 " type file\n"
456 " file-name \"trust-anchor-5.cert\"\n"
457 "}\n";
458 const boost::filesystem::path CONFIG_PATH =
459 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
460
461
Yingdi Yu96e64062014-04-15 19:57:33 -0700462 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700463 ValidatorConfig validator(face);
464 validator.load(CONFIG, CONFIG_PATH.native());
465
466 validator.validate(*data1,
467 bind(&onValidated, _1),
468 bind(&onValidationFailed, _1, _2));
469
470 validator.validate(*data2,
471 bind(&onIntentionalFailureValidated, _1),
472 bind(&onIntentionalFailureInvalidated, _1, _2));
473
474 validator.validate(*data3,
475 bind(&onIntentionalFailureValidated, _1),
476 bind(&onIntentionalFailureInvalidated, _1, _2));
477
478 keyChain.deleteIdentity(identity);
479
480 const boost::filesystem::path CERT_PATH =
481 (boost::filesystem::current_path() / std::string("trust-anchor-5.cert"));
482 boost::filesystem::remove(CERT_PATH);
483}
484
485struct FacesFixture
486{
487 FacesFixture()
488 : regPrefixId(0)
489 , regPrefixId2(0)
490 {}
491
492 void
493 onInterest(shared_ptr<Face> face, shared_ptr<Data> data)
494 {
495 face->put(*data);
496 face->unsetInterestFilter(regPrefixId);
497 }
498
499 void
500 onInterest2(shared_ptr<Face> face, shared_ptr<Data> data)
501 {
502 face->put(*data);
503 face->unsetInterestFilter(regPrefixId2);
504 }
505
506 void
507 onRegFailed()
508 {}
509
510 void
511 validate1(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
512 {
513 validator->validate(*data,
514 bind(&onValidated, _1),
515 bind(&onValidationFailed, _1, _2));
516 }
517
518 void
519 validate2(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
520 {
521 validator->validate(*data,
522 bind(&onIntentionalFailureValidated, _1),
523 bind(&onIntentionalFailureInvalidated, _1, _2));
524 }
525
526 void
527 validate3(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
528 {
529 validator->validate(*interest,
530 bind(&onValidated2, _1),
531 bind(&onValidationFailed2, _1, _2));
532 }
533
534 void
535 validate4(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
536 {
537 validator->validate(*interest,
538 bind(&onIntentionalFailureValidated2, _1),
539 bind(&onIntentionalFailureInvalidated2, _1, _2));
540 }
541
542 void
543 terminate(shared_ptr<Face> face)
544 {
545 face->ioService()->stop();
546 }
547
548 const RegisteredPrefixId* regPrefixId;
549 const RegisteredPrefixId* regPrefixId2;
550};
551
552BOOST_FIXTURE_TEST_CASE(HierarchicalChecker, FacesFixture)
553{
554 KeyChain keyChain;
555 std::vector<CertificateSubjectDescription> subjectDescription;
556
557 Name root("/TestValidatorConfig");
558 Name rootCertName = keyChain.createIdentity(root);
559 shared_ptr<IdentityCertificate> rootCert =
560 keyChain.getCertificate(rootCertName);
561 io::save(*rootCert, "trust-anchor-6.cert");
562
563
564 Name sld("/TestValidatorConfig/HierarchicalChecker");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700565 Name sldKeyName = keyChain.generateRsaKeyPairAsDefault(sld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700566 shared_ptr<IdentityCertificate> sldCert =
567 keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
568 root,
569 time::system_clock::now(),
570 time::system_clock::now() + time::days(7300),
571 subjectDescription);
572 keyChain.signByIdentity(*sldCert, root);
573 keyChain.addCertificateAsIdentityDefault(*sldCert);
574
575 Name nld("/TestValidatorConfig/HierarchicalChecker/NextLevel");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700576 Name nldKeyName = keyChain.generateRsaKeyPairAsDefault(nld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700577 shared_ptr<IdentityCertificate> nldCert =
578 keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
579 sld,
580 time::system_clock::now(),
581 time::system_clock::now() + time::days(7300),
582 subjectDescription);
583 keyChain.signByIdentity(*nldCert, sld);
584 keyChain.addCertificateAsIdentityDefault(*nldCert);
585
586 shared_ptr<Face> face = make_shared<Face>();
Yingdi Yu96e64062014-04-15 19:57:33 -0700587 Face face2(face->ioService());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700588 Scheduler scheduler(*face->ioService());
589
590 scheduler.scheduleEvent(time::seconds(1),
591 bind(&FacesFixture::terminate, this, face));
592
593 regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
594 bind(&FacesFixture::onInterest, this, face, sldCert),
595 bind(&FacesFixture::onRegFailed, this));
596
597 regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
598 bind(&FacesFixture::onInterest2, this, face, nldCert),
599 bind(&FacesFixture::onRegFailed, this));
600
601 Name dataName1 = nld;
602 dataName1.append("data1");
603 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
604 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, nld));
605
606 Name dataName2("/ConfValidatorTest");
607 dataName2.append("data1");
608 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
609 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, nld));
610
611
612 const std::string CONFIG =
613 "rule\n"
614 "{\n"
615 " id \"Simple3 Rule\"\n"
616 " for data\n"
617 " checker\n"
618 " {\n"
619 " type hierarchical\n"
620 " sig-type rsa-sha256\n"
621 " }\n"
622 "}\n"
623 "trust-anchor\n"
624 "{\n"
625 " type file\n"
626 " file-name \"trust-anchor-6.cert\"\n"
627 "}\n";
628 const boost::filesystem::path CONFIG_PATH =
629 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
630
631
632 shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
633 validator->load(CONFIG, CONFIG_PATH.native());
634
635 scheduler.scheduleEvent(time::milliseconds(200),
636 bind(&FacesFixture::validate1, this,
637 validator, data1));
638
639 scheduler.scheduleEvent(time::milliseconds(400),
640 bind(&FacesFixture::validate2, this,
641 validator, data2));
642
643 BOOST_REQUIRE_NO_THROW(face->processEvents());
644
645 keyChain.deleteIdentity(root);
646 keyChain.deleteIdentity(sld);
647 keyChain.deleteIdentity(nld);
648
649 const boost::filesystem::path CERT_PATH =
650 (boost::filesystem::current_path() / std::string("trust-anchor-6.cert"));
651 boost::filesystem::remove(CERT_PATH);
652}
653
654BOOST_AUTO_TEST_CASE(FixedSingerChecker)
655{
656 KeyChain keyChain;
657
658 Name identity("/TestValidatorConfig/FixedSingerChecker");
659
660 Name identity1 = identity;
661 identity1.append("1").appendVersion();
662 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity1));
663 Name certName1 = keyChain.getDefaultCertificateNameForIdentity(identity1);
664 shared_ptr<IdentityCertificate> idCert1 = keyChain.getCertificate(certName1);
665 io::save(*idCert1, "trust-anchor-7.cert");
666
667 Name identity2 = identity;
668 identity2.append("2").appendVersion();
669 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity2));
670
671 Name dataName1 = identity;
672 dataName1.append("data").appendVersion();
673 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
674 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity1));
675
676 Name dataName2 = identity;
677 dataName2.append("data").appendVersion();
678 shared_ptr<Data> data2 = make_shared<Data>(dataName2);
679 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity2));
680
Yingdi Yu20a06962014-04-17 12:56:04 -0700681 Name interestName("/TestValidatorConfig/FixedSingerChecker/fakeSigInfo/fakeSigValue");
682 shared_ptr<Interest> interest = make_shared<Interest>(interestName);
683
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700684 const std::string CONFIG =
685 "rule\n"
686 "{\n"
Yingdi Yu20a06962014-04-17 12:56:04 -0700687 " id \"FixedSingerChecker Data Rule\"\n"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700688 " for data\n"
689 " filter"
690 " {\n"
691 " type name\n"
692 " name /TestValidatorConfig/FixedSingerChecker\n"
693 " relation is-strict-prefix-of\n"
694 " }\n"
695 " checker\n"
696 " {\n"
697 " type fixed-signer\n"
698 " sig-type rsa-sha256\n"
699 " signer\n"
700 " {\n"
701 " type file\n"
702 " file-name \"trust-anchor-7.cert\"\n"
703 " }\n"
704 " }\n"
Yingdi Yu20a06962014-04-17 12:56:04 -0700705 "}\n"
706 "rule\n"
707 "{\n"
708 " id \"FixedSingerChecker Interest Rule\"\n"
709 " for interest\n"
710 " filter"
711 " {\n"
712 " type name\n"
713 " name /TestValidatorConfig/FixedSingerChecker\n"
714 " relation is-strict-prefix-of\n"
715 " }\n"
716 " checker\n"
717 " {\n"
718 " type fixed-signer\n"
719 " sig-type rsa-sha256\n"
720 " signer\n"
721 " {\n"
722 " type file\n"
723 " file-name \"trust-anchor-7.cert\"\n"
724 " }\n"
725 " }\n"
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700726 "}\n";
727 const boost::filesystem::path CONFIG_PATH =
728 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
729
730
Yingdi Yu96e64062014-04-15 19:57:33 -0700731 Face face;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700732 ValidatorConfig validator(face);
733 validator.load(CONFIG, CONFIG_PATH.native());
734
735 validator.validate(*data1,
736 bind(&onValidated, _1),
737 bind(&onValidationFailed, _1, _2));
738
739 validator.validate(*data2,
740 bind(&onIntentionalFailureValidated, _1),
741 bind(&onIntentionalFailureInvalidated, _1, _2));
742
Yingdi Yu20a06962014-04-17 12:56:04 -0700743 validator.validate(*interest,
744 bind(&onIntentionalFailureValidated2, _1),
745 bind(&onIntentionalFailureInvalidated2, _1, _2));
746
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700747
748 keyChain.deleteIdentity(identity1);
749 keyChain.deleteIdentity(identity2);
750
751 const boost::filesystem::path CERT_PATH =
752 (boost::filesystem::current_path() / std::string("trust-anchor-7.cert"));
753 boost::filesystem::remove(CERT_PATH);
754}
755
756
757BOOST_FIXTURE_TEST_CASE(Nrd, FacesFixture)
758{
759 KeyChain keyChain;
760 std::vector<CertificateSubjectDescription> subjectDescription;
761
762 Name root("/TestValidatorConfig");
763 Name rootCertName = keyChain.createIdentity(root);
764 shared_ptr<IdentityCertificate> rootCert =
765 keyChain.getCertificate(rootCertName);
766 io::save(*rootCert, "trust-anchor-8.cert");
767
768
769 Name sld("/TestValidatorConfig/Nrd-1");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700770 Name sldKeyName = keyChain.generateRsaKeyPairAsDefault(sld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700771 shared_ptr<IdentityCertificate> sldCert =
772 keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
773 root,
774 time::system_clock::now(),
775 time::system_clock::now() + time::days(7300),
776 subjectDescription);
777 keyChain.signByIdentity(*sldCert, root);
778 keyChain.addCertificateAsIdentityDefault(*sldCert);
779
780 Name nld("/TestValidatorConfig/Nrd-1/Nrd-2");
Yingdi Yuf56c68f2014-04-24 21:50:13 -0700781 Name nldKeyName = keyChain.generateRsaKeyPairAsDefault(nld, true);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700782 shared_ptr<IdentityCertificate> nldCert =
783 keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
784 sld,
785 time::system_clock::now(),
786 time::system_clock::now() + time::days(7300),
787 subjectDescription);
788 keyChain.signByIdentity(*nldCert, sld);
789 keyChain.addCertificateAsIdentityDefault(*nldCert);
790
791 shared_ptr<Face> face = make_shared<Face>();
Yingdi Yu96e64062014-04-15 19:57:33 -0700792 Face face2(face->ioService());
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700793 Scheduler scheduler(*face->ioService());
794
795 scheduler.scheduleEvent(time::seconds(1),
796 bind(&FacesFixture::terminate, this, face));
797
798 regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
799 bind(&FacesFixture::onInterest, this, face, sldCert),
800 bind(&FacesFixture::onRegFailed, this));
801
802 regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
803 bind(&FacesFixture::onInterest2, this, face, nldCert),
804 bind(&FacesFixture::onRegFailed, this));
805
806 Name interestName1("/localhost/nrd/register/option/timestamp/nonce");
807 shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
808 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest1, nld));
809
810 Name interestName2("/localhost/nrd/non-register");
811 shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
812 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest2, nld));
813
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700814 Name interestName3("/localhost/nrd/register/option/timestamp/nonce");
815 shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
816 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest3, root));
817
Yingdi Yu20a06962014-04-17 12:56:04 -0700818 Name interestName4("/localhost/nrd/register/option/timestamp/nonce/fakeSigInfo/fakeSigValue");
819 shared_ptr<Interest> interest4 = make_shared<Interest>(interestName4);
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700820
821 const std::string CONFIG =
822 "rule\n"
823 "{\n"
824 " id \"NRD Prefix Registration Command Rule\"\n"
825 " for interest\n"
826 " filter\n"
827 " {\n"
828 " type name\n"
829 " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
830 " }\n"
831 " checker\n"
832 " {\n"
833 " type customized\n"
834 " sig-type rsa-sha256\n"
835 " key-locator\n"
836 " {\n"
837 " type name\n"
838 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
839 " }\n"
840 " }\n"
841 "}\n"
842 "rule\n"
843 "{\n"
844 " id \"Testbed Hierarchy Rule\"\n"
845 " for data\n"
846 " filter\n"
847 " {\n"
848 " type name\n"
849 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
850 " }\n"
851 " checker\n"
852 " {\n"
853 " type hierarchical\n"
854 " sig-type rsa-sha256\n"
855 " }\n"
856 "}\n"
857 "trust-anchor\n"
858 "{\n"
859 " type file\n"
860 " file-name \"trust-anchor-8.cert\"\n"
861 "}\n";
862 const boost::filesystem::path CONFIG_PATH =
863 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
864
865
866 shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
867 validator->load(CONFIG, CONFIG_PATH.native());
868
Yingdi Yu20a06962014-04-17 12:56:04 -0700869 // should succeed
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700870 scheduler.scheduleEvent(time::milliseconds(200),
871 bind(&FacesFixture::validate3, this,
872 validator, interest1));
Yingdi Yu20a06962014-04-17 12:56:04 -0700873 // should fail
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700874 scheduler.scheduleEvent(time::milliseconds(400),
875 bind(&FacesFixture::validate4, this,
876 validator, interest2));
Yingdi Yu20a06962014-04-17 12:56:04 -0700877 // should succeed
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700878 scheduler.scheduleEvent(time::milliseconds(600),
879 bind(&FacesFixture::validate3, this,
880 validator, interest3));
Yingdi Yu20a06962014-04-17 12:56:04 -0700881 // should fail
882 scheduler.scheduleEvent(time::milliseconds(600),
883 bind(&FacesFixture::validate4, this,
884 validator, interest4));
Yingdi Yu3cca4ab2014-04-11 12:46:53 -0700885
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700886 BOOST_REQUIRE_NO_THROW(face->processEvents());
887
888 keyChain.deleteIdentity(root);
889 keyChain.deleteIdentity(sld);
890 keyChain.deleteIdentity(nld);
891
892 const boost::filesystem::path CERT_PATH =
893 (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
894 boost::filesystem::remove(CERT_PATH);
895}
896
Yingdi Yu58f33712014-04-16 16:57:47 -0700897BOOST_AUTO_TEST_CASE(Reset)
898{
899 KeyChain keyChain;
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700900
Yingdi Yu58f33712014-04-16 16:57:47 -0700901 Name root("/TestValidatorConfig/Reload");
902 Name rootCertName = keyChain.createIdentity(root);
903 shared_ptr<IdentityCertificate> rootCert =
904 keyChain.getCertificate(rootCertName);
905 io::save(*rootCert, "trust-anchor-8.cert");
906
907 Face face;
908
909 const std::string CONFIG =
910 "rule\n"
911 "{\n"
912 " id \"NRD Prefix Registration Command Rule\"\n"
913 " for interest\n"
914 " filter\n"
915 " {\n"
916 " type name\n"
917 " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
918 " }\n"
919 " checker\n"
920 " {\n"
921 " type customized\n"
922 " sig-type rsa-sha256\n"
923 " key-locator\n"
924 " {\n"
925 " type name\n"
926 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
927 " }\n"
928 " }\n"
929 "}\n"
930 "rule\n"
931 "{\n"
932 " id \"Testbed Hierarchy Rule\"\n"
933 " for data\n"
934 " filter\n"
935 " {\n"
936 " type name\n"
937 " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
938 " }\n"
939 " checker\n"
940 " {\n"
941 " type hierarchical\n"
942 " sig-type rsa-sha256\n"
943 " }\n"
944 "}\n"
945 "trust-anchor\n"
946 "{\n"
947 " type file\n"
948 " file-name \"trust-anchor-8.cert\"\n"
949 "}\n";
950 const boost::filesystem::path CONFIG_PATH =
951 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
952
953
954 shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face));
955
956 validator->load(CONFIG, CONFIG_PATH.native());
957 BOOST_CHECK_EQUAL(validator->isEmpty(), false);
958
959 validator->reset();
960 BOOST_CHECK(validator->isEmpty());
961
962 keyChain.deleteIdentity(root);
963
964 const boost::filesystem::path CERT_PATH =
965 (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
966 boost::filesystem::remove(CERT_PATH);
967}
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700968
Yingdi Yu44d190c2014-04-16 17:05:46 -0700969BOOST_AUTO_TEST_CASE(Wildcard)
970{
971 KeyChain keyChain;
972
973 Name identity("/TestValidatorConfig/Wildcard");
974 identity.appendVersion();
975 BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
976
977 Name dataName1("/any/data");
978 shared_ptr<Data> data1 = make_shared<Data>(dataName1);
979 BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
980
981 std::string CONFIG =
982 "trust-anchor\n"
983 "{\n"
984 " type any\n"
985 "}\n";
986
987 const boost::filesystem::path CONFIG_PATH =
988 (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
989
990
991 Face face;
992 ValidatorConfig validator(face);
993 validator.load(CONFIG, CONFIG_PATH.native());
994
995 validator.validate(*data1,
996 bind(&onValidated, _1),
997 bind(&onValidationFailed, _1, _2));
998
999 keyChain.deleteIdentity(identity);
1000}
1001
1002
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07001003BOOST_AUTO_TEST_SUITE_END()
1004
1005} // namespace ndn