security: Adding wildcard support in CommandInterestValidator
Change-Id: I21beb5704f2e2584155377c5b2de59f0ea46c4fa
Refs: #1561
diff --git a/src/security/sec-rule-specific.cpp b/src/security/sec-rule-specific.cpp
index 58bcc26..9b44d83 100644
--- a/src/security/sec-rule-specific.cpp
+++ b/src/security/sec-rule-specific.cpp
@@ -26,6 +26,14 @@
: SecRule(true)
, m_dataRegex(dataRegex)
, m_signerRegex(signerRegex)
+ , m_isExempted(false)
+{
+}
+
+SecRuleSpecific::SecRuleSpecific(shared_ptr<Regex> dataRegex)
+ : SecRule(true)
+ , m_dataRegex(dataRegex)
+ , m_isExempted(true)
{
}
@@ -33,6 +41,7 @@
: SecRule(true)
, m_dataRegex(rule.m_dataRegex)
, m_signerRegex(rule.m_signerRegex)
+ , m_isExempted(rule.m_isExempted)
{
}
@@ -45,6 +54,9 @@
bool
SecRuleSpecific::matchSignerName(const Data& data)
{
+ if (m_isExempted)
+ return true;
+
try
{
SignatureSha256WithRsa sig(data.getSignature());
@@ -66,7 +78,8 @@
bool
SecRuleSpecific::satisfy(const Name& dataName, const Name& signerName)
{
- return (m_dataRegex->match(dataName) && m_signerRegex->match(signerName));
+ bool isSignerMatched = m_isExempted || m_signerRegex->match(signerName);
+ return (m_dataRegex->match(dataName) && isSignerMatched);
}
} // namespace ndn
diff --git a/src/security/sec-rule-specific.hpp b/src/security/sec-rule-specific.hpp
index 278bbcd..a7bf833 100644
--- a/src/security/sec-rule-specific.hpp
+++ b/src/security/sec-rule-specific.hpp
@@ -28,6 +28,8 @@
SecRuleSpecific(shared_ptr<Regex> dataRegex,
shared_ptr<Regex> signerRegex);
+ SecRuleSpecific(shared_ptr<Regex> dataRegex);
+
SecRuleSpecific(const SecRuleSpecific& rule);
virtual
@@ -45,9 +47,16 @@
bool
satisfy(const Name& dataName, const Name& signerName);
+ bool
+ isExempted() const
+ {
+ return m_isExempted;
+ }
+
private:
shared_ptr<Regex> m_dataRegex;
shared_ptr<Regex> m_signerRegex;
+ bool m_isExempted;
};
} // namespace ndn
diff --git a/src/util/command-interest-validator.hpp b/src/util/command-interest-validator.hpp
index 17d264b..6bd3250 100644
--- a/src/util/command-interest-validator.hpp
+++ b/src/util/command-interest-validator.hpp
@@ -45,12 +45,34 @@
{
}
+ /**
+ * @brief add an Interest rule that allows a specific certificate
+ *
+ * @param regex NDN Regex to match Interest Name
+ * @param certificate trusted certificate
+ */
void
addInterestRule(const std::string& regex, const IdentityCertificate& certificate);
+ /**
+ * @brief add an Interest rule that allows a specific public key
+ *
+ * @param regex NDN Regex to match Interest Name
+ * @param keyName KeyLocator.Name
+ * @param publicKey public key
+ */
void
addInterestRule(const std::string& regex, const Name& keyName, const PublicKey& publicKey);
+ /**
+ * @brief add an Interest rule that allows any signer
+ *
+ * @param regex NDN Regex to match Interest Name
+ * @note Command Interest matched by regex that is signed by any key will be accepted.
+ */
+ void
+ addInterestBypassRule(const std::string& regex);
+
protected:
virtual void
checkPolicy(const Data& data,
@@ -97,6 +119,13 @@
}
inline void
+CommandInterestValidator::addInterestBypassRule(const std::string& regex)
+{
+ shared_ptr<Regex> interestRegex = make_shared<Regex>(regex);
+ m_trustScopeForInterest.push_back(SecRuleSpecific(interestRegex));
+}
+
+inline void
CommandInterestValidator::checkPolicy(const Interest& interest,
int stepCount,
const OnInterestValidated& onValidated,
@@ -137,6 +166,11 @@
{
if (scopeIt->satisfy(interestName, keyName))
{
+ if (scopeIt->isExempted())
+ {
+ return onValidated(interest.shared_from_this());
+ }
+
isInScope = true;
break;
}
diff --git a/tests/security/test-signed-interest.cpp b/tests/security/test-signed-interest.cpp
index 62cec61..b8faad0 100644
--- a/tests/security/test-signed-interest.cpp
+++ b/tests/security/test-signed-interest.cpp
@@ -76,7 +76,7 @@
bool m_validity;
};
-BOOST_FIXTURE_TEST_CASE (CommandInterest, CommandInterestFixture)
+BOOST_FIXTURE_TEST_CASE(CommandInterest, CommandInterestFixture)
{
KeyChain keyChain;
Name identity("/TestCommandInterest/Validation");
@@ -149,6 +149,33 @@
BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identity2));
}
+BOOST_FIXTURE_TEST_CASE(Exemption, CommandInterestFixture)
+{
+ KeyChain keyChain;
+ Name identity("/TestCommandInterest/AnyKey");
+
+ Name certName;
+ BOOST_REQUIRE_NO_THROW(certName = keyChain.createIdentity(identity));
+
+ CommandInterestGenerator generator;
+ CommandInterestValidator validator;
+
+ validator.addInterestBypassRule("^<TestCommandInterest><Exemption>");
+
+ //Test a legitimate command
+ shared_ptr<Interest> commandInterest1 =
+ make_shared<Interest>("/TestCommandInterest/Exemption/Command1");
+ generator.generateWithIdentity(*commandInterest1, identity);
+ validator.validate(*commandInterest1,
+ bind(&CommandInterestFixture::validated, this, _1),
+ bind(&CommandInterestFixture::validationFailed, this, _1, _2));
+
+ BOOST_CHECK_EQUAL(m_validity, true);
+
+ BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identity));
+}
+
+
BOOST_AUTO_TEST_SUITE_END()