signature-info: add signed Interest elements
refs #4804
Change-Id: Ice910b7740212cf116ddac24e12634877f75c71e
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index fe34062..306a09e 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.cpp
@@ -65,7 +65,7 @@
}
// SignatureInfo
- totalLength += m_signatureInfo.wireEncode(encoder);
+ totalLength += m_signatureInfo.wireEncode(encoder, SignatureInfo::Type::Data);
// Content
totalLength += encoder.prependBlock(getContent());
diff --git a/ndn-cxx/encoding/tlv.hpp b/ndn-cxx/encoding/tlv.hpp
index f27c1cb..b435d14 100644
--- a/ndn-cxx/encoding/tlv.hpp
+++ b/ndn-cxx/encoding/tlv.hpp
@@ -74,6 +74,8 @@
InterestLifetime = 12,
HopLimit = 34,
ApplicationParameters = 36,
+ InterestSignatureInfo = 44,
+ InterestSignatureValue = 46,
MetaInfo = 20,
Content = 21,
SignatureInfo = 22,
@@ -84,6 +86,9 @@
SignatureType = 27,
KeyLocator = 28,
KeyDigest = 29,
+ SignatureNonce = 38,
+ SignatureTime = 40,
+ SignatureSeqNum = 42,
LinkDelegation = 31,
LinkPreference = 30,
@@ -135,7 +140,7 @@
std::ostream&
operator<<(std::ostream& os, SignatureTypeValue st);
-/** @brief TLV-TYPE numbers for SignatureInfo features
+/** @brief TLV-TYPE numbers for SignatureInfo extensions
* @sa docs/specs/certificate-format.rst
*/
enum {
diff --git a/ndn-cxx/security/v2/certificate.cpp b/ndn-cxx/security/v2/certificate.cpp
index f5ef157..ae3ae30 100644
--- a/ndn-cxx/security/v2/certificate.cpp
+++ b/ndn-cxx/security/v2/certificate.cpp
@@ -121,10 +121,14 @@
return getSignatureInfo().getValidityPeriod().isValid(ts);
}
-const Block&
+Block
Certificate::getExtension(uint32_t type) const
{
- return getSignatureInfo().getTypeSpecificTlv(type);
+ auto block = getSignatureInfo().getCustomTlv(type);
+ if (!block) {
+ NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
+ }
+ return *block;
}
bool
@@ -146,16 +150,13 @@
os << " NotAfter: " << time::toIsoString(cert.getValidityPeriod().getPeriod().second) << "\n";
}
- try {
- const Block& info = cert.getSignatureInfo().getTypeSpecificTlv(tlv::AdditionalDescription);
+ auto additionalDescription = cert.getSignatureInfo().getCustomTlv(tlv::AdditionalDescription);
+ if (additionalDescription) {
os << "Additional Description:\n";
- for (const auto& item : v2::AdditionalDescription(info)) {
+ for (const auto& item : v2::AdditionalDescription(*additionalDescription)) {
os << " " << item.first << ": " << item.second << "\n";
}
}
- catch (const SignatureInfo::Error&) {
- // ignore
- }
os << "Public key bits:\n";
{
diff --git a/ndn-cxx/security/v2/certificate.hpp b/ndn-cxx/security/v2/certificate.hpp
index 12621ea..8d939b2 100644
--- a/ndn-cxx/security/v2/certificate.hpp
+++ b/ndn-cxx/security/v2/certificate.hpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -149,9 +149,9 @@
/**
* @brief Get extension with TLV @p type
- * @throw ndn::SignatureInfo::Error if the specified block type does not exist
+ * @throw Error The specified block type does not exist
*/
- const Block&
+ Block
getExtension(uint32_t type) const;
// @TODO Implement extension enumeration (Issue #3907)
diff --git a/ndn-cxx/signature-info.cpp b/ndn-cxx/signature-info.cpp
index 9c96cda..59c93bc 100644
--- a/ndn-cxx/signature-info.cpp
+++ b/ndn-cxx/signature-info.cpp
@@ -22,6 +22,9 @@
#include "ndn-cxx/signature-info.hpp"
#include "ndn-cxx/encoding/block-helpers.hpp"
#include "ndn-cxx/util/concepts.hpp"
+#include "ndn-cxx/util/string-helper.hpp"
+
+#include <boost/range/adaptor/reversed.hpp>
namespace ndn {
@@ -40,14 +43,14 @@
{
}
-SignatureInfo::SignatureInfo(const Block& block)
+SignatureInfo::SignatureInfo(const Block& block, SignatureInfo::Type type)
{
- wireDecode(block);
+ wireDecode(block, type);
}
template<encoding::Tag TAG>
size_t
-SignatureInfo::wireEncode(EncodingImpl<TAG>& encoder) const
+SignatureInfo::wireEncode(EncodingImpl<TAG>& encoder, SignatureInfo::Type type) const
{
if (m_type == -1) {
NDN_THROW(Error("Cannot encode invalid SignatureInfo"));
@@ -56,13 +59,23 @@
// SignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
// SignatureType
// [KeyLocator]
- // [ValidityPeriod] ; if present, stored as first item of m_otherTlvs
+ // [ValidityPeriod]
// *OtherSubelements
+ // InterestSignatureInfo = INTEREST-SIGNATURE-INFO-TYPE TLV-LENGTH
+ // SignatureType
+ // [KeyLocator]
+ // [SignatureNonce]
+ // [SignatureTime]
+ // [SignatureSeqNum]
+ // *OtherSubelements
+
size_t totalLength = 0;
- for (auto i = m_otherTlvs.rbegin(); i != m_otherTlvs.rend(); i++) {
- totalLength += encoder.prependBlock(*i);
+ // m_otherTlvs contains (if set) SignatureNonce, SignatureTime, SignatureSeqNum, ValidityPeriod,
+ // and AdditionalDescription, as well as any custom elements added by the user
+ for (const auto& block : m_otherTlvs | boost::adaptors::reversed) {
+ totalLength += encoder.prependBlock(block);
}
if (m_keyLocator) {
@@ -71,32 +84,37 @@
totalLength += prependNonNegativeIntegerBlock(encoder, tlv::SignatureType,
static_cast<uint64_t>(m_type));
+
totalLength += encoder.prependVarNumber(totalLength);
- totalLength += encoder.prependVarNumber(tlv::SignatureInfo);
+ totalLength += encoder.prependVarNumber(to_underlying(type));
return totalLength;
}
-NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(SignatureInfo);
+template size_t
+SignatureInfo::wireEncode<encoding::EncoderTag>(encoding::EncodingBuffer&, SignatureInfo::Type) const;
+
+template size_t
+SignatureInfo::wireEncode<encoding::EstimatorTag>(encoding::EncodingEstimator&, SignatureInfo::Type) const;
const Block&
-SignatureInfo::wireEncode() const
+SignatureInfo::wireEncode(SignatureInfo::Type type) const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
- size_t estimatedSize = wireEncode(estimator);
+ size_t estimatedSize = wireEncode(estimator, type);
EncodingBuffer buffer(estimatedSize, 0);
- wireEncode(buffer);
+ wireEncode(buffer, type);
m_wire = buffer.block();
return m_wire;
}
void
-SignatureInfo::wireDecode(const Block& wire)
+SignatureInfo::wireDecode(const Block& wire, SignatureInfo::Type type)
{
m_type = -1;
m_keyLocator = nullopt;
@@ -105,28 +123,56 @@
m_wire = wire;
m_wire.parse();
- if (m_wire.type() != tlv::SignatureInfo)
+ if (m_wire.type() != to_underlying(type)) {
NDN_THROW(Error("SignatureInfo", m_wire.type()));
-
- auto it = m_wire.elements_begin();
-
- // the first sub-element must be SignatureType
- if (it == m_wire.elements_end() || it->type() != tlv::SignatureType)
- NDN_THROW(Error("Missing SignatureType in SignatureInfo"));
-
- m_type = readNonNegativeIntegerAs<tlv::SignatureTypeValue>(*it);
- ++it;
-
- // the second sub-element could be KeyLocator
- if (it != m_wire.elements_end() && it->type() == tlv::KeyLocator) {
- m_keyLocator.emplace(*it);
- ++it;
}
- // store SignatureType-specific sub-elements, if any
- while (it != m_wire.elements_end()) {
- m_otherTlvs.push_back(*it);
- ++it;
+ size_t lastCriticalElement = 0;
+ for (const auto& element : m_wire.elements()) {
+ switch (element.type()) {
+ case tlv::SignatureType: {
+ if (lastCriticalElement > 0) {
+ NDN_THROW(Error("SignatureType element is repeated or out-of-order"));
+ }
+ m_type = readNonNegativeIntegerAs<tlv::SignatureTypeValue>(element);
+ lastCriticalElement = 1;
+ break;
+ }
+ case tlv::KeyLocator: {
+ if (lastCriticalElement > 1) {
+ NDN_THROW(Error("KeyLocator element is repeated or out-of-order"));
+ }
+ m_keyLocator.emplace(element);
+ lastCriticalElement = 2;
+ break;
+ }
+ case tlv::SignatureNonce: {
+ // Must handle SignatureNonce specifically because we must check that its length is >0
+ if (element.value_size() < 1) {
+ NDN_THROW(Error("SignatureNonce element cannot be empty"));
+ }
+ m_otherTlvs.push_back(element);
+ break;
+ }
+ case tlv::ValidityPeriod:
+ // ValidityPeriod is treated differently than other "extension" TLVs for historical reasons:
+ // It is intended to be non-critical, but its TLV-TYPE is in the critical range. Therefore,
+ // we must handle it specifically.
+ m_otherTlvs.push_back(element);
+ break;
+ default: {
+ // If the TLV-TYPE is unrecognized and critical, abort decoding
+ if (tlv::isCriticalType(element.type())) {
+ NDN_THROW(Error("Unrecognized element of critical type " + to_string(element.type())));
+ }
+ // Otherwise, store in m_otherTlvs
+ m_otherTlvs.push_back(element);
+ }
+ }
+ }
+
+ if (m_type == -1) {
+ NDN_THROW(Error("Missing SignatureType in SignatureInfo"));
}
}
@@ -168,29 +214,21 @@
security::ValidityPeriod
SignatureInfo::getValidityPeriod() const
{
- if (!hasValidityPeriod()) {
+ auto it = findOtherTlv(tlv::ValidityPeriod);
+ if (it == m_otherTlvs.end()) {
NDN_THROW(Error("ValidityPeriod does not exist in SignatureInfo"));
}
- return security::ValidityPeriod(m_otherTlvs.front());
+ return security::ValidityPeriod(*it);
}
SignatureInfo&
SignatureInfo::setValidityPeriod(optional<security::ValidityPeriod> validityPeriod)
{
- if (validityPeriod) {
- auto block = validityPeriod->wireEncode();
- if (!hasValidityPeriod()) {
- m_otherTlvs.push_front(std::move(block));
- m_wire.reset();
- }
- else if (m_otherTlvs.front() != block) {
- m_otherTlvs.front() = std::move(block);
- m_wire.reset();
- }
+ if (!validityPeriod) {
+ removeCustomTlv(tlv::ValidityPeriod);
}
- else if (hasValidityPeriod()) {
- m_otherTlvs.pop_front();
- m_wire.reset();
+ else {
+ addCustomTlv(validityPeriod->wireEncode());
}
return *this;
}
@@ -201,22 +239,133 @@
setValidityPeriod(nullopt);
}
+optional<std::vector<uint8_t>>
+SignatureInfo::getNonce() const
+{
+ auto it = findOtherTlv(tlv::SignatureNonce);
+ if (it == m_otherTlvs.end()) {
+ return nullopt;
+ }
+ return std::vector<uint8_t>(it->value_begin(), it->value_end());
+}
+
+SignatureInfo&
+SignatureInfo::setNonce(optional<std::vector<uint8_t>> nonce)
+{
+ if (!nonce) {
+ removeCustomTlv(tlv::SignatureNonce);
+ }
+ else {
+ addCustomTlv(makeBinaryBlock(tlv::SignatureNonce, nonce->data(), nonce->size()));
+ }
+ return *this;
+}
+
+optional<time::system_clock::time_point>
+SignatureInfo::getTime() const
+{
+ auto it = findOtherTlv(tlv::SignatureTime);
+ if (it == m_otherTlvs.end()) {
+ return nullopt;
+ }
+ return time::fromUnixTimestamp(time::milliseconds(readNonNegativeInteger(*it)));
+}
+
+SignatureInfo&
+SignatureInfo::setTime(optional<time::system_clock::time_point> time)
+{
+ if (!time) {
+ removeCustomTlv(tlv::SignatureTime);
+ }
+ else {
+ addCustomTlv(makeNonNegativeIntegerBlock(tlv::SignatureTime, time::toUnixTimestamp(*time).count()));
+ }
+ return *this;
+}
+
+optional<uint64_t>
+SignatureInfo::getSeqNum() const
+{
+ auto it = findOtherTlv(tlv::SignatureSeqNum);
+ if (it == m_otherTlvs.end()) {
+ return nullopt;
+ }
+ return readNonNegativeInteger(*it);
+}
+
+SignatureInfo&
+SignatureInfo::setSeqNum(optional<uint64_t> seqNum)
+{
+ if (!seqNum) {
+ removeCustomTlv(tlv::SignatureSeqNum);
+ }
+ else {
+ addCustomTlv(makeNonNegativeIntegerBlock(tlv::SignatureSeqNum, *seqNum));
+ }
+ return *this;
+}
+
+optional<Block>
+SignatureInfo::getCustomTlv(uint32_t type) const
+{
+ auto it = findOtherTlv(type);
+ if (it == m_otherTlvs.end()) {
+ return nullopt;
+ }
+ return *it;
+}
+
+void
+SignatureInfo::addCustomTlv(Block block)
+{
+ auto existingIt = std::find_if(m_otherTlvs.begin(), m_otherTlvs.end(), [&block] (const Block& b) {
+ return b.type() == block.type();
+ });
+ if (existingIt == m_otherTlvs.end()) {
+ m_otherTlvs.push_back(std::move(block));
+ m_wire.reset();
+ }
+ else if (*existingIt != block) {
+ *existingIt = std::move(block);
+ m_wire.reset();
+ }
+}
+
+void
+SignatureInfo::removeCustomTlv(uint32_t type)
+{
+ auto it = std::remove_if(m_otherTlvs.begin(), m_otherTlvs.end(), [type] (const Block& block) {
+ return block.type() == type;
+ });
+
+ if (it != m_otherTlvs.end()) {
+ m_otherTlvs.erase(it, m_otherTlvs.end());
+ m_wire.reset();
+ }
+}
+
const Block&
SignatureInfo::getTypeSpecificTlv(uint32_t type) const
{
- for (const Block& block : m_otherTlvs) {
- if (block.type() == type)
- return block;
+ auto it = findOtherTlv(type);
+ if (it == m_otherTlvs.end()) {
+ NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
}
-
- NDN_THROW(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
+ return *it;
}
void
SignatureInfo::appendTypeSpecificTlv(const Block& block)
{
- m_otherTlvs.push_back(block);
- m_wire.reset();
+ addCustomTlv(block);
+}
+
+std::vector<Block>::const_iterator
+SignatureInfo::findOtherTlv(uint32_t type) const
+{
+ return std::find_if(m_otherTlvs.begin(), m_otherTlvs.end(), [type] (const Block& block) {
+ return block.type() == type;
+ });
}
bool
@@ -230,8 +379,9 @@
std::ostream&
operator<<(std::ostream& os, const SignatureInfo& info)
{
- if (info.getSignatureType() == -1)
+ if (info.getSignatureType() == -1) {
return os << "Invalid SignatureInfo";
+ }
os << static_cast<tlv::SignatureTypeValue>(info.getSignatureType());
if (info.hasKeyLocator()) {
@@ -240,7 +390,27 @@
if (!info.m_otherTlvs.empty()) {
os << " { ";
for (const auto& block : info.m_otherTlvs) {
- os << block.type() << " ";
+ switch (block.type()) {
+ case tlv::SignatureNonce: {
+ os << "Nonce=";
+ auto nonce = *info.getNonce();
+ printHex(os, nonce.data(), nonce.size(), false);
+ os << " ";
+ break;
+ }
+ case tlv::SignatureTime:
+ os << "Time=" << time::toUnixTimestamp(*info.getTime()).count() << " ";
+ break;
+ case tlv::SignatureSeqNum:
+ os << "SeqNum=" << *info.getSeqNum() << " ";
+ break;
+ case tlv::ValidityPeriod:
+ os << "ValidityPeriod=" << info.getValidityPeriod() << " ";
+ break;
+ default:
+ os << block.type() << " ";
+ break;
+ }
}
os << "}";
}
diff --git a/ndn-cxx/signature-info.hpp b/ndn-cxx/signature-info.hpp
index 9e7b42e..bcfa2ee 100644
--- a/ndn-cxx/signature-info.hpp
+++ b/ndn-cxx/signature-info.hpp
@@ -25,11 +25,9 @@
#include "ndn-cxx/key-locator.hpp"
#include "ndn-cxx/security/validity-period.hpp"
-#include <list>
-
namespace ndn {
-/** @brief Represents a SignatureInfo TLV element
+/** @brief Represents a SignatureInfo or InterestSignatureInfo TLV element
*/
class SignatureInfo
{
@@ -40,8 +38,12 @@
using tlv::Error::Error;
};
- /** @brief Create an invalid SignatureInfo
- */
+ enum class Type : uint32_t {
+ Data = tlv::SignatureInfo,
+ Interest = tlv::InterestSignatureInfo
+ };
+
+public:
SignatureInfo();
/** @brief Create with the specified type and KeyLocator
@@ -50,10 +52,12 @@
SignatureInfo(tlv::SignatureTypeValue type, optional<KeyLocator> keyLocator = nullopt);
/** @brief Create from wire encoding
- * @throw tlv::Error decode error
+ * @param wire Wire to decode from
+ * @param type Which type of SignatureInfo block decoding should expect
+ * @throw tlv::Error Decode error
*/
explicit
- SignatureInfo(const Block& wire);
+ SignatureInfo(const Block& wire, Type type = Type::Data);
/** @brief Determine whether SignatureInfo is valid
*/
@@ -65,21 +69,33 @@
/** @brief Fast encoding or block size estimation
* @param encoder EncodingEstimator or EncodingBuffer instance
+ * @param type Which type of SignatureInfo block to encode
+ *
+ * Elements are encoded in the following order: SignatureType, KeyLocator (if present), and
+ * other elements in the order they were set (changing the value of an already present element
+ * will not change that element's encoding order).
*/
template<encoding::Tag TAG>
size_t
- wireEncode(EncodingImpl<TAG>& encoder) const;
+ wireEncode(EncodingImpl<TAG>& encoder, Type type = Type::Data) const;
/** @brief Encode to wire format
+ * @param type Which type of SignatureInfo block to encode
+ *
+ * Elements are encoded in the following order: SignatureType, KeyLocator (if present), and
+ * other elements in the order they were set (changing the value of an already present element
+ * will not change that element's encoding order).
*/
const Block&
- wireEncode() const;
+ wireEncode(Type type = Type::Data) const;
/** @brief Decode from wire format
- * @throw tlv::Error decode error
+ * @param wire Wire to decode from
+ * @param type Which type of SignatureInfo block decoding should expect
+ * @throw tlv::Error Decode error
*/
void
- wireDecode(const Block& wire);
+ wireDecode(const Block& wire, Type type = Type::Data);
/** @brief Check if this instance has cached wire encoding.
*/
@@ -91,7 +107,7 @@
public: // field access
/** @brief Get SignatureType
- * @return tlv::SignatureTypeValue, or -1 to indicate invalid SignatureInfo
+ * @return tlv::SignatureTypeValue, or -1 to indicate an invalid SignatureInfo
*/
int32_t
getSignatureType() const noexcept
@@ -100,7 +116,7 @@
}
/** @brief Set SignatureType
- * @return a reference to this SignatureInfo, to allow chaining
+ * @return A reference to this SignatureInfo, to allow chaining
*/
SignatureInfo&
setSignatureType(tlv::SignatureTypeValue type);
@@ -120,7 +136,7 @@
getKeyLocator() const;
/** @brief Set KeyLocator
- * @return a reference to this SignatureInfo, to allow chaining
+ * @return A reference to this SignatureInfo, to allow chaining
*
* Passing `nullopt` will remove the KeyLocator.
*/
@@ -134,22 +150,14 @@
void
unsetKeyLocator();
- /** @brief Check if ValidityPeriod is present
- */
- bool
- hasValidityPeriod() const noexcept
- {
- return !m_otherTlvs.empty() && m_otherTlvs.front().type() == tlv::ValidityPeriod;
- }
-
/** @brief Get ValidityPeriod
* @throw Error This SignatureInfo does not contain a ValidityPeriod
*/
security::ValidityPeriod
getValidityPeriod() const;
- /** @brief Set ValidityPeriod
- * @return a reference to this SignatureInfo, to allow chaining
+ /** @brief Append or replace ValidityPeriod
+ * @return A reference to this SignatureInfo, to allow chaining
*
* Passing `nullopt` will remove the ValidityPeriod.
*/
@@ -163,22 +171,92 @@
void
unsetValidityPeriod();
- /** @brief Get SignatureType-specific sub-element
- * @param type TLV-TYPE of sub-element
- * @throw Error sub-element of specified type does not exist
+ /** @brief Get SignatureNonce
+ * @retval nullopt SignatureNonce is not set
*/
+ optional<std::vector<uint8_t>>
+ getNonce() const;
+
+ /** @brief Append or replace SignatureNonce
+ * @return A reference to this SignatureInfo, to allow chaining
+ *
+ * Passing `nullopt` will remove the SignatureNonce.
+ */
+ SignatureInfo&
+ setNonce(optional<std::vector<uint8_t>> nonce);
+
+ /** @brief Get SignatureTime
+ * @retval nullopt SignatureTime is not set
+ */
+ optional<time::system_clock::time_point>
+ getTime() const;
+
+ /** @brief Append or replace SignatureTime
+ * @return A reference to this SignatureInfo, to allow chaining
+ *
+ * Passing `nullopt` will remove the SignatureTime.
+ */
+ SignatureInfo&
+ setTime(optional<time::system_clock::time_point> time = time::system_clock::now());
+
+ /** @brief Get SignatureSeqNum
+ * @retval nullopt SignatureSeqNum is not set
+ */
+ optional<uint64_t>
+ getSeqNum() const;
+
+ /** @brief Append or replace SignatureSeqNum
+ * @return A reference to this SignatureInfo, to allow chaining
+ *
+ * Passing `nullopt` will remove the SignatureSeqNum.
+ */
+ SignatureInfo&
+ setSeqNum(optional<uint64_t> seqNum);
+
+ /** @brief Get first custom TLV element with the specified TLV-TYPE
+ * @param type TLV-TYPE of element to get
+ * @retval nullopt No custom TLV elements with the specified TLV-TYPE exist
+ */
+ optional<Block>
+ getCustomTlv(uint32_t type) const;
+
+ /** @brief Append an arbitrary TLV element to this SignatureInfo
+ *
+ * If an element of the same TLV-TYPE already exists, it will be replaced by the new element.
+ */
+ void
+ addCustomTlv(Block block);
+
+ /** @brief Remove all arbitrary TLV elements with the specified TLV-TYPE from this SignatureInfo
+ * @param type TLV-TYPE of elements to remove
+ */
+ void
+ removeCustomTlv(uint32_t type);
+
+ /** @brief Get SignatureType-specific sub-element
+ * @deprecated Use getCustomTlv
+ * @param type TLV-TYPE of sub-element
+ * @throw Error Sub-element of specified type does not exist
+ */
+ [[deprecated("use getCustomTlv")]]
const Block&
getTypeSpecificTlv(uint32_t type) const;
/** @brief Append SignatureType-specific sub-element
+ * @deprecated Use addCustomTlv
*/
+ [[deprecated("use addCustomTlv")]]
void
- appendTypeSpecificTlv(const Block& element);
+ appendTypeSpecificTlv(const Block& block);
+
+private:
+ std::vector<Block>::const_iterator
+ findOtherTlv(uint32_t type) const;
private:
int32_t m_type = -1;
optional<KeyLocator> m_keyLocator;
- std::list<Block> m_otherTlvs;
+ std::vector<Block> m_otherTlvs;
mutable Block m_wire;
@@ -189,7 +267,11 @@
operator<<(std::ostream& os, const SignatureInfo& info);
};
-NDN_CXX_DECLARE_WIRE_ENCODE_INSTANTIATIONS(SignatureInfo);
+extern template size_t
+SignatureInfo::wireEncode<encoding::EncoderTag>(EncodingBuffer&, SignatureInfo::Type) const;
+
+extern template size_t
+SignatureInfo::wireEncode<encoding::EstimatorTag>(EncodingEstimator&, SignatureInfo::Type) const;
bool
operator==(const SignatureInfo& lhs, const SignatureInfo& rhs);
diff --git a/tests/identity-management-fixture.cpp b/tests/identity-management-fixture.cpp
index 781b2a1..3877a23 100644
--- a/tests/identity-management-fixture.cpp
+++ b/tests/identity-management-fixture.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2020 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -93,7 +93,7 @@
v2::AdditionalDescription description;
description.set("type", "sub-certificate");
- info.appendTypeSpecificTlv(description.wireEncode());
+ info.addCustomTlv(description.wireEncode());
m_keyChain.sign(request, signingByIdentity(issuer).setSignatureInfo(info));
m_keyChain.setDefaultCertificate(subIdentity.getDefaultKey(), request);
diff --git a/tests/unit/security/v2/certificate.t.cpp b/tests/unit/security/v2/certificate.t.cpp
index 0d848fd..91bb5c1 100644
--- a/tests/unit/security/v2/certificate.t.cpp
+++ b/tests/unit/security/v2/certificate.t.cpp
@@ -151,7 +151,7 @@
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()),
"(20150814T223739, 20150818T223738)");
- BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
+ BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::Data::Error);
BOOST_CHECK_NO_THROW(certificate.getPublicKey());
Data data(block);
@@ -177,7 +177,7 @@
BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()),
"(20141111T050000, 20141111T060000)");
- BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
+ BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::Data::Error);
BOOST_CHECK_NO_THROW(certificate.getPublicKey());
}
diff --git a/tests/unit/signature-info.t.cpp b/tests/unit/signature-info.t.cpp
index 1b0fe58..ee8c826 100644
--- a/tests/unit/signature-info.t.cpp
+++ b/tests/unit/signature-info.t.cpp
@@ -30,7 +30,7 @@
BOOST_AUTO_TEST_SUITE(TestSignatureInfo)
-const uint8_t sigInfoRsa[] = {
+const uint8_t sigInfoDataRsa[] = {
0x16, 0x1b, // SignatureInfo
0x1b, 0x01, // SignatureType
0x01, // Sha256WithRsa
@@ -44,96 +44,56 @@
0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
};
+const uint8_t sigInfoInterestRsa[] = {
+ 0x2c, 0x33, // InterestSignatureInfo
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ 0x1c, 0x16, // KeyLocator
+ 0x07, 0x14, // Name
+ 0x08, 0x04,
+ 0x74, 0x65, 0x73, 0x74,
+ 0x08, 0x03,
+ 0x6b, 0x65, 0x79,
+ 0x08, 0x07,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
+ 0x26, 0x08, // SignatureNonce
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x28, 0x08, // SignatureTime
+ 0x00, 0x00, 0x01, 0x72, 0x3d, 0x77, 0x00, 0x00,
+ 0x2a, 0x02, // SignatureSeqNum
+ 0x10, 0x20,
+};
+
BOOST_AUTO_TEST_CASE(Constructor)
{
SignatureInfo info;
BOOST_CHECK_EQUAL(info.getSignatureType(), -1);
BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
BOOST_CHECK_THROW(info.getKeyLocator(), SignatureInfo::Error);
- BOOST_CHECK_EQUAL(info.hasValidityPeriod(), false);
BOOST_CHECK_THROW(info.getValidityPeriod(), SignatureInfo::Error);
-
- BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info), "Invalid SignatureInfo");
+ BOOST_CHECK(!info.getNonce());
+ BOOST_CHECK(!info.getTime());
+ BOOST_CHECK(!info.getSeqNum());
SignatureInfo sha256Info(tlv::DigestSha256);
BOOST_CHECK_EQUAL(sha256Info.getSignatureType(), tlv::DigestSha256);
- BOOST_CHECK_EQUAL(sha256Info.hasKeyLocator(), false);
BOOST_CHECK_THROW(sha256Info.getKeyLocator(), SignatureInfo::Error);
-
- BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(sha256Info), "DigestSha256");
+ BOOST_CHECK(!info.getNonce());
+ BOOST_CHECK(!info.getTime());
+ BOOST_CHECK(!info.getSeqNum());
KeyLocator keyLocator("/test/key/locator");
SignatureInfo sha256RsaInfo(tlv::SignatureSha256WithRsa, keyLocator);
BOOST_CHECK_EQUAL(sha256RsaInfo.getSignatureType(), tlv::SignatureSha256WithRsa);
BOOST_CHECK_EQUAL(sha256RsaInfo.hasKeyLocator(), true);
BOOST_CHECK_EQUAL(sha256RsaInfo.getKeyLocator().getName(), Name("/test/key/locator"));
- BOOST_CHECK_EQUAL(sha256RsaInfo.hasValidityPeriod(), false);
BOOST_CHECK_THROW(sha256RsaInfo.getValidityPeriod(), SignatureInfo::Error);
-
- BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(sha256RsaInfo),
- "SignatureSha256WithRsa Name=/test/key/locator");
-
- auto encoded = sha256RsaInfo.wireEncode();
- Block sigInfoBlock(sigInfoRsa, sizeof(sigInfoRsa));
- BOOST_CHECK_EQUAL_COLLECTIONS(sigInfoBlock.wire(), sigInfoBlock.wire() + sigInfoBlock.size(),
- encoded.wire(), encoded.wire() + encoded.size());
-
- sha256RsaInfo = SignatureInfo(sigInfoBlock);
- BOOST_CHECK_EQUAL(sha256RsaInfo.getSignatureType(), tlv::SignatureSha256WithRsa);
- BOOST_CHECK_EQUAL(sha256RsaInfo.hasKeyLocator(), true);
- BOOST_CHECK_EQUAL(sha256RsaInfo.getKeyLocator().getName(), Name("/test/key/locator"));
+ BOOST_CHECK(!info.getNonce());
+ BOOST_CHECK(!info.getTime());
+ BOOST_CHECK(!info.getSeqNum());
}
-BOOST_AUTO_TEST_CASE(ConstructorError)
-{
- const uint8_t error1[] = {
- 0x15, 0x1b, // Wrong SignatureInfo (0x16, 0x1b)
- 0x1b, 0x01, // SignatureType
- 0x01, // Sha256WithRsa
- 0x1c, 0x16, // KeyLocator
- 0x07, 0x14, // Name
- 0x08, 0x04,
- 0x74, 0x65, 0x73, 0x74,
- 0x08, 0x03,
- 0x6b, 0x65, 0x79,
- 0x08, 0x07,
- 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
- };
- Block errorBlock1(error1, sizeof(error1));
- BOOST_CHECK_THROW(SignatureInfo info(errorBlock1), tlv::Error);
-
- const uint8_t error2[] = {
- 0x16, 0x01, // SignatureInfo
- 0x01 // Wrong SignatureInfo value
- };
- Block errorBlock2(error2, sizeof(error2));
- BOOST_CHECK_THROW(SignatureInfo info(errorBlock2), tlv::Error);
-
- const uint8_t error3[] = {
- 0x16, 0x01, // SignatureInfo
- 0x1a, 0x01, // Wrong SignatureType (0x1b, 0x1b)
- 0x01, // Sha256WithRsa
- 0x1c, 0x16, // KeyLocator
- 0x07, 0x14, // Name
- 0x08, 0x04,
- 0x74, 0x65, 0x73, 0x74,
- 0x08, 0x03,
- 0x6b, 0x65, 0x79,
- 0x08, 0x07,
- 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
- };
- Block errorBlock3(error3, sizeof(error3));
- BOOST_CHECK_THROW(SignatureInfo info(errorBlock3), tlv::Error);
-
- const uint8_t error4[] = {
- 0x16, 0x00 // Empty SignatureInfo
- };
- Block errorBlock4(error4, sizeof(error4));
- BOOST_CHECK_THROW(SignatureInfo info(errorBlock4), tlv::Error);
-
-}
-
-BOOST_AUTO_TEST_CASE(GetSetSignatureType)
+BOOST_AUTO_TEST_CASE(SignatureType)
{
SignatureInfo info;
BOOST_CHECK_EQUAL(info.getSignatureType(), -1);
@@ -153,7 +113,8 @@
BOOST_CHECK_EQUAL(info.hasWire(), false);
}
-BOOST_AUTO_TEST_CASE(GetSetKeyLocator)
+// We must name this test case differently to avoid naming conflicts
+BOOST_AUTO_TEST_CASE(KeyLocatorField)
{
SignatureInfo info(tlv::SignatureSha256WithEcdsa);
BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
@@ -179,6 +140,230 @@
BOOST_CHECK_EQUAL(info.hasWire(), false);
}
+BOOST_AUTO_TEST_CASE(SignatureNonce)
+{
+ SignatureInfo info(tlv::SignatureSha256WithEcdsa);
+ BOOST_CHECK(!info.getNonce());
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ std::vector<uint8_t> nonce{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ info.setNonce(nonce);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(info.getNonce() == nonce);
+
+ info.wireEncode();
+ info.setNonce(nonce);
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ nonce[2] = 0xFF;
+ info.setNonce(nonce);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(info.getNonce() == nonce);
+
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.setNonce(nullopt);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(!info.getNonce());
+}
+
+BOOST_AUTO_TEST_CASE(SignatureTime)
+{
+ SignatureInfo info(tlv::SignatureSha256WithEcdsa);
+ BOOST_CHECK(!info.getTime());
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ time::system_clock::time_point timePoint(1590169108480_ms);
+ info.setTime(timePoint);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(info.getTime() == timePoint);
+
+ info.wireEncode();
+ info.setTime(timePoint);
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.setTime(timePoint + 2_s);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(info.getTime() == timePoint + 2_s);
+
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.setTime(nullopt);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(!info.getTime());
+}
+
+BOOST_AUTO_TEST_CASE(SignatureSeqNum)
+{
+ SignatureInfo info(tlv::SignatureSha256WithEcdsa);
+ BOOST_CHECK(!info.getSeqNum());
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.setSeqNum(256);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(info.getSeqNum() == 256UL);
+
+ info.wireEncode();
+ info.setSeqNum(256);
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.setSeqNum(512);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(info.getSeqNum() == 512UL);
+
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.setSeqNum(nullopt);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(!info.getSeqNum());
+}
+
+BOOST_AUTO_TEST_CASE(EncodeDecode)
+{
+ KeyLocator keyLocator("/test/key/locator");
+ SignatureInfo info(tlv::SignatureSha256WithRsa, keyLocator);
+
+ // Encode as SignatureInfo (for Data packets)
+ auto encodedData = info.wireEncode(SignatureInfo::Type::Data);
+ Block sigInfoDataBlock(sigInfoDataRsa, sizeof(sigInfoDataRsa));
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(sigInfoDataBlock.wire(), sigInfoDataBlock.wire() + sigInfoDataBlock.size(),
+ encodedData.wire(), encodedData.wire() + encodedData.size());
+
+ // Decode as SignatureInfo (for Data packets)
+ info = SignatureInfo(sigInfoDataBlock, SignatureInfo::Type::Data);
+ BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithRsa);
+ BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
+ BOOST_CHECK_EQUAL(info.getKeyLocator().getName(), Name("/test/key/locator"));
+
+ BOOST_CHECK(!info.getNonce());
+ BOOST_CHECK(!info.getTime());
+ BOOST_CHECK(!info.getSeqNum());
+
+ // Encode as InterestSignatureInfo
+ std::vector<uint8_t> nonce{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
+ info.setNonce(nonce);
+ time::system_clock::time_point timePoint(1590169108480_ms);
+ info.setTime(timePoint);
+ info.setSeqNum(0x1020);
+ auto encodedInterest = info.wireEncode(SignatureInfo::Type::Interest);
+ Block sigInfoInterestBlock(sigInfoInterestRsa, sizeof(sigInfoInterestRsa));
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(sigInfoInterestBlock.wire(),
+ sigInfoInterestBlock.wire() + sigInfoInterestBlock.size(),
+ encodedInterest.wire(),
+ encodedInterest.wire() + encodedInterest.size());
+
+ // Decode as InterestSignatureInfo
+ info = SignatureInfo(sigInfoInterestBlock, SignatureInfo::Type::Interest);
+ BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithRsa);
+ BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
+ BOOST_CHECK_EQUAL(info.getKeyLocator().getName(), Name("/test/key/locator"));
+ BOOST_CHECK(info.getNonce() == nonce);
+ BOOST_CHECK(info.getTime() == timePoint);
+ BOOST_CHECK(info.getSeqNum() == 0x1020UL);
+}
+
+BOOST_AUTO_TEST_CASE(DecodeError)
+{
+ const uint8_t error1[] = {
+ 0x15, 0x1b, // Wrong SignatureInfo (0x16, 0x1b)
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ 0x1c, 0x16, // KeyLocator
+ 0x07, 0x14, // Name
+ 0x08, 0x04,
+ 0x74, 0x65, 0x73, 0x74,
+ 0x08, 0x03,
+ 0x6b, 0x65, 0x79,
+ 0x08, 0x07,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
+ };
+ Block errorBlock1(error1, sizeof(error1));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock1, SignatureInfo::Type::Data), tlv::Error);
+
+ const uint8_t error2[] = {
+ 0x16, 0x05, // SignatureInfo
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ 0x83, 0x00, // Unrecognized critical TLV
+ };
+ Block errorBlock2(error2, sizeof(error2));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock2, SignatureInfo::Type::Data), tlv::Error);
+
+ const uint8_t error3[] = {
+ 0x16, 0x00 // Empty SignatureInfo
+ };
+ Block errorBlock3(error3, sizeof(error3));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock3, SignatureInfo::Type::Data), tlv::Error);
+
+ // Encoding is correct for SignatureInfo, but decoder is expecting InterestSignatureInfo
+ const uint8_t error4[] = {
+ 0x16, 0x1b, // SignatureInfo
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ 0x1c, 0x16, // KeyLocator
+ 0x07, 0x14, // Name
+ 0x08, 0x04,
+ 0x74, 0x65, 0x73, 0x74,
+ 0x08, 0x03,
+ 0x6b, 0x65, 0x79,
+ 0x08, 0x07,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
+ };
+ Block errorBlock4(error4, sizeof(error4));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock4, SignatureInfo::Type::Interest), tlv::Error);
+
+ // SignatureType and KeyLocator out-of-order
+ const uint8_t error5[] = {
+ 0x2c, 0x1b, // SignatureInfo
+ 0x1c, 0x16, // KeyLocator
+ 0x07, 0x14, // Name
+ 0x08, 0x04,
+ 0x74, 0x65, 0x73, 0x74,
+ 0x08, 0x03,
+ 0x6b, 0x65, 0x79,
+ 0x08, 0x07,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ };
+ Block errorBlock5(error5, sizeof(error5));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock5, SignatureInfo::Type::Interest), tlv::Error);
+
+ // Repeated KeyLocator
+ const uint8_t error6[] = {
+ 0x2c, 0x33, // SignatureInfo
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ 0x1c, 0x16, // KeyLocator
+ 0x07, 0x14, // Name
+ 0x08, 0x04,
+ 0x74, 0x65, 0x73, 0x74,
+ 0x08, 0x03,
+ 0x6b, 0x65, 0x79,
+ 0x08, 0x07,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72,
+ 0x1c, 0x16, // KeyLocator
+ 0x07, 0x14, // Name
+ 0x08, 0x04,
+ 0x74, 0x65, 0x73, 0x74,
+ 0x08, 0x03,
+ 0x6b, 0x65, 0x79,
+ 0x08, 0x07,
+ 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
+ };
+ Block errorBlock6(error6, sizeof(error6));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock6, SignatureInfo::Type::Interest), tlv::Error);
+
+ // Zero-length SignatureNonce
+ const uint8_t error7[] = {
+ 0x2c, 0x05, // SignatureInfo
+ 0x1b, 0x01, // SignatureType
+ 0x01, // Sha256WithRsa
+ 0x26, 0x00 // SignatureNonce
+ };
+ Block errorBlock7(error7, sizeof(error7));
+ BOOST_CHECK_THROW(SignatureInfo(errorBlock7, SignatureInfo::Type::Interest), tlv::Error);
+}
+
BOOST_AUTO_TEST_CASE(ValidityPeriod)
{
const uint8_t sigInfo[] = {
@@ -207,12 +392,10 @@
security::ValidityPeriod vp1(notBefore, notAfter);
SignatureInfo info(tlv::SignatureSha256WithRsa, KeyLocator("/test/key/locator"));
- BOOST_CHECK_EQUAL(info.hasValidityPeriod(), false);
BOOST_CHECK_THROW(info.getValidityPeriod(), SignatureInfo::Error);
info.wireEncode();
info.setValidityPeriod(vp1);
- BOOST_CHECK_EQUAL(info.hasValidityPeriod(), true);
BOOST_CHECK_EQUAL(info.getValidityPeriod(), vp1);
BOOST_CHECK_EQUAL(info.hasWire(), false);
@@ -227,13 +410,11 @@
// decode
Block block(sigInfo, sizeof(sigInfo));
- SignatureInfo info2(block);
- BOOST_CHECK_EQUAL(info2.hasValidityPeriod(), true);
+ SignatureInfo info2(block, SignatureInfo::Type::Data);
BOOST_CHECK_EQUAL(info2.getValidityPeriod(), vp1);
BOOST_CHECK_EQUAL(info2.hasWire(), true);
info2.setValidityPeriod(security::ValidityPeriod(notBefore, notBefore + 42_days));
- BOOST_CHECK_EQUAL(info2.hasValidityPeriod(), true);
BOOST_CHECK_NE(info2.getValidityPeriod(), vp1);
BOOST_CHECK(info2.getValidityPeriod().getPeriod() == std::make_pair(notBefore, notBefore + 42_days));
BOOST_CHECK_EQUAL(info2.hasWire(), false);
@@ -241,51 +422,93 @@
info2.wireEncode();
BOOST_CHECK_EQUAL(info2.hasWire(), true);
info2.setValidityPeriod(nullopt);
- BOOST_CHECK_EQUAL(info2.hasValidityPeriod(), false);
BOOST_CHECK_THROW(info2.getValidityPeriod(), SignatureInfo::Error);
BOOST_CHECK_EQUAL(info2.hasWire(), false);
}
-BOOST_AUTO_TEST_CASE(OtherTlvs)
+BOOST_AUTO_TEST_CASE(CustomTlvs)
{
SignatureInfo info(tlv::SignatureSha256WithEcdsa);
- info.appendTypeSpecificTlv("810101"_block);
- BOOST_CHECK_THROW(info.getTypeSpecificTlv(0x82), SignatureInfo::Error);
- BOOST_CHECK_EQUAL(info.getTypeSpecificTlv(0x81).type(), 0x81);
+ info.addCustomTlv("810101"_block);
+ BOOST_CHECK(!info.getCustomTlv(0x82));
+ BOOST_REQUIRE(info.getCustomTlv(0x81));
+ BOOST_CHECK_EQUAL(info.getCustomTlv(0x81)->type(), 0x81);
info.wireEncode();
BOOST_CHECK_EQUAL(info.hasWire(), true);
- info.appendTypeSpecificTlv("82020202"_block);
+ info.addCustomTlv("82020202"_block);
BOOST_CHECK_EQUAL(info.hasWire(), false);
+
+ info.wireEncode();
+ BOOST_CHECK_EQUAL(info.hasWire(), true);
+ info.removeCustomTlv(0x81);
+ BOOST_CHECK_EQUAL(info.hasWire(), false);
+ BOOST_CHECK(!info.getCustomTlv(0x81));
}
-BOOST_AUTO_TEST_CASE(OtherTlvsEncoding) // Bug #3914
+BOOST_AUTO_TEST_CASE(CustomTlvsEncoding) // Bug #3914
{
SignatureInfo info1(tlv::SignatureSha256WithRsa);
- info1.appendTypeSpecificTlv(makeStringBlock(101, "First"));
- info1.appendTypeSpecificTlv(makeStringBlock(102, "Second"));
- info1.appendTypeSpecificTlv(makeStringBlock(103, "Third"));
+ info1.appendTypeSpecificTlv(makeStringBlock(102, "First"));
+ info1.appendTypeSpecificTlv(makeStringBlock(104, "Second"));
+ info1.appendTypeSpecificTlv(makeStringBlock(106, "Third"));
- BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info1), "SignatureSha256WithRsa { 101 102 103 }");
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info1), "SignatureSha256WithRsa { 102 104 106 }");
SignatureInfo info2;
- info2.wireDecode(info1.wireEncode());
+ info2.wireDecode(info1.wireEncode(), SignatureInfo::Type::Data);
BOOST_CHECK_EQUAL(info1, info2);
const uint8_t infoBytes[] = {
0x16, 0x19, // SignatureInfo
0x1b, 0x01, 0x01, // SignatureType=1
- 0x65, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, // 101 "First"
- 0x66, 0x06, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, // 102 "Second"
- 0x67, 0x05, 0x54, 0x68, 0x69, 0x72, 0x64 // 103 "Third"
+ 0x66, 0x05, 0x46, 0x69, 0x72, 0x73, 0x74, // 102 "First"
+ 0x68, 0x06, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, // 104 "Second"
+ 0x6a, 0x05, 0x54, 0x68, 0x69, 0x72, 0x64 // 106 "Third"
};
- SignatureInfo info3(Block(infoBytes, sizeof(infoBytes)));
+ SignatureInfo info3(Block(infoBytes, sizeof(infoBytes)), SignatureInfo::Type::Data);
BOOST_CHECK_EQUAL(info3, info1);
BOOST_CHECK_EQUAL_COLLECTIONS(infoBytes, infoBytes + sizeof(infoBytes),
info1.wireEncode().begin(), info1.wireEncode().end());
}
+BOOST_AUTO_TEST_CASE(OutputStream)
+{
+ SignatureInfo info;
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info), "Invalid SignatureInfo");
+
+ info.setSignatureType(tlv::DigestSha256);
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info), "DigestSha256");
+
+ info.setSignatureType(tlv::SignatureSha256WithRsa);
+ info.setKeyLocator(KeyLocator("/test/key/locator"));
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info),
+ "SignatureSha256WithRsa Name=/test/key/locator");
+
+ info.setNonce(std::vector<uint8_t>{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08});
+ info.setTime(time::system_clock::time_point(1590169108480_ms));
+ info.setSeqNum(0x1020);
+
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info),
+ "SignatureSha256WithRsa Name=/test/key/locator "
+ "{ Nonce=0102030405060708 Time=1590169108480 SeqNum=4128 }");
+
+ info.setValidityPeriod(security::ValidityPeriod(time::getUnixEpoch(), time::getUnixEpoch() + 31_days));
+
+ info.addCustomTlv("82020102"_block);
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info),
+ "SignatureSha256WithRsa Name=/test/key/locator "
+ "{ Nonce=0102030405060708 Time=1590169108480 SeqNum=4128 "
+ "ValidityPeriod=(19700101T000000, 19700201T000000) 130 }");
+
+ info.addCustomTlv("84020102"_block);
+ BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(info),
+ "SignatureSha256WithRsa Name=/test/key/locator "
+ "{ Nonce=0102030405060708 Time=1590169108480 SeqNum=4128 "
+ "ValidityPeriod=(19700101T000000, 19700201T000000) 130 132 }");
+}
+
BOOST_AUTO_TEST_SUITE_END() // TestSignatureInfo
} // namespace tests
diff --git a/tools/ndnsec/cert-gen.cpp b/tools/ndnsec/cert-gen.cpp
index 1749b2b..c526654 100644
--- a/tools/ndnsec/cert-gen.cpp
+++ b/tools/ndnsec/cert-gen.cpp
@@ -152,7 +152,7 @@
SignatureInfo signatureInfo;
signatureInfo.setValidityPeriod(security::ValidityPeriod(notBefore, notAfter));
if (!additionalDescription.empty()) {
- signatureInfo.appendTypeSpecificTlv(additionalDescription.wireEncode());
+ signatureInfo.addCustomTlv(additionalDescription.wireEncode());
}
security::Identity identity;