security: Adding delete methods in KeyChain

Change-Id: I8e3bbbf6e911b43189c510c56118d291f8932df4
diff --git a/src/security/key-chain.hpp b/src/security/key-chain.hpp
index 778732b..e79b9c2 100644
--- a/src/security/key-chain.hpp
+++ b/src/security/key-chain.hpp
@@ -42,24 +42,29 @@
   /**
    * Create an identity by creating a pair of Key-Signing-Key (KSK) for this identity and a self-signed certificate of the KSK.
    * @param identityName The name of the identity.
-   * @return The key name of the auto-generated KSK of the identity.
+   * @return The name of the default certificate of the identity.
    */
   Name
   createIdentity(const Name& identityName)
   {
-    if (!Info::doesIdentityExist(identityName)) {
+    if (!Info::doesIdentityExist(identityName))
       Info::addIdentity(identityName);
-  
-      Name keyName = generateRSAKeyPairAsDefault(identityName, true);
+ 
+    Name keyName = Info::getDefaultKeyNameForIdentity(identityName);
+    
+    if(keyName.empty())
+      keyName = generateRSAKeyPairAsDefault(identityName, true);
 
-      ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
-  
-      Info::addCertificateAsIdentityDefault(*selfCert);
+    Name certName = Info::getDefaultCertificateNameForKey(keyName);
 
-      return keyName;
-    }
-    else
-      return Name();
+    if(certName.empty())
+      {
+        ptr_lib::shared_ptr<IdentityCertificate> selfCert = selfSign(keyName); 
+        Info::addCertificateAsIdentityDefault(*selfCert);
+        certName = selfCert->getName();
+      }
+
+    return certName;
   }
     
   /**
@@ -227,34 +232,6 @@
     
     interest.getName().append(signature.getValue());
   }
-
-  void
-  sign(Data &data, const IdentityCertificate& certificate)
-  {
-    SignatureSha256WithRsa signature;
-    signature.setKeyLocator(certificate.getName().getPrefix(-1));
-    data.setSignature(signature);
-
-    // For temporary usage, we support RSA + SHA256 only, but will support more.
-    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 &interestName = interest.getName();
-    interestName.append(Name::Component::fromNumber(getNow())).append(signature.getInfo());
-
-    signature.setValue(Tpm::signInTpm(interestName.wireEncode().value(), 
-                                      interestName.wireEncode().value_size(), 
-                                      certificate.getPublicKeyName(), 
-                                      DIGEST_ALGORITHM_SHA256));
-    
-    interestName.append(signature.getValue());
-  }
   
   /**
    * Sign the byte array using a certificate name and return a Signature object.
@@ -288,8 +265,8 @@
   {
     Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
 
-    if (signingCertificateName.getComponentCount() == 0)
-      throw std::runtime_error("No qualified certificate name found!");
+    if (signingCertificateName.empty())
+      signingCertificateName = createIdentity(identityName);
 
     sign(data, signingCertificateName);
   }
@@ -299,8 +276,8 @@
   {
     Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
 
-    if (signingCertificateName.getComponentCount() == 0)
-      throw std::runtime_error("No qualified certificate name found!");
+    if (signingCertificateName.empty())
+      signingCertificateName = createIdentity(identityName);
 
     sign(interest, signingCertificateName);
   }
@@ -314,12 +291,12 @@
    * @return The Signature.
    */
   Signature
-  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName = Name())
+  signByIdentity(const uint8_t* buffer, size_t bufferLength, const Name& identityName)
   {
     Name signingCertificateName = Info::getDefaultCertificateNameForIdentity(identityName);
     
-    if (signingCertificateName.size() == 0)
-      throw std::runtime_error("No qualified certificate name found!");
+    if (signingCertificateName.empty())
+      signingCertificateName = createIdentity(identityName);
 
     return sign(buffer, bufferLength, signingCertificateName);
   }
@@ -369,8 +346,73 @@
     signDataInTpm(cert, cert.getPublicKeyName(), DIGEST_ALGORITHM_SHA256);
   }
 
+  void
+  deleteCertificate (const Name &certificateName)
+  {
+    if(Info::getDefaultIdentity() == IdentityCertificate::certificateNameToPublicKeyName(certificateName).getPrefix(-1))
+      return;
+
+    Info::deleteCertificateInfo(certificateName);
+  }
+
+  void
+  deleteKey (const Name &keyName)
+  {
+    if(Info::getDefaultIdentity() == keyName.getPrefix(-1))
+      return;
+
+    Info::deletePublicKeyInfo(keyName);
+    Tpm::deleteKeyPairInTpm(keyName);
+  }
+
+  void
+  deleteIdentity (const Name &identity)
+  {
+    if(Info::getDefaultIdentity() == identity)
+      return;
+
+    std::vector<Name> nameList;
+    Info::getAllKeyNamesOfIdentity(identity, nameList, true);
+    Info::getAllKeyNamesOfIdentity(identity, nameList, false);
+    
+    Info::deleteIdentityInfo(identity);
+    
+    std::vector<Name>::const_iterator it = nameList.begin();
+    for(; it != nameList.end(); it++)
+      Tpm::deleteKeyPairInTpm(*it);
+  }
+
 
 private:
+
+  void
+  sign(Data &data, const IdentityCertificate& certificate)
+  {
+    SignatureSha256WithRsa signature;
+    signature.setKeyLocator(certificate.getName().getPrefix(-1));
+    data.setSignature(signature);
+
+    // For temporary usage, we support RSA + SHA256 only, but will support more.
+    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 &interestName = interest.getName();
+    interestName.append(Name::Component::fromNumber(getNow())).append(signature.getInfo());
+
+    signature.setValue(Tpm::signInTpm(interestName.wireEncode().value(), 
+                                      interestName.wireEncode().value_size(), 
+                                      certificate.getPublicKeyName(), 
+                                      DIGEST_ALGORITHM_SHA256));
+    
+    interestName.append(signature.getValue());
+  }
+
   /**
    * Generate a key pair for the specified identity.
    * @param identityName The name of the specified identity.
diff --git a/src/security/sec-public-info-memory.cpp b/src/security/sec-public-info-memory.cpp
index 2fc7418..c6d7316 100644
--- a/src/security/sec-public-info-memory.cpp
+++ b/src/security/sec-public-info-memory.cpp
@@ -171,35 +171,54 @@
 }
 
 
-std::vector<Name>
-SecPublicInfoMemory::getAllIdentities(bool isDefault)
+void
+SecPublicInfoMemory::getAllIdentities(std::vector<Name> &nameList, bool isDefault)
 {
   throw runtime_error("SecPublicInfoMemory::getAllIdentities not implemented");
 }
 
-std::vector<Name>
-SecPublicInfoMemory::getAllKeyNames(bool isDefault)
+void
+SecPublicInfoMemory::getAllKeyNames(std::vector<Name> &nameList, bool isDefault)
 {
   throw runtime_error("SecPublicInfoMemory::getAllKeyNames not implemented");
 }
 
-std::vector<Name>
-SecPublicInfoMemory::getAllKeyNamesOfIdentity(const Name& identity, bool isDefault)
+void
+SecPublicInfoMemory::getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name> &nameList, bool isDefault)
 {
   throw runtime_error("SecPublicInfoMemory::getAllKeyNamesOfIdentity not implemented");
 }
     
-std::vector<Name>
-SecPublicInfoMemory::getAllCertificateNames(bool isDefault)
+void
+SecPublicInfoMemory::getAllCertificateNames(std::vector<Name> &nameList, bool isDefault)
 {
   throw runtime_error("SecPublicInfoMemory::getAllCertificateNames not implemented");
 }
 
-std::vector<Name>
-SecPublicInfoMemory::getAllCertificateNamesOfKey(const Name& keyName, bool isDefault)
+void
+SecPublicInfoMemory::getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault)
 {
   throw runtime_error("SecPublicInfoMemory::getAllCertificateNamesOfKey not implemented");
 }
 
+void
+SecPublicInfoMemory::deleteCertificateInfo(const Name &certName)
+{
+  throw runtime_error("SecPublicInfoMemory::deleteCertificateInfo not implemented");
+}
+
+void
+SecPublicInfoMemory::deletePublicKeyInfo(const Name &keyName)
+{
+  throw runtime_error("SecPublicInfoMemory::deletePublicKeyInfo not implemented");
+}
+
+void
+SecPublicInfoMemory::deleteIdentityInfo(const Name &identityName)
+{
+  throw runtime_error("SecPublicInfoMemory::deleteIdentityInfo not implemented");
+}
+
+
 
 }
diff --git a/src/security/sec-public-info-memory.hpp b/src/security/sec-public-info-memory.hpp
index c991f1a..eb747e9 100644
--- a/src/security/sec-public-info-memory.hpp
+++ b/src/security/sec-public-info-memory.hpp
@@ -142,20 +142,20 @@
   virtual Name 
   getDefaultCertificateNameForKey(const Name& keyName);
 
-  virtual std::vector<Name>
-  getAllIdentities(bool isDefault);
+  virtual void
+  getAllIdentities(std::vector<Name> &nameList, bool isDefault);
 
-  virtual std::vector<Name>
-  getAllKeyNames(bool isDefault);
+  virtual void
+  getAllKeyNames(std::vector<Name> &nameList, bool isDefault);
 
-  virtual std::vector<Name>
-  getAllKeyNamesOfIdentity(const Name& identity, bool isDefault);
+  virtual void
+  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name> &nameList, bool isDefault);
     
-  virtual std::vector<Name>
-  getAllCertificateNames(bool isDefault);
+  virtual void
+  getAllCertificateNames(std::vector<Name> &nameList, bool isDefault);
 
-  virtual std::vector<Name>
-  getAllCertificateNamesOfKey(const Name& keyName, bool isDefault);
+  virtual void
+  getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault);
 
 protected:
   /**
@@ -182,6 +182,27 @@
   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:
   class KeyRecord {
diff --git a/src/security/sec-public-info-sqlite3.cpp b/src/security/sec-public-info-sqlite3.cpp
index fe96f07..7e6f4c8 100644
--- a/src/security/sec-public-info-sqlite3.cpp
+++ b/src/security/sec-public-info-sqlite3.cpp
@@ -89,14 +89,14 @@
   boost::filesystem::path identityDir = boost::filesystem::path(getenv("HOME")) / ".ndnx";
   boost::filesystem::create_directories (identityDir);
   
-  int res = sqlite3_open((identityDir / "ndnsec-public-info.db").c_str(), &database_);
+  int res = sqlite3_open((identityDir / "ndnsec-public-info.db").c_str(), &m_database);
 
   if (res != SQLITE_OK)
     throw Error("identity DB cannot be opened/created");
   
   //Check if Key table exists;
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Identity'", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT name FROM sqlite_master WHERE type='table' And name='Identity'", -1, &statement, 0);
   res = sqlite3_step(statement);
 
   bool idTableExists = false;
@@ -107,7 +107,7 @@
 
   if (!idTableExists) {
     char *errorMessage = 0;
-    res = sqlite3_exec(database_, INIT_ID_TABLE.c_str(), NULL, NULL, &errorMessage);
+    res = sqlite3_exec(m_database, INIT_ID_TABLE.c_str(), NULL, NULL, &errorMessage);
       
     if (res != SQLITE_OK && errorMessage != 0) {
       _LOG_TRACE("Init \"error\" in Identity: " << errorMessage);
@@ -116,7 +116,7 @@
   }
 
   //Check if Key table exists;
-  sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Key'", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT name FROM sqlite_master WHERE type='table' And name='Key'", -1, &statement, 0);
   res = sqlite3_step(statement);
 
   bool keyTableExists = false;
@@ -127,7 +127,7 @@
 
   if (!keyTableExists) {
     char *errorMessage = 0;
-    res = sqlite3_exec(database_, INIT_KEY_TABLE.c_str(), NULL, NULL, &errorMessage);
+    res = sqlite3_exec(m_database, INIT_KEY_TABLE.c_str(), NULL, NULL, &errorMessage);
       
     if (res != SQLITE_OK && errorMessage != 0) {
       _LOG_TRACE("Init \"error\" in KEY: " << errorMessage);
@@ -136,7 +136,7 @@
   }
 
   //Check if Certificate table exists;
-  sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'", -1, &statement, 0);
   res = sqlite3_step(statement);
 
   bool idCertificateTableExists = false;
@@ -147,7 +147,7 @@
 
   if (!idCertificateTableExists) {
     char *errorMessage = 0;
-    res = sqlite3_exec(database_, INIT_CERT_TABLE.c_str(), NULL, NULL, &errorMessage);
+    res = sqlite3_exec(m_database, INIT_CERT_TABLE.c_str(), NULL, NULL, &errorMessage);
       
     if (res != SQLITE_OK && errorMessage != 0) {
       _LOG_TRACE("Init \"error\" in ID-CERT: " << errorMessage);
@@ -166,7 +166,7 @@
   bool result = false;
   
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT count(*) FROM Identity WHERE identity_name=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT count(*) FROM Identity WHERE identity_name=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   int res = sqlite3_step(statement);
@@ -190,7 +190,7 @@
 
   sqlite3_stmt *statement;
 
-  sqlite3_prepare_v2(database_, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
       
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   
@@ -216,7 +216,7 @@
   Name identityName = keyName.getPrefix(-1);
 
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -252,7 +252,7 @@
     throw Error("a key with the same name already exists!");
 
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "INSERT 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);
@@ -276,7 +276,7 @@
   Name identityName = keyName.getPrefix(-1);
   
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -302,7 +302,7 @@
   Name identityName = keyName.getPrefix(-1);
   
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "UPDATE Key SET active=? WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
+  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);
@@ -317,7 +317,7 @@
 SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
 {
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT count(*) FROM Certificate WHERE cert_name=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT count(*) FROM Certificate WHERE cert_name=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
 
@@ -348,7 +348,7 @@
   std::string identityName = keyName.getPrefix(-1).toUri();
 
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, 
+  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);
@@ -402,7 +402,7 @@
 
   // Insert the certificate
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, 
+  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);
@@ -435,7 +435,7 @@
 {
   sqlite3_stmt *statement;
   
-  sqlite3_prepare_v2(database_, 
+  sqlite3_prepare_v2(m_database, 
                      "SELECT certificate_data FROM Certificate WHERE cert_name=?",
                      -1, &statement, 0);
   
@@ -459,7 +459,7 @@
 SecPublicInfoSqlite3::getDefaultIdentity()
 {
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &statement, 0);
 
   int res = sqlite3_step(statement);
       
@@ -479,7 +479,7 @@
   sqlite3_stmt *statement;
 
   //Reset previous default identity
-  sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=0 WHERE default_identity=1", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "UPDATE Identity SET default_identity=0 WHERE default_identity=1", -1, &statement, 0);
 
   while (sqlite3_step(statement) == SQLITE_ROW)
     {}
@@ -487,7 +487,7 @@
   sqlite3_finalize(statement);
 
   //Set current default identity
-  sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=1 WHERE identity_name=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "UPDATE Identity SET default_identity=1 WHERE identity_name=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   
@@ -500,7 +500,7 @@
 SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
 {
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
 
@@ -528,7 +528,7 @@
   sqlite3_stmt *statement;
 
   //Reset previous default Key
-  sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
 
@@ -538,7 +538,7 @@
   sqlite3_finalize(statement);
 
   //Set current default Key
-  sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -558,7 +558,7 @@
   Name identityName = keyName.getPrefix(-1);
 
   sqlite3_stmt *statement;
-  sqlite3_prepare_v2(database_, "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -588,7 +588,7 @@
   sqlite3_stmt *statement;
 
   //Reset previous default Key
-  sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -599,7 +599,7 @@
   sqlite3_finalize(statement);
 
   //Set current default Key
-  sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?", -1, &statement, 0);
+  sqlite3_prepare_v2(m_database, "UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?", -1, &statement, 0);
 
   sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
@@ -610,33 +610,30 @@
   sqlite3_finalize(statement);
 }
 
-vector<Name>
-SecPublicInfoSqlite3::getAllIdentities(bool isDefault)
+void
+SecPublicInfoSqlite3::getAllIdentities(vector<Name> &nameList, bool isDefault)
 {
   sqlite3_stmt *stmt;
   if(isDefault)
-    sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &stmt, 0);
   else
-    sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=0", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT identity_name FROM Identity WHERE default_identity=0", -1, &stmt, 0);
 
-  vector<Name> nameList;
   while(sqlite3_step (stmt) == SQLITE_ROW)
     nameList.push_back(Name(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0))));
         
   sqlite3_finalize (stmt);        
-  return nameList;
 }
 
-vector<Name>
-SecPublicInfoSqlite3::getAllKeyNames(bool isDefault)
+void
+SecPublicInfoSqlite3::getAllKeyNames(vector<Name> &nameList, bool isDefault)
 {
   sqlite3_stmt *stmt;
   if(isDefault)
-    sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=1", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT identity_name, key_identifier FROM Key WHERE default_key=1", -1, &stmt, 0);
   else
-    sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=0", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT identity_name, key_identifier FROM Key WHERE default_key=0", -1, &stmt, 0);
 
-  vector<Name> nameList;
   while(sqlite3_step (stmt) == SQLITE_ROW)
     {
       Name keyName(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
@@ -644,21 +641,19 @@
       nameList.push_back(keyName);
     } 
   sqlite3_finalize (stmt);        
-  return nameList;
 }
 
-vector<Name>
-SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity, bool isDefault)
+void
+SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity, vector<Name> &nameList, bool isDefault)
 {
   sqlite3_stmt *stmt;
   if(isDefault)
-    sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?", -1, &stmt, 0);
   else
-    sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?", -1, &stmt, 0);
     
   sqlite3_bind_text(stmt, 1, identity.toUri().c_str(),  identity.toUri().size (),  SQLITE_TRANSIENT);
 
-  vector<Name> nameList;
   while(sqlite3_step (stmt) == SQLITE_ROW)
     {
       Name keyName(identity);
@@ -666,49 +661,102 @@
       nameList.push_back(keyName);
     } 
   sqlite3_finalize (stmt);        
-  return nameList;
 }
     
-vector<Name>
-SecPublicInfoSqlite3::getAllCertificateNames(bool isDefault)
+void
+SecPublicInfoSqlite3::getAllCertificateNames(vector<Name> &nameList, bool isDefault)
 {
   sqlite3_stmt *stmt;
   if(isDefault)
-    sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT cert_name FROM Certificate WHERE default_cert=1", -1, &stmt, 0);
   else
-    sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT cert_name FROM Certificate WHERE default_cert=0", -1, &stmt, 0);
 
-  vector<Name> nameList;
   while(sqlite3_step (stmt) == SQLITE_ROW)
     nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
 
   sqlite3_finalize (stmt);        
-  return nameList;
 }
 
-vector<Name>
-SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, bool isDefault)
+void
+SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, vector<Name> &nameList, bool isDefault)
 {
   if(keyName.empty())
-    return vector<Name>();
+    return;
 
   sqlite3_stmt *stmt;
   if(isDefault)
-    sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1 and identity_name=? and key_identifier=?", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT cert_name FROM Certificate WHERE default_cert=1 and identity_name=? and key_identifier=?", -1, &stmt, 0);
   else
-    sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0 and identity_name=? and key_identifier=?", -1, &stmt, 0);
+    sqlite3_prepare_v2 (m_database, "SELECT cert_name FROM Certificate WHERE default_cert=0 and identity_name=? and key_identifier=?", -1, &stmt, 0);
 
   Name identity = keyName.getPrefix(-1);
   sqlite3_bind_text(stmt, 1, identity.toUri().c_str(),  identity.toUri().size (),  SQLITE_TRANSIENT);
   std::string baseKeyName = keyName.get(-1).toEscapedString();
   sqlite3_bind_text(stmt, 2, baseKeyName.c_str(), baseKeyName.size(), SQLITE_TRANSIENT);
 
-  vector<Name> nameList;
   while(sqlite3_step (stmt) == SQLITE_ROW)
     nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
 
   sqlite3_finalize (stmt);        
-  return nameList;
+}
+
+void
+SecPublicInfoSqlite3::deleteCertificateInfo(const Name &certName)
+{
+  if(certName.empty())
+    return;
+  
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE cert_name=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, certName.toUri().c_str(),  certName.toUri().size (),  SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize (stmt);
+}
+
+void
+SecPublicInfoSqlite3::deletePublicKeyInfo(const Name &keyName)
+{
+  if(keyName.empty())
+    return;
+
+  string identity = keyName.getPrefix(-1).toUri();
+  string keyId = keyName.get(-1).toEscapedString();
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE identity_name=? and key_identifier=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, keyId.c_str(), keyId.size(), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize (stmt);
+
+  sqlite3_prepare_v2(m_database, "DELETE FROM Key WHERE identity_name=? and key_identifier=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+  sqlite3_bind_text(stmt, 2, keyId.c_str(), keyId.size(), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize (stmt);
+}
+
+void
+SecPublicInfoSqlite3::deleteIdentityInfo(const Name &identityName)
+{
+  string identity = identityName.toUri();
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE identity_name=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize (stmt);
+
+  sqlite3_prepare_v2(m_database, "DELETE FROM Key WHERE identity_name=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize (stmt);
+
+  sqlite3_prepare_v2(m_database, "DELETE FROM Identity WHERE identity_name=?", -1, &stmt, 0);
+  sqlite3_bind_text(stmt, 1, identity.c_str(), identity.size (), SQLITE_TRANSIENT);
+  sqlite3_step(stmt);
+  sqlite3_finalize (stmt);
 }
 
 } // namespace ndn
diff --git a/src/security/sec-public-info-sqlite3.hpp b/src/security/sec-public-info-sqlite3.hpp
index f6e45c3..94dc0fa 100644
--- a/src/security/sec-public-info-sqlite3.hpp
+++ b/src/security/sec-public-info-sqlite3.hpp
@@ -154,20 +154,20 @@
   virtual Name 
   getDefaultCertificateNameForKey(const Name& keyName);
 
-  virtual std::vector<Name>
-  getAllIdentities(bool isDefault);
+  virtual void
+  getAllIdentities(std::vector<Name> &nameList, bool isDefault);
 
-  virtual std::vector<Name>
-  getAllKeyNames(bool isDefault);
+  virtual void
+  getAllKeyNames(std::vector<Name> &nameList, bool isDefault);
 
-  virtual std::vector<Name>
-  getAllKeyNamesOfIdentity(const Name& identity, bool isDefault);
+  virtual void
+  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name> &nameList, bool isDefault);
     
-  virtual std::vector<Name>
-  getAllCertificateNames(bool isDefault);
+  virtual void
+  getAllCertificateNames(std::vector<Name> &nameList, bool isDefault);
 
-  virtual std::vector<Name>
-  getAllCertificateNamesOfKey(const Name& keyName, bool isDefault);
+  virtual void
+  getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault);
   
 protected:
   /**
@@ -193,12 +193,33 @@
    */
   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 *database_;
+  sqlite3 * m_database;
 };
 
 void
diff --git a/src/security/sec-public-info.hpp b/src/security/sec-public-info.hpp
index 7cd7230..37afd5d 100644
--- a/src/security/sec-public-info.hpp
+++ b/src/security/sec-public-info.hpp
@@ -145,20 +145,20 @@
   virtual Name 
   getDefaultCertificateNameForKey(const Name& keyName) = 0;
 
-  virtual std::vector<Name>
-  getAllIdentities(bool isDefault) = 0;
+  virtual void
+  getAllIdentities(std::vector<Name> &nameList, bool isDefault) = 0;
 
-  virtual std::vector<Name>
-  getAllKeyNames(bool isDefault) = 0;
+  virtual void
+  getAllKeyNames(std::vector<Name> &nameList, bool isDefault) = 0;
 
-  virtual std::vector<Name>
-  getAllKeyNamesOfIdentity(const Name& identity, bool isDefault) = 0;
+  virtual void
+  getAllKeyNamesOfIdentity(const Name& identity, std::vector<Name> &nameList, bool isDefault) = 0;
     
-  virtual std::vector<Name>
-  getAllCertificateNames(bool isDefault) = 0;
+  virtual void
+  getAllCertificateNames(std::vector<Name> &nameList, bool isDefault) = 0;
     
-  virtual std::vector<Name>
-  getAllCertificateNamesOfKey(const Name& keyName, bool isDefault) = 0;
+  virtual void
+  getAllCertificateNamesOfKey(const Name& keyName, std::vector<Name> &nameList, bool isDefault) = 0;
 
 protected:
 
@@ -188,6 +188,31 @@
   virtual void 
   setDefaultCertificateNameForKeyInternal(const Name& certificateName) = 0; 
 
+  /*****************************************
+   *            Delete Methods             *
+   *****************************************/
+
+  /**
+   * Delete a certificate.
+   * @param certificateName The certificate name.
+   */
+  virtual void
+  deleteCertificateInfo(const Name &certificateName) = 0;
+
+  /**
+   * 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.
+   * @param identity The identity name.
+   */
+  virtual void
+  deleteIdentityInfo(const Name &identity) = 0;
+
 public:
   
   /*****************************************
@@ -306,12 +331,12 @@
   else
     oss << "dsk-";
 
-  oss << static_cast<int>(getNow()/1000);  
+  oss << static_cast<int>(getNow());  
 
   Name keyName = Name(identityName).append(oss.str());
 
   if (doesPublicKeyExist(keyName))
-    throw Error("Key name already exists");
+    throw Error("Key name already exists: " + keyName.toUri());
 
   return keyName;
 }
@@ -374,7 +399,6 @@
     defaultCertificate_ = getCertificate(certName);
 }
 
-
 }
 
 #endif
diff --git a/src/security/sec-tpm-file.cpp b/src/security/sec-tpm-file.cpp
index 56f42f8..c8dab80 100644
--- a/src/security/sec-tpm-file.cpp
+++ b/src/security/sec-tpm-file.cpp
@@ -102,6 +102,19 @@
   }
 }
 
+void
+SecTpmFile::deleteKeyPairInTpm(const Name &keyName)
+{
+  boost::filesystem::path publicKeyPath(nameTransform(keyName.toUri(), ".pub"));
+  boost::filesystem::path privateKeyPath(nameTransform(keyName.toUri(), ".pri"));
+
+  if(boost::filesystem::exists(publicKeyPath))
+    boost::filesystem::remove(publicKeyPath);
+
+  if(boost::filesystem::exists(privateKeyPath))
+    boost::filesystem::remove(privateKeyPath);
+}
+
 ptr_lib::shared_ptr<PublicKey>
 SecTpmFile::getPublicKeyFromTpm(const Name & keyName)
 {
diff --git a/src/security/sec-tpm-file.hpp b/src/security/sec-tpm-file.hpp
index 8ef5586..d0a68b8 100644
--- a/src/security/sec-tpm-file.hpp
+++ b/src/security/sec-tpm-file.hpp
@@ -39,6 +39,13 @@
   generateKeyPairInTpm(const Name & keyName, KeyType keyType, int keySize);
 
   /**
+   * Delete a key pair of asymmetric keys.
+   * @param keyName The name of the key pair.
+   */
+  virtual void
+  deleteKeyPairInTpm(const Name &keyName);
+
+  /**
    * Get the public key
    * @param keyName The name of public key.
    * @return The public key.
diff --git a/src/security/sec-tpm-memory.cpp b/src/security/sec-tpm-memory.cpp
index 71b1f62..d4de6fc 100644
--- a/src/security/sec-tpm-memory.cpp
+++ b/src/security/sec-tpm-memory.cpp
@@ -62,10 +62,16 @@
 SecTpmMemory::generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
 {
 #if 1
-  throw Error("MemoryPrivateKeyStorage::generateKeyPair not implemented");
+  throw Error("SecTpmMemory::generateKeyPair not implemented");
 #endif
 }
 
+void
+SecTpmMemory::deleteKeyPairInTpm(const Name &keyName)
+{
+  throw Error("SecTpmMemory::deleteKeyPairInTpm not implemented");
+}
+
 ptr_lib::shared_ptr<PublicKey> 
 SecTpmMemory::getPublicKeyFromTpm(const Name& keyName)
 {
diff --git a/src/security/sec-tpm-memory.hpp b/src/security/sec-tpm-memory.hpp
index 21dc272..110442e 100644
--- a/src/security/sec-tpm-memory.hpp
+++ b/src/security/sec-tpm-memory.hpp
@@ -57,6 +57,13 @@
    */
   virtual ptr_lib::shared_ptr<PublicKey> 
   getPublicKeyFromTpm(const Name& keyName);
+
+  /**
+   * Delete a key pair of asymmetric keys.
+   * @param keyName The name of the key pair.
+   */
+  virtual void
+  deleteKeyPairInTpm(const Name &keyName);
   
   /**
    * Fetch the private key for keyName and sign the data, returning a signature Blob.
diff --git a/src/security/sec-tpm-osx.cpp b/src/security/sec-tpm-osx.cpp
index fed73e1..25b42df 100644
--- a/src/security/sec-tpm-osx.cpp
+++ b/src/security/sec-tpm-osx.cpp
@@ -168,6 +168,30 @@
     }
   }
 
+  void
+  SecTpmOsx::deleteKeyPairInTpm(const Name &keyName)
+  {
+    string keyNameUri = keyName.toUri();
+
+    CFStringRef keyLabel = CFStringCreateWithCString(NULL, 
+                                                     keyNameUri.c_str(), 
+                                                     kCFStringEncodingUTF8);
+    
+    CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL,
+                                                             5,
+                                                             &kCFTypeDictionaryKeyCallBacks,
+                                                             NULL);
+
+    CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
+    CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
+    CFDictionaryAddValue(attrDict, kSecMatchLimit, kSecMatchLimitAll);
+
+    OSStatus res = SecItemDelete((CFDictionaryRef) attrDict);
+    
+    if(res != errSecSuccess)
+      _LOG_DEBUG("Fail to find the key!");
+  }
+
   void 
   SecTpmOsx::generateSymmetricKeyInTpm(const Name & keyName, KeyType keyType, int keySize)
   {
@@ -465,10 +489,11 @@
                                                      kCFStringEncodingUTF8);
     
     CFMutableDictionaryRef attrDict = CFDictionaryCreateMutable(NULL,
-                                                                3,
+                                                                4,
                                                                 &kCFTypeDictionaryKeyCallBacks,
                                                                 NULL);
 
+    CFDictionaryAddValue(attrDict, kSecClass, kSecClassKey);
     CFDictionaryAddValue(attrDict, kSecAttrKeyClass, impl_->getKeyClass(keyClass));
     CFDictionaryAddValue(attrDict, kSecAttrLabel, keyLabel);
     CFDictionaryAddValue(attrDict, kSecReturnRef, kCFBooleanTrue);
@@ -477,9 +502,9 @@
     OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict, (CFTypeRef*)&itemRef);
     
     if(res == errSecItemNotFound)
-      return true;
-    else
       return false;
+    else
+      return true;
 
   }
 
diff --git a/src/security/sec-tpm-osx.hpp b/src/security/sec-tpm-osx.hpp
index c724ca7..915bb1d 100644
--- a/src/security/sec-tpm-osx.hpp
+++ b/src/security/sec-tpm-osx.hpp
@@ -35,6 +35,13 @@
   virtual void 
   generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize);
 
+  /**
+   * Delete a key pair of asymmetric keys.
+   * @param keyName The name of the key pair.
+   */
+  virtual void
+  deleteKeyPairInTpm(const Name &keyName);
+
   virtual ptr_lib::shared_ptr<PublicKey> 
   getPublicKeyFromTpm(const Name& keyName);
   
diff --git a/src/security/sec-tpm.hpp b/src/security/sec-tpm.hpp
index dd9a55e..3336a32 100644
--- a/src/security/sec-tpm.hpp
+++ b/src/security/sec-tpm.hpp
@@ -35,6 +35,13 @@
    */
   virtual void 
   generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize) = 0;
+  
+  /**
+   * Delete a key pair of asymmetric keys.
+   * @param keyName The name of the key pair.
+   */
+  virtual void
+  deleteKeyPairInTpm(const Name &keyName) = 0;
 
   /**
    * Get the public key
diff --git a/tests/test-sec-public-info-sqlite3.cpp b/tests/test-sec-public-info-sqlite3.cpp
new file mode 100644
index 0000000..233109c
--- /dev/null
+++ b/tests/test-sec-public-info-sqlite3.cpp
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi0@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#if __clang__
+#pragma clang diagnostic ignored "-Wtautological-compare"
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "security/key-chain.hpp"
+
+using namespace std;
+using namespace ndn;
+
+
+BOOST_AUTO_TEST_SUITE(TestSecPublicInfoSqlite3)
+
+BOOST_AUTO_TEST_CASE (Delete)
+{
+  KeyChainImpl<SecPublicInfoSqlite3, SecTpmFile> keyChain;
+
+  Name identity("/tmp");
+  Name certName1 = keyChain.createIdentity(identity);
+  Name keyName1 = IdentityCertificate::certificateNameToPublicKeyName(certName1);  
+  Name keyName2 = keyChain.generateRSAKeyPairAsDefault(identity);
+  ptr_lib::shared_ptr<IdentityCertificate> cert2 = keyChain.selfSign(keyName2);
+  Name certName2 = cert2->getName();
+  keyChain.addCertificateAsKeyDefault(*cert2);
+  Name keyName3 = keyChain.generateRSAKeyPairAsDefault(identity);
+  ptr_lib::shared_ptr<IdentityCertificate> cert3 = keyChain.selfSign(keyName3);
+  Name certName3 = cert3->getName();
+  keyChain.addCertificateAsKeyDefault(*cert3);
+  ptr_lib::shared_ptr<IdentityCertificate> cert4 = keyChain.selfSign(keyName3);
+  Name certName4 = cert4->getName();
+  keyChain.addCertificateAsKeyDefault(*cert4);
+  ptr_lib::shared_ptr<IdentityCertificate> cert5 = keyChain.selfSign(keyName3);
+  Name certName5 = cert5->getName();
+  keyChain.addCertificateAsKeyDefault(*cert5);
+
+  BOOST_REQUIRE_EQUAL(keyChain.doesIdentityExist(identity), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesPublicKeyExist(keyName1), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesPublicKeyExist(keyName2), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesPublicKeyExist(keyName3), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName1), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName2), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName3), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName4), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName5), true);
+
+  keyChain.deleteCertificate(certName5);
+  BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName5), false);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName3), true);
+  BOOST_REQUIRE_EQUAL(keyChain.doesCertificateExist(certName4), true);
+  BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName3), true);
+
+  keyChain.deleteKey(keyName3);
+  BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName4), false);
+  BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName3), false);
+  BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName3), false);
+  BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName2), true);
+  BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName1), true);
+  BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), true);
+
+  keyChain.deleteIdentity(identity);
+  BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName2), false);
+  BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName2), false);
+  BOOST_CHECK_EQUAL(keyChain.doesCertificateExist(certName1), false);
+  BOOST_CHECK_EQUAL(keyChain.doesPublicKeyExist(keyName1), false);
+  BOOST_CHECK_EQUAL(keyChain.doesIdentityExist(identity), false);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/test-sec-tpm-file.cpp b/tests/test-sec-tpm-file.cpp
index 5facdf4..fd27ae8 100644
--- a/tests/test-sec-tpm-file.cpp
+++ b/tests/test-sec-tpm-file.cpp
@@ -6,14 +6,6 @@
 
 #if __clang__
 #pragma clang diagnostic ignored "-Wtautological-compare"
-// #pragma clang diagnostic push
-// #pragma clang diagnostic ignored "-Wreorder"
-// #pragma clang diagnostic ignored "-Wunused-variable"
-// #pragma clang diagnostic ignored "-Wunused-function"
-// #elif __GNUC__
-// #pragma GCC diagnostic ignored "-Wreorder"
-// #pragma GCC diagnostic ignored "-Wunused-variable"
-// #pragma GCC diagnostic ignored "-Wunused-function"
 #endif
 
 #include <boost/test/unit_test.hpp>
@@ -27,16 +19,28 @@
 
 BOOST_AUTO_TEST_SUITE(TestSecTpmFile)
 
+BOOST_AUTO_TEST_CASE (Delete)
+{
+  SecTpmFile tpm;
+  
+  Name keyName("/tmp/ksk-123456");
+  tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048);
+  
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), true);
+  
+  tpm.deleteKeyPairInTpm(keyName);
+  
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
+}
+
 BOOST_AUTO_TEST_CASE (SignVerify)
 {
   SecTpmFile tpm;
 
   Name keyName("/tmp/ksk-123456");
-  try {
-    tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048);
-  }
-  catch(const SecTpm::Error&) {
-  }
+  tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048);
   
   Data data("/tmp/test/1");
   const uint8_t content[] = {0x01, 0x02, 0x03, 0x04};
@@ -59,7 +63,7 @@
     BOOST_REQUIRE_EQUAL(result, true);
   }
 
-  //We should remove the temporary test key, this should be fixed in a later commit which will add delete operation in SecTpm.
+  tpm.deleteKeyPairInTpm(keyName);
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/test-sec-tpm-osx.cpp b/tests/test-sec-tpm-osx.cpp
new file mode 100644
index 0000000..8c57dc0
--- /dev/null
+++ b/tests/test-sec-tpm-osx.cpp
@@ -0,0 +1,69 @@
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi0@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#if __clang__
+#pragma clang diagnostic ignored "-Wtautological-compare"
+#endif
+
+#include <boost/test/unit_test.hpp>
+
+#include "security/key-chain.hpp"
+#include <cryptopp/rsa.h>
+
+using namespace std;
+using namespace ndn;
+
+
+BOOST_AUTO_TEST_SUITE(TestSecTpmOsx)
+
+BOOST_AUTO_TEST_CASE (Delete)
+{
+  SecTpmOsx tpm;
+  
+  Name keyName("/tmp/ksk-123456");
+  tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048);
+  
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), true);
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), true);
+  
+  tpm.deleteKeyPairInTpm(keyName);
+  
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PUBLIC), false);
+  BOOST_REQUIRE_EQUAL(tpm.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE), false);
+}
+
+BOOST_AUTO_TEST_CASE (SignVerify)
+{
+  SecTpmOsx tpm;
+
+  Name keyName("/tmp/ksk-123456");
+  tpm.generateKeyPairInTpm(keyName, KEY_TYPE_RSA, 2048);
+  
+  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);
+
+  {
+    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);
+  }
+
+  tpm.deleteKeyPairInTpm(keyName);
+}
+
+BOOST_AUTO_TEST_SUITE_END()