security: string representation for SigningInfo

Change-Id: I92b227a0d0cb89654536043f703cea9e7b40fa64
refs: #3281
diff --git a/src/security/signing-info.cpp b/src/security/signing-info.cpp
index c231cc5..283484b 100644
--- a/src/security/signing-info.cpp
+++ b/src/security/signing-info.cpp
@@ -20,6 +20,7 @@
  */
 
 #include "signing-info.hpp"
+#include "key-chain.hpp"
 
 namespace ndn {
 namespace security {
@@ -37,6 +38,41 @@
 {
 }
 
+SigningInfo::SigningInfo(const std::string& signingStr)
+{
+  if (signingStr.empty()) {
+    *this = SigningInfo();
+    return;
+  }
+
+  size_t pos = signingStr.find(':');
+
+  if (pos == std::string::npos) {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid signing string cannot represent SigningInfo"));
+  }
+
+  std::string scheme = signingStr.substr(0, pos);
+  std::string nameArg = signingStr.substr(pos + 1);
+
+  if (scheme == "id") {
+    if (nameArg == KeyChain::DIGEST_SHA256_IDENTITY.toUri()) {
+      setSha256Signing();
+    }
+    else {
+      setSigningIdentity(nameArg);
+    }
+  }
+  else if (scheme == "key") {
+    setSigningKeyName(nameArg);
+  }
+  else if (scheme == "cert") {
+    setSigningCertName(nameArg);
+  }
+  else {
+    BOOST_THROW_EXCEPTION(std::invalid_argument("Invalid signing string scheme"));
+  }
+}
+
 void
 SigningInfo::setSigningIdentity(const Name& identity)
 {
@@ -70,5 +106,31 @@
   m_info = signatureInfo;
 }
 
-} // namespace ndn
+std::ostream&
+operator<<(std::ostream& os, const SigningInfo& si)
+{
+  switch (si.getSignerType()) {
+    case SigningInfo::SIGNER_TYPE_NULL:
+      return os;
+    case SigningInfo::SIGNER_TYPE_ID:
+      os << "id:";
+      break;
+    case SigningInfo::SIGNER_TYPE_KEY:
+      os << "key:";
+      break;
+    case SigningInfo::SIGNER_TYPE_CERT:
+      os << "cert:";
+      break;
+    case SigningInfo::SIGNER_TYPE_SHA256:
+      os << "id:" << KeyChain::DIGEST_SHA256_IDENTITY;
+      return os;
+    default:
+      BOOST_THROW_EXCEPTION(std::invalid_argument("Unknown signer type"));
+  }
+
+  os << si.getSignerName();
+  return os;
+}
+
 } // namespace security
+} // namespace ndn
diff --git a/src/security/signing-info.hpp b/src/security/signing-info.hpp
index 661276f..aaa2770 100644
--- a/src/security/signing-info.hpp
+++ b/src/security/signing-info.hpp
@@ -75,6 +75,21 @@
               const SignatureInfo& signatureInfo = EMPTY_SIGNATURE_INFO);
 
   /**
+   * @brief Construct SigningInfo from its string representation
+   *
+   * @param signingStr The representative signing string for SigningInfo signing method
+   *
+   * Structure of the representative string is as follows:
+   * - default signing: "" (empty string)
+   * - signing with a default certificate of a default key for the identity: `id:/my-identity`
+   * - signing with a default certificate of the key: `key:/my-identity/ksk-1`
+   * - signing with the certificate: `cert:/my-identity/KEY/ksk-1/ID-CERT/%FD%01`
+   * - signing with sha256 digest: `id:/localhost/identity/digest-sha256`
+   */
+  explicit
+  SigningInfo(const std::string& signingStr);
+
+  /**
    * @brief Set signer as an identity with name @p identity
    * @post Change the signerType to SIGNER_TYPE_ID
    */
@@ -166,6 +181,9 @@
   SignatureInfo m_info;
 };
 
+std::ostream&
+operator<<(std::ostream& os, const SigningInfo& si);
+
 } // namespace security
 } // namespace ndn