data: add shortcuts to access SignatureType and KeyLocator

Also, modernize the API of SignatureInfo and deprecate
unsetKeyLocator() and unsetValidityPeriod()

Change-Id: I8b775a4deb185784a3dcc8bd96c8f5f0c2915854
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index ad49f32..fe34062 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.cpp
@@ -271,6 +271,9 @@
 Data&
 Data::setContent(ConstBufferPtr value)
 {
+  if (value == nullptr) {
+    NDN_THROW(std::invalid_argument("Content buffer cannot be nullptr"));
+  }
   resetWire();
   m_content = Block(tlv::Content, std::move(value));
   return *this;
@@ -300,13 +303,13 @@
 }
 
 Data&
-Data::setSignatureValue(const Block& value)
+Data::setSignatureValue(ConstBufferPtr value)
 {
-  if (value.type() != tlv::SignatureValue) {
-    NDN_THROW(Error("SignatureValue", value.type()));
+  if (value == nullptr) {
+    NDN_THROW(std::invalid_argument("SignatureValue buffer cannot be nullptr"));
   }
   resetWire();
-  m_signatureValue = value;
+  m_signatureValue = Block(tlv::SignatureValue, std::move(value));
   return *this;
 }
 
@@ -350,8 +353,7 @@
   os << "Name: " << data.getName() << "\n";
   os << "MetaInfo: " << data.getMetaInfo() << "\n";
   os << "Content: (size: " << data.getContent().value_size() << ")\n";
-  os << "Signature: (type: "
-     << static_cast<tlv::SignatureTypeValue>(data.getSignatureInfo().getSignatureType())
+  os << "Signature: (type: " << static_cast<tlv::SignatureTypeValue>(data.getSignatureType())
      << ", value_length: "<< data.getSignatureValue().value_size() << ")";
   os << std::endl;
 
diff --git a/ndn-cxx/data.hpp b/ndn-cxx/data.hpp
index e4d72b6..88c37b1 100644
--- a/ndn-cxx/data.hpp
+++ b/ndn-cxx/data.hpp
@@ -22,11 +22,11 @@
 #ifndef NDN_DATA_HPP
 #define NDN_DATA_HPP
 
+#include "ndn-cxx/detail/packet-base.hpp"
+#include "ndn-cxx/encoding/block.hpp"
 #include "ndn-cxx/meta-info.hpp"
 #include "ndn-cxx/name.hpp"
 #include "ndn-cxx/signature.hpp"
-#include "ndn-cxx/detail/packet-base.hpp"
-#include "ndn-cxx/encoding/block.hpp"
 
 namespace ndn {
 
@@ -105,7 +105,7 @@
   /** @brief Check if this instance has cached wire encoding.
    */
   bool
-  hasWire() const
+  hasWire() const noexcept
   {
     return m_wire.hasWire();
   }
@@ -121,7 +121,7 @@
   /** @brief Get name
    */
   const Name&
-  getName() const
+  getName() const noexcept
   {
     return m_name;
   }
@@ -135,7 +135,7 @@
   /** @brief Get MetaInfo
    */
   const MetaInfo&
-  getMetaInfo() const
+  getMetaInfo() const noexcept
   {
     return m_metaInfo;
   }
@@ -154,26 +154,26 @@
   const Block&
   getContent() const;
 
-  /** @brief Set Content from a block
+  /** @brief Set Content from a Block
    *
-   *  If block's TLV-TYPE is Content, it will be used directly as Data's Content element.
-   *  If block's TLV-TYPE is not Content, it will be nested into a Content element.
+   *  If the block's TLV-TYPE is Content, it will be used directly as this Data's Content element.
+   *  Otherwise, the block will be nested into a Content element.
    *
    *  @return a reference to this Data, to allow chaining
    */
   Data&
   setContent(const Block& block);
 
-  /** @brief Copy Content value from raw buffer
+  /** @brief Set Content by copying from a raw buffer
    *  @param value pointer to the first octet of the value
-   *  @param valueSize size of the raw buffer
+   *  @param valueSize size of the buffer
    *  @return a reference to this Data, to allow chaining
    */
   Data&
   setContent(const uint8_t* value, size_t valueSize);
 
-  /** @brief Set Content from wire buffer
-   *  @param value Content value, which does not need to be a TLV element
+  /** @brief Set Content from a shared buffer
+   *  @param value buffer containing the TLV-VALUE of the content; must not be nullptr
    *  @return a reference to this Data, to allow chaining
    */
   Data&
@@ -197,14 +197,19 @@
   /** @brief Get SignatureInfo
    */
   const SignatureInfo&
-  getSignatureInfo() const
+  getSignatureInfo() const noexcept
   {
     return m_signatureInfo;
   }
 
   /** @brief Set SignatureInfo
+   *
+   *  This is a low-level function that should not normally be called directly by applications.
+   *  Instead, provide a SignatureInfo to the SigningInfo object passed to KeyChain::sign().
+   *
    *  @return a reference to this Data, to allow chaining
-   *  @throw tlv::Error TLV-TYPE of supplied block is not SignatureValue, or the block does not have TLV-VALUE
+   *  @warning SignatureInfo is overwritten when the packet is signed via KeyChain::sign().
+   *  @sa SigningInfo
    */
   Data&
   setSignatureInfo(const SignatureInfo& info);
@@ -212,16 +217,22 @@
   /** @brief Get SignatureValue
    */
   const Block&
-  getSignatureValue() const
+  getSignatureValue() const noexcept
   {
     return m_signatureValue;
   }
 
   /** @brief Set SignatureValue
+   *  @param value buffer containing the TLV-VALUE of the SignatureValue; must not be nullptr
+   *
+   *  This is a low-level function that should not normally be called directly by applications.
+   *  Instead, use KeyChain::sign() to sign the packet.
+   *
    *  @return a reference to this Data, to allow chaining
+   *  @warning SignatureValue is overwritten when the packet is signed via KeyChain::sign().
    */
   Data&
-  setSignatureValue(const Block& value);
+  setSignatureValue(ConstBufferPtr value);
 
 public: // MetaInfo fields
   uint32_t
@@ -251,6 +262,24 @@
   Data&
   setFinalBlock(optional<name::Component> finalBlockId);
 
+public: // SignatureInfo fields
+  /** @brief Get SignatureType
+   *  @return tlv::SignatureTypeValue, or -1 to indicate the signature is invalid
+   */
+  int32_t
+  getSignatureType() const noexcept
+  {
+    return m_signatureInfo.getSignatureType();
+  }
+
+  /** @brief Get KeyLocator
+   */
+  optional<KeyLocator>
+  getKeyLocator() const noexcept
+  {
+    return m_signatureInfo.hasKeyLocator() ? make_optional(m_signatureInfo.getKeyLocator()) : nullopt;
+  }
+
 protected:
   /** @brief Clear wire encoding and cached FullName
    *  @note This does not clear the SignatureValue.
diff --git a/ndn-cxx/security/v2/certificate.cpp b/ndn-cxx/security/v2/certificate.cpp
index 489a793..f5ef157 100644
--- a/ndn-cxx/security/v2/certificate.cpp
+++ b/ndn-cxx/security/v2/certificate.cpp
@@ -166,16 +166,15 @@
 
   os << "Signature Information:\n";
   {
-    os << "  Signature Type: "
-       << static_cast<tlv::SignatureTypeValue>(cert.getSignatureInfo().getSignatureType()) << "\n";
+    os << "  Signature Type: " << static_cast<tlv::SignatureTypeValue>(cert.getSignatureType()) << "\n";
 
-    if (cert.getSignatureInfo().hasKeyLocator()) {
+    auto keyLoc = cert.getKeyLocator();
+    if (keyLoc) {
       os << "  Key Locator: ";
-      const auto& keyLocator = cert.getSignatureInfo().getKeyLocator();
-      if (keyLocator.getType() == tlv::Name && keyLocator.getName() == cert.getKeyName()) {
+      if (keyLoc->getType() == tlv::Name && keyLoc->getName() == cert.getKeyName()) {
         os << "Self-Signed ";
       }
-      os << keyLocator << "\n";
+      os << *keyLoc << "\n";
     }
   }
 
diff --git a/ndn-cxx/signature-info.cpp b/ndn-cxx/signature-info.cpp
index 41f1cb2..9c96cda 100644
--- a/ndn-cxx/signature-info.cpp
+++ b/ndn-cxx/signature-info.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 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).
  *
@@ -32,22 +32,11 @@
 static_assert(std::is_base_of<tlv::Error, SignatureInfo::Error>::value,
               "SignatureInfo::Error must inherit from tlv::Error");
 
-SignatureInfo::SignatureInfo()
-  : m_type(-1)
-  , m_hasKeyLocator(false)
-{
-}
+SignatureInfo::SignatureInfo() = default;
 
-SignatureInfo::SignatureInfo(tlv::SignatureTypeValue type)
+SignatureInfo::SignatureInfo(tlv::SignatureTypeValue type, optional<KeyLocator> keyLocator)
   : m_type(type)
-  , m_hasKeyLocator(false)
-{
-}
-
-SignatureInfo::SignatureInfo(tlv::SignatureTypeValue type, const KeyLocator& keyLocator)
-  : m_type(type)
-  , m_hasKeyLocator(true)
-  , m_keyLocator(keyLocator)
+  , m_keyLocator(std::move(keyLocator))
 {
 }
 
@@ -64,11 +53,11 @@
     NDN_THROW(Error("Cannot encode invalid SignatureInfo"));
   }
 
-  // SignatureInfo ::= SIGNATURE-INFO-TLV TLV-LENGTH
-  //                     SignatureType
-  //                     KeyLocator?
-  //                     ValidityPeriod? (if present, stored as first item of m_otherTlvs)
-  //                     other SignatureType-specific sub-elements*
+  // SignatureInfo = SIGNATURE-INFO-TYPE TLV-LENGTH
+  //                   SignatureType
+  //                   [KeyLocator]
+  //                   [ValidityPeriod] ; if present, stored as first item of m_otherTlvs
+  //                   *OtherSubelements
 
   size_t totalLength = 0;
 
@@ -76,8 +65,9 @@
     totalLength += encoder.prependBlock(*i);
   }
 
-  if (m_hasKeyLocator)
-    totalLength += m_keyLocator.wireEncode(encoder);
+  if (m_keyLocator) {
+    totalLength += m_keyLocator->wireEncode(encoder);
+  }
 
   totalLength += prependNonNegativeIntegerBlock(encoder, tlv::SignatureType,
                                                 static_cast<uint64_t>(m_type));
@@ -109,7 +99,7 @@
 SignatureInfo::wireDecode(const Block& wire)
 {
   m_type = -1;
-  m_hasKeyLocator = false;
+  m_keyLocator = nullopt;
   m_otherTlvs.clear();
 
   m_wire = wire;
@@ -129,8 +119,7 @@
 
   // the second sub-element could be KeyLocator
   if (it != m_wire.elements_end() && it->type() == tlv::KeyLocator) {
-    m_keyLocator.wireDecode(*it);
-    m_hasKeyLocator = true;
+    m_keyLocator.emplace(*it);
     ++it;
   }
 
@@ -141,62 +130,75 @@
   }
 }
 
-void
+SignatureInfo&
 SignatureInfo::setSignatureType(tlv::SignatureTypeValue type)
 {
-  m_wire.reset();
-  m_type = type;
+  if (type != m_type) {
+    m_type = type;
+    m_wire.reset();
+  }
+  return *this;
 }
 
 const KeyLocator&
 SignatureInfo::getKeyLocator() const
 {
-  if (m_hasKeyLocator)
-    return m_keyLocator;
-  else
+  if (!hasKeyLocator()) {
     NDN_THROW(Error("KeyLocator does not exist in SignatureInfo"));
+  }
+  return *m_keyLocator;
 }
 
-void
-SignatureInfo::setKeyLocator(const KeyLocator& keyLocator)
+SignatureInfo&
+SignatureInfo::setKeyLocator(optional<KeyLocator> keyLocator)
 {
-  m_wire.reset();
-  m_keyLocator = keyLocator;
-  m_hasKeyLocator = true;
+  if (keyLocator != m_keyLocator) {
+    m_keyLocator = std::move(keyLocator);
+    m_wire.reset();
+  }
+  return *this;
 }
 
 void
 SignatureInfo::unsetKeyLocator()
 {
-  m_wire.reset();
-  m_keyLocator = KeyLocator();
-  m_hasKeyLocator = false;
+  setKeyLocator(nullopt);
 }
 
 security::ValidityPeriod
 SignatureInfo::getValidityPeriod() const
 {
-  if (m_otherTlvs.empty() || m_otherTlvs.front().type() != tlv::ValidityPeriod) {
+  if (!hasValidityPeriod()) {
     NDN_THROW(Error("ValidityPeriod does not exist in SignatureInfo"));
   }
-
   return security::ValidityPeriod(m_otherTlvs.front());
 }
 
-void
-SignatureInfo::setValidityPeriod(const security::ValidityPeriod& validityPeriod)
+SignatureInfo&
+SignatureInfo::setValidityPeriod(optional<security::ValidityPeriod> validityPeriod)
 {
-  unsetValidityPeriod();
-  m_otherTlvs.push_front(validityPeriod.wireEncode());
+  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();
+    }
+  }
+  else if (hasValidityPeriod()) {
+    m_otherTlvs.pop_front();
+    m_wire.reset();
+  }
+  return *this;
 }
 
 void
 SignatureInfo::unsetValidityPeriod()
 {
-  if (!m_otherTlvs.empty() && m_otherTlvs.front().type() == tlv::ValidityPeriod) {
-    m_otherTlvs.pop_front();
-    m_wire.reset();
-  }
+  setValidityPeriod(nullopt);
 }
 
 const Block&
@@ -213,15 +215,14 @@
 void
 SignatureInfo::appendTypeSpecificTlv(const Block& block)
 {
-  m_wire.reset();
   m_otherTlvs.push_back(block);
+  m_wire.reset();
 }
 
 bool
 operator==(const SignatureInfo& lhs, const SignatureInfo& rhs)
 {
   return lhs.m_type == rhs.m_type &&
-         lhs.m_hasKeyLocator == rhs.m_hasKeyLocator &&
          lhs.m_keyLocator == rhs.m_keyLocator &&
          lhs.m_otherTlvs == rhs.m_otherTlvs;
 }
diff --git a/ndn-cxx/signature-info.hpp b/ndn-cxx/signature-info.hpp
index 525f116..9e7b42e 100644
--- a/ndn-cxx/signature-info.hpp
+++ b/ndn-cxx/signature-info.hpp
@@ -44,14 +44,10 @@
    */
   SignatureInfo();
 
-  /** @brief Create with specified type
+  /** @brief Create with the specified type and KeyLocator
    */
   explicit
-  SignatureInfo(tlv::SignatureTypeValue type);
-
-  /** @brief Create with specified type and KeyLocator
-   */
-  SignatureInfo(tlv::SignatureTypeValue type, const KeyLocator& keyLocator);
+  SignatureInfo(tlv::SignatureTypeValue type, optional<KeyLocator> keyLocator = nullopt);
 
   /** @brief Create from wire encoding
    *  @throw tlv::Error decode error
@@ -62,7 +58,7 @@
   /** @brief Determine whether SignatureInfo is valid
    */
   explicit
-  operator bool() const
+  operator bool() const noexcept
   {
     return m_type != -1;
   }
@@ -85,58 +81,85 @@
   void
   wireDecode(const Block& wire);
 
+  /** @brief Check if this instance has cached wire encoding.
+   */
+  bool
+  hasWire() const noexcept
+  {
+    return m_wire.hasWire();
+  }
+
 public: // field access
   /** @brief Get SignatureType
    *  @return tlv::SignatureTypeValue, or -1 to indicate invalid SignatureInfo
    */
   int32_t
-  getSignatureType() const
+  getSignatureType() const noexcept
   {
     return m_type;
   }
 
   /** @brief Set SignatureType
+   *  @return a reference to this SignatureInfo, to allow chaining
    */
-  void
+  SignatureInfo&
   setSignatureType(tlv::SignatureTypeValue type);
 
-  /** @brief Check if KeyLocator exists
+  /** @brief Check if KeyLocator is present
    */
   bool
-  hasKeyLocator() const
+  hasKeyLocator() const noexcept
   {
-    return m_hasKeyLocator;
+    return m_keyLocator.has_value();
   }
 
   /** @brief Get KeyLocator
-   *  @throw Error KeyLocator does not exist
+   *  @throw Error This SignatureInfo does not contain a KeyLocator
    */
   const KeyLocator&
   getKeyLocator() const;
 
   /** @brief Set KeyLocator
+   *  @return a reference to this SignatureInfo, to allow chaining
+   *
+   *  Passing `nullopt` will remove the KeyLocator.
    */
-  void
-  setKeyLocator(const KeyLocator& keyLocator);
+  SignatureInfo&
+  setKeyLocator(optional<KeyLocator> keyLocator);
 
-  /** @brief Unset KeyLocator
+  /** @brief Remove KeyLocator
+   *  @deprecated Use `setKeyLocator(nullopt)`
    */
+  [[deprecated("use setKeyLocator(nullopt)")]]
   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 ValidityPeriod does not exist
+   *  @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
+   *
+   *  Passing `nullopt` will remove the ValidityPeriod.
    */
-  void
-  setValidityPeriod(const security::ValidityPeriod& validityPeriod);
+  SignatureInfo&
+  setValidityPeriod(optional<security::ValidityPeriod> validityPeriod);
 
-  /** @brief Unset ValidityPeriod
+  /** @brief Remove ValidityPeriod
+   *  @deprecated Use `setValidityPeriod(nullopt)`
    */
+  [[deprecated("use setValidityPeriod(nullopt)")]]
   void
   unsetValidityPeriod();
 
@@ -153,9 +176,8 @@
   appendTypeSpecificTlv(const Block& element);
 
 private:
-  int32_t m_type;
-  bool m_hasKeyLocator;
-  KeyLocator m_keyLocator;
+  int32_t m_type = -1;
+  optional<KeyLocator> m_keyLocator;
   std::list<Block> m_otherTlvs;
 
   mutable Block m_wire;
diff --git a/ndn-cxx/signature.hpp b/ndn-cxx/signature.hpp
index a0fc84e..ab536f3 100644
--- a/ndn-cxx/signature.hpp
+++ b/ndn-cxx/signature.hpp
@@ -148,7 +148,7 @@
   void
   unsetKeyLocator()
   {
-    m_info.unsetKeyLocator();
+    m_info.setKeyLocator(nullopt);
   }
 
 protected:
diff --git a/tests/make-interest-data.cpp b/tests/make-interest-data.cpp
index c6e3a4c..9f5a790 100644
--- a/tests/make-interest-data.cpp
+++ b/tests/make-interest-data.cpp
@@ -21,8 +21,6 @@
 
 #include "tests/make-interest-data.hpp"
 
-#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
-
 namespace ndn {
 namespace tests {
 
@@ -47,7 +45,7 @@
 signData(Data& data)
 {
   data.setSignatureInfo(SignatureInfo(tlv::SignatureSha256WithRsa));
-  data.setSignatureValue(encoding::makeEmptyBlock(tlv::SignatureValue));
+  data.setSignatureValue(std::make_shared<Buffer>());
   data.wireEncode();
   return data;
 }
diff --git a/tests/unit/data.t.cpp b/tests/unit/data.t.cpp
index 041ddc0..f741a82 100644
--- a/tests/unit/data.t.cpp
+++ b/tests/unit/data.t.cpp
@@ -21,7 +21,6 @@
 
 #include "ndn-cxx/data.hpp"
 #include "ndn-cxx/encoding/buffer-stream.hpp"
-#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
 #include "ndn-cxx/security/transform/private-key.hpp"
 #include "ndn-cxx/security/transform/public-key.hpp"
 #include "ndn-cxx/security/transform/signer-filter.hpp"
@@ -29,9 +28,11 @@
 #include "ndn-cxx/security/transform/stream-sink.hpp"
 #include "ndn-cxx/security/verification-helpers.hpp"
 #include "ndn-cxx/util/sha256.hpp"
+#include "ndn-cxx/util/string-helper.hpp"
 
 #include "tests/boost-test.hpp"
 #include "tests/identity-management-fixture.hpp"
+
 #include <boost/lexical_cast.hpp>
 
 namespace ndn {
@@ -42,41 +43,42 @@
 const uint8_t CONTENT1[] = {0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x21};
 
 const uint8_t DATA1[] = {
-0x06, 0xc5, // Data
+  0x06, 0xc5, // Data
     0x07, 0x14, // Name
-        0x08, 0x05,
-            0x6c, 0x6f, 0x63, 0x61, 0x6c,
-        0x08, 0x03,
-            0x6e, 0x64, 0x6e,
-        0x08, 0x06,
-            0x70, 0x72, 0x65, 0x66, 0x69, 0x78,
+      0x08, 0x05,
+        0x6c, 0x6f, 0x63, 0x61, 0x6c,
+      0x08, 0x03,
+        0x6e, 0x64, 0x6e,
+      0x08, 0x06,
+        0x70, 0x72, 0x65, 0x66, 0x69, 0x78,
     0x14, 0x04, // MetaInfo
-        0x19, 0x02, // FreshnessPeriod
-            0x27, 0x10,
+      0x19, 0x02, // FreshnessPeriod
+        0x27, 0x10,
     0x15, 0x08, // Content
-        0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x21,
+      0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x21,
     0x16, 0x1b, // SignatureInfo
-        0x1b, 0x01, // SignatureType
-            0x01,
-        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,
+      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,
     0x17, 0x80, // SignatureValue
-        0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31, 0xec,
-        0xe3, 0xb9, 0xea, 0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9, 0xb3, 0xc6,
-        0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41, 0x69, 0x62, 0x56, 0xd8, 0xb3, 0x6a, 0x38,
-        0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6, 0x4d, 0x10, 0x1d, 0xdc,
-        0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96, 0x5e, 0xc0, 0x62, 0x0b, 0xcf,
-        0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41, 0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9,
-        0x64, 0xd6, 0x66, 0xb4, 0xe9, 0x8d, 0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8,
-        0x55, 0xf6, 0x1c, 0x19, 0x0b, 0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7,
-        0xaa, 0x0d, 0x14, 0x58, 0x30, 0xe5, 0x37, 0x6a, 0x6d, 0xdb, 0x56, 0xac, 0xa3,
-        0xfc, 0x90, 0x7a, 0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1
+      0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31,
+      0xec, 0xe3, 0xb9, 0xea, 0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9,
+      0xb3, 0xc6, 0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41, 0x69, 0x62, 0x56, 0xd8,
+      0xb3, 0x6a, 0x38, 0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6,
+      0x4d, 0x10, 0x1d, 0xdc, 0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96,
+      0x5e, 0xc0, 0x62, 0x0b, 0xcf, 0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41,
+      0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9, 0x64, 0xd6, 0x66, 0xb4, 0xe9, 0x8d,
+      0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8, 0x55, 0xf6, 0x1c, 0x19, 0x0b,
+      0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7, 0xaa, 0x0d, 0x14, 0x58,
+      0x30, 0xe5, 0x37, 0x6a, 0x6d, 0xdb, 0x56, 0xac, 0xa3, 0xfc, 0x90, 0x7a,
+      0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1,
 };
 
 BOOST_AUTO_TEST_CASE(DefaultConstructor)
@@ -90,6 +92,9 @@
   BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
   BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
   BOOST_CHECK(!d.getSignatureInfo());
+  BOOST_CHECK_EQUAL(d.getSignatureType(), -1);
+  BOOST_CHECK(!d.getKeyLocator());
+  BOOST_CHECK_EQUAL(d.getSignatureValue().isValid(), false);
 }
 
 class DataSigningKeyFixture
@@ -155,27 +160,15 @@
 
 BOOST_FIXTURE_TEST_CASE(Encode, DataSigningKeyFixture)
 {
-  // manual data packet creation for now
-
   Data d(Name("/local/ndn/prefix"));
   d.setContentType(tlv::ContentType_Blob);
   d.setFreshnessPeriod(10_s);
   d.setContent(CONTENT1, sizeof(CONTENT1));
 
-  Block signatureInfo(tlv::SignatureInfo);
-  // SignatureType
-  signatureInfo.push_back(makeNonNegativeIntegerBlock(tlv::SignatureType, tlv::SignatureSha256WithRsa));
-  // KeyLocator
-  {
-    KeyLocator keyLocator;
-    keyLocator.setName("/test/key/locator");
-    signatureInfo.push_back(keyLocator.wireEncode());
-  }
-  signatureInfo.encode();
-
-  // SignatureValue
-  OBufferStream os;
-  tlv::writeVarNumber(os, tlv::SignatureValue);
+  SignatureInfo signatureInfo;
+  signatureInfo.setSignatureType(tlv::SignatureSha256WithRsa);
+  signatureInfo.setKeyLocator(Name("/test/key/locator"));
+  d.setSignatureInfo(signatureInfo);
 
   OBufferStream sig;
   {
@@ -187,16 +180,10 @@
     input.write(d.getName().    wireEncode().wire(), d.getName().    wireEncode().size());
     input.write(d.getMetaInfo().wireEncode().wire(), d.getMetaInfo().wireEncode().size());
     input.write(d.getContent().              wire(), d.getContent().              size());
-    input.write(signatureInfo.               wire(), signatureInfo.               size());
+    input.write(signatureInfo.  wireEncode().wire(), signatureInfo.  wireEncode().size());
     input.end();
   }
-  auto buf = sig.buf();
-  tlv::writeVarNumber(os, buf->size());
-  os.write(buf->get<char>(), buf->size());
-
-  Block signatureValue(os.buf());
-  d.setSignatureInfo(SignatureInfo(signatureInfo));
-  d.setSignatureValue(signatureValue);
+  d.setSignatureValue(sig.buf());
 
   Block dataBlock(d.wireEncode());
   BOOST_CHECK_EQUAL_COLLECTIONS(DATA1, DATA1 + sizeof(DATA1),
@@ -213,7 +200,7 @@
   BOOST_CHECK_EQUAL(d.getFreshnessPeriod(), 10_s);
   BOOST_CHECK_EQUAL(std::string(reinterpret_cast<const char*>(d.getContent().value()),
                                 d.getContent().value_size()), "SUCCESS!");
-  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::SignatureSha256WithRsa);
+  BOOST_CHECK_EQUAL(d.getSignatureType(), tlv::SignatureSha256WithRsa);
 
   Block block = d.getSignatureInfo().wireEncode();
   block.parse();
@@ -233,10 +220,10 @@
     d.setContentType(tlv::ContentType_Key);
     d.setContent("1504C0C1C2C3"_block);
     d.setSignatureInfo(SignatureInfo("160A 1B0101 1C050703080142"_block));
-    d.setSignatureValue("1780 B48F1707A3BCA3CFC5F32DE51D9B46C32D7D262A21544EBDA88C3B415D637503"
-                             "FC9BEF20F88202A56AF9831E0D30205FD4154B08502BCDEE860267A5C3E03D8E"
-                             "A6CB74BE391C01E0A57B991B4404FC11B7D777F1B700A4B65F201118CF1840A8"
-                             "30A2A7C17DB4B7A8777E58515121AF9E2498627F8475414CDFD9801B8152AD5B"_block);
+    d.setSignatureValue(fromHex("B48F1707A3BCA3CFC5F32DE51D9B46C32D7D262A21544EBDA88C3B415D637503"
+                                "FC9BEF20F88202A56AF9831E0D30205FD4154B08502BCDEE860267A5C3E03D8E"
+                                "A6CB74BE391C01E0A57B991B4404FC11B7D777F1B700A4B65F201118CF1840A8"
+                                "30A2A7C17DB4B7A8777E58515121AF9E2498627F8475414CDFD9801B8152AD5B"));
   }
 
 protected:
@@ -254,7 +241,8 @@
   BOOST_CHECK_EQUAL(d.getFreshnessPeriod(), 0_ms);
   BOOST_CHECK_EQUAL(d.getFinalBlock().has_value(), false);
   BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
-  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getKeyLocator().has_value(), false);
   BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 32);
 
   // encode without modification: retain original wire encoding
@@ -275,7 +263,8 @@
   BOOST_CHECK_EQUAL(d.getFreshnessPeriod(), 0_ms);
   BOOST_CHECK_EQUAL(d.getFinalBlock().has_value(), false);
   BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
-  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getKeyLocator().has_value(), false);
   BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 0);
 }
 
@@ -288,7 +277,8 @@
   BOOST_CHECK_EQUAL(d.getFreshnessPeriod(), 0_ms);
   BOOST_CHECK_EQUAL(d.getFinalBlock().has_value(), false);
   BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
-  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getKeyLocator().has_value(), false);
   BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 32);
 
   // encode without modification: retain original wire encoding
@@ -388,6 +378,57 @@
     "sha256digest=28bad4b5275bd392dbb670c75cf0b66f13f7942b21e80f55c0e86b374753a548");
 }
 
+BOOST_AUTO_TEST_CASE(Content)
+{
+  Data d;
+  BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
+  BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
+
+  const uint8_t direct[] = {0xca, 0xfe};
+  d.setContent("1502CAFE"_block); // Block overload, used directly as Content
+  BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
+  BOOST_CHECK_EQUAL_COLLECTIONS(d.getContent().value_begin(), d.getContent().value_end(),
+                                direct, direct + sizeof(direct));
+
+  const uint8_t nested[] = {0x99, 0x02, 0xca, 0xfe};
+  d.setContent(Block(nested, sizeof(nested))); // Block overload, nested inside Content element
+  BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
+  BOOST_CHECK_EQUAL_COLLECTIONS(d.getContent().value_begin(), d.getContent().value_end(),
+                                nested, nested + sizeof(nested));
+
+  d.setContent(nested, sizeof(nested)); // raw buffer overload
+  BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
+  BOOST_CHECK_EQUAL_COLLECTIONS(d.getContent().value_begin(), d.getContent().value_end(),
+                                nested, nested + sizeof(nested));
+
+  d.setContent(std::make_shared<Buffer>(direct, sizeof(direct))); // ConstBufferPtr overload
+  BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
+  BOOST_CHECK_EQUAL_COLLECTIONS(d.getContent().value_begin(), d.getContent().value_end(),
+                                direct, direct + sizeof(direct));
+
+  d.setContent(std::make_shared<Buffer>()); // ConstBufferPtr overload, empty buffer
+  BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
+  BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
+
+  BOOST_CHECK_THROW(d.setContent(nullptr), std::invalid_argument);
+}
+
+BOOST_AUTO_TEST_CASE(SignatureValue)
+{
+  Data d;
+  BOOST_CHECK_EQUAL(d.getSignatureValue().type(), tlv::Invalid);
+
+  d.setSignatureValue(fromHex("FACADE"));
+  BOOST_CHECK_EQUAL(d.getSignatureValue().type(), tlv::SignatureValue);
+  BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 3);
+
+  d.setSignatureValue(std::make_shared<Buffer>()); // empty buffer
+  BOOST_CHECK_EQUAL(d.getSignatureValue().type(), tlv::SignatureValue);
+  BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 0);
+
+  BOOST_CHECK_THROW(d.setSignatureValue(nullptr), std::invalid_argument);
+}
+
 BOOST_AUTO_TEST_CASE(Equality)
 {
   Data a;
@@ -395,15 +436,15 @@
   BOOST_CHECK_EQUAL(a == b, true);
   BOOST_CHECK_EQUAL(a != b, false);
 
-  a.setName("ndn:/A");
+  a.setName("/A");
   BOOST_CHECK_EQUAL(a == b, false);
   BOOST_CHECK_EQUAL(a != b, true);
 
-  b.setName("ndn:/B");
+  b.setName("/B");
   BOOST_CHECK_EQUAL(a == b, false);
   BOOST_CHECK_EQUAL(a != b, true);
 
-  b.setName("ndn:/A");
+  b.setName("/A");
   BOOST_CHECK_EQUAL(a == b, true);
   BOOST_CHECK_EQUAL(a != b, false);
 
diff --git a/tests/unit/ims/in-memory-storage.t.cpp b/tests/unit/ims/in-memory-storage.t.cpp
index ca1fc35..737bb0e 100644
--- a/tests/unit/ims/in-memory-storage.t.cpp
+++ b/tests/unit/ims/in-memory-storage.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2019 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).
  *
@@ -24,7 +24,6 @@
 #include "ndn-cxx/ims/in-memory-storage-lfu.hpp"
 #include "ndn-cxx/ims/in-memory-storage-lru.hpp"
 #include "ndn-cxx/ims/in-memory-storage-persistent.hpp"
-#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
 #include "ndn-cxx/util/sha256.hpp"
 
 #include "tests/boost-test.hpp"
diff --git a/tests/unit/interest-filter.t.cpp b/tests/unit/interest-filter.t.cpp
index 100429c..f802c1d 100644
--- a/tests/unit/interest-filter.t.cpp
+++ b/tests/unit/interest-filter.t.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).
  *
@@ -22,8 +22,6 @@
 #include "ndn-cxx/interest-filter.hpp"
 #include "ndn-cxx/data.hpp"
 #include "ndn-cxx/encoding/buffer-stream.hpp"
-#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
-#include "ndn-cxx/security/digest-sha256.hpp"
 #include "ndn-cxx/util/dummy-client-face.hpp"
 
 #include "tests/boost-test.hpp"
diff --git a/tests/unit/lp/packet.t.cpp b/tests/unit/lp/packet.t.cpp
index c189641..e5a9cdd 100644
--- a/tests/unit/lp/packet.t.cpp
+++ b/tests/unit/lp/packet.t.cpp
@@ -21,10 +21,10 @@
 
 #include "ndn-cxx/lp/packet.hpp"
 #include "ndn-cxx/prefix-announcement.hpp"
-#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
 
 #include "tests/boost-test.hpp"
 #include "tests/identity-management-fixture.hpp"
+#include "tests/make-interest-data.hpp"
 
 namespace ndn {
 namespace lp {
@@ -431,14 +431,10 @@
 BOOST_FIXTURE_TEST_CASE(DecodePrefixAnnouncement, ndn::tests::IdentityManagementFixture)
 {
   // Construct Data which prefix announcement is attached to
-  Data data0("/edu/ua/cs/news/index.html");
-  data0.setSignatureInfo(SignatureInfo(ndn::tlv::SignatureSha256WithRsa));
-  data0.setSignatureValue(encoding::makeEmptyBlock(ndn::tlv::SignatureValue));
+  auto data0 = ndn::tests::makeData("/edu/ua/cs/news/index.html");
 
-  Block wire;
-  wire = data0.wireEncode();
   Packet packet0;
-  packet0.wireDecode(wire);
+  packet0.wireDecode(data0->wireEncode());
 
   // Construct Prefix Announcement
   PrefixAnnouncement pa;
diff --git a/tests/unit/lp/prefix-announcement-header.t.cpp b/tests/unit/lp/prefix-announcement-header.t.cpp
index fb57ded..3cccdb7 100644
--- a/tests/unit/lp/prefix-announcement-header.t.cpp
+++ b/tests/unit/lp/prefix-announcement-header.t.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).
  *
@@ -21,7 +21,6 @@
 
 #include "ndn-cxx/lp/prefix-announcement-header.hpp"
 #include "ndn-cxx/lp/tlv.hpp"
-#include "ndn-cxx/security/signature-sha256-with-rsa.hpp"
 
 #include "tests/boost-test.hpp"
 #include "tests/identity-management-fixture.hpp"
diff --git a/tests/unit/security/pib/pib-data-fixture.cpp b/tests/unit/security/pib/pib-data-fixture.cpp
index 0d12fd5..e88c48e 100644
--- a/tests/unit/security/pib/pib-data-fixture.cpp
+++ b/tests/unit/security/pib/pib-data-fixture.cpp
@@ -24,6 +24,7 @@
 // #include "ndn-cxx/security/pib/pib-memory.hpp"
 // #include "ndn-cxx/security/tpm/tpm.hpp"
 // #include "ndn-cxx/security/tpm/back-end-mem.hpp"
+
 // #include <fstream>
 
 namespace ndn {
@@ -54,7 +55,7 @@
 //         cert.setFreshnessPeriod(1_h);
 //         cert.setContent(tpm.getPublicKey(keyName));
 
-//         // @TODO sign using the new KeyChain
+//         // TODO: sign using KeyChain
 //         SignatureInfo info;
 //         info.setSignatureType(tlv::SignatureSha256WithEcdsa);
 //         info.setKeyLocator(KeyLocator(keyName));
@@ -65,8 +66,7 @@
 //         EncodingBuffer buf;
 //         cert.wireEncode(buf, true);
 
-//         cert.setSignatureValue(Block(tlv::SignatureValue,
-//                                      tpm.sign(buf.buf(), buf.size(), keyName, DigestAlgorithm::SHA256)));
+//         cert.setSignatureValue(tpm.sign(buf.buf(), buf.size(), keyName, DigestAlgorithm::SHA256));
 
 //         printBytes(prefix + "_KEY" + to_string(keyId) + "_CERT" + to_string(certVersion),
 //                    cert.wireEncode());
diff --git a/tests/unit/security/pib/pib-impl.t.cpp b/tests/unit/security/pib/pib-impl.t.cpp
index 7b13306..24d2b86 100644
--- a/tests/unit/security/pib/pib-impl.t.cpp
+++ b/tests/unit/security/pib/pib-impl.t.cpp
@@ -331,8 +331,8 @@
   // Create a fake cert with the same name
   auto cert2 = this->id1Key2Cert1;
   cert2.setName(this->id1Key1Cert1.getName());
-  cert2.setSignatureInfo(this->id1Key2Cert1.getSignatureInfo());
-  cert2.setSignatureValue(this->id1Key2Cert1.getSignatureValue());
+  BOOST_CHECK_EQUAL(cert2.getSignatureInfo(), this->id1Key2Cert1.getSignatureInfo());
+  BOOST_CHECK_EQUAL(cert2.getSignatureValue(), this->id1Key2Cert1.getSignatureValue());
   this->pib.addCertificate(cert2);
 
   auto cert3 = this->pib.getCertificate(this->id1Key1Cert1.getName());
diff --git a/tests/unit/security/v2/certificate.t.cpp b/tests/unit/security/v2/certificate.t.cpp
index dc1d8b5..0d848fd 100644
--- a/tests/unit/security/v2/certificate.t.cpp
+++ b/tests/unit/security/v2/certificate.t.cpp
@@ -63,17 +63,14 @@
 };
 
 const uint8_t SIG_VALUE[] = {
-  0x17, 0x80, // SignatureValue
-    0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31, 0xec,
-    0xe3, 0xb9, 0xea, 0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9, 0xb3, 0xc6,
-    0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41, 0x69, 0x62, 0x56, 0xd8, 0xb3, 0x6a, 0x38,
-    0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6, 0x4d, 0x10, 0x1d, 0xdc,
-    0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96, 0x5e, 0xc0, 0x62, 0x0b, 0xcf,
-    0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41, 0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9,
-    0x64, 0xd6, 0x66, 0xb4, 0xe9, 0x8d, 0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8,
-    0x55, 0xf6, 0x1c, 0x19, 0x0b, 0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7,
-    0xaa, 0x0d, 0x14, 0x58, 0x30, 0xe5, 0x37, 0x6a, 0x6d, 0xdb, 0x56, 0xac, 0xa3,
-    0xfc, 0x90, 0x7a, 0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1
+  0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31, 0xec, 0xe3, 0xb9, 0xea,
+  0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9, 0xb3, 0xc6, 0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41,
+  0x69, 0x62, 0x56, 0xd8, 0xb3, 0x6a, 0x38, 0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6,
+  0x4d, 0x10, 0x1d, 0xdc, 0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96, 0x5e, 0xc0, 0x62, 0x0b,
+  0xcf, 0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41, 0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9, 0x64, 0xd6,
+  0x66, 0xb4, 0xe9, 0x8d, 0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8, 0x55, 0xf6, 0x1c, 0x19, 0x0b,
+  0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7, 0xaa, 0x0d, 0x14, 0x58, 0x30, 0xe5, 0x37, 0x6a,
+  0x6d, 0xdb, 0x56, 0xac, 0xa3, 0xfc, 0x90, 0x7a, 0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1,
 };
 
 const uint8_t CERT[] = {
@@ -136,7 +133,7 @@
                                                  time::fromIsoString("20141111T060000")));
 
   data.setSignatureInfo(signatureInfo);
-  data.setSignatureValue(Block(SIG_VALUE, sizeof(SIG_VALUE)));
+  data.setSignatureValue(make_shared<Buffer>(SIG_VALUE, sizeof(SIG_VALUE)));
 }
 
 BOOST_AUTO_TEST_CASE(Construction)
@@ -149,8 +146,10 @@
   BOOST_CHECK_EQUAL(certificate.getIdentity(), "/ndn/site1");
   BOOST_CHECK_EQUAL(certificate.getIssuerId(), name::Component("0123"));
   BOOST_CHECK_EQUAL(certificate.getKeyId(), name::Component("ksk-1416425377094"));
-  BOOST_CHECK_EQUAL(certificate.getSignatureInfo().getKeyLocator().getName(), "/ndn/site1/KEY/ksk-2516425377094");
-  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()), "(20150814T223739, 20150818T223738)");
+  BOOST_REQUIRE_EQUAL(certificate.getKeyLocator().has_value(), true);
+  BOOST_CHECK_EQUAL(certificate.getKeyLocator()->getName(), "/ndn/site1/KEY/ksk-2516425377094");
+  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()),
+                    "(20150814T223739, 20150818T223738)");
 
   BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
   BOOST_CHECK_NO_THROW(certificate.getPublicKey());
@@ -173,8 +172,10 @@
   BOOST_CHECK_EQUAL(certificate.getIdentity(), "/ndn/site1");
   BOOST_CHECK_EQUAL(certificate.getIssuerId(), name::Component("0123"));
   BOOST_CHECK_EQUAL(certificate.getKeyId(), name::Component("ksk-1416425377094"));
-  BOOST_CHECK_EQUAL(certificate.getSignatureInfo().getKeyLocator().getName(), "/ndn/site1/KEY/ksk-2516425377094");
-  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()), "(20141111T050000, 20141111T060000)");
+  BOOST_REQUIRE_EQUAL(certificate.getKeyLocator().has_value(), true);
+  BOOST_CHECK_EQUAL(certificate.getKeyLocator()->getName(), "/ndn/site1/KEY/ksk-2516425377094");
+  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(certificate.getValidityPeriod()),
+                    "(20141111T050000, 20141111T060000)");
 
   BOOST_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
   BOOST_CHECK_NO_THROW(certificate.getPublicKey());
diff --git a/tests/unit/security/v2/key-chain.t.cpp b/tests/unit/security/v2/key-chain.t.cpp
index b065fb2..ee19346 100644
--- a/tests/unit/security/v2/key-chain.t.cpp
+++ b/tests/unit/security/v2/key-chain.t.cpp
@@ -355,7 +355,7 @@
     Signature interestSignature(interest.getName()[-2].blockFromValue(), interest.getName()[-1].blockFromValue());
 
     if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_SHA256) {
-      BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(), tlv::DigestSha256);
+      BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::DigestSha256);
       BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::DigestSha256);
 
       BOOST_CHECK(verifyDigest(data, DigestAlgorithm::SHA256));
@@ -363,17 +363,17 @@
     }
     else if (signingInfo.getSignerType() == SigningInfo::SIGNER_TYPE_HMAC) {
       Name keyName = signingInfo.getSignerName();
-      BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(), tlv::SignatureHmacWithSha256);
+      BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::SignatureHmacWithSha256);
       BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::SignatureHmacWithSha256);
 
       BOOST_CHECK(bool(verifySignature(data, tpm, keyName, DigestAlgorithm::SHA256)));
       BOOST_CHECK(bool(verifySignature(interest, tpm, keyName, DigestAlgorithm::SHA256)));
     }
     else {
-      BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(), tlv::SignatureSha256WithEcdsa);
+      BOOST_CHECK_EQUAL(data.getSignatureType(), tlv::SignatureSha256WithEcdsa);
       BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::SignatureSha256WithEcdsa);
 
-      BOOST_CHECK_EQUAL(data.getSignatureInfo().getKeyLocator().getName(), cert.getName().getPrefix(-2));
+      BOOST_CHECK_EQUAL(data.getKeyLocator()->getName(), cert.getName().getPrefix(-2));
       BOOST_CHECK_EQUAL(interestSignature.getKeyLocator().getName(), cert.getName().getPrefix(-2));
 
       BOOST_CHECK(verifySignature(data, key));
@@ -392,16 +392,18 @@
   // Create identity with EC key and the corresponding self-signed certificate
   Identity id = addIdentity("/ndn/test/ec", EcKeyParams());
   BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id.getName())));
-  BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(),
+  BOOST_CHECK_EQUAL(data.getSignatureType(),
                     KeyChain::getSignatureType(EcKeyParams().getKeyType(), DigestAlgorithm::SHA256));
-  BOOST_CHECK(id.getName().isPrefixOf(data.getSignatureInfo().getKeyLocator().getName()));
+  BOOST_REQUIRE(data.getKeyLocator().has_value());
+  BOOST_CHECK(id.getName().isPrefixOf(data.getKeyLocator()->getName()));
 
   // Create identity with RSA key and the corresponding self-signed certificate
   id = addIdentity("/ndn/test/rsa", RsaKeyParams());
   BOOST_CHECK_NO_THROW(m_keyChain.sign(data, signingByIdentity(id.getName())));
-  BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(),
+  BOOST_CHECK_EQUAL(data.getSignatureType(),
                     KeyChain::getSignatureType(RsaKeyParams().getKeyType(), DigestAlgorithm::SHA256));
-  BOOST_CHECK(id.getName().isPrefixOf(data.getSignatureInfo().getKeyLocator().getName()));
+  BOOST_REQUIRE(data.getKeyLocator().has_value());
+  BOOST_CHECK(id.getName().isPrefixOf(data.getKeyLocator()->getName()));
 }
 
 BOOST_FIXTURE_TEST_CASE(ImportPrivateKey, IdentityManagementFixture)
diff --git a/tests/unit/security/v2/validator.t.cpp b/tests/unit/security/v2/validator.t.cpp
index 934492f..b5a7e04 100644
--- a/tests/unit/security/v2/validator.t.cpp
+++ b/tests/unit/security/v2/validator.t.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).
  *
@@ -316,8 +316,8 @@
     request.setName(Name(key.getName()).append("looper").appendVersion());
 
     SignatureInfo info;
-    info.setValidityPeriod({time::system_clock::now() - 100_days,
-                            time::system_clock::now() + 100_days});
+    info.setValidityPeriod(ValidityPeriod(time::system_clock::now() - 100_days,
+                                          time::system_clock::now() + 100_days));
     m_keyChain.sign(request, signingByKey(signer).setSignatureInfo(info));
     m_keyChain.addCertificate(key, request);
 
diff --git a/tests/unit/signature-info.t.cpp b/tests/unit/signature-info.t.cpp
index 2702282..1b0fe58 100644
--- a/tests/unit/signature-info.t.cpp
+++ b/tests/unit/signature-info.t.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).
  *
@@ -22,6 +22,7 @@
 #include "ndn-cxx/signature-info.hpp"
 
 #include "tests/boost-test.hpp"
+
 #include <boost/lexical_cast.hpp>
 
 namespace ndn {
@@ -30,17 +31,17 @@
 BOOST_AUTO_TEST_SUITE(TestSignatureInfo)
 
 const uint8_t sigInfoRsa[] = {
-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
+  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
 };
 
 BOOST_AUTO_TEST_CASE(Constructor)
@@ -49,6 +50,8 @@
   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");
 
@@ -63,23 +66,21 @@
   SignatureInfo sha256RsaInfo(tlv::SignatureSha256WithRsa, keyLocator);
   BOOST_CHECK_EQUAL(sha256RsaInfo.getSignatureType(), tlv::SignatureSha256WithRsa);
   BOOST_CHECK_EQUAL(sha256RsaInfo.hasKeyLocator(), true);
-  BOOST_CHECK_NO_THROW(sha256RsaInfo.getKeyLocator());
   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");
+  BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(sha256RsaInfo),
+                    "SignatureSha256WithRsa Name=/test/key/locator");
 
-  const Block& encoded = sha256RsaInfo.wireEncode();
+  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());
+  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_NO_THROW(sha256RsaInfo.getKeyLocator());
   BOOST_CHECK_EQUAL(sha256RsaInfo.getKeyLocator().getName(), Name("/test/key/locator"));
 }
 
@@ -132,37 +133,53 @@
 
 }
 
-BOOST_AUTO_TEST_CASE(SetterGetter)
+BOOST_AUTO_TEST_CASE(GetSetSignatureType)
 {
   SignatureInfo info;
   BOOST_CHECK_EQUAL(info.getSignatureType(), -1);
-  BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
-  BOOST_CHECK_THROW(info.getKeyLocator(), SignatureInfo::Error);
+  BOOST_CHECK_THROW(info.wireEncode(), SignatureInfo::Error);
 
-  info.setSignatureType(tlv::SignatureSha256WithRsa);
-  BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithRsa);
-  BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
+  info.setSignatureType(tlv::SignatureSha256WithEcdsa);
+  BOOST_CHECK_EQUAL(info.getSignatureType(), tlv::SignatureSha256WithEcdsa);
+  BOOST_CHECK_EQUAL(info.hasWire(), false);
 
-  KeyLocator keyLocator("/test/key/locator");
-  info.setKeyLocator(keyLocator);
-  BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
-  BOOST_CHECK_NO_THROW(info.getKeyLocator());
-  BOOST_CHECK_EQUAL(info.getKeyLocator().getName(), Name("/test/key/locator"));
+  info.wireEncode();
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
+  info.setSignatureType(tlv::SignatureSha256WithEcdsa);
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
 
-  const Block& encoded = info.wireEncode();
-  Block sigInfoBlock(sigInfoRsa, sizeof(sigInfoRsa));
-
-  BOOST_CHECK_EQUAL_COLLECTIONS(sigInfoBlock.wire(),
-                                sigInfoBlock.wire() + sigInfoBlock.size(),
-                                encoded.wire(),
-                                encoded.wire() + encoded.size());
-
-  info.unsetKeyLocator();
-  BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
-  BOOST_CHECK_THROW(info.getKeyLocator(), SignatureInfo::Error);
+  info.setSignatureType(static_cast<tlv::SignatureTypeValue>(1234));
+  BOOST_CHECK_EQUAL(info.getSignatureType(), 1234);
+  BOOST_CHECK_EQUAL(info.hasWire(), false);
 }
 
-BOOST_AUTO_TEST_CASE(ValidityPeriodExtension)
+BOOST_AUTO_TEST_CASE(GetSetKeyLocator)
+{
+  SignatureInfo info(tlv::SignatureSha256WithEcdsa);
+  BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
+  BOOST_CHECK_THROW(info.getKeyLocator(), SignatureInfo::Error);
+
+  info.setKeyLocator(Name("/test/key/locator"));
+  BOOST_CHECK_EQUAL(info.hasKeyLocator(), true);
+  BOOST_CHECK_EQUAL(info.getKeyLocator().getName(), "/test/key/locator");
+  BOOST_CHECK_EQUAL(info.hasWire(), false);
+
+  info.wireEncode();
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
+  info.setKeyLocator(Name("/test/key/locator"));
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
+  info.setKeyLocator(Name("/another/key/locator"));
+  BOOST_CHECK_EQUAL(info.hasWire(), false);
+
+  info.wireEncode();
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
+  info.setKeyLocator(nullopt);
+  BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
+  BOOST_CHECK_THROW(info.getKeyLocator(), SignatureInfo::Error);
+  BOOST_CHECK_EQUAL(info.hasWire(), false);
+}
+
+BOOST_AUTO_TEST_CASE(ValidityPeriod)
 {
   const uint8_t sigInfo[] = {
     0x16, 0x45, // SignatureInfo
@@ -185,50 +202,61 @@
           0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30
   };
 
-  time::system_clock::TimePoint notBefore = time::getUnixEpoch();
-  time::system_clock::TimePoint notAfter = notBefore + 1_day;
+  const auto notBefore = time::getUnixEpoch();
+  const auto notAfter = notBefore + 1_day;
   security::ValidityPeriod vp1(notBefore, notAfter);
 
-  // encode
-  SignatureInfo info;
-  info.setSignatureType(tlv::SignatureSha256WithRsa);
-  info.setKeyLocator(KeyLocator("/test/key/locator"));
+  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);
 
-  const Block& encoded = info.wireEncode();
-
+  // encode
+  auto encoded = info.wireEncode();
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
   BOOST_CHECK_EQUAL_COLLECTIONS(sigInfo, sigInfo + sizeof(sigInfo),
                                 encoded.wire(), encoded.wire() + encoded.size());
 
+  info.setValidityPeriod(vp1);
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
+
   // decode
   Block block(sigInfo, sizeof(sigInfo));
-  SignatureInfo info2;
-  info2.wireDecode(block);
+  SignatureInfo info2(block);
+  BOOST_CHECK_EQUAL(info2.hasValidityPeriod(), true);
   BOOST_CHECK_EQUAL(info2.getValidityPeriod(), vp1);
+  BOOST_CHECK_EQUAL(info2.hasWire(), true);
 
-  const security::ValidityPeriod& validityPeriod = info2.getValidityPeriod();
-  BOOST_CHECK(validityPeriod.getPeriod() == std::make_pair(notBefore, notAfter));
+  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);
+
+  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)
 {
-  SignatureInfo info;
-  BOOST_CHECK_EQUAL(info.getSignatureType(), -1);
-  BOOST_CHECK_EQUAL(info.hasKeyLocator(), false);
-  BOOST_CHECK_THROW(info.getKeyLocator(), SignatureInfo::Error);
-
-  const uint8_t tlv1[] = {
-    0x81, // T
-    0x01, // L
-    0x01, // V
-  };
-  Block block1(tlv1, sizeof(tlv1));
-
-  info.appendTypeSpecificTlv(block1);
+  SignatureInfo info(tlv::SignatureSha256WithEcdsa);
+  info.appendTypeSpecificTlv("810101"_block);
   BOOST_CHECK_THROW(info.getTypeSpecificTlv(0x82), SignatureInfo::Error);
-  BOOST_REQUIRE_NO_THROW(info.getTypeSpecificTlv(0x81));
+  BOOST_CHECK_EQUAL(info.getTypeSpecificTlv(0x81).type(), 0x81);
+
+  info.wireEncode();
+  BOOST_CHECK_EQUAL(info.hasWire(), true);
+  info.appendTypeSpecificTlv("82020202"_block);
+  BOOST_CHECK_EQUAL(info.hasWire(), false);
 }
 
 BOOST_AUTO_TEST_CASE(OtherTlvsEncoding) // Bug #3914