security: Consistent exception handling.

Change-Id: Ia29963e96028e591e9c4fc4a68a472f794b17e52
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index b9cb2d4..6ac1668 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -14,6 +14,7 @@
 #include "signature-sha256-with-rsa.hpp"
 #include "../interest.hpp"
 #include "../encoding/tlv-security.hpp"
+#include "../util/random.hpp"
 
 //PublicInfo
 #include "sec-public-info-sqlite3.hpp"
@@ -30,7 +31,7 @@
 namespace ndn {
 
 /**
- * KeyChain is one of the main classes of the security library.
+ * @brief KeyChain is one of the main classes of the security library.
  *
  * The KeyChain class provides a set of interfaces of identity management and private key related operations.
  */
@@ -38,41 +39,35 @@
 class KeyChainImpl : public Info, public Tpm
 {
   typedef typename Info::Error InfoError;
+  typedef typename Tpm::Error TpmError;
 public:
-
   /**
-   * @brief Unlock key chain
+   * @brief Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
    *
-   * @param password The password.
-   * @param passwordLength The password size.
-   * @param usePassword True if password parameter is used.
-   */
-  void
-  unlock(const char* password, size_t passwordLength, bool usePassword)
-  { 
-    return Tpm::unlockTpm(password, passwordLength, usePassword); 
-  }
-
-  
-  /**
-   * 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 name of the default certificate of the identity.
    */
   Name
   createIdentity(const Name& identityName)
   {
-    if (!Info::doesIdentityExist(identityName))
-      Info::addIdentity(identityName);
- 
-    Name keyName = Info::getDefaultKeyNameForIdentity(identityName);
+    Info::addIdentity(identityName);
     
-    if(keyName.empty())
-      keyName = generateRSAKeyPairAsDefault(identityName, true);
+    Name keyName;
+    try
+      {
+        keyName = Info::getDefaultKeyNameForIdentity(identityName);
+      }
+    catch(InfoError& e)
+      {
+        keyName = generateRSAKeyPairAsDefault(identityName, true);
+      }
 
-    Name certName = Info::getDefaultCertificateNameForKey(keyName);
-
-    if(certName.empty())
+    Name certName;
+    try
+      {
+        certName = Info::getDefaultCertificateNameForKey(keyName);
+      }
+    catch(InfoError& e)
       {
         shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
         Info::addCertificateAsIdentityDefault(*selfCert);
@@ -83,7 +78,8 @@
   }
     
   /**
-   * Generate a pair of RSA keys for the specified identity.
+   * @brief 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.
@@ -96,7 +92,8 @@
   }
   
   /**
-   * Generate a pair of RSA keys for the specified identity and set it as default key for the identity.
+   * @brief 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.
@@ -113,193 +110,118 @@
   }
 
   /**
-   * 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.
+   * @brief Sign packet with default identity
+   *
+   * on return signatureInfo and signatureValue in the packet are set.
+   *
+   * @param packet The packet to be signed
    */
-  shared_ptr<IdentityCertificate>
-  createIdentityCertificate
-    (const Name& certificatePrefix,
-     const Name& signerCertificateName,
-     const MillisecondsSince1970& notBefore, 
-     const MillisecondsSince1970& notAfter)
-  {
-    Name keyName = getKeyNameFromCertificatePrefix(certificatePrefix);
-    
-    shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
-    if (!pubKey)
-      throw InfoError("Requested public key [" + keyName.toUri() + "] doesn't exist");
-    
-    shared_ptr<IdentityCertificate> certificate =
-      createIdentityCertificate(certificatePrefix,
-                                *pubKey,
-                                signerCertificateName,
-                                notBefore, notAfter);
-
-    Info::addCertificate(*certificate);
-  
-    return certificate;
-  }
-
-
-  /**
-   * 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.
-   */
-  shared_ptr<IdentityCertificate>
-  createIdentityCertificate
-    (const Name& certificatePrefix,
-     const PublicKey& publicKey,
-     const Name& signerCertificateName, 
-     const MillisecondsSince1970& notBefore,
-     const MillisecondsSince1970& notAfter)
-  {
-    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;
-  }
-
+  template<typename T>
   void
-  sign(Data &data)
+  sign(T& packet)
   {
     if (!Info::defaultCertificate())
       {
         Info::refreshDefaultCertificate();
 
         if(!Info::defaultCertificate())
-          throw InfoError("Default IdentityCertificate cannot be determined");
+          {
+            Name defaultIdentity;
+            try
+              {
+                defaultIdentity = Info::getDefaultIdentity();
+              }
+            catch(InfoError& e)
+              {
+                uint32_t random = random::generateWord32();
+                defaultIdentity.append("tmp-identity").append(reinterpret_cast<uint8_t*>(&random), 4);
+              }
+            createIdentity(defaultIdentity);
+            Info::refreshDefaultCertificate();
+          }
       }
 
-    sign(data, *Info::defaultCertificate());
-  }
-
-  void
-  sign(Interest &interest)
-  {
-    if (!Info::defaultCertificate())
-      {
-        Info::refreshDefaultCertificate();
-
-        if(!Info::defaultCertificate())
-          throw InfoError("Default IdentityCertificate cannot be determined");
-      }
-
-    sign(interest, *Info::defaultCertificate());
+    sign(packet, *Info::defaultCertificate());
   }
   
   /**
-   * Wire encode the Data object, sign it and set its signature.
-   * @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.
+   * @brief Sign packet with a particular certificate.
+   *
+   * @param packet The packet to be signed.
+   * @param certificateName The certificate name of the key to use for signing.
+   * @throws SecPublicInfo::Error if certificate does not exist.
    */
+  template<typename T>
   void 
-  sign(Data& data, const Name& certificateName)
+  sign(T& packet, const Name& certificateName)
   {
-    shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
-    if (!cert)
+    if (!Info::doesCertificateExist(certificateName))
       throw InfoError("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.
-    signDataInTpm(data, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-  }
-
-  void
-  sign(Interest &interest, const Name &certificateName)
-  {
-    shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
-    if(!static_cast<bool>(cert))
-      throw InfoError("Requested certificate [" + certificateName.toUri() + "] doesn't exist");
-
-    SignatureSha256WithRsa signature;
-    signature.setKeyLocator(certificateName.getPrefix(-1)); // implicit conversion should take care
-
-    Name signedName = Name(interest.getName()).append(signature.getInfo());
-
-    signature.setValue(Tpm::signInTpm(signedName.wireEncode().value(), 
-                                      signedName.wireEncode().value_size(), 
-                                      cert->getPublicKeyName(),
-                                      DIGEST_ALGORITHM_SHA256));
-    signedName.append(signature.getValue());
-    interest.setName(signedName);
+    signPacketWrapper(packet, signature, 
+                      IdentityCertificate::certificateNameToPublicKeyName(certificateName), 
+                      DIGEST_ALGORITHM_SHA256);
   }
   
   /**
-   * Sign the byte array using a certificate name and return a Signature object.
+   * @brief Sign the byte array using a particular certificate.
+   *
    * @param buffer The byte array to be signed.
    * @param bufferLength the length of buffer.
-   * @param certificateName The certificate name used to get the signing key and which will be put into KeyLocator.
+   * @param certificateName The certificate name of the signing key.
    * @return The Signature.
+   * @throws SecPublicInfo::Error if certificate does not exist.
    */
   Signature
   sign(const uint8_t* buffer, size_t bufferLength, const Name& certificateName)
   {
-    shared_ptr<IdentityCertificate> cert = Info::getCertificate(certificateName);
-    if (!static_cast<bool>(cert))
+    if (!Info::doesCertificateExist(certificateName))
       throw InfoError("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::signInTpm(buffer, bufferLength, cert->getPublicKeyName(), DIGEST_ALGORITHM_SHA256));
+    signature.setValue(Tpm::signInTpm(buffer, bufferLength, 
+                                      IdentityCertificate::certificateNameToPublicKeyName(certificateName), 
+                                      DIGEST_ALGORITHM_SHA256));
     return signature;
   }
 
   /**
-   * Wire encode the Data object, sign it and set its signature.
-   * @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.
+   * @brief Sign packet using the default certificate of a particular identity.
+   *
+   * If there is no default certificate of that identity, this method will create a self-signed certificate.
+   *
+   * @param packet The packet to be signed.
+   * @param identityName The signing identity name.
    */
+  template<typename T>
   void 
-  signByIdentity(Data& data, const Name& identityName)
+  signByIdentity(T& packet, const Name& identityName)
   {
-    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+    Name signingCertificateName;
+    try
+      {
+        signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+      }
+    catch(InfoError& e)
+      {
+        signingCertificateName = createIdentity(identityName); 
+        // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which is a fatal error.
+      }
 
-    if (signingCertificateName.empty())
-      signingCertificateName = createIdentity(identityName);
-
-    sign(data, signingCertificateName);
+    // We either get or create the signing certificate, sign packet! (no exception unless fatal error in TPM)
+    sign(packet, signingCertificateName);
   }
 
-  void 
-  signByIdentity(Interest& interest, const Name& identityName)
-  {
-    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
-
-    if (signingCertificateName.empty())
-      signingCertificateName = createIdentity(identityName);
-
-    sign(interest, signingCertificateName);
-  }
-
-
   /**
-   * Sign the byte array using an identity name and return a Signature object.
+   * @brief Sign the byte array using the default certificate of a particular identity.
+   *
    * @param buffer The byte array to be signed.
    * @param bufferLength the length of buffer.
    * @param identityName The identity name.
@@ -308,34 +230,45 @@
   Signature
   signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
   {
-    Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+    Name signingCertificateName;
+    try
+      {
+        signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
+      }
+    catch(InfoError& e)
+      {
+        signingCertificateName = createIdentity(identityName); 
+        // Ideally, no exception will be thrown out, unless something goes wrong in the TPM, which is a fatal error.
+      }
     
-    if (signingCertificateName.empty())
-      signingCertificateName = createIdentity(identityName);
-
+    // We either get or create the signing certificate, sign data! (no exception unless fatal error in TPM)
     return sign(buffer, bufferLength, signingCertificateName);
   }
 
   /**
-   * Generate a self-signed certificate for a public key.
+   * @brief Generate a self-signed certificate for a public key.
+   *
    * @param keyName The name of the public key.
-   * @return The generated certificate.
+   * @return The generated certificate, NULL if selfSign fails.
    */
   shared_ptr<IdentityCertificate>
   selfSign(const Name& keyName)
   {
-    if(keyName.empty())
-      throw InfoError("Incorrect key name: " + keyName.toUri());
+    shared_ptr<PublicKey> pubKey;
+    try
+      {
+        pubKey = Info::getPublicKey(keyName); // may throw an exception.
+      }
+    catch(InfoError& e)
+      {
+        return shared_ptr<IdentityCertificate>();
+      }
 
     shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
     
     Name certificateName = keyName.getPrefix(-1);
     certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
-    
-    shared_ptr<PublicKey> pubKey = Info::getPublicKey(keyName);
-    if (!pubKey)
-      throw InfoError("Requested public key [" + keyName.toUri() + "] doesn't exist");
-  
+
     certificate->setName(certificateName);
     certificate->setNotBefore(getNow());
     certificate->setNotAfter(getNow() + 630720000 /* 20 years*/);
@@ -348,43 +281,94 @@
   }
 
   /**
-   * @brief Self-sign the supplied identity certificate
+   * @brief Self-sign the supplied identity certificate.
+   *
+   * @param cert The supplied cert.
+   * @throws SecTpm::Error if the private key does not exist.
    */
   void
   selfSign (IdentityCertificate& cert)
   {
+    Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert.getName());
+    if(!Tpm::doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
+      throw TpmError("private key does not exist!");
+
     SignatureSha256WithRsa signature;
     signature.setKeyLocator(cert.getName().getPrefix(-1)); // implicit conversion should take care
-    cert.setSignature(signature);
 
     // For temporary usage, we support RSA + SHA256 only, but will support more.
-    signDataInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
+    signPacketWrapper(cert, signature, keyName, DIGEST_ALGORITHM_SHA256);
   }
 
+  /**
+   * @brief delete a certificate.
+   *
+   * If the certificate to be deleted is current default system default, 
+   * the method will not delete the certificate and return immediately.
+   * 
+   * @param certificateName The certificate to be deleted.
+   */
   void
-  deleteCertificate (const Name &certificateName)
+  deleteCertificate (const Name& certificateName)
   {
-    if(Info::getDefaultIdentity() == IdentityCertificate::certificateNameToPublicKeyName(certificateName).getPrefix(-1))
-      return;
+    try
+      {
+        if(Info::getDefaultCertificateName() == certificateName)
+          return;
+      }
+    catch(InfoError& e)
+      {
+        // Not a real error, just try to delete the certificate
+      }
 
     Info::deleteCertificateInfo(certificateName);
   }
 
+  /**
+   * @brief delete a key.
+   *
+   * If the key to be deleted is current default system default, 
+   * the method will not delete the key and return immediately.
+   * 
+   * @param keyName The key to be deleted.
+   */
   void
-  deleteKey (const Name &keyName)
+  deleteKey (const Name& keyName)
   {
-    if(Info::getDefaultIdentity() == keyName.getPrefix(-1))
-      return;
+    try
+      {
+        if(Info::getDefaultKeyNameForIdentity(Info::getDefaultIdentity()) == keyName)
+          return;
+      }
+    catch(InfoError& e)
+      {
+        // Not a real error, just try to delete the key
+      }
 
     Info::deletePublicKeyInfo(keyName);
     Tpm::deleteKeyPairInTpm(keyName);
   }
 
+  /**
+   * @brief delete an identity.
+   *
+   * If the identity to be deleted is current default system default, 
+   * the method will not delete the identity and return immediately.
+   * 
+   * @param identity The identity to be deleted.
+   */
   void
   deleteIdentity (const Name& identity)
   {
-    if(Info::getDefaultIdentity() == identity)
-      return;
+    try
+      {
+        if(Info::getDefaultIdentity() == identity)
+          return;
+      }
+    catch(InfoError& e)
+      {
+        // Not a real error, just try to delete the identity
+      }
 
     std::vector<Name> nameList;
     Info::getAllKeyNamesOfIdentity(identity, nameList, true);
@@ -397,6 +381,14 @@
       Tpm::deleteKeyPairInTpm(*it);
   }
 
+  /**
+   * @brief export an identity.
+   *
+   * @param identity The identity to export.
+   * @param passwordStr The password to secure the private key.
+   * @param The encoded export data.
+   * @throws InfoError if anything goes wrong in exporting.
+   */
   Block
   exportIdentity(const Name& identity, const std::string& passwordStr)
   {
@@ -404,23 +396,29 @@
       throw InfoError("Identity does not exist!");
  
     Name keyName = Info::getDefaultKeyNameForIdentity(identity);
-    
-    if(keyName.empty())
-      throw InfoError("Default key does not exist!");
 
-    ConstBufferPtr pkcs8 = Tpm::exportPrivateKeyPkcs8FromTpm(keyName, passwordStr);
+    ConstBufferPtr pkcs8;
+    try
+      {
+        pkcs8 = Tpm::exportPrivateKeyPkcs8FromTpm(keyName, passwordStr);
+      }
+    catch(TpmError& e)
+      {
+        throw InfoError("Fail to export PKCS8 of private key");
+      }
     Block wireKey(tlv::security::KeyPackage, pkcs8);
 
-    Name certName = Info::getDefaultCertificateNameForKey(keyName);
 
-    if(certName.empty())
+    shared_ptr<IdentityCertificate> cert;    
+    try
       {
-        shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
-        Info::addCertificateAsIdentityDefault(*selfCert);
-        certName = selfCert->getName();
+        cert = Info::getCertificate(Info::getDefaultCertificateNameForKey(keyName));
       }
-
-    shared_ptr<IdentityCertificate> cert = Info::getCertificate(certName);
+    catch(InfoError& e)
+      {
+        cert = selfSign(keyName); 
+        Info::addCertificateAsIdentityDefault(*cert);
+      }
     Block wireCert(tlv::security::CertificatePackage, cert->wireEncode());
 
     Block wire(tlv::security::IdentityPackage);
@@ -430,71 +428,67 @@
     return wire;
   }
 
+  /**
+   * @brief import an identity.
+   *
+   * @param The encoded import data.
+   * @param passwordStr The password to secure the private key.
+   */
   void
   importIdentity(const Block& block, const std::string& passwordStr)
   {
-    block.parse();
+    try
+      {
+        block.parse();
     
-    Data data;
-    data.wireDecode(block.get(tlv::security::CertificatePackage).blockFromValue());
-    shared_ptr<IdentityCertificate> cert = make_shared<IdentityCertificate>(data);
+        Data data;
+        data.wireDecode(block.get(tlv::security::CertificatePackage).blockFromValue());
+        shared_ptr<IdentityCertificate> cert = make_shared<IdentityCertificate>(data);
     
-    Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert->getName());
-    Name identity = keyName.getPrefix(-1);
-
-    // Add identity
-    if (Info::doesIdentityExist(identity))
-      deleteIdentity(identity);
-    Info::addIdentity(identity);
-
-    // Add key
-    Block wireKey = block.get(tlv::security::KeyPackage);
-    if (Tpm::doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
-      deleteKey(keyName);
-    Tpm::importPrivateKeyPkcs8IntoTpm(keyName, wireKey.value(), wireKey.value_size(), passwordStr);
-    shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
-    Info::addPublicKey(keyName, KEY_TYPE_RSA, *pubKey); // HACK! We should set key type according to the pkcs8 info.
-    Info::setDefaultKeyNameForIdentity(keyName);
-
-    // Add cert
-    if (Info::doesCertificateExist(cert->getName()))
-        deleteCertificate(cert->getName());
-    Info::addCertificateAsIdentityDefault(*cert);
+        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(cert->getName());
+        Name identity = keyName.getPrefix(-1);
+        
+        // Add identity
+        Info::addIdentity(identity);
+        
+        // Add key
+        Block wireKey = block.get(tlv::security::KeyPackage);
+        Tpm::importPrivateKeyPkcs8IntoTpm(keyName, wireKey.value(), wireKey.value_size(), passwordStr);
+        shared_ptr<PublicKey> pubKey = Tpm::getPublicKeyFromTpm(keyName.toUri());
+        Info::addPublicKey(keyName, KEY_TYPE_RSA, *pubKey); // HACK! We should set key type according to the pkcs8 info.
+        Info::setDefaultKeyNameForIdentity(keyName);
+        
+        // Add cert
+        Info::addCertificateAsIdentityDefault(*cert);
+      }
+    catch(Block::Error& e)
+      {
+        return;
+      }
   }
 
 
 private:
-
+  /**
+   * @brief sign a packet using a pariticular certificate.
+   *
+   * @param packet The packet to be signed.
+   * @param certificate The signing certificate.
+   */
+  template<typename T>
   void
-  sign(Data &data, const IdentityCertificate& certificate)
+  sign(T& packet, 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.
-    signDataInTpm(data, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
-  }
-
-  void
-  sign(Interest &interest, const IdentityCertificate& certificate)
-  {
-    SignatureSha256WithRsa signature;
-    signature.setKeyLocator(certificate.getName().getPrefix(-1)); // implicit conversion should take care
-
-    Name signedName = Name(interest.getName()).append(signature.getInfo());
-
-    signature.setValue(Tpm::signInTpm(signedName.wireEncode().value(), 
-                                      signedName.wireEncode().value_size(), 
-                                      certificate.getPublicKeyName(), 
-                                      DIGEST_ALGORITHM_SHA256));
-    
-    signedName.append(signature.getValue());
-    interest.setName(signedName);
+    signPacketWrapper(packet, signature, certificate.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
   }
 
   /**
-   * Generate a key pair for the specified identity.
+   * @brief 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.
@@ -514,43 +508,49 @@
     return keyName;
   }
 
-  static Name
-  getKeyNameFromCertificatePrefix(const Name& certificatePrefix)
-  {
-    Name result;
-
-    std::string keyString("KEY");
-    int i = 0;
-    for(; i < certificatePrefix.size(); i++) {
-      if (certificatePrefix.get(i).toEscapedString() == keyString)
-        break;
-    }
-    
-    if (i >= certificatePrefix.size())
-      throw InfoError("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;
-  }
-
   /**
-   * Fetch the private key for keyName and sign the data, and set the signature block of the data packet.
-   * @param data Reference to the input data packet.
+   * @brief Sign the data using a particular key.
+   *
+   * @param data Reference to the data packet.
+   * @param signature Signature to be added.
    * @param keyName The name of the signing key.
    * @param digestAlgorithm the digest algorithm.
    * @throws Tpm::Error
    */  
   void
-  signDataInTpm(Data &data, const Name& keyName, DigestAlgorithm digestAlgorithm)
+  signPacketWrapper(Data& data, const SignatureSha256WithRsa& signature, const Name& keyName, DigestAlgorithm digestAlgorithm)
   {
+    data.setSignature(signature);
     data.setSignatureValue
       (Tpm::signInTpm(data.wireEncode().value(),
                       data.wireEncode().value_size() - data.getSignature().getValue().size(),
                       keyName, digestAlgorithm));
   }
 
+  /**
+   * @brief Sign the interest using a particular key.
+   *
+   * @param interest Reference to the interest packet.
+   * @param signature Signature to be added.
+   * @param keyName The name of the signing key.
+   * @param digestAlgorithm the digest algorithm.
+   * @throws Tpm::Error
+   */  
+  void
+  signPacketWrapper(Interest& interest, const SignatureSha256WithRsa& signature, const Name& keyName, DigestAlgorithm digestAlgorithm)
+  {
+    Name signedName = Name(interest.getName()).append(signature.getInfo());
+
+    Block sigValue = Tpm::signInTpm(signedName.wireEncode().value(), 
+                                    signedName.wireEncode().value_size(), 
+                                    keyName,
+                                    DIGEST_ALGORITHM_SHA256);
+    sigValue.encode();
+    signedName.append(sigValue);
+    interest.setName(signedName);
+  }
+
+
 };
 
 } // namespace ndn
diff --git a/src/security/sec-public-info-memory.cpp b/src/security/sec-public-info-memory.cpp
index 1e41df1..82affaa 100644
--- a/src/security/sec-public-info-memory.cpp
+++ b/src/security/sec-public-info-memory.cpp
@@ -30,7 +30,7 @@
 {
   string identityUri = identityName.toUri();
   if (find(identityStore_.begin(), identityStore_.end(), identityUri) != identityStore_.end())
-    throw Error("Identity already exists: " + identityUri);
+    return;
   
   identityStore_.push_back(identityUri);
 }
@@ -39,7 +39,7 @@
 SecPublicInfoMemory::revokeIdentity()
 {
 #if 1
-  throw runtime_error("SecPublicInfoMemory::revokeIdentity not implemented");
+  throw Error("SecPublicInfoMemory::revokeIdentity not implemented");
 #endif
 }
 
@@ -54,40 +54,19 @@
 {
   Name identityName = keyName.getSubName(0, keyName.size() - 1);
 
-  if (!doesIdentityExist(identityName))
-    addIdentity(identityName);
-
-  if (doesPublicKeyExist(keyName))
-    throw Error("a key with the same name already exists!");
+  addIdentity(identityName);
   
-  keyStore_[keyName.toUri()] = ptr_lib::make_shared<KeyRecord>(keyType, publicKey);
+  keyStore_[keyName.toUri()] = make_shared<KeyRecord>(keyType, publicKey);
 }
 
-ptr_lib::shared_ptr<PublicKey>
+shared_ptr<PublicKey>
 SecPublicInfoMemory::getPublicKey(const Name& keyName)
 {
   KeyStore::iterator record = keyStore_.find(keyName.toUri());
   if (record == keyStore_.end())
-    // Not found.  Silently return null.
-    return ptr_lib::shared_ptr<PublicKey>();
+    throw Error("SecPublicInfoMemory::getPublicKey  " + keyName.toUri());
   
-  return ptr_lib::make_shared<PublicKey> (record->second->getKey());
-}
-
-void 
-SecPublicInfoMemory::activatePublicKey(const Name& keyName)
-{
-#if 1
-  throw runtime_error("SecPublicInfoMemory::activateKey not implemented");
-#endif
-}
-
-void 
-SecPublicInfoMemory::deactivatePublicKey(const Name& keyName)
-{
-#if 1
-  throw runtime_error("SecPublicInfoMemory::deactivateKey not implemented");
-#endif
+  return make_shared<PublicKey> (record->second->getKey());
 }
 
 bool
@@ -101,30 +80,19 @@
 {
   const Name& certificateName = certificate.getName();
   const Name& keyName = certificate.getPublicKeyName();
+  const Name& identity = keyName.getPrefix(-1);
 
-  if (!doesPublicKeyExist(keyName))
-    throw Error("No corresponding Key record for certificate! " + keyName.toUri() + " " + certificateName.toUri());
-
-  // Check if certificate has already existed!
-  if (doesCertificateExist(certificateName))
-    throw Error("Certificate has already been installed!");
-
-  // Check if the public key of certificate is the same as the key record. 
-  ptr_lib::shared_ptr<PublicKey> pubKey = getPublicKey(keyName);
-  if (!pubKey || (*pubKey) != certificate.getPublicKeyInfo())
-    throw Error("Certificate does not match the public key!");
-  
-  // Insert the certificate.
-  certificateStore_[certificateName.toUri()] = ptr_lib::make_shared<IdentityCertificate> (certificate);
+  addIdentity(identity);
+  addPublicKey(keyName, KEY_TYPE_RSA, certificate.getPublicKeyInfo());
+  certificateStore_[certificateName.toUri()] = make_shared<IdentityCertificate> (certificate);
 }
 
-ptr_lib::shared_ptr<IdentityCertificate> 
+shared_ptr<IdentityCertificate> 
 SecPublicInfoMemory::getCertificate(const Name& certificateName)
 {
   CertificateStore::iterator record = certificateStore_.find(certificateName.toUri());
   if (record == certificateStore_.end())
-    // Not found.  Silently return null.
-    return ptr_lib::shared_ptr<IdentityCertificate>();
+    throw Error("SecPublicInfoMemory::getCertificate  " + certificateName.toUri());
 
   return record->second;
 }
@@ -174,49 +142,49 @@
 void
 SecPublicInfoMemory::getAllIdentities(std::vector<Name> &nameList, bool isDefault)
 {
-  throw runtime_error("SecPublicInfoMemory::getAllIdentities not implemented");
+  throw Error("SecPublicInfoMemory::getAllIdentities not implemented");
 }
 
 void
 SecPublicInfoMemory::getAllKeyNames(std::vector<Name> &nameList, bool isDefault)
 {
-  throw runtime_error("SecPublicInfoMemory::getAllKeyNames not implemented");
+  throw Error("SecPublicInfoMemory::getAllKeyNames not implemented");
 }
 
 void
 SecPublicInfoMemory::getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name> &nameList, bool isDefault)
 {
-  throw runtime_error("SecPublicInfoMemory::getAllKeyNamesOfIdentity not implemented");
+  throw Error("SecPublicInfoMemory::getAllKeyNamesOfIdentity not implemented");
 }
     
 void
 SecPublicInfoMemory::getAllCertificateNames(std::vector<Name> &nameList, bool isDefault)
 {
-  throw runtime_error("SecPublicInfoMemory::getAllCertificateNames not implemented");
+  throw Error("SecPublicInfoMemory::getAllCertificateNames not implemented");
 }
 
 void
 SecPublicInfoMemory::getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault)
 {
-  throw runtime_error("SecPublicInfoMemory::getAllCertificateNamesOfKey not implemented");
+  throw Error("SecPublicInfoMemory::getAllCertificateNamesOfKey not implemented");
 }
 
 void
 SecPublicInfoMemory::deleteCertificateInfo(const Name &certName)
 {
-  throw runtime_error("SecPublicInfoMemory::deleteCertificateInfo not implemented");
+  throw Error("SecPublicInfoMemory::deleteCertificateInfo not implemented");
 }
 
 void
 SecPublicInfoMemory::deletePublicKeyInfo(const Name &keyName)
 {
-  throw runtime_error("SecPublicInfoMemory::deletePublicKeyInfo not implemented");
+  throw Error("SecPublicInfoMemory::deletePublicKeyInfo not implemented");
 }
 
 void
 SecPublicInfoMemory::deleteIdentityInfo(const Name &identityName)
 {
-  throw runtime_error("SecPublicInfoMemory::deleteIdentityInfo not implemented");
+  throw Error("SecPublicInfoMemory::deleteIdentityInfo not implemented");
 }
 
 } // namespace ndn
diff --git a/src/security/sec-public-info-memory.hpp b/src/security/sec-public-info-memory.hpp
index 04104ea..16001c8 100644
--- a/src/security/sec-public-info-memory.hpp
+++ b/src/security/sec-public-info-memory.hpp
@@ -14,130 +14,49 @@
 namespace ndn {
 
 /**
- * MemoryKeyMetaInfo extends IdentityStorage and implements its methods to store identity, public key and certificate objects in memory.
- * The application must get the objects through its own means and add the objects to the MemoryKeyMetaInfo object.
- * To use permanent file-based storage, see BasicKeyMetaInfo.
+ * @brief SecPublicInfoMemory extends SecPublicInfo and implements its methods to store identity, public key and certificate objects in memory.
  */
 class SecPublicInfoMemory : public SecPublicInfo {
 public:
   struct Error : public SecPublicInfo::Error { Error(const std::string &what) : SecPublicInfo::Error(what) {} };
 
-  /**
-   * The virtual Destructor.
-   */
   virtual
   ~SecPublicInfoMemory();
 
-  /**
-   * Check if the specified identity already exists.
-   * @param identityName The identity name.
-   * @return true if the identity exists, otherwise false.
-   */
   virtual bool
   doesIdentityExist(const Name& identityName);
 
-  /**
-   * Add a new identity. An exception will be thrown if the identity already exists.
-   * @param identityName The identity name to be added.
-   */
   virtual void
   addIdentity(const Name& identityName);
 
-  /**
-   * Revoke the identity.
-   * @return true if the identity was revoked, false if not.
-   */
   virtual bool
   revokeIdentity();
 
-  /**
-   * Check if the specified key already exists.
-   * @param keyName The name of the key.
-   * @return true if the key exists, otherwise false.
-   */
   virtual bool 
   doesPublicKeyExist(const Name& keyName);
 
-  /**
-   * Add a public key to the identity storage.
-   * @param keyName The name of the public key to be added.
-   * @param keyType Type of the public key to be added.
-   * @param publicKeyDer A blob of the public key DER to be added.
-   */
   virtual void 
   addPublicKey(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 ptr_lib::shared_ptr<PublicKey>
   getPublicKey(const Name& keyName);
 
-  /**
-   * Activate a key.  If a key is marked as inactive, its private part will not be used in packet signing.
-   * @param keyName name of the key
-   */
-  virtual void 
-  activatePublicKey(const Name& keyName);
-
-  /**
-   * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
-   * @param keyName name of the key
-   */
-  virtual void 
-  deactivatePublicKey(const Name& keyName);
-
-  /**
-   * Check if the specified certificate already exists.
-   * @param certificateName The name of the certificate.
-   * @return true if the certificate exists, otherwise false.
-   */
   virtual bool
   doesCertificateExist(const Name& certificateName);
 
-  /**
-   * Add a certificate to the identity storage.
-   * @param certificate The certificate to be added.  This makes a copy of the certificate.
-   */
   virtual void 
   addCertificate(const IdentityCertificate& certificate);
 
-  /**
-   * Get a certificate from the identity storage.
-   * @param certificateName The name of the requested certificate.
-   * @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<IdentityCertificate> 
   getCertificate(const Name &certificateName);
 
 
-  /*****************************************
-   *           Get/Set Default             *
-   *****************************************/
-
-  /**
-   * Get the default identity. 
-   * @param return The name of default identity, or an empty name if there is no default.
-   */
   virtual Name 
   getDefaultIdentity();
 
-  /**
-   * Get the default key name for the specified identity.
-   * @param identityName The identity name.
-   * @return The default key name.
-   */
   virtual Name 
   getDefaultKeyNameForIdentity(const Name& identityName);
 
-  /**
-   * Get the default certificate name for the specified key.
-   * @param keyName The key name.
-   * @return The default certificate name.
-   */
   virtual Name 
   getDefaultCertificateNameForKey(const Name& keyName);
 
@@ -157,48 +76,21 @@
   getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault);
 
 protected:
-  /**
-   * Set the default identity.  If the identityName does not exist, then clear the default identity
-   * so that getDefaultIdentity() returns an empty name.
-   * @param identityName The default identity name.
-   */
   virtual void 
   setDefaultIdentityInternal(const Name& identityName);
 
-  /**
-   * Set the default key name for the specified identity.
-   * @param keyName The key name.
-   * @param identityNameCheck (optional) The identity name to check the keyName.
-   */
   virtual void 
   setDefaultKeyNameForIdentityInternal(const Name& keyName);
 
-  /**
-   * Set the default key name for the specified identity.
-   * @param keyName The key name.
-   * @param certificateName The certificate name.
-   */
   virtual void 
   setDefaultCertificateNameForKeyInternal(const Name& certificateName);  
 
-  /**
-   * Delete a certificate.
-   * @param certificateName The certificate name.
-   */
   virtual void
   deleteCertificateInfo(const Name &certificateName);
 
-  /**
-   * Delete a public key and related certificates.
-   * @param keyName The key name.
-   */
   virtual void
   deletePublicKeyInfo(const Name &keyName);
 
-  /**
-   * Delete an identity and related public keys and certificates.
-   * @param identity The identity name.
-   */
   virtual void
   deleteIdentityInfo(const Name &identity);
 
diff --git a/src/security/sec-public-info-sqlite3.cpp b/src/security/sec-public-info-sqlite3.cpp
index fbef713..3cf24a8 100644
--- a/src/security/sec-public-info-sqlite3.cpp
+++ b/src/security/sec-public-info-sqlite3.cpp
@@ -196,12 +196,9 @@
 void 
 SecPublicInfoSqlite3::addIdentity(const Name& identityName)
 {
-  if (doesIdentityExist(identityName))
-    throw Error("Identity already exists");
-
   sqlite3_stmt *statement;
 
-  sqlite3_prepare_v2(m_database, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "INSERT OR REPLACE INTO Identity (identity_name) values (?)", -1, &statement, 0);
       
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   
@@ -250,20 +247,15 @@
 SecPublicInfoSqlite3::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
 {
   if(keyName.empty())
-    throw Error("Incorrect key name " + keyName.toUri());
+    return;
 
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
-
-  if (!doesIdentityExist(identityName))
-    addIdentity(identityName);
-
-  if (doesPublicKeyExist(keyName))
-    throw Error("a key with the same name already exists!");
+  addIdentity(identityName);
 
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(m_database, "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "INSERT OR REPLACE INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -275,13 +267,14 @@
   sqlite3_finalize(statement);
 }
 
-ptr_lib::shared_ptr<PublicKey>
+shared_ptr<PublicKey>
 SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
 {
-  if (!doesPublicKeyExist(keyName)) {
-    _LOG_DEBUG("keyName does not exist");
-    return ptr_lib::shared_ptr<PublicKey>();
-  }
+  if (keyName.empty()) 
+    {
+      _LOG_DEBUG("SecPublicInfoSqlite3::getPublicKey  Empty keyName");
+      throw Error("SecPublicInfoSqlite3::getPublicKey  Empty keyName");
+    }
 
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
@@ -294,34 +287,18 @@
 
   int res = sqlite3_step(statement);
 
-  ptr_lib::shared_ptr<PublicKey> result;
+  shared_ptr<PublicKey> result;
   if (res == SQLITE_ROW)
-    result = ptr_lib::make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)), sqlite3_column_bytes(statement, 0));
-
-  sqlite3_finalize(statement);
-
-  return result;
-}
-
-void 
-SecPublicInfoSqlite3::updateKeyStatus(const Name& keyName, bool isActive)
-{
-  if(keyName.empty())
-    throw Error("Incorrect key name " + keyName.toUri());
-
-  string keyId = keyName.get(-1).toEscapedString();
-  Name identityName = keyName.getPrefix(-1);
-  
-  sqlite3_stmt *statement;
-  sqlite3_prepare_v2(m_database, "UPDATE Key SET active=? WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
-
-  sqlite3_bind_int(statement, 1, (isActive ? 1 : 0));
-  sqlite3_bind_text(statement, 2, identityName.toUri(), SQLITE_TRANSIENT);
-  sqlite3_bind_text(statement, 3, keyId, SQLITE_TRANSIENT);
-
-  sqlite3_step(statement);
-
-  sqlite3_finalize(statement);
+    {
+      result = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)), sqlite3_column_bytes(statement, 0));
+      sqlite3_finalize(statement);
+      return result;
+    }
+  else
+    {
+      sqlite3_finalize(statement);
+      throw Error("SecPublicInfoSqlite3::getPublicKey  public key does not exist");
+    }
 }
 
 bool
@@ -346,86 +323,99 @@
   return certExist;
 }
 
-void
-SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
-{
-  std::string certificateName = certificate.getName().toUri();
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
+// void
+// SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
+// {
+//   std::string certificateName = certificate.getName().toUri();
+//   Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
 
-  if(keyName.empty())
-    throw Error("Incorrect key name " + keyName.toUri());
+//   if(keyName.empty())
+//     return;
 
-  std::string keyId = keyName.get(-1).toEscapedString();
-  std::string identityName = keyName.getPrefix(-1).toUri();
+//   std::string keyId = keyName.get(-1).toEscapedString();
+//   std::string identityName = keyName.getPrefix(-1).toUri();
 
-  sqlite3_stmt *statement;
-  sqlite3_prepare_v2(m_database, 
-                      "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
-                       values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
-                      -1, &statement, 0);
+//   sqlite3_stmt *statement;
+//   sqlite3_prepare_v2(m_database, 
+//                       "INSERT OR REPLACE INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
+//                        values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
+//                       -1, &statement, 0);
 
-  
-  _LOG_DEBUG("certName: " << certificateName);
-  sqlite3_bind_text(statement, 1, certificateName, SQLITE_STATIC);
+//   _LOG_DEBUG("certName: " << certificateName);
+//   sqlite3_bind_text(statement, 1, certificateName, SQLITE_STATIC);
 
-  // this will throw an exception if the signature is not the standard one or there is no key locator present
-  SignatureSha256WithRsa signature(certificate.getSignature());
-  std::string signerName = signature.getKeyLocator().getName().toUri();
+//   try
+//     {
+//       SignatureSha256WithRsa signature(certificate.getSignature());
+//       std::string signerName = signature.getKeyLocator().getName().toUri();
 
-  sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
+//       sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
+//     }
+//   catch(KeyLocator::Error& e)
+//     {
+//       _LOG_DEBUG("SecPublicInfoSqlite3::addAnyCertificate unsupported keylocator type");
+//       return;
+//     }
+//   catch(SignatureSha256WithRsa::Error& e)
+//     {
+//       _LOG_DEBUG("SecPublicInfoSqlite3::addAnyCertificate unsupported signature type");
+//       return;
+//     }
 
-  sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
-  sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
+//   sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
+//   sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
 
-  // Convert from milliseconds to seconds since 1/1/1970.
-  sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
-  sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
+//   // Convert from milliseconds to seconds since 1/1/1970.
+//   sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
+//   sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
 
-  sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
+//   sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
 
-  sqlite3_step(statement);
+//   sqlite3_step(statement);
 
-  sqlite3_finalize(statement);
-}
+//   sqlite3_finalize(statement);
+// }
 
 void 
 SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
 {
   const Name& certificateName = certificate.getName();
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
+  Name keyName = 
+    IdentityCertificate::certificateNameToPublicKeyName(certificate.getName()); // KeyName is from IdentityCertificate name, so should be qualified.
 
-  if (!doesPublicKeyExist(keyName))
-    throw Error("No corresponding Key record for certificate!" + keyName.toUri() + " " + certificateName.toUri());
-
-  // Check if certificate has already existed!
-  if (doesCertificateExist(certificateName))
-    throw Error("Certificate has already been installed!");
+  addPublicKey(keyName, KEY_TYPE_RSA, certificate.getPublicKeyInfo()); //HACK!!! Assume the key type is RSA, we should check more.
 
   string keyId = keyName.get(-1).toEscapedString();
   Name identity = keyName.getPrefix(-1);
-  
-  // Check if the public key of certificate is the same as the key record
- 
-  ptr_lib::shared_ptr<PublicKey> pubKey = getPublicKey(keyName);
-  
-  if (!pubKey || (*pubKey) != certificate.getPublicKeyInfo())
-    throw Error("Certificate does not match the public key!");
 
   // Insert the certificate
   sqlite3_stmt *statement;
   sqlite3_prepare_v2(m_database, 
-                      "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
+                      "INSERT OR REPLACE INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
                        values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
                       -1, &statement, 0);
 
   _LOG_DEBUG("certName: " << certificateName.toUri());
   sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
 
-  // this will throw an exception if the signature is not the standard one or there is no key locator present
-  SignatureSha256WithRsa signature(certificate.getSignature());
-  std::string signerName = signature.getKeyLocator().getName().toUri();
+  try
+    {
+      // this will throw an exception if the signature is not the standard one or there is no key locator present
+      SignatureSha256WithRsa signature(certificate.getSignature());
+      std::string signerName = signature.getKeyLocator().getName().toUri();
 
-  sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
+      sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
+    }
+  catch(KeyLocator::Error& e)
+    {
+      _LOG_DEBUG("SecPublicInfoSqlite3::addAnyCertificate unsupported keylocator type");
+      return;
+    }
+  catch(SignatureSha256WithRsa::Error& e)
+    {
+      _LOG_DEBUG("SecPublicInfoSqlite3::addAnyCertificate unsupported signature type");
+      return;
+    }
 
   sqlite3_bind_text(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
@@ -441,7 +431,7 @@
   sqlite3_finalize(statement);
 }
 
-ptr_lib::shared_ptr<IdentityCertificate> 
+shared_ptr<IdentityCertificate> 
 SecPublicInfoSqlite3::getCertificate(const Name &certificateName)
 {
   sqlite3_stmt *statement;
@@ -454,15 +444,18 @@
   
   int res = sqlite3_step(statement);
   
-  ptr_lib::shared_ptr<IdentityCertificate> certificate;
   if (res == SQLITE_ROW)
     {
-      certificate = ptr_lib::make_shared<IdentityCertificate>();
+      shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
       certificate->wireDecode(Block((const uint8_t*)sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0)));
+      sqlite3_finalize(statement);
+      return certificate;
     }
-  sqlite3_finalize(statement);
-  
-  return certificate;
+  else
+    {
+      sqlite3_finalize(statement);
+      throw Error("SecPublicInfoSqlite3::getCertificate  certificate does not exist");
+    }
 }
  
 
@@ -474,19 +467,24 @@
 
   int res = sqlite3_step(statement);
       
-  Name identity;
-
   if (res == SQLITE_ROW)
-    identity = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
- 
-  sqlite3_finalize(statement);
-      
-  return identity;
+    {
+      Name identity = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
+      sqlite3_finalize(statement);
+      return identity;
+    }
+  else
+    {
+      sqlite3_finalize(statement);
+      throw Error("SecPublicInfoSqlite3::getDefaultIdentity  no default identity");
+    }
 }
 
 void 
 SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
 {
+  addIdentity(identityName);
+
   sqlite3_stmt *statement;
 
   //Reset previous default identity
@@ -516,22 +514,26 @@
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
 
   int res = sqlite3_step(statement);
-      
-  Name keyName;
 
   if (res == SQLITE_ROW)
-    keyName = Name(identityName).append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
- 
-  sqlite3_finalize(statement);
-      
-  return keyName;
+    {
+      Name keyName = Name(identityName).append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), 
+                                                      sqlite3_column_bytes(statement, 0)));
+      sqlite3_finalize(statement);
+      return keyName;
+    }
+  else
+    {
+      sqlite3_finalize(statement);
+      throw Error("SecPublicInfoSqlite3::getDefaultKeyNameForIdentity key not found");
+    }
 }
 
 void 
 SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
 {
-  if(keyName.empty())
-    throw Error("Incorrect key name " + keyName.toUri());
+  if(!doesPublicKeyExist(keyName))
+    throw Error("SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal Key does not exist:" + keyName.toUri());
 
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
@@ -563,7 +565,7 @@
 SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
 {
   if(keyName.empty())
-    return Name();
+    throw Error("SecPublicInfoSqlite3::getDefaultCertificateNameForKey wrong key");
 
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
@@ -576,23 +578,26 @@
 
   int res = sqlite3_step(statement);
 
-  Name certName;
-
   if (res == SQLITE_ROW)
-    certName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
- 
-  sqlite3_finalize(statement);
-      
-  return certName;
+    {
+      Name certName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
+      sqlite3_finalize(statement);
+      return certName;
+    }
+  else
+    {
+      sqlite3_finalize(statement);
+      throw Error("SecPublicInfoSqlite3::getDefaultCertificateNameForKey certificate not found");
+    }
 }
 
 void 
 SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
 {
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
-  if(keyName.empty())
-    throw Error("Incorrect key name for certificate " + certificateName.toUri());
+  if(!doesCertificateExist(certificateName))
+    throw Error("SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal  certificate does not exist:" + certificateName.toUri());
 
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
   string keyId = keyName.get(-1).toEscapedString();
   Name identityName = keyName.getPrefix(-1);
 
diff --git a/src/security/sec-public-info-sqlite3.hpp b/src/security/sec-public-info-sqlite3.hpp
index 2cecb04..feb07a5 100644
--- a/src/security/sec-public-info-sqlite3.hpp
+++ b/src/security/sec-public-info-sqlite3.hpp
@@ -16,140 +16,53 @@
 
 namespace ndn {
   
-/**
- * BasicIdentityStorage extends IdentityStorage to implement a basic storage of identity, public keys and certificates
- * using SQLite.
- */
 class SecPublicInfoSqlite3 : public SecPublicInfo {
 public:
   struct Error : public SecPublicInfo::Error { Error(const std::string &what) : SecPublicInfo::Error(what) {} };
 
   SecPublicInfoSqlite3();
   
-  /**
-   * The virtual Destructor.
-   */
   virtual 
   ~SecPublicInfoSqlite3();
 
-  // from SecPublicInfo
-  /**
-   * Check if the specified identity already exists.
-   * @param identityName The identity name.
-   * @return true if the identity exists, otherwise false.
-   */
+  /**********************
+   * from SecPublicInfo *
+   **********************/
   virtual bool 
   doesIdentityExist(const Name& identityName);
 
-  /**
-   * Add a new identity. An exception will be thrown if the identity already exists.
-   * @param identityName The identity name to be added.
-   */
   virtual void
   addIdentity(const Name& identityName);
 
-  /**
-   * Revoke the identity.
-   * @return true if the identity was revoked, false if not.
-   */
   virtual bool 
   revokeIdentity();
 
-  /**
-   * Check if the specified key already exists.
-   * @param keyName The name of the key.
-   * @return true if the key exists, otherwise false.
-   */
   virtual bool 
   doesPublicKeyExist(const Name& keyName);
 
-  /**
-   * Add a public key to the identity storage.
-   * @param keyName The name of the public key to be added.
-   * @param keyType Type of the public key to be added.
-   * @param publicKeyDer A blob of the public key DER to be added.
-   */
   virtual void 
   addPublicKey(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 ptr_lib::shared_ptr<PublicKey>
   getPublicKey(const Name& keyName);
 
-  /**
-   * Activate a key.  If a key is marked as inactive, its private part will not be used in packet signing.
-   * @param keyName name of the key
-   */
-  virtual inline void 
-  activatePublicKey(const Name& keyName);
-
-  /**
-   * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
-   * @param keyName name of the key
-   */
-  virtual inline void 
-  deactivatePublicKey(const Name& keyName);
-
-  /**
-   * Check if the specified certificate already exists.
-   * @param certificateName The name of the certificate.
-   * @return true if the certificate exists, otherwise false.
-   */
   virtual bool
   doesCertificateExist(const Name& certificateName);
 
-  /**
-   * Add a certificate in to the identity storage without checking if the identity and key exists.
-   * @param certificate The certificate to be added.
-   */
-  virtual void
-  addAnyCertificate (const IdentityCertificate& certificate);
-
-  /**
-   * Add a certificate to the identity storage.
-   * @param certificate The certificate to be added.  This makes a copy of the certificate.
-   */
   virtual void 
   addCertificate(const IdentityCertificate& certificate);
 
-  /**
-   * Get a certificate from the identity storage.
-   * @param certificateName The name of the requested certificate.
-   * @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<IdentityCertificate> 
   getCertificate(const Name &certificateName);
 
 
-  /*****************************************
-   *            Default Getter             *
-   *****************************************/
 
-  /**
-   * Get the default identity. 
-   * @param return The name of default identity, or an empty name if there is no default.
-   */
   virtual Name 
   getDefaultIdentity();
 
-  /**
-   * Get the default key name for the specified identity.
-   * @param identityName The identity name.
-   * @return The default key name.
-   */
   virtual Name 
   getDefaultKeyNameForIdentity(const Name& identityName);
 
-  /**
-   * Get the default certificate name for the specified key.
-   * @param keyName The key name.
-   * @return The default certificate name.
-   */
   virtual Name 
   getDefaultCertificateNameForKey(const Name& keyName);
 
@@ -169,70 +82,28 @@
   getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault);
   
 protected:
-  /**
-   * Set the default identity.  If the identityName does not exist, then clear the default identity
-   * so that getDefaultIdentity() returns an empty name.
-   * @param identityName The default identity name.
-   */
   virtual void 
   setDefaultIdentityInternal(const Name& identityName);
 
-  /**
-   * Set the default key name for the specified identity.
-   * @param keyName The key name.
-   * @param identityNameCheck (optional) The identity name to check the keyName.
-   */
   virtual void
   setDefaultKeyNameForIdentityInternal(const Name& keyName);
 
-  /**
-   * Set the default key name for the specified identity.
-   * @param keyName The key name.
-   * @param certificateName The certificate name.
-   */
   virtual void 
   setDefaultCertificateNameForKeyInternal(const Name& certificateName);  
 
-  /**
-   * Delete a certificate.
-   * @param certificateName The certificate name.
-   */
   virtual void
   deleteCertificateInfo(const Name &certificateName);
 
-  /**
-   * Delete a public key and related certificates.
-   * @param keyName The key name.
-   */
   virtual void
   deletePublicKeyInfo(const Name &keyName);
 
-  /**
-   * Delete an identity and related public keys and certificates.
-   * @param identity The identity name.
-   */
   virtual void
   deleteIdentityInfo(const Name &identity);
   
 private:
-  void
-  updateKeyStatus(const Name& keyName, bool isActive);
-
   sqlite3 * m_database;
 };
 
-void
-SecPublicInfoSqlite3::activatePublicKey(const Name& keyName)
-{
-  updateKeyStatus(keyName, true);
-}
-
-void
-SecPublicInfoSqlite3::deactivatePublicKey(const Name& keyName)
-{
-  updateKeyStatus(keyName, false);
-}
-
 } // namespace ndn
 
 #endif //NDN_SECURITY_SEC_PUBLIC_INFO_SQLITE3_HPP
diff --git a/src/security/sec-public-info.hpp b/src/security/sec-public-info.hpp
index b68875b..1d992d0 100644
--- a/src/security/sec-public-info.hpp
+++ b/src/security/sec-public-info.hpp
@@ -18,22 +18,23 @@
 namespace ndn {
 
 /**
- * SecPublicInfo is a base class for the storage of identity, public keys and certificates. 
- * Private keys are stored in SecTpm.
- * This is an abstract base class.  A subclass must implement the methods.
+ * @brief SecPublicInfo is a base class for the storage of public information.
+ *
+ * It specify interfaces related to public information, such as identity, public keys and certificates.
  */
 class SecPublicInfo {
 public:
   struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
 
   /**
-   * The virtual Destructor.
+   * @brief The virtual Destructor.
    */
   virtual 
   ~SecPublicInfo() {}
 
   /**
-   * Check if the specified identity already exists.
+   * @brief Check if the specified identity already exists.
+   *
    * @param identityName The identity name.
    * @return true if the identity exists, otherwise false.
    */
@@ -41,21 +42,26 @@
   doesIdentityExist(const Name& identityName) = 0;
 
   /**
-   * Add a new identity. An exception will be thrown if the identity already exists.
+   * @brief Add a new identity.
+   *
+   * if identity already exist, do not add it again.
+   *
    * @param identityName The identity name to be added.
    */
   virtual void
   addIdentity(const Name& identityName) = 0;
 
   /**
-   * Revoke the identity.
-   * @return true if the identity was revoked, false if not.
+   * @brief Revoke the identity.
+   *
+   * @return true if the identity was revoked, otherwise false.
    */
   virtual bool 
   revokeIdentity() = 0;
 
   /**
-   * Check if the specified key already exists.
+   * @brief Check if the specified key already exists.
+   *
    * @param keyName The name of the key.
    * @return true if the key exists, otherwise false.
    */
@@ -63,7 +69,8 @@
   doesPublicKeyExist(const Name& keyName) = 0;
 
   /**
-   * Add a public key to the identity storage.
+   * @brief Add a public key to the identity storage.
+   *
    * @param keyName The name of the public key to be added.
    * @param keyType Type of the public key to be added.
    * @param publicKeyDer A blob of the public key DER to be added.
@@ -72,29 +79,18 @@
   addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer) = 0;
 
   /**
-   * Get the public key DER blob from the identity storage.
+   * @brief 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.
+   * @return The DER Blob.
+   * @throws SecPublicInfo::Error if public key does not exist.
    */
-  virtual ptr_lib::shared_ptr<PublicKey>
+  virtual shared_ptr<PublicKey>
   getPublicKey(const Name& keyName) = 0;
 
   /**
-   * Activate a key.  If a key is marked as inactive, its private part will not be used in packet signing.
-   * @param keyName name of the key
-   */
-  virtual void 
-  activatePublicKey(const Name& keyName) = 0;
-
-  /**
-   * Deactivate a key. If a key is marked as inactive, its private part will not be used in packet signing.
-   * @param keyName name of the key
-   */
-  virtual void 
-  deactivatePublicKey(const Name& keyName) = 0;
-
-  /**
-   * Check if the specified certificate already exists.
+   * @brief Check if the specified certificate already exists.
+   *
    * @param certificateName The name of the certificate.
    * @return true if the certificate exists, otherwise false.
    */
@@ -102,19 +98,23 @@
   doesCertificateExist(const Name& certificateName) = 0;
 
   /**
-   * Add a certificate to the identity storage.
-   * @param certificate The certificate to be added.  This makes a copy of the certificate.
+   * @brief Add a certificate to the identity storage.
+   *
+   * It will add the corresponding public key and identity if they do not exist.
+   *
+   * @param certificate The certificate to be added.
    */
   virtual void 
   addCertificate(const IdentityCertificate& certificate) = 0;
 
   /**
-   * Get a certificate from the identity storage.
+   * @brief Get a certificate from the identity storage.
+   *
    * @param certificateName The name of the requested certificate.
-   * @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.
+   * @return The requested certificate.  
+   * @throws SecPublicInfo::Error if the certificate does not exist.
    */
-  virtual ptr_lib::shared_ptr<IdentityCertificate> 
+  virtual shared_ptr<IdentityCertificate> 
   getCertificate(const Name &certificateName) = 0;
 
 
@@ -123,40 +123,78 @@
    *****************************************/
 
   /**
-   * Get the default identity. 
-   * @param return The name of default identity, or an empty name if there is no default.
+   * @brief Get the default identity. 
+   *
+   * @param return The name of default identity, 
+   * @throws SecPublicInfo::Error if there is no default.
    */
   virtual Name 
   getDefaultIdentity() = 0;
 
   /**
-   * Get the default key name for the specified identity.
+   * @brief Get the default key name for the specified identity.
+   *
    * @param identityName The identity name.
    * @return The default key name.
+   * @throws SecPublicInfo::Error if there is no default.
    */
   virtual Name 
   getDefaultKeyNameForIdentity(const Name& identityName) = 0;
 
   /**
-   * Get the default certificate name for the specified key.
+   * @brief Get the default certificate name for the specified key.
+   *
    * @param keyName The key name.
    * @return The default certificate name.
+   * @throws SecPublicInfo::Error if there is no default.
    */
   virtual Name 
   getDefaultCertificateNameForKey(const Name& keyName) = 0;
 
+  /**
+   * @brief Get all the identities in public info.
+   *
+   * @param nameList On return, the identity list.
+   * @param isDefault If specified, only the default identity is returned.
+   */
   virtual void
   getAllIdentities(std::vector<Name> &nameList, bool isDefault) = 0;
 
+  /**
+   * @brief Get all the key name in public info.
+   *
+   * @param nameList On return, the key name list.
+   * @param isDefault If specified, only the default keys are returned.
+   */
   virtual void
   getAllKeyNames(std::vector<Name> &nameList, bool isDefault) = 0;
 
+  /**
+   * @brief Get all the key name of a particular identity.
+   *
+   * @param identity The specified identity name.
+   * @param nameList On return, the key name list.
+   * @param isDefault If specified, only the default key is returned.
+   */
   virtual void
   getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name> &nameList, bool isDefault) = 0;
-    
+
+  /**
+   * @brief Get all the certificate name in public info.
+   *
+   * @param nameList On return, the certificate name list.
+   * @param isDefault If specified, only the default certificates are returned.
+   */
   virtual void
   getAllCertificateNames(std::vector<Name> &nameList, bool isDefault) = 0;
     
+  /**
+   * @brief Get all the certificate name of a particular key.
+   *
+   * @param identity The specified key name.
+   * @param nameList On return, the certificate name list.
+   * @param isDefault If specified, only the default certificate is returned.
+   */
   virtual void
   getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault) = 0;
 
@@ -167,23 +205,27 @@
    *****************************************/
   
   /**
-   * Set the default identity.  If the identityName does not exist, then clear the default identity
-   * so that getDefaultIdentity() returns an empty name.
+   * @brief Set the default identity.
+   *
    * @param identityName The default identity name.
    */
   virtual void 
   setDefaultIdentityInternal(const Name& identityName) = 0;
   
   /**
-   * Set the default key name for the corresponding identity.
+   * @brief Set the default key name for the corresponding identity.
+   * 
    * @param keyName The key name.
+   * @throws SecPublicInfo::Error if the key does not exist.
    */
   virtual void
   setDefaultKeyNameForIdentityInternal(const Name& keyName) = 0;
 
   /**
-   * Set the default certificate name for the corresponding key.
+   * @brief Set the default certificate name for the corresponding key.
+   *
    * @param certificateName The certificate name.
+   * @throws SecPublicInfo::Error if the certificatedoes not exist.
    */
   virtual void 
   setDefaultCertificateNameForKeyInternal(const Name& certificateName) = 0; 
@@ -193,21 +235,24 @@
    *****************************************/
 
   /**
-   * Delete a certificate.
+   * @brief Delete a certificate.
+   *
    * @param certificateName The certificate name.
    */
   virtual void
   deleteCertificateInfo(const Name &certificateName) = 0;
 
   /**
-   * Delete a public key and related certificates.
+   * @brief Delete a public key and related certificates.
+   *
    * @param keyName The key name.
    */
   virtual void
   deletePublicKeyInfo(const Name &keyName) = 0;
 
   /**
-   * Delete an identity and related public keys and certificates.
+   * @brief Delete an identity and related public keys and certificates.
+   *
    * @param identity The identity name.
    */
   virtual void
@@ -220,29 +265,35 @@
    *****************************************/
 
   /**
-   * Set the default identity.  If the identityName does not exist, then clear the default identity
-   * so that getDefaultIdentity() returns an empty name.
+   * @brief Set the default identity.  
+   *
    * @param identityName The default identity name.
+   * @throws SecPublicInfo::Error if the identity does not exist.
    */
   inline void 
   setDefaultIdentity(const Name& identityName);
 
   /**
-   * Set the default key name for the corresponding identity.
+   * @brief Set the default key name for the corresponding identity.
+   * 
    * @param keyName The key name.
+   * @throws SecPublicInfo::Error if either the identity or key does not exist.
    */
   inline void 
   setDefaultKeyNameForIdentity(const Name& keyName);
 
   /**
-   * Set the default certificate name for the corresponding key.
+   * @brief Set the default certificate name for the corresponding key.
+   *
    * @param certificateName The certificate name.
+   * @throws SecPublicInfo::Error if either the certificate or key does not exist.
    */
   inline void 
   setDefaultCertificateNameForKey(const Name& certificateName); 
 
   /**
-   * Generate a name for a new key belonging to the identity.
+   * @brief Generate a key name for the identity.
+   *
    * @param identityName The identity name.
    * @param useKsk If true, generate a KSK name, otherwise a DSK name.
    * @return The generated key name.
@@ -250,48 +301,68 @@
   inline Name 
   getNewKeyName(const Name& identityName, bool useKsk);
 
-    /**
-   * Get the default certificate name for the specified identity.
+  /**
+   * @brief Get the default certificate name for the specified identity.
+   *
    * @param identityName The identity name.
    * @return The default certificate name.
+   * @throws SecPublicInfo::Error if no certificate is found.
    */
   inline Name 
   getDefaultCertificateNameForIdentity(const Name& 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.
+   * @brief Get the default certificate name of the default identity
+   *
    * @return The requested certificate name.
+   * @throws SecPublicInfo::Error if no certificate is found.
    */
   inline Name
   getDefaultCertificateName();
 
   /**
-   * Add a certificate 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.
+   * @brief Add a certificate and set the certificate as the default one of its corresponding key.
+   *
+   * @param certificate The certificate to be added.
+   * @throws SecPublicInfo::Error if the certificate cannot be added (though it is really rare)
    */
   inline void
   addCertificateAsKeyDefault(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.
+   * @brief Add a certificate into the public key identity storage and set the certificate as the default one of its corresponding identity.
+   *
+   * @param certificate The certificate to be added.
+   * @throws SecPublicInfo::Error if the certificate cannot be added (though it is really rare)
    */
   inline void
   addCertificateAsIdentityDefault(const IdentityCertificate& certificate);
 
+  /**
+   * @brief Add a certificate into the public key identity storage and set the certificate as the default one of the default identity.
+   *
+   * @param certificate The certificate to be added.
+   * @throws SecPublicInfo::Error if the certificate cannot be added (though it is really rare)
+   */
   inline void
   addCertificateAsSystemDefault(const IdentityCertificate& certificate);
 
-  inline ptr_lib::shared_ptr<IdentityCertificate>
+  /**
+   * @brief get cached default certificate of the default identity.
+   *
+   * @return The certificate which might be a NULL pointer.
+   */
+  inline shared_ptr<IdentityCertificate>
   defaultCertificate();
   
+  /**
+   * @brief try to get the default certificate of the default identity from the public info.
+   */
   inline void
   refreshDefaultCertificate();
 
 protected:
-  ptr_lib::shared_ptr<IdentityCertificate> defaultCertificate_;
-
+  shared_ptr<IdentityCertificate> m_defaultCertificate;
 };
 
 void
@@ -344,13 +415,13 @@
 Name
 SecPublicInfo::getDefaultCertificateName()
 {
-  if(!static_cast<bool>(defaultCertificate_))
+  if(!static_cast<bool>(m_defaultCertificate))
     refreshDefaultCertificate();
 
-  if(!static_cast<bool>(defaultCertificate_))
-    return Name();
+  if(!static_cast<bool>(m_defaultCertificate))
+    throw Error("No default certificate is set");
 
-  return defaultCertificate_->getName();
+  return m_defaultCertificate->getName();
 }
 
 void
@@ -366,7 +437,7 @@
 {
   addCertificate(certificate);
   Name certName = certificate.getName();
-  setDefaultKeyNameForIdentityInternal(IdentityCertificate::certificateNameToPublicKeyName(certName));
+  setDefaultKeyNameForIdentityInternal(IdentityCertificate::certificateNameToPublicKeyName(certName)); 
   setDefaultCertificateNameForKeyInternal(certName);
   refreshDefaultCertificate();
 }
@@ -383,20 +454,25 @@
   refreshDefaultCertificate();
 }
 
-ptr_lib::shared_ptr<IdentityCertificate>
+shared_ptr<IdentityCertificate>
 SecPublicInfo::defaultCertificate()
 {
-  return defaultCertificate_;
+  return m_defaultCertificate;
 }
 
 void
 SecPublicInfo::refreshDefaultCertificate()
 {
-  Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity());
-  if(certName.empty())
-    defaultCertificate_.reset();
-  else
-    defaultCertificate_ = getCertificate(certName);
+  try
+    {
+      Name certName = getDefaultCertificateNameForIdentity(getDefaultIdentity());
+      m_defaultCertificate = getCertificate(certName);
+    }
+  catch(SecPublicInfo::Error& e)
+    {
+      m_defaultCertificate.reset();
+    }
+
 }
 
 } // namespace ndn
diff --git a/src/security/sec-tpm-file.cpp b/src/security/sec-tpm-file.cpp
index d25c593..93d2886 100644
--- a/src/security/sec-tpm-file.cpp
+++ b/src/security/sec-tpm-file.cpp
@@ -151,14 +151,14 @@
   string keyURI = keyName.toUri();
 
   if(!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
-    return shared_ptr<PublicKey>();
+    throw Error("Public Key already exist");
 
   ostringstream os;
   try{
     using namespace CryptoPP;
     FileSource(m_impl->nameTransform(keyURI, ".pub").string().c_str(), true, new Base64Decoder(new FileSink(os)));
   }catch(const CryptoPP::Exception& e){
-    return shared_ptr<PublicKey>();
+    throw Error(e.what());
   }
 
   return make_shared<PublicKey>(reinterpret_cast<const uint8_t*>(os.str().c_str()), os.str().size());
@@ -245,156 +245,159 @@
 ConstBufferPtr
 SecTpmFile::decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
 {
-  string keyURI = keyName.toUri();
-  if (!isSymmetric)
-    {
-      if(!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
-	throw Error("private key doesn't exist");
+  throw Error("SecTpmFile::decryptInTpm is not supported!");
+  // string keyURI = keyName.toUri();
+  // if (!isSymmetric)
+  //   {
+  //     if(!doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE))
+  //       throw Error("private key doesn't exist");
 
-      try{
-	using namespace CryptoPP;
-        AutoSeededRandomPool rng;
+  //     try{
+  //       using namespace CryptoPP;
+  //       AutoSeededRandomPool rng;
 
-	//Read private key
-	ByteQueue bytes;
-	FileSource file(m_impl->nameTransform(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
-	file.TransferTo(bytes);
-	bytes.MessageEnd();
-	RSA::PrivateKey privateKey;
-	privateKey.Load(bytes);
-	RSAES_PKCS1v15_Decryptor decryptor(privateKey);
+  //       //Read private key
+  //       ByteQueue bytes;
+  //       FileSource file(m_impl->nameTransform(keyURI, ".pri").string().c_str(), true, new Base64Decoder);
+  //       file.TransferTo(bytes);
+  //       bytes.MessageEnd();
+  //       RSA::PrivateKey privateKey;
+  //       privateKey.Load(bytes);
+  //       RSAES_PKCS1v15_Decryptor decryptor(privateKey);
 	
-	OBufferStream os;
-	StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
+  //       OBufferStream os;
+  //       StringSource(data, dataLength, true, new PK_DecryptorFilter(rng, decryptor, new FileSink(os)));
 	
-	return os.buf();
-      }
-      catch(const CryptoPP::Exception& e){
-	throw Error(e.what());
-      }
-    }
-  else
-    {
-      throw Error("Symmetric encryption is not implemented!");
-      // if(!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
-      // 	throw Error("symmetric key doesn't exist");
+  //       return os.buf();
+  //     }
+  //     catch(const CryptoPP::Exception& e){
+  //       throw Error(e.what());
+  //     }
+  //   }
+  // else
+  //   {
+  //     throw Error("Symmetric encryption is not implemented!");
+  //     // if(!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
+  //     // 	throw Error("symmetric key doesn't exist");
 
-      // try{
-      // 	string keyBits;
-      // 	string symKeyFileName = m_impl->nameTransform(keyURI, ".key");
-      // 	FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
+  //     // try{
+  //     // 	string keyBits;
+  //     // 	string symKeyFileName = m_impl->nameTransform(keyURI, ".key");
+  //     // 	FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
 	
-      // 	using CryptoPP::AES;
-      // 	AutoSeededRandomPool rnd;
-      // 	byte iv[AES::BLOCKSIZE];
-      // 	rnd.GenerateBlock(iv, AES::BLOCKSIZE);
+  //     // 	using CryptoPP::AES;
+  //     // 	AutoSeededRandomPool rnd;
+  //     // 	byte iv[AES::BLOCKSIZE];
+  //     // 	rnd.GenerateBlock(iv, AES::BLOCKSIZE);
 
-      // 	CFB_Mode<AES>::Decryption decryptor;
-      // 	decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
+  //     // 	CFB_Mode<AES>::Decryption decryptor;
+  //     // 	decryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
 	
-      // 	OBufferStream os;
-      // 	StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
-      // 	return os.buf();
+  //     // 	OBufferStream os;
+  //     // 	StringSource(data, dataLength, true, new StreamTransformationFilter(decryptor,new FileSink(os)));
+  //     // 	return os.buf();
 
-      // }catch(const CryptoPP::Exception& e){
-      // 	throw Error(e.what());
-      // }
-    }
+  //     // }catch(const CryptoPP::Exception& e){
+  //     // 	throw Error(e.what());
+  //     // }
+  //   }
 }
 
 ConstBufferPtr
 SecTpmFile::encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric)
 {
-  string keyURI = keyName.toUri();
+  throw Error("SecTpmFile::encryptInTpm is not supported!");
+  // string keyURI = keyName.toUri();
 
-  if (!isSymmetric)
-    {
-      if(!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
-	throw Error("public key doesn't exist");
-      try
-	{
-          using namespace CryptoPP;
-          AutoSeededRandomPool rng;
+  // if (!isSymmetric)
+  //   {
+  //     if(!doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC))
+  //       throw Error("public key doesn't exist");
+  //     try
+  //       {
+  //         using namespace CryptoPP;
+  //         AutoSeededRandomPool rng;
 
-	  //Read private key
-	  ByteQueue bytes;
-	  FileSource file(m_impl->nameTransform(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
-	  file.TransferTo(bytes);
-	  bytes.MessageEnd();
-	  RSA::PublicKey publicKey;
-	  publicKey.Load(bytes);
+  //         //Read private key
+  //         ByteQueue bytes;
+  //         FileSource file(m_impl->nameTransform(keyURI, ".pub").string().c_str(), true, new Base64Decoder);
+  //         file.TransferTo(bytes);
+  //         bytes.MessageEnd();
+  //         RSA::PublicKey publicKey;
+  //         publicKey.Load(bytes);
 
-	  OBufferStream os;
-	  RSAES_PKCS1v15_Encryptor encryptor(publicKey);
+  //         OBufferStream os;
+  //         RSAES_PKCS1v15_Encryptor encryptor(publicKey);
 
-	  StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
-	  return os.buf();
-	}
-      catch(const CryptoPP::Exception& e){
-	throw Error(e.what());
-      }
-    }
-  else
-    {
-      throw Error("Symmetric encryption is not implemented!");
-      // if(!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
-      // 	throw Error("symmetric key doesn't exist");
+  //         StringSource(data, dataLength, true, new PK_EncryptorFilter(rng, encryptor, new FileSink(os)));
+  //         return os.buf();
+  //       }
+  //     catch(const CryptoPP::Exception& e){
+  //       throw Error(e.what());
+  //     }
+  //   }
+  // else
+  //   {
+  //     throw Error("Symmetric encryption is not implemented!");
+  //     // if(!doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
+  //     // 	throw Error("symmetric key doesn't exist");
 
-      // try{
-      // 	string keyBits;
-      // 	string symKeyFileName = m_impl->nameTransform(keyURI, ".key");
-      // 	FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
+  //     // try{
+  //     // 	string keyBits;
+  //     // 	string symKeyFileName = m_impl->nameTransform(keyURI, ".key");
+  //     // 	FileSource(symKeyFileName, true, new HexDecoder(new StringSink(keyBits)));
 
-      // 	using CryptoPP::AES;
-      // 	AutoSeededRandomPool rnd;
-      // 	byte iv[AES::BLOCKSIZE];
-      // 	rnd.GenerateBlock(iv, AES::BLOCKSIZE);
+  //     // 	using CryptoPP::AES;
+  //     // 	AutoSeededRandomPool rnd;
+  //     // 	byte iv[AES::BLOCKSIZE];
+  //     // 	rnd.GenerateBlock(iv, AES::BLOCKSIZE);
 
-      // 	CFB_Mode<AES>::Encryption encryptor;
-      // 	encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
+  //     // 	CFB_Mode<AES>::Encryption encryptor;
+  //     // 	encryptor.SetKeyWithIV(reinterpret_cast<const uint8_t*>(keyBits.c_str()), keyBits.size(), iv);
 
-      // 	OBufferStream os;
-      // 	StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
-      // 	return os.buf();
-      // }catch(const CryptoPP::Exception& e){
-      // 	throw Error(e.what());
-      // }
-    }
+  //     // 	OBufferStream os;
+  //     // 	StringSource(data, dataLength, true, new StreamTransformationFilter(encryptor, new FileSink(os)));
+  //     // 	return os.buf();
+  //     // }catch(const CryptoPP::Exception& e){
+  //     // 	throw Error(e.what());
+  //     // }
+  //   }
 }
 
 
 void
 SecTpmFile::generateSymmetricKeyInTpm(const Name & keyName, KeyType keyType, int keySize)
 {
-  string keyURI = keyName.toUri();
+  throw Error("SecTpmFile::generateSymmetricKeyInTpm is not supported!");
+  // string keyURI = keyName.toUri();
 
-  if(doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
-    throw Error("symmetric key exists");
+  // if(doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
+  //   throw Error("symmetric key exists");
 
-  string keyFileName = m_impl->maintainMapping(keyURI);
-  string symKeyFileName = keyFileName + ".key";
+  // string keyFileName = m_impl->maintainMapping(keyURI);
+  // string symKeyFileName = keyFileName + ".key";
 
-  try{
-    switch(keyType){
-    case KEY_TYPE_AES:
-      {
-        using namespace CryptoPP;
-        AutoSeededRandomPool rng;
+  // try{
+  //   switch(keyType){
+  //   case KEY_TYPE_AES:
+  //     {
+  //       using namespace CryptoPP;
+  //       AutoSeededRandomPool rng;
 
-	SecByteBlock key(0x00, keySize);
-	rng.GenerateBlock(key, keySize);
+  //       SecByteBlock key(0x00, keySize);
+  //       rng.GenerateBlock(key, keySize);
 	
-	StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
+  //       StringSource(key, key.size(), true, new HexEncoder(new FileSink(symKeyFileName.c_str())));
 	
-	chmod(symKeyFileName.c_str(), 0000400);
-	return;
-      }
-    default:
-      throw Error("Unsupported symmetric key type!");
-    }
-  }catch(const CryptoPP::Exception& e){
-    throw Error(e.what());
-  }
+  //       chmod(symKeyFileName.c_str(), 0000400);
+  //       return;
+  //     }
+  //   default:
+  //     throw Error("Unsupported symmetric key type!");
+  //   }
+  // }catch(const CryptoPP::Exception& e){
+  //   throw Error(e.what());
+  // }
 }
 
 bool
diff --git a/src/security/sec-tpm-file.hpp b/src/security/sec-tpm-file.hpp
index 4887a15..8a108c5 100644
--- a/src/security/sec-tpm-file.hpp
+++ b/src/security/sec-tpm-file.hpp
@@ -51,9 +51,11 @@
     return false;
   }
 
-  virtual void
+  virtual bool
   unlockTpm(const char* password, size_t passwordLength, bool usePassword)
-  {}
+  {
+    return !locked();
+  }
 
   virtual void
   generateKeyPairInTpm(const Name & keyName, KeyType keyType, int keySize);
@@ -82,6 +84,10 @@
   virtual bool
   generateRandomBlock(uint8_t* res, size_t size);
 
+  virtual void 
+  addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
+  {}
+
 protected:
   /******************************
    * From TrustedPlatformModule *
diff --git a/src/security/sec-tpm-memory.cpp b/src/security/sec-tpm-memory.cpp
index 638a174..5ca9673 100644
--- a/src/security/sec-tpm-memory.cpp
+++ b/src/security/sec-tpm-memory.cpp
@@ -55,11 +55,11 @@
 
 void
 SecTpmMemory::setKeyPairForKeyName(const Name& keyName,
-                                uint8_t *publicKeyDer, size_t publicKeyDerLength,
-                                uint8_t *privateKeyDer, size_t privateKeyDerLength)
+                                   uint8_t *publicKeyDer, size_t publicKeyDerLength,
+                                   uint8_t *privateKeyDer, size_t privateKeyDerLength)
 {
-  publicKeyStore_[keyName.toUri()]  = ptr_lib::make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
-  privateKeyStore_[keyName.toUri()] = ptr_lib::make_shared<RsaPrivateKey>(privateKeyDer, privateKeyDerLength);
+  publicKeyStore_[keyName.toUri()]  = make_shared<PublicKey>(publicKeyDer, publicKeyDerLength);
+  privateKeyStore_[keyName.toUri()] = make_shared<RsaPrivateKey>(privateKeyDer, privateKeyDerLength);
 }
 
 void 
@@ -79,22 +79,22 @@
 ConstBufferPtr
 SecTpmMemory::exportPrivateKeyPkcs1FromTpm(const Name& keyName)
 {
-  throw Error("SecTpmMemory::exportPrivateKeyPkcs1FromTpm is not implemented");
+  return shared_ptr<Buffer>();
 }
 
 bool
 SecTpmMemory::importPrivateKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
 {
-  throw Error("SecTpmMemory::importPrivateKeyPkcs1IntoTpm is not implemented");
+  return false;
 }
 
 bool
 SecTpmMemory::importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
 {
-  throw Error("SecTpmMemory::importPublicKeyPkcs1IntoTpm is not implemented");
+  return false;
 }
 
-ptr_lib::shared_ptr<PublicKey> 
+shared_ptr<PublicKey> 
 SecTpmMemory::getPublicKeyFromTpm(const Name& keyName)
 {
   PublicKeyStore::iterator publicKey = publicKeyStore_.find(keyName.toUri());
@@ -105,11 +105,11 @@
 
 Block 
 SecTpmMemory::signInTpm(const uint8_t *data, size_t dataLength,
-                const Name& keyName,
-                DigestAlgorithm digestAlgorithm)
+                        const Name& keyName,
+                        DigestAlgorithm digestAlgorithm)
 {
   if (digestAlgorithm != DIGEST_ALGORITHM_SHA256)
-    return ConstBufferPtr();
+    throw Error("Unsupported digest algorithm.");
 
   // Find the private key and sign.
   PrivateKeyStore::iterator privateKey = privateKeyStore_.find(keyName.toUri());
@@ -122,7 +122,7 @@
   SHA256_Update(&sha256, data, dataLength);
   SHA256_Final(digest, &sha256);
 
-  BufferPtr signatureBuffer = ptr_lib::make_shared<Buffer>();
+  BufferPtr signatureBuffer = make_shared<Buffer>();
   signatureBuffer->resize(RSA_size(privateKey->second->getPrivateKey()));
   
   unsigned int signatureBitsLength;  
diff --git a/src/security/sec-tpm-memory.hpp b/src/security/sec-tpm-memory.hpp
index 5bddf88..de48201 100644
--- a/src/security/sec-tpm-memory.hpp
+++ b/src/security/sec-tpm-memory.hpp
@@ -56,14 +56,16 @@
     return true;
   }
 
-  virtual void
+  virtual bool
   unlockTpm(const char* password, size_t passwordLength, bool usePassword)
-  {}
+  {
+    return !locked();
+  }
 
   virtual void 
   generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize);
 
-  virtual ptr_lib::shared_ptr<PublicKey> 
+  virtual shared_ptr<PublicKey> 
   getPublicKeyFromTpm(const Name& keyName);
 
   virtual void
@@ -87,6 +89,10 @@
   virtual bool
   generateRandomBlock(uint8_t* res, size_t size);
 
+  virtual void 
+  addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl)
+  {}
+
   /******************************
    *   SecTpmMemory specific    *
    ******************************/
@@ -121,8 +127,8 @@
 private:
   class RsaPrivateKey;
 
-  typedef std::map<std::string, ptr_lib::shared_ptr<PublicKey> >     PublicKeyStore;
-  typedef std::map<std::string, ptr_lib::shared_ptr<RsaPrivateKey> > PrivateKeyStore;
+  typedef std::map<std::string, shared_ptr<PublicKey> >     PublicKeyStore;
+  typedef std::map<std::string, shared_ptr<RsaPrivateKey> > PrivateKeyStore;
   
   PublicKeyStore  publicKeyStore_;  /**< The map key is the keyName.toUri() */
   PrivateKeyStore privateKeyStore_; /**< The map key is the keyName.toUri() */
diff --git a/src/security/sec-tpm-osx.cpp b/src/security/sec-tpm-osx.cpp
index de95ef1..383f021 100644
--- a/src/security/sec-tpm-osx.cpp
+++ b/src/security/sec-tpm-osx.cpp
@@ -176,14 +176,14 @@
     return ((kSecUnlockStateStatus & keychainStatus) == 0);
 }
 
-void
+bool
 SecTpmOsx::unlockTpm(const char* password, size_t passwordLength, bool usePassword)
 {
   OSStatus res; 
 
   // If the default key chain is already unlocked, return immediately.
   if(!locked())
-    return;
+    return true;
 
   // If the default key chain is locked, unlock the key chain.
   if(usePassword)
@@ -229,7 +229,7 @@
           memset(getPassword, 0, strlen(getPassword));
           
           if(res == errSecSuccess)
-            return;
+            break;
         }
     }
   else
@@ -237,6 +237,8 @@
       // If inTerminal is not set, get the password from GUI.
       SecKeychainUnlock(m_impl->m_keyChainRef, 0, 0, false);
     }
+
+  return !locked();
 }
 
 void 
@@ -276,8 +278,10 @@
   
   if (res == errSecAuthFailed && !retry)
     {
-      unlockTpm(0, 0, false);
-      generateKeyPairInTpmInternal(keyName, keyType, keySize, true);
+      if(unlockTpm(0, 0, false))
+        generateKeyPairInTpmInternal(keyName, keyType, keySize, true);
+      else
+        throw Error("Fail to unlock the keychain");
     }
   else
     {
@@ -306,48 +310,43 @@
   
   if (res == errSecAuthFailed && !retry)
     {
-      unlockTpm(0, 0, false);
-      deleteKeyPairInTpmInternal(keyName, true);
-    }
-  else
-    {
-      _LOG_DEBUG("Fail to delete a key pair: " << res);
-      throw Error("Fail to delete a key pair");
+      if(unlockTpm(0, 0, false))
+        deleteKeyPairInTpmInternal(keyName, true);
     }
 }
 
 void 
 SecTpmOsx::generateSymmetricKeyInTpm(const Name & keyName, KeyType keyType, int keySize)
 {
+  throw Error("SecTpmOsx::generateSymmetricKeyInTpm is not supported");
+  // if(doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
+  //   throw Error("keyName has existed!");
 
-  if(doesKeyExistInTpm(keyName, KEY_CLASS_SYMMETRIC))
-    throw Error("keyName has existed!");
+  // string keyNameUri =  m_impl->toInternalKeyName(keyName, KEY_CLASS_SYMMETRIC);
 
-  string keyNameUri =  m_impl->toInternalKeyName(keyName, KEY_CLASS_SYMMETRIC);
+  // CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
+  //                                                             0,
+  //                                                             &kCFTypeDictionaryKeyCallBacks,
+  //                                                             &kCFTypeDictionaryValueCallBacks);
 
-  CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
-                                                              0,
-                                                              &kCFTypeDictionaryKeyCallBacks,
-                                                              &kCFTypeDictionaryValueCallBacks);
+  // CFStringRef keyLabel = CFStringCreateWithCString(NULL, 
+  //                                                  keyNameUri.c_str(), 
+  //                                                  kCFStringEncodingUTF8);
 
-  CFStringRef keyLabel = CFStringCreateWithCString(NULL, 
-                                                   keyNameUri.c_str(), 
-                                                   kCFStringEncodingUTF8);
+  // CFDictionaryAddValue(attrDict, kSecAttrKeyType, m_impl->getSymKeyType(keyType));
+  // CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &keySize));
+  // CFDictionaryAddValue(attrDict, kSecAttrIsPermanent, kCFBooleanTrue);
+  // CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
 
-  CFDictionaryAddValue(attrDict, kSecAttrKeyType, m_impl->getSymKeyType(keyType));
-  CFDictionaryAddValue(attrDict, kSecAttrKeySizeInBits, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &keySize));
-  CFDictionaryAddValue(attrDict, kSecAttrIsPermanent, kCFBooleanTrue);
-  CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
+  // CFErrorRef error = NULL;
 
-  CFErrorRef error = NULL;
+  // SecKeyRef symmetricKey = SecKeyGenerateSymmetric(attrDict, &error);
 
-  SecKeyRef symmetricKey = SecKeyGenerateSymmetric(attrDict, &error);
-
-  if (error) 
-    throw Error("Fail to create a symmetric key");
+  // if (error) 
+  //   throw Error("Fail to create a symmetric key");
 }
 
-ptr_lib::shared_ptr<PublicKey>
+shared_ptr<PublicKey>
 SecTpmOsx::getPublicKeyFromTpm(const Name & keyName)
 {
   _LOG_TRACE("OSXPrivateKeyStorage::getPublickey");
@@ -388,8 +387,10 @@
     {
       if(res == errSecAuthFailed && !retry)
         {
-          unlockTpm(0, 0, false);
-          return exportPrivateKeyPkcs1FromTpmInternal(keyName, true);
+          if(unlockTpm(0, 0, false))
+            return exportPrivateKeyPkcs1FromTpmInternal(keyName, true);
+          else
+            return shared_ptr<Buffer>();
         }
       else
         return shared_ptr<Buffer>();
@@ -479,8 +480,10 @@
     {
       if(res == errSecAuthFailed && !retry)
         {
-          unlockTpm(0, 0, false);
-          return importPrivateKeyPkcs1IntoTpmInternal(keyName, buf, size, true);
+          if(unlockTpm(0, 0, false))
+            return importPrivateKeyPkcs1IntoTpmInternal(keyName, buf, size, true);
+          else
+            return false;
         }
       else
         return false;
@@ -566,8 +569,7 @@
   CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL,
                                                   data,
                                                   dataLength,
-                                                  kCFAllocatorNull
-                                                  );
+                                                  kCFAllocatorNull);
 
   SecKeyRef privateKey = (SecKeyRef)m_impl->getKey(keyName, KEY_CLASS_PRIVATE);
     
@@ -583,8 +585,7 @@
   if (error) throw Error("Fail to configure input of signer");
 
   // Enable use of padding
-  SecTransformSetAttribute(
-                           signer,
+  SecTransformSetAttribute(signer,
                            kSecPaddingKey,
                            kSecPaddingPKCS1Key,
                            &error);
@@ -611,8 +612,10 @@
     {
       if(!retry) 
         {
-          unlockTpm(0, 0, false);
-          return signInTpmInternal(data, dataLength, keyName, digestAlgorithm, true);
+          if(unlockTpm(0, 0, false))
+            return signInTpmInternal(data, dataLength, keyName, digestAlgorithm, true);
+          else
+            throw Error("Fail to unlock the keychain");
         }
       else
         {
@@ -624,136 +627,130 @@
   if (!signature) throw Error("Signature is NULL!\n");
 
   return Block(Tlv::SignatureValue,
-               ptr_lib::make_shared<Buffer>(CFDataGetBytePtr(signature), CFDataGetLength(signature)));
+               make_shared<Buffer>(CFDataGetBytePtr(signature), CFDataGetLength(signature)));
 }
 
 ConstBufferPtr
 SecTpmOsx::decryptInTpm(const uint8_t* data, size_t dataLength, const Name & keyName, bool sym)
 {
-  _LOG_TRACE("OSXPrivateKeyStorage::Decrypt");
+  throw Error("SecTpmOsx::decryptInTpm is not supported");
+  // _LOG_TRACE("OSXPrivateKeyStorage::Decrypt");
 
-  KeyClass keyClass;
-  if(sym)
-    keyClass = KEY_CLASS_SYMMETRIC;
-  else
-    keyClass = KEY_CLASS_PRIVATE;
+  // KeyClass keyClass;
+  // if(sym)
+  //   keyClass = KEY_CLASS_SYMMETRIC;
+  // else
+  //   keyClass = KEY_CLASS_PRIVATE;
 
-  CFDataRef dataRef = CFDataCreate(NULL,
-                                   reinterpret_cast<const unsigned char*>(data),
-                                   dataLength
-                                   );
+  // CFDataRef dataRef = CFDataCreate(NULL,
+  //                                  reinterpret_cast<const unsigned char*>(data),
+  //                                  dataLength
+  //                                  );
 
-  // _LOG_DEBUG("CreateData");
+  // // _LOG_DEBUG("CreateData");
     
-  SecKeyRef decryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
+  // SecKeyRef decryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
 
-  // _LOG_DEBUG("GetKey");
+  // // _LOG_DEBUG("GetKey");
 
-  CFErrorRef error;
-  SecTransformRef decrypt = SecDecryptTransformCreate(decryptKey, &error);
-  if (error) throw Error("Fail to create decrypt");
+  // CFErrorRef error;
+  // SecTransformRef decrypt = SecDecryptTransformCreate(decryptKey, &error);
+  // if (error) throw Error("Fail to create decrypt");
 
-  Boolean set_res = SecTransformSetAttribute(decrypt,
-                                             kSecTransformInputAttributeName,
-                                             dataRef,
-                                             &error);
-  if (error) throw Error("Fail to configure decrypt");
+  // Boolean set_res = SecTransformSetAttribute(decrypt,
+  //                                            kSecTransformInputAttributeName,
+  //                                            dataRef,
+  //                                            &error);
+  // if (error) throw Error("Fail to configure decrypt");
 
-  CFDataRef output = (CFDataRef) SecTransformExecute(decrypt, &error);
-  if (error)
-    {
-      CFShow(error);
-      throw Error("Fail to decrypt data");
-    }
-  if (!output) throw Error("Output is NULL!\n");
+  // CFDataRef output = (CFDataRef) SecTransformExecute(decrypt, &error);
+  // if (error)
+  //   {
+  //     CFShow(error);
+  //     throw Error("Fail to decrypt data");
+  //   }
+  // if (!output) throw Error("Output is NULL!\n");
 
-  return ptr_lib::make_shared<Buffer>(CFDataGetBytePtr(output), CFDataGetLength(output));
+  // return make_shared<Buffer>(CFDataGetBytePtr(output), CFDataGetLength(output));
 }
   
-bool
-SecTpmOsx::setACL(const Name & keyName, KeyClass keyClass, int acl, const string & appPath)
+void
+SecTpmOsx::addAppToACL(const Name & keyName, KeyClass keyClass, const string & appPath, AclType acl)
 {
-  SecKeychainItemRef privateKey = m_impl->getKey(keyName, keyClass);
-    
-  SecAccessRef accRef;
-  OSStatus acc_res = SecKeychainItemCopyAccess(privateKey, &accRef);
-
-  CFArrayRef signACL = SecAccessCopyMatchingACLList(accRef,
-                                                    kSecACLAuthorizationSign);
-
-  SecACLRef aclRef = (SecACLRef) CFArrayGetValueAtIndex(signACL, 0);
-
-  CFArrayRef appList;
-  CFStringRef description;
-  SecKeychainPromptSelector promptSelector;
-  OSStatus acl_res = SecACLCopyContents(aclRef,
-                                        &appList,
-                                        &description,
-                                        &promptSelector);
-
-  CFMutableArrayRef newAppList = CFArrayCreateMutableCopy(NULL,
-                                                          0,
-                                                          appList);
-
-  SecTrustedApplicationRef trustedApp;
-  acl_res = SecTrustedApplicationCreateFromPath(appPath.c_str(),
-                                                &trustedApp);
-    
-  CFArrayAppendValue(newAppList, trustedApp);
-
-
-  CFArrayRef authList = SecACLCopyAuthorizations(aclRef);
-    
-  acl_res = SecACLRemove(aclRef);
-
-  SecACLRef newACL;
-  acl_res = SecACLCreateWithSimpleContents(accRef,
-                                           newAppList,
-                                           description,
-                                           promptSelector,
-                                           &newACL);
-
-  acl_res = SecACLUpdateAuthorizations(newACL, authList);
-
-  acc_res = SecKeychainItemSetAccess(privateKey, accRef);
-
-  return true;
+  if(keyClass == KEY_CLASS_PRIVATE && acl == ACL_TYPE_PRIVATE)
+    {
+      SecKeychainItemRef privateKey = m_impl->getKey(keyName, keyClass);
+      
+      SecAccessRef accRef;
+      OSStatus acc_res = SecKeychainItemCopyAccess(privateKey, &accRef);
+      
+      CFArrayRef signACL = SecAccessCopyMatchingACLList(accRef,
+                                                        kSecACLAuthorizationSign);
+      
+      SecACLRef aclRef = (SecACLRef) CFArrayGetValueAtIndex(signACL, 0);
+      
+      CFArrayRef appList;
+      CFStringRef description;
+      SecKeychainPromptSelector promptSelector;
+      OSStatus acl_res = SecACLCopyContents(aclRef,
+                                            &appList,
+                                            &description,
+                                            &promptSelector);
+      
+      CFMutableArrayRef newAppList = CFArrayCreateMutableCopy(NULL,
+                                                              0,
+                                                              appList);
+      
+      SecTrustedApplicationRef trustedApp;
+      acl_res = SecTrustedApplicationCreateFromPath(appPath.c_str(),
+                                                    &trustedApp);
+      
+      CFArrayAppendValue(newAppList, trustedApp);
+      
+      acl_res = SecACLSetContents(aclRef,
+                                  newAppList,
+                                  description,
+                                  promptSelector);
+      
+      acc_res = SecKeychainItemSetAccess(privateKey, accRef);
+    }
 }
 
 ConstBufferPtr
 SecTpmOsx::encryptInTpm(const uint8_t* data, size_t dataLength, const Name & keyName, bool sym)
 {
-  _LOG_TRACE("OSXPrivateKeyStorage::Encrypt");
+  throw Error("SecTpmOsx::encryptInTpm is not supported");
+  // _LOG_TRACE("OSXPrivateKeyStorage::Encrypt");
 
-  KeyClass keyClass;
-  if(sym)
-    keyClass = KEY_CLASS_SYMMETRIC;
-  else
-    keyClass = KEY_CLASS_PUBLIC;
+  // KeyClass keyClass;
+  // if(sym)
+  //   keyClass = KEY_CLASS_SYMMETRIC;
+  // else
+  //   keyClass = KEY_CLASS_PUBLIC;
     
-  CFDataRef dataRef = CFDataCreate(NULL,
-                                   reinterpret_cast<const unsigned char*>(data),
-                                   dataLength
-                                   );
+  // CFDataRef dataRef = CFDataCreate(NULL,
+  //                                  reinterpret_cast<const unsigned char*>(data),
+  //                                  dataLength
+  //                                  );
     
-  SecKeyRef encryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
+  // SecKeyRef encryptKey = (SecKeyRef)m_impl->getKey(keyName, keyClass);
 
-  CFErrorRef error;
-  SecTransformRef encrypt = SecEncryptTransformCreate(encryptKey, &error);
-  if (error) throw Error("Fail to create encrypt");
+  // CFErrorRef error;
+  // SecTransformRef encrypt = SecEncryptTransformCreate(encryptKey, &error);
+  // if (error) throw Error("Fail to create encrypt");
 
-  Boolean set_res = SecTransformSetAttribute(encrypt,
-                                             kSecTransformInputAttributeName,
-                                             dataRef,
-                                             &error);
-  if (error) throw Error("Fail to configure encrypt");
+  // Boolean set_res = SecTransformSetAttribute(encrypt,
+  //                                            kSecTransformInputAttributeName,
+  //                                            dataRef,
+  //                                            &error);
+  // if (error) throw Error("Fail to configure encrypt");
 
-  CFDataRef output = (CFDataRef) SecTransformExecute(encrypt, &error);
-  if (error) throw Error("Fail to encrypt data");
+  // CFDataRef output = (CFDataRef) SecTransformExecute(encrypt, &error);
+  // if (error) throw Error("Fail to encrypt data");
 
-  if (!output) throw Error("Output is NULL!\n");
+  // if (!output) throw Error("Output is NULL!\n");
 
-  return ptr_lib::make_shared<Buffer> (CFDataGetBytePtr(output), CFDataGetLength(output));
+  // return make_shared<Buffer> (CFDataGetBytePtr(output), CFDataGetLength(output));
 }
 
 bool
diff --git a/src/security/sec-tpm-osx.hpp b/src/security/sec-tpm-osx.hpp
index e18d3bc..f9cfc57 100644
--- a/src/security/sec-tpm-osx.hpp
+++ b/src/security/sec-tpm-osx.hpp
@@ -42,7 +42,7 @@
   virtual bool
   locked();
 
-  virtual void
+  virtual bool
   unlockTpm(const char* password, size_t passwordLength, bool usePassword);
 
   virtual void 
@@ -57,7 +57,7 @@
     deleteKeyPairInTpmInternal(keyName, false);
   }
 
-  virtual ptr_lib::shared_ptr<PublicKey> 
+  virtual shared_ptr<PublicKey> 
   getPublicKeyFromTpm(const Name& keyName);
   
   virtual Block
@@ -81,22 +81,8 @@
   virtual bool
   generateRandomBlock(uint8_t* res, size_t size); 
 
-
-  ////////////////////////////////////////////////////////////////////////////////////
-  // OSX-specifics
-  ////////////////////////////////////////////////////////////////////////////////////
-  
-  /**
-   * @brief Configure ACL of a particular key.
-   *
-   * @param keyName the name of key
-   * @param keyClass the class of key, e.g. Private Key
-   * @param acl the new acl of the key
-   * @param appPath the absolute path to the application
-   * @returns true if setting succeeds
-   */
-  bool 
-  setACL(const Name& keyName, KeyClass keyClass, int acl, const std::string& appPath);
+  virtual void 
+  addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl);
 
 protected:
   /******************************
diff --git a/src/security/sec-tpm.cpp b/src/security/sec-tpm.cpp
index f93169d..56c39b8 100644
--- a/src/security/sec-tpm.cpp
+++ b/src/security/sec-tpm.cpp
@@ -26,224 +26,260 @@
 ConstBufferPtr
 SecTpm::exportPrivateKeyPkcs8FromTpm(const Name& keyName, const string& passwordStr)
 {
+  using namespace CryptoPP;
+    
   uint8_t salt[8] = {0};
   uint8_t iv[8] = {0};
     
-  try{
-    using namespace CryptoPP;
+  // derive key
+  if(!generateRandomBlock(salt, 8) || !generateRandomBlock(iv, 8))
+    throw Error("Cannot generate salt or iv");
 
-    // derive key
-    if(!generateRandomBlock(salt, 8))
-      return shared_ptr<Buffer>();
-    
-    if(!generateRandomBlock(iv, 8))
-      return shared_ptr<Buffer>();
-    
-    uint32_t iterationCount = 2048;
-
-    PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
-    size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
-    byte derived[24] = {0};
-    byte purpose = 0;
-
-    keyGenerator.DeriveKey(derived, derivedLen, 
-                           purpose, 
-                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(), 
-                           salt, 8, 
-                           iterationCount);
-
-    //encrypt
-    CBC_Mode< DES_EDE3 >::Encryption e;
-    e.SetKeyWithIV(derived, derivedLen, iv);
-    
-    string encrypted;
-    OBufferStream encryptedOs;
-    ConstBufferPtr pkcs1PrivateKey = exportPrivateKeyPkcs1FromTpm(keyName);
-    StringSource stringSource(pkcs1PrivateKey->buf(), pkcs1PrivateKey->size(), true, 
-			      new StreamTransformationFilter(e, new FileSink(encryptedOs)));
-
-    //encode
-    OID pbes2Id("1.2.840.113549.1.5.13");
-    OID pbkdf2Id("1.2.840.113549.1.5.12");
-    OID pbes2encsId("1.2.840.113549.3.7");
-
-    OBufferStream pkcs8Os;
-    FileSink sink(pkcs8Os);
+  uint32_t iterationCount = 2048;
   
-    // EncryptedPrivateKeyInfo ::= SEQUENCE {
-    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
-    //   encryptedData        OCTET STRING }
-    DERSequenceEncoder encryptedPrivateKeyInfo(sink);
+  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
+  size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
+  byte derived[24] = {0};
+  byte purpose = 0;
+  
+  try
     {
-      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
-      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
-      //   parameters     SEQUENCE {{PBES2-params}} }
-      DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
-      {
-        pbes2Id.encode(encryptionAlgorithm);
-        // PBES2-params ::= SEQUENCE {
-        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
-        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
-        DERSequenceEncoder pbes2Params(encryptionAlgorithm);
-        {
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
-          //   parameters     SEQUENCE {{PBKDF2-params}} }
-          DERSequenceEncoder pbes2KDFs(pbes2Params);
-          {
-             pbkdf2Id.encode(pbes2KDFs);
-            // AlgorithmIdentifier ::= SEQUENCE {
-            //   salt           OCTET STRING,
-            //   iterationCount INTEGER (1..MAX),
-            //   keyLength      INTEGER (1..MAX) OPTIONAL,
-            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
-            DERSequenceEncoder pbkdf2Params(pbes2KDFs);
-            {
-              DEREncodeOctetString(pbkdf2Params, salt, 8);
-              DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
-            }
-            pbkdf2Params.MessageEnd();
-          }
-          pbes2KDFs.MessageEnd();
-        
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
-          //   parameters  OCTET STRING} {{iv}} }
-          DERSequenceEncoder pbes2Encs(pbes2Params);
-          {
-            pbes2encsId.encode(pbes2Encs);
-            DEREncodeOctetString(pbes2Encs, iv, 8);
-          }
-          pbes2Encs.MessageEnd();
-        }
-        pbes2Params.MessageEnd();
-      }
-      encryptionAlgorithm.MessageEnd();
-
-      DEREncodeOctetString(encryptedPrivateKeyInfo, encryptedOs.buf()->buf(), encryptedOs.buf()->size());
+      keyGenerator.DeriveKey(derived, derivedLen, purpose, 
+                             reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(), 
+                             salt, 8, iterationCount);
     }
-    encryptedPrivateKeyInfo.MessageEnd();
+  catch(CryptoPP::Exception& e)
+    {
+      throw Error("Cannot derived the encryption key");
+    }
 
-    return pkcs8Os.buf();
-  }catch(...){
-    return shared_ptr<Buffer>();
-  }
+  //encrypt
+  CBC_Mode< DES_EDE3 >::Encryption e;
+  e.SetKeyWithIV(derived, derivedLen, iv);
+  
+  ConstBufferPtr pkcs1PrivateKey = exportPrivateKeyPkcs1FromTpm(keyName);
+  if(!static_cast<bool>(pkcs1PrivateKey))
+    throw Error("Cannot export the private key, #1");
+
+  OBufferStream encryptedOs;
+  try
+    {
+      StringSource stringSource(pkcs1PrivateKey->buf(), pkcs1PrivateKey->size(), true, 
+                                new StreamTransformationFilter(e, new FileSink(encryptedOs)));
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      throw Error("Cannot export the private key, #2");
+    }
+
+  //encode
+  OID pbes2Id("1.2.840.113549.1.5.13");
+  OID pbkdf2Id("1.2.840.113549.1.5.12");
+  OID pbes2encsId("1.2.840.113549.3.7");
+
+  OBufferStream pkcs8Os;
+  try
+    {
+      FileSink sink(pkcs8Os);
+      
+      // EncryptedPrivateKeyInfo ::= SEQUENCE {
+      //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
+      //   encryptedData        OCTET STRING }
+      DERSequenceEncoder encryptedPrivateKeyInfo(sink);
+      {
+        // EncryptionAlgorithmIdentifier ::= SEQUENCE {
+        //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
+        //   parameters     SEQUENCE {{PBES2-params}} }
+        DERSequenceEncoder encryptionAlgorithm(encryptedPrivateKeyInfo);
+        {
+          pbes2Id.encode(encryptionAlgorithm);
+          // PBES2-params ::= SEQUENCE {
+          //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+          //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
+          DERSequenceEncoder pbes2Params(encryptionAlgorithm);
+          {
+            // AlgorithmIdentifier ::= SEQUENCE {
+            //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
+            //   parameters     SEQUENCE {{PBKDF2-params}} }
+            DERSequenceEncoder pbes2KDFs(pbes2Params);
+            {
+              pbkdf2Id.encode(pbes2KDFs);
+              // AlgorithmIdentifier ::= SEQUENCE {
+              //   salt           OCTET STRING,
+              //   iterationCount INTEGER (1..MAX),
+              //   keyLength      INTEGER (1..MAX) OPTIONAL,
+              //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
+              DERSequenceEncoder pbkdf2Params(pbes2KDFs);
+              {
+                DEREncodeOctetString(pbkdf2Params, salt, 8);
+                DEREncodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
+              }
+              pbkdf2Params.MessageEnd();
+            }
+            pbes2KDFs.MessageEnd();
+            
+            // AlgorithmIdentifier ::= SEQUENCE {
+            //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
+            //   parameters  OCTET STRING} {{iv}} }
+            DERSequenceEncoder pbes2Encs(pbes2Params);
+            {
+              pbes2encsId.encode(pbes2Encs);
+              DEREncodeOctetString(pbes2Encs, iv, 8);
+            }
+            pbes2Encs.MessageEnd();
+          }
+          pbes2Params.MessageEnd();
+        }
+        encryptionAlgorithm.MessageEnd();
+        
+        DEREncodeOctetString(encryptedPrivateKeyInfo, encryptedOs.buf()->buf(), encryptedOs.buf()->size());
+      }
+      encryptedPrivateKeyInfo.MessageEnd();
+      
+      return pkcs8Os.buf();
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      throw Error("Cannot export the private key, #3");
+    }
 }
 
 bool
 SecTpm::importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size, const string& passwordStr)
 {
-  try{
-    using namespace CryptoPP;
-    
-    OID pbes2Id;
-    OID pbkdf2Id;
-    SecByteBlock saltBlock;
-    uint32_t iterationCount;
-    OID pbes2encsId;
-    SecByteBlock ivBlock;
-    SecByteBlock encryptedDataBlock;
-    
-    //decode some decoding processes are not necessary for now, because we assume only one encryption scheme.
-    StringSource source(buf, size, true);
-    
-    // EncryptedPrivateKeyInfo ::= SEQUENCE {
-    //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
-    //   encryptedData        OCTET STRING }
-    BERSequenceDecoder encryptedPrivateKeyInfo(source);
+  using namespace CryptoPP;
+  
+  OID pbes2Id;
+  OID pbkdf2Id;
+  SecByteBlock saltBlock;
+  uint32_t iterationCount;
+  OID pbes2encsId;
+  SecByteBlock ivBlock;
+  SecByteBlock encryptedDataBlock;
+  
+  try
     {
-      // EncryptionAlgorithmIdentifier ::= SEQUENCE {
-      //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
-      //   parameters     SEQUENCE {{PBES2-params}} }
-      BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
+      //decode some decoding processes are not necessary for now, because we assume only one encryption scheme.
+      StringSource source(buf, size, true);
+      
+      // EncryptedPrivateKeyInfo ::= SEQUENCE {
+      //   encryptionAlgorithm  EncryptionAlgorithmIdentifier,
+      //   encryptedData        OCTET STRING }
+      BERSequenceDecoder encryptedPrivateKeyInfo(source);
       {
-        pbes2Id.decode(encryptionAlgorithm);
-        // PBES2-params ::= SEQUENCE {
-        //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
-        //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
-        BERSequenceDecoder pbes2Params(encryptionAlgorithm);
+        // EncryptionAlgorithmIdentifier ::= SEQUENCE {
+        //   algorithm      OBJECT IDENTIFIER {{PBES2-id}},
+        //   parameters     SEQUENCE {{PBES2-params}} }
+        BERSequenceDecoder encryptionAlgorithm(encryptedPrivateKeyInfo);
         {
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
-          //   parameters     SEQUENCE {{PBKDF2-params}} }
-          BERSequenceDecoder pbes2KDFs(pbes2Params);
+          pbes2Id.decode(encryptionAlgorithm);
+          // PBES2-params ::= SEQUENCE {
+          //   keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
+          //   encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} }
+          BERSequenceDecoder pbes2Params(encryptionAlgorithm);
           {
-            pbkdf2Id.decode(pbes2KDFs);
             // AlgorithmIdentifier ::= SEQUENCE {
-            //   salt           OCTET STRING,
-            //   iterationCount INTEGER (1..MAX),
-            //   keyLength      INTEGER (1..MAX) OPTIONAL,
-            //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
-            BERSequenceDecoder pbkdf2Params(pbes2KDFs);
+            //   algorithm      OBJECT IDENTIFIER {{PBKDF2-id}},
+            //   parameters     SEQUENCE {{PBKDF2-params}} }
+            BERSequenceDecoder pbes2KDFs(pbes2Params);
             {
-              BERDecodeOctetString(pbkdf2Params, saltBlock);
-              BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
+              pbkdf2Id.decode(pbes2KDFs);
+              // AlgorithmIdentifier ::= SEQUENCE {
+              //   salt           OCTET STRING,
+              //   iterationCount INTEGER (1..MAX),
+              //   keyLength      INTEGER (1..MAX) OPTIONAL,
+              //   prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 }
+              BERSequenceDecoder pbkdf2Params(pbes2KDFs);
+              {
+                BERDecodeOctetString(pbkdf2Params, saltBlock);
+                BERDecodeUnsigned<uint32_t>(pbkdf2Params, iterationCount, INTEGER);
+              }
+              pbkdf2Params.MessageEnd();
             }
-            pbkdf2Params.MessageEnd();
+            pbes2KDFs.MessageEnd();
+            
+            // AlgorithmIdentifier ::= SEQUENCE {
+            //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
+            //   parameters  OCTET STRING} {{iv}} }
+            BERSequenceDecoder pbes2Encs(pbes2Params);
+            {
+              pbes2encsId.decode(pbes2Encs);
+              BERDecodeOctetString(pbes2Encs, ivBlock);
+            }
+            pbes2Encs.MessageEnd();
           }
-          pbes2KDFs.MessageEnd();
-        
-          // AlgorithmIdentifier ::= SEQUENCE {
-          //   algorithm   OBJECT IDENTIFIER {{DES-EDE3-CBC-PAD}},
-          //   parameters  OCTET STRING} {{iv}} }
-          BERSequenceDecoder pbes2Encs(pbes2Params);
-          {
-            pbes2encsId.decode(pbes2Encs);
-            BERDecodeOctetString(pbes2Encs, ivBlock);
-          }
-          pbes2Encs.MessageEnd();
+          pbes2Params.MessageEnd();
         }
-        pbes2Params.MessageEnd();
-      }
-      encryptionAlgorithm.MessageEnd();
+        encryptionAlgorithm.MessageEnd();
 
-      BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
+        BERDecodeOctetString(encryptedPrivateKeyInfo, encryptedDataBlock);
+      }
+      encryptedPrivateKeyInfo.MessageEnd();
     }
-    encryptedPrivateKeyInfo.MessageEnd();
+  catch(CryptoPP::Exception& e)
+    {
+      return false;
+    }
 
   
-    PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
-    size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
-    byte derived[24] = {0};
-    byte purpose = 0;
-      
-    keyGenerator.DeriveKey(derived, derivedLen, 
-                           purpose, 
-                           reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(), 
-                           saltBlock.BytePtr(), saltBlock.size(), 
-                           iterationCount);
-
+  PKCS5_PBKDF2_HMAC<SHA1> keyGenerator;
+  size_t derivedLen = 24; //For DES-EDE3-CBC-PAD
+  byte derived[24] = {0};
+  byte purpose = 0;
+  
+  try
+    {
+      keyGenerator.DeriveKey(derived, derivedLen, 
+                             purpose, 
+                             reinterpret_cast<const byte*>(passwordStr.c_str()), passwordStr.size(), 
+                             saltBlock.BytePtr(), saltBlock.size(), 
+                             iterationCount);
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      return false;
+    }
         
-    //decrypt
-    CBC_Mode< DES_EDE3 >::Decryption d;
-    d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
-    
-    OBufferStream privateKeyOs;
-    StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true, 
-                                 new StreamTransformationFilter(d,  new FileSink(privateKeyOs)));
-
-    if(!importPrivateKeyPkcs1IntoTpm(keyName, privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
+  //decrypt
+  CBC_Mode< DES_EDE3 >::Decryption d;
+  d.SetKeyWithIV(derived, derivedLen, ivBlock.BytePtr());
+  
+  OBufferStream privateKeyOs;
+  try
+    {
+      StringSource encryptedSource(encryptedDataBlock.BytePtr(), encryptedDataBlock.size(), true, 
+                                   new StreamTransformationFilter(d,  new FileSink(privateKeyOs)));
+    }
+  catch(CryptoPP::Exception& e)
+    {
       return false;
-    
-    //derive public key
-    RSA::PrivateKey privateKey;
-    privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
+    }
 
-    RSAFunction publicKey(privateKey);
-
-    OBufferStream publicKeyOs;
-    FileSink publicKeySink(publicKeyOs);
-    publicKey.DEREncode(publicKeySink);
-    publicKeySink.MessageEnd();
-
-    if(!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
-      return false;
-
-    return true;
-  }catch(std::runtime_error& e){
-    cerr << e.what() << endl;
+  if(!importPrivateKeyPkcs1IntoTpm(keyName, privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()))
     return false;
-  }
+    
+  //derive public key
+  OBufferStream publicKeyOs;
+
+  try
+    {
+      RSA::PrivateKey privateKey;
+      privateKey.Load(StringStore(privateKeyOs.buf()->buf(), privateKeyOs.buf()->size()).Ref());
+      RSAFunction publicKey(privateKey);
+  
+      FileSink publicKeySink(publicKeyOs);
+      publicKey.DEREncode(publicKeySink);
+      publicKeySink.MessageEnd();
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      return false;
+    }
+
+  if(!importPublicKeyPkcs1IntoTpm(keyName, publicKeyOs.buf()->buf(), publicKeyOs.buf()->size()))
+    return false;
+  
+  return true;
 }
 
 
diff --git a/src/security/sec-tpm.hpp b/src/security/sec-tpm.hpp
index 5d836ee..2be17d8 100644
--- a/src/security/sec-tpm.hpp
+++ b/src/security/sec-tpm.hpp
@@ -80,8 +80,9 @@
    * @param password The password.
    * @param passwordLength The password size. 0 indicates no password.
    * @param usePassword True if we want to use the supplied password to unlock the TPM.
+   * @return true if TPM is unlocked, otherwise false.
    */
-  virtual void
+  virtual bool
   unlockTpm(const char* password, size_t passwordLength, bool usePassword) = 0;
 
   /**
@@ -107,7 +108,8 @@
    * @brief Get a public key.
    *
    * @param keyName The public key name.
-   * @return The public key if exists, otherwise a NULL pointer.
+   * @return The public key.
+   * @throws SecTpm::Error if public key does not exist in TPM.
    */
   virtual shared_ptr<PublicKey> 
   getPublicKeyFromTpm(const Name& keyName) = 0;
@@ -157,6 +159,7 @@
    * @param keyName The name of the key.
    * @param keyType The type of the key, e.g. KEY_TYPE_AES.
    * @param keySize The size of the key.
+   * @throws SecTpm::Error if key generating fails.
    */
   virtual void 
   generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
@@ -182,11 +185,23 @@
   generateRandomBlock(uint8_t* res, size_t size) = 0;
 
   /**
+   * @brief Add the application into the ACL of a particular key.
+   *
+   * @param keyName the name of key
+   * @param keyClass the class of key, e.g. Private Key
+   * @param appPath the absolute path to the application
+   * @param acl the new acl of the key
+   */
+  virtual void 
+  addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl) = 0;
+
+  /**
    * @brief Export a private key in PKCS#8 format.
    * 
    * @param keyName The private key name.
    * @param password The password to encrypt the private key.
-   * @return The private key info (in PKCS8 format) if exist, otherwise a NULL pointer.
+   * @return The private key info (in PKCS8 format) if exist.
+   * @throws SecTpm::Error if private key cannot be exported.
    */
   ConstBufferPtr
   exportPrivateKeyPkcs8FromTpm(const Name& keyName, const std::string& password);
diff --git a/src/security/security-common.hpp b/src/security/security-common.hpp
index 9ce4599..1bea763 100644
--- a/src/security/security-common.hpp
+++ b/src/security/security-common.hpp
@@ -38,6 +38,11 @@
   // ENCRYPT_MODE_CBC_AES
 };
 
+enum AclType {
+  ACL_TYPE_PUBLIC,
+  ACL_TYPE_PRIVATE,
+};
+
 }
 
 #endif
diff --git a/tests/security/test-sec-public-info-sqlite3.cpp b/tests/security/test-sec-public-info-sqlite3.cpp
index 4335b71..bbbe01c 100644
--- a/tests/security/test-sec-public-info-sqlite3.cpp
+++ b/tests/security/test-sec-public-info-sqlite3.cpp
@@ -22,30 +22,34 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identity(string("/TestSecPublicInfoSqlite3/Delete/") + boost::lexical_cast<string>(time::now()));
+  Name identity("/TestSecPublicInfoSqlite3/Delete/" + boost::lexical_cast<string>(time::now()));
   Name certName1;
   BOOST_REQUIRE_NO_THROW(certName1 = keyChain.createIdentity(identity));
 
   Name keyName1 = IdentityCertificate::certificateNameToPublicKeyName(certName1);  
   Name keyName2;
-  BOOST_CHECK_NO_THROW(keyName2 = keyChain.generateRSAKeyPairAsDefault(identity));
+  BOOST_REQUIRE_NO_THROW(keyName2 = keyChain.generateRSAKeyPairAsDefault(identity));
   
-  ptr_lib::shared_ptr<IdentityCertificate> cert2 = keyChain.selfSign(keyName2);
+  shared_ptr<IdentityCertificate> cert2;
+  BOOST_REQUIRE_NO_THROW(cert2 = keyChain.selfSign(keyName2));
   Name certName2 = cert2->getName();
-  keyChain.addCertificateAsKeyDefault(*cert2);
+  BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert2));
   
   Name keyName3;
-  BOOST_CHECK_NO_THROW(keyName3 = keyChain.generateRSAKeyPairAsDefault(identity));
+  BOOST_REQUIRE_NO_THROW(keyName3 = keyChain.generateRSAKeyPairAsDefault(identity));
   
-  ptr_lib::shared_ptr<IdentityCertificate> cert3 = keyChain.selfSign(keyName3);
+  shared_ptr<IdentityCertificate> cert3;
+  BOOST_REQUIRE_NO_THROW(cert3 = keyChain.selfSign(keyName3));
   Name certName3 = cert3->getName();
-  keyChain.addCertificateAsKeyDefault(*cert3);
-  ptr_lib::shared_ptr<IdentityCertificate> cert4 = keyChain.selfSign(keyName3);
+  BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert3));
+  shared_ptr<IdentityCertificate> cert4;
+  BOOST_REQUIRE_NO_THROW(cert4 = keyChain.selfSign(keyName3));
   Name certName4 = cert4->getName();
-  keyChain.addCertificateAsKeyDefault(*cert4);
-  ptr_lib::shared_ptr<IdentityCertificate> cert5 = keyChain.selfSign(keyName3);
+  BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert4));
+  shared_ptr<IdentityCertificate> cert5;
+  BOOST_REQUIRE_NO_THROW(cert5 = keyChain.selfSign(keyName3));
   Name certName5 = cert5->getName();
-  keyChain.addCertificateAsKeyDefault(*cert5);
+  BOOST_REQUIRE_NO_THROW(keyChain.addCertificateAsKeyDefault(*cert5));
 
   BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), true);
   BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName1), true);
diff --git a/tests/security/test-sec-tpm-file.cpp b/tests/security/test-sec-tpm-file.cpp
index c16ed24..146a1e1 100644
--- a/tests/security/test-sec-tpm-file.cpp
+++ b/tests/security/test-sec-tpm-file.cpp
@@ -46,23 +46,30 @@
   Data data("/tmp/test/1");
   const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
 
-  Block sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256);
-  ptr_lib::shared_ptr<PublicKey> pubkeyPtr = tpm.getPublicKeyFromTpm(keyName);
+  Block sigBlock;
+  BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256));
+  shared_ptr<PublicKey> pubkeyPtr;
+  BOOST_CHECK_NO_THROW(pubkeyPtr = tpm.getPublicKeyFromTpm(keyName));
 
-  {
-    using namespace CryptoPP;
-    
-    RSA::PublicKey publicKey;
-    ByteQueue queue;
-    queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
-    publicKey.Load(queue);
-
-    RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-    bool result = verifier.VerifyMessage(content, sizeof(content),
-				  sigBlock.value(), sigBlock.value_size());
-  
-    BOOST_REQUIRE_EQUAL(result, true);
-  }
+  try
+    {
+      using namespace CryptoPP;
+      
+      RSA::PublicKey publicKey;
+      ByteQueue queue;
+      queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
+      publicKey.Load(queue);
+      
+      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+      bool result = verifier.VerifyMessage(content, sizeof(content),
+					   sigBlock.value(), sigBlock.value_size());
+      
+      BOOST_CHECK_EQUAL(result, true);
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      BOOST_CHECK(false);
+    }
 
   tpm.deleteKeyPairInTpm(keyName);
 }
@@ -96,7 +103,7 @@
 "3082050E304006092A864886F70D01050D3033301B06092A864886F70D01050C300E0408209CF0B1B4C856A802020800301406082A864886F70D0307040884B1229D80690211048204C8DA62C11E1CCFC43F318D0C03DA4B11350122B18F23645C454F41BB46C7F8EED4F95041A9130B33E989AF338951A286B55FB9A707AF1C5B2E1FAE7CD66D6D556CBFD90640BDA0D7904DD8D89CF15AB24F1A652AB76E16411B78E8A9AAEEB6EE06FA793B2B4A3EE4B9B5DFB3FC3D38076145915A11CEC8FD2EAB70F51A0DA8B88B73B4DD5BAFB933ABCD92FFBA7843083CCE6B7A6BD9A51094EFF93DC93A19B4982F5FF8696FDF07B76366B6408EC18F4EA218A4F6B5EA85A5AF3B082D0E3AE74665BDD9FC7DE87A7A54EB038AB2E9196365F8481F1CC601EB866D554B4FBCDABECD35CBE404F3CB313E9799D111AD955C42629FB1A01E6138EFF15E6DE7D2BF8754868157DAC72EE5125221D502DCF0B8E8FF5CA87B601357785E7C95CBFC369B31D747ADACFB95E614507A5622ACAA3541B4FE02AEEC2DD588D3D7860A50C78EF460C39E250851140155052F18419F37D551FC3F5224764A17A2C47F9CEDC63780E3AF48C421D682FD3A68A2E12EB28737DB0F785137FC01282D0D82220E2D147E4E2D261046D3C5842B55C1C2F6BA51727AF57C502242F397ACEC341F2C6C6E739E629A144602C9994C88B4F8B4F7150C087C143D9FEC23A686E5E46A5541A071869089BECC05B186FC3D8F95668A671D7088462D61423BAEB73B41CDA5B69E22D6EE3A64BB523B1522F2433BA8AD98A7500EB5C5859469F45C15E91AC1DA9D9473B3C2B37C38D038F99122E157166B89C1EA941A683A73C3F7C0762E79E9C1E28A306042D8683C26995F7AA1B5CC1B985BB0A9DEE6471E9BCEF977A2BE84BD90CE3025FA76B8B546725D85C37543B69604D3F0822DBA3067E9CF9BF2F0DC676E0D718C963C71DBD7A278BAF2A2FFA65BDB8E60FCDD0D0BA841E37284FB6174047D1EC974730A77A7E808C5F27BF1FF0818AD7B0596C538ECFF2068BD5EED5E90102918E2F224EBFFDB2C8366A5C819A00BF6DDF823BD861331F4BF2323ECA284B90C96AB6C7CDBB200163AEA8FD9EC18BA5ACAA8B8B4BDA532A04AD179D402F09E69F5CE0A179EBEF9A99E8B0C5BC8A9C3CA71C820508E33C79A98B9C31F856F53D1369AD7D9C668BC9160D6C7F3612842BDCDB42F5AE6860E93B2B203CAE26C93A7640640D403BC107DDA031CAD54DC63FFF73861D25DE26B9147C328B3940F2CFB44E82112DD6FA514CB8FD5DD6E6FF4D4EFF430B06AC970D8D75F5BD6A015558ED8D82C5121115DC3657BE88356348C0F8B8EADFD5506C0C046984BB1F12F3EEFD32FED4C8684ABD252BF3CA56092D4A752CF51E13755568C3BF25CFCA0F7AF9279CA593305C27645022DD2DD0F7FFCAC92EDEF04B9DCAE7FD55E2C69C76CF061F1ECD724850FCA574543954105B9A3824B849DDD75DEB57B382054AAB4A1FE467D235FB77C220730ED7D9B79A575831395AAE0C4C0B0D3E7EC17511C3DE9A86AD1C68BFF861FA0151020E43A1C6B4F4D6273D586B1D291AEF45DF454463F39BACA2FF07AA5E24A7EA850189F8C39BA8E88FEB21C1647EF910898B02492C49599111D3558F05A4CFD0FDBF33E802798FF2C437FCD65AAC1024FB29D08DCD7DB7E08279C3EB4B64E58747096641D1886145EC9E5ADDC8BBC81BE0DC77C3F3A017311050B921B5506F13AF30BA04AFAA210F0359E710C01319DE7BFF165A3615E8DDFC6E3FC167BA39B332B42E5207CA4934EABDAE2D057FA661DEB3EBC1A4AFD4F3E014918EC");
 
   string decoded;
-  StringSource source(imported, true, new HexDecoder(new StringSink(decoded))); // StringSource
+  BOOST_CHECK_NO_THROW(StringSource source(imported, true, new HexDecoder(new StringSink(decoded)))); // StringSource
 
   SecTpmFile tpm;
 
@@ -110,27 +117,35 @@
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == true);
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == true);
 
-  shared_ptr<PublicKey> pubkeyPtr = tpm.getPublicKeyFromTpm(keyName);
+  shared_ptr<PublicKey> pubkeyPtr;
+  BOOST_CHECK_NO_THROW(pubkeyPtr = tpm.getPublicKeyFromTpm(keyName));
 
   const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
-  Block sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256);
+  Block sigBlock;
+  BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256));
 
-  {
-    using namespace CryptoPP;
-    
-    RSA::PublicKey publicKey;
-    ByteQueue queue;
-    queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
-    publicKey.Load(queue);
+  try
+    {
+      using namespace CryptoPP;
+      
+      RSA::PublicKey publicKey;
+      ByteQueue queue;
+      queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
+      publicKey.Load(queue);
+      
+      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+      bool result = verifier.VerifyMessage(content, sizeof(content),
+					   sigBlock.value(), sigBlock.value_size());
+      
+      BOOST_CHECK_EQUAL(result, true);
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      BOOST_CHECK(false);
+    }
 
-    RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-    bool result = verifier.VerifyMessage(content, sizeof(content),
-  					 sigBlock.value(), sigBlock.value_size());
-  
-    BOOST_REQUIRE_EQUAL(result, true);
-  }
-
-  ConstBufferPtr exported = tpm.exportPrivateKeyPkcs8FromTpm(keyName, "5678");
+  ConstBufferPtr exported;
+  BOOST_CHECK_NO_THROW(exported = tpm.exportPrivateKeyPkcs8FromTpm(keyName, "5678"));
 
   tpm.deleteKeyPairInTpm(keyName);
 
@@ -143,22 +158,28 @@
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == true);
   
   const uint8_t content2[] = {0x05, 0x06, 0x07, 0x08};
-  Block sigBlock2 = tpm.signInTpm(content2, sizeof(content2), keyName, DIGEST_ALGORITHM_SHA256);
+  Block sigBlock2;
+  BOOST_CHECK_NO_THROW(sigBlock2 = tpm.signInTpm(content2, sizeof(content2), keyName, DIGEST_ALGORITHM_SHA256));
 
-  {
-    using namespace CryptoPP;
-    
-    RSA::PublicKey publicKey;
-    ByteQueue queue;
-    queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
-    publicKey.Load(queue);
+  try
+    {
+      using namespace CryptoPP;
+      
+      RSA::PublicKey publicKey;
+      ByteQueue queue;
+      queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
+      publicKey.Load(queue);
 
-    RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-    bool result = verifier.VerifyMessage(content2, sizeof(content2),
-  					 sigBlock2.value(), sigBlock2.value_size());
+      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+      bool result = verifier.VerifyMessage(content2, sizeof(content2),
+					   sigBlock2.value(), sigBlock2.value_size());
   
-    BOOST_REQUIRE_EQUAL(result, true);
-  }
+      BOOST_CHECK_EQUAL(result, true);
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      BOOST_CHECK(false);
+    }
   
   tpm.deleteKeyPairInTpm(keyName);
 
diff --git a/tests/security/test-sec-tpm-osx.cpp b/tests/security/test-sec-tpm-osx.cpp
index 7a94f33..d75eec1 100644
--- a/tests/security/test-sec-tpm-osx.cpp
+++ b/tests/security/test-sec-tpm-osx.cpp
@@ -25,7 +25,7 @@
 {
   SecTpmOsx tpm;
   
-  Name keyName("/TestSecTpmOsx/Delete/ksk-123456");
+  Name keyName("/TestSecTpmOsx/Delete/ksk-" + boost::lexical_cast<string>(time::now()));
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
   
   BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
@@ -41,29 +41,36 @@
 {
   SecTpmOsx tpm;
 
-  Name keyName("/TestSecTpmOsx/SignVerify/ksk-123456");
+  Name keyName("/TestSecTpmOsx/SignVerify/ksk-" + boost::lexical_cast<string>(time::now()));
   BOOST_CHECK_NO_THROW(tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048));
   
   Data data("/TestSecTpmOsx/SignVaerify/Data/1");
   const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
 
-  Block sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256);
-  shared_ptr<PublicKey> pubkeyPtr = tpm.getPublicKeyFromTpm(keyName);
+  Block sigBlock;
+  BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256));
 
-  {
-    using namespace CryptoPP;
-    
-    RSA::PublicKey publicKey;
-    ByteQueue queue;
-    queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
-    publicKey.Load(queue);
+  shared_ptr<PublicKey> pubkeyPtr;
+  BOOST_CHECK_NO_THROW(pubkeyPtr = tpm.getPublicKeyFromTpm(keyName));
+  try
+    {
+      using namespace CryptoPP;
 
-    RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-    bool result = verifier.VerifyMessage(content, sizeof(content),
-					 sigBlock.value(), sigBlock.value_size());
+      RSA::PublicKey publicKey;
+      ByteQueue queue;
+      queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
+      publicKey.Load(queue);
+
+      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+      bool result = verifier.VerifyMessage(content, sizeof(content),
+					   sigBlock.value(), sigBlock.value_size());
   
-    BOOST_REQUIRE_EQUAL(result, true);
-  }
+      BOOST_CHECK_EQUAL(result, true);
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      BOOST_CHECK(false);
+    }
 
   tpm.deleteKeyPairInTpm(keyName);
 }
@@ -102,8 +109,10 @@
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == true);
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC) == true);
 
-  ConstBufferPtr exported = tpm.exportPrivateKeyPkcs8FromTpm(keyName, "1234");
-  shared_ptr<PublicKey> pubkeyPtr = tpm.getPublicKeyFromTpm(keyName);
+  ConstBufferPtr exported;
+  BOOST_CHECK_NO_THROW(exported = tpm.exportPrivateKeyPkcs8FromTpm(keyName, "1234"));
+  shared_ptr<PublicKey> pubkeyPtr;
+  BOOST_REQUIRE_NO_THROW(pubkeyPtr = tpm.getPublicKeyFromTpm(keyName));
 
   tpm.deleteKeyPairInTpm(keyName);
 
@@ -116,22 +125,28 @@
   BOOST_REQUIRE(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE) == true);
 
   const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
-  Block sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256);
+  Block sigBlock;
+  BOOST_CHECK_NO_THROW(sigBlock = tpm.signInTpm(content, sizeof(content), keyName, DIGEST_ALGORITHM_SHA256));
 
-  {
-    using namespace CryptoPP;
-    
-    RSA::PublicKey publicKey;
-    ByteQueue queue;
-    queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
-    publicKey.Load(queue);
+  try
+    {
+      using namespace CryptoPP;
 
-    RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-    bool result = verifier.VerifyMessage(content, sizeof(content),
-  					 sigBlock.value(), sigBlock.value_size());
-  
-    BOOST_REQUIRE_EQUAL(result, true);
-  }
+      RSA::PublicKey publicKey;
+      ByteQueue queue;
+      queue.Put(reinterpret_cast<const byte*>(pubkeyPtr->get().buf()), pubkeyPtr->get().size());
+      publicKey.Load(queue);
+
+      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+      bool result = verifier.VerifyMessage(content, sizeof(content),
+					   sigBlock.value(), sigBlock.value_size());
+      
+      BOOST_CHECK_EQUAL(result, true);
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      BOOST_CHECK(false);
+    }
   
   tpm.deleteKeyPairInTpm(keyName);
   // This is some problem related to Mac OS Key chain, and we will fix it later.
diff --git a/tests/security/test-signed-interest.cpp b/tests/security/test-signed-interest.cpp
index 80f55a4..3adb0a4 100644
--- a/tests/security/test-signed-interest.cpp
+++ b/tests/security/test-signed-interest.cpp
@@ -21,24 +21,25 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identityName("/TestSignedInterest/SignVerify");
+  Name identityName("/TestSignedInterest/SignVerify/" + boost::lexical_cast<string>(time::now()));
   Name certificateName;
   BOOST_REQUIRE_NO_THROW(certificateName = keyChain.createIdentity(identityName));
 
   Interest interest("/TestSignedInterest/SignVerify/Interest1");
-  keyChain.signByIdentity(interest, identityName);
+  BOOST_CHECK_NO_THROW(keyChain.signByIdentity(interest, identityName));
   
   Block interestBlock(interest.wireEncode().wire(), interest.wireEncode().size());
 
   Interest interest2;
   interest2.wireDecode(interestBlock);
   
-  shared_ptr<PublicKey> publicKey = keyChain.getPublicKeyFromTpm(keyChain.getDefaultKeyNameForIdentity(identityName));
+  shared_ptr<PublicKey> publicKey;
+  BOOST_REQUIRE_NO_THROW(publicKey = keyChain.getPublicKeyFromTpm(keyChain.getDefaultKeyNameForIdentity(identityName)));
   bool result = Validator::verifySignature(interest2, *publicKey);
   
   BOOST_CHECK_EQUAL(result, true);
 
-  BOOST_CHECK_NO_THROW(keyChain.deleteIdentity(identityName));
+  keyChain.deleteIdentity(identityName);
 }
 
 class CommandInterestFixture
diff --git a/tests/security/test-validator.cpp b/tests/security/test-validator.cpp
index 48e1eec..5c4fba0 100644
--- a/tests/security/test-validator.cpp
+++ b/tests/security/test-validator.cpp
@@ -29,14 +29,14 @@
 {
   KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
 
-  Name identity(string("/TestValidator/Null/") + boost::lexical_cast<std::string>(time::now()));
-  keyChain.createIdentity(identity);
+  Name identity("/TestValidator/Null/" + boost::lexical_cast<std::string>(time::now()));
+  BOOST_REQUIRE_NO_THROW(keyChain.createIdentity(identity));
 
   Name dataName = identity;
   dataName.append("1");
   shared_ptr<Data> data = make_shared<Data>(dataName);
 
-  keyChain.signByIdentity(*data, identity);
+  BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data, identity));
   
   ValidatorNull validator;