security: cleanup validation error reporting
Change-Id: I313bedb336ecfb4180ba0f31ad77666544ba1c10
diff --git a/.jenkins.d/00-deps.sh b/.jenkins.d/00-deps.sh
index 54476fe..12b5de3 100755
--- a/.jenkins.d/00-deps.sh
+++ b/.jenkins.d/00-deps.sh
@@ -8,7 +8,7 @@
case $JOB_NAME in
*code-coverage)
APT_PKGS+=(lcov python3-pip)
- PIP_PKGS+=('gcovr~=5.1')
+ PIP_PKGS+=('gcovr~=5.2')
;;
*Docs)
APT_PKGS+=(doxygen graphviz python3-pip)
diff --git a/docs/INSTALL.rst b/docs/INSTALL.rst
index 45652ab..f9492db 100644
--- a/docs/INSTALL.rst
+++ b/docs/INSTALL.rst
@@ -42,7 +42,7 @@
To build ndn-cxx from source, one must first install a C++ compiler and all necessary
development tools and libraries:
-- On **Ubuntu**
+- On **Debian** and **Ubuntu**
In a terminal, enter::
@@ -98,7 +98,7 @@
export PATH="${HOME}/.local/bin${PATH:+:}${PATH}"
-- On **Ubuntu**:
+- On **Debian** and **Ubuntu**:
.. code-block:: sh
diff --git a/ndn-cxx/mgmt/nfd/controller.cpp b/ndn-cxx/mgmt/nfd/controller.cpp
index dbc0014..8d8f248 100644
--- a/ndn-cxx/mgmt/nfd/controller.cpp
+++ b/ndn-cxx/mgmt/nfd/controller.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -66,9 +66,10 @@
[=] (const Interest&, const Data& data) {
processCommandResponse(data, command, onSuccess, onFailure);
},
- [=] (const Interest&, const lp::Nack&) {
+ [=] (const Interest&, const lp::Nack& nack) {
if (onFailure)
- onFailure(ControlResponse(Controller::ERROR_NACK, "network Nack received"));
+ onFailure(ControlResponse(Controller::ERROR_NACK,
+ "received Nack: " + boost::lexical_cast<std::string>(nack.getReason())));
},
[=] (const Interest&) {
if (onFailure)
@@ -159,8 +160,8 @@
}
auto it = m_fetchers.insert(fetcher).first;
- fetcher->onComplete.connect([this, it] (ConstBufferPtr) { m_fetchers.erase(it); });
- fetcher->onError.connect([this, it] (uint32_t, const std::string&) { m_fetchers.erase(it); });
+ fetcher->onComplete.connect([this, it] (auto&&...) { m_fetchers.erase(it); });
+ fetcher->onError.connect([this, it] (auto&&...) { m_fetchers.erase(it); });
}
void
diff --git a/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp b/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp
index abfc636..06c6a57 100644
--- a/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp
+++ b/ndn-cxx/security/certificate-fetcher-direct-fetch.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -46,8 +46,8 @@
const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation)
{
- auto interestState = dynamic_pointer_cast<InterestValidationState>(state);
uint64_t incomingFaceId = 0;
+ auto interestState = dynamic_pointer_cast<InterestValidationState>(state);
if (interestState != nullptr) {
auto incomingFaceIdTag = interestState->getOriginalInterest().getTag<lp::IncomingFaceIdTag>();
if (incomingFaceIdTag != nullptr) {
@@ -61,6 +61,7 @@
incomingFaceId = incomingFaceIdTag->get();
}
}
+
if (incomingFaceId != 0) {
Interest directInterest(keyRequest->interest);
directInterest.refreshNonce();
@@ -89,8 +90,7 @@
CertificateFetcherFromNetwork::doFetch(keyRequest, state, continueValidation);
}
else if (incomingFaceId == 0) {
- state->fail({ValidationError::Code::CANNOT_RETRIEVE_CERT,
- "Cannot direct fetch certificate as IncomingFaceId tag is not set"});
+ state->fail({ValidationError::CANNOT_RETRIEVE_CERT, "IncomingFaceId not set"});
}
}
diff --git a/ndn-cxx/security/certificate-fetcher-from-network.cpp b/ndn-cxx/security/certificate-fetcher-from-network.cpp
index a117ee4..65c70c9 100644
--- a/ndn-cxx/security/certificate-fetcher-from-network.cpp
+++ b/ndn-cxx/security/certificate-fetcher-from-network.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -71,8 +71,7 @@
cert = Certificate(data);
}
catch (const tlv::Error& e) {
- return state->fail({ValidationError::Code::MALFORMED_CERT, "Fetched a malformed certificate "
- "`" + data.getName().toUri() + "` (" + e.what() + ")"});
+ return state->fail({ValidationError::MALFORMED_CERT, "`" + data.getName().toUri() + "`: " + e.what()});
}
continueValidation(cert, state);
}
@@ -83,7 +82,7 @@
const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation)
{
- NDN_LOG_DEBUG_DEPTH("NACK (" << nack.getReason() << ") while fetching certificate "
+ NDN_LOG_DEBUG_DEPTH("Nack (" << nack.getReason() << ") while fetching certificate "
<< certRequest->interest.getName());
--certRequest->nRetriesLeft;
@@ -93,8 +92,8 @@
certRequest->waitAfterNack *= 2;
}
else {
- state->fail({ValidationError::Code::CANNOT_RETRIEVE_CERT, "Cannot fetch certificate after all "
- "retries `" + certRequest->interest.getName().toUri() + "`"});
+ state->fail({ValidationError::CANNOT_RETRIEVE_CERT, "Nack after exhausting all retries for "
+ "`" + certRequest->interest.getName().toUri() + "`"});
}
}
@@ -103,16 +102,15 @@
const shared_ptr<ValidationState>& state,
const ValidationContinuation& continueValidation)
{
- NDN_LOG_DEBUG_DEPTH("Timeout while fetching certificate " << certRequest->interest.getName()
- << ", retrying");
+ NDN_LOG_DEBUG_DEPTH("Timeout while fetching certificate " << certRequest->interest.getName());
--certRequest->nRetriesLeft;
if (certRequest->nRetriesLeft >= 0) {
fetch(certRequest, state, continueValidation);
}
else {
- state->fail({ValidationError::Code::CANNOT_RETRIEVE_CERT, "Cannot fetch certificate after all "
- "retries `" + certRequest->interest.getName().toUri() + "`"});
+ state->fail({ValidationError::CANNOT_RETRIEVE_CERT, "Timeout after exhausting all retries for "
+ "`" + certRequest->interest.getName().toUri() + "`"});
}
}
diff --git a/ndn-cxx/security/certificate-fetcher-offline.cpp b/ndn-cxx/security/certificate-fetcher-offline.cpp
index ea19a73..a613a9e 100644
--- a/ndn-cxx/security/certificate-fetcher-offline.cpp
+++ b/ndn-cxx/security/certificate-fetcher-offline.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -32,8 +32,8 @@
const shared_ptr<ValidationState>& state,
const ValidationContinuation&)
{
- state->fail({ValidationError::Code::CANNOT_RETRIEVE_CERT,
- "Cannot fetch certificate " + certRequest->interest.getName().toUri() + " in offline mode"});
+ state->fail({ValidationError::CANNOT_RETRIEVE_CERT,
+ "Cannot fetch `" + certRequest->interest.getName().toUri() + "` in offline mode"});
}
} // inline namespace v2
diff --git a/ndn-cxx/security/validation-callback.hpp b/ndn-cxx/security/validation-callback.hpp
index 23018eb..8e00c33 100644
--- a/ndn-cxx/security/validation-callback.hpp
+++ b/ndn-cxx/security/validation-callback.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -24,7 +24,6 @@
#include "ndn-cxx/data.hpp"
#include "ndn-cxx/interest.hpp"
-#include "ndn-cxx/security/security-common.hpp"
#include "ndn-cxx/security/validation-error.hpp"
namespace ndn {
@@ -34,22 +33,22 @@
/**
* @brief Callback to report a successful Data validation.
*/
-typedef function<void(const Data& data)> DataValidationSuccessCallback;
+using DataValidationSuccessCallback = std::function<void(const Data&)>;
/**
* @brief Callback to report a failed Data validation.
*/
-typedef function<void(const Data& data, const ValidationError& error)> DataValidationFailureCallback;
+using DataValidationFailureCallback = std::function<void(const Data&, const ValidationError&)>;
/**
* @brief Callback to report a successful Interest validation.
*/
-typedef function<void(const Interest& interest)> InterestValidationSuccessCallback;
+using InterestValidationSuccessCallback = std::function<void(const Interest&)>;
/**
* @brief Callback to report a failed Interest validation.
*/
-typedef function<void(const Interest& interest, const ValidationError& error)> InterestValidationFailureCallback;
+using InterestValidationFailureCallback = std::function<void(const Interest&, const ValidationError&)>;
} // inline namespace v2
} // namespace security
diff --git a/ndn-cxx/security/validation-error.cpp b/ndn-cxx/security/validation-error.cpp
index 102cb30..b32ce5a 100644
--- a/ndn-cxx/security/validation-error.cpp
+++ b/ndn-cxx/security/validation-error.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -21,8 +21,6 @@
#include "ndn-cxx/security/validation-error.hpp"
-#include <ostream>
-
namespace ndn {
namespace security {
inline namespace v2 {
@@ -31,29 +29,29 @@
operator<<(std::ostream& os, ValidationError::Code code)
{
switch (code) {
- case ValidationError::Code::NO_ERROR:
+ case ValidationError::NO_ERROR:
return os << "No error";
- case ValidationError::Code::INVALID_SIGNATURE:
+ case ValidationError::INVALID_SIGNATURE:
return os << "Invalid signature";
- case ValidationError::Code::NO_SIGNATURE:
+ case ValidationError::NO_SIGNATURE:
return os << "Missing signature";
- case ValidationError::Code::CANNOT_RETRIEVE_CERT:
+ case ValidationError::CANNOT_RETRIEVE_CERT:
return os << "Cannot retrieve certificate";
- case ValidationError::Code::EXPIRED_CERT:
- return os << "Certificate expired";
- case ValidationError::Code::LOOP_DETECTED:
+ case ValidationError::EXPIRED_CERT:
+ return os << "Certificate expired or not yet valid";
+ case ValidationError::LOOP_DETECTED:
return os << "Loop detected in certification chain";
- case ValidationError::Code::MALFORMED_CERT:
+ case ValidationError::MALFORMED_CERT:
return os << "Malformed certificate";
- case ValidationError::Code::EXCEEDED_DEPTH_LIMIT:
+ case ValidationError::EXCEEDED_DEPTH_LIMIT:
return os << "Exceeded validation depth limit";
- case ValidationError::Code::INVALID_KEY_LOCATOR:
+ case ValidationError::INVALID_KEY_LOCATOR:
return os << "Key locator violates validation policy";
- case ValidationError::Code::POLICY_ERROR:
+ case ValidationError::POLICY_ERROR:
return os << "Validation policy error";
- case ValidationError::Code::IMPLEMENTATION_ERROR:
- return os << "Internal implementation error";
- case ValidationError::Code::USER_MIN:
+ case ValidationError::IMPLEMENTATION_ERROR:
+ return os << "Internal error";
+ case ValidationError::USER_MIN:
break;
}
if (code >= ValidationError::Code::USER_MIN) {
@@ -64,14 +62,13 @@
}
}
-std::ostream&
-operator<<(std::ostream& os, const ValidationError& error)
+void
+ValidationError::print(std::ostream& os) const
{
- os << static_cast<ValidationError::Code>(error.getCode());
- if (!error.getInfo().empty()) {
- os << " (" << error.getInfo() << ")";
+ os << static_cast<ValidationError::Code>(m_code);
+ if (!m_info.empty()) {
+ os << " (" << m_info << ")";
}
- return os;
}
} // inline namespace v2
diff --git a/ndn-cxx/security/validation-error.hpp b/ndn-cxx/security/validation-error.hpp
index 5c0c3ae..bc68b4e 100644
--- a/ndn-cxx/security/validation-error.hpp
+++ b/ndn-cxx/security/validation-error.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -50,12 +50,11 @@
INVALID_KEY_LOCATOR = 8,
POLICY_ERROR = 9,
IMPLEMENTATION_ERROR = 255,
- USER_MIN = 256 // custom error codes should use >=256
+ USER_MIN = 256, // custom error codes should use >=256
};
-public:
/**
- * @brief Validation error, implicitly convertible from an error code and info
+ * @brief Validation error, implicitly convertible from an error code and info string
*/
ValidationError(uint32_t code, const std::string& info = "")
: m_code(code)
@@ -76,6 +75,18 @@
}
private:
+ void
+ print(std::ostream& os) const;
+
+ // hidden friend non-member operator, must be defined inline
+ friend std::ostream&
+ operator<<(std::ostream& os, const ValidationError& err)
+ {
+ err.print(os);
+ return os;
+ }
+
+private:
uint32_t m_code;
std::string m_info;
};
@@ -83,9 +94,6 @@
std::ostream&
operator<<(std::ostream& os, ValidationError::Code code);
-std::ostream&
-operator<<(std::ostream& os, const ValidationError& error);
-
} // inline namespace v2
} // namespace security
} // namespace ndn
diff --git a/ndn-cxx/security/validation-policy-command-interest.cpp b/ndn-cxx/security/validation-policy-command-interest.cpp
index 8da3d68..3ee2cb8 100644
--- a/ndn-cxx/security/validation-policy-command-interest.cpp
+++ b/ndn-cxx/security/validation-policy-command-interest.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -93,7 +93,7 @@
// TODO: Refactor to support other/combinations of the restrictions based on Nonce, Time, and/or SeqNum
if (!optionalTimestamp) {
state->fail({ValidationError::POLICY_ERROR, "Signed Interest `" +
- interest.getName().toUri() + "` doesn't include required SignatureTime element"});
+ interest.getName().toUri() + "` does not include required SignatureTime element"});
return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
}
timestamp = *optionalTimestamp;
@@ -106,10 +106,10 @@
return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
}
- const name::Component& timestampComp = name.at(command_interest::POS_TIMESTAMP);
+ const auto& timestampComp = name.at(command_interest::POS_TIMESTAMP);
if (!timestampComp.isNumber()) {
state->fail({ValidationError::POLICY_ERROR, "Command interest `" +
- interest.getName().toUri() + "` doesn't include timestamp component"});
+ interest.getName().toUri() + "` does not include timestamp component"});
return std::make_tuple(false, Name(), time::system_clock::TimePoint{});
}
timestamp = time::fromUnixTimestamp(time::milliseconds(timestampComp.toNumber()));
diff --git a/ndn-cxx/security/validation-policy-config.cpp b/ndn-cxx/security/validation-policy-config.cpp
index 4cf0f44..18ed830 100644
--- a/ndn-cxx/security/validation-policy-config.cpp
+++ b/ndn-cxx/security/validation-policy-config.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -294,11 +294,10 @@
SignatureInfo si;
try {
- si.wireDecode(interest.getName().at(signed_interest::POS_SIG_INFO).blockFromValue());
+ si.wireDecode(interest.getName()[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())});
+ state->fail({ValidationError::INVALID_KEY_LOCATOR, "Invalid signed Interest: "s + e.what()});
return;
}
diff --git a/ndn-cxx/security/validation-policy-simple-hierarchy.cpp b/ndn-cxx/security/validation-policy-simple-hierarchy.cpp
index 95b24f9..40f554f 100644
--- a/ndn-cxx/security/validation-policy-simple-hierarchy.cpp
+++ b/ndn-cxx/security/validation-policy-simple-hierarchy.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -41,12 +41,12 @@
}
}
catch (const KeyLocator::Error& e) {
- state->fail({ValidationError::Code::INVALID_KEY_LOCATOR, e.what()});
+ state->fail({ValidationError::INVALID_KEY_LOCATOR, e.what()});
return;
}
- state->fail({ValidationError::Code::INVALID_KEY_LOCATOR, "Data signing policy violation for " +
- data.getName().toUri() + " by " + klName.toUri()});
+ state->fail({ValidationError::INVALID_KEY_LOCATOR, "Data signing policy violation for " +
+ data.getName().toUri() + " by " + klName.toUri()});
}
void
@@ -65,12 +65,12 @@
}
}
catch (const KeyLocator::Error& e) {
- state->fail({ValidationError::Code::INVALID_KEY_LOCATOR, e.what()});
+ state->fail({ValidationError::INVALID_KEY_LOCATOR, e.what()});
return;
}
- state->fail({ValidationError::Code::INVALID_KEY_LOCATOR, "Interest signing policy violation for " +
- interest.getName().toUri() + " by " + klName.toUri()});
+ state->fail({ValidationError::INVALID_KEY_LOCATOR, "Interest signing policy violation for " +
+ interest.getName().toUri() + " by " + klName.toUri()});
}
} // inline namespace v2
diff --git a/ndn-cxx/security/validation-policy.cpp b/ndn-cxx/security/validation-policy.cpp
index 969d403..8b8fabc 100644
--- a/ndn-cxx/security/validation-policy.cpp
+++ b/ndn-cxx/security/validation-policy.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -68,14 +68,14 @@
}
if (!si.hasKeyLocator()) {
- state.fail({ValidationError::Code::INVALID_KEY_LOCATOR, "KeyLocator is missing"});
- return Name();
+ state.fail({ValidationError::INVALID_KEY_LOCATOR, "KeyLocator is missing"});
+ return {};
}
const KeyLocator& kl = si.getKeyLocator();
if (kl.getType() != tlv::Name) {
- state.fail({ValidationError::Code::INVALID_KEY_LOCATOR, "KeyLocator type is not Name"});
- return Name();
+ state.fail({ValidationError::INVALID_KEY_LOCATOR, "KeyLocator type is not Name"});
+ return {};
}
return kl.getName();
@@ -102,17 +102,16 @@
const Name& name = interest.getName();
if (name.size() < signed_interest::MIN_SIZE) {
state.fail({ValidationError::INVALID_KEY_LOCATOR, "Invalid signed Interest: name too short"});
- return Name();
+ return {};
}
SignatureInfo si;
try {
- si.wireDecode(name.at(signed_interest::POS_SIG_INFO).blockFromValue());
+ si.wireDecode(name[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 Name();
+ state.fail({ValidationError::INVALID_KEY_LOCATOR, "Invalid signed Interest: "s + e.what()});
+ return {};
}
return getKeyLocatorName(si, state);
diff --git a/ndn-cxx/security/validation-state.cpp b/ndn-cxx/security/validation-state.cpp
index 4bb1ab9..b926fd7 100644
--- a/ndn-cxx/security/validation-state.cpp
+++ b/ndn-cxx/security/validation-state.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -33,23 +33,12 @@
#define NDN_LOG_DEBUG_DEPTH(x) NDN_LOG_DEBUG(std::string(this->getDepth() + 1, '>') << " " << x)
#define NDN_LOG_TRACE_DEPTH(x) NDN_LOG_TRACE(std::string(this->getDepth() + 1, '>') << " " << x)
-ValidationState::ValidationState()
- : m_outcome(boost::logic::indeterminate)
-{
-}
-
ValidationState::~ValidationState()
{
NDN_LOG_TRACE(__func__);
BOOST_ASSERT(!boost::logic::indeterminate(m_outcome));
}
-size_t
-ValidationState::getDepth() const
-{
- return m_certificateChain.size();
-}
-
bool
ValidationState::hasSeenCertificateName(const Name& certName)
{
@@ -70,7 +59,7 @@
const auto& certToValidate = *it;
if (!verifySignature(certToValidate, *validatedCert)) {
- this->fail({ValidationError::Code::INVALID_SIGNATURE, "Invalid signature of certificate `" +
+ this->fail({ValidationError::INVALID_SIGNATURE, "Invalid signature of certificate `" +
certToValidate.getName().toUri() + "`"});
m_certificateChain.erase(it, m_certificateChain.end());
return nullptr;
@@ -99,7 +88,7 @@
DataValidationState::~DataValidationState()
{
if (boost::logic::indeterminate(m_outcome)) {
- this->fail({ValidationError::Code::IMPLEMENTATION_ERROR,
+ this->fail({ValidationError::IMPLEMENTATION_ERROR,
"Validator/policy did not invoke success or failure callback"});
}
}
@@ -114,7 +103,7 @@
m_outcome = true;
}
else {
- this->fail({ValidationError::Code::INVALID_SIGNATURE, "Invalid signature of data `" +
+ this->fail({ValidationError::INVALID_SIGNATURE, "Invalid signature of data `" +
m_data.getName().toUri() + "`"});
}
}
@@ -137,12 +126,6 @@
m_outcome = false;
}
-const Data&
-DataValidationState::getOriginalData() const
-{
- return m_data;
-}
-
/////// InterestValidationState
InterestValidationState::InterestValidationState(const Interest& interest,
@@ -159,7 +142,7 @@
InterestValidationState::~InterestValidationState()
{
if (boost::logic::indeterminate(m_outcome)) {
- this->fail({ValidationError::Code::IMPLEMENTATION_ERROR,
+ this->fail({ValidationError::IMPLEMENTATION_ERROR,
"Validator/policy did not invoke success or failure callback"});
}
}
@@ -174,7 +157,7 @@
m_outcome = true;
}
else {
- this->fail({ValidationError::Code::INVALID_SIGNATURE, "Invalid signature of interest `" +
+ this->fail({ValidationError::INVALID_SIGNATURE, "Invalid signature of interest `" +
m_interest.getName().toUri() + "`"});
}
}
@@ -197,12 +180,6 @@
m_outcome = false;
}
-const Interest&
-InterestValidationState::getOriginalInterest() const
-{
- return m_interest;
-}
-
} // inline namespace v2
} // namespace security
} // namespace ndn
diff --git a/ndn-cxx/security/validation-state.hpp b/ndn-cxx/security/validation-state.hpp
index 83d7f94..aed0264 100644
--- a/ndn-cxx/security/validation-state.hpp
+++ b/ndn-cxx/security/validation-state.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -59,16 +59,11 @@
class ValidationState : public TagHost, noncopyable
{
public:
- /**
- * @brief Create validation state
- */
- ValidationState();
-
virtual
~ValidationState();
boost::logic::tribool
- getOutcome() const
+ getOutcome() const noexcept
{
return m_outcome;
}
@@ -83,7 +78,10 @@
* @return Depth of certificate chain
*/
size_t
- getDepth() const;
+ getDepth() const noexcept
+ {
+ return m_certificateChain.size();
+ }
/**
* @brief Check if @p certName has been previously seen and record the supplied name
@@ -139,7 +137,7 @@
verifyCertificateChain(const Certificate& trustedCert);
protected:
- boost::logic::tribool m_outcome;
+ boost::logic::tribool m_outcome{boost::logic::indeterminate};
private:
std::unordered_set<Name> m_seenCertificateNames;
@@ -186,7 +184,10 @@
* @return Original data being validated
*/
const Data&
- getOriginalData() const;
+ getOriginalData() const
+ {
+ return m_data;
+ }
private:
void
@@ -232,7 +233,10 @@
* @return Original interest being validated
*/
const Interest&
- getOriginalInterest() const;
+ getOriginalInterest() const
+ {
+ return m_interest;
+ }
public:
util::Signal<InterestValidationState, Interest> afterSuccess;
diff --git a/ndn-cxx/security/validator.cpp b/ndn-cxx/security/validator.cpp
index 2a86be4..ba00728 100644
--- a/ndn-cxx/security/validator.cpp
+++ b/ndn-cxx/security/validator.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -20,11 +20,10 @@
*/
#include "ndn-cxx/security/validator.hpp"
-
-#include "ndn-cxx/face.hpp"
-#include "ndn-cxx/security/transform/public-key.hpp"
#include "ndn-cxx/util/logger.hpp"
+#include <boost/lexical_cast.hpp>
+
namespace ndn {
namespace security {
inline namespace v2 {
@@ -37,7 +36,6 @@
Validator::Validator(unique_ptr<ValidationPolicy> policy, unique_ptr<CertificateFetcher> certFetcher)
: m_policy(std::move(policy))
, m_certFetcher(std::move(certFetcher))
- , m_maxDepth(25)
{
BOOST_ASSERT(m_policy != nullptr);
BOOST_ASSERT(m_certFetcher != nullptr);
@@ -45,31 +43,7 @@
m_certFetcher->setCertificateStorage(*this);
}
-Validator::~Validator() = default;
-
-ValidationPolicy&
-Validator::getPolicy()
-{
- return *m_policy;
-}
-
-CertificateFetcher&
-Validator::getFetcher()
-{
- return *m_certFetcher;
-}
-
-void
-Validator::setMaxDepth(size_t depth)
-{
- m_maxDepth = depth;
-}
-
-size_t
-Validator::getMaxDepth() const
-{
- return m_maxDepth;
-}
+Validator::~Validator() noexcept = default;
void
Validator::validate(const Data& data,
@@ -77,10 +51,11 @@
const DataValidationFailureCallback& failureCb)
{
auto state = make_shared<DataValidationState>(data, successCb, failureCb);
+
NDN_LOG_DEBUG_DEPTH("Start validating data " << data.getName());
m_policy->checkPolicy(data, state,
- [this] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
+ [this] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
if (certRequest == nullptr) {
state->bypassValidation();
}
@@ -97,14 +72,13 @@
const InterestValidationFailureCallback& failureCb)
{
auto state = make_shared<InterestValidationState>(interest, successCb, failureCb);
-
auto fmt = interest.getSignatureInfo() ? SignedInterestFormat::V03 : SignedInterestFormat::V02;
state->setTag(make_shared<SignedInterestFormatTag>(fmt));
NDN_LOG_DEBUG_DEPTH("Start validating interest (" << fmt << ") " << interest.getName());
m_policy->checkPolicy(interest, state,
- [this] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
+ [this] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
if (certRequest == nullptr) {
state->bypassValidation();
}
@@ -121,12 +95,12 @@
NDN_LOG_DEBUG_DEPTH("Start validating certificate " << cert.getName());
if (!cert.isValid()) {
- return state->fail({ValidationError::Code::EXPIRED_CERT, "Retrieved certificate is not yet valid or expired "
- "`" + cert.getName().toUri() + "`"});
+ return state->fail({ValidationError::EXPIRED_CERT, "`" + cert.getName().toUri() + "` is valid "
+ "between " + boost::lexical_cast<std::string>(cert.getValidityPeriod())});
}
m_policy->checkPolicy(cert, state,
- [this, cert] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
+ [this, cert] (const shared_ptr<CertificateRequest>& certRequest, const shared_ptr<ValidationState>& state) {
if (certRequest == nullptr) {
state->fail({ValidationError::POLICY_ERROR, "Validation policy is not allowed to designate `" +
cert.getName().toUri() + "` as a trust anchor"});
@@ -143,10 +117,8 @@
Validator::requestCertificate(const shared_ptr<CertificateRequest>& certRequest,
const shared_ptr<ValidationState>& state)
{
- // TODO configurable check for the maximum number of steps
if (state->getDepth() >= m_maxDepth) {
- state->fail({ValidationError::Code::EXCEEDED_DEPTH_LIMIT,
- "Exceeded validation depth limit (" + to_string(m_maxDepth) + ")"});
+ state->fail({ValidationError::EXCEEDED_DEPTH_LIMIT, to_string(m_maxDepth)});
return;
}
@@ -156,8 +128,7 @@
}
if (state->hasSeenCertificateName(certRequest->interest.getName())) {
- state->fail({ValidationError::Code::LOOP_DETECTED,
- "Validation loop detected for certificate `" + certRequest->interest.getName().toUri() + "`"});
+ state->fail({ValidationError::LOOP_DETECTED, "`" + certRequest->interest.getName().toUri() + "`"});
return;
}
@@ -179,9 +150,9 @@
return;
}
- m_certFetcher->fetch(certRequest, state, [this] (const Certificate& cert, const shared_ptr<ValidationState>& state) {
- validate(cert, state);
- });
+ m_certFetcher->fetch(certRequest, state, [this] (auto&&... args) {
+ validate(std::forward<decltype(args)>(args)...);
+ });
}
////////////////////////////////////////////////////////////////////////
diff --git a/ndn-cxx/security/validator.hpp b/ndn-cxx/security/validator.hpp
index 46712c7..1e453ec 100644
--- a/ndn-cxx/security/validator.hpp
+++ b/ndn-cxx/security/validator.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2021 Regents of the University of California.
+ * Copyright (c) 2013-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -64,30 +64,42 @@
/**
* @brief Validator constructor.
*
- * @param policy Validation policy to be associated with the validator
+ * @param policy Validation policy to be associated with the validator.
* @param certFetcher Certificate fetcher implementation.
*/
Validator(unique_ptr<ValidationPolicy> policy, unique_ptr<CertificateFetcher> certFetcher);
- ~Validator();
+ ~Validator() noexcept;
ValidationPolicy&
- getPolicy();
+ getPolicy() const noexcept
+ {
+ return *m_policy;
+ }
CertificateFetcher&
- getFetcher();
+ getFetcher() const noexcept
+ {
+ return *m_certFetcher;
+ }
/**
- * @brief Set the maximum depth of the certificate chain
- */
- void
- setMaxDepth(size_t depth);
-
- /**
- * @return The maximum depth of the certificate chain
+ * @brief Return the maximum depth of the certificate chain.
*/
size_t
- getMaxDepth() const;
+ getMaxDepth() const noexcept
+ {
+ return m_maxDepth;
+ }
+
+ /**
+ * @brief Set the maximum depth of the certificate chain.
+ */
+ void
+ setMaxDepth(size_t depth) noexcept
+ {
+ m_maxDepth = depth;
+ }
/**
* @brief Asynchronously validate @p data
@@ -179,7 +191,7 @@
private:
unique_ptr<ValidationPolicy> m_policy;
unique_ptr<CertificateFetcher> m_certFetcher;
- size_t m_maxDepth;
+ size_t m_maxDepth{25};
};
} // inline namespace v2
diff --git a/tests/unit/security/certificate-fetcher-direct-fetch.t.cpp b/tests/unit/security/certificate-fetcher-direct-fetch.t.cpp
index bc134a1..183a947 100644
--- a/tests/unit/security/certificate-fetcher-direct-fetch.t.cpp
+++ b/tests/unit/security/certificate-fetcher-direct-fetch.t.cpp
@@ -216,7 +216,7 @@
VALIDATE_FAILURE(this->data, "Should fail, as no interests are expected");
BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 0);
- BOOST_CHECK(this->lastError.getCode() != ValidationError::Code::IMPLEMENTATION_ERROR);
+ BOOST_CHECK_NE(this->lastError.getCode(), ValidationError::IMPLEMENTATION_ERROR);
}
BOOST_FIXTURE_TEST_CASE(ValidateSuccessInterest, CertificateFetcherDirectFetchFixture<Cert>)
diff --git a/tests/unit/security/validation-error.t.cpp b/tests/unit/security/validation-error.t.cpp
index 6ecb94f..6c1b5f7 100644
--- a/tests/unit/security/validation-error.t.cpp
+++ b/tests/unit/security/validation-error.t.cpp
@@ -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-2022 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -34,12 +34,12 @@
BOOST_AUTO_TEST_CASE(Basic)
{
- ValidationError e1{ValidationError::Code::INVALID_SIGNATURE};
+ ValidationError e1{ValidationError::INVALID_SIGNATURE};
BOOST_CHECK_EQUAL(e1.getCode(), 1);
BOOST_CHECK_EQUAL(e1.getInfo(), "");
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(e1), "Invalid signature");
- ValidationError e2{ValidationError::Code::NO_SIGNATURE, "message"};
+ ValidationError e2{ValidationError::NO_SIGNATURE, "message"};
BOOST_CHECK_EQUAL(e2.getCode(), 2);
BOOST_CHECK_EQUAL(e2.getInfo(), "message");
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(e2), "Missing signature (message)");
diff --git a/tests/unit/security/validator-fixture.hpp b/tests/unit/security/validator-fixture.hpp
index 25cbe93..b225c53 100644
--- a/tests/unit/security/validator-fixture.hpp
+++ b/tests/unit/security/validator-fixture.hpp
@@ -68,7 +68,7 @@
util::DummyClientFace face{m_io, {true, true}};
std::function<void(const Interest&)> processInterest;
CertificateCache cache{100_days};
- ValidationError lastError{ValidationError::Code::NO_ERROR};
+ ValidationError lastError{ValidationError::NO_ERROR};
private:
const static time::milliseconds s_mockPeriod;