signature: deprecate Signature in favor of SignatureInfo

The Signature in Data packets and Certificates
has been deprecated in favor of separate objects
representing the Signature info and value.

Also deprecate type-specific Signature helpers.

refs #4804

Change-Id: Iab5b5c618e75cc11d31801d86a89a550a6add7a0
diff --git a/ndn-cxx/data.cpp b/ndn-cxx/data.cpp
index 1ba5f4f..ad49f32 100644
--- a/ndn-cxx/data.cpp
+++ b/ndn-cxx/data.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).
  *
@@ -58,14 +58,14 @@
 
   // SignatureValue
   if (!wantUnsignedPortionOnly) {
-    if (!m_signature) {
+    if (!m_signatureInfo) {
       NDN_THROW(Error("Requested wire format, but Data has not been signed"));
     }
-    totalLength += encoder.prependBlock(m_signature.getValue());
+    totalLength += encoder.prependBlock(m_signatureValue);
   }
 
   // SignatureInfo
-  totalLength += encoder.prependBlock(m_signature.getInfo());
+  totalLength += m_signatureInfo.wireEncode(encoder);
 
   // Content
   totalLength += encoder.prependBlock(getContent());
@@ -140,7 +140,8 @@
 
   m_metaInfo = MetaInfo();
   m_content = Block(tlv::Content);
-  m_signature = Signature();
+  m_signatureInfo = SignatureInfo();
+  m_signatureValue = Block();
   m_fullName.clear();
 
   for (++element; element != m_wire.elements_end(); ++element) {
@@ -165,7 +166,7 @@
         if (lastElement >= 4) {
           NDN_THROW(Error("SignatureInfo element is out of order"));
         }
-        m_signature.setInfo(*element);
+        m_signatureInfo.wireDecode(*element);
         lastElement = 4;
         break;
       }
@@ -173,7 +174,10 @@
         if (lastElement >= 5) {
           NDN_THROW(Error("SignatureValue element is out of order"));
         }
-        m_signature.setValue(*element);
+        if (element->type() != tlv::SignatureValue) {
+          NDN_THROW(Error("SignatureValue", element->type()));
+        }
+        m_signatureValue = *element;
         lastElement = 5;
         break;
       }
@@ -186,9 +190,13 @@
     }
   }
 
-  if (!m_signature) {
+  if (!m_signatureInfo) {
     NDN_THROW(Error("SignatureInfo element is missing"));
   }
+
+  if (m_signatureValue.empty()) {
+    NDN_THROW(Error("SignatureValue element is missing"));
+  }
 }
 
 const Name&
@@ -268,19 +276,37 @@
   return *this;
 }
 
+Signature
+Data::getSignature() const
+{
+  return Signature(m_signatureInfo, m_signatureValue);
+}
+
 Data&
 Data::setSignature(const Signature& signature)
 {
   resetWire();
-  m_signature = signature;
+  m_signatureInfo = signature.getSignatureInfo();
+  m_signatureValue = signature.getValue();
+  return *this;
+}
+
+Data&
+Data::setSignatureInfo(const SignatureInfo& info)
+{
+  resetWire();
+  m_signatureInfo = info;
   return *this;
 }
 
 Data&
 Data::setSignatureValue(const Block& value)
 {
+  if (value.type() != tlv::SignatureValue) {
+    NDN_THROW(Error("SignatureValue", value.type()));
+  }
   resetWire();
-  m_signature.setValue(value);
+  m_signatureValue = value;
   return *this;
 }
 
@@ -314,8 +340,8 @@
   return lhs.getName() == rhs.getName() &&
          lhs.getMetaInfo().wireEncode() == rhs.getMetaInfo().wireEncode() &&
          lhs.getContent() == rhs.getContent() &&
-         lhs.getSignature().getSignatureInfo() == rhs.getSignature().getSignatureInfo() &&
-         lhs.getSignature().getValue() == rhs.getSignature().getValue();
+         lhs.getSignatureInfo() == rhs.getSignatureInfo() &&
+         lhs.getSignatureValue() == rhs.getSignatureValue();
 }
 
 std::ostream&
@@ -324,8 +350,9 @@
   os << "Name: " << data.getName() << "\n";
   os << "MetaInfo: " << data.getMetaInfo() << "\n";
   os << "Content: (size: " << data.getContent().value_size() << ")\n";
-  os << "Signature: (type: " << data.getSignature().getType()
-     << ", value_length: "<< data.getSignature().getValue().value_size() << ")";
+  os << "Signature: (type: "
+     << static_cast<tlv::SignatureTypeValue>(data.getSignatureInfo().getSignatureType())
+     << ", value_length: "<< data.getSignatureValue().value_size() << ")";
   os << std::endl;
 
   return os;
diff --git a/ndn-cxx/data.hpp b/ndn-cxx/data.hpp
index d15b850..e4d72b6 100644
--- a/ndn-cxx/data.hpp
+++ b/ndn-cxx/data.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).
  *
@@ -180,19 +180,43 @@
   setContent(ConstBufferPtr value);
 
   /** @brief Get Signature
+   *  @deprecated Use getSignatureInfo and getSignatureValue
    */
-  const Signature&
-  getSignature() const
-  {
-    return m_signature;
-  }
+  [[deprecated("use getSignatureInfo and getSignatureValue")]]
+  Signature
+  getSignature() const;
 
   /** @brief Set Signature
+   *  @deprecated Use setSignatureInfo and setSignatureValue
    *  @return a reference to this Data, to allow chaining
    */
+  [[deprecated("use setSignatureInfo and setSignatureValue")]]
   Data&
   setSignature(const Signature& signature);
 
+  /** @brief Get SignatureInfo
+   */
+  const SignatureInfo&
+  getSignatureInfo() const
+  {
+    return m_signatureInfo;
+  }
+
+  /** @brief Set SignatureInfo
+   *  @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
+   */
+  Data&
+  setSignatureInfo(const SignatureInfo& info);
+
+  /** @brief Get SignatureValue
+   */
+  const Block&
+  getSignatureValue() const
+  {
+    return m_signatureValue;
+  }
+
   /** @brief Set SignatureValue
    *  @return a reference to this Data, to allow chaining
    */
@@ -238,7 +262,8 @@
   Name m_name;
   MetaInfo m_metaInfo;
   Block m_content;
-  Signature m_signature;
+  SignatureInfo m_signatureInfo;
+  Block m_signatureValue;
 
   mutable Block m_wire;
   mutable Name m_fullName; ///< cached FullName computed from m_wire
diff --git a/ndn-cxx/security/digest-sha256.hpp b/ndn-cxx/security/digest-sha256.hpp
index 5ed480c..3f2a2c7 100644
--- a/ndn-cxx/security/digest-sha256.hpp
+++ b/ndn-cxx/security/digest-sha256.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).
  *
@@ -27,11 +27,16 @@
 namespace ndn {
 
 /** @brief Represents a signature of DigestSha256 type
+ *  @deprecated Use SignatureInfo with type DigestSha256 instead
  *
  *  This signature type provides integrity protection using SHA-256 digest, but no provenance of a
  *  Data packet or any kind of guarantee that packet is from the original source.
  */
-class DigestSha256 : public Signature
+class
+#ifndef DOXYGEN // Older versions of doxygen can't parse deprecated decorators on classes
+[[deprecated("use SignatureInfo with type DigestSha256 instead")]]
+#endif // DOXYGEN
+DigestSha256 : public Signature
 {
 public:
   /** @brief Create empty DigestSha256 signature
diff --git a/ndn-cxx/security/signature-sha256-with-ecdsa.hpp b/ndn-cxx/security/signature-sha256-with-ecdsa.hpp
index 5428825..61f2d6d 100644
--- a/ndn-cxx/security/signature-sha256-with-ecdsa.hpp
+++ b/ndn-cxx/security/signature-sha256-with-ecdsa.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).
  *
@@ -27,11 +27,16 @@
 namespace ndn {
 
 /** @brief Represents a signature of Sha256WithEcdsa type
+ *  @deprecated Use SignatureInfo with type SignatureSha256WithEcdsa instead
  *
  *  This signature type provides integrity and provenance protection using an ECDSA signature over a
  *  SHA-256 digest.
  */
-class SignatureSha256WithEcdsa : public Signature
+class
+#ifndef DOXYGEN // Older versions of doxygen can't parse deprecated decorators on classes
+[[deprecated("use SignatureInfo with type SignatureSha256WithRsa instead")]]
+#endif // DOXYGEN
+SignatureSha256WithEcdsa : public Signature
 {
 public:
   /** @brief Create Sha256WithEcdsa signature with specified KeyLocator
diff --git a/ndn-cxx/security/signature-sha256-with-rsa.hpp b/ndn-cxx/security/signature-sha256-with-rsa.hpp
index da79292..3064119 100644
--- a/ndn-cxx/security/signature-sha256-with-rsa.hpp
+++ b/ndn-cxx/security/signature-sha256-with-rsa.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).
  *
@@ -27,11 +27,16 @@
 namespace ndn {
 
 /** @brief Represents a signature of Sha256WithRsa type
+ *  @deprecated Use SignatureInfo with type SignatureSha256WithRsa instead
  *
  *  This signature type provides integrity and provenance protection using a RSA signature over a
  *  SHA-256 digest.
  */
-class SignatureSha256WithRsa : public Signature
+class
+#ifndef DOXYGEN // Older versions of doxygen can't parse deprecated decorators on classes
+[[deprecated("use SignatureInfo with type SignatureSha256WithRsa instead")]]
+#endif // DOXYGEN
+SignatureSha256WithRsa : public Signature
 {
 public:
   /** @brief Create Sha256WithRsa signature with specified KeyLocator
diff --git a/ndn-cxx/security/v2/certificate.cpp b/ndn-cxx/security/v2/certificate.cpp
index 83e1656..489a793 100644
--- a/ndn-cxx/security/v2/certificate.cpp
+++ b/ndn-cxx/security/v2/certificate.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).
  *
@@ -112,19 +112,19 @@
 ValidityPeriod
 Certificate::getValidityPeriod() const
 {
-  return getSignature().getSignatureInfo().getValidityPeriod();
+  return getSignatureInfo().getValidityPeriod();
 }
 
 bool
 Certificate::isValid(const time::system_clock::TimePoint& ts) const
 {
-  return getSignature().getSignatureInfo().getValidityPeriod().isValid(ts);
+  return getSignatureInfo().getValidityPeriod().isValid(ts);
 }
 
 const Block&
 Certificate::getExtension(uint32_t type) const
 {
-  return getSignature().getSignatureInfo().getTypeSpecificTlv(type);
+  return getSignatureInfo().getTypeSpecificTlv(type);
 }
 
 bool
@@ -147,7 +147,7 @@
   }
 
   try {
-    const Block& info = cert.getSignature().getSignatureInfo().getTypeSpecificTlv(tlv::AdditionalDescription);
+    const Block& info = cert.getSignatureInfo().getTypeSpecificTlv(tlv::AdditionalDescription);
     os << "Additional Description:\n";
     for (const auto& item : v2::AdditionalDescription(info)) {
       os << "  " << item.first << ": " << item.second << "\n";
@@ -166,11 +166,12 @@
 
   os << "Signature Information:\n";
   {
-    os << "  Signature Type: " << cert.getSignature().getType() << "\n";
+    os << "  Signature Type: "
+       << static_cast<tlv::SignatureTypeValue>(cert.getSignatureInfo().getSignatureType()) << "\n";
 
-    if (cert.getSignature().hasKeyLocator()) {
+    if (cert.getSignatureInfo().hasKeyLocator()) {
       os << "  Key Locator: ";
-      const auto& keyLocator = cert.getSignature().getKeyLocator();
+      const auto& keyLocator = cert.getSignatureInfo().getKeyLocator();
       if (keyLocator.getType() == tlv::Name && keyLocator.getName() == cert.getKeyName()) {
         os << "Self-Signed ";
       }
diff --git a/ndn-cxx/security/v2/key-chain.cpp b/ndn-cxx/security/v2/key-chain.cpp
index 63f1d98..255f310 100644
--- a/ndn-cxx/security/v2/key-chain.cpp
+++ b/ndn-cxx/security/v2/key-chain.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).
  *
@@ -453,7 +453,7 @@
   SignatureInfo sigInfo;
   std::tie(keyName, sigInfo) = prepareSignatureInfo(params);
 
-  data.setSignature(Signature(sigInfo));
+  data.setSignatureInfo(sigInfo);
 
   EncodingBuffer encoder;
   data.wireEncode(encoder, true);
diff --git a/ndn-cxx/security/v2/validation-policy.cpp b/ndn-cxx/security/v2/validation-policy.cpp
index 23a63e2..28396d1 100644
--- a/ndn-cxx/security/v2/validation-policy.cpp
+++ b/ndn-cxx/security/v2/validation-policy.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).
  *
@@ -84,7 +84,7 @@
 Name
 getKeyLocatorName(const Data& data, ValidationState& state)
 {
-  return getKeyLocatorName(data.getSignature().getSignatureInfo(), state);
+  return getKeyLocatorName(data.getSignatureInfo(), state);
 }
 
 Name
diff --git a/ndn-cxx/security/verification-helpers.cpp b/ndn-cxx/security/verification-helpers.cpp
index cbca64f..cb79ac9 100644
--- a/ndn-cxx/security/verification-helpers.cpp
+++ b/ndn-cxx/security/verification-helpers.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).
  *
@@ -89,9 +89,9 @@
   try {
     return {true,
             data.wireEncode().value(),
-            data.wireEncode().value_size() - data.getSignature().getValue().size(),
-            data.getSignature().getValue().value(),
-            data.getSignature().getValue().value_size()};
+            data.wireEncode().value_size() - data.getSignatureValue().size(),
+            data.getSignatureValue().value(),
+            data.getSignatureValue().value_size()};
   }
   catch (const tlv::Error&) {
     return ParseResult();
diff --git a/ndn-cxx/signature-info.hpp b/ndn-cxx/signature-info.hpp
index 7cfc248..525f116 100644
--- a/ndn-cxx/signature-info.hpp
+++ b/ndn-cxx/signature-info.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).
  *
@@ -59,6 +59,14 @@
   explicit
   SignatureInfo(const Block& wire);
 
+  /** @brief Determine whether SignatureInfo is valid
+   */
+  explicit
+  operator bool() const
+  {
+    return m_type != -1;
+  }
+
   /** @brief Fast encoding or block size estimation
    *  @param encoder EncodingEstimator or EncodingBuffer instance
    */
diff --git a/ndn-cxx/signature.hpp b/ndn-cxx/signature.hpp
index 1c02c60..a0fc84e 100644
--- a/ndn-cxx/signature.hpp
+++ b/ndn-cxx/signature.hpp
@@ -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).
  *
@@ -27,6 +27,7 @@
 namespace ndn {
 
 /** @brief Holds SignatureInfo and SignatureValue in a Data packet
+ *  @deprecated Use Data::get/setSignatureInfo and Data::get/setSignatureValue directly
  *
  *  A Signature is not a TLV element itself. It collects SignatureInfo and SignatureValue TLV
  *  elements together for easy access.
@@ -34,7 +35,11 @@
  *  SignatureSha256WithRsa , or @p SignatureSha256WithEcdsa instead of using @p Signature type
  *  directly.
  */
-class Signature
+class
+#ifndef DOXYGEN // Older versions of doxygen can't parse deprecated decorators on classes
+[[deprecated("use Data::get/setSignatureInfo and Data::get/setSignatureValue directly")]]
+#endif // DOXYGEN
+Signature
 {
 public:
   class Error : public tlv::Error
diff --git a/tests/make-interest-data.cpp b/tests/make-interest-data.cpp
index 09d879b..c6e3a4c 100644
--- a/tests/make-interest-data.cpp
+++ b/tests/make-interest-data.cpp
@@ -46,9 +46,8 @@
 Data&
 signData(Data& data)
 {
-  ndn::SignatureSha256WithRsa fakeSignature;
-  fakeSignature.setValue(ndn::encoding::makeEmptyBlock(tlv::SignatureValue));
-  data.setSignature(fakeSignature);
+  data.setSignatureInfo(SignatureInfo(tlv::SignatureSha256WithRsa));
+  data.setSignatureValue(encoding::makeEmptyBlock(tlv::SignatureValue));
   data.wireEncode();
   return data;
 }
diff --git a/tests/unit/data.t.cpp b/tests/unit/data.t.cpp
index 56ca775..041ddc0 100644
--- a/tests/unit/data.t.cpp
+++ b/tests/unit/data.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).
  *
@@ -89,7 +89,7 @@
   BOOST_CHECK(!d.getFinalBlock());
   BOOST_CHECK_EQUAL(d.getContent().type(), tlv::Content);
   BOOST_CHECK_EQUAL(d.getContent().value_size(), 0);
-  BOOST_CHECK(!d.getSignature());
+  BOOST_CHECK(!d.getSignatureInfo());
 }
 
 class DataSigningKeyFixture
@@ -195,8 +195,8 @@
   os.write(buf->get<char>(), buf->size());
 
   Block signatureValue(os.buf());
-  Signature signature(signatureInfo, signatureValue);
-  d.setSignature(signature);
+  d.setSignatureInfo(SignatureInfo(signatureInfo));
+  d.setSignatureValue(signatureValue);
 
   Block dataBlock(d.wireEncode());
   BOOST_CHECK_EQUAL_COLLECTIONS(DATA1, DATA1 + sizeof(DATA1),
@@ -213,9 +213,9 @@
   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.getSignature().getType(), tlv::SignatureSha256WithRsa);
+  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::SignatureSha256WithRsa);
 
-  Block block = d.getSignature().getInfo();
+  Block block = d.getSignatureInfo().wireEncode();
   block.parse();
   KeyLocator keyLocator(block.get(tlv::KeyLocator));
   BOOST_CHECK_EQUAL(keyLocator.getName().toUri(), "/test/key/locator");
@@ -232,11 +232,11 @@
     d.setName("/A");
     d.setContentType(tlv::ContentType_Key);
     d.setContent("1504C0C1C2C3"_block);
-    d.setSignature(Signature("160A 1B0101 1C050703080142"_block,
-                   "1780 B48F1707A3BCA3CFC5F32DE51D9B46C32D7D262A21544EBDA88C3B415D637503"
-                        "FC9BEF20F88202A56AF9831E0D30205FD4154B08502BCDEE860267A5C3E03D8E"
-                        "A6CB74BE391C01E0A57B991B4404FC11B7D777F1B700A4B65F201118CF1840A8"
-                        "30A2A7C17DB4B7A8777E58515121AF9E2498627F8475414CDFD9801B8152AD5B"_block));
+    d.setSignatureInfo(SignatureInfo("160A 1B0101 1C050703080142"_block));
+    d.setSignatureValue("1780 B48F1707A3BCA3CFC5F32DE51D9B46C32D7D262A21544EBDA88C3B415D637503"
+                             "FC9BEF20F88202A56AF9831E0D30205FD4154B08502BCDEE860267A5C3E03D8E"
+                             "A6CB74BE391C01E0A57B991B4404FC11B7D777F1B700A4B65F201118CF1840A8"
+                             "30A2A7C17DB4B7A8777E58515121AF9E2498627F8475414CDFD9801B8152AD5B"_block);
   }
 
 protected:
@@ -245,18 +245,6 @@
 
 BOOST_FIXTURE_TEST_SUITE(Decode03, Decode03Fixture)
 
-BOOST_AUTO_TEST_CASE(MinimalNoSigValue)
-{
-  d.wireDecode("0607 0700 16031B0100"_block);
-  BOOST_CHECK_EQUAL(d.getName(), "/"); // empty Name is allowed in Data
-  BOOST_CHECK_EQUAL(d.getContentType(), tlv::ContentType_Blob);
-  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.getSignature().getType(), tlv::DigestSha256);
-  BOOST_CHECK_EQUAL(d.getSignature().getValue().value_size(), 0);
-}
-
 BOOST_AUTO_TEST_CASE(Minimal)
 {
   d.wireDecode("062C 0703080144 16031B0100 "
@@ -266,8 +254,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.getSignature().getType(), tlv::DigestSha256);
-  BOOST_CHECK_EQUAL(d.getSignature().getValue().value_size(), 32);
+  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 32);
 
   // encode without modification: retain original wire encoding
   BOOST_CHECK_EQUAL(d.wireEncode().value_size(), 44);
@@ -279,6 +267,18 @@
     "1720612A79399E60304A9F701C1ECAC7956BF2F1B046E6C6F0D6C29B3FE3A29BAD76"_block);
 }
 
+BOOST_AUTO_TEST_CASE(MinimalEmptyName)
+{
+  d.wireDecode("0609 0700 16031B0100 1700"_block);
+  BOOST_CHECK_EQUAL(d.getName(), "/"); // empty Name is allowed in Data
+  BOOST_CHECK_EQUAL(d.getContentType(), tlv::ContentType_Blob);
+  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.getSignatureValue().value_size(), 0);
+}
+
 BOOST_AUTO_TEST_CASE(Full)
 {
   d.wireDecode("063A 0703080144 FC00 1400 FC00 1500 FC00 16031B0100 FC00 "
@@ -288,8 +288,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.getSignature().getType(), tlv::DigestSha256);
-  BOOST_CHECK_EQUAL(d.getSignature().getValue().value_size(), 32);
+  BOOST_CHECK_EQUAL(d.getSignatureInfo().getSignatureType(), tlv::DigestSha256);
+  BOOST_CHECK_EQUAL(d.getSignatureValue().value_size(), 32);
 
   // encode without modification: retain original wire encoding
   BOOST_CHECK_EQUAL(d.wireEncode().value_size(), 58);
@@ -328,12 +328,17 @@
 
 BOOST_AUTO_TEST_CASE(NameMissing)
 {
-  BOOST_CHECK_THROW(d.wireDecode("0605 16031B0100"_block), tlv::Error);
+  BOOST_CHECK_THROW(d.wireDecode("0605 16031B0100 1700"_block), tlv::Error);
 }
 
 BOOST_AUTO_TEST_CASE(SigInfoMissing)
 {
-  BOOST_CHECK_THROW(d.wireDecode("0605 0703080144"_block), tlv::Error);
+  BOOST_CHECK_THROW(d.wireDecode("0605 0703080144 1700"_block), tlv::Error);
+}
+
+BOOST_AUTO_TEST_CASE(SigValueMissing)
+{
+  BOOST_CHECK_THROW(d.wireDecode("0607 0700 16031B0100"_block), tlv::Error);
 }
 
 BOOST_AUTO_TEST_CASE(UnrecognizedNonCriticalElementBeforeName)
@@ -419,11 +424,11 @@
   BOOST_CHECK_EQUAL(a == b, true);
   BOOST_CHECK_EQUAL(a != b, false);
 
-  a.setSignature(SignatureSha256WithRsa());
+  a.setSignatureInfo(SignatureInfo(tlv::SignatureSha256WithRsa));
   BOOST_CHECK_EQUAL(a == b, false);
   BOOST_CHECK_EQUAL(a != b, true);
 
-  b.setSignature(SignatureSha256WithRsa());
+  b.setSignatureInfo(SignatureInfo(tlv::SignatureSha256WithRsa));
   BOOST_CHECK_EQUAL(a == b, true);
   BOOST_CHECK_EQUAL(a != b, false);
 }
diff --git a/tests/unit/lp/packet.t.cpp b/tests/unit/lp/packet.t.cpp
index 30c8bae..c189641 100644
--- a/tests/unit/lp/packet.t.cpp
+++ b/tests/unit/lp/packet.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).
  *
@@ -432,9 +432,8 @@
 {
   // Construct Data which prefix announcement is attached to
   Data data0("/edu/ua/cs/news/index.html");
-  ndn::SignatureSha256WithRsa fakeSignature;
-  fakeSignature.setValue(ndn::encoding::makeEmptyBlock(ndn::tlv::SignatureValue));
-  data0.setSignature(fakeSignature);
+  data0.setSignatureInfo(SignatureInfo(ndn::tlv::SignatureSha256WithRsa));
+  data0.setSignatureValue(encoding::makeEmptyBlock(ndn::tlv::SignatureValue));
 
   Block wire;
   wire = data0.wireEncode();
diff --git a/tests/unit/security/digest-sha256.t.cpp b/tests/unit/security/digest-sha256.t.cpp
index d3fcf4a..8b5e11d 100644
--- a/tests/unit/security/digest-sha256.t.cpp
+++ b/tests/unit/security/digest-sha256.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).
  *
@@ -53,7 +53,7 @@
   testData.setContent(reinterpret_cast<uint8_t*>(content), 5);
   m_keyChain.sign(testData, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
 
-  BOOST_CHECK_THROW(testData.getSignature().getKeyLocator(), ndn::SignatureInfo::Error);
+  BOOST_CHECK_THROW(testData.getSignatureInfo().getKeyLocator(), ndn::SignatureInfo::Error);
   verifyDigest(testData, DigestAlgorithm::SHA256);
 }
 
diff --git a/tests/unit/security/pib/pib-data-fixture.cpp b/tests/unit/security/pib/pib-data-fixture.cpp
index d2ddd10..0d12fd5 100644
--- a/tests/unit/security/pib/pib-data-fixture.cpp
+++ b/tests/unit/security/pib/pib-data-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).
  *
@@ -60,7 +60,7 @@
 //         info.setKeyLocator(KeyLocator(keyName));
 //         info.setValidityPeriod(ValidityPeriod(time::fromIsoString("20170102T000000"),
 //                                               time::fromIsoString("20180102T000000")));
-//         cert.setSignature(Signature(info, Block()));
+//         cert.setSignatureInfo(info);
 
 //         EncodingBuffer buf;
 //         cert.wireEncode(buf, true);
diff --git a/tests/unit/security/pib/pib-impl.t.cpp b/tests/unit/security/pib/pib-impl.t.cpp
index 500e5fd..7b13306 100644
--- a/tests/unit/security/pib/pib-impl.t.cpp
+++ b/tests/unit/security/pib/pib-impl.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).
  *
@@ -331,7 +331,8 @@
   // Create a fake cert with the same name
   auto cert2 = this->id1Key2Cert1;
   cert2.setName(this->id1Key1Cert1.getName());
-  cert2.setSignature(this->id1Key2Cert1.getSignature());
+  cert2.setSignatureInfo(this->id1Key2Cert1.getSignatureInfo());
+  cert2.setSignatureValue(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 9d04b6d..dc1d8b5 100644
--- a/tests/unit/security/v2/certificate.t.cpp
+++ b/tests/unit/security/v2/certificate.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).
  *
@@ -127,24 +127,16 @@
       0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 };
 
-Signature
-generateFakeSignature()
+static void
+generateFakeSignature(Data& data)
 {
-  Block block1(SIG_INFO, sizeof(SIG_INFO));
-  SignatureInfo signatureInfo(block1);
+  SignatureInfo signatureInfo(Block(SIG_INFO, sizeof(SIG_INFO)));
+  signatureInfo.setKeyLocator(KeyLocator(Name("/ndn/site1/KEY/ksk-2516425377094")));
+  signatureInfo.setValidityPeriod(ValidityPeriod(time::fromIsoString("20141111T050000"),
+                                                 time::fromIsoString("20141111T060000")));
 
-  Name keyLocatorName("/ndn/site1/KEY/ksk-2516425377094");
-  KeyLocator keyLocator(keyLocatorName);
-  signatureInfo.setKeyLocator(keyLocator);
-
-  ValidityPeriod period(time::fromIsoString("20141111T050000"), time::fromIsoString("20141111T060000"));
-  signatureInfo.setValidityPeriod(period);
-
-  Signature signature(signatureInfo);
-  Block block2(SIG_VALUE, sizeof(SIG_VALUE));
-  signature.setValue(block2);
-
-  return signature;
+  data.setSignatureInfo(signatureInfo);
+  data.setSignatureValue(Block(SIG_VALUE, sizeof(SIG_VALUE)));
 }
 
 BOOST_AUTO_TEST_CASE(Construction)
@@ -157,7 +149,7 @@
   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.getSignature().getKeyLocator().getName(), "/ndn/site1/KEY/ksk-2516425377094");
+  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_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
@@ -174,14 +166,14 @@
   certificate.setName("/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
   certificate.setFreshnessPeriod(1_h);
   certificate.setContent(PUBLIC_KEY, sizeof(PUBLIC_KEY));
-  certificate.setSignature(generateFakeSignature());
+  generateFakeSignature(certificate);
 
   BOOST_CHECK_EQUAL(certificate.getName(), "/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
   BOOST_CHECK_EQUAL(certificate.getKeyName(), "/ndn/site1/KEY/ksk-1416425377094");
   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.getSignature().getKeyLocator().getName(), "/ndn/site1/KEY/ksk-2516425377094");
+  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_CHECK_THROW(certificate.getExtension(12345), ndn::SignatureInfo::Error);
@@ -194,7 +186,7 @@
   certificate.setName("/ndn/site1/KEY/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
   certificate.setFreshnessPeriod(1_h);
   certificate.setContent(PUBLIC_KEY, sizeof(PUBLIC_KEY));
-  certificate.setSignature(generateFakeSignature());
+  generateFakeSignature(certificate);
 
   BOOST_CHECK_EQUAL(certificate.isValid(), true);
   BOOST_CHECK_EQUAL(certificate.isValid(time::fromIsoString("20141111T045959")), false);
@@ -213,7 +205,7 @@
     BOOST_CHECK_NO_THROW((Certificate(certBase)));
 
     m_certBase = Data(certBase);
-    m_certBase.setSignature(generateFakeSignature());
+    generateFakeSignature(m_certBase);
 
     BOOST_CHECK_NO_THROW((Certificate(m_certBase)));
   }
@@ -226,7 +218,7 @@
 {
   Data data(m_certBase);
   data.setName("/ndn/site1/ksk-1416425377094/0123/%FD%00%00%01I%C9%8B");
-  data.setSignature(generateFakeSignature());
+  generateFakeSignature(data);
 
   BOOST_CHECK_THROW((Certificate(data)), Certificate::Error);
   BOOST_CHECK_THROW((Certificate(std::move(data))), Certificate::Error);
@@ -236,7 +228,7 @@
 {
   Data data(m_certBase);
   data.setContentType(tlv::ContentType_Blob);
-  data.setSignature(generateFakeSignature());
+  generateFakeSignature(data);
 
   BOOST_CHECK_THROW((Certificate(data)), Certificate::Error);
   BOOST_CHECK_THROW((Certificate(std::move(data))), Certificate::Error);
@@ -246,14 +238,14 @@
 {
   Data data(m_certBase);
   data.setContent(nullptr, 0);
-  data.setSignature(generateFakeSignature());
+  generateFakeSignature(data);
 
   BOOST_CHECK_THROW((Certificate(data)), Certificate::Error);
   BOOST_CHECK_THROW((Certificate(std::move(data))), Certificate::Error);
 
   Certificate cert(m_certBase);
   cert.setContent(nullptr, 0);
-  cert.setSignature(generateFakeSignature());
+  generateFakeSignature(cert);
   BOOST_CHECK_THROW(cert.getPublicKey(), Certificate::Error);
 }
 
diff --git a/tests/unit/security/v2/key-chain.t.cpp b/tests/unit/security/v2/key-chain.t.cpp
index 1d25e59..b065fb2 100644
--- a/tests/unit/security/v2/key-chain.t.cpp
+++ b/tests/unit/security/v2/key-chain.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).
  *
@@ -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.getSignature().getType(), tlv::DigestSha256);
+      BOOST_CHECK_EQUAL(data.getSignatureInfo().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.getSignature().getType(), tlv::SignatureHmacWithSha256);
+      BOOST_CHECK_EQUAL(data.getSignatureInfo().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.getSignature().getType(), tlv::SignatureSha256WithEcdsa);
+      BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(), tlv::SignatureSha256WithEcdsa);
       BOOST_CHECK_EQUAL(interestSignature.getType(), tlv::SignatureSha256WithEcdsa);
 
-      BOOST_CHECK_EQUAL(data.getSignature().getKeyLocator().getName(), cert.getName().getPrefix(-2));
+      BOOST_CHECK_EQUAL(data.getSignatureInfo().getKeyLocator().getName(), cert.getName().getPrefix(-2));
       BOOST_CHECK_EQUAL(interestSignature.getKeyLocator().getName(), cert.getName().getPrefix(-2));
 
       BOOST_CHECK(verifySignature(data, key));
@@ -392,16 +392,16 @@
   // 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.getSignature().getType(),
+  BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(),
                     KeyChain::getSignatureType(EcKeyParams().getKeyType(), DigestAlgorithm::SHA256));
-  BOOST_CHECK(id.getName().isPrefixOf(data.getSignature().getKeyLocator().getName()));
+  BOOST_CHECK(id.getName().isPrefixOf(data.getSignatureInfo().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.getSignature().getType(),
+  BOOST_CHECK_EQUAL(data.getSignatureInfo().getSignatureType(),
                     KeyChain::getSignatureType(RsaKeyParams().getKeyType(), DigestAlgorithm::SHA256));
-  BOOST_CHECK(id.getName().isPrefixOf(data.getSignature().getKeyLocator().getName()));
+  BOOST_CHECK(id.getName().isPrefixOf(data.getSignatureInfo().getKeyLocator().getName()));
 }
 
 BOOST_FIXTURE_TEST_CASE(ImportPrivateKey, IdentityManagementFixture)