security: Enforce sig-type check in ValidatorConfig
Change-Id: Ia58e19bbe7453095cb83b3b05dee29ae58d64522 Refs: #4524
This commit is contained in:
1 parent
aef53b6c26
commit
17d4b93f04
9 files changed
+331
-83
No files matched your search
@@ -199,31 +199,38 @@ checkers:
|
||||
Customized Checker
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The customized checker requires two properties: **sig-type**, **key-locator**. Both must
|
||||
appear exactly once and are related to the ``SignatureInfo`` of a packet.
|
||||
The customized checker can include optional **sig-type** property, which specifies the acceptable signature
|
||||
type. If not specified, the checker will only accept ECDSA signature. Possible values for **sig-type** are:
|
||||
|
||||
- **ecdsa-sha256**: ECDSA signature required (default if **sig-type** not specified)
|
||||
- **rsa-sha256**: RSA signature required
|
||||
- **sha256** (not recommended, as it is not a real signature): SHA256 digest is required
|
||||
|
||||
If sig-type is **rsa-sha256** or **ecdsa-sha256**, the customized checker requires
|
||||
**key-locator** property. If sig-type is **sha256**, **key-locator** property can be
|
||||
specified, but is optional.
|
||||
|
||||
::
|
||||
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ...
|
||||
sig-type rsa-sha256
|
||||
key-locator
|
||||
{
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
The property **sig-type** specifies the acceptable signature type and can be
|
||||
**rsa-sha256**, **ecdsa-sha256** (strong signature types), or **sha256** (weak signature
|
||||
type). If sig-type is sha256, **key-locator** is ignored, and the validator will simply
|
||||
calculate the digest of a packet and compare it with the one in ``SignatureValue``. If
|
||||
sig-type is rsa-sha256 or ecdsa-sha256, you have to further customize the checker with
|
||||
**key-locator**.
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type sha256
|
||||
}
|
||||
|
||||
The property **key-locator** specifies the conditions on ``KeyLocator``. If the
|
||||
**key-locator** property is specified, it requires the existence of the ``KeyLocator``
|
||||
field in ``SignatureInfo``. **key-locator** property only supports one type: **name**:
|
||||
The **key-locator** property is a nested configuration property that can appear exactly once
|
||||
and specifies conditions on ``KeyLocator``. It requires **type** property that currently
|
||||
supports only one value: **name**.
|
||||
|
||||
::
|
||||
|
||||
@@ -233,9 +240,9 @@ field in ``SignatureInfo``. **key-locator** property only supports one type: **
|
||||
...
|
||||
}
|
||||
|
||||
This key-locator property specifies the conditions on the certificate name of the signing
|
||||
key. Since the conditions are about name, they can be specified in the same way as the
|
||||
name filter. For example, a checker can be:
|
||||
``KeyLocator`` conditions can be specified in the same way as the name filter. For example, a
|
||||
checker that requires ``SignatureSha256WithRsa`` signature type with ``KeyLocator`` to be exactly
|
||||
``/ndn/edu/ucla/yingdi/KEY/1234`` can be written as follows:
|
||||
|
||||
::
|
||||
|
||||
@@ -251,13 +258,27 @@ name filter. For example, a checker can be:
|
||||
}
|
||||
}
|
||||
|
||||
This checker property requires that the packet must have a ``rsa-sha256`` signature that
|
||||
can be verified with ``/ndn/edu/ucla/yingdi/KEY/1234`` key.
|
||||
Similarly, a checker that requires ``SignatureSha256WithEcdsa`` signature with ``KeyLocator``
|
||||
that follows a regular expression pattern ``<ndn><>*<KEY><>{1,3}`` can be written as follows:
|
||||
|
||||
Besides the two ways to express conditions on the ``KeyLocator`` name (name and regex),
|
||||
you can further constrain the ``KeyLocator`` name using the information extracted from the
|
||||
packet name. This third type of condition is expressed via a property
|
||||
**hyper-relation**. The **hyper-relation** property consists of three parts:
|
||||
::
|
||||
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
regex <ndn><>*<KEY><>{1,3}
|
||||
relation equal
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
In addition, ``KeyLocator`` can be further constrained using information extracted from the
|
||||
packet name using the **hyper-relation** property.
|
||||
The **hyper-relation** property consists of three parts:
|
||||
|
||||
- an NDN regular expression that extracts information from the packet name
|
||||
- an NDN regular expression that extracts information from the ``KeyLocator`` name
|
||||
@@ -277,7 +298,7 @@ For example, a checker:
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^(<>*)<KEY><>$
|
||||
k-regex ^(<>*)<KEY><>{1,3}$
|
||||
k-expand \\1
|
||||
h-relation is-prefix-of
|
||||
p-regex ^(<>*)$
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
||||
/*
|
||||
* Copyright (c) 2013-2020 Regents of the University of California.
|
||||
* Copyright (c) 2013-2021 Regents of the University of California.
|
||||
*
|
||||
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
|
||||
*
|
||||
@@ -247,7 +247,8 @@ ValidationPolicyConfig::checkPolicy(const Data& data, const shared_ptr<Validatio
|
||||
|
||||
for (const auto& rule : m_dataRules) {
|
||||
if (rule->match(tlv::Data, data.getName(), state)) {
|
||||
if (rule->check(tlv::Data, data.getName(), klName, state)) {
|
||||
if (rule->check(tlv::Data, tlv::SignatureTypeValue(data.getSignatureType()),
|
||||
data.getName(), klName, state)) {
|
||||
return continueValidation(make_shared<CertificateRequest>(klName), state);
|
||||
}
|
||||
// rule->check calls state->fail(...) if the check fails
|
||||
@@ -276,7 +277,34 @@ ValidationPolicyConfig::checkPolicy(const Interest& interest, const shared_ptr<V
|
||||
|
||||
for (const auto& rule : m_interestRules) {
|
||||
if (rule->match(tlv::Interest, interest.getName(), state)) {
|
||||
if (rule->check(tlv::Interest, interest.getName(), klName, state)) {
|
||||
|
||||
tlv::SignatureTypeValue sigType;
|
||||
auto fmt = state->getTag<SignedInterestFormatTag>();
|
||||
BOOST_ASSERT(fmt);
|
||||
|
||||
if (*fmt == SignedInterestFormat::V03) {
|
||||
sigType = tlv::SignatureTypeValue(interest.getSignatureInfo()->getSignatureType());
|
||||
}
|
||||
else {
|
||||
if (interest.getName().size() < signed_interest::MIN_SIZE) {
|
||||
state->fail({ValidationError::INVALID_KEY_LOCATOR, "Invalid signed Interest: name too short"});
|
||||
return;
|
||||
}
|
||||
|
||||
SignatureInfo si;
|
||||
try {
|
||||
si.wireDecode(interest.getName().at(signed_interest::POS_SIG_INFO).blockFromValue());
|
||||
}
|
||||
catch (const tlv::Error& e) {
|
||||
state->fail({ValidationError::Code::INVALID_KEY_LOCATOR,
|
||||
"Invalid signed Interest: " + std::string(e.what())});
|
||||
return;
|
||||
}
|
||||
|
||||
sigType = tlv::SignatureTypeValue(si.getSignatureType());
|
||||
}
|
||||
|
||||
if (rule->check(tlv::Interest, sigType, interest.getName(), klName, state)) {
|
||||
return continueValidation(make_shared<CertificateRequest>(klName), state);
|
||||
}
|
||||
// rule->check calls state->fail(...) if the check fails
|
||||
|
||||
@@ -32,6 +32,11 @@ namespace security {
|
||||
inline namespace v2 {
|
||||
namespace validator_config {
|
||||
|
||||
Checker::Checker(tlv::SignatureTypeValue sigType)
|
||||
: m_sigType(sigType)
|
||||
{
|
||||
}
|
||||
|
||||
Checker::Result::Result(std::string error)
|
||||
: m_error(std::move(error))
|
||||
{
|
||||
@@ -65,11 +70,16 @@ Checker::reject()
|
||||
}
|
||||
|
||||
Checker::Result
|
||||
Checker::check(uint32_t pktType, const Name& pktName, const Name& klName,
|
||||
Checker::check(uint32_t pktType, tlv::SignatureTypeValue sigType, const Name& pktName, const Name& klName,
|
||||
const ValidationState& state)
|
||||
{
|
||||
BOOST_ASSERT(pktType == tlv::Interest || pktType == tlv::Data);
|
||||
|
||||
if (sigType != m_sigType) {
|
||||
return reject() << "signature type does not match the checker "
|
||||
<< sigType << " != " << m_sigType;
|
||||
}
|
||||
|
||||
if (pktType == tlv::Interest) {
|
||||
auto fmt = state.getTag<SignedInterestFormatTag>();
|
||||
BOOST_ASSERT(fmt);
|
||||
@@ -94,8 +104,15 @@ Checker::check(uint32_t pktType, const Name& pktName, const Name& klName,
|
||||
}
|
||||
}
|
||||
|
||||
NameRelationChecker::NameRelationChecker(const Name& name, const NameRelation& relation)
|
||||
: m_name(name)
|
||||
Checker::Result
|
||||
Checker::checkNames(const Name& pktName, const Name& klName)
|
||||
{
|
||||
return accept();
|
||||
}
|
||||
|
||||
NameRelationChecker::NameRelationChecker(tlv::SignatureTypeValue sigType, const Name& name, const NameRelation& relation)
|
||||
: Checker(sigType)
|
||||
, m_name(name)
|
||||
, m_relation(relation)
|
||||
{
|
||||
}
|
||||
@@ -113,8 +130,9 @@ NameRelationChecker::checkNames(const Name& pktName, const Name& klName)
|
||||
<< m_relation << " relation";
|
||||
}
|
||||
|
||||
RegexChecker::RegexChecker(const Regex& regex)
|
||||
: m_regex(regex)
|
||||
RegexChecker::RegexChecker(tlv::SignatureTypeValue sigType, const Regex& regex)
|
||||
: Checker(sigType)
|
||||
, m_regex(regex)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -128,10 +146,12 @@ RegexChecker::checkNames(const Name& pktName, const Name& klName)
|
||||
return reject() << "KeyLocator does not match regex " << m_regex;
|
||||
}
|
||||
|
||||
HyperRelationChecker::HyperRelationChecker(const std::string& pktNameExpr, const std::string pktNameExpand,
|
||||
HyperRelationChecker::HyperRelationChecker(tlv::SignatureTypeValue sigType,
|
||||
const std::string& pktNameExpr, const std::string pktNameExpand,
|
||||
const std::string& klNameExpr, const std::string klNameExpand,
|
||||
const NameRelation& hyperRelation)
|
||||
: m_hyperPRegex(pktNameExpr, pktNameExpand)
|
||||
: Checker(sigType)
|
||||
, m_hyperPRegex(pktNameExpr, pktNameExpand)
|
||||
, m_hyperKRegex(klNameExpr, klNameExpand)
|
||||
, m_hyperRelation(hyperRelation)
|
||||
{
|
||||
@@ -180,6 +200,27 @@ Checker::create(const ConfigSection& configSection, const std::string& configFil
|
||||
}
|
||||
}
|
||||
|
||||
static tlv::SignatureTypeValue
|
||||
parseSigType(const std::string& value)
|
||||
{
|
||||
if (boost::iequals(value, "rsa-sha256")) {
|
||||
return tlv::SignatureSha256WithRsa;
|
||||
}
|
||||
else if (boost::iequals(value, "ecdsa-sha256")) {
|
||||
return tlv::SignatureSha256WithEcdsa;
|
||||
}
|
||||
// TODO: uncomment when HMAC logic is defined/implemented
|
||||
// else if (boost::iequals(value, "hmac-sha256")) {
|
||||
// return tlv::SignatureHmacWithSha256;
|
||||
// }
|
||||
else if (boost::iequals(value, "sha256")) {
|
||||
return tlv::DigestSha256;
|
||||
}
|
||||
else {
|
||||
NDN_THROW(Error("Unrecognized value of <checker.sig-type>: " + value));
|
||||
}
|
||||
}
|
||||
|
||||
unique_ptr<Checker>
|
||||
Checker::createCustomizedChecker(const ConfigSection& configSection,
|
||||
const std::string& configFilename)
|
||||
@@ -187,19 +228,23 @@ Checker::createCustomizedChecker(const ConfigSection& configSection,
|
||||
auto propertyIt = configSection.begin();
|
||||
propertyIt++;
|
||||
|
||||
// TODO implement restrictions based on signature type (outside this checker)
|
||||
// assume that checker by default is for ecdsa-sha256, unless explicitly specified
|
||||
auto sigType = tlv::SignatureSha256WithEcdsa;
|
||||
|
||||
if (propertyIt != configSection.end() && boost::iequals(propertyIt->first, "sig-type")) {
|
||||
// ignore sig-type
|
||||
sigType = parseSigType(propertyIt->second.data());
|
||||
propertyIt++;
|
||||
}
|
||||
|
||||
// Get checker.key-locator
|
||||
if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "key-locator")) {
|
||||
if (sigType == tlv::DigestSha256) {
|
||||
// for sha256, key-locator is optional
|
||||
return make_unique<Checker>(sigType);
|
||||
}
|
||||
NDN_THROW(Error("Expecting <checker.key-locator>"));
|
||||
}
|
||||
|
||||
auto checker = createKeyLocatorChecker(propertyIt->second, configFilename);
|
||||
auto checker = createKeyLocatorChecker(sigType, propertyIt->second, configFilename);
|
||||
propertyIt++;
|
||||
|
||||
if (propertyIt != configSection.end()) {
|
||||
@@ -215,24 +260,26 @@ Checker::createHierarchicalChecker(const ConfigSection& configSection,
|
||||
auto propertyIt = configSection.begin();
|
||||
propertyIt++;
|
||||
|
||||
// TODO implement restrictions based on signature type (outside this checker)
|
||||
// assume that checker by default is for ecdsa-sha256, unless explicitly specificied
|
||||
auto sigType = tlv::SignatureSha256WithEcdsa;
|
||||
|
||||
if (propertyIt != configSection.end() && boost::iequals(propertyIt->first, "sig-type")) {
|
||||
// ignore sig-type
|
||||
sigType = parseSigType(propertyIt->second.data());
|
||||
propertyIt++;
|
||||
}
|
||||
|
||||
if (propertyIt != configSection.end()) {
|
||||
NDN_THROW(Error("Expecting end of <checker>"));
|
||||
}
|
||||
return make_unique<HyperRelationChecker>("^(<>*)$", "\\1",
|
||||
return make_unique<HyperRelationChecker>(sigType,
|
||||
"^(<>*)$", "\\1",
|
||||
"^(<>*)<KEY><>{1,3}$", "\\1",
|
||||
NameRelation::IS_PREFIX_OF);
|
||||
}
|
||||
|
||||
unique_ptr<Checker>
|
||||
Checker::createKeyLocatorChecker(const ConfigSection& configSection,
|
||||
const std::string& configFilename)
|
||||
Checker::createKeyLocatorChecker(tlv::SignatureTypeValue sigType,
|
||||
const ConfigSection& configSection, const std::string& configFilename)
|
||||
{
|
||||
auto propertyIt = configSection.begin();
|
||||
|
||||
@@ -242,14 +289,14 @@ Checker::createKeyLocatorChecker(const ConfigSection& configSection,
|
||||
|
||||
std::string type = propertyIt->second.data();
|
||||
if (boost::iequals(type, "name"))
|
||||
return createKeyLocatorNameChecker(configSection, configFilename);
|
||||
return createKeyLocatorNameChecker(sigType, configSection, configFilename);
|
||||
else
|
||||
NDN_THROW(Error("Unrecognized <checker.key-locator.type>: " + type));
|
||||
}
|
||||
|
||||
unique_ptr<Checker>
|
||||
Checker::createKeyLocatorNameChecker(const ConfigSection& configSection,
|
||||
const std::string& configFilename)
|
||||
Checker::createKeyLocatorNameChecker(tlv::SignatureTypeValue sigType,
|
||||
const ConfigSection& configSection, const std::string& configFilename)
|
||||
{
|
||||
auto propertyIt = configSection.begin();
|
||||
propertyIt++;
|
||||
@@ -279,7 +326,7 @@ Checker::createKeyLocatorNameChecker(const ConfigSection& configSection,
|
||||
if (propertyIt != configSection.end()) {
|
||||
NDN_THROW(Error("Expecting end of <checker.key-locator>"));
|
||||
}
|
||||
return make_unique<NameRelationChecker>(name, relation);
|
||||
return make_unique<NameRelationChecker>(sigType, name, relation);
|
||||
}
|
||||
else if (boost::iequals(propertyIt->first, "regex")) {
|
||||
std::string regexString = propertyIt->second.data();
|
||||
@@ -290,7 +337,7 @@ Checker::createKeyLocatorNameChecker(const ConfigSection& configSection,
|
||||
}
|
||||
|
||||
try {
|
||||
return make_unique<RegexChecker>(Regex(regexString));
|
||||
return make_unique<RegexChecker>(sigType, Regex(regexString));
|
||||
}
|
||||
catch (const Regex::Error&) {
|
||||
NDN_THROW_NESTED(Error("Invalid <checker.key-locator.regex>: " + regexString));
|
||||
@@ -346,7 +393,7 @@ Checker::createKeyLocatorNameChecker(const ConfigSection& configSection,
|
||||
|
||||
NameRelation relation = getNameRelationFromString(hRelation);
|
||||
try {
|
||||
return make_unique<HyperRelationChecker>(pRegex, pExpand, kRegex, kExpand, relation);
|
||||
return make_unique<HyperRelationChecker>(sigType, pRegex, pExpand, kRegex, kExpand, relation);
|
||||
}
|
||||
catch (const Regex::Error&) {
|
||||
NDN_THROW_NESTED(Error("Invalid regex for <key-locator.hyper-relation>"));
|
||||
|
||||
@@ -71,6 +71,9 @@ public:
|
||||
friend Checker;
|
||||
};
|
||||
|
||||
explicit
|
||||
Checker(tlv::SignatureTypeValue sigType);
|
||||
|
||||
virtual
|
||||
~Checker() = default;
|
||||
|
||||
@@ -78,12 +81,14 @@ public:
|
||||
* @brief Check if packet name and KeyLocator satisfy the checker's conditions
|
||||
*
|
||||
* @param pktType tlv::Interest or tlv::Data
|
||||
* @param sigType Signature type
|
||||
* @param pktName packet's name
|
||||
* @param klName KeyLocator's name
|
||||
* @param state Validation state
|
||||
*/
|
||||
Result
|
||||
check(uint32_t pktType, const Name& pktName, const Name& klName, const ValidationState& state);
|
||||
check(uint32_t pktType, tlv::SignatureTypeValue sigType,
|
||||
const Name& pktName, const Name& klName, const ValidationState& state);
|
||||
|
||||
/**
|
||||
* @brief create a checker from configuration section
|
||||
@@ -96,8 +101,12 @@ public:
|
||||
create(const ConfigSection& configSection, const std::string& configFilename);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Base version of name checking
|
||||
* @return always returns accept()
|
||||
*/
|
||||
virtual Result
|
||||
checkNames(const Name& pktName, const Name& klName) = 0;
|
||||
checkNames(const Name& pktName, const Name& klName);
|
||||
|
||||
static Result
|
||||
accept()
|
||||
@@ -118,16 +127,21 @@ private:
|
||||
createHierarchicalChecker(const ConfigSection& configSection, const std::string& configFilename);
|
||||
|
||||
static unique_ptr<Checker>
|
||||
createKeyLocatorChecker(const ConfigSection& configSection, const std::string& configFilename);
|
||||
createKeyLocatorChecker(tlv::SignatureTypeValue sigType,
|
||||
const ConfigSection& configSection, const std::string& configFilename);
|
||||
|
||||
static unique_ptr<Checker>
|
||||
createKeyLocatorNameChecker(const ConfigSection& configSection, const std::string& configFilename);
|
||||
createKeyLocatorNameChecker(tlv::SignatureTypeValue sigType,
|
||||
const ConfigSection& configSection, const std::string& configFilename);
|
||||
|
||||
protected:
|
||||
tlv::SignatureTypeValue m_sigType = tlv::SignatureSha256WithEcdsa;
|
||||
};
|
||||
|
||||
class NameRelationChecker : public Checker
|
||||
{
|
||||
public:
|
||||
NameRelationChecker(const Name& name, const NameRelation& relation);
|
||||
NameRelationChecker(tlv::SignatureTypeValue sigType, const Name& name, const NameRelation& relation);
|
||||
|
||||
protected:
|
||||
Result
|
||||
@@ -142,7 +156,7 @@ class RegexChecker : public Checker
|
||||
{
|
||||
public:
|
||||
explicit
|
||||
RegexChecker(const Regex& regex);
|
||||
RegexChecker(tlv::SignatureTypeValue sigType, const Regex& regex);
|
||||
|
||||
protected:
|
||||
Result
|
||||
@@ -155,7 +169,8 @@ private:
|
||||
class HyperRelationChecker : public Checker
|
||||
{
|
||||
public:
|
||||
HyperRelationChecker(const std::string& pktNameExpr, const std::string pktNameExpand,
|
||||
HyperRelationChecker(tlv::SignatureTypeValue sigType,
|
||||
const std::string& pktNameExpr, const std::string pktNameExpand,
|
||||
const std::string& klNameExpr, const std::string klNameExpand,
|
||||
const NameRelation& hyperRelation);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ Rule::match(uint32_t pktType, const Name& pktName, const shared_ptr<ValidationSt
|
||||
}
|
||||
|
||||
bool
|
||||
Rule::check(uint32_t pktType, const Name& pktName, const Name& klName,
|
||||
Rule::check(uint32_t pktType, tlv::SignatureTypeValue sigType, const Name& pktName, const Name& klName,
|
||||
const shared_ptr<ValidationState>& state) const
|
||||
{
|
||||
NDN_LOG_TRACE("Trying to check " << pktName << " with KeyLocator " << klName);
|
||||
@@ -87,7 +87,7 @@ Rule::check(uint32_t pktType, const Name& pktName, const Name& klName,
|
||||
std::vector<Checker::Result> checkerResults;
|
||||
checkerResults.reserve(m_checkers.size());
|
||||
for (const auto& checker : m_checkers) {
|
||||
auto result = checker->check(pktType, pktName, klName, *state);
|
||||
auto result = checker->check(pktType, sigType, pktName, klName, *state);
|
||||
if (result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ public:
|
||||
* @brief Check if packet satisfies rule's condition.
|
||||
*
|
||||
* @param pktType tlv::Interest or tlv::Data
|
||||
* @param sigType Signature type
|
||||
* @param pktName packet name, for signed Interests the last two components are not removed
|
||||
* @param klName KeyLocator name
|
||||
* @param state Validation state
|
||||
@@ -87,7 +88,8 @@ public:
|
||||
* @throw Error the supplied pktType doesn't match one for which the rule is designed.
|
||||
*/
|
||||
bool
|
||||
check(uint32_t pktType, const Name& pktName, const Name& klName, const shared_ptr<ValidationState>& state) const;
|
||||
check(uint32_t pktType, tlv::SignatureTypeValue sigType, const Name& pktName, const Name& klName,
|
||||
const shared_ptr<ValidationState>& state) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
)CONF";
|
||||
@@ -445,6 +445,55 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateInterest, Policy, InterestPolicies, Pol
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(DigestSha256, HierarchicalValidatorFixture<ValidationPolicyConfig>)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
|
||||
this->policy.load(R"CONF(
|
||||
rule
|
||||
{
|
||||
id test-rule-data-id
|
||||
for data
|
||||
filter
|
||||
{
|
||||
type name
|
||||
name /Security/ValidatorFixture
|
||||
relation is-prefix-of
|
||||
}
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type sha256
|
||||
}
|
||||
}
|
||||
rule
|
||||
{
|
||||
id test-rule-interest-id
|
||||
for interest
|
||||
filter
|
||||
{
|
||||
type name
|
||||
name /Security/ValidatorFixture
|
||||
relation is-prefix-of
|
||||
}
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type sha256
|
||||
}
|
||||
}
|
||||
)CONF", "test-config");
|
||||
|
||||
|
||||
Interest interest("/Security/ValidatorFixture/Sub1/Sub2/Packet");
|
||||
interest.setCanBePrefix(false);
|
||||
this->m_keyChain.sign(interest, signingWithSha256());
|
||||
VALIDATE_SUCCESS(interest, "Should be accepted");
|
||||
|
||||
Data data("/Security/ValidatorFixture/Sub1/Sub2/Packet");
|
||||
this->m_keyChain.sign(data, signingWithSha256());
|
||||
VALIDATE_SUCCESS(data, "Should be accepted");
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(DigestSha256WithKeyLocator, HierarchicalValidatorFixture<ValidationPolicyConfig>)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
|
||||
this->policy.load(R"CONF(
|
||||
@@ -517,6 +566,79 @@ BOOST_FIXTURE_TEST_CASE(DigestSha256, HierarchicalValidatorFixture<ValidationPol
|
||||
VALIDATE_SUCCESS(data, "Should be accepted");
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(SigTypeCheck, HierarchicalValidatorFixture<ValidationPolicyConfig>)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
|
||||
this->policy.load(R"CONF(
|
||||
rule
|
||||
{
|
||||
id test-rule-data-id
|
||||
for data
|
||||
filter
|
||||
{
|
||||
type name
|
||||
name /localhost/identity/digest-sha256
|
||||
relation is-prefix-of
|
||||
}
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^(<>*)$
|
||||
k-expand \\1
|
||||
h-relation is-prefix-of
|
||||
p-regex ^(<>*)$
|
||||
p-expand \\1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rule
|
||||
{
|
||||
id test-rule-interest-id
|
||||
for interest
|
||||
filter
|
||||
{
|
||||
type name
|
||||
name /localhost/identity/digest-sha256
|
||||
relation is-prefix-of
|
||||
}
|
||||
checker
|
||||
{
|
||||
type customized
|
||||
sig-type ecdsa-sha256
|
||||
key-locator
|
||||
{
|
||||
type name
|
||||
hyper-relation
|
||||
{
|
||||
k-regex ^(<>*)$
|
||||
k-expand \\1
|
||||
h-relation is-prefix-of
|
||||
p-regex ^(<>*)$
|
||||
p-expand \\1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)CONF", "test-config");
|
||||
|
||||
|
||||
Interest interest("/localhost/identity/digest-sha256/foobar");
|
||||
interest.setCanBePrefix(false);
|
||||
this->m_keyChain.sign(interest, signingWithSha256());
|
||||
VALIDATE_FAILURE(interest, "Signature type check should fail");
|
||||
|
||||
Data data("/localhost/identity/digest-sha256/foobar");
|
||||
this->m_keyChain.sign(data, signingWithSha256());
|
||||
VALIDATE_FAILURE(data, "Signature type check should fail");
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE(Reload, HierarchicalValidatorFixture<ValidationPolicyConfig>)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(this->policy.m_isConfigured, false);
|
||||
@@ -534,7 +656,7 @@ BOOST_FIXTURE_TEST_CASE(Reload, HierarchicalValidatorFixture<ValidationPolicyCon
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
rule
|
||||
@@ -550,7 +672,7 @@ BOOST_FIXTURE_TEST_CASE(Reload, HierarchicalValidatorFixture<ValidationPolicyCon
|
||||
checker
|
||||
{
|
||||
type hierarchical
|
||||
sig-type rsa-sha256
|
||||
sig-type ecdsa-sha256
|
||||
}
|
||||
}
|
||||
trust-anchor
|
||||
|
||||
@@ -68,11 +68,11 @@ public:
|
||||
|
||||
template<typename PktType, typename C>
|
||||
static void
|
||||
testChecker(C& checker, const Name& pktName, const Name& klName, bool expectedOutcome)
|
||||
testChecker(C& checker, tlv::SignatureTypeValue sigType, const Name& pktName, const Name& klName, bool expectedOutcome)
|
||||
{
|
||||
BOOST_TEST_CONTEXT("pkt=" << pktName << " kl=" << klName) {
|
||||
auto state = PktType::makeState();
|
||||
auto result = checker.check(PktType::getType(), pktName, klName, *state);
|
||||
auto result = checker.check(PktType::getType(), sigType, pktName, klName, *state);
|
||||
BOOST_CHECK_EQUAL(bool(result), expectedOutcome);
|
||||
BOOST_CHECK(boost::logic::indeterminate(state->getOutcome()));
|
||||
if (!result) {
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
class NameRelationEqual : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
NameRelationChecker checker{"/foo/bar", NameRelation::EQUAL};
|
||||
NameRelationChecker checker{tlv::SignatureSha256WithRsa, "/foo/bar", NameRelation::EQUAL};
|
||||
std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
|
||||
{true, false, false, false},
|
||||
{true, false, false, false},
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
class NameRelationIsPrefixOf : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
NameRelationChecker checker{"/foo/bar", NameRelation::IS_PREFIX_OF};
|
||||
NameRelationChecker checker{tlv::SignatureSha256WithRsa, "/foo/bar", NameRelation::IS_PREFIX_OF};
|
||||
std::vector<std::vector<bool>> outcomes = {{true, true, false, false},
|
||||
{true, true, false, false},
|
||||
{true, true, false, false},
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
class NameRelationIsStrictPrefixOf : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
NameRelationChecker checker{"/foo/bar", NameRelation::IS_STRICT_PREFIX_OF};
|
||||
NameRelationChecker checker{tlv::SignatureSha256WithRsa, "/foo/bar", NameRelation::IS_STRICT_PREFIX_OF};
|
||||
std::vector<std::vector<bool>> outcomes = {{false, true, false, false},
|
||||
{false, true, false, false},
|
||||
{false, true, false, false},
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
class RegexEqual : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
RegexChecker checker{Regex("^<foo><bar><KEY><>{1,3}$")};
|
||||
RegexChecker checker{tlv::SignatureSha256WithRsa, Regex("^<foo><bar><KEY><>{1,3}$")};
|
||||
std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
|
||||
{true, false, false, false},
|
||||
{true, false, false, false},
|
||||
@@ -128,7 +128,7 @@ public:
|
||||
class RegexIsPrefixOf : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
RegexChecker checker{Regex("^<foo><bar><>*<KEY><>{1,3}$")};
|
||||
RegexChecker checker{tlv::SignatureSha256WithRsa, Regex("^<foo><bar><>*<KEY><>{1,3}$")};
|
||||
std::vector<std::vector<bool>> outcomes = {{true, true, false, false},
|
||||
{true, true, false, false},
|
||||
{true, true, false, false},
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
class RegexIsStrictPrefixOf : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
RegexChecker checker{Regex("^<foo><bar><>+<KEY><>{1,3}$")};
|
||||
RegexChecker checker{tlv::SignatureSha256WithRsa, Regex("^<foo><bar><>+<KEY><>{1,3}$")};
|
||||
std::vector<std::vector<bool>> outcomes = {{false, true, false, false},
|
||||
{false, true, false, false},
|
||||
{false, true, false, false},
|
||||
@@ -148,7 +148,8 @@ public:
|
||||
class HyperRelationEqual : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
HyperRelationChecker checker{"^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::EQUAL};
|
||||
HyperRelationChecker checker{tlv::SignatureSha256WithRsa,
|
||||
"^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::EQUAL};
|
||||
std::vector<std::vector<bool>> outcomes = {{true, false, false, false},
|
||||
{false, true, false, false},
|
||||
{false, false, true, false},
|
||||
@@ -158,7 +159,8 @@ public:
|
||||
class HyperRelationIsPrefixOf : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
HyperRelationChecker checker{"^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::IS_PREFIX_OF};
|
||||
HyperRelationChecker checker{tlv::SignatureSha256WithRsa,
|
||||
"^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::IS_PREFIX_OF};
|
||||
std::vector<std::vector<bool>> outcomes = {{true, false, true, false},
|
||||
{true, true, true, false},
|
||||
{false, false, true, false},
|
||||
@@ -168,7 +170,8 @@ public:
|
||||
class HyperRelationIsStrictPrefixOf : public CheckerFixture
|
||||
{
|
||||
public:
|
||||
HyperRelationChecker checker{"^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::IS_STRICT_PREFIX_OF};
|
||||
HyperRelationChecker checker{tlv::SignatureSha256WithRsa,
|
||||
"^(<>+)$", "\\1", "^(<>+)<KEY><>{1,3}$", "\\1", NameRelation::IS_STRICT_PREFIX_OF};
|
||||
std::vector<std::vector<bool>> outcomes = {{false, false, true, false},
|
||||
{true, false, true, false},
|
||||
{false, false, false, false},
|
||||
@@ -326,10 +329,13 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checks, T, Tests, T::second)
|
||||
bool expectedOutcome = this->outcomes[i][j];
|
||||
|
||||
auto klName = this->makeKeyLocatorKeyName(this->names[j]);
|
||||
this->template testChecker<PktType>(this->checker, pktName, klName, expectedOutcome);
|
||||
this->template testChecker<PktType>(this->checker, tlv::SignatureSha256WithRsa, pktName, klName, expectedOutcome);
|
||||
this->template testChecker<PktType>(this->checker, tlv::SignatureSha256WithEcdsa, pktName, klName, false);
|
||||
|
||||
|
||||
klName = this->makeKeyLocatorCertName(this->names[j]);
|
||||
this->template testChecker<PktType>(this->checker, pktName, klName, expectedOutcome);
|
||||
this->template testChecker<PktType>(this->checker, tlv::SignatureSha256WithRsa, pktName, klName, expectedOutcome);
|
||||
this->template testChecker<PktType>(this->checker, tlv::SignatureSha256WithEcdsa, pktName, klName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,8 @@ BOOST_AUTO_TEST_SUITE(TestRule)
|
||||
BOOST_FIXTURE_TEST_CASE(Errors, RuleFixture<DataPkt>)
|
||||
{
|
||||
BOOST_CHECK_THROW(rule.match(tlv::Interest, this->pktName, state), Error);
|
||||
BOOST_CHECK_THROW(rule.check(tlv::Interest, this->pktName, "/foo/bar", state), Error);
|
||||
BOOST_CHECK_THROW(rule.check(tlv::Interest, tlv::SignatureSha256WithRsa,
|
||||
this->pktName, "/foo/bar", state), Error);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(Constructor, PktType, PktTypes, RuleFixture<PktType>)
|
||||
@@ -76,7 +77,8 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Constructor, PktType, PktTypes, RuleFixture<Pkt
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(EmptyRule, PktType, PktTypes, RuleFixture<PktType>)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
|
||||
BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), this->pktName, "/foo/bar", this->state), false);
|
||||
BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
|
||||
this->pktName, "/foo/bar", this->state), false);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(Filters, PktType, PktTypes, RuleFixture<PktType>)
|
||||
@@ -91,7 +93,8 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Filters, PktType, PktTypes, RuleFixture<PktType
|
||||
BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), this->pktName, this->state), true);
|
||||
BOOST_CHECK_EQUAL(this->rule.match(PktType::getType(), "/not" + this->pktName.toUri(), this->state), true);
|
||||
|
||||
BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), this->pktName, "/foo/bar", this->state), false);
|
||||
BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
|
||||
this->pktName, "/foo/bar", this->state), false);
|
||||
}
|
||||
|
||||
BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checkers, PktType, PktTypes, RuleFixture<PktType>)
|
||||
@@ -99,7 +102,8 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checkers, PktType, PktTypes, RuleFixture<PktTyp
|
||||
auto testChecker = [this] (const Name& klName, bool expectedOutcome) {
|
||||
BOOST_TEST_CONTEXT(klName << " expected=" << expectedOutcome) {
|
||||
this->state = PktType::makeState(); // reset state
|
||||
BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), this->pktName, klName, this->state),
|
||||
BOOST_CHECK_EQUAL(this->rule.check(PktType::getType(), tlv::SignatureSha256WithRsa,
|
||||
this->pktName, klName, this->state),
|
||||
expectedOutcome);
|
||||
|
||||
auto outcome = this->state->getOutcome();
|
||||
@@ -113,14 +117,16 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(Checkers, PktType, PktTypes, RuleFixture<PktTyp
|
||||
}
|
||||
};
|
||||
|
||||
this->rule.addChecker(make_unique<HyperRelationChecker>("^(<>+)$", "\\1",
|
||||
this->rule.addChecker(make_unique<HyperRelationChecker>(tlv::SignatureSha256WithRsa,
|
||||
"^(<>+)$", "\\1",
|
||||
"^<always>(<>+)$", "\\1",
|
||||
NameRelation::EQUAL));
|
||||
testChecker("/always/foo/bar", true);
|
||||
testChecker("/seldomly/foo/bar", false);
|
||||
testChecker("/never/foo/bar", false);
|
||||
|
||||
this->rule.addChecker(make_unique<HyperRelationChecker>("^(<>+)$", "\\1",
|
||||
this->rule.addChecker(make_unique<HyperRelationChecker>(tlv::SignatureSha256WithRsa,
|
||||
"^(<>+)$", "\\1",
|
||||
"^<seldomly>(<>+)$", "\\1",
|
||||
NameRelation::EQUAL));
|
||||
testChecker("/always/foo/bar", true);
|
||||
@@ -189,13 +195,14 @@ BOOST_FIXTURE_TEST_CASE_TEMPLATE(FilterAndChecker, PktType, PktTypes, RuleFixtur
|
||||
)CONF";
|
||||
auto rule = Rule::create(makeSection(config), "test-config");
|
||||
|
||||
BOOST_CHECK_EQUAL(rule->match(PktType::getType(), this->pktName, this->state), true);
|
||||
BOOST_CHECK_EQUAL(rule->match(PktType::getType(), "/not" + this->pktName.toUri(), this->state), false);
|
||||
BOOST_CHECK(rule->match(PktType::getType(), this->pktName, this->state));
|
||||
BOOST_CHECK(!rule->match(PktType::getType(), "/not" + this->pktName.toUri(), this->state));
|
||||
|
||||
BOOST_CHECK_EQUAL(rule->check(PktType::getType(), this->pktName, "/foo/bar", this->state), true);
|
||||
BOOST_CHECK(rule->check(PktType::getType(), tlv::SignatureSha256WithRsa, this->pktName, "/foo/bar", this->state));
|
||||
BOOST_CHECK(!rule->check(PktType::getType(), tlv::SignatureSha256WithEcdsa, this->pktName, "/foo/bar", this->state));
|
||||
|
||||
this->state = PktType::makeState(); // reset state
|
||||
BOOST_CHECK_EQUAL(rule->check(PktType::getType(), this->pktName, "/not/foo/bar", this->state), false);
|
||||
BOOST_CHECK(!rule->check(PktType::getType(), tlv::SignatureSha256WithRsa, this->pktName, "/not/foo/bar", this->state));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END() // Create
|
||||
|
||||
Reference in new issue
Block a user