security: rename NO_SIGNATURE error code to MALFORMED_SIGNATURE
And move the documentation for all validation error codes to doxygen
Change-Id: Ibf4b507e3a544f2978192fbfad20cd7dc486818f
diff --git a/docs/index.rst b/docs/index.rst
index 5d7364c..b1f9012 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -51,7 +51,6 @@
+ :doc:`specs/certificate`
+ :doc:`specs/safe-bag`
- + :doc:`specs/validation-error-code`
+ :doc:`specs/signed-interest`
- :doc:`manpages`
diff --git a/docs/specs.rst b/docs/specs.rst
index 2d4a5ab..e5b1eff 100644
--- a/docs/specs.rst
+++ b/docs/specs.rst
@@ -6,5 +6,4 @@
specs/certificate
specs/safe-bag
- specs/validation-error-code
specs/signed-interest
diff --git a/docs/specs/validation-error-code.rst b/docs/specs/validation-error-code.rst
deleted file mode 100644
index dc2c18c..0000000
--- a/docs/specs/validation-error-code.rst
+++ /dev/null
@@ -1,33 +0,0 @@
-Validation Error Code
-=====================
-
-The following table defines a list of known codes and their description, which can be returned from the :ndn-cxx:`Validator` interface.
-Other error codes can be returned by validator implementations outside ndn-cxx codebase.
-
-+------------+--------------------------+-----------------------------------------------------+
-| Error code | Short ID | Description |
-+============+==========================+=====================================================+
-| 0 | NO_ERROR | No error |
-+------------+--------------------------+-----------------------------------------------------+
-| 1 | INVALID_SIGNATURE | Invalid signature |
-+------------+--------------------------+-----------------------------------------------------+
-| 2 | NO_SIGNATURE | Missing signature |
-+------------+--------------------------+-----------------------------------------------------+
-| 3 | CANNOT_RETRIEVE_CERT | Cannot retrieve certificate |
-+------------+--------------------------+-----------------------------------------------------+
-| 4 | EXPIRED_CERT | Certificate expired |
-+------------+--------------------------+-----------------------------------------------------+
-| 5 | LOOP_DETECTED | Loop detected in certification chain |
-+------------+--------------------------+-----------------------------------------------------+
-| 6 | MALFORMED_CERT | Malformed certificate |
-+------------+--------------------------+-----------------------------------------------------+
-| 7 | EXCEEDED_DEPTH_LIMIT | Exceeded validation depth limit |
-+------------+--------------------------+-----------------------------------------------------+
-| 8 | INVALID_KEY_LOCATOR | Key locator violates validation policy |
-+------------+--------------------------+-----------------------------------------------------+
-| .. | ... | ... |
-+------------+--------------------------+-----------------------------------------------------+
-| 255 | IMPLEMENTATION_ERROR | Internal implementation error |
-+------------+--------------------------+-----------------------------------------------------+
-
-Specialized validator implementations can use error codes >= 256 to indicate a specialized error.
diff --git a/ndn-cxx/security/validation-error.cpp b/ndn-cxx/security/validation-error.cpp
index b32ce5a..7ab3abe 100644
--- a/ndn-cxx/security/validation-error.cpp
+++ b/ndn-cxx/security/validation-error.cpp
@@ -32,9 +32,9 @@
case ValidationError::NO_ERROR:
return os << "No error";
case ValidationError::INVALID_SIGNATURE:
- return os << "Invalid signature";
- case ValidationError::NO_SIGNATURE:
- return os << "Missing signature";
+ return os << "Signature verification failed";
+ case ValidationError::MALFORMED_SIGNATURE:
+ return os << "Missing or malformed signature";
case ValidationError::CANNOT_RETRIEVE_CERT:
return os << "Cannot retrieve certificate";
case ValidationError::EXPIRED_CERT:
@@ -46,9 +46,9 @@
case ValidationError::EXCEEDED_DEPTH_LIMIT:
return os << "Exceeded validation depth limit";
case ValidationError::INVALID_KEY_LOCATOR:
- return os << "Key locator violates validation policy";
+ return os << "Invalid key locator";
case ValidationError::POLICY_ERROR:
- return os << "Validation policy error";
+ return os << "Policy violation";
case ValidationError::IMPLEMENTATION_ERROR:
return os << "Internal error";
case ValidationError::USER_MIN:
@@ -58,14 +58,14 @@
return os << "Custom error code " << to_underlying(code);
}
else {
- return os << "Unrecognized error code " << to_underlying(code);
+ return os << "Unknown error code " << to_underlying(code);
}
}
void
ValidationError::print(std::ostream& os) const
{
- os << static_cast<ValidationError::Code>(m_code);
+ os << m_code;
if (!m_info.empty()) {
os << " (" << m_info << ")";
}
diff --git a/ndn-cxx/security/validation-error.hpp b/ndn-cxx/security/validation-error.hpp
index bc68b4e..07a1aaa 100644
--- a/ndn-cxx/security/validation-error.hpp
+++ b/ndn-cxx/security/validation-error.hpp
@@ -35,34 +35,49 @@
{
public:
/**
- * @brief Known validation error codes
- * @sa <a href="../specs/validation-error-code.html">Validation Error Codes</a>
+ * @brief Known error codes that can be returned by the Validator interface.
+ *
+ * Additional error codes can be defined by validation policies implemented outside ndn-cxx.
*/
enum Code : uint32_t {
+ /// No error
NO_ERROR = 0,
+ /// Signature verification failed
INVALID_SIGNATURE = 1,
- NO_SIGNATURE = 2,
+ /// The signature (e.g., SignatureInfo element) is missing or malformed
+ MALFORMED_SIGNATURE = 2,
+ /// The certificate cannot be retrieved
CANNOT_RETRIEVE_CERT = 3,
+ /// The certificate expired or is not yet valid
EXPIRED_CERT = 4,
+ /// Loop detected in the certification chain
LOOP_DETECTED = 5,
+ /// The certificate is malformed
MALFORMED_CERT = 6,
+ /// Exceeded validation depth limit
EXCEEDED_DEPTH_LIMIT = 7,
+ /// The KeyLocator element is missing or has an invalid format
INVALID_KEY_LOCATOR = 8,
+ /// The packet violates the validation rules enforced by the policy
POLICY_ERROR = 9,
+ /// Internal implementation error
IMPLEMENTATION_ERROR = 255,
- USER_MIN = 256, // custom error codes should use >=256
+ /// Third-party validator implementations can use error codes greater than or equal
+ /// to this value to indicate a custom or specialized error condition
+ USER_MIN = 256,
};
/**
- * @brief Validation error, implicitly convertible from an error code and info string
+ * @brief ValidationError is implicitly constructible from an integer error code and
+ * an optional info string.
*/
ValidationError(uint32_t code, const std::string& info = "")
- : m_code(code)
+ : m_code(static_cast<Code>(code))
, m_info(info)
{
}
- uint32_t
+ Code
getCode() const
{
return m_code;
@@ -87,7 +102,7 @@
}
private:
- uint32_t m_code;
+ Code m_code;
std::string m_info;
};
diff --git a/ndn-cxx/security/validation-policy.cpp b/ndn-cxx/security/validation-policy.cpp
index 5dc199b..97a839b 100644
--- a/ndn-cxx/security/validation-policy.cpp
+++ b/ndn-cxx/security/validation-policy.cpp
@@ -95,7 +95,8 @@
// Try the old Signed Interest format from Packet Specification v0.2
const Name& name = interest.getName();
if (name.size() < signed_interest::MIN_SIZE) {
- state.fail({ValidationError::NO_SIGNATURE, "Interest name too short `" + name.toUri() + "`"});
+ state.fail({ValidationError::MALFORMED_SIGNATURE,
+ "Interest name too short `" + name.toUri() + "`"});
return {};
}
@@ -103,7 +104,7 @@
return SignatureInfo(name[signed_interest::POS_SIG_INFO].blockFromValue());
}
catch (const tlv::Error& e) {
- state.fail({ValidationError::NO_SIGNATURE,
+ state.fail({ValidationError::MALFORMED_SIGNATURE,
"Malformed SignatureInfo in `" + name.toUri() + "`: " + e.what()});
return {};
}
diff --git a/ndn-cxx/security/validation-policy.hpp b/ndn-cxx/security/validation-policy.hpp
index 31ef78e..f49670a 100644
--- a/ndn-cxx/security/validation-policy.hpp
+++ b/ndn-cxx/security/validation-policy.hpp
@@ -154,7 +154,7 @@
* SignedInterestFormatTag inside @p state, must have an InterestSignatureInfo element.
* Legacy signed Interests must contain a (%Data)%SignatureInfo name component.
* In both cases, if any TLV parsing errors are encountered, ValidationState::fail()
- * is invoked on @p state with a ValidationError::NO_SIGNATURE error code.
+ * is invoked on @p state with a ValidationError::MALFORMED_SIGNATURE error code.
*
* @pre @p state must contain a SignedInterestFormatTag to indicate whether the %Interest is
* signed according to Packet Specification v0.3+ or a previous specification.
diff --git a/ndn-cxx/security/validator.cpp b/ndn-cxx/security/validator.cpp
index 984508b..99d1a6f 100644
--- a/ndn-cxx/security/validator.cpp
+++ b/ndn-cxx/security/validator.cpp
@@ -71,7 +71,7 @@
state->setTag(make_shared<SignedInterestFormatTag>(fmt));
}
catch (const tlv::Error& e) {
- return state->fail({ValidationError::NO_SIGNATURE, "Malformed InterestSignatureInfo in `" +
+ return state->fail({ValidationError::MALFORMED_SIGNATURE, "Malformed InterestSignatureInfo in `" +
interest.getName().toUri() + "`: " + e.what()});
}
diff --git a/tests/unit/security/validation-error.t.cpp b/tests/unit/security/validation-error.t.cpp
index 6c1b5f7..c4a1a08 100644
--- a/tests/unit/security/validation-error.t.cpp
+++ b/tests/unit/security/validation-error.t.cpp
@@ -22,6 +22,7 @@
#include "ndn-cxx/security/validation-error.hpp"
#include "tests/boost-test.hpp"
+
#include <boost/lexical_cast.hpp>
namespace ndn {
@@ -37,17 +38,22 @@
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");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(e1), "Signature verification failed");
- ValidationError e2{ValidationError::NO_SIGNATURE, "message"};
+ ValidationError e2{ValidationError::MALFORMED_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)");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(e2), "Missing or malformed signature (message)");
ValidationError e3{65535, "other message"};
BOOST_CHECK_EQUAL(e3.getCode(), 65535);
BOOST_CHECK_EQUAL(e3.getInfo(), "other message");
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(e3), "Custom error code 65535 (other message)");
+
+ ValidationError e4{200};
+ BOOST_CHECK_EQUAL(e4.getCode(), 200);
+ BOOST_CHECK_EQUAL(e4.getInfo(), "");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(e4), "Unknown error code 200");
}
BOOST_AUTO_TEST_SUITE_END() // TestValidationError
diff --git a/tests/unit/security/validation-policy-command-interest.t.cpp b/tests/unit/security/validation-policy-command-interest.t.cpp
index d6fd74f..604c60d 100644
--- a/tests/unit/security/validation-policy-command-interest.t.cpp
+++ b/tests/unit/security/validation-policy-command-interest.t.cpp
@@ -165,7 +165,7 @@
auto i1 = Interest("/short");
BOOST_TEST_REQUIRE(i1.getName().size() < signed_interest::MIN_SIZE);
VALIDATE_FAILURE(i1, "Should fail (not signed / name too short)");
- BOOST_TEST(lastError.getCode() == ValidationError::NO_SIGNATURE);
+ BOOST_TEST(lastError.getCode() == ValidationError::MALFORMED_SIGNATURE);
}
BOOST_AUTO_TEST_CASE(BadSigInfo)
@@ -174,7 +174,7 @@
setNameComponent(i1, command_interest::POS_SIG_INFO, "not-SignatureInfo");
BOOST_TEST_REQUIRE(i1.getName().size() >= command_interest::MIN_SIZE);
VALIDATE_FAILURE(i1, "Should fail (signature info is missing)");
- BOOST_TEST(lastError.getCode() == ValidationError::NO_SIGNATURE);
+ BOOST_TEST(lastError.getCode() == ValidationError::MALFORMED_SIGNATURE);
}
BOOST_AUTO_TEST_CASE(BadTimestampV02)
diff --git a/tests/unit/security/validation-policy-simple-hierarchy.t.cpp b/tests/unit/security/validation-policy-simple-hierarchy.t.cpp
index 38ab30c..788a7c9 100644
--- a/tests/unit/security/validation-policy-simple-hierarchy.t.cpp
+++ b/tests/unit/security/validation-policy-simple-hierarchy.t.cpp
@@ -43,7 +43,7 @@
auto packet = Packet::makePacket(name);
VALIDATE_FAILURE(packet, "Unsigned");
- BOOST_TEST((lastError.getCode() == ValidationError::NO_SIGNATURE || // Interest
+ BOOST_TEST((lastError.getCode() == ValidationError::MALFORMED_SIGNATURE || // Interest
lastError.getCode() == ValidationError::INVALID_KEY_LOCATOR)); // Data
packet = Packet::makePacket(name);
diff --git a/tests/unit/security/validator.t.cpp b/tests/unit/security/validator.t.cpp
index 842f2f5..d1b746b 100644
--- a/tests/unit/security/validator.t.cpp
+++ b/tests/unit/security/validator.t.cpp
@@ -64,7 +64,7 @@
BOOST_REQUIRE_NO_THROW(interest.getSignatureValue());
VALIDATE_FAILURE(interest, "InterestSignatureInfo decoding should fail");
- BOOST_TEST(lastError.getCode() == ValidationError::NO_SIGNATURE);
+ BOOST_TEST(lastError.getCode() == ValidationError::MALFORMED_SIGNATURE);
BOOST_TEST(face.sentInterests.size() == 0);
}
@@ -259,7 +259,7 @@
Data data("/Security/ValidatorFixture/Sub1/Sub2/Data");
VALIDATE_FAILURE(interest, "Unsigned");
- BOOST_TEST(lastError.getCode() == ValidationError::NO_SIGNATURE);
+ BOOST_TEST(lastError.getCode() == ValidationError::MALFORMED_SIGNATURE);
VALIDATE_SUCCESS(data, "Policy bypasses validation for all data");
BOOST_TEST(face.sentInterests.size() == 0);
face.sentInterests.clear();