security: Allow Identity and Key abstractions to be used in SigningInfo

Change-Id: Ic1c8d6925557ea5da2011ab68f16587eef2102f3
Refs: #3153
diff --git a/src/security/signing-helpers.cpp b/src/security/signing-helpers.cpp
index 37de8dc..4011623 100644
--- a/src/security/signing-helpers.cpp
+++ b/src/security/signing-helpers.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -25,9 +25,15 @@
 namespace security {
 
 SigningInfo
-signingByIdentity(const Name& identity)
+signingByIdentity(const Name& identityName)
 {
-  return SigningInfo(SigningInfo::SIGNER_TYPE_ID, identity);
+  return SigningInfo(SigningInfo::SIGNER_TYPE_ID, identityName);
+}
+
+SigningInfo
+signingByIdentity(const Identity& identity)
+{
+  return SigningInfo(identity);
 }
 
 SigningInfo
@@ -37,16 +43,28 @@
 }
 
 SigningInfo
+signingByKey(const Key& key)
+{
+  return SigningInfo(key);
+}
+
+SigningInfo
 signingByCertificate(const Name& certName)
 {
   return SigningInfo(SigningInfo::SIGNER_TYPE_CERT, certName);
 }
 
 SigningInfo
+signingByCertificate(const v2::Certificate& cert)
+{
+  return SigningInfo(SigningInfo::SIGNER_TYPE_CERT, cert.getName());
+}
+
+SigningInfo
 signingWithSha256()
 {
   return SigningInfo(SigningInfo::SIGNER_TYPE_SHA256);
 }
 
 } // namespace security
-} // namespace ndn
\ No newline at end of file
+} // namespace ndn
diff --git a/src/security/signing-helpers.hpp b/src/security/signing-helpers.hpp
index 689eba6..8a01597 100644
--- a/src/security/signing-helpers.hpp
+++ b/src/security/signing-helpers.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -32,7 +32,13 @@
  * \return a SigningInfo for signing with an identity
  */
 SigningInfo
-signingByIdentity(const Name& identity);
+signingByIdentity(const Name& identityName);
+
+/**
+ * \return a SigningInfo for signing with an identity
+ */
+SigningInfo
+signingByIdentity(const Identity& identity);
 
 /**
  * \return a SigningInfo for signing with a key
@@ -41,12 +47,24 @@
 signingByKey(const Name& keyName);
 
 /**
+ * \return a SigningInfo for signing with a key
+ */
+SigningInfo
+signingByKey(const Key& key);
+
+/**
  * \return a SigningInfo for signing with a certificate
  */
 SigningInfo
 signingByCertificate(const Name& certName);
 
 /**
+ * \return a SigningInfo for signing with a certificate
+ */
+SigningInfo
+signingByCertificate(const v2::Certificate& cert);
+
+/**
  * \return a SigningInfo for signing with Sha256
  */
 SigningInfo
@@ -61,4 +79,4 @@
 
 } // namespace ndn
 
-#endif // NDN_CXX_SECURITY_SIGNING_HELPERS_HPP
\ No newline at end of file
+#endif // NDN_CXX_SECURITY_SIGNING_HELPERS_HPP
diff --git a/src/security/signing-info.cpp b/src/security/signing-info.cpp
index 48b278a..d02b0bd 100644
--- a/src/security/signing-info.cpp
+++ b/src/security/signing-info.cpp
@@ -53,6 +53,25 @@
   , m_digestAlgorithm(DigestAlgorithm::SHA256)
   , m_info(signatureInfo)
 {
+  BOOST_ASSERT(signerType == SIGNER_TYPE_NULL ||
+               signerType == SIGNER_TYPE_ID ||
+               signerType == SIGNER_TYPE_KEY ||
+               signerType == SIGNER_TYPE_CERT ||
+               signerType == SIGNER_TYPE_SHA256);
+}
+
+SigningInfo::SigningInfo(const Identity& identity)
+  : m_type(SIGNER_TYPE_PIB_ID)
+  , m_identity(identity)
+  , m_digestAlgorithm(DigestAlgorithm::SHA256)
+{
+}
+
+SigningInfo::SigningInfo(const Key& key)
+  : m_type(SIGNER_TYPE_PIB_KEY)
+  , m_key(key)
+  , m_digestAlgorithm(DigestAlgorithm::SHA256)
+{
 }
 
 SigningInfo::SigningInfo(const std::string& signingStr)
@@ -124,6 +143,24 @@
 }
 
 SigningInfo&
+SigningInfo::setPibIdentity(const Identity& identity)
+{
+  m_type = SIGNER_TYPE_PIB_ID;
+  m_name.clear();
+  m_identity = identity;
+  return *this;
+}
+
+SigningInfo&
+SigningInfo::setPibKey(const Key& key)
+{
+  m_type = SIGNER_TYPE_PIB_KEY;
+  m_name.clear();
+  m_key = key;
+  return *this;
+}
+
+SigningInfo&
 SigningInfo::setSignatureInfo(const SignatureInfo& signatureInfo)
 {
   m_info = signatureInfo;
@@ -137,22 +174,20 @@
     case SigningInfo::SIGNER_TYPE_NULL:
       return os;
     case SigningInfo::SIGNER_TYPE_ID:
-      os << "id:";
-      break;
+      return os << "id:" << si.getSignerName();
     case SigningInfo::SIGNER_TYPE_KEY:
-      os << "key:";
-      break;
+      return os << "key:" << si.getSignerName();
     case SigningInfo::SIGNER_TYPE_CERT:
-      os << "cert:";
-      break;
+      return os << "cert:" << si.getSignerName();
     case SigningInfo::SIGNER_TYPE_SHA256:
-      os << "id:" << SigningInfo::getDigestSha256Identity();
-      return os;
-    default:
-      BOOST_THROW_EXCEPTION(std::invalid_argument("Unknown signer type"));
+      return os << "id:" << SigningInfo::getDigestSha256Identity();
+    case SigningInfo::SIGNER_TYPE_PIB_ID:
+      return os << "id:" << si.getPibIdentity().getName();
+    case SigningInfo::SIGNER_TYPE_PIB_KEY:
+      return os << "key:" << si.getPibKey().getName();
   }
 
-  os << si.getSignerName();
+  BOOST_THROW_EXCEPTION(std::invalid_argument("Unknown signer type"));
   return os;
 }
 
diff --git a/src/security/signing-info.hpp b/src/security/signing-info.hpp
index 499f25b..6284644 100644
--- a/src/security/signing-info.hpp
+++ b/src/security/signing-info.hpp
@@ -24,6 +24,8 @@
 
 #include "../name.hpp"
 #include "../signature-info.hpp"
+#include "pib/identity.hpp"
+#include "pib/key.hpp"
 #include "security-common.hpp"
 
 
@@ -32,6 +34,9 @@
 
 /**
  * @brief Signing parameters passed to KeyChain
+ *
+ * A SigningInfo is invalid if the specified identity/key/certificate does not exist,
+ * or the PIB Identity or Key instance is not valid.
  */
 class SigningInfo
 {
@@ -56,7 +61,11 @@
     /// @brief signer is a certificate, use it directly
     SIGNER_TYPE_CERT = 3,
     /// @brief use sha256 digest, no signer needs to be specified
-    SIGNER_TYPE_SHA256 = 4
+    SIGNER_TYPE_SHA256 = 4,
+    /// @brief given PIB identity handle, use its default key and default certificate
+    SIGNER_TYPE_PIB_ID = 5,
+    /// @brief given PIB key handle, use its default certificate
+    SIGNER_TYPE_PIB_KEY = 6
   };
 
 public:
@@ -75,6 +84,18 @@
               const SignatureInfo& signatureInfo = getEmptySignatureInfo());
 
   /**
+   * @brief Create a signingInfo using pib identity;
+   */
+  explicit
+  SigningInfo(const Identity& identity);
+
+  /**
+   * @brief Create a signingInfo using pib key;
+   */
+  explicit
+  SigningInfo(const Key& key);
+
+  /**
    * @brief Construct SigningInfo from its string representation
    *
    * @param signingStr The representative signing string for SigningInfo signing method
@@ -118,6 +139,20 @@
   setSha256Signing();
 
   /**
+   * @brief Set signer as a PIB identity handler @p identity
+   * @post Change the signerType to SIGNER_TYPE_PIB_ID
+   */
+  SigningInfo&
+  setPibIdentity(const Identity& identity);
+
+  /**
+   * @brief Set signer as a PIB key handler @p key
+   * @post Change the signerType to SIGNER_TYPE_PIB_KEY
+   */
+  SigningInfo&
+  setPibKey(const Key& key);
+
+  /**
    * @return Type of the signer
    */
   SignerType
@@ -136,6 +171,28 @@
   }
 
   /**
+   * @pre signerType must be SIGNER_TYPE_PIB_ID
+   * @return the identity handler of signer
+   */
+  const Identity&
+  getPibIdentity() const
+  {
+    BOOST_ASSERT(m_type == SIGNER_TYPE_PIB_ID);
+    return m_identity;
+  }
+
+  /**
+   * @pre signerType must be SIGNER_TYPE_PIB_KEY
+   * @return the key handler of signer
+   */
+  const Key&
+  getPibKey() const
+  {
+    BOOST_ASSERT(m_type == SIGNER_TYPE_PIB_KEY);
+    return m_key;
+  }
+
+  /**
    * @brief Set the digest algorithm for public key operations
    */
   SigningInfo&
@@ -185,6 +242,8 @@
 private:
   SignerType m_type;
   Name m_name;
+  Identity m_identity;
+  Key m_key;
   DigestAlgorithm m_digestAlgorithm;
   SignatureInfo m_info;
 };
diff --git a/src/security/v2/key-chain.cpp b/src/security/v2/key-chain.cpp
index 0f3909e..d0fd486 100644
--- a/src/security/v2/key-chain.cpp
+++ b/src/security/v2/key-chain.cpp
@@ -643,6 +643,18 @@
       sigInfo.setSignatureType(tlv::DigestSha256);
       return std::make_tuple(SigningInfo::getDigestSha256Identity(), sigInfo);
     }
+    case SigningInfo::SIGNER_TYPE_PIB_ID: {
+      identity = params.getPibIdentity();
+      if (!identity)
+        BOOST_THROW_EXCEPTION(InvalidSigningInfoError("PIB Identity is invalid"));
+      break;
+    }
+    case SigningInfo::SIGNER_TYPE_PIB_KEY: {
+      key = params.getPibKey();
+      if (!key)
+        BOOST_THROW_EXCEPTION(InvalidSigningInfoError("PIB Key is invalid"));
+      break;
+    }
     default: {
       BOOST_THROW_EXCEPTION(InvalidSigningInfoError("Unrecognized signer type " +
                                                     boost::lexical_cast<std::string>(params.getSignerType())));
diff --git a/tests/unit-tests/security/signing-helpers.t.cpp b/tests/unit-tests/security/signing-helpers.t.cpp
index eeefcbc..0c608e7 100644
--- a/tests/unit-tests/security/signing-helpers.t.cpp
+++ b/tests/unit-tests/security/signing-helpers.t.cpp
@@ -30,6 +30,8 @@
 BOOST_AUTO_TEST_SUITE(Security)
 BOOST_AUTO_TEST_SUITE(TestSigningHelpers)
 
+// update of this test case deferred until the new IdentityManagementFixture is available
+
 BOOST_AUTO_TEST_CASE(Identity)
 {
   Name identity("/identity");
diff --git a/tests/unit-tests/security/signing-info.t.cpp b/tests/unit-tests/security/signing-info.t.cpp
index 5b63ae7..cfada95 100644
--- a/tests/unit-tests/security/signing-info.t.cpp
+++ b/tests/unit-tests/security/signing-info.t.cpp
@@ -158,6 +158,8 @@
     .setSigningIdentity("/identity")
     .setSigningKeyName("/key/name")
     .setSigningCertName("/cert/name")
+    .setPibIdentity(Identity())
+    .setPibKey(Key())
     .setSha256Signing()
     .setDigestAlgorithm(DigestAlgorithm::SHA256)
     .setSignatureInfo(SignatureInfo());
diff --git a/tests/unit-tests/security/v2/key-chain.t.cpp b/tests/unit-tests/security/v2/key-chain.t.cpp
index ddc020b..db14070 100644
--- a/tests/unit-tests/security/v2/key-chain.t.cpp
+++ b/tests/unit-tests/security/v2/key-chain.t.cpp
@@ -300,11 +300,18 @@
     SigningInfo(SigningInfo::SIGNER_TYPE_ID, id.getName()),
     signingByIdentity(id.getName()),
 
+    SigningInfo(id),
+    signingByIdentity(id),
+
     SigningInfo(SigningInfo::SIGNER_TYPE_KEY, key.getName()),
     signingByKey(key.getName()),
 
+    SigningInfo(key),
+    signingByKey(key),
+
     SigningInfo(SigningInfo::SIGNER_TYPE_CERT, cert.getName()),
     signingByCertificate(cert.getName()),
+    signingByCertificate(cert),
 
     SigningInfo(SigningInfo::SIGNER_TYPE_SHA256),
     signingWithSha256()