security: Add configuration based validator
configuration file format can be found at: http://redmine.named-data.net/projects/ndn-cpp-dev/wiki/CommandValidatorConf
Change-Id: Icc2725f349aed7513f35f2cccdcd4463fadeef31
diff --git a/tests-integrated/security/test-validator-config.cpp b/tests-integrated/security/test-validator-config.cpp
new file mode 100644
index 0000000..0e778db
--- /dev/null
+++ b/tests-integrated/security/test-validator-config.cpp
@@ -0,0 +1,848 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi0@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "security/validator-config.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+#include "security/key-chain.hpp"
+#include "util/io.hpp"
+
+
+using namespace std;
+
+namespace ndn {
+
+BOOST_AUTO_TEST_SUITE(TestValidatorConfig)
+
+void
+onValidated(const shared_ptr<const Data>& data)
+{
+ BOOST_CHECK(true);
+}
+
+void
+onValidationFailed(const shared_ptr<const Data>& data, const string& failureInfo)
+{
+ std::cerr << "Failure Info: " << failureInfo << std::endl;
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureValidated(const shared_ptr<const Data>& data)
+{
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureInvalidated(const shared_ptr<const Data>& data, const string& failureInfo)
+{
+ BOOST_CHECK(true);
+}
+
+void
+onValidated2(const shared_ptr<const Interest>& interest)
+{
+ BOOST_CHECK(true);
+}
+
+void
+onValidationFailed2(const shared_ptr<const Interest>& interest, const string& failureInfo)
+{
+ std::cerr << "Interest Name: " << interest->getName() << std::endl;
+ std::cerr << "Failure Info: " << failureInfo << std::endl;
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureValidated2(const shared_ptr<const Interest>& interest)
+{
+ BOOST_CHECK(false);
+}
+
+void
+onIntentionalFailureInvalidated2(const shared_ptr<const Interest>& interest,
+ const string& failureInfo)
+{
+ BOOST_CHECK(true);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-1.cert");
+
+ Name dataName1("/simple/equal");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple/different");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /simple/equal\n"
+ " relation equal\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-1.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<Face> face = make_shared<Face>();
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-1.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter2)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter2");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-2.cert");
+
+ Name dataName1("/simple/isPrefixOf");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple/notPrefixOf");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/simple/isPrefixOf/anotherLevel");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple2 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /simple/isPrefixOf\n"
+ " relation is-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-2.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<Face> face = make_shared<Face>();
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-2.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter3)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter3");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-3.cert");
+
+ Name dataName1("/simple/isStrictPrefixOf");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/simple/isStrictPrefixOf/anotherLevel");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /simple/isStrictPrefixOf\n"
+ " relation is-strict-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-3.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<Face> face = make_shared<Face>();
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-3.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(NameFilter4)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/NameFilter4");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-4.cert");
+
+ Name dataName1("/simple/regex");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2("/simple/regex-wrong");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/simple/regex/correct");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ std::string CONFIG_1 =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " regex ^<simple><regex>\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " name ";
+
+ std::string CONFIG_2 =
+ "\n"
+ " relation equal\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-4.cert\"\n"
+ "}\n";
+ const std::string CONFIG = CONFIG_1 + certName.getPrefix(-1).toUri() + CONFIG_2;
+
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<Face> face = make_shared<Face>();
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-4.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(KeyLocatorNameChecker1)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/KeyLocatorNameChecker1");
+ identity.appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
+ Name certName = keyChain.getDefaultCertificateNameForIdentity(identity);
+ shared_ptr<IdentityCertificate> idCert = keyChain.getCertificate(certName);
+ io::save(*idCert, "trust-anchor-5.cert");
+
+ Name dataName1 = identity;
+ dataName1.append("1");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity));
+
+ Name dataName2 = identity;
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity));
+
+ Name dataName3("/TestValidatorConfig/KeyLocatorNameChecker1");
+ shared_ptr<Data> data3 = make_shared<Data>(dataName3);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data3, identity));
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " hyper-relation\n"
+ " {\n"
+ " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$\n"
+ " k-expand \\\\1\\\\2\n"
+ " h-relation is-strict-prefix-of\n"
+ " p-regex ^(<>*)$\n"
+ " p-expand \\\\1\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-5.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<Face> face = make_shared<Face>();
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ validator.validate(*data3,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+ keyChain.deleteIdentity(identity);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-5.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+struct FacesFixture
+{
+ FacesFixture()
+ : regPrefixId(0)
+ , regPrefixId2(0)
+ {}
+
+ void
+ onInterest(shared_ptr<Face> face, shared_ptr<Data> data)
+ {
+ face->put(*data);
+ face->unsetInterestFilter(regPrefixId);
+ }
+
+ void
+ onInterest2(shared_ptr<Face> face, shared_ptr<Data> data)
+ {
+ face->put(*data);
+ face->unsetInterestFilter(regPrefixId2);
+ }
+
+ void
+ onRegFailed()
+ {}
+
+ void
+ validate1(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
+ {
+ validator->validate(*data,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+ }
+
+ void
+ validate2(shared_ptr<ValidatorConfig> validator, shared_ptr<Data> data)
+ {
+ validator->validate(*data,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+ }
+
+ void
+ validate3(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
+ {
+ validator->validate(*interest,
+ bind(&onValidated2, _1),
+ bind(&onValidationFailed2, _1, _2));
+ }
+
+ void
+ validate4(shared_ptr<ValidatorConfig> validator, shared_ptr<Interest> interest)
+ {
+ validator->validate(*interest,
+ bind(&onIntentionalFailureValidated2, _1),
+ bind(&onIntentionalFailureInvalidated2, _1, _2));
+ }
+
+ void
+ terminate(shared_ptr<Face> face)
+ {
+ face->ioService()->stop();
+ }
+
+ const RegisteredPrefixId* regPrefixId;
+ const RegisteredPrefixId* regPrefixId2;
+};
+
+BOOST_FIXTURE_TEST_CASE(HierarchicalChecker, FacesFixture)
+{
+ KeyChain keyChain;
+ std::vector<CertificateSubjectDescription> subjectDescription;
+
+ Name root("/TestValidatorConfig");
+ Name rootCertName = keyChain.createIdentity(root);
+ shared_ptr<IdentityCertificate> rootCert =
+ keyChain.getCertificate(rootCertName);
+ io::save(*rootCert, "trust-anchor-6.cert");
+
+
+ Name sld("/TestValidatorConfig/HierarchicalChecker");
+ Name sldKeyName = keyChain.generateRSAKeyPairAsDefault(sld, true);
+ shared_ptr<IdentityCertificate> sldCert =
+ keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
+ root,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*sldCert, root);
+ keyChain.addCertificateAsIdentityDefault(*sldCert);
+
+ Name nld("/TestValidatorConfig/HierarchicalChecker/NextLevel");
+ Name nldKeyName = keyChain.generateRSAKeyPairAsDefault(nld, true);
+ shared_ptr<IdentityCertificate> nldCert =
+ keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
+ sld,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*nldCert, sld);
+ keyChain.addCertificateAsIdentityDefault(*nldCert);
+
+ shared_ptr<Face> face = make_shared<Face>();
+ shared_ptr<Face> face2 = shared_ptr<Face>(new Face(face->ioService()));
+ Scheduler scheduler(*face->ioService());
+
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&FacesFixture::terminate, this, face));
+
+ regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest, this, face, sldCert),
+ bind(&FacesFixture::onRegFailed, this));
+
+ regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest2, this, face, nldCert),
+ bind(&FacesFixture::onRegFailed, this));
+
+ Name dataName1 = nld;
+ dataName1.append("data1");
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, nld));
+
+ Name dataName2("/ConfValidatorTest");
+ dataName2.append("data1");
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, nld));
+
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " checker\n"
+ " {\n"
+ " type hierarchical\n"
+ " sig-type rsa-sha256\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-6.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
+ validator->load(CONFIG, CONFIG_PATH.native());
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::validate1, this,
+ validator, data1));
+
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::validate2, this,
+ validator, data2));
+
+ BOOST_REQUIRE_NO_THROW(face->processEvents());
+
+ keyChain.deleteIdentity(root);
+ keyChain.deleteIdentity(sld);
+ keyChain.deleteIdentity(nld);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-6.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+BOOST_AUTO_TEST_CASE(FixedSingerChecker)
+{
+ KeyChain keyChain;
+
+ Name identity("/TestValidatorConfig/FixedSingerChecker");
+
+ Name identity1 = identity;
+ identity1.append("1").appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity1));
+ Name certName1 = keyChain.getDefaultCertificateNameForIdentity(identity1);
+ shared_ptr<IdentityCertificate> idCert1 = keyChain.getCertificate(certName1);
+ io::save(*idCert1, "trust-anchor-7.cert");
+
+ Name identity2 = identity;
+ identity2.append("2").appendVersion();
+ BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity2));
+
+ Name dataName1 = identity;
+ dataName1.append("data").appendVersion();
+ shared_ptr<Data> data1 = make_shared<Data>(dataName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data1, identity1));
+
+ Name dataName2 = identity;
+ dataName2.append("data").appendVersion();
+ shared_ptr<Data> data2 = make_shared<Data>(dataName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity2));
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"Simple3 Rule\"\n"
+ " for data\n"
+ " filter"
+ " {\n"
+ " type name\n"
+ " name /TestValidatorConfig/FixedSingerChecker\n"
+ " relation is-strict-prefix-of\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type fixed-signer\n"
+ " sig-type rsa-sha256\n"
+ " signer\n"
+ " {\n"
+ " type file\n"
+ " file-name \"trust-anchor-7.cert\"\n"
+ " }\n"
+ " }\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<Face> face = make_shared<Face>();
+ ValidatorConfig validator(face);
+ validator.load(CONFIG, CONFIG_PATH.native());
+
+ validator.validate(*data1,
+ bind(&onValidated, _1),
+ bind(&onValidationFailed, _1, _2));
+
+ validator.validate(*data2,
+ bind(&onIntentionalFailureValidated, _1),
+ bind(&onIntentionalFailureInvalidated, _1, _2));
+
+
+ keyChain.deleteIdentity(identity1);
+ keyChain.deleteIdentity(identity2);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-7.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+
+BOOST_FIXTURE_TEST_CASE(Nrd, FacesFixture)
+{
+ KeyChain keyChain;
+ std::vector<CertificateSubjectDescription> subjectDescription;
+
+ Name root("/TestValidatorConfig");
+ Name rootCertName = keyChain.createIdentity(root);
+ shared_ptr<IdentityCertificate> rootCert =
+ keyChain.getCertificate(rootCertName);
+ io::save(*rootCert, "trust-anchor-8.cert");
+
+
+ Name sld("/TestValidatorConfig/Nrd-1");
+ Name sldKeyName = keyChain.generateRSAKeyPairAsDefault(sld, true);
+ shared_ptr<IdentityCertificate> sldCert =
+ keyChain.prepareUnsignedIdentityCertificate(sldKeyName,
+ root,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*sldCert, root);
+ keyChain.addCertificateAsIdentityDefault(*sldCert);
+
+ Name nld("/TestValidatorConfig/Nrd-1/Nrd-2");
+ Name nldKeyName = keyChain.generateRSAKeyPairAsDefault(nld, true);
+ shared_ptr<IdentityCertificate> nldCert =
+ keyChain.prepareUnsignedIdentityCertificate(nldKeyName,
+ sld,
+ time::system_clock::now(),
+ time::system_clock::now() + time::days(7300),
+ subjectDescription);
+ keyChain.signByIdentity(*nldCert, sld);
+ keyChain.addCertificateAsIdentityDefault(*nldCert);
+
+ shared_ptr<Face> face = make_shared<Face>();
+ shared_ptr<Face> face2 = shared_ptr<Face>(new Face(face->ioService()));
+ Scheduler scheduler(*face->ioService());
+
+ scheduler.scheduleEvent(time::seconds(1),
+ bind(&FacesFixture::terminate, this, face));
+
+ regPrefixId = face->setInterestFilter(sldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest, this, face, sldCert),
+ bind(&FacesFixture::onRegFailed, this));
+
+ regPrefixId2 = face->setInterestFilter(nldCert->getName().getPrefix(-1),
+ bind(&FacesFixture::onInterest2, this, face, nldCert),
+ bind(&FacesFixture::onRegFailed, this));
+
+ Name interestName1("/localhost/nrd/register/option/timestamp/nonce");
+ shared_ptr<Interest> interest1 = make_shared<Interest>(interestName1);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest1, nld));
+
+ Name interestName2("/localhost/nrd/non-register");
+ shared_ptr<Interest> interest2 = make_shared<Interest>(interestName2);
+ BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest2, nld));
+
+
+ const std::string CONFIG =
+ "rule\n"
+ "{\n"
+ " id \"NRD Prefix Registration Command Rule\"\n"
+ " for interest\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^<localhost><nrd>[<register><unregister><advertise><withdraw>]<>{3}$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type customized\n"
+ " sig-type rsa-sha256\n"
+ " key-locator\n"
+ " {\n"
+ " type name\n"
+ " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT>$\n"
+ " }\n"
+ " }\n"
+ "}\n"
+ "rule\n"
+ "{\n"
+ " id \"Testbed Hierarchy Rule\"\n"
+ " for data\n"
+ " filter\n"
+ " {\n"
+ " type name\n"
+ " regex ^[^<KEY>]*<KEY><>*<ksk-.*><ID-CERT><>$\n"
+ " }\n"
+ " checker\n"
+ " {\n"
+ " type hierarchical\n"
+ " sig-type rsa-sha256\n"
+ " }\n"
+ "}\n"
+ "trust-anchor\n"
+ "{\n"
+ " type file\n"
+ " file-name \"trust-anchor-8.cert\"\n"
+ "}\n";
+ const boost::filesystem::path CONFIG_PATH =
+ (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
+
+
+ shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
+ validator->load(CONFIG, CONFIG_PATH.native());
+
+ scheduler.scheduleEvent(time::milliseconds(200),
+ bind(&FacesFixture::validate3, this,
+ validator, interest1));
+
+ scheduler.scheduleEvent(time::milliseconds(400),
+ bind(&FacesFixture::validate4, this,
+ validator, interest2));
+
+ BOOST_REQUIRE_NO_THROW(face->processEvents());
+
+ keyChain.deleteIdentity(root);
+ keyChain.deleteIdentity(sld);
+ keyChain.deleteIdentity(nld);
+
+ const boost::filesystem::path CERT_PATH =
+ (boost::filesystem::current_path() / std::string("trust-anchor-8.cert"));
+ boost::filesystem::remove(CERT_PATH);
+}
+
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace ndn