security: Porting security elements to the updated framework

Change-Id: Ie9ad6ee34f94fc520b9d3c8adf871e2557eaa9b6
diff --git a/include/ndn-cpp/security/certificate/certificate.hpp b/include/ndn-cpp/security/certificate/certificate.hpp
index 0c7323b..c2fd95a 100644
--- a/include/ndn-cpp/security/certificate/certificate.hpp
+++ b/include/ndn-cpp/security/certificate/certificate.hpp
@@ -18,11 +18,13 @@
 
 namespace ndn {
 
-typedef std::vector<CertificateSubjectDescription> SubjectDescriptionList;
-typedef std::vector<CertificateExtension> ExtensionList;
-
 class Certificate : public Data {
 public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  typedef std::vector<CertificateSubjectDescription> SubjectDescriptionList;
+  typedef std::vector<CertificateExtension> ExtensionList;
+
   /**
    * The default constructor.
    */
@@ -40,6 +42,9 @@
   virtual 
   ~Certificate();
 
+  inline void
+  wireDecode(const Block &wire);
+  
   /**
    * encode certificate info into content
    */
@@ -117,7 +122,7 @@
   isTooLate();
 
   void 
-  printCertificate();
+  printCertificate(std::ostream &os) const;
 
 protected:
   void
@@ -131,6 +136,21 @@
   ExtensionList extensionList_;
 };
 
+inline void
+Certificate::wireDecode(const Block &wire)
+{
+  Data::wireDecode(wire);
+  decode();
 }
 
+
+inline std::ostream&
+operator <<(std::ostream &os, const Certificate &cert)
+{
+  cert.printCertificate(os);
+  return os;
+}
+
+} // namespace ndn
+
 #endif
diff --git a/include/ndn-cpp/security/certificate/identity-certificate.hpp b/include/ndn-cpp/security/certificate/identity-certificate.hpp
index 4d3a9db..85c8e72 100644
--- a/include/ndn-cpp/security/certificate/identity-certificate.hpp
+++ b/include/ndn-cpp/security/certificate/identity-certificate.hpp
@@ -16,12 +16,13 @@
 class IdentityCertificate : public Certificate
 {
 public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
   /**
    * The default constructor.
    */
-  IdentityCertificate()
-  {
-  }
+  inline
+  IdentityCertificate();
 
   // Note: The copy constructor works because publicKeyName_ has a copy constructor.
 
@@ -29,29 +30,20 @@
    * Create an IdentityCertificate from the content in the data packet.
    * @param data The data packet with the content to decode.
    */
+  inline
   IdentityCertificate(const Data& data);
   
   /**
-   * The copy constructor. 
-   */
-  IdentityCertificate(const IdentityCertificate& identityCertificate);
-  
-  /**
    * The virtual destructor.
    */
-  virtual 
+  inline virtual 
   ~IdentityCertificate();
   
-  /**
-   * Override the base class method to check that the name is a valid identity certificate name.
-   * @param name The identity certificate name which is copied.
-   * @return This Data so that you can chain calls to update values.
-   */
-  virtual Data &
-  setName(const Name& name);
-
-  Name 
-  getPublicKeyName () const { return publicKeyName_; }
+  inline void
+  wireDecode(const Block &wire);
+  
+  inline const Name &
+  getPublicKeyName () const;
 
   static bool
   isIdentityCertificate(const Certificate& certificate);
@@ -75,6 +67,36 @@
   Name publicKeyName_;
 };
 
+inline
+IdentityCertificate::IdentityCertificate()
+{
+}
+
+inline
+IdentityCertificate::IdentityCertificate(const Data& data)
+  : Certificate(data)
+{
+  setPublicKeyName();
+}
+  
+inline
+IdentityCertificate::~IdentityCertificate()
+{
+}
+
+inline void
+IdentityCertificate::wireDecode(const Block &wire)
+{
+  Certificate::wireDecode(wire);
+  setPublicKeyName();
+}
+
+inline const Name &
+IdentityCertificate::getPublicKeyName () const
+{
+  return publicKeyName_;
+}
+
 }
 
 #endif
diff --git a/include/ndn-cpp/security/certificate/public-key.hpp b/include/ndn-cpp/security/certificate/public-key.hpp
index 43e1223..1fac1ec 100644
--- a/include/ndn-cpp/security/certificate/public-key.hpp
+++ b/include/ndn-cpp/security/certificate/public-key.hpp
@@ -33,13 +33,13 @@
    */
   PublicKey(const uint8_t *keyDerBuf, size_t keyDerSize);
 
-  const Buffer&
+  inline const Buffer&
   get() const
   {
     return key_;
   }
 
-  void
+  inline void
   set(const uint8_t *keyDerBuf, size_t keyDerSize)
   {
     Buffer buf(keyDerBuf, keyDerSize);
@@ -59,6 +59,18 @@
   // Blob 
   // getDigest(DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) const;
 
+  inline bool
+  operator ==(const PublicKey &key) const
+  {
+    return key_ == key.key_;
+  }
+
+  inline bool
+  operator !=(const PublicKey &key) const
+  {
+    return key_ != key.key_;
+  }
+  
 private:
   Buffer key_;
 };
diff --git a/include/ndn-cpp/security/identity/basic-identity-storage.hpp b/include/ndn-cpp/security/identity/basic-identity-storage.hpp
index 4954f01..0dc3e5d 100644
--- a/include/ndn-cpp/security/identity/basic-identity-storage.hpp
+++ b/include/ndn-cpp/security/identity/basic-identity-storage.hpp
@@ -26,6 +26,8 @@
  */
 class BasicIdentityStorage : public IdentityStorage {
 public:
+  struct Error : public IdentityStorage::Error { Error(const std::string &what) : IdentityStorage::Error(what) {} };
+
   BasicIdentityStorage();
   
   /**
@@ -34,6 +36,7 @@
   virtual 
   ~BasicIdentityStorage();
 
+  // from IdentityStorage
   /**
    * Check if the specified identity already exists.
    * @param identityName The identity name.
@@ -71,14 +74,14 @@
    * @param publicKeyDer A blob of the public key DER to be added.
    */
   virtual void 
-  addKey(const Name& keyName, KeyType keyType, const Blob& publicKeyDer);
+  addKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer);
 
   /**
    * Get the public key DER blob from the identity storage.
    * @param keyName The name of the requested public key.
    * @return The DER Blob.  If not found, return a Blob with a null pointer.
    */
-  virtual Blob
+  virtual ptr_lib::shared_ptr<PublicKey>
   getKey(const Name& keyName);
 
   /**
@@ -123,7 +126,7 @@
    * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
    * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
    */
-  virtual ptr_lib::shared_ptr<Data> 
+  virtual ptr_lib::shared_ptr<IdentityCertificate> 
   getCertificate(const Name &certificateName, bool allowAny = false);
 
 
diff --git a/include/ndn-cpp/security/identity/identity-manager.hpp b/include/ndn-cpp/security/identity/identity-manager.hpp
index 4273f6b..702ad1f 100644
--- a/include/ndn-cpp/security/identity/identity-manager.hpp
+++ b/include/ndn-cpp/security/identity/identity-manager.hpp
@@ -11,6 +11,7 @@
 
 #include "identity-storage.hpp"
 #include "private-key-storage.hpp"
+#include "../certificate/public-key.hpp"
 
 #include "../../data.hpp"
 
@@ -25,10 +26,20 @@
 public:
   struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
 
-  IdentityManager(const ptr_lib::shared_ptr<IdentityStorage>& identityStorage, const ptr_lib::shared_ptr<PrivateKeyStorage>& privateKeyStorage)
-  : identityStorage_(identityStorage), privateKeyStorage_(privateKeyStorage)
-  {
-  }
+  IdentityManager(const ptr_lib::shared_ptr<IdentityStorage>   &identityStorage   = DefaultIdentityStorage,
+                  const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage = DefaultPrivateKeyStorage);
+
+  inline IdentityStorage&
+  info();
+
+  inline const IdentityStorage&
+  info() const;
+
+  inline PrivateKeyStorage&
+  tpm();
+
+  inline const PrivateKeyStorage&
+  tpm() const;
   
   /**
    * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
@@ -45,7 +56,7 @@
   Name
   getDefaultIdentity()
   {
-    return identityStorage_->getDefaultIdentity();
+    return info().getDefaultIdentity();
   }
 
   /**
@@ -66,7 +77,7 @@
   void
   setDefaultKeyForIdentity(const Name& keyName, const Name& identityName = Name())
   {
-    identityStorage_->setDefaultKeyNameForIdentity(keyName, identityName);
+    info().setDefaultKeyNameForIdentity(keyName, identityName);
   }
 
   /**
@@ -77,7 +88,7 @@
   Name
   getDefaultKeyNameForIdentity(const Name& identityName = Name())
   {
-    return identityStorage_->getDefaultKeyNameForIdentity(identityName);
+    return info().getDefaultKeyNameForIdentity(identityName);
   }
   
   /**
@@ -95,11 +106,11 @@
    * @param keyName The name of the key.
    * @return The public key.
    */
-  // ptr_lib::shared_ptr<PublicKey>
-  // getPublicKey(const Name& keyName)
-  // {
-  //   return PublicKey::fromDer(identityStorage_->getKey(keyName));
-  // }
+  ptr_lib::shared_ptr<PublicKey>
+  getPublicKey(const Name& keyName)
+  {
+    return info().getKey(keyName);
+  }
 
   /**
    * Create an identity certificate for a public key managed by this IdentityManager.
@@ -109,9 +120,11 @@
    * @param notAfter The notAfter vallue in validity field of the generated certificate.
    * @return The name of generated identity certificate.
    */
-  Name
+  ptr_lib::shared_ptr<IdentityCertificate>
   createIdentityCertificate
-    (const Name& certificatePrefix, const Name& signerCertificateName, const MillisecondsSince1970& notBefore, 
+    (const Name& certificatePrefix,
+     const Name& signerCertificateName,
+     const MillisecondsSince1970& notBefore, 
      const MillisecondsSince1970& notAfter);
 
   /**
@@ -125,8 +138,11 @@
    */
   ptr_lib::shared_ptr<IdentityCertificate>
   createIdentityCertificate
-    (const Name& certificatePrefix, const PublicKey& publickey, const Name& signerCertificateName, 
-     const MillisecondsSince1970& notBefore, const MillisecondsSince1970& notAfter); 
+    (const Name& certificatePrefix,
+     const PublicKey& publickey,
+     const Name& signerCertificateName, 
+     const MillisecondsSince1970& notBefore,
+     const MillisecondsSince1970& notAfter); 
     
   /**
    * Add a certificate into the public key identity storage.
@@ -135,7 +151,7 @@
   void
   addCertificate(const IdentityCertificate& certificate)
   {
-    identityStorage_->addCertificate(certificate);
+    info().addCertificate(certificate);
   }
 
   /**
@@ -164,22 +180,22 @@
    * @param certificateName The name of the requested certificate.
    * @return the requested certificate which is valid.
    */
-  // ptr_lib::shared_ptr<IdentityCertificate>
-  // getCertificate(const Name& certificateName)
-  // {
-  //   return ptr_lib::make_shared<IdentityCertificate>(*identityStorage_->getCertificate(certificateName, false));
-  // }
+  ptr_lib::shared_ptr<IdentityCertificate>
+  getCertificate(const Name& certificateName)
+  {
+    return info().getCertificate(certificateName, false);
+  }
     
   /**
    * Get a certificate even if the certificate is not valid anymore.
    * @param certificateName The name of the requested certificate.
    * @return the requested certificate.
    */
-  // ptr_lib::shared_ptr<IdentityCertificate>
-  // getAnyCertificate(const Name& certificateName)
-  // {
-  //   return ptr_lib::make_shared<IdentityCertificate>(*identityStorage_->getCertificate(certificateName, true));
-  // }
+  ptr_lib::shared_ptr<IdentityCertificate>
+  getAnyCertificate(const Name& certificateName)
+  {
+    return info().getCertificate(certificateName, true);
+  }
     
   /**
    * Get the default certificate name for the specified identity, which will be used when signing is performed based on identity.
@@ -189,7 +205,7 @@
   Name
   getDefaultCertificateNameForIdentity(const Name& identityName)
   {
-    return identityStorage_->getDefaultCertificateNameForIdentity(identityName);
+    return info().getDefaultCertificateNameForIdentity(identityName);
   }
     
   /**
@@ -200,7 +216,7 @@
   Name
   getDefaultCertificateName()
   {
-    return identityStorage_->getDefaultCertificateNameForIdentity(getDefaultIdentity());
+    return info().getDefaultCertificateNameForIdentity(getDefaultIdentity());
   }
         
   /**
@@ -231,6 +247,16 @@
    */
   ptr_lib::shared_ptr<IdentityCertificate>
   selfSign(const Name& keyName);
+
+  /**
+   * @brief Self-sign the supplied identity certificate
+   */
+  void
+  selfSign (IdentityCertificate& cert);
+  
+public:
+  static const ptr_lib::shared_ptr<IdentityStorage>   DefaultIdentityStorage;
+  static const ptr_lib::shared_ptr<PrivateKeyStorage> DefaultPrivateKeyStorage;
   
 private:
   /**
@@ -246,11 +272,49 @@
 
   static Name
   getKeyNameFromCertificatePrefix(const Name& certificatePrefix);
-  
-  ptr_lib::shared_ptr<IdentityStorage> identityStorage_;
+
+private:
+  ptr_lib::shared_ptr<IdentityStorage>   identityStorage_;
   ptr_lib::shared_ptr<PrivateKeyStorage> privateKeyStorage_;
 };
 
+inline IdentityStorage&
+IdentityManager::info()
+{
+  if (!identityStorage_)
+    throw Error("IdentityStorage is not assigned to IdentityManager");
+
+  return *identityStorage_;
+}
+
+inline const IdentityStorage&
+IdentityManager::info() const
+{
+  if (!identityStorage_)
+    throw Error("IdentityStorage is not assigned to IdentityManager");
+  
+  return *identityStorage_;
+}
+
+inline PrivateKeyStorage&
+IdentityManager::tpm()
+{
+  if (!identityStorage_)
+    throw Error("PrivateKeyStorage is not assigned to IdentityManager");
+  
+  return *privateKeyStorage_;
+}
+
+inline const PrivateKeyStorage&
+IdentityManager::tpm() const
+{
+  if (!identityStorage_)
+    throw Error("PrivateKeyStorage is not assigned to IdentityManager");
+  return *privateKeyStorage_;
+}
+  
+  
+
 }
 
 #endif
diff --git a/include/ndn-cpp/security/identity/identity-storage.hpp b/include/ndn-cpp/security/identity/identity-storage.hpp
index 442e522..87d93fd 100644
--- a/include/ndn-cpp/security/identity/identity-storage.hpp
+++ b/include/ndn-cpp/security/identity/identity-storage.hpp
@@ -11,6 +11,7 @@
 
 #include "../../name.hpp"
 #include "../security-common.hpp"
+#include "../certificate/public-key.hpp"
 
 namespace ndn {
 
@@ -79,14 +80,14 @@
    * @param publicKeyDer A blob of the public key DER to be added.
    */
   virtual void 
-  addKey(const Name& keyName, KeyType keyType, const Buffer& publicKeyDer) = 0;
+  addKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer) = 0;
 
   /**
    * Get the public key DER blob from the identity storage.
    * @param keyName The name of the requested public key.
    * @return The DER Blob.  If not found, return a Blob with a null pointer.
    */
-  virtual Buffer
+  virtual ptr_lib::shared_ptr<PublicKey>
   getKey(const Name& keyName) = 0;
 
   /**
@@ -124,7 +125,7 @@
    * @param allowAny If false, only a valid certificate will be returned, otherwise validity is disregarded.
    * @return The requested certificate.  If not found, return a shared_ptr with a null pointer.
    */
-  virtual ptr_lib::shared_ptr<Data> 
+  virtual ptr_lib::shared_ptr<IdentityCertificate> 
   getCertificate(const Name &certificateName, bool allowAny = false) = 0;
 
 
diff --git a/include/ndn-cpp/security/identity/private-key-storage.hpp b/include/ndn-cpp/security/identity/private-key-storage.hpp
index c789d89..29461bb 100644
--- a/include/ndn-cpp/security/identity/private-key-storage.hpp
+++ b/include/ndn-cpp/security/identity/private-key-storage.hpp
@@ -12,6 +12,7 @@
 #include <string>
 #include "../security-common.hpp"
 #include "../../name.hpp"
+#include "../../data.hpp"
 
 namespace ndn {
 
@@ -51,8 +52,15 @@
    * @return The signature, or a null pointer if signing fails.
    */  
   virtual ConstBufferPtr
-  sign(const uint8_t *data, size_t dataLength, const Name& keyName, DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) = 0;
-    
+  sign(const uint8_t *data, size_t dataLength,
+       const Signature &signature,
+       const Name& keyName, DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) = 0;
+
+  virtual ConstBufferPtr
+  sign(const Data &data,
+       const Signature &signature,
+       const Name& keyName, DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256) = 0;
+  
   /**
    * Decrypt data.
    * @param keyName The name of the decrypting key.
diff --git a/include/ndn-cpp/security/key-chain.hpp b/include/ndn-cpp/security/key-chain.hpp
index 4e804cc..da470f7 100644
--- a/include/ndn-cpp/security/key-chain.hpp
+++ b/include/ndn-cpp/security/key-chain.hpp
@@ -29,7 +29,9 @@
 public:
   struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
 
-  KeyChain(IdentityManager *identityManager, PolicyManager *policyManager);
+  KeyChain(const ptr_lib::shared_ptr<IdentityManager>   &identityManager   = DefaultIdentityManager,
+           const ptr_lib::shared_ptr<PolicyManager>     &policyManager     = DefaultPolicyManager,
+           const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager = DefaultEncryptionManager);
 
   /**
    * @brief Set the Face which will be used to fetch required certificates.
@@ -47,6 +49,9 @@
   inline IdentityManager&
   identities()
   {
+    if (!identityManager_)
+      throw Error("IdentityManager is not assigned to the KeyChain");
+
     return *identityManager_;
   }
 
@@ -57,10 +62,26 @@
   inline PolicyManager&
   policies()
   {
+    if (!policyManager_)
+      throw Error("PolicyManager is not assigned to the KeyChain");
+
     return *policyManager_;
   }
 
   /*****************************************
+   *         Encryption Management         *
+   *****************************************/
+
+  inline EncryptionManager&
+  encryption()
+  {
+    if (!encryptionManager_)
+      throw Error("EncryptionManager is not assigned to the KeyChain");
+
+    return *encryptionManager_;
+  }
+
+  /*****************************************
    *              Sign/Verify              *
    *****************************************/
 
@@ -70,7 +91,6 @@
    * data.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0).
    * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
    * @param certificateName The certificate name of the key to use for signing.  If omitted, infer the signing identity from the data packet name.
-   * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
    */
   void 
   sign(Data& data, const Name& certificateName);
@@ -91,7 +111,6 @@
    * data.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0).
    * @param data The Data object to be signed.  This updates its signature and key locator field and wireEncoding.
    * @param identityName The identity name for the key to use for signing.  If omitted, infer the signing identity from the data packet name.
-   * @param wireFormat A WireFormat object used to encode the input. If omitted, use WireFormat getDefaultWireFormat().
    */
   void 
   signByIdentity(Data& data, const Name& identityName = Name());
@@ -122,7 +141,12 @@
    *           Encrypt/Decrypt             *
    *****************************************/
   // todo
-  
+
+public:
+  static const ptr_lib::shared_ptr<IdentityManager>   DefaultIdentityManager;
+  static const ptr_lib::shared_ptr<PolicyManager>     DefaultPolicyManager;
+  static const ptr_lib::shared_ptr<EncryptionManager> DefaultEncryptionManager;
+    
 private:
   void
   onCertificateData
@@ -134,9 +158,10 @@
      const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
 
 private:
-  std::auto_ptr<IdentityManager>   identityManager_;
-  std::auto_ptr<PolicyManager>     policyManager_;
-  // std::auto_ptr<EncryptionManager> encryptionManager_;
+  ptr_lib::shared_ptr<IdentityManager>   identityManager_;
+  ptr_lib::shared_ptr<PolicyManager>     policyManager_;
+  ptr_lib::shared_ptr<EncryptionManager> encryptionManager_;
+
   ptr_lib::shared_ptr<Face>        face_;
   
   const int maxSteps_;
diff --git a/src/security/certificate/identity-certificate.cpp b/src/security/certificate/identity-certificate.cpp
index 7e6d50d..aa2ad9c 100644
--- a/src/security/certificate/identity-certificate.cpp
+++ b/src/security/certificate/identity-certificate.cpp
@@ -12,19 +12,6 @@
 
 namespace ndn {
 
-IdentityCertificate::IdentityCertificate(const Data& data)
-  : Certificate(data)
-{
-  if (!isCorrectName(data.getName()))
-    throw Error("Wrong Identity Certificate Name!");
-  
-  setPublicKeyName();
-}
-
-IdentityCertificate::~IdentityCertificate()
-{
-}
-
 bool
 IdentityCertificate::isCorrectName(const Name& name)
 {
@@ -53,25 +40,18 @@
 }
 
 void
-IdentityCertificate::setName(const Name& name)
-{
-  if (!isCorrectName(name))
-    throw Error("Wrong Identity Certificate Name!");
-  
-  Data::setName(name);
-  setPublicKeyName();
-}
-
-void
 IdentityCertificate::setPublicKeyName()
 {
+  if (!isCorrectName(getName()))
+    throw Error("Wrong Identity Certificate Name!");
+  
   publicKeyName_ = certificateNameToPublicKeyName(getName());
 }
 
 bool
 IdentityCertificate::isIdentityCertificate(const Certificate& certificate)
-{ 
-  return isCorrectName(certificate.getName()); 
+{
+  return dynamic_cast<const IdentityCertificate*>(&certificate);
 }
 
 Name
diff --git a/src/security/identity/identity-manager.cpp b/src/security/identity/identity-manager.cpp
index 88e6782..ce90cc5 100644
--- a/src/security/identity/identity-manager.cpp
+++ b/src/security/identity/identity-manager.cpp
@@ -17,11 +17,12 @@
 #include <fstream>
 #include <math.h>
 #include <ndn-cpp/key-locator.hpp>
-#include <ndn-cpp/sha256-with-rsa-signature.hpp>
-#include <ndn-cpp/security/security-exception.hpp>
+
 #include "../../util/logging.hpp"
 #include "../../c/util/time.h"
 #include <ndn-cpp/security/identity/identity-manager.hpp>
+#include "../certificate/identity-certificate.hpp"
+#include "../signature/signature-sha256-with-rsa.hpp"
 
 INIT_LOGGER("ndn.security.IdentityManager")
 
@@ -29,41 +30,51 @@
 
 namespace ndn {
 
+const ptr_lib::shared_ptr<IdentityStorage>   IdentityManager::DefaultIdentityStorage   = ptr_lib::shared_ptr<IdentityStorage>();
+const ptr_lib::shared_ptr<PrivateKeyStorage> IdentityManager::DefaultPrivateKeyStorage = ptr_lib::shared_ptr<PrivateKeyStorage>();
+
+IdentityManager::IdentityManager(const ptr_lib::shared_ptr<IdentityStorage>   &identityStorage   /* = DefaultIdentityStorage */,
+                                 const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */)
+  : identityStorage_(identityStorage)
+  , privateKeyStorage_(privateKeyStorage)
+{
+}
+
 Name
 IdentityManager::createIdentity(const Name& identityName)
 {
-  if (!identityStorage_->doesIdentityExist(identityName)) {
-  _LOG_DEBUG("Create Identity");
-  identityStorage_->addIdentity(identityName);
+  if (!info().doesIdentityExist(identityName)) {
+    _LOG_DEBUG("Create Identity");
+    info().addIdentity(identityName);
   
-  _LOG_DEBUG("Create Default RSA key pair");
-  Name keyName = generateRSAKeyPairAsDefault(identityName, true);
+    _LOG_DEBUG("Create Default RSA key pair");
+    Name keyName = generateRSAKeyPairAsDefault(identityName, true);
 
-  _LOG_DEBUG("Create self-signed certificate");
-  ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
+    _LOG_DEBUG("Create self-signed certificate");
+    ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
   
-  _LOG_DEBUG("Add self-signed certificate as default");
+    _LOG_DEBUG("Add self-signed certificate as default");
 
-  addCertificateAsDefault(*selfCert);
+    addCertificateAsDefault(*selfCert);
 
-  return keyName;
+    return keyName;
   }
   else
-    throw SecurityException("Identity has already been created!");
+    throw Error("Identity has already been created!");
 }
 
 Name
 IdentityManager::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
 {
   _LOG_DEBUG("Get new key ID");    
-  Name keyName = identityStorage_->getNewKeyName(identityName, isKsk);
+  Name keyName = info().getNewKeyName(identityName, isKsk);
 
   _LOG_DEBUG("Generate key pair in private storage");
-  privateKeyStorage_->generateKeyPair(keyName.toUri(), keyType, keySize);
+  tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
 
   _LOG_DEBUG("Create a key record in public storage");
-  ptr_lib::shared_ptr<PublicKey> pubKey = privateKeyStorage_->getPublicKey(keyName.toUri());
-  identityStorage_->addKey(keyName, keyType, pubKey->getKeyDer());
+  ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
+  info().addKey(keyName, keyType, *pubKey);
 
   return keyName;
 }
@@ -81,12 +92,12 @@
 {
   Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
 
-  identityStorage_->setDefaultKeyNameForIdentity(keyName, identityName);
+  info().setDefaultKeyNameForIdentity(keyName, identityName);
   
   return keyName;
 }
 
-Name
+ptr_lib::shared_ptr<IdentityCertificate>
 IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
                                            const Name& signerCertificateName,
                                            const MillisecondsSince1970& notBefore,
@@ -94,15 +105,15 @@
 {
   Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
   
-  Blob keyBlob = identityStorage_->getKey(keyName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = PublicKey::fromDer(keyBlob);
+  ptr_lib::shared_ptr<IdentityCertificate> certificate =
+    createIdentityCertificate(certificatePrefix,
+                              *info().getKey(keyName),
+                              signerCertificateName,
+                              notBefore, notAfter);
 
-  ptr_lib::shared_ptr<IdentityCertificate> certificate = createIdentityCertificate
-    (certificatePrefix, *publicKey,  signerCertificateName, notBefore, notAfter);
-
-  identityStorage_->addCertificate(*certificate);
+  info().addCertificate(*certificate);
   
-  return certificate->getName();
+  return certificate;
 }
 
 ptr_lib::shared_ptr<IdentityCertificate>
@@ -112,16 +123,11 @@
                                            const MillisecondsSince1970& notBefore,
                                            const MillisecondsSince1970& notAfter)
 {
-  ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
+  ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
   Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
   
   Name certificateName = certificatePrefix;
-  MillisecondsSince1970 ti = ::ndn_getNowMilliseconds();
-  // Get the number of seconds.
-  ostringstream oss;
-  oss << floor(ti / 1000.0);
-
-  certificateName.append("ID-CERT").append(oss.str());
+  certificateName.append("ID-CERT").appendVersion();
   
   certificate->setName(certificateName);
   certificate->setNotBefore(notBefore);
@@ -130,33 +136,34 @@
   certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
   certificate->encode();
 
-  ptr_lib::shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
+  signByCertificate(*certificate, signerCertificateName);
 
-  KeyLocator keyLocator;    
-  keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
-  keyLocator.setKeyName(signerCertificateName);
+  return certificate;
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+IdentityManager::selfSign(const Name& keyName)
+{
+  ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
   
-  sha256Sig->setKeyLocator(keyLocator);
-  sha256Sig->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey.getDigest());
+  Name certificateName = keyName.getSubName(0, keyName.size() - 1);
+  certificateName.append("KEY").append(keyName.get(keyName.size() - 1)).append("ID-CERT").appendVersion();
+  
+  certificate->setName(certificateName);
+  certificate->setNotBefore(ndn_getNowMilliseconds());
+  certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
+  certificate->setPublicKeyInfo(*info().getKey(keyName));
+  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+  certificate->encode();
 
-  certificate->setSignature(*sha256Sig);
-
-  SignedBlob unsignedData = certificate->wireEncode();
-
-  ptr_lib::shared_ptr<IdentityCertificate> signerCertificate = getCertificate(signerCertificateName);
-  Name signerkeyName = signerCertificate->getPublicKeyName();
-
-  Blob sigBits = privateKeyStorage_->sign(unsignedData, signerkeyName);
-    
-  sha256Sig->setSignature(sigBits);
-
+  selfSign(*certificate);
   return certificate;
 }
 
 void
 IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
 {
-  identityStorage_->addCertificate(certificate);
+  info().addCertificate(certificate);
 
   setDefaultCertificateForKey(certificate);
 }
@@ -164,7 +171,7 @@
 void
 IdentityManager::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
 {
-  identityStorage_->addCertificate(certificate);
+  info().addCertificate(certificate);
 
   Name keyName = certificate.getPublicKeyName();
     
@@ -178,113 +185,45 @@
 {
   Name keyName = certificate.getPublicKeyName();
   
-  if(!identityStorage_->doesKeyExist(keyName))
-    throw SecurityException("No corresponding Key record for certificate!");
+  if(!info().doesKeyExist(keyName))
+    throw Error("No corresponding Key record for certificate!");
 
-  identityStorage_->setDefaultCertificateNameForKey(keyName, certificate.getName());
+  info().setDefaultCertificateNameForKey(keyName, certificate.getName());
 }
   
-ptr_lib::shared_ptr<Signature>
+Signature
 IdentityManager::signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
 {
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey(keyName.toUri());
+  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
 
-  Blob sigBits = privateKeyStorage_->sign(buffer, bufferLength, keyName.toUri());
-
-  //For temporary usage, we support RSA + SHA256 only, but will support more.
-  ptr_lib::shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
-
-  KeyLocator keyLocator;    
-  keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
-  keyLocator.setKeyName(certificateName);
-  
-  sha256Sig->setKeyLocator(keyLocator);
-  sha256Sig->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
-  sha256Sig->setSignature(sigBits);
-
-  return sha256Sig;
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signature.setValue(tpm().sign(buffer, bufferLength, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  return signature;
 }
 
 void
-IdentityManager::signByCertificate(Data &data, const Name &certificateName, WireFormat& wireFormat)
+IdentityManager::signByCertificate(Data &data, const Name &certificateName)
 {
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = privateKeyStorage_->getPublicKey(keyName);
+  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
 
   // For temporary usage, we support RSA + SHA256 only, but will support more.
-  data.setSignature(Sha256WithRsaSignature());
-  // Get a pointer to the clone which Data made.
-  Sha256WithRsaSignature *signature = dynamic_cast<Sha256WithRsaSignature*>(data.getSignature());
-  DigestAlgorithm digestAlgorithm = DIGEST_ALGORITHM_SHA256;
-    
-  signature->getKeyLocator().setType(ndn_KeyLocatorType_KEYNAME);
-  signature->getKeyLocator().setKeyName(certificateName.getPrefix(-1));
-  // Omit the certificate digest.
-  signature->getKeyLocator().setKeyNameType((ndn_KeyNameType)-1);
-  // Ignore witness and leave the digestAlgorithm as the default.
-  signature->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
-  
-  // Encode once to get the signed portion.
-  SignedBlob encoding = data.wireEncode(wireFormat);
-  
-  signature->setSignature
-    (privateKeyStorage_->sign(encoding.signedBuf(), encoding.signedSize(), keyName, digestAlgorithm));
-
-  // Encode again to include the signature.
-  data.wireEncode(wireFormat);
+  signature.setValue(tpm().sign(data, signature, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  data.setSignature(signature);
 }
 
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::selfSign(const Name& keyName)
+void
+IdentityManager::selfSign (IdentityCertificate& cert)
 {
-  ptr_lib::shared_ptr<IdentityCertificate> certificate(new IdentityCertificate());
-  
-  Name certificateName = keyName.getSubName(0, keyName.size() - 1);
-  certificateName.append("KEY").append(keyName.get(keyName.size() - 1)).append("ID-CERT").append("0");
-  certificate->setName(certificateName);
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
 
-  Blob keyBlob = identityStorage_->getKey(keyName);
-  ptr_lib::shared_ptr<PublicKey> publicKey = PublicKey::fromDer(keyBlob);
-
-#if NDN_CPP_HAVE_GMTIME_SUPPORT
-  time_t nowSeconds = time(NULL);
-  struct tm current = *gmtime(&nowSeconds);
-  current.tm_hour = 0;
-  current.tm_min  = 0;
-  current.tm_sec  = 0;
-  MillisecondsSince1970 notBefore = timegm(&current) * 1000.0;
-  current.tm_year = current.tm_year + 20;
-  MillisecondsSince1970 notAfter = timegm(&current) * 1000.0;
-
-  certificate->setNotBefore(notBefore);
-  certificate->setNotAfter(notAfter);
-#else
-  // Don't really expect this to happen.
-  throw SecurityException("selfSign: Can't set certificate validity because time functions are not supported by the standard library.");
-#endif  
-  certificate->setPublicKeyInfo(*publicKey);
-  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
-  certificate->encode();
-
-  ptr_lib::shared_ptr<Sha256WithRsaSignature> sha256Sig(new Sha256WithRsaSignature());
-
-  KeyLocator keyLocator;    
-  keyLocator.setType(ndn_KeyLocatorType_KEYNAME);
-  keyLocator.setKeyName(certificateName);
-  
-  sha256Sig->setKeyLocator(keyLocator);
-  sha256Sig->getPublisherPublicKeyDigest().setPublisherPublicKeyDigest(publicKey->getDigest());
-
-  certificate->setSignature(*sha256Sig);
-
-  Blob unsignedData = certificate->wireEncode();
-
-  Blob sigBits = privateKeyStorage_->sign(unsignedData, keyName.toUri());
-  
-  sha256Sig->setSignature(sigBits);
-
-  return certificate;
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signature.setValue(tpm().sign(cert, signature, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  cert.setSignature(signature);
 }
 
 Name
@@ -300,7 +239,7 @@
   }
     
   if (i >= certificatePrefix.size())
-    throw SecurityException("Identity Certificate Prefix does not have a KEY component");
+    throw Error("Identity Certificate Prefix does not have a KEY component");
 
   result.append(certificatePrefix.getSubName(0, i));
   result.append(certificatePrefix.getSubName(i + 1, certificatePrefix.size()-i-1));
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index 26dcec8..017a462 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -6,11 +6,10 @@
  * See COPYING for copyright and distribution information.
  */
 
-#include "../util/logging.hpp"
-#include <ndn-cpp/security/security-exception.hpp>
-#include <ndn-cpp/security/policy/policy-manager.hpp>
 #include <ndn-cpp/security/key-chain.hpp>
 
+#include <ndn-cpp/security/policy/policy-manager.hpp>
+
 using namespace std;
 using namespace ndn::func_lib;
 #if NDN_CPP_HAVE_STD_FUNCTION
@@ -19,26 +18,64 @@
 #endif
 
 namespace ndn {
-  
-KeyChain::KeyChain(const ptr_lib::shared_ptr<IdentityManager>& identityManager, const ptr_lib::shared_ptr<PolicyManager>& policyManager)
-: identityManager_(identityManager), policyManager_(policyManager), face_(0), maxSteps_(100)
+
+const ptr_lib::shared_ptr<IdentityManager>   KeyChain::DefaultIdentityManager   = ptr_lib::shared_ptr<IdentityManager>();
+const ptr_lib::shared_ptr<PolicyManager>     KeyChain::DefaultPolicyManager     = ptr_lib::shared_ptr<PolicyManager>();
+const ptr_lib::shared_ptr<EncryptionManager> KeyChain::DefaultEncryptionManager = ptr_lib::shared_ptr<EncryptionManager>();
+
+
+KeyChain::KeyChain(const ptr_lib::shared_ptr<IdentityManager>   &identityManager   /* = DefaultIdentityManager */,
+                   const ptr_lib::shared_ptr<PolicyManager>     &policyManager     /* = DefaultPolicyManager */,
+                   const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager /* = DefaultEncryptionManager */)
+  : identityManager_(identityManager)
+  , policyManager_(policyManager)
+  , encryptionManager_(encryptionManager)
+  , maxSteps_(100)
 {  
+// #ifdef USE_SIMPLE_POLICY_MANAGER
+//   Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager());
+//   Ptr<IdentityPolicyRule> rule1 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
+//                                                                                  "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
+//                                                                                  ">", "\\1\\2", "\\1", true));
+//   Ptr<IdentityPolicyRule> rule2 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
+//                                                                                  "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
+//                                                                                  "==", "\\1", "\\1\\2", true));
+//   Ptr<IdentityPolicyRule> rule3 = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^(<>*)$", 
+//                                                                                  "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>", 
+//                                                                                  ">", "\\1", "\\1", true));
+//   policyManager->addVerificationPolicyRule(rule1);
+//   policyManager->addVerificationPolicyRule(rule2);
+//   policyManager->addVerificationPolicyRule(rule3);
+    
+//   policyManager->addSigningPolicyRule(rule3);
+
+//   m_policyManager = policyManager;
+// #endif
+
+//   if (!policyManager_)
+//     {
+//       policyManager_ = new NoVerifyPolicyManager();
+//     }
+
+// #ifdef USE_BASIC_ENCRYPTION_MANAGER
+//     encryptionManager_ = new BasicEncryptionManager(m_identityManager->getPrivateStorage(), "/tmp/encryption.db");
+// #endif
 }
 
 void 
-KeyChain::sign(Data& data, const Name& certificateName, WireFormat& wireFormat)
+KeyChain::sign(Data& data, const Name& certificateName)
 {
-  identityManager_->signByCertificate(data, certificateName, wireFormat);
+  identities().signByCertificate(data, certificateName);
 }
 
-ptr_lib::shared_ptr<Signature> 
+Signature
 KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
 {
-  return identityManager_->signByCertificate(buffer, bufferLength, certificateName);
+  return identities().signByCertificate(buffer, bufferLength, certificateName);
 }
 
 void 
-KeyChain::signByIdentity(Data& data, const Name& identityName, WireFormat& wireFormat)
+KeyChain::signByIdentity(Data& data, const Name& identityName)
 {
   Name signingCertificateName;
   
@@ -53,41 +90,44 @@
     signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
 
   if (signingCertificateName.getComponentCount() == 0)
-    throw SecurityException("No qualified certificate name found!");
+    throw Error("No qualified certificate name found!");
 
   if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
-    throw SecurityException("Signing Cert name does not comply with signing policy");
+    throw Error("Signing Cert name does not comply with signing policy");
 
-  identityManager_->signByCertificate(data, signingCertificateName, wireFormat);  
+  identities().signByCertificate(data, signingCertificateName);  
 }
 
-ptr_lib::shared_ptr<Signature> 
+Signature
 KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
 {
   Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
     
   if (signingCertificateName.size() == 0)
-    throw SecurityException("No qualified certificate name found!");
+    throw Error("No qualified certificate name found!");
 
-  return identityManager_->signByCertificate(buffer, bufferLength, signingCertificateName);
+  return identities().signByCertificate(buffer, bufferLength, signingCertificateName);
 }
 
 void
 KeyChain::verifyData
   (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
 {
-  _LOG_TRACE("Enter Verify");
-
-  if (policyManager_->requireVerify(*data)) {
+  if (policies().requireVerify(*data)) {
     ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
       (data, stepCount, onVerified, onVerifyFailed);
     if (nextStep)
-      face_->expressInterest
-        (*nextStep->interest_, 
-         bind(&KeyChain::onCertificateData, this, _1, _2, nextStep), 
-         bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
+      {
+        if (!face_)
+          throw Error("Face should be set prior to verifyData method to call");
+        
+        face_->expressInterest
+          (*nextStep->interest_, 
+           bind(&KeyChain::onCertificateData, this, _1, _2, nextStep), 
+           bind(&KeyChain::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
+      }
   }
-  else if (policyManager_->skipVerifyAndTrust(*data))
+  else if (policies().skipVerifyAndTrust(*data))
     onVerified(data);
   else
     onVerifyFailed(data);
diff --git a/src/util/ndnd-id-fetcher.hpp b/src/util/ndnd-id-fetcher.hpp
index 1a938f9..c78a385 100644
--- a/src/util/ndnd-id-fetcher.hpp
+++ b/src/util/ndnd-id-fetcher.hpp
@@ -55,7 +55,7 @@
 void 
 NdndIdFetcher::operator()(const ptr_lib::shared_ptr<const Interest>& interest, const ptr_lib::shared_ptr<Data>& ndndIdData)
 {
-  if (ndndIdData->getSignature().getType() == Signature::SignatureSha256WithRsa)
+  if (ndndIdData->getSignature().getType() == Signature::Sha256WithRsa)
     {
       ndndId_.resize(32);
       ndn_digestSha256(ndndIdData->getSignature().getValue().value(), ndndIdData->getSignature().getValue().value_size(), ndndId_.buf());