Update validation related codes to security v2

Change-Id: I5467b87092820666c04f22623f0f1665ce9a1194
diff --git a/src/daemon/db-mgr.cpp b/src/daemon/db-mgr.cpp
index 8f5fcb3..b925f2d 100644
--- a/src/daemon/db-mgr.cpp
+++ b/src/daemon/db-mgr.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014, Regents of the University of California.
+/*
+ * Copyright (c) 2014-2017, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
  * See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -29,25 +29,32 @@
 
 NDNS_LOG_INIT("DbMgr")
 
-static const std::string NDNS_SCHEMA = "\
-CREATE TABLE IF NOT EXISTS zones (      \n\
-  id    INTEGER NOT NULL PRIMARY KEY,   \n\
-  name  blob NOT NULL UNIQUE,           \n\
-  ttl   integer(10) NOT NULL);          \n\
-                                        \n\
-CREATE TABLE IF NOT EXISTS rrsets (     \n\
-  id      INTEGER NOT NULL PRIMARY KEY, \n\
-  zone_id integer(10) NOT NULL,         \n\
-  label   blob NOT NULL,                \n\
-  type    blob NOT NULL,                \n\
-  version blob NOT NULL,                \n\
-  ttl     integer(10) NOT NULL,         \n\
-  data    blob NOT NULL,                                                \n\
-  FOREIGN KEY(zone_id) REFERENCES zones(id) ON UPDATE Cascade ON DELETE Cascade); \n\
-                                                                        \n\
-CREATE UNIQUE INDEX rrsets_zone_id_label_type_version                   \n\
-  ON rrsets (zone_id, label, type, version);                            \n\
-";
+static const std::string NDNS_SCHEMA = R"VALUE(
+CREATE TABLE IF NOT EXISTS zones (
+  id    INTEGER NOT NULL PRIMARY KEY,
+  name  blob NOT NULL UNIQUE,
+  ttl   integer(10) NOT NULL);
+
+CREATE TABLE IF NOT EXISTS zone_info (
+  zone_id  INTEGER NOT NULL,
+  key      VARCHAR(10) NOT NULL,
+  value    blob NOT NULL,
+  PRIMARY KEY (zone_id, key),
+  FOREIGN KEY(zone_id) REFERENCES zones(id) ON UPDATE Cascade ON DELETE Cascade);
+
+CREATE TABLE IF NOT EXISTS rrsets (
+  id      INTEGER NOT NULL PRIMARY KEY,
+  zone_id integer(10) NOT NULL,
+  label   blob NOT NULL,
+  type    blob NOT NULL,
+  version blob NOT NULL,
+  ttl     integer(10) NOT NULL,
+  data    blob NOT NULL,
+  FOREIGN KEY(zone_id) REFERENCES zones(id) ON UPDATE Cascade ON DELETE Cascade);
+
+CREATE UNIQUE INDEX rrsets_zone_id_label_type_version
+  ON rrsets (zone_id, label, type, version);
+)VALUE";
 
 DbMgr::DbMgr(const std::string& dbFile/* = DEFAULT_CONFIG_PATH "/" "ndns.db"*/)
   : m_dbFile(dbFile)
@@ -83,7 +90,7 @@
 
   if (res != SQLITE_OK) {
     NDNS_LOG_FATAL("Cannot open the db file: " << m_dbFile);
-    throw ConnectError("Cannot open the db file: " + m_dbFile);
+    BOOST_THROW_EXCEPTION(ConnectError("Cannot open the db file: " + m_dbFile));
   }
   // ignore any errors from DB creation (command will fail for the existing database, which is ok)
   sqlite3_exec(m_conn, NDNS_SCHEMA.c_str(), 0, 0, 0);
@@ -112,7 +119,7 @@
 
   int rc = sqlite3_exec(m_conn, sql, 0, 0, 0); // sqlite3_step cannot execute multiple SQL statement
   if (rc != SQLITE_OK) {
-    throw ExecuteError(sql);
+    BOOST_THROW_EXCEPTION(ExecuteError(sql));
   }
 
   NDNS_LOG_INFO("clear all the data in the database: " << m_dbFile);
@@ -132,7 +139,7 @@
   const char* sql = "INSERT INTO zones (name, ttl) VALUES (?, ?)";
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   const Block& zoneName = zone.getName().wireEncode();
@@ -142,13 +149,80 @@
   rc = sqlite3_step(stmt);
   if (rc != SQLITE_DONE) {
     sqlite3_finalize(stmt);
-    throw ExecuteError(sql);
+    BOOST_THROW_EXCEPTION(ExecuteError(sql));
   }
 
   zone.setId(sqlite3_last_insert_rowid(m_conn));
   sqlite3_finalize(stmt);
 }
 
+void
+DbMgr::setZoneInfo(Zone& zone,
+                   const std::string& key,
+                   const Block& value)
+{
+  if (zone.getId() == 0) {
+    BOOST_THROW_EXCEPTION(Error("zone has not been initialized"));
+  }
+
+  if (key.length() > 10) {
+    BOOST_THROW_EXCEPTION(Error("key length should not exceed 10"));
+  }
+
+  sqlite3_stmt* stmt;
+  const char* sql = "INSERT OR REPLACE INTO zone_info (zone_id, key, value) VALUES (?, ?, ?)";
+  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
+  if (rc != SQLITE_OK) {
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
+  }
+
+  sqlite3_bind_int(stmt,  1, zone.getId());
+  sqlite3_bind_text(stmt, 2, key.c_str(),  key.length(), SQLITE_STATIC);
+  sqlite3_bind_blob(stmt, 3, value.wire(), value.size(), SQLITE_STATIC);
+
+  rc = sqlite3_step(stmt);
+  if (rc != SQLITE_DONE) {
+    sqlite3_finalize(stmt);
+    BOOST_THROW_EXCEPTION(ExecuteError(sql));
+  }
+
+  sqlite3_finalize(stmt);
+}
+
+std::map<std::string, Block>
+DbMgr::getZoneInfo(Zone& zone)
+{
+  using std::string;
+  std::map<string, Block> rtn;
+
+  if (zone.getId() == 0) {
+    find(zone);
+  }
+
+  if (zone.getId() == 0) {
+    BOOST_THROW_EXCEPTION(Error("zone has not been initialized"));
+  }
+
+  sqlite3_stmt* stmt;
+  const char* sql = "SELECT key, value FROM zone_info WHERE zone_id=?";
+  int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
+  if (rc != SQLITE_OK) {
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
+  }
+
+  sqlite3_bind_int(stmt, 1, zone.getId());
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    const char* key = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0));
+    rtn[string(key)] = Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 1)),
+                             sqlite3_column_bytes(stmt, 1));
+  }
+
+  sqlite3_finalize(stmt);
+  return rtn;
+}
+
+
 bool
 DbMgr::find(Zone& zone)
 {
@@ -156,7 +230,7 @@
   const char* sql = "SELECT id, ttl FROM zones WHERE name=?";
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   const Block& zoneName = zone.getName().wireEncode();
@@ -165,7 +239,8 @@
   if (sqlite3_step(stmt) == SQLITE_ROW) {
     zone.setId(sqlite3_column_int64(stmt, 0));
     zone.setTtl(time::seconds(sqlite3_column_int(stmt, 1)));
-  } else {
+  }
+  else {
     zone.setId(0);
   }
 
@@ -181,7 +256,7 @@
   const char* sql = "SELECT id, name, ttl FROM zones";
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   std::vector<Zone> vec;
@@ -209,7 +284,7 @@
   const char* sql = "DELETE FROM zones where id=?";
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   sqlite3_bind_int64(stmt, 1, zone.getId());
@@ -217,7 +292,7 @@
   rc = sqlite3_step(stmt);
   if (rc != SQLITE_DONE) {
     sqlite3_finalize(stmt);
-    throw ExecuteError(sql);
+    BOOST_THROW_EXCEPTION(ExecuteError(sql));
   }
 
   sqlite3_finalize(stmt);
@@ -237,7 +312,7 @@
     return;
 
   if (rrset.getZone() == 0) {
-    throw RrsetError("Rrset has not been assigned to a zone");
+    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
   }
 
   if (rrset.getZone()->getId() == 0) {
@@ -251,7 +326,7 @@
   sqlite3_stmt* stmt;
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   sqlite3_bind_int64(stmt, 1, rrset.getZone()->getId());
@@ -266,7 +341,7 @@
   rc = sqlite3_step(stmt);
   if (rc != SQLITE_DONE) {
     sqlite3_finalize(stmt);
-    throw ExecuteError(sql);
+    BOOST_THROW_EXCEPTION(ExecuteError(sql));
   }
 
   rrset.setId(sqlite3_last_insert_rowid(m_conn));
@@ -277,7 +352,7 @@
 DbMgr::find(Rrset& rrset)
 {
   if (rrset.getZone() == 0) {
-    throw RrsetError("Rrset has not been assigned to a zone");
+    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
   }
 
   if (rrset.getZone()->getId() == 0) {
@@ -294,7 +369,7 @@
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
 
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   sqlite3_bind_int64(stmt, 1, rrset.getZone()->getId());
@@ -310,7 +385,8 @@
                            sqlite3_column_bytes(stmt, 2)));
     rrset.setData(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 3)),
                         sqlite3_column_bytes(stmt, 3)));
-  } else {
+  }
+  else {
     rrset.setId(0);
   }
   sqlite3_finalize(stmt);
@@ -325,7 +401,7 @@
     find(zone);
 
   if (zone.getId() == 0)
-    throw RrsetError("Attempting to find all the rrsets with a zone does not in the database");
+    BOOST_THROW_EXCEPTION(RrsetError("Attempting to find all the rrsets with a zone does not in the database"));
 
   std::vector<Rrset> vec;
   sqlite3_stmt* stmt;
@@ -334,7 +410,7 @@
 
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
   sqlite3_bind_int64(stmt, 1, zone.getId());
 
@@ -363,14 +439,14 @@
 DbMgr::remove(Rrset& rrset)
 {
   if (rrset.getId() == 0)
-    throw RrsetError("Attempting to remove Rrset that has no assigned id");
+    BOOST_THROW_EXCEPTION(RrsetError("Attempting to remove Rrset that has no assigned id"));
 
   sqlite3_stmt* stmt;
   const char* sql = "DELETE FROM rrsets WHERE id=?";
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
 
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   sqlite3_bind_int64(stmt, 1, rrset.getId());
@@ -378,7 +454,7 @@
   rc = sqlite3_step(stmt);
   if (rc != SQLITE_DONE) {
     sqlite3_finalize(stmt);
-    throw ExecuteError(sql);
+    BOOST_THROW_EXCEPTION(ExecuteError(sql));
   }
 
   sqlite3_finalize(stmt);
@@ -390,11 +466,11 @@
 DbMgr::update(Rrset& rrset)
 {
   if (rrset.getId() == 0) {
-    throw RrsetError("Attempting to replace Rrset that has no assigned id");
+    BOOST_THROW_EXCEPTION(RrsetError("Attempting to replace Rrset that has no assigned id"));
   }
 
   if (rrset.getZone() == 0) {
-    throw RrsetError("Rrset has not been assigned to a zone");
+    BOOST_THROW_EXCEPTION(RrsetError("Rrset has not been assigned to a zone"));
   }
 
   sqlite3_stmt* stmt;
@@ -402,7 +478,7 @@
   int rc = sqlite3_prepare_v2(m_conn, sql, -1, &stmt, 0);
 
   if (rc != SQLITE_OK) {
-    throw PrepareError(sql);
+    BOOST_THROW_EXCEPTION(PrepareError(sql));
   }
 
   sqlite3_bind_int64(stmt, 1, rrset.getTtl().count());
diff --git a/src/daemon/db-mgr.hpp b/src/daemon/db-mgr.hpp
index 5c4e179..9e79223 100644
--- a/src/daemon/db-mgr.hpp
+++ b/src/daemon/db-mgr.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014, Regents of the University of California.
+/*
+ * Copyright (c) 2014-2017, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
  * See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -33,7 +33,7 @@
 #define DEFINE_ERROR(ErrorName, Base)           \
 class ErrorName : public Base                   \
 {                                               \
- public:                                        \
+public:                                         \
   explicit                                      \
   ErrorName(const std::string& what)            \
     : Base(what)                                \
@@ -105,6 +105,20 @@
   insert(Zone& zone);
 
   /**
+   * @brief set zoneInfo by key-value
+   */
+  void
+  setZoneInfo(Zone& zone,
+              const std::string& key,
+              const Block& value);
+
+  /**
+   * @brief get zoneInfo
+   */
+  std::map<std::string, Block>
+  getZoneInfo(Zone& zone);
+
+  /**
    * @brief lookup the zone by name, fill the m_id and m_ttl
    * @post whatever the previous id is
    * @return true if the record exist
diff --git a/src/daemon/name-server.cpp b/src/daemon/name-server.cpp
index 70288ec..11ad3a8 100644
--- a/src/daemon/name-server.cpp
+++ b/src/daemon/name-server.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+/*
+ * Copyright (c) 2014-2017, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
  * See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -20,6 +20,7 @@
 #include "name-server.hpp"
 #include "logger.hpp"
 #include <ndn-cxx/encoding/encoding-buffer.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
 
 namespace ndn {
 namespace ndns {
@@ -28,44 +29,32 @@
 const time::milliseconds NAME_SERVER_DEFAULT_CONTENT_FRESHNESS(4000);
 
 NameServer::NameServer(const Name& zoneName, const Name& certName, Face& face, DbMgr& dbMgr,
-                       KeyChain& keyChain, Validator& validator)
+                       KeyChain& keyChain, security::v2::Validator& validator)
   : m_zone(zoneName)
   , m_dbMgr(dbMgr)
   , m_ndnsPrefix(zoneName)
-  , m_keyPrefix(zoneName)
   , m_certName(certName)
   , m_contentFreshness(NAME_SERVER_DEFAULT_CONTENT_FRESHNESS)
   , m_face(face)
   , m_keyChain(keyChain)
   , m_validator(validator)
 {
-  if (!m_keyChain.doesCertificateExist(m_certName)) {
-    NDNS_LOG_FATAL("Certificate: " << m_certName << " does not exist");
-    throw Error("certificate does not exist in the KeyChain: " + m_certName.toUri());
-  }
-
   m_dbMgr.find(m_zone);
 
   if (m_zone.getId() == 0) {
     NDNS_LOG_FATAL("m_zone does not exist: " << zoneName);
-    throw Error("Zone " + zoneName.toUri() + " does not exist in the database");
+    BOOST_THROW_EXCEPTION(Error("Zone " + zoneName.toUri() + " does not exist in the database"));
   }
 
   m_ndnsPrefix.append(ndns::label::NDNS_ITERATIVE_QUERY);
-  m_keyPrefix.append(ndns::label::NDNS_CERT_QUERY);
 
   m_face.setInterestFilter(m_ndnsPrefix,
                            bind(&NameServer::onInterest, this, _1, _2),
                            bind(&NameServer::onRegisterFailed, this, _1, _2)
                            );
 
-  m_face.setInterestFilter(m_keyPrefix,
-                           bind(&NameServer::onInterest, this, _1, _2),
-                           bind(&NameServer::onRegisterFailed, this, _1, _2)
-                           );
-
   NDNS_LOG_INFO("Zone: " << m_zone.getName() << " binds "
-                << "Prefix: " << m_ndnsPrefix << " and " << m_keyPrefix
+                << "Prefix: " << m_ndnsPrefix
                 << " with Certificate: " << m_certName
                 );
 }
@@ -109,7 +98,7 @@
     answer->setFreshnessPeriod(this->getContentFreshness());
     answer->setContentType(NDNS_NACK);
 
-    m_keyChain.sign(*answer, m_certName);
+    m_keyChain.sign(*answer, signingByCertificate(m_certName));
     NDNS_LOG_TRACE("answer query with NDNS-NACK: " << answer->getName());
     m_face.put(*answer);
   }
@@ -127,13 +116,13 @@
       const Block& block = it->blockFromValue();
       data = make_shared<Data>(block);
     }
-    catch (std::exception& e) {
+    catch (const std::exception& e) {
       NDNS_LOG_WARN("exception when getting update info: " << e.what());
       return;
     }
     m_validator.validate(*data,
                          bind(&NameServer::doUpdate, this, interest.shared_from_this(), data),
-                         [this] (const shared_ptr<const Data>& data, const std::string& msg) {
+                         [this] (const Data& data, const security::v2::ValidationError& msg) {
                            NDNS_LOG_WARN("Ignoring update that did not pass the verification. "
                                          << "Check the root certificate")
                          });
@@ -144,8 +133,8 @@
 NameServer::onRegisterFailed(const ndn::Name& prefix, const std::string& reason)
 {
   NDNS_LOG_FATAL("fail to register prefix=" << prefix << ". Due to: " << reason);
-  throw Error("zone " + m_zone.getName().toUri() + " register prefix: " +
-              prefix.toUri() + " fails. due to: " + reason);
+  BOOST_THROW_EXCEPTION(Error("zone " + m_zone.getName().toUri() + " register prefix: " +
+                              prefix.toUri() + " fails. due to: " + reason));
 }
 
 void
@@ -157,7 +146,7 @@
     if (!label::matchName(*data, m_zone.getName(), re))
       return;
   }
-  catch (std::exception& e) {
+  catch (const std::exception& e) {
     NDNS_LOG_INFO("Error while name/certificate matching: " << e.what());
   }
 
@@ -204,7 +193,7 @@
       NDNS_LOG_TRACE("insert new record and answer update with UPDATE_OK");
     }
   }
-  catch (std::exception& e) {
+  catch (const std::exception& e) {
     blk.push_back(makeNonNegativeIntegerBlock(ndn::ndns::tlv::UpdateReturnCode, UPDATE_FAILURE));
     blk.encode(); // must
     answer->setContent(blk);
@@ -212,7 +201,7 @@
                   << ". Update may need sudo privilege to write DbFile");
     NDNS_LOG_TRACE("exception happens and answer update with UPDATE_FAILURE");
   }
-  m_keyChain.sign(*answer, m_certName);
+  m_keyChain.sign(*answer, signingByCertificate(m_certName));
   m_face.put(*answer);
 }
 
diff --git a/src/daemon/name-server.hpp b/src/daemon/name-server.hpp
index aa75ade..d62cf79 100644
--- a/src/daemon/name-server.hpp
+++ b/src/daemon/name-server.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016, Regents of the University of California.
+/*
+ * Copyright (c) 2014-2017, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
  * See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -53,11 +53,11 @@
 public:
   explicit
   NameServer(const Name& zoneName, const Name& certName, Face& face, DbMgr& dbMgr,
-             KeyChain& keyChain, Validator& validator);
+             KeyChain& keyChain, security::v2::Validator& validator);
 
 NDNS_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   void
-  onInterest(const Name& prefix, const Interest &interest);
+  onInterest(const Name& prefix, const Interest& interest);
 
   /**
    * @brief handle NDNS query message
@@ -84,18 +84,6 @@
     return m_ndnsPrefix;
   }
 
-  const Name&
-  getKeyPrefix() const
-  {
-    return m_keyPrefix;
-  }
-
-  void
-  setKeyPrefix(const Name& keyPrefix)
-  {
-    m_keyPrefix = keyPrefix;
-  }
-
   const Zone&
   getZone() const
   {
@@ -123,14 +111,13 @@
   DbMgr& m_dbMgr;
 
   Name m_ndnsPrefix;
-  Name m_keyPrefix;
   Name m_certName;
 
   time::milliseconds m_contentFreshness;
 
   Face& m_face;
   KeyChain& m_keyChain;
-  Validator& m_validator;
+  security::v2::Validator& m_validator;
 };
 
 } // namespace ndns
diff --git a/src/daemon/rrset-factory.cpp b/src/daemon/rrset-factory.cpp
index 9757abc..da7ffde 100644
--- a/src/daemon/rrset-factory.cpp
+++ b/src/daemon/rrset-factory.cpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
@@ -19,6 +19,9 @@
 
 #include "rrset-factory.hpp"
 #include "mgmt/management-tool.hpp"
+#include "util/cert-helper.hpp"
+
+#include <ndn-cxx/security/signing-helpers.hpp>
 
 #include <boost/algorithm/string/join.hpp>
 
@@ -37,9 +40,10 @@
   , m_dskCertName(inputDskCertName)
   , m_checked(false)
 {
+  Name identityName = Name(zoneName).append(label::NDNS_CERT_QUERY);
   if (m_dskCertName == DEFAULT_CERT) {
-    m_dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
-    m_dskCertName = m_keyChain.getDefaultCertificateNameForKey(m_dskName);
+    m_dskName = CertHelper::getDefaultKeyNameOfIdentity(m_keyChain, identityName);
+    m_dskCertName = CertHelper::getDefaultCertificateNameOfIdentity(m_keyChain, identityName);
   }
 }
 
@@ -47,8 +51,9 @@
 RrsetFactory::checkZoneKey()
 {
   onlyCheckZone();
+  Name zoneIdentityName = Name(m_zone.getName()).append(label::NDNS_CERT_QUERY);
   if (m_dskCertName != DEFAULT_CERT &&
-      !matchCertificate(m_dskCertName, m_zone.getName())) {
+      !matchCertificate(m_dskCertName, zoneIdentityName)) {
     BOOST_THROW_EXCEPTION(Error("Cannot verify certificate"));
   }
 }
@@ -84,7 +89,8 @@
   name::Component qType;
   if (type == label::CERT_RR_TYPE) {
     qType = label::NDNS_CERT_QUERY;
-  } else {
+  }
+  else {
     qType = label::NDNS_ITERATIVE_QUERY;
   }
 
@@ -96,7 +102,8 @@
 
   if (version != VERSION_USE_UNIX_TIMESTAMP) {
     name.append(name::Component::fromVersion(version));
-  } else {
+  }
+  else {
     name.appendVersion();
   }
 
@@ -108,26 +115,12 @@
 bool
 RrsetFactory::matchCertificate(const Name& certName, const Name& identity)
 {
-  if (!m_keyChain.doesCertificateExist(certName)) {
-    NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
+  try {
+    CertHelper::getCertificate(m_keyChain, identity, certName);
+    return true;
+  } catch (ndn::security::Pib::Error) {
     return false;
   }
-
-  // Check its public key information
-  shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
-  Name keyName = cert->getPublicKeyName();
-
-  if (!identity.isPrefixOf(keyName) || identity.size() != keyName.size() - 1) {
-    NDNS_LOG_WARN(keyName.toUri() << " is not a key of " << identity.toUri());
-    return false;
-  }
-
-  if (!m_keyChain.doesKeyExistInTpm(keyName, KeyClass::PRIVATE)) {
-    NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not present in KeyChain");
-    return false;
-  }
-
-  return true;
 }
 
 Rrset
@@ -135,7 +128,7 @@
                               const name::Component& type,
                               const uint64_t version,
                               time::seconds ttl,
-                              const ndn::Link::DelegationSet& delegations)
+                              const ndn::DelegationList& delegations)
 {
   if (!m_checked) {
     BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
@@ -149,9 +142,7 @@
   Rrset& rrset = rrsetAndName.first;
 
   Link link(name);
-  for (const auto& i : delegations) {
-    link.addDelegation(i.first, i.second);
-  }
+  link.setDelegationList(delegations);
 
   setContentType(link, NDNS_LINK, ttl);
   sign(link);
@@ -200,7 +191,7 @@
                                 const name::Component& type,
                                 const uint64_t version,
                                 time::seconds ttl,
-                                const IdentityCertificate& cert)
+                                const ndn::security::v2::Certificate& cert)
 {
   if (!m_checked) {
     BOOST_THROW_EXCEPTION(Error("You have to call checkZoneKey before call generate functions"));
@@ -252,7 +243,7 @@
 void
 RrsetFactory::sign(Data& data)
 {
-  m_keyChain.sign(data, m_dskCertName);
+  m_keyChain.sign(data, signingByCertificate(m_dskCertName));
 }
 
 void
diff --git a/src/daemon/rrset-factory.hpp b/src/daemon/rrset-factory.hpp
index e6c5455..89f5b98 100644
--- a/src/daemon/rrset-factory.hpp
+++ b/src/daemon/rrset-factory.hpp
@@ -1,5 +1,5 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
+/*
  * Copyright (c) 2014-2017, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
@@ -64,7 +64,7 @@
                   const name::Component& type,
                   const uint64_t version,
                   time::seconds ttl,
-                  const ndn::Link::DelegationSet& delegations);
+                  const ndn::DelegationList& delegations);
 
   Rrset
   generateTxtRrset(const Name& label,
@@ -84,7 +84,7 @@
                     const name::Component& type,
                     const uint64_t version,
                     time::seconds ttl,
-                    const IdentityCertificate& cert);
+                    const ndn::security::v2::Certificate& cert);
 
   static std::vector<std::string>
   wireDecodeTxt(const Block& wire);