security: Split KeyChain into signing (KeyChain) and verification (Verifier) interfaces

This split removes the need for IdentityManager.

Also in this commit: Make verifySignature methods a set of static methods of Verifier.

Change-Id: Iea1c4353857a21417b2dcd1f91ba7013995d1459
diff --git a/Makefile.am b/Makefile.am
index 79ee8e4..39a0e7e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -105,11 +105,11 @@
   src/security/certificate/identity-certificate.cpp \
   src/security/certificate/public-key.cpp \
   src/security/identity/basic-identity-storage.cpp \
-  src/security/identity/identity-manager.cpp \
   src/security/identity/identity-storage.cpp \
   src/security/identity/memory-identity-storage.cpp \
   src/security/identity/memory-private-key-storage.cpp \
   src/security/key-chain.cpp \
+  src/security/verifier.cpp \
   src/security/policy/no-verify-policy-manager.cpp \
   src/security/policy/self-verify-policy-manager.cpp \
   src/transport/unix-transport.cpp \
diff --git a/include/ndn-cpp/security/identity/identity-manager.hpp b/include/ndn-cpp/security/identity/identity-manager.hpp
deleted file mode 100644
index e1c11df..0000000
--- a/include/ndn-cpp/security/identity/identity-manager.hpp
+++ /dev/null
@@ -1,322 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
- * @author: Jeff Thompson <jefft0@remap.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NDN_IDENTITY_MANAGER_HPP
-#define NDN_IDENTITY_MANAGER_HPP
-
-#include "identity-storage.hpp"
-#include "private-key-storage.hpp"
-#include "../certificate/public-key.hpp"
-
-#include "../../data.hpp"
-#include "../certificate/identity-certificate.hpp"
-
-namespace ndn {
-
-/**
- * An IdentityManager is the interface of operations related to identity, keys, and certificates.
- */
-class IdentityManager {
-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);
-
-  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.
-   * @param identityName The name of the identity.
-   * @return The key name of the auto-generated KSK of the identity.
-   */
-  Name
-  createIdentity(const Name& identityName);
-    
-  /**
-   * Get the default identity.
-   * @return The default identity name.
-   */
-  Name
-  getDefaultIdentity()
-  {
-    return info().getDefaultIdentity();
-  }
-
-  /**
-   * Generate a pair of RSA keys for the specified identity.
-   * @param identityName The name of the identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keySize The size of the key.
-   * @return The generated key name.
-   */
-  Name
-  generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048);
-
-  /**
-   * Set a key as the default key of an identity.
-   * @param keyName The name of the key.
-   * @param identityName the name of the identity. If not specified, the identity name is inferred from the keyName.
-   */
-  void
-  setDefaultKeyForIdentity(const Name& keyName, const Name& identityName = Name())
-  {
-    info().setDefaultKeyNameForIdentity(keyName, identityName);
-    defaultCertificate_.reset();
-  }
-
-  /**
-   * Get the default key for an identity.
-   * @param identityName the name of the identity. If omitted, the identity name is inferred from the keyName.
-   * @return The default key name.
-   */
-  Name
-  getDefaultKeyNameForIdentity(const Name& identityName = Name())
-  {
-    return info().getDefaultKeyNameForIdentity(identityName);
-  }
-  
-  /**
-   * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
-   * @param identityName The name of the identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keySize The size of the key.
-   * @return The generated key name.
-   */
-  Name
-  generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048);
-
-  /**
-   * Get the public key with the specified name.
-   * @param keyName The name of the key.
-   * @return The public key.
-   */
-  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.
-   * @param certificatePrefix The name of public key to be signed.
-   * @param signerCertificateName The name of signing certificate.
-   * @param notBefore The notBefore value in the validity field of the generated certificate.
-   * @param notAfter The notAfter vallue in validity field of the generated certificate.
-   * @return The name of generated identity certificate.
-   */
-  ptr_lib::shared_ptr<IdentityCertificate>
-  createIdentityCertificate
-    (const Name& certificatePrefix,
-     const Name& signerCertificateName,
-     const MillisecondsSince1970& notBefore, 
-     const MillisecondsSince1970& notAfter);
-
-  /**
-   * Create an identity certificate for a public key supplied by the caller.
-   * @param certificatePrefix The name of public key to be signed.
-   * @param publickey The public key to be signed.
-   * @param signerCertificateName The name of signing certificate.
-   * @param notBefore The notBefore value in the validity field of the generated certificate.
-   * @param notAfter The notAfter vallue in validity field of the generated certificate.
-   * @return The generated identity certificate.
-   */
-  ptr_lib::shared_ptr<IdentityCertificate>
-  createIdentityCertificate
-    (const Name& certificatePrefix,
-     const PublicKey& publickey,
-     const Name& signerCertificateName, 
-     const MillisecondsSince1970& notBefore,
-     const MillisecondsSince1970& notAfter); 
-    
-  /**
-   * Add a certificate into the public key identity storage.
-   * @param certificate The certificate to to added.  This makes a copy of the certificate.
-   */
-  void
-  addCertificate(const IdentityCertificate& certificate)
-  {
-    info().addCertificate(certificate);
-  }
-
-  /**
-   * Set the certificate as the default for its corresponding key.
-   * @param certificateName The certificate.
-   */
-  void
-  setDefaultCertificateForKey(const IdentityCertificate& certificate);
-
-  /**
-   * Add a certificate into the public key identity storage and set the certificate as the default for its corresponding identity.
-   * @param certificate The certificate to be added.  This makes a copy of the certificate.
-   */
-  void
-  addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
-
-  /**
-   * Add a certificate into the public key identity storage and set the certificate as the default of its corresponding key.
-   * @param certificate The certificate to be added.  This makes a copy of the certificate.
-   */
-  void
-  addCertificateAsDefault(const IdentityCertificate& certificate);
-
-  /**
-   * Get a certificate with the specified name.
-   * @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 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 info().getCertificate(certificateName, true);
-  }
-    
-  /**
-   * Get the default certificate name for the specified identity, which will be used when signing is performed based on identity.
-   * @param identityName The name of the specified identity.
-   * @return The requested certificate name.
-   */
-  Name
-  getDefaultCertificateNameForIdentity(const Name& identityName)
-  {
-    return info().getDefaultCertificateNameForIdentity(identityName);
-  }
-    
-  /**
-   * Get the default certificate name of the default identity, which will be used when signing is based on identity and 
-   * the identity is not specified.
-   * @return The requested certificate name.
-   */
-  Name
-  getDefaultCertificateName()
-  {
-    return info().getDefaultCertificateNameForIdentity(getDefaultIdentity());
-  }
-
-  void
-  sign(Data &data);
-  
-  /**
-   * Sign the byte array data based on the certificate name.
-   * @param buffer The byte array to be signed.
-   * @param bufferLength the length of buffer.
-   * @param certificateName The signing certificate name.
-   * @return The generated signature.
-   */
-  Signature
-  signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
-
-  /**
-   * Sign data packet based on the certificate name.
-   * Note: the caller must make sure the timestamp in data is correct, for example with 
-   * data.getMetaInfo().setTimestampMilliseconds(time(NULL) * 1000.0).
-   * @param data The Data object to sign and update its signature.
-   * @param certificateName The Name identifying the certificate which identifies the signing key.
-   * @param wireFormat The WireFormat for calling encodeData, or WireFormat::getDefaultWireFormat() if omitted.
-   */
-  void 
-  signByCertificate(Data& data, const Name& certificateName);
-
-  void
-  signByCertificate(Data& data, const IdentityCertificate& certificate);
-
-  /**
-   * Generate a self-signed certificate for a public key.
-   * @param keyName The name of the public key.
-   * @return The generated certificate.
-   */
-  ptr_lib::shared_ptr<IdentityCertificate>
-  selfSign(const Name& keyName);
-
-  /**
-   * @brief Self-sign the supplied identity certificate
-   */
-  void
-  selfSign (IdentityCertificate& cert);
-
-private:
-  /**
-   * Generate a key pair for the specified identity.
-   * @param identityName The name of the specified identity.
-   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
-   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
-   * @param keySize The size of the key pair.
-   * @return The name of the generated key.
-   */
-  Name
-  generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
-
-  static Name
-  getKeyNameFromCertificatePrefix(const Name& certificatePrefix);
-
-private:
-  ptr_lib::shared_ptr<IdentityStorage>   identityStorage_;
-  ptr_lib::shared_ptr<PrivateKeyStorage> privateKeyStorage_;
-
-  ptr_lib::shared_ptr<IdentityCertificate> defaultCertificate_;
-};
-
-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/key-chain.hpp b/include/ndn-cpp/security/key-chain.hpp
index 6d1e212..1dc8e7b 100644
--- a/include/ndn-cpp/security/key-chain.hpp
+++ b/include/ndn-cpp/security/key-chain.hpp
@@ -9,95 +9,231 @@
 #ifndef NDN_KEY_CHAIN_HPP
 #define NDN_KEY_CHAIN_HPP
 
-#include "../data.hpp"
-#include "../face.hpp"
-#include "identity/identity-manager.hpp"
-#include "encryption/encryption-manager.hpp"
-#include "policy/validation-request.hpp"
+#include "certificate/identity-certificate.hpp"
+#include "certificate/public-key.hpp"
+#include "identity/identity-storage.hpp"
+#include "identity/private-key-storage.hpp"
+
 
 namespace ndn {
 
-class PolicyManager;
-  
 /**
- * KeyChain is the main class of the security library.
+ * KeyChain is one of the main classes of the security library.
  *
- * The KeyChain class provides a set of interfaces to the security library such as identity management, policy configuration 
- * and packet signing and verification.
+ * The KeyChain class provides a set of interfaces of identity management and private key related operations.
  */
 class KeyChain {
 public:
   struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
 
   KeyChain(const ptr_lib::shared_ptr<IdentityStorage>   &identityStorage   = DefaultIdentityStorage,
-           const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage = DefaultPrivateKeyStorage,
-           const ptr_lib::shared_ptr<PolicyManager>     &policyManager     = DefaultPolicyManager,
-           const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager = DefaultEncryptionManager);
+           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.
+   * @param identityName The name of the identity.
+   * @return The key name of the auto-generated KSK of the identity.
+   */
+  Name
+  createIdentity(const Name& identityName);
+    
+  /**
+   * Get the default identity.
+   * @return The default identity name.
+   */
+  Name
+  getDefaultIdentity()
+  {
+    return info().getDefaultIdentity();
+  }
+  
+  /**
+   * Generate a pair of RSA keys for the specified identity.
+   * @param identityName The name of the identity.
+   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+   * @param keySize The size of the key.
+   * @return The generated key name.
+   */
+  Name
+  generateRSAKeyPair(const Name& identityName, bool isKsk = false, int keySize = 2048);
 
   /**
-   * @brief Set the Face which will be used to fetch required certificates.
-   * @param face A pointer to the Face object.
-   *
-   * Setting face is necessary for keychain operation that involve fetching data.
+   * Set a key as the default key of an identity.
+   * @param keyName The name of the key.
+   * @param identityName the name of the identity. If not specified, the identity name is inferred from the keyName.
    */
   void
-  setFace(const ptr_lib::shared_ptr<Face> &face) { face_ = face; }
+  setDefaultKeyForIdentity(const Name& keyName, const Name& identityName = Name())
+  {
+    info().setDefaultKeyNameForIdentity(keyName, identityName);
+    defaultCertificate_.reset();
+  }
+
+  /**
+   * Get the default key for an identity.
+   * @param identityName the name of the identity. If omitted, the identity name is inferred from the keyName.
+   * @return The default key name.
+   */
+  Name
+  getDefaultKeyNameForIdentity(const Name& identityName = Name())
+  {
+    return info().getDefaultKeyNameForIdentity(identityName);
+  }
   
-  /*****************************************
-   *          Identity Management          *
-   *****************************************/
+  /**
+   * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
+   * @param identityName The name of the identity.
+   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+   * @param keySize The size of the key.
+   * @return The generated key name.
+   */
+  Name
+  generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk = false, int keySize = 2048);
 
-  inline IdentityManager&
-  identities()
+  /**
+   * Get the public key with the specified name.
+   * @param keyName The name of the key.
+   * @return The public key.
+   */
+  ptr_lib::shared_ptr<PublicKey>
+  getPublicKey(const Name& keyName)
   {
-    if (!identityManager_)
-      throw Error("IdentityManager is not assigned to the KeyChain");
-
-    return *identityManager_;
+    return info().getKey(keyName);
   }
 
-  /*****************************************
-   *           Policy Management           *
-   *****************************************/
+  /**
+   * Create an identity certificate for a public key managed by this IdentityManager.
+   * @param certificatePrefix The name of public key to be signed.
+   * @param signerCertificateName The name of signing certificate.
+   * @param notBefore The notBefore value in the validity field of the generated certificate.
+   * @param notAfter The notAfter vallue in validity field of the generated certificate.
+   * @return The name of generated identity certificate.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  createIdentityCertificate
+    (const Name& certificatePrefix,
+     const Name& signerCertificateName,
+     const MillisecondsSince1970& notBefore, 
+     const MillisecondsSince1970& notAfter);
 
-  inline PolicyManager&
-  policies()
+  /**
+   * Create an identity certificate for a public key supplied by the caller.
+   * @param certificatePrefix The name of public key to be signed.
+   * @param publickey The public key to be signed.
+   * @param signerCertificateName The name of signing certificate.
+   * @param notBefore The notBefore value in the validity field of the generated certificate.
+   * @param notAfter The notAfter vallue in validity field of the generated certificate.
+   * @return The generated identity certificate.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  createIdentityCertificate
+    (const Name& certificatePrefix,
+     const PublicKey& publickey,
+     const Name& signerCertificateName, 
+     const MillisecondsSince1970& notBefore,
+     const MillisecondsSince1970& notAfter); 
+    
+  /**
+   * Add a certificate into the public key identity storage.
+   * @param certificate The certificate to to added.  This makes a copy of the certificate.
+   */
+  void
+  addCertificate(const IdentityCertificate& certificate)
   {
-    if (!policyManager_)
-      throw Error("PolicyManager is not assigned to the KeyChain");
-
-    return *policyManager_;
+    info().addCertificate(certificate);
   }
 
-  /*****************************************
-   *         Encryption Management         *
-   *****************************************/
+  /**
+   * Set the certificate as the default for its corresponding key.
+   * @param certificateName The certificate.
+   */
+  void
+  setDefaultCertificateForKey(const IdentityCertificate& certificate);
 
-  inline EncryptionManager&
-  encryption()
+  /**
+   * Add a certificate into the public key identity storage and set the certificate as the default for its corresponding identity.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  void
+  addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
+
+  /**
+   * Add a certificate into the public key identity storage and set the certificate as the default of its corresponding key.
+   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   */
+  void
+  addCertificateAsDefault(const IdentityCertificate& certificate);
+
+  /**
+   * Get a certificate with the specified name.
+   * @param certificateName The name of the requested certificate.
+   * @return the requested certificate which is valid.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  getCertificate(const Name& certificateName)
   {
-    if (!encryptionManager_)
-      throw Error("EncryptionManager is not assigned to the KeyChain");
-
-    return *encryptionManager_;
+    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 info().getCertificate(certificateName, true);
+  }
+    
+  /**
+   * Get the default certificate name for the specified identity, which will be used when signing is performed based on identity.
+   * @param identityName The name of the specified identity.
+   * @return The requested certificate name.
+   */
+  Name
+  getDefaultCertificateNameForIdentity(const Name& identityName)
+  {
+    return info().getDefaultCertificateNameForIdentity(identityName);
+  }
+    
+  /**
+   * Get the default certificate name of the default identity, which will be used when signing is based on identity and 
+   * the identity is not specified.
+   * @return The requested certificate name.
+   */
+  Name
+  getDefaultCertificateName()
+  {
+    return info().getDefaultCertificateNameForIdentity(getDefaultIdentity());
   }
 
-  /*****************************************
-   *              Sign/Verify              *
-   *****************************************/
-
-  inline void 
-  sign(Data& data);
+  void
+  sign(Data &data);
   
   /**
    * Wire encode the Data object, sign it and set its signature.
-   * Note: the caller must make sure the timestamp is correct, for example with 
-   * 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.
    */
-  inline void 
+  void 
   sign(Data& data, const Name& certificateName);
+
+  void
+  sign(Data& data, const IdentityCertificate& certificate);
   
   /**
    * Sign the byte array using a certificate name and return a Signature object.
@@ -106,13 +242,11 @@
    * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
    * @return The Signature.
    */
-  inline Signature
+  Signature
   sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName);
 
   /**
    * Wire encode the Data object, sign it and set its signature.
-   * Note: the caller must make sure the timestamp is correct, for example with 
-   * 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.
    */
@@ -127,70 +261,82 @@
    * @return The Signature.
    */
   Signature
-  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName);
+  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName = Name());
 
   /**
-   * Check the signature on the Data object and call either onVerify or onVerifyFailed. 
-   * We use callback functions because verify may fetch information to check the signature.
-   * @param data The Data object with the signature to check. It is an error if data does not have a wireEncoding. 
-   * To set the wireEncoding, you can call data.wireDecode.
-   * @param onVerified If the signature is verified, this calls onVerified(data).
-   * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+   * Generate a self-signed certificate for a public key.
+   * @param keyName The name of the public key.
+   * @return The generated certificate.
+   */
+  ptr_lib::shared_ptr<IdentityCertificate>
+  selfSign(const Name& keyName);
+
+  /**
+   * @brief Self-sign the supplied identity certificate
    */
   void
-  verifyData
-    (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount = 0);
+  selfSign (IdentityCertificate& cert);
 
-  /*****************************************
-   *           Encrypt/Decrypt             *
-   *****************************************/
-  // todo
+private:
+  /**
+   * Generate a key pair for the specified identity.
+   * @param identityName The name of the specified identity.
+   * @param isKsk true for generating a Key-Signing-Key (KSK), false for a Data-Signing-Key (KSK).
+   * @param keyType The type of the key pair, e.g. KEY_TYPE_RSA.
+   * @param keySize The size of the key pair.
+   * @return The name of the generated key.
+   */
+  Name
+  generateKeyPair(const Name& identityName, bool isKsk = false, KeyType keyType = KEY_TYPE_RSA, int keySize = 2048);
+
+  static Name
+  getKeyNameFromCertificatePrefix(const Name& certificatePrefix);
 
 public:
   static const ptr_lib::shared_ptr<IdentityStorage>   DefaultIdentityStorage;
   static const ptr_lib::shared_ptr<PrivateKeyStorage> DefaultPrivateKeyStorage;
-  static const ptr_lib::shared_ptr<PolicyManager>     DefaultPolicyManager;
-  static const ptr_lib::shared_ptr<EncryptionManager> DefaultEncryptionManager;
     
 private:
-  void
-  onCertificateData
-    (const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
-  
-  void
-  onCertificateInterestTimeout
-    (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, 
-     const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
-
-private:
   ptr_lib::shared_ptr<IdentityStorage>   publicInfoStorage_;
   ptr_lib::shared_ptr<PrivateKeyStorage> privateKeyStorage_;
-  ptr_lib::shared_ptr<IdentityManager>   identityManager_; // uses publicInfo and privateKey storages
 
-  ptr_lib::shared_ptr<PolicyManager>     policyManager_;
-  ptr_lib::shared_ptr<EncryptionManager> encryptionManager_;
-
-  ptr_lib::shared_ptr<Face>        face_;
-  
-  // const int maxSteps_;
+  ptr_lib::shared_ptr<IdentityCertificate> defaultCertificate_;
 };
 
-void 
-KeyChain::sign(Data& data)
+
+inline IdentityStorage&
+KeyChain::info()
 {
-  identities().sign(data);
+  if (!publicInfoStorage_)
+    throw Error("IdentityStorage is not assigned to IdentityManager");
+
+  return *publicInfoStorage_;
 }
 
-void 
-KeyChain::sign(Data& data, const Name& certificateName)
+inline const IdentityStorage&
+KeyChain::info() const
 {
-  identities().signByCertificate(data, certificateName);
+  if (!publicInfoStorage_)
+    throw Error("IdentityStorage is not assigned to IdentityManager");
+  
+  return *publicInfoStorage_;
 }
 
-Signature
-KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
+inline PrivateKeyStorage&
+KeyChain::tpm()
 {
-  return identities().signByCertificate(buffer, bufferLength, certificateName);
+  if (!privateKeyStorage_)
+    throw Error("PrivateKeyStorage is not assigned to IdentityManager");
+  
+  return *privateKeyStorage_;
+}
+
+inline const PrivateKeyStorage&
+KeyChain::tpm() const
+{
+  if (!privateKeyStorage_)
+    throw Error("PrivateKeyStorage is not assigned to IdentityManager");
+  return *privateKeyStorage_;
 }
 
 }
diff --git a/include/ndn-cpp/security/policy/policy-manager.hpp b/include/ndn-cpp/security/policy/policy-manager.hpp
index f84a505..400360d 100644
--- a/include/ndn-cpp/security/policy/policy-manager.hpp
+++ b/include/ndn-cpp/security/policy/policy-manager.hpp
@@ -10,7 +10,7 @@
 #define NDN_POLICY_MANAGER_HPP
 
 #include "../../data.hpp"
-#include "../key-chain.hpp"
+#include "validation-request.hpp"
 
 namespace ndn {
 
@@ -22,6 +22,8 @@
  */
 class PolicyManager {
 public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
   /**
    * The virtual destructor.
    */
diff --git a/include/ndn-cpp/security/policy/validation-request.hpp b/include/ndn-cpp/security/policy/validation-request.hpp
index 78f2d6c..69a1079 100644
--- a/include/ndn-cpp/security/policy/validation-request.hpp
+++ b/include/ndn-cpp/security/policy/validation-request.hpp
@@ -9,7 +9,7 @@
 #ifndef NDN_VALIDATION_REQUEST_HPP
 #define NDN_VALIDATION_REQUEST_HPP
 
-#include "../key-chain.hpp"
+#include "../../interest.hpp"
 
 namespace ndn {
 
diff --git a/include/ndn-cpp/security/verifier.hpp b/include/ndn-cpp/security/verifier.hpp
new file mode 100644
index 0000000..0682927
--- /dev/null
+++ b/include/ndn-cpp/security/verifier.hpp
@@ -0,0 +1,95 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_VERIFIER_HPP
+#define NDN_VERIFIER_HPP
+
+#include "../data.hpp"
+#include "../face.hpp"
+#include "policy/validation-request.hpp"
+#include "certificate/public-key.hpp"
+#include "signature/signature-sha256-with-rsa.hpp"
+
+namespace ndn {
+
+class PolicyManager;
+  
+/**
+ * Verifier is one of the main classes of the security librar .
+ *
+ * The Verifier class provides the interfaces for packet verification.
+ */
+class Verifier {
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+
+  Verifier(const ptr_lib::shared_ptr<PolicyManager> &policyManager = DefaultPolicyManager);
+
+  /**
+   * @brief Set the Face which will be used to fetch required certificates.
+   * @param face A pointer to the Face object.
+   *
+   * Setting face is necessary for verifier operation that involve fetching data.
+   */
+  void
+  setFace(const ptr_lib::shared_ptr<Face> &face) { face_ = face; }
+  
+  /**
+   * @brief Get the policyManager.
+   * @return The PolicyManager.
+   */
+  inline PolicyManager&
+  policies()
+  {
+    if (!policyManager_)
+      throw Error("PolicyManager is not assigned to the KeyChain");
+
+    return *policyManager_;
+  }
+
+
+  /**
+   * Check the signature on the Data object and call either onVerify or onVerifyFailed. 
+   * We use callback functions because verify may fetch information to check the signature.
+   * @param data The Data object with the signature to check. It is an error if data does not have a wireEncoding. 
+   * To set the wireEncoding, you can call data.wireDecode.
+   * @param onVerified If the signature is verified, this calls onVerified(data).
+   * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
+   */
+  void
+  verifyData
+    (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount = 0);
+
+  /*****************************************
+   *      verifySignature method set       *
+   *****************************************/
+  static bool
+  verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey);
+
+
+public:
+  static const ptr_lib::shared_ptr<PolicyManager>     DefaultPolicyManager;
+    
+private:
+  void
+  onCertificateData
+    (const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
+  
+  void
+  onCertificateInterestTimeout
+    (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, 
+     const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep);
+
+private:
+  ptr_lib::shared_ptr<PolicyManager>     policyManager_;
+  ptr_lib::shared_ptr<Face>        face_;
+};
+
+}
+
+#endif
diff --git a/src/security/identity/identity-manager.cpp b/src/security/identity/identity-manager.cpp
deleted file mode 100644
index 44f0d0b..0000000
--- a/src/security/identity/identity-manager.cpp
+++ /dev/null
@@ -1,293 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
- * @author: Jeff Thompson <jefft0@remap.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#include <ndn-cpp/ndn-cpp-config.h>
-#if NDN_CPP_HAVE_TIME_H
-#include <time.h>
-#endif
-#if NDN_CPP_HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#include <ctime>
-#include <fstream>
-#include <math.h>
-#include <ndn-cpp/key-locator.hpp>
-
-#include "../../util/logging.hpp"
-#include "../../c/util/time.h"
-#include <ndn-cpp/security/identity/identity-manager.hpp>
-#include <ndn-cpp/security/certificate/identity-certificate.hpp>
-#include <ndn-cpp/security/signature/signature-sha256-with-rsa.hpp>
-
-INIT_LOGGER("ndn.security.IdentityManager")
-
-using namespace std;
-
-namespace ndn {
-
-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 (!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 self-signed certificate");
-    ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
-  
-    _LOG_DEBUG("Add self-signed certificate as default");
-
-    addCertificateAsDefault(*selfCert);
-
-    return keyName;
-  }
-  else
-    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 = info().getNewKeyName(identityName, isKsk);
-
-  _LOG_DEBUG("Generate key pair in private storage");
-  tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
-
-  _LOG_DEBUG("Create a key record in public storage");
-  ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
-  info().addKey(keyName, keyType, *pubKey);
-
-  return keyName;
-}
-
-Name
-IdentityManager::generateRSAKeyPair(const Name& identityName, bool isKsk, int keySize)
-{
-  Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-
-  return keyName;
-}
-
-Name
-IdentityManager::generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
-{
-  defaultCertificate_.reset();
-  
-  Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
-
-  info().setDefaultKeyNameForIdentity(keyName, identityName);
-  
-  return keyName;
-}
-
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
-                                           const Name& signerCertificateName,
-                                           const MillisecondsSince1970& notBefore,
-                                           const MillisecondsSince1970& notAfter)
-{
-  Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
-
-  ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
-  if (!pubKey)
-    throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
-  
-  ptr_lib::shared_ptr<IdentityCertificate> certificate =
-    createIdentityCertificate(certificatePrefix,
-                              *pubKey,
-                              signerCertificateName,
-                              notBefore, notAfter);
-
-  info().addCertificate(*certificate);
-  
-  return certificate;
-}
-
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::createIdentityCertificate(const Name& certificatePrefix,
-                                           const PublicKey& publicKey,
-                                           const Name& signerCertificateName,
-                                           const MillisecondsSince1970& notBefore,
-                                           const MillisecondsSince1970& notAfter)
-{
-  ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
-  Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
-  
-  Name certificateName = certificatePrefix;
-  certificateName.append("ID-CERT").appendVersion();
-  
-  certificate->setName(certificateName);
-  certificate->setNotBefore(notBefore);
-  certificate->setNotAfter(notAfter);
-  certificate->setPublicKeyInfo(publicKey);
-  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
-  certificate->encode();
-
-  signByCertificate(*certificate, signerCertificateName);
-
-  return certificate;
-}
-
-ptr_lib::shared_ptr<IdentityCertificate>
-IdentityManager::selfSign(const Name& keyName)
-{
-  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").appendVersion();
-
-  ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
-  if (!pubKey)
-    throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
-  
-  certificate->setName(certificateName);
-  certificate->setNotBefore(ndn_getNowMilliseconds());
-  certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
-  certificate->setPublicKeyInfo(*pubKey);
-  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
-  certificate->encode();
-
-  selfSign(*certificate);
-  return certificate;
-}
-
-void
-IdentityManager::addCertificateAsDefault(const IdentityCertificate& certificate)
-{
-  info().addCertificate(certificate);
-
-  setDefaultCertificateForKey(certificate);
-}
-
-void
-IdentityManager::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
-{
-  info().addCertificate(certificate);
-
-  Name keyName = certificate.getPublicKeyName();
-    
-  setDefaultKeyForIdentity(keyName);
-
-  setDefaultCertificateForKey(certificate);
-}
-
-void
-IdentityManager::setDefaultCertificateForKey(const IdentityCertificate& certificate)
-{
-  defaultCertificate_.reset();
-  
-  Name keyName = certificate.getPublicKeyName();
-  
-  if(!info().doesKeyExist(keyName))
-    throw Error("No corresponding Key record for certificate!");
-
-  info().setDefaultCertificateNameForKey(keyName, certificate.getName());
-}
-
-void
-IdentityManager::sign(Data &data)
-{
-  if (!defaultCertificate_)
-    {
-      defaultCertificate_ = info().getCertificate(
-                                                  info().getDefaultCertificateNameForIdentity(
-                                                                                              info().getDefaultIdentity()));
-
-      if(!defaultCertificate_)
-        throw Error("Default IdentityCertificate cannot be determined");
-    }
-
-  signByCertificate(data, *defaultCertificate_);
-}
-
-Signature
-IdentityManager::signByCertificate(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
-{
-  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
-  if (!cert)
-    throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
-  SignatureSha256WithRsa signature;
-  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
-  
-  // For temporary usage, we support RSA + SHA256 only, but will support more.
-  signature.setValue
-    (tpm().sign(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
-  return signature;
-}
-
-void
-IdentityManager::signByCertificate(Data &data, const Name &certificateName)
-{
-  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
-  if (!cert)
-    throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
-  SignatureSha256WithRsa signature;
-  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
-  data.setSignature(signature);
-
-  // For temporary usage, we support RSA + SHA256 only, but will support more.
-  tpm().sign(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-}
-
-void
-IdentityManager::signByCertificate(Data& data, const IdentityCertificate& certificate)
-{
-  SignatureSha256WithRsa signature;
-  signature.setKeyLocator(certificate.getName().getPrefix(-1));
-  data.setSignature(signature);
-
-  // For temporary usage, we support RSA + SHA256 only, but will support more.
-  tpm().sign(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-}
-
-void
-IdentityManager::selfSign (IdentityCertificate& cert)
-{
-  SignatureSha256WithRsa signature;
-  signature.setKeyLocator(cert.getName().getPrefix(cert.getName().size()-1)); // implicit conversion should take care
-  cert.setSignature(signature);
-
-  // For temporary usage, we support RSA + SHA256 only, but will support more.
-  tpm().sign(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-}
-
-Name
-IdentityManager::getKeyNameFromCertificatePrefix(const Name & certificatePrefix)
-{
-  Name result;
-
-  string keyString("KEY");
-  int i = 0;
-  for(; i < certificatePrefix.size(); i++) {
-    if (certificatePrefix.get(i).toEscapedString() == keyString)
-      break;
-  }
-    
-  if (i >= certificatePrefix.size())
-    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));
-    
-  return result;
-}
-
-}
diff --git a/src/security/key-chain.cpp b/src/security/key-chain.cpp
index e61013f..8d3f412 100644
--- a/src/security/key-chain.cpp
+++ b/src/security/key-chain.cpp
@@ -7,10 +7,10 @@
  */
 
 #include <ndn-cpp/security/key-chain.hpp>
-
-#include <ndn-cpp/security/policy/policy-manager.hpp>
-
 #include <ndn-cpp/security/identity/basic-identity-storage.hpp>
+#include <ndn-cpp/security/signature/signature-sha256-with-rsa.hpp>
+#include "../util/logging.hpp"
+#include "../c/util/time.h"
 
 
 using namespace std;
@@ -20,22 +20,17 @@
 using namespace ndn::func_lib::placeholders;
 #endif
 
+INIT_LOGGER("ndn.KeyChain");
+
 namespace ndn {
 
 const ptr_lib::shared_ptr<IdentityStorage>   KeyChain::DefaultIdentityStorage   = ptr_lib::shared_ptr<IdentityStorage>();
 const ptr_lib::shared_ptr<PrivateKeyStorage> KeyChain::DefaultPrivateKeyStorage = ptr_lib::shared_ptr<PrivateKeyStorage>();
-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<IdentityStorage>   &publicInfoStorage /* = DefaultIdentityStorage */,
-                   const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */,
-                   const ptr_lib::shared_ptr<PolicyManager>     &policyManager     /* = DefaultPolicyManager */,
-                   const ptr_lib::shared_ptr<EncryptionManager> &encryptionManager /* = DefaultEncryptionManager */)
+		 const ptr_lib::shared_ptr<PrivateKeyStorage> &privateKeyStorage /* = DefaultPrivateKeyStorage */)
   : publicInfoStorage_(publicInfoStorage)
   , privateKeyStorage_(privateKeyStorage)
-  , policyManager_(policyManager)
-  , encryptionManager_(encryptionManager)
-  // , maxSteps_(100)
 {
   if (publicInfoStorage_ == DefaultIdentityStorage)
     {
@@ -50,124 +45,280 @@
       //       m_privateStorage = Ptr<SimpleKeyStore>::Create();
 #endif  
     }
-
-  identityManager_ = ptr_lib::make_shared<IdentityManager>(publicInfoStorage_, privateKeyStorage_);
-
-  if (policyManager_ == DefaultPolicyManager)
-    {
-      // #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;
-      //
-      // #else
-      //   policyManager_ = new NoVerifyPolicyManager();
-      // #endif
-    }
-  
-  if (encryptionManager_ == DefaultEncryptionManager)
-    {
-    }
-
-// #ifdef USE_BASIC_ENCRYPTION_MANAGER
-//     encryptionManager_ = new BasicEncryptionManager(m_identityManager->getPrivateStorage(), "/tmp/encryption.db");
-// #endif
 }
 
+Name
+KeyChain::createIdentity(const Name& 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 self-signed certificate");
+    ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
+  
+    _LOG_DEBUG("Add self-signed certificate as default");
+    addCertificateAsDefault(*selfCert);
+
+    return keyName;
+  }
+  else
+    throw Error("Identity has already been created!");
+}
+
+Name
+KeyChain::generateKeyPair(const Name& identityName, bool isKsk, KeyType keyType, int keySize)
+{
+  _LOG_DEBUG("Get new key ID");    
+  Name keyName = info().getNewKeyName(identityName, isKsk);
+
+  _LOG_DEBUG("Generate key pair in private storage");
+  tpm().generateKeyPair(keyName.toUri(), keyType, keySize);
+
+  _LOG_DEBUG("Create a key record in public storage");
+  ptr_lib::shared_ptr<PublicKey> pubKey = tpm().getPublicKey(keyName.toUri());
+  info().addKey(keyName, keyType, *pubKey);
+
+  return keyName;
+}
+
+Name
+KeyChain::generateRSAKeyPair(const Name& identityName, bool isKsk, int keySize)
+{
+  Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+  return keyName;
+}
+
+Name
+KeyChain::generateRSAKeyPairAsDefault(const Name& identityName, bool isKsk, int keySize)
+{
+  defaultCertificate_.reset();
+  
+  Name keyName = generateKeyPair(identityName, isKsk, KEY_TYPE_RSA, keySize);
+
+  info().setDefaultKeyNameForIdentity(keyName, identityName);
+  
+  return keyName;
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+KeyChain::createIdentityCertificate(const Name& certificatePrefix,
+				   const Name& signerCertificateName,
+				   const MillisecondsSince1970& notBefore,
+				   const MillisecondsSince1970& notAfter)
+{
+  Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+
+  ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
+  if (!pubKey)
+    throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+  
+  ptr_lib::shared_ptr<IdentityCertificate> certificate =
+    createIdentityCertificate(certificatePrefix,
+                              *pubKey,
+                              signerCertificateName,
+                              notBefore, notAfter);
+
+  info().addCertificate(*certificate);
+  
+  return certificate;
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+KeyChain::createIdentityCertificate(const Name& certificatePrefix,
+				   const PublicKey& publicKey,
+				   const Name& signerCertificateName,
+				   const MillisecondsSince1970& notBefore,
+				   const MillisecondsSince1970& notAfter)
+{
+  ptr_lib::shared_ptr<IdentityCertificate> certificate (new IdentityCertificate());
+  Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
+  
+  Name certificateName = certificatePrefix;
+  certificateName.append("ID-CERT").appendVersion();
+  
+  certificate->setName(certificateName);
+  certificate->setNotBefore(notBefore);
+  certificate->setNotAfter(notAfter);
+  certificate->setPublicKeyInfo(publicKey);
+  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+  certificate->encode();
+
+  sign(*certificate, signerCertificateName);
+
+  return certificate;
+}
+
+Name
+KeyChain::getKeyNameFromCertificatePrefix(const Name & certificatePrefix)
+{
+  Name result;
+
+  string keyString("KEY");
+  int i = 0;
+  for(; i < certificatePrefix.size(); i++) {
+    if (certificatePrefix.get(i).toEscapedString() == keyString)
+      break;
+  }
+    
+  if (i >= certificatePrefix.size())
+    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));
+    
+  return result;
+}
+
+void
+KeyChain::setDefaultCertificateForKey(const IdentityCertificate& certificate)
+{
+  defaultCertificate_.reset();
+  
+  Name keyName = certificate.getPublicKeyName();
+  
+  if(!info().doesKeyExist(keyName))
+    throw Error("No corresponding Key record for certificate!");
+
+  info().setDefaultCertificateNameForKey(keyName, certificate.getName());
+}
+
+void
+KeyChain::addCertificateAsIdentityDefault(const IdentityCertificate& certificate)
+{
+  info().addCertificate(certificate);
+
+  Name keyName = certificate.getPublicKeyName();
+    
+  setDefaultKeyForIdentity(keyName);
+
+  setDefaultCertificateForKey(certificate);
+}
+
+void
+KeyChain::addCertificateAsDefault(const IdentityCertificate& certificate)
+{
+  info().addCertificate(certificate);
+
+  setDefaultCertificateForKey(certificate);
+}
+
+void
+KeyChain::sign(Data &data)
+{
+  if (!defaultCertificate_)
+    {
+      defaultCertificate_ = info().getCertificate(
+                                                  info().getDefaultCertificateNameForIdentity(
+                                                                                              info().getDefaultIdentity()));
+
+      if(!defaultCertificate_)
+        throw Error("Default IdentityCertificate cannot be determined");
+    }
+
+  sign(data, *defaultCertificate_);
+}
+
+void
+KeyChain::sign(Data &data, const Name &certificateName)
+{
+  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+  if (!cert)
+    throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+  data.setSignature(signature);
+
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  tpm().sign(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+}
+
+void
+KeyChain::sign(Data& data, const IdentityCertificate& certificate)
+{
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificate.getName().getPrefix(-1));
+  data.setSignature(signature);
+
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  tpm().sign(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+}
+
+Signature
+KeyChain::sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
+{
+  ptr_lib::shared_ptr<IdentityCertificate> cert = info().getCertificate(certificateName);
+  if (!cert)
+    throw Error("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
+
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
+  
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  signature.setValue
+    (tpm().sign(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+  return signature;
+}
 
 void 
 KeyChain::signByIdentity(Data& data, const Name& identityName)
 {
-  Name signingCertificateName;
-  
-  if (identityName.getComponentCount() == 0) {
-    Name inferredIdentity = policyManager_->inferSigningIdentity(data.getName());
-    if (inferredIdentity.getComponentCount() == 0)
-      signingCertificateName = identityManager_->getDefaultCertificateName();
-    else
-      signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(inferredIdentity);    
-  }
-  else
-    signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
+  Name signingCertificateName = info().getDefaultCertificateNameForIdentity(identityName);
 
   if (signingCertificateName.getComponentCount() == 0)
     throw Error("No qualified certificate name found!");
 
-  if (!policyManager_->checkSigningPolicy(data.getName(), signingCertificateName))
-    throw Error("Signing Cert name does not comply with signing policy");
-
-  identities().signByCertificate(data, signingCertificateName);
+  sign(data, signingCertificateName);
 }
 
 Signature
 KeyChain::signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
 {
-  Name signingCertificateName = identityManager_->getDefaultCertificateNameForIdentity(identityName);
+  Name signingCertificateName = info().getDefaultCertificateNameForIdentity(identityName);
     
   if (signingCertificateName.size() == 0)
     throw Error("No qualified certificate name found!");
 
-  return identities().signByCertificate(buffer, bufferLength, signingCertificateName);
+  return sign(buffer, bufferLength, signingCertificateName);
+}
+
+ptr_lib::shared_ptr<IdentityCertificate>
+KeyChain::selfSign(const Name& keyName)
+{
+  ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
+  
+  Name certificateName = keyName.getPrefix(-1);
+  certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
+
+  ptr_lib::shared_ptr<PublicKey> pubKey = info().getKey(keyName);
+  if (!pubKey)
+    throw Error("Requested public key [" + keyName.toUri() + "] doesn't exist");
+  
+  certificate->setName(certificateName);
+  certificate->setNotBefore(ndn_getNowMilliseconds());
+  certificate->setNotAfter(ndn_getNowMilliseconds() + 630720000 /* 20 years*/);
+  certificate->setPublicKeyInfo(*pubKey);
+  certificate->addSubjectDescription(CertificateSubjectDescription("2.5.4.41", keyName.toUri()));
+  certificate->encode();
+
+  selfSign(*certificate);
+  return certificate;
 }
 
 void
-KeyChain::verifyData
-  (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
+KeyChain::selfSign (IdentityCertificate& cert)
 {
-  if (policies().requireVerify(*data)) {
-    ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
-      (data, stepCount, onVerified, onVerifyFailed);
-    if (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 (policies().skipVerifyAndTrust(*data))
-    onVerified(data);
-  else
-    onVerifyFailed(data);
-}
+  SignatureSha256WithRsa signature;
+  signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
+  cert.setSignature(signature);
 
-void
-KeyChain::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep)
-{
-  // Try to verify the certificate (data) according to the parameters in nextStep.
-  verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
-}
-
-void
-KeyChain::onCertificateInterestTimeout
-  (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data, 
-   ptr_lib::shared_ptr<ValidationRequest> nextStep)
-{
-  if (retry > 0)
-    // Issue the same expressInterest as in verifyData except decrement retry.
-    face_->expressInterest
-      (*interest, 
-       bind(&KeyChain::onCertificateData, this, _1, _2, nextStep), 
-       bind(&KeyChain::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
-  else
-    onVerifyFailed(data);
+  // For temporary usage, we support RSA + SHA256 only, but will support more.
+  tpm().sign(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
 }
 
 }
diff --git a/src/security/verifier.cpp b/src/security/verifier.cpp
new file mode 100644
index 0000000..67a1f33
--- /dev/null
+++ b/src/security/verifier.cpp
@@ -0,0 +1,139 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * @author: Jeff Thompson <jefft0@remap.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#if __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreorder"
+#pragma clang diagnostic ignored "-Wtautological-compare"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#pragma clang diagnostic ignored "-Wunused-function"
+#elif __GNUC__
+#pragma GCC diagnostic ignored "-Wreorder"
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#include <ndn-cpp/security/verifier.hpp>
+
+#include <ndn-cpp/security/policy/policy-manager.hpp>
+
+#include <cryptopp/rsa.h>
+
+#include "../util/logging.hpp"
+
+using namespace std;
+using namespace ndn::func_lib;
+#if NDN_CPP_HAVE_CXX11
+// In the std library, the placeholders are in a different namespace than boost.
+using namespace ndn::func_lib::placeholders;
+#endif
+
+INIT_LOGGER("ndn.Verifier");
+
+namespace ndn {
+const ptr_lib::shared_ptr<PolicyManager>     Verifier::DefaultPolicyManager     = ptr_lib::shared_ptr<PolicyManager>();
+
+Verifier::Verifier(const ptr_lib::shared_ptr<PolicyManager>     &policyManager     /* = DefaultPolicyManager */)                   
+  : policyManager_(policyManager)
+{
+  if (policyManager_ == DefaultPolicyManager)
+    {
+      // #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;
+      //
+      // #else
+      //   policyManager_ = new NoVerifyPolicyManager();
+      // #endif
+    }  
+}
+
+void
+Verifier::verifyData
+  (const ptr_lib::shared_ptr<Data>& data, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed, int stepCount)
+{
+  if (policies().requireVerify(*data)) {
+    ptr_lib::shared_ptr<ValidationRequest> nextStep = policyManager_->checkVerificationPolicy
+      (data, stepCount, onVerified, onVerifyFailed);
+    if (static_cast<bool>(nextStep))
+      {
+        if (!face_)
+          throw Error("Face should be set prior to verifyData method to call");
+        
+        face_->expressInterest
+          (*nextStep->interest_, 
+           bind(&Verifier::onCertificateData, this, _1, _2, nextStep), 
+           bind(&Verifier::onCertificateInterestTimeout, this, _1, nextStep->retry_, onVerifyFailed, data, nextStep));
+      }
+  }
+  else if (policies().skipVerifyAndTrust(*data))
+    onVerified(data);
+  else
+    onVerifyFailed(data);
+}
+
+void
+Verifier::onCertificateData(const ptr_lib::shared_ptr<const Interest> &interest, const ptr_lib::shared_ptr<Data> &data, ptr_lib::shared_ptr<ValidationRequest> nextStep)
+{
+  // Try to verify the certificate (data) according to the parameters in nextStep.
+  verifyData(data, nextStep->onVerified_, nextStep->onVerifyFailed_, nextStep->stepCount_);
+}
+
+void
+Verifier::onCertificateInterestTimeout
+  (const ptr_lib::shared_ptr<const Interest> &interest, int retry, const OnVerifyFailed& onVerifyFailed, const ptr_lib::shared_ptr<Data> &data, 
+   ptr_lib::shared_ptr<ValidationRequest> nextStep)
+{
+  if (retry > 0)
+    // Issue the same expressInterest as in verifyData except decrement retry.
+    face_->expressInterest
+      (*interest, 
+       bind(&Verifier::onCertificateData, this, _1, _2, nextStep), 
+       bind(&Verifier::onCertificateInterestTimeout, this, _1, retry - 1, onVerifyFailed, data, nextStep));
+  else
+    onVerifyFailed(data);
+}
+
+bool
+Verifier::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
+{
+  using namespace CryptoPP;
+
+  bool result = false;
+  
+  RSA::PublicKey publicKey;
+  ByteQueue queue;
+
+  queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
+  publicKey.Load(queue);
+
+  RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+  result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
+				  sig.getValue().value(), sig.getValue().value_size());
+
+  _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
+  
+  return result;
+}
+
+}