diff --git a/AUTHORS.md b/AUTHORS.md
index d1af3b8..02ce1d8 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -5,7 +5,7 @@
 
 * Xiaoke Jiang          <http://netarchlab.tsinghua.edu.cn/~shock/>
 * Alexander Afanasyev   <http://lasr.cs.ucla.edu/afanasyev/index.html>
-
+* Jiewen Tan            <alanwake@ucla.edu>
 
 ## All project authors and contributors
 
diff --git a/src/daemon/db-mgr.cpp b/src/daemon/db-mgr.cpp
index 35af5de..53d3822 100644
--- a/src/daemon/db-mgr.cpp
+++ b/src/daemon/db-mgr.cpp
@@ -174,6 +174,31 @@
   return zone.getId() != 0;
 }
 
+std::vector<Zone>
+DbMgr::listZones()
+{
+  sqlite3_stmt* stmt;
+  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);
+  }
+
+  std::vector<Zone> vec;
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    vec.emplace_back();
+    Zone& zone = vec.back();
+    zone.setId(sqlite3_column_int64(stmt, 0));
+    zone.setTtl(time::seconds(sqlite3_column_int(stmt, 2)));
+    zone.setName(Name(Block(static_cast<const uint8_t*>(sqlite3_column_blob(stmt, 1)),
+                            sqlite3_column_bytes(stmt, 1))));
+  }
+  sqlite3_finalize(stmt);
+
+  return vec;
+}
+
 void
 DbMgr::remove(Zone& zone)
 {
diff --git a/src/daemon/db-mgr.hpp b/src/daemon/db-mgr.hpp
index ca83691..336b330 100644
--- a/src/daemon/db-mgr.hpp
+++ b/src/daemon/db-mgr.hpp
@@ -113,6 +113,12 @@
   find(Zone& zone);
 
   /**
+   * @brief get all zones in the database
+   */
+  std::vector<Zone>
+  listZones();
+
+  /**
    * @brief remove the zone
    * @pre m_zone.getId() > 0
    * @post m_zone.getId() == 0
diff --git a/src/mgmt/management-tool.cpp b/src/mgmt/management-tool.cpp
new file mode 100644
index 0000000..619d1c0
--- /dev/null
+++ b/src/mgmt/management-tool.cpp
@@ -0,0 +1,642 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "management-tool.hpp"
+#include "logger.hpp"
+#include "ndns-label.hpp"
+#include "ndns-tlv.hpp"
+
+#include <string>
+#include <iomanip>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/algorithm/string/replace.hpp>
+
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/util/regex.hpp>
+#include <ndn-cxx/encoding/oid.hpp>
+#include <ndn-cxx/security/cryptopp.hpp>
+
+namespace ndn {
+namespace ndns {
+
+NDNS_LOG_INIT("ManagementTool");
+
+ManagementTool::ManagementTool(const std::string& dbFile)
+  : m_dbMgr(dbFile)
+{
+}
+
+void
+ManagementTool::createZone(const Name &zoneName,
+                           const Name& parentZoneName,
+                           const time::seconds& cacheTtl,
+                           const time::seconds& certTtl,
+                           const Name& kskCertName,
+                           const Name& dskCertName)
+{
+  bool isRoot = zoneName == ROOT_ZONE;
+
+  //check preconditions
+  Zone zone(zoneName, cacheTtl);
+  if (m_dbMgr.find(zone)) {
+    throw Error(zoneName.toUri() + " is already presented in the NDNS db");
+  }
+
+  if (!isRoot && parentZoneName.equals(zoneName)) {
+    throw Error("Parent zone name can not be the zone itself");
+  }
+
+  if (!isRoot && !parentZoneName.isPrefixOf(zoneName)) {
+    throw Error(parentZoneName.toUri() + " is not a prefix of " + zoneName.toUri());
+  }
+
+  if (kskCertName != DEFAULT_CERT) {
+    if (!matchCertificate(kskCertName, zoneName)) {
+      throw Error("Cannot verify KSK certificate");
+    }
+  }
+
+  if (dskCertName != DEFAULT_CERT) {
+    if (!matchCertificate(dskCertName, zoneName)) {
+      throw Error("Cannot verify DSK certificate");
+    }
+  }
+
+  if (kskCertName == DEFAULT_CERT && isRoot) {
+    throw Error("Cannot generate KSK for root zone");
+  }
+
+  //first generate KSK and DSK to the keyChain system, and add DSK as default
+  NDNS_LOG_INFO("Start generating KSK and DSK and their corresponding certificates");
+  time::system_clock::TimePoint notBefore = time::system_clock::now();
+  time::system_clock::TimePoint notAfter = notBefore + certTtl;
+  shared_ptr<IdentityCertificate> kskCert;
+
+  if (kskCertName == DEFAULT_CERT) {
+    //create KSK's certificate
+    Name kskName = m_keyChain.generateRsaKeyPair(zoneName, true);
+    std::vector<CertificateSubjectDescription> kskDesc;
+    kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName, zoneName, notBefore, notAfter,
+                                                            kskDesc);
+    //prepare the correct name for the ksk certificate
+    Name newScertName = parentZoneName;
+    newScertName.append(label::NDNS_CERT_QUERY);
+    newScertName.append(zoneName.getSubName(parentZoneName.size()));
+    //remove the zone prefix and KEY
+    newScertName.append(kskCert->getName().getSubName(zoneName.size()+1));
+    kskCert->setName(newScertName);
+
+    m_keyChain.selfSign(*kskCert);
+    m_keyChain.addCertificate(*kskCert);
+    NDNS_LOG_INFO("Generated KSK: " << kskCert->getName().toUri());
+  }
+  else {
+    kskCert = m_keyChain.getCertificate(kskCertName);
+  }
+
+  Name dskName;
+  shared_ptr<IdentityCertificate> dskCert;
+  if (dskCertName == DEFAULT_CERT) {
+    dskName = m_keyChain.generateRsaKeyPairAsDefault(zoneName, false);
+    //create DSK's certificate
+    std::vector<CertificateSubjectDescription> dskDesc;
+    dskCert = m_keyChain.prepareUnsignedIdentityCertificate(dskName, zoneName, notBefore, notAfter,
+                                                            dskDesc);
+    m_keyChain.sign(*dskCert, kskCert->getName());
+    m_keyChain.addCertificateAsKeyDefault(*dskCert);
+    NDNS_LOG_INFO("Generated DSK: " << dskCert->getName().toUri());
+  }
+  else {
+    dskCert = m_keyChain.getCertificate(dskCertName);
+    dskName = dskCert->getPublicKeyName();
+    m_keyChain.setDefaultKeyNameForIdentity(dskName);
+    m_keyChain.setDefaultCertificateNameForKey(dskCert->getName());
+  }
+
+  //second add zone to the database
+  NDNS_LOG_INFO("Start adding new zone to data base");
+  addZone(zone);
+
+  //third create ID-cert
+  NDNS_LOG_INFO("Start creating DSK's ID-CERT");
+  addIdCert(zone, dskCert, cacheTtl);
+}
+
+void
+ManagementTool::deleteZone(const Name& zoneName)
+{
+  //check pre-conditions
+  Zone zone(zoneName);
+  if (!m_dbMgr.find(zone)) {
+    throw Error(zoneName.toUri() + " is not presented in the NDNS db");
+  }
+
+  //first remove all rrsets of this zone from local ndns database
+  std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
+  for (Rrset& rrset : rrsets) {
+    m_dbMgr.remove(rrset);
+  }
+
+  //second remove zone from local ndns database
+  removeZone(zone);
+
+  //third remove identity
+  m_keyChain.deleteIdentity(zoneName);
+}
+
+void
+ManagementTool::exportCertificate(const Name& certName, const std::string& outFile)
+{
+  //search for the certificate, start from KeyChain then local NDNS database
+  shared_ptr<IdentityCertificate> cert;
+  if (m_keyChain.doesCertificateExist(certName)) {
+    cert = m_keyChain.getCertificate(certName);
+  }
+  else {
+    shared_ptr<Regex> regex = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
+    if (regex->match(certName) != true) {
+      throw Error("Certificate name is illegal");
+    }
+    Name zoneName = regex->expand("\\1");
+    Name label = regex->expand("\\2");
+
+    Zone zone(zoneName);
+    Rrset rrset(&zone);
+    rrset.setLabel(label);
+    rrset.setType(label::CERT_RR_TYPE);
+    if (m_dbMgr.find(rrset)) {
+      Data data(rrset.getData());
+      cert = make_shared<IdentityCertificate>(data);
+    }
+    else {
+      throw Error("Cannot find the cert: " + certName.toUri());
+    }
+  }
+
+  if (outFile == DEFAULT_IO) {
+    ndn::io::save(*cert, std::cout);
+  }
+  else {
+    ndn::io::save(*cert, outFile);
+    NDNS_LOG_INFO("save cert to file: " << outFile);
+  }
+}
+
+void
+ManagementTool::addRrSet(const Name& zoneName,
+                         const Name& label,
+                         const name::Component& type,
+                         NdnsType ndnsType,
+                         const uint64_t version,
+                         const std::vector<std::string>& contents,
+                         const Name& inputDskCertName,
+                         const time::seconds& ttl)
+{
+  // check pre-condition
+  Zone zone(zoneName);
+  if (!m_dbMgr.find(zone)) {
+    throw Error(zoneName.toUri() + " is not presented in the NDNS db");
+  }
+
+  if (ndnsType == NDNS_UNKNOWN) {
+    throw Error("The ndns type is unknown");
+  }
+
+  if (type == label::CERT_RR_TYPE) {
+    throw Error("It cannot handle ID-CERT rrset type");
+  }
+
+  // check strange rr type and ndns type combination
+  if (type == label::NS_RR_TYPE && ndnsType == NDNS_RAW) {
+    throw Error("NS cannot be of the type NDNS_RAW");
+  }
+
+  if (type == label::TXT_RR_TYPE && ndnsType != NDNS_RESP) {
+    throw Error("TXT cannot be of the type NDNS_RAW or NDNS_AUTH");
+  }
+
+  if (ndnsType == NDNS_RAW && contents.size() != 1) {
+    throw Error("NDNS_RAW must contain a single content element");
+  }
+
+  Name dskName;
+  Name dskCertName = inputDskCertName;
+  if (dskCertName == DEFAULT_CERT) {
+    dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
+    dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
+  }
+  else {
+    if (!matchCertificate(dskCertName, zoneName)) {
+      throw Error("Cannot verify certificate");
+    }
+  }
+
+  // set rrset
+  Rrset rrset(&zone);
+  rrset.setLabel(label);
+  rrset.setType(type);
+  if (ttl == DEFAULT_RR_TTL)
+    rrset.setTtl(zone.getTtl());
+  else
+    rrset.setTtl(ttl);
+
+  // set response
+  Response re;
+  re.setZone(zoneName);
+  re.setQueryType(label::NDNS_ITERATIVE_QUERY);
+  re.setRrLabel(label);
+  re.setRrType(type);
+  re.setNdnsType(ndnsType);
+
+  //set content according to ndns type
+  if (ndnsType == NDNS_RAW) {
+    Block tmp = ndn::dataBlock(ndn::tlv::Content, contents[0].c_str(), contents[0].length());
+    re.setAppContent(tmp);
+  }
+  else if (ndnsType != NDNS_AUTH) {
+    if (contents.empty()) {
+      re.addRr("");
+    }
+    else {
+      for (const auto& item : contents) {
+        re.addRr(item);
+      }
+    }
+  }
+
+  shared_ptr<Data> data = re.toData();
+  if (version != VERSION_USE_UNIX_TIMESTAMP) {
+    name::Component tmp = name::Component::fromVersion(version);
+    re.setVersion(tmp);
+  }
+  m_keyChain.sign(*data, dskCertName);
+
+  rrset.setVersion(re.getVersion());
+  rrset.setData(data->wireEncode());
+
+  if (m_dbMgr.find(rrset)) {
+    throw Error("Rrset with label=" + label.toUri() + " is already in local NDNS databse");
+  }
+  NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
+                << type);
+  m_dbMgr.insert(rrset);
+}
+
+void
+ManagementTool::addRrSet(const Name& zoneName,
+                         const std::string& inFile,
+                         const time::seconds& ttl,
+                         const Name& inputDskCertName)
+{
+  //check precondition
+  Zone zone(zoneName);
+  if (!m_dbMgr.find(zone)) {
+    throw Error(zoneName.toUri() + " is not presented in the NDNS db");
+  }
+
+  Name dskName;
+  Name dskCertName = inputDskCertName;
+  if (dskCertName == DEFAULT_CERT) {
+    dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
+    dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
+  }
+  else {
+    if (!matchCertificate(dskCertName, zoneName)) {
+      throw Error("Cannot verify certificate");
+    }
+  }
+
+  if (inFile != DEFAULT_IO) {
+    boost::filesystem::path dir = boost::filesystem::path(inFile);
+    if (!boost::filesystem::exists(dir) || boost::filesystem::is_directory(dir)) {
+      throw Error("Data: " + inFile + " does not exist");
+    }
+  }
+
+  //first load the data
+  shared_ptr<Data> data;
+  if (inFile == DEFAULT_IO)
+    data = ndn::io::load<ndn::Data>(std::cin);
+  else
+    data = ndn::io::load<ndn::Data>(inFile);
+
+  //determine whether the data is a self-signed certificate
+  shared_ptr<Regex> regex1 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
+  if (regex1->match(data->getName())) {
+    IdentityCertificate scert(*data);
+    Name keyName = scert.getPublicKeyName();
+    Name keyLocator = scert.getSignature().getKeyLocator().getName();
+
+    //if it is, extract the content and name from the data, and resign it using the dsk.
+    shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
+    BOOST_VERIFY(regex2->match(keyLocator) == true);
+    if (keyName == regex2->expand("\\1\\2")) {
+      shared_ptr<Data> pre = data;
+      Name name = pre->getName();
+      //check whether the name is legal or not. if not converting it to a legal name
+      if (zoneName != regex1->expand("\\1")) {
+        Name comp1 = regex1->expand("\\1").getSubName(zoneName.size());
+        Name comp2 = regex1->expand("\\2");
+        name = zoneName;
+        name.append("KEY");
+        name.append(comp1);
+        name.append(comp2);
+        name.append("ID-CERT");
+        name.append(pre->getName().get(-1));
+      }
+
+      data = make_shared<Data>();
+      data->setName(name);
+      data->setContent(pre->getContent());
+
+      m_keyChain.sign(*data, dskCertName);
+    }
+  }
+
+  // create response for the input data
+  Response re;
+  Name hint;
+  re.fromData(hint, zoneName, *data);
+  Name label = re.getRrLabel();
+  name::Component type = re.getRrType();
+
+  Rrset rrset(&zone);
+  rrset.setLabel(label);
+  rrset.setType(type);
+  if (ttl == DEFAULT_RR_TTL)
+    rrset.setTtl(zone.getTtl());
+  else
+    rrset.setTtl(ttl);
+  rrset.setVersion(re.getVersion());
+  rrset.setData(data->wireEncode());
+
+  if (m_dbMgr.find(rrset)) {
+    throw Error("Rrset with label=" + label.toUri() + " is already in local NDNS databse");
+  }
+  NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
+                << type);
+  m_dbMgr.insert(rrset);
+}
+
+void
+ManagementTool::listZone(const Name& zoneName, std::ostream& os, const bool printRaw) {
+  Zone zone(zoneName);
+  if (!m_dbMgr.find(zone)) {
+    os << "No record is found" << std::endl;
+    return;
+  }
+
+  //first output the zone name
+  os << "; Zone " << zoneName.toUri() << std::endl << std::endl;
+
+  //second output all rrsets
+  std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
+
+  //set width for different columns
+  size_t labelWidth = 0;
+  size_t ttlWidth = 0;
+  size_t typeWidth = 0;
+  for (Rrset& rrset : rrsets) {
+    Data data(rrset.getData());
+    Response re;
+    Name hint;
+    re.fromData(hint, zoneName, data);
+
+    if (rrset.getLabel().toUri().size() > labelWidth)
+      labelWidth = rrset.getLabel().toUri().size();
+
+    std::stringstream seconds;
+    seconds << rrset.getTtl().count();
+    if (seconds.str().size() > ttlWidth)
+      ttlWidth = seconds.str().size();
+
+    if (rrset.getType().toUri().size() > typeWidth)
+      typeWidth = rrset.getType().toUri().size();
+  }
+
+  //output
+  for (Rrset& rrset : rrsets) {
+    Data data(rrset.getData());
+    Response re;
+    Name hint;
+    re.fromData(hint, zoneName, data);
+    int iteration = re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH ?
+                      1 : re.getRrs().size();
+    const std::vector<Block> &rrs = re.getRrs();
+
+    if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
+      os << "; rrset=" << rrset.getLabel().toUri()
+         << " type=" << rrset.getType().toUri()
+         << " version=" << rrset.getVersion().toUri()
+         << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri()
+         << std::endl;
+    }
+
+    for (int i = 0; i < iteration; i++) {
+      os.setf(os.left);
+      os.width(labelWidth + 2);
+      os << rrset.getLabel().toUri();
+
+      os.width(ttlWidth + 2);
+      os << rrset.getTtl().count();
+
+      os.width(typeWidth + 2);
+      os << rrset.getType().toUri();
+
+      if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
+        using namespace CryptoPP;
+        if (rrset.getType() == label::TXT_RR_TYPE) {
+          os.write(reinterpret_cast<const char*>(rrs[i].value()), rrs[i].value_size());
+          os << std::endl;
+        }
+        else if (rrset.getType() == label::NS_RR_TYPE) {
+          //TODO output the NS data once we have it
+          os << std::endl;
+        }
+        else {
+          StringSource ss(rrs[i].wire(), rrs[i].size(), true,
+                          new Base64Encoder(new FileSink(os), true, 64));
+        }
+      }
+    }
+
+    if (re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH) {
+      os.width();
+      os << "; content-type=" << re.getNdnsType()
+         << " version=" << rrset.getVersion().toUri()
+         << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri();
+      os << std::endl;
+
+      if (printRaw && re.getNdnsType() == NDNS_RAW) {
+        using namespace CryptoPP;
+        std::stringstream sstream;
+        StringSource ss(re.getAppContent().wire(), re.getAppContent().size(), true,
+                        new Base64Encoder(new FileSink(sstream), true, 64));
+
+        std::string content = sstream.str();
+        std::string delimiter = "\n";
+        size_t pos = 0;
+        std::string token;
+        while ((pos = content.find(delimiter)) != std::string::npos) {
+            token = content.substr(0, pos);
+            os << "; " << token << std::endl;
+            content.erase(0, pos + delimiter.length());
+        }
+
+        os << std::endl;
+      }
+    }
+    else {
+      os << std::endl;
+    }
+  }
+}
+
+void
+ManagementTool::listAllZones(std::ostream& os) {
+  std::vector<Zone> zones = m_dbMgr.listZones();
+
+  size_t nameWidth = 0;
+  for (const Zone& zone : zones) {
+    if (zone.getName().toUri().size() > nameWidth)
+      nameWidth = zone.getName().toUri().size();
+  }
+
+  for (const Zone& zone : zones) {
+    os.setf(os.left);
+    os.width(nameWidth + 2);
+    os << zone.getName().toUri();
+
+    os << "; default-ttl=" << zone.getTtl().count();
+    os << " default-key=" << m_keyChain.getDefaultKeyNameForIdentity(zone.getName());
+    os << " default-certificate="
+       << m_keyChain.getDefaultCertificateNameForIdentity(zone.getName());
+    os << std::endl;
+  }
+}
+
+void
+ManagementTool::removeRrSet(const Name& zoneName, const Name& label, const name::Component& type)
+{
+  Zone zone(zoneName);
+  Rrset rrset(&zone);
+  rrset.setLabel(label);
+  rrset.setType(type);
+
+  if (!m_dbMgr.find(rrset)) {
+    return;
+  }
+  NDNS_LOG_INFO("Remove rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
+                << type);
+  m_dbMgr.remove(rrset);
+}
+
+void
+ManagementTool::getRrSet(const Name& zoneName,
+                         const Name& label,
+                         const name::Component& type,
+                         std::ostream& os)
+{
+  Zone zone(zoneName);
+  Rrset rrset(&zone);
+  rrset.setLabel(label);
+  rrset.setType(type);
+
+  if (!m_dbMgr.find(rrset)) {
+    os << "No record is found" << std::endl;
+    return;
+  }
+
+  using namespace CryptoPP;
+  StringSource ss(rrset.getData().wire(), rrset.getData().size(), true,
+                  new Base64Encoder(new FileSink(os), true, 64));
+}
+
+void
+ManagementTool::addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert,
+                          const time::seconds& ttl)
+{
+  Rrset rrset(&zone);
+  size_t size = zone.getName().size();
+  Name label = cert->getName().getSubName(size + 1, cert->getName().size() - size - 3);
+  rrset.setLabel(label);
+  rrset.setType(label::CERT_RR_TYPE);
+  rrset.setTtl(ttl);
+  rrset.setVersion(cert->getName().get(-1));
+  rrset.setData(cert->wireEncode());
+
+  if (m_dbMgr.find(rrset)) {
+    throw Error("ID-CERT with label=" + label.toUri() +
+                " is already presented in local NDNS databse");
+  }
+  NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
+                << label::CERT_RR_TYPE);
+  m_dbMgr.insert(rrset);
+}
+
+void
+ManagementTool::addZone(Zone& zone)
+{
+  if (m_dbMgr.find(zone)) {
+    throw Error("Zone with Name=" + zone.getName().toUri() +
+                " is already presented in local NDNS databse");
+  }
+  NDNS_LOG_INFO("Add zone with Name: " << zone.getName().toUri());
+  m_dbMgr.insert(zone);
+}
+
+void
+ManagementTool::removeZone(Zone& zone)
+{
+  if (!m_dbMgr.find(zone)) {
+    return;
+  }
+  NDNS_LOG_INFO("Remove zone with Name: " << zone.getName().toUri());
+  m_dbMgr.remove(zone);
+}
+
+bool
+ManagementTool::matchCertificate(const Name& certName, const Name& identity)
+{
+  if (!m_keyChain.doesCertificateExist(certName)) {
+    NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
+    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, KEY_CLASS_PRIVATE)) {
+    NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not presented in KeyChain");
+    return false;
+  }
+
+  return true;
+}
+
+} // namespace ndns
+} // namespace ndn
diff --git a/src/mgmt/management-tool.hpp b/src/mgmt/management-tool.hpp
new file mode 100644
index 0000000..f962b11
--- /dev/null
+++ b/src/mgmt/management-tool.hpp
@@ -0,0 +1,233 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NDNS_MGMT_MANAGEMENT_TOOL_HPP
+#define NDNS_MGMT_MANAGEMENT_TOOL_HPP
+
+#include "config.hpp"
+#include "ndns-enum.hpp"
+#include "./daemon/zone.hpp"
+#include "./daemon/db-mgr.hpp"
+#include "./daemon/rrset.hpp"
+#include "./clients/response.hpp"
+
+#include <stdexcept>
+#include <ndn-cxx/common.hpp>
+#include <ndn-cxx/security/identity-certificate.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+
+namespace ndn {
+namespace ndns {
+
+static const Name DEFAULT_CERT;
+static const Name ROOT_ZONE;
+static const time::seconds DEFAULT_CACHE_TTL = time::seconds(3600);
+static const time::seconds DEFAULT_CERT_TTL = time::days(365);
+static const std::vector<std::string> DEFAULT_CONTENTS;
+static const std::string DEFAULT_IO = "-";
+static const time::seconds DEFAULT_RR_TTL = time::seconds(0);
+static constexpr uint64_t VERSION_USE_UNIX_TIMESTAMP = std::numeric_limits<uint64_t>::max();
+
+/**
+ * @brief provides management tools to the NDNS system, such as zone creation, zone delegation, DSK
+ * generation and root zone creation.
+ */
+class ManagementTool : noncopyable
+{
+public:
+  /** @brief Represents an error might be thrown during runtime
+   */
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what) : std::runtime_error(what)
+    {
+    }
+  };
+
+  /** @param certDir Path to the directory to store certificates
+   *  @param dbFile Path to the local database
+   */
+  explicit
+  ManagementTool(const std::string& dbFile);
+
+  /** @brief Create a Zone according to a given name.
+   *
+   *  Specifically, It will generate a KSK and a DSK (and their certificates) to the following
+   *  places:
+   *  1) Local NDNS database: a new zone is added.
+   *  2) Local NDNS database: an ID-CERT of the DSK is added.
+   *  3) KeyChain: an identity named with zone name is added.
+   *  4) KeyChain: a KSK and its self-signed certificate is added. The ownership of the KSK is the
+   *  parent zone.
+   *  5) KeyChain: a DSK and its KSK signed certificate is added.
+   *
+   *  -SS.cert (self-signed)
+   *  -SKS.cert (self's Key signed)
+   *  -PKS.cert (parent's Key Signed)
+   *
+   *  @attention
+   *  1) to create root zone, supply zoneName and parentZoneName both with ROOT_ZONE
+   *
+   *  @param zoneName zone's name
+   *  @param parentZoneName parent zone's name
+   *  @param ttl ttl for the created zone
+   *  @param kskCertName if given, a zone will be created with this ksk certificate and its key
+   *  @param kskCertName if given, a zone will be created with this dsk certificate and its key
+   */
+  void
+  createZone(const Name& zoneName,
+             const Name& parentZoneName,
+             const time::seconds& cacheTtl = DEFAULT_CACHE_TTL,
+             const time::seconds& certTtl = DEFAULT_CERT_TTL,
+             const Name& kskCertName = DEFAULT_CERT,
+             const Name& dskCertName = DEFAULT_CERT);
+
+  /** @brief Delete a Zone according to a given name.
+   *
+   *  Specifically, It will do the following things:
+   *  1) KeyChain System: delete the Identity with zone name and all its keys/certificates
+   *  2) Local NDNS database: delete the zone record
+   *  3) Local NDNS database: delete the ID-CERT of the zone's DSK
+   */
+  void
+  deleteZone(const Name& zoneName);
+
+  /** @brief Export the certificate to file system
+   *
+   *  @param certName the name of the certificate to be exported
+   *  @param output the path to output to-be exported file, including the file name
+   */
+  void
+  exportCertificate(const Name& certName, const std::string& outFile = DEFAULT_IO);
+
+  /** @brief add rrset to the NDNS local database
+   *
+   *  This one is only capable of adding NS type including NDNS_RESP and NDNS_AUTH and user defined
+   *  type with string content.
+   *  Other complicated situations can be handled by the other addRrSet() overload function.
+   *
+   *  @param zoneName the name of the zone to hold the rrset
+   *  @param label the rrset label
+   *  @param type the rrset type
+   *  @param ndnsType the ndnsType of the response, for user-defined type, just set it NDNS_RAW
+   *  @param version the version of the response and rrset, default is Unix Timestamp
+   *  @param content the content of the response
+   *  @param dskName the DSK to signed the response, default is the zone's DSK
+   *  @param ttl the ttl of the rrset
+    */
+  void
+  addRrSet(const Name& zoneName,
+           const Name& label,
+           const name::Component& type,
+           NdnsType ndnsType,
+           const uint64_t version = VERSION_USE_UNIX_TIMESTAMP,
+           const std::vector<std::string>& contents = DEFAULT_CONTENTS,
+           const Name& dskCertName = DEFAULT_CERT,
+           const time::seconds& ttl = DEFAULT_RR_TTL);
+
+  /** @brief add rrset to the NDNS local database
+   *
+   *  This overload is capable of adding any data to the rrset as long as the supplied data is
+   *  valid.
+   *  A special case is to add the ID-CERT of KSK to the parent zone. At this case, the SS cert
+   *  should be supplied, and therefore it will use the parent zone's DSK to resign the certificate.
+   *  For other cases, the data will be added directly without any modification.
+   *
+   *  @param zoneName the name of the zone to hold the rrset
+   *  @param dataPath the path to the supplied data
+   *  @param ttl the ttl of the rrset
+   *  @param dskName the DSK to signed the special case, default is the zone's DSK
+    */
+  void
+  addRrSet(const Name& zoneName,
+           const std::string& inFile = DEFAULT_IO,
+           const time::seconds& ttl = DEFAULT_RR_TTL,
+           const Name& dskCertName = DEFAULT_CERT);
+
+  /** @brief remove rrset from the NDNS local database
+   *
+   *  @param zonName the name of the zone holding the rrset
+   *  @param label rrset's label
+   *  @param type rrset's type
+    */
+  void
+  removeRrSet(const Name& zoneName, const Name& label, const name::Component& type);
+
+  /** @brief output the raw data of the selected rrset
+   *
+   *  @param zonName the name of the zone holding the rrset
+   *  @param label rrset's label
+   *  @param type rrset's type
+   *  @param os the ostream to print information to
+   *  @param isPP indicate pretty print
+    */
+  void
+  getRrSet(const Name& zoneName,
+           const Name& label,
+           const name::Component& type,
+           std::ostream& os);
+
+  /** @brief generates an output like DNS zone file. Reference:
+   *  http://en.wikipedia.org/wiki/Zone_file
+   *
+   *  @param zoneName the name of the zone to investigate
+   *  @param os the ostream to print information to
+   *  @param printRaw set to print content of ndns-raw rrset
+    */
+  void
+  listZone(const Name& zoneName, std::ostream& os, const bool printRaw = false);
+
+  /** @brief lists all existing zones within this name server.
+   *
+   *  @param os the ostream to print information to
+    */
+  void
+  listAllZones(std::ostream& os);
+
+private:
+  /** @brief add ID-CERT to the NDNS local database
+    */
+  void
+  addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert, const time::seconds& ttl);
+
+  /** @brief add zone to the NDNS local database
+    */
+  void
+  addZone(Zone& zone);
+
+  /** @brief remove zone from the NDNS local database
+    */
+  void
+  removeZone(Zone& zone);
+
+  /** @brief determine whether a certificate matches with both the identity and key type
+   */
+  bool
+  matchCertificate(const Name& certName, const Name& identity);
+
+private:
+  KeyChain m_keyChain;
+  DbMgr m_dbMgr;
+};
+
+} // namespace ndns
+} // namespace ndn
+#endif // NDNS_MGMT_MANAGEMENT_TOOL_HPP
diff --git a/tests/unit/daemon/db-mgr.cpp b/tests/unit/daemon/db-mgr.cpp
index fb621d2..be728d6 100644
--- a/tests/unit/daemon/db-mgr.cpp
+++ b/tests/unit/daemon/db-mgr.cpp
@@ -179,6 +179,33 @@
   BOOST_CHECK_NO_THROW(session.remove(rrset1));
 }
 
+BOOST_FIXTURE_TEST_CASE(FindAllZones, DbMgrFixture)
+{
+  Zone zone("/ndn");
+  zone.setTtl(time::seconds(1600));
+  session.insert(zone);
+
+  Zone zone2("/ndn/ucla");
+  zone2.setTtl(time::seconds(2600));
+  session.insert(zone2);
+
+  std::vector<Zone> vec = session.listZones();
+  BOOST_CHECK_EQUAL(vec.size(), 2);
+
+  std::sort(vec.begin(),
+            vec.end(),
+            [] (const Zone& n1, const Zone& n2) {
+              return n1.getName().size() < n2.getName().size();
+            });
+  BOOST_CHECK_EQUAL(vec[0].getId(), zone.getId());
+  BOOST_CHECK_EQUAL(vec[0].getName(), "/ndn");
+  BOOST_CHECK_EQUAL(vec[0].getTtl(), time::seconds(1600));
+
+  BOOST_CHECK_EQUAL(vec[1].getId(), zone2.getId());
+  BOOST_CHECK_EQUAL(vec[1].getName(), "/ndn/ucla");
+  BOOST_CHECK_EQUAL(vec[1].getTtl(), time::seconds(2600));
+
+}
 
 BOOST_FIXTURE_TEST_CASE(FindRrsets, DbMgrFixture)
 {
diff --git a/tests/unit/daemon/name-server.cpp b/tests/unit/daemon/name-server.cpp
index f721a5e..09d192f 100644
--- a/tests/unit/daemon/name-server.cpp
+++ b/tests/unit/daemon/name-server.cpp
@@ -167,7 +167,6 @@
     Response resp;
 
     BOOST_CHECK_NO_THROW(resp.fromData(hint, zone, data));
-    std::cout << resp << std::endl;
     BOOST_CHECK_EQUAL(resp.getNdnsType(), NDNS_RESP); // by default NDNS_RAW is enough
     BOOST_CHECK_GT(resp.getRrs().size(), 0);
     Block block = resp.getRrs()[0];
@@ -220,7 +219,6 @@
     Response resp;
 
     BOOST_CHECK_NO_THROW(resp.fromData(hint, zone, data));
-    std::cout << resp << std::endl;
     BOOST_CHECK_EQUAL(resp.getNdnsType(), NDNS_RESP); // by default NDNS_RAW is enough
     BOOST_CHECK_GT(resp.getRrs().size(), 0);
     Block block = resp.getRrs()[0];
@@ -401,7 +399,6 @@
       Response resp;
 
       BOOST_CHECK_NO_THROW(resp.fromData(hint, zone, data));
-      std::cout << resp << std::endl;
       BOOST_CHECK_EQUAL(resp.getNdnsType(), NDNS_RESP); // by default NDNS_RAW is enough
       BOOST_CHECK_GT(resp.getRrs().size(), 0);
       Block block = resp.getRrs()[0];
diff --git a/tests/unit/mgmt/management-tool.cpp b/tests/unit/mgmt/management-tool.cpp
new file mode 100644
index 0000000..2eefe15
--- /dev/null
+++ b/tests/unit/mgmt/management-tool.cpp
@@ -0,0 +1,982 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "../../src/mgmt/management-tool.hpp"
+
+#include "../../boost-test.hpp"
+#include <boost/test/output_test_stream.hpp>
+using boost::test_tools::output_test_stream;
+
+#include "ndns-enum.hpp"
+#include "ndns-label.hpp"
+#include "ndns-tlv.hpp"
+
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string/replace.hpp>
+
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/validator.hpp>
+#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/util/regex.hpp>
+
+namespace ndn {
+namespace ndns {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(ManagementTool)
+
+static const boost::filesystem::path TEST_DATABASE = TEST_CONFIG_PATH "/management_tool.db";
+static const boost::filesystem::path TEST_CERTDIR = TEST_CONFIG_PATH "/management_tool_certs";
+static const Name FAKE_ROOT("/fake-root/123456789");
+
+class ManagementToolFixture
+{
+public:
+  ManagementToolFixture()
+    : m_tool(TEST_DATABASE.string().c_str())
+    , m_keyChain("sqlite3", "file")
+    , m_dbMgr(TEST_DATABASE.string().c_str())
+  {
+    boost::filesystem::create_directory(TEST_CERTDIR);
+  }
+
+  ~ManagementToolFixture()
+  {
+    boost::filesystem::remove_all(TEST_CERTDIR);
+    boost::filesystem::remove(TEST_DATABASE);
+  }
+
+  void
+  getKeyList(const Name& identity, std::vector<Name>& keyList)
+  {
+    m_keyChain.getAllKeyNamesOfIdentity(identity, keyList, false);
+    m_keyChain.getAllKeyNamesOfIdentity(identity, keyList, true);
+  }
+
+  void
+  getCertList(const Name& identity, std::vector<Name>& certNameList)
+  {
+    std::vector<Name> keyList;
+    getKeyList(identity, keyList);
+    for (const Name& name : keyList) {
+      m_keyChain.getAllCertificateNamesOfKey(name, certNameList, false);
+      m_keyChain.getAllCertificateNamesOfKey(name, certNameList, true);
+    }
+  }
+
+  bool
+  checkIdCert(Zone& zone, const Name& certName)
+  {
+    Rrset rrset(&zone);
+    size_t size = zone.getName().size();
+    Name label = certName.getSubName(size+1, certName.size()-size-3);
+    rrset.setLabel(label);
+    rrset.setType(label::CERT_RR_TYPE);
+
+    if (!m_dbMgr.find(rrset))
+      return false;
+
+    Data data(rrset.getData());
+    IdentityCertificate cert(data);
+    return cert.getName() == certName;
+  }
+
+  bool
+  checkNs(Zone& zone, const Name& label, NdnsType ndnsType)
+  {
+    Rrset rrset(&zone);
+    rrset.setLabel(label);
+    rrset.setType(label::NS_RR_TYPE);
+
+    if (!m_dbMgr.find(rrset))
+      return false;
+
+    Data data(rrset.getData());
+    MetaInfo info = data.getMetaInfo();
+
+    const Block* block = info.findAppMetaInfo(tlv::NdnsType);
+    if (block == 0)
+      return false;
+
+    return static_cast<NdnsType>(readNonNegativeInteger(*block)) == ndnsType;
+  }
+
+  bool
+  checkVersion(Zone& zone, const Name& label, const name::Component& type, uint64_t version)
+  {
+    Rrset rrset(&zone);
+    rrset.setLabel(label);
+    rrset.setType(type);
+
+    if (!m_dbMgr.find(rrset))
+      return false;
+
+    name::Component tmp = name::Component::fromVersion(version);
+
+    return rrset.getVersion() == tmp;
+  }
+
+  bool
+  checkTtl(Zone& zone, const Name& label, const name::Component& type, time::seconds ttl)
+  {
+    Rrset rrset(&zone);
+    rrset.setLabel(label);
+    rrset.setType(type);
+
+    if (!m_dbMgr.find(rrset))
+      return false;
+
+    return rrset.getTtl() == ttl;
+  }
+
+  // function to get a verified public key of a given data
+  PublicKey
+  getPublicKeyOfData(const Data& data) {
+    // first extract certificate name of the signing key
+    Signature sig = data.getSignature();
+    KeyLocator kl = sig.getKeyLocator();
+    Name klName = kl.getName();
+
+    //base case, return root key to verify ROOT DSK certificate
+    shared_ptr<Regex> regex1 = make_shared<Regex>(
+                                 "<KEY><fake-root><123456789><ksk-[0-9]+><ID-CERT>");
+    if (regex1->match(klName)) {
+      std::vector<Name> keyList1;
+      m_keyChain.getAllKeyNamesOfIdentity(FAKE_ROOT, keyList1, false);
+      shared_ptr<PublicKey> rootKey = m_keyChain.getPublicKey(keyList1.front());
+
+      // return root key
+      return *rootKey;
+    }
+
+    // second extract the certificate from local NDNS database
+    // extract zone name and label
+    shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
+    BOOST_ASSERT(regex2->match(klName) == true);
+    Name zoneName = regex2->expand("\\1");
+    Name label = regex2->expand("\\2");
+
+    // get ID-CERT from local NDNS database
+    Zone zone(zoneName);
+    Rrset rrset(&zone);
+    rrset.setLabel(label);
+    rrset.setType(label::CERT_RR_TYPE);
+
+    BOOST_CHECK_EQUAL(m_dbMgr.find(rrset), true);
+
+    // get public key siging the ID-CERT
+    Data tmp(rrset.getData());
+    PublicKey pk = getPublicKeyOfData(tmp);
+
+    // verified the ID-CERT
+    BOOST_CHECK_EQUAL(Validator::verifySignature(tmp, pk), true);
+    IdentityCertificate cert(tmp);
+
+    // third return public key
+    return cert.getPublicKeyInfo();
+  }
+
+public:
+  ndns::ManagementTool m_tool;
+  ndn::KeyChain m_keyChain;
+  ndns::DbMgr m_dbMgr;
+};
+
+BOOST_FIXTURE_TEST_CASE(CreateZone1, ManagementToolFixture)
+{
+  //create root zone with supplied certificates
+  bool isRoot = m_keyChain.doesIdentityExist(ROOT_ZONE);
+  size_t iniKey = 0;
+  size_t iniCert = 0;
+  if (isRoot) {
+    std::vector<Name> keyList;
+    getKeyList(ROOT_ZONE, keyList);
+    iniKey = keyList.size();
+
+    std::vector<Name> certList;
+    getCertList(ROOT_ZONE, certList);
+    iniCert = certList.size();
+  }
+
+  time::system_clock::TimePoint notBefore = time::system_clock::now();
+  time::system_clock::TimePoint notAfter = notBefore + DEFAULT_CERT_TTL;
+
+  Name kskName = m_keyChain.generateRsaKeyPair(ROOT_ZONE, true);
+  std::vector<CertificateSubjectDescription> kskDesc;
+  shared_ptr<IdentityCertificate> kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName,
+    ROOT_ZONE, notBefore, notAfter, kskDesc);
+  m_keyChain.selfSign(*kskCert);
+  m_keyChain.addCertificate(*kskCert);
+
+  Name dskName = m_keyChain.generateRsaKeyPair(ROOT_ZONE, false);
+  std::vector<CertificateSubjectDescription> dskDesc;
+  shared_ptr<IdentityCertificate> dskCert = m_keyChain.prepareUnsignedIdentityCertificate(
+    dskName, ROOT_ZONE, notBefore, notAfter, dskDesc);
+  m_keyChain.sign(*dskCert, kskCert->getName());
+  m_keyChain.addCertificate(*dskCert);
+
+  m_tool.createZone(ROOT_ZONE, ROOT_ZONE, time::seconds(4600), time::seconds(4600),
+                    kskCert->getName(), dskCert->getName());
+
+  BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(ROOT_ZONE), true);
+
+  std::vector<Name> keyList;
+  getKeyList(ROOT_ZONE, keyList);
+  BOOST_CHECK_EQUAL(keyList.size(), 2 + iniKey);
+
+  std::vector<Name> certList;
+  getCertList(ROOT_ZONE, certList);
+  BOOST_CHECK_EQUAL(certList.size(), 2 + iniCert);
+
+  Zone zone(ROOT_ZONE);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(zone), true);
+  BOOST_CHECK_EQUAL(checkIdCert(zone, dskCert->getName()), true);
+
+  if (isRoot) {
+    // will leave the identity in KeyChain
+    m_keyChain.deleteCertificate(kskCert->getName());
+    m_keyChain.deleteCertificate(dskCert->getName());
+
+    m_keyChain.deleteKey(kskName);
+    m_keyChain.deleteKey(dskName);
+  }
+  else {
+    m_tool.deleteZone(ROOT_ZONE);
+  }
+}
+
+BOOST_FIXTURE_TEST_CASE(CreateZone2, ManagementToolFixture)
+{
+  //create normal zone
+  Name parentZoneName("/ndns-test");
+  parentZoneName.appendVersion();
+  Name zoneName = parentZoneName;
+  zoneName.append("child-zone");
+
+
+  m_tool.createZone(zoneName, parentZoneName);
+
+  BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(zoneName), true);
+
+  std::vector<Name> keyList;
+  getKeyList(zoneName, keyList);
+  BOOST_CHECK_EQUAL(keyList.size(), 2);
+
+  std::vector<Name> certList;
+  getCertList(zoneName, certList);
+  BOOST_CHECK_EQUAL(certList.size(), 2);
+
+  Name dskName;
+  Name kskName;
+  for (std::vector<Name>::iterator it = certList.begin();
+      it != certList.end();
+      it++) {
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("dsk");
+    if (found != std::string::npos) {
+      dskName = *it;
+    }
+    else {
+      kskName = *it;
+    }
+  }
+
+  Zone zone(zoneName);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(zone), true);
+  BOOST_CHECK_EQUAL(checkIdCert(zone, dskName), true);
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(CreateZone3, ManagementToolFixture)
+{
+  //create normal zone with TTL
+  Name parentZoneName("/ndns-test");
+  parentZoneName.appendVersion();
+  Name zoneName = parentZoneName;
+  zoneName.append("child-zone");
+
+  time::seconds ttl = time::seconds(4200);
+  m_tool.createZone(zoneName, parentZoneName, ttl, ttl);
+
+  BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(zoneName), true);
+
+  std::vector<Name> keyList;
+  getKeyList(zoneName, keyList);
+  BOOST_CHECK_EQUAL(keyList.size(), 2);
+
+  std::vector<Name> certList;
+  getCertList(zoneName, certList);
+  BOOST_CHECK_EQUAL(certList.size(), 2);
+
+  Name dskName;
+  for (std::vector<Name>::iterator it = certList.begin();
+      it != certList.end();
+      it++) {
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("dsk");
+    if (found != std::string::npos) {
+      dskName = *it;
+    }
+  }
+
+  //check zone ttl
+  Zone zone(zoneName);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(zone), true);
+  BOOST_CHECK_EQUAL(zone.getTtl(), ttl);
+
+  //check dsk rrset ttl
+  Rrset rrset(&zone);
+  size_t size = zone.getName().size();
+  Name label = dskName.getSubName(size+1, dskName.size()-size-3);
+  rrset.setLabel(label);
+  rrset.setType(label::CERT_RR_TYPE);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(rrset), true);
+  BOOST_CHECK_EQUAL(rrset.getTtl(), ttl);
+
+  //check certificate ttl
+  shared_ptr<IdentityCertificate> dskCert = m_keyChain.getCertificate(dskName);
+  time::system_clock::Duration tmp = dskCert->getNotAfter() - dskCert->getNotBefore();
+  BOOST_CHECK_EQUAL(ttl, tmp);
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(CreateZone4, ManagementToolFixture)
+{
+  //check pre-condition
+  Name zoneName("/net/ndnsim");
+  Name parentZoneName("/net");
+
+  Zone zone(zoneName);
+  m_dbMgr.insert(zone);
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, parentZoneName), ndns::ManagementTool::Error);
+  m_dbMgr.remove(zone);
+
+  time::seconds ttl = time::seconds(4200);
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, zoneName), ndns::ManagementTool::Error);
+
+  Name fake1("/com");
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, fake1), ndns::ManagementTool::Error);
+
+  Name fake2("/com/ndnsim");
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, parentZoneName, ttl, ttl, fake2),
+                    ndns::ManagementTool::Error);
+  Name cert2 = m_keyChain.createIdentity(fake2);
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, parentZoneName, ttl, ttl, cert2),
+                    ndns::ManagementTool::Error);
+  m_keyChain.deleteIdentity(fake2);
+
+  Name fake3("/net/ndnsim/www");
+  Name cert3 = m_keyChain.createIdentity(fake3);
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, parentZoneName, ttl, ttl, cert3),
+                    ndns::ManagementTool::Error);
+  m_keyChain.deleteIdentity(fake3);
+
+  Name cert4 = m_keyChain.createIdentity(zoneName);
+  shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(cert4);
+  //delete keys in tpm
+  m_keyChain.deleteKeyPairInTpm(cert->getPublicKeyName());
+  BOOST_CHECK_THROW(m_tool.createZone(zoneName, parentZoneName, ttl, ttl, cert4),
+                    ndns::ManagementTool::Error);
+  m_keyChain.deleteIdentity(zoneName);
+
+  //for root zone special case
+  BOOST_CHECK_THROW(m_tool.createZone(ROOT_ZONE, ROOT_ZONE), ndns::ManagementTool::Error);
+}
+
+BOOST_FIXTURE_TEST_CASE(DeleteZone1, ManagementToolFixture)
+{
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+
+  m_tool.createZone(zoneName, ROOT_ZONE);
+
+  std::vector<Name> keyList;
+  getKeyList(zoneName, keyList);
+  std::vector<Name> certList;
+  getCertList(zoneName, certList);
+
+  m_tool.deleteZone(zoneName);
+
+  BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(zoneName), false);
+
+  for (std::vector<Name>::iterator it = keyList.begin(); it != keyList.end(); it++) {
+    BOOST_CHECK_EQUAL(m_keyChain.doesKeyExistInTpm(*it, KEY_CLASS_PUBLIC), false);
+    BOOST_CHECK_EQUAL(m_keyChain.doesKeyExistInTpm(*it, KEY_CLASS_PRIVATE), false);
+  }
+
+  Name dskName;
+  for (std::vector<Name>::iterator it = certList.begin();
+      it != certList.end();
+      it++) {
+    BOOST_CHECK_EQUAL(m_keyChain.doesCertificateExist(*it), false);
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("dsk");
+    if (found != std::string::npos) {
+      dskName = *it;
+    }
+  }
+
+  Zone zone(zoneName);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(zone), false);
+  BOOST_CHECK_EQUAL(checkIdCert(zone, dskName), false);
+}
+
+BOOST_FIXTURE_TEST_CASE(DeleteZone2, ManagementToolFixture)
+{
+  Name zoneName("/net/ndnsim");
+
+  BOOST_CHECK_THROW(m_tool.deleteZone(zoneName), ndns::ManagementTool::Error);
+}
+
+class OutputTester
+{
+public:
+  OutputTester()
+    : savedBuf(std::clog.rdbuf())
+  {
+    std::cout.rdbuf(buffer.rdbuf());
+  }
+
+  ~OutputTester()
+  {
+    std::cout.rdbuf(savedBuf);
+  }
+
+public:
+  std::stringstream buffer;
+  std::streambuf* savedBuf;
+};
+
+BOOST_FIXTURE_TEST_CASE(ExportCertificate, ManagementToolFixture)
+{
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+  std::string output = TEST_CERTDIR.string() + "/ss.cert";
+
+  /// @todo Do not generate anything in root zone. Use some prefix for testing, e.g. /test
+
+  //check precondition
+  Name certName("/net/KEY/ksk-123/ID-CERT/123");
+  BOOST_CHECK_THROW(m_tool.exportCertificate(certName, output), ndns::ManagementTool::Error);
+
+  //get certificate from KeyChain
+  m_tool.createZone(zoneName, ROOT_ZONE);
+  std::vector<Name> certList;
+  getCertList(zoneName, certList);
+  Name kskCertName;
+  Name dskCertName;
+  for (const auto& cert : certList) {
+    std::string temp = cert.toUri();
+    size_t found = temp.find("ksk");
+    if (found != std::string::npos) {
+      kskCertName = cert;
+    }
+    else {
+      dskCertName = cert;
+    }
+  }
+  m_tool.exportCertificate(kskCertName, output);
+  BOOST_CHECK_EQUAL(boost::filesystem::exists(output), true);
+
+  //get certificate from ndns database
+  boost::filesystem::remove(output);
+  m_keyChain.deleteCertificate(dskCertName);
+  m_tool.exportCertificate(dskCertName, output);
+  BOOST_CHECK_EQUAL(boost::filesystem::exists(output), true);
+
+  //output to std::cout
+  std::string acutalOutput;
+  {
+    OutputTester tester;
+    m_tool.exportCertificate(dskCertName, "-");
+    acutalOutput = tester.buffer.str();
+  }
+  // BOOST_CHECK_EQUAL(acutalOutput,
+  //                   "Bv0DDAdCCAluZG5zLXRlc3QICf0AAAFJ6RF8OggDS0VZCBFkc2stMTQxNjk1NDQ3\n"
+  //                   "NzcxNQgHSUQtQ0VSVAgJ/QAAAUnpEXzcFAMYAQIV/QF7MIIBdzAiGA8yMDE0MTEy\n"
+  //                   "NTIyMjc1N1oYDzIwMTUxMTI1MjIyNzU3WjAtMCsGA1UEKRMkL25kbnMtdGVzdC8l\n"
+  //                   "RkQlMDAlMDAlMDFJJUU5JTExJTdDJTNBMIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0A\n"
+  //                   "MIIBCAKCAQEAvRAQ0iLGmoUCNFQjtD6ClA6BzmtViWywDRU7eDXHHqz1BmXNGS28\n"
+  //                   "dmVbk6C8ZiQxVh5IoN2psxU1avC2lLM7HXHnyUtmfu9/zkxdBSFq8B+8FchFpPWe\n"
+  //                   "9M/TSFmEemcFLdMgYEJOurF3osASZ70/kJJ7f1yiFRm1dtO2pl5eVUuiZPcgVwMU\n"
+  //                   "nCUDT/wZ6l2LDr4K7wo6p5F8PYiIddS6zT38gZsRNwCeR5JDwCPY3u5x21aVSSY7\n"
+  //                   "8PS/wdSG0vmjI/kQEWhjaV7ibyTc6ygrbq5RiLD+18CkEF+ECLKjvLnyIO8DkbbM\n"
+  //                   "iMVyc6QSiKnq7bLCyqbBVpZqNpBjdMvDuQIBERY+GwEBHDkHNwgDS0VZCAluZG5z\n"
+  //                   "LXRlc3QICf0AAAFJ6RF8OggRa3NrLTE0MTY5NTQ0Nzc2MjcIB0lELUNFUlQX/QEA\n"
+  //                   "BKchd4m2kpI7N376Z8yRAKA3epcUlGI5E1Xs7pKTFwA16ZQ+dTThBQSzzVaJcOC2\n"
+  //                   "UIc2WVRG5wCxcCLou4bxnbuPaQORyeRnmoodTPoIYsDrWVPxeVY1xJSKCbGoY8dh\n"
+  //                   "BuXmo9nl4X2wk/gZx6//afATgzQCliQK/J9PwigqirJqH6aD+3Ji209FbP57tv0g\n"
+  //                   "aL0Dy5IA6LrJI1Dxq0MXCRv3bNtdGNQZT0AfHIgCrhPe6MMLGn+C9UTDP2nzMqbX\n"
+  //                   "4MaAdshgUFj0mI2iPL3Bep9pYI6zxbU3hJ25UQegjJdC3qoFjz2sp/D6J8wAlCPX\n"
+  //                   "gGH3iewd94xFpPcdrhxtHQ==\n");
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRrSet1, ManagementToolFixture)
+{
+  // check pre-condition
+  BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, ROOT_ZONE, label::NS_RR_TYPE, NDNS_RESP),
+                    ndns::ManagementTool::Error);
+
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+  Zone zone(zoneName);
+  m_dbMgr.insert(zone);
+
+  BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, ROOT_ZONE, label::NS_RR_TYPE, NDNS_UNKNOWN),
+                    ndns::ManagementTool::Error);
+  BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, zoneName, label::CERT_RR_TYPE, NDNS_RAW),
+                    ndns::ManagementTool::Error);
+  BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, ROOT_ZONE, label::NS_RR_TYPE, NDNS_RAW),
+                    ndns::ManagementTool::Error);
+  BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, ROOT_ZONE, label::TXT_RR_TYPE, NDNS_RAW),
+                    ndns::ManagementTool::Error);
+
+  m_dbMgr.remove(zone);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRrSet2, ManagementToolFixture)
+{
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+  Zone zone(zoneName);
+  uint64_t version = 1234;
+  time::seconds ttl1(4200);
+  time::seconds ttl2(4500);
+  m_tool.createZone(zoneName, ROOT_ZONE, ttl1);
+
+  //add NS NDNS_AUTH and check user-defined ttl
+  Name label1("/net/ndnsim1");
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, label1, label::NS_RR_TYPE, NDNS_AUTH, version,
+                                       {}, DEFAULT_CERT, ttl2));
+  BOOST_CHECK_EQUAL(checkNs(zone, label1, NDNS_AUTH), true);
+  BOOST_CHECK_EQUAL(checkVersion(zone, label1, label::NS_RR_TYPE, version), true);
+  BOOST_CHECK_EQUAL(checkTtl(zone, label1, label::NS_RR_TYPE, ttl2), true);
+
+  //add NS NDNS_RESP and check default ttl
+  Name label2("/net/ndnsim2");
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, label2, label::NS_RR_TYPE, NDNS_RESP, version));
+  BOOST_CHECK_EQUAL(checkNs(zone, label2, NDNS_RESP), true);
+  BOOST_CHECK_EQUAL(checkVersion(zone, label2, label::NS_RR_TYPE, version), true);
+  BOOST_CHECK_EQUAL(checkTtl(zone, label2, label::NS_RR_TYPE, ttl1), true);
+
+  //add TXT NDNS_RESP and check rr
+  std::string test = "oops";
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, label2, label::TXT_RR_TYPE, NDNS_RESP, version,
+                                       {test}));
+  Rrset rrset1(&zone);
+  rrset1.setLabel(label2);
+  rrset1.setType(label::TXT_RR_TYPE);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(rrset1), true);
+
+  Data data1(rrset1.getData());
+  Response re1;
+  Name hint1;
+  BOOST_CHECK_EQUAL(re1.fromData(hint1, zoneName, data1), true);
+  const Block &block = re1.getRrs().front();
+  std::string someString(reinterpret_cast<const char*>(block.value()), block.value_size());
+  BOOST_CHECK_EQUAL(test, someString);
+
+  //add user defined type
+  Name label3("/net/ndnsim3");
+  name::Component type("A");
+  std::string content = "10.10.0.1";
+  m_tool.addRrSet(zoneName, label3, type, NDNS_RAW, version, {content});
+  BOOST_CHECK_EQUAL(checkVersion(zone, label3, type, version), true);
+
+  Rrset rrset2(&zone);
+  rrset2.setLabel(label3);
+  rrset2.setType(type);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(rrset2), true);
+
+  Data data2(rrset2.getData());
+  Response re2;
+  Name hint2;
+  BOOST_CHECK_EQUAL(re2.fromData(hint2, zoneName, data2), true);
+  Block tmp = ndn::dataBlock(ndn::tlv::Content, content.c_str(), content.length());
+  tmp.encode();
+  BOOST_REQUIRE(tmp == re2.getAppContent());
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRrSet3, ManagementToolFixture)
+{
+  // check pre-condition
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+  std::string certPath = TEST_CERTDIR.string();
+  BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, certPath), ndns::ManagementTool::Error);
+
+  m_tool.createZone(zoneName, ROOT_ZONE);
+  BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, certPath), ndns::ManagementTool::Error);
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRrSet4, ManagementToolFixture)
+{
+  Name parentZoneName("/ndns-test");
+  parentZoneName.appendVersion();
+  Name zoneName = parentZoneName;
+  zoneName.append("/child-zone");
+  Zone zone(parentZoneName);
+  time::seconds ttl1(4200);
+  time::seconds ttl2(4500);
+  m_tool.createZone(zoneName, parentZoneName);
+  m_tool.createZone(parentZoneName, ROOT_ZONE, ttl1);
+
+  //add KSK ID-CERT
+  std::string output = TEST_CERTDIR.string() + "/ss.cert";
+  std::vector<Name> certList;
+  getCertList(zoneName, certList);
+  Name kskCertName;
+  for (std::vector<Name>::iterator it = certList.begin();
+       it != certList.end();
+       it++) {
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("ksk");
+    if (found != std::string::npos) {
+      kskCertName = *it;
+      break;
+    }
+  }
+  m_tool.exportCertificate(kskCertName, output);
+
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output, ttl2));
+  BOOST_CHECK_EQUAL(checkIdCert(zone, kskCertName), true);
+
+  //add data
+  Response re;
+  re.setZone(parentZoneName);
+  re.setQueryType(label::NDNS_ITERATIVE_QUERY);
+  re.setRrLabel(zoneName);
+  re.setRrType(label::NS_RR_TYPE);
+  re.setNdnsType(NDNS_RESP);
+  shared_ptr<Data> data1 = re.toData();
+  m_keyChain.sign(*data1, kskCertName);
+  ndn::io::save(*data1, output);
+
+  //check user-defined ttl and default ttl
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output));
+  BOOST_CHECK_EQUAL(checkTtl(zone, zoneName, label::NS_RR_TYPE, ttl1), true);
+  m_tool.removeRrSet(parentZoneName, zoneName, label::NS_RR_TYPE);
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output, ttl2));
+  BOOST_CHECK_EQUAL(checkTtl(zone, zoneName, label::NS_RR_TYPE, ttl2), true);
+
+  Rrset rrset(&zone);
+  rrset.setLabel(zoneName);
+  rrset.setType(label::NS_RR_TYPE);
+  BOOST_CHECK_EQUAL(m_dbMgr.find(rrset), true);
+
+  Data data2(rrset.getData());
+  BOOST_REQUIRE(*data1 == data2);
+
+  //add KSK ID-CERT with illegal name and convert it
+  Name iZoneName = parentZoneName;
+  iZoneName.append("illegal");
+  Name illegalCertName = m_keyChain.createIdentity(iZoneName);
+  m_tool.exportCertificate(illegalCertName, output);
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output, ttl2));
+
+  Name legalCertName = parentZoneName;
+  legalCertName.append("KEY");
+  legalCertName.append("illegal");
+  legalCertName.append(illegalCertName.getSubName(4));
+  BOOST_CHECK_EQUAL(checkIdCert(zone, legalCertName), true);
+  m_keyChain.deleteIdentity(iZoneName);
+
+  m_tool.deleteZone(zoneName);
+  m_tool.deleteZone(parentZoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(AddRrSet5, ManagementToolFixture)
+{
+  //check using user provided certificate
+  Name parentZoneName("/ndns-test");
+  parentZoneName.appendVersion();
+  Name zoneName = parentZoneName;
+  zoneName.append("child-zone");
+
+  Name dskName = m_keyChain.generateRsaKeyPair(parentZoneName, false);
+  shared_ptr<IdentityCertificate> dskCert = m_keyChain.selfSign(dskName);
+  m_keyChain.addCertificateAsKeyDefault(*dskCert);
+
+  //check addRrSet1
+  m_tool.createZone(zoneName, parentZoneName);
+  m_tool.createZone(parentZoneName, ROOT_ZONE);
+
+  //add KSK ID-CERT
+  std::string output =  TEST_CERTDIR.string() +  "/ss.cert";
+  std::vector<Name> certList;
+  getCertList(zoneName, certList);
+  Name kskCertName;
+  for (std::vector<Name>::iterator it = certList.begin();
+       it != certList.end();
+       it++) {
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("ksk");
+    if (found != std::string::npos) {
+      kskCertName = *it;
+      break;
+    }
+  }
+  m_tool.exportCertificate(kskCertName, output);
+
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output, time::seconds(4600),
+                                       dskCert->getName()));
+
+  //check addRrSet2
+  Name label1("/net/ndnsim1");
+  BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, label1, label::NS_RR_TYPE, NDNS_AUTH, -1, {},
+                                       dskCert->getName()));
+
+  m_tool.deleteZone(zoneName);
+  m_tool.deleteZone(parentZoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(ListZone, ManagementToolFixture)
+{
+  Name zoneName("/ndns-test/mgmt/123456789");
+
+  m_tool.createZone(zoneName, ROOT_ZONE);
+  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(zoneName);
+  shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
+
+  //add NS with NDNS_RESP
+  Name label2("/ndnsim");
+  uint64_t version = 1234;
+  m_tool.addRrSet(zoneName, label2, label::NS_RR_TYPE, NDNS_RESP, version);
+
+  //add NS with NDNS_AUTH
+  Name label3("/ndnsim/oops");
+  m_tool.addRrSet(zoneName, label3, label::NS_RR_TYPE, NDNS_AUTH, version);
+
+  //add TXT
+  std::string output = TEST_CERTDIR.string() + "/a.rrset";
+  Response re1;
+  re1.setZone(zoneName);
+  re1.setQueryType(label::NDNS_ITERATIVE_QUERY);
+  re1.setRrLabel(label2);
+  re1.setRrType(label::TXT_RR_TYPE);
+  re1.setNdnsType(NDNS_RESP);
+  re1.setVersion(name::Component::fromVersion(version));
+  re1.addRr("First RR");
+  re1.addRr("Second RR");
+  re1.addRr("Last RR");
+  shared_ptr<Data> data1= re1.toData();
+  m_keyChain.sign(*data1, certName);
+  ndn::io::save(*data1, output);
+  m_tool.addRrSet(zoneName, output);
+
+  //add User-Defined
+  name::Component type("A");
+  Response re2;
+  re2.setZone(zoneName);
+  re2.setQueryType(label::NDNS_ITERATIVE_QUERY);
+  re2.setRrLabel(label2);
+  re2.setRrType(type);
+  re2.setNdnsType(NDNS_RESP);
+  re2.setVersion(name::Component::fromVersion(version));
+  re2.addRr("First RR");
+  re2.addRr("Second RR");
+  re2.addRr("Last RR");
+  shared_ptr<Data> data2= re2.toData();
+  m_keyChain.sign(*data2, certName);
+  ndn::io::save(*data2, output);
+  m_tool.addRrSet(zoneName, output);
+
+  output_test_stream testOutput;
+  m_tool.listZone(zoneName, testOutput, true);
+
+  /// @todo check the output
+
+  // BOOST_CHECK(testOutput.
+  //   is_equal(
+  //     "; Zone /ndns-test/mgmt/123456789\n"
+  //     "\n"
+  //     "; rrset=/ndnsim type=A version=%FD%04%D2 signed-by=*\n"
+  //     "/ndnsim             3600  A        vwhGaXJzdCBSUg==\n"
+  //     "/ndnsim             3600  A        vwlTZWNvbmQgUlI=\n"
+  //     "/ndnsim             3600  A        vwdMYXN0IFJS\n"
+  //     "\n"
+  //     "; rrset=/ndnsim type=NS version=%FD%04%D2 signed-by=*\n"
+  //     "/ndnsim             3600  NS\n"
+  //     "\n"
+  //     "; rrset=/ndnsim type=TXT version=%FD%04%D2 signed-by=*\n"
+  //     "/ndnsim             3600  TXT      First RR\n"
+  //     "/ndnsim             3600  TXT      Second RR\n"
+  //     "/ndnsim             3600  TXT      Last RR\n"
+  //     ""
+  //     "/ndnsim/oops        3600  NS       ; content-type=NDNS-Auth version=* signed-by=*\n"
+  //     "/dsk-1416888156106  3600  ID-CERT  ; content-type=NDNS-Raw version=* signed-by=*\n"
+  //     "; Ff0BcjCCAW4wIhgPMjAxNDExMjUwNDAyMzVaGA8yMDE1MTEyNTA0MDIzNVowIjAg\n"
+  //     "; BgNVBCkTGS9uZG5zLXRlc3QvbWdtdC8xMjM0NTY3ODkwggEiMA0GCSqGSIb3DQEB\n"
+  //     "; AQUAA4IBDwAwggEKAoIBAQD8Lsd/kKdcdXTKEhcJpy7M0cnZgpZ3lpQX2Nz8InXN\n"
+  //     "; BkF3b6TsuMSokmDQ78xXNTx0jGUM1g47kQNsk2WTjYgDZUOfpBWz5PZcaO35dUz8\n"
+  //     "; wNGc1lED9A/PbFB4t5NPbZsrThCPw+IvzTYN6A/Dxg9h69zLEEsLWD2PzCkyHQ+F\n"
+  //     "; JjRgzhJPsrl1CoVFSP/bu70xMJVqOwj3GMej6mm0gXXmMv4aEI22jot7+fO07jIy\n"
+  //     "; WUl0fhY33Cgo50YvDeeRsdo+At29OMN8Dd/s2z/6olH0P7IK1/cn++DWcO5zMd1x\n"
+  //     "; zWm+6IoZA6mV1J2O5U0AkbllRVZ+vZPI/lWGzCtXK6jfAgMBAAE=\n"
+  //     ));
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(ListAllZones, ManagementToolFixture)
+{
+  Name zoneName1("/ndns-test1/mgmt/123456789");
+  m_tool.createZone(zoneName1, ROOT_ZONE);
+
+  Name zoneName2("/ndns-test2/mgmt/123456789");
+  m_tool.createZone(zoneName2, ROOT_ZONE);
+
+  Name zoneName3("/ndns-test3/mgmt/123456789");
+  m_tool.createZone(zoneName3, ROOT_ZONE);
+
+  //TODO Check the output
+  // a sample output is like this
+  //  /ndns-test1/mgmt/123456789  ; default-ttl=* default-key=* default-certificate=*
+  //  /ndns-test2/mgmt/123456789  ; default-ttl=* default-key=* default-certificate=*
+  //  /ndns-test3/mgmt/123456789  ; default-ttl=* default-key=* default-certificate=*
+  output_test_stream testOutput;
+  m_tool.listAllZones(testOutput);
+
+  m_tool.deleteZone(zoneName1);
+  m_tool.deleteZone(zoneName2);
+  m_tool.deleteZone(zoneName3);
+}
+
+BOOST_FIXTURE_TEST_CASE(GetRrSet, ManagementToolFixture)
+{
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+  m_tool.createZone(zoneName, ROOT_ZONE);
+
+  Name label("/net/ndnsim2");
+
+  m_tool.addRrSet(zoneName, label, label::NS_RR_TYPE, NDNS_RESP);
+
+  // a sample output is like this
+//  Bv0Bjgc5CAluZG5zLXRlc3QICf0AAAFJ5Sn8HwgETkROUwgDbmV0CAduZG5zaW0y
+//  CAJOUwgJ/QAAAUnlKgXYFAkZBAA27oC0AQEVAr8AFj4bAQEcOQc3CAluZG5zLXRl
+//  c3QICf0AAAFJ5Sn8HwgDS0VZCBFkc2stMTQxNjg4ODk3NTY0NAgHSUQtQ0VSVBf9
+//  AQBj8QOr3vPo1wzuTAwwdF6UEfHmHYxkMor5bw/5Lc6Wpt6SkTb7Ku92/MHedtRD
+//  2UsIhQV+JR7jUGzLVLUuktmrBTT7G9tSioTOVpbtJ7EEYYhcDCV0h1Kefz01AS1O
+//  bUuZbxAWboZCzW6OluTq9Db2c2xEmzE8EzmMQ5zflIL7vQxEigH1kBsvGoMZThOb
+//  aKrfcACfKU3kZQBzyPVbur5PER3dgBjVcdu5aIEXhO3Nf7b22OrPSP8AztZGvkz0
+//  5TSBf7wwxtB6V/aMlDPaKFPgI2mXan729e1JGYZ0OmKhvuPnhT9ApOh9UNSJuhO8
+//  puPJKCOSQHspQHOhnEy9Ee9U
+  output_test_stream testOutput;
+  m_tool.getRrSet(zoneName, label, label::NS_RR_TYPE, testOutput);
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(RemoveRrSet, ManagementToolFixture)
+{
+  Name zoneName("/ndns-test");
+  zoneName.appendVersion();
+  m_tool.createZone(zoneName, ROOT_ZONE);
+  Name label2("/net/ndnsim2");
+  m_tool.addRrSet(zoneName, label2, label::NS_RR_TYPE, NDNS_RESP);
+
+  m_tool.removeRrSet(zoneName, label2, label::NS_RR_TYPE);
+  Zone zone(zoneName);
+  BOOST_CHECK_EQUAL(checkNs(zone, label2, NDNS_RESP), false);
+
+  m_tool.deleteZone(zoneName);
+}
+
+BOOST_FIXTURE_TEST_CASE(DataValidation, ManagementToolFixture)
+{
+  Name subZoneName1 = FAKE_ROOT;
+  subZoneName1.append("net");
+  Name subZoneName2 = subZoneName1;
+  subZoneName2.append("ndnsim");
+
+  // create fake-root zone
+  m_tool.createZone(FAKE_ROOT, ROOT_ZONE);
+
+  // create subZone1 by creating zone, delegating it to ROOT zone
+  m_tool.createZone(subZoneName1, FAKE_ROOT);
+
+  std::string output1 = TEST_CERTDIR.string() + "/ss1.cert";
+  std::vector<Name> certList1;
+  getCertList(subZoneName1, certList1);
+  Name kskCertName1;
+  for (std::vector<Name>::iterator it = certList1.begin();
+       it != certList1.end();
+       it++) {
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("ksk");
+    if (found != std::string::npos) {
+      kskCertName1 = *it;
+      break;
+    }
+  }
+  m_tool.exportCertificate(kskCertName1, output1);
+  m_tool.addRrSet(FAKE_ROOT, output1, time::seconds(4600));
+
+  // create subZone2 by creating zone, delegating it to subZone1
+  m_tool.createZone(subZoneName2, subZoneName1);
+
+  std::string output2 = TEST_CERTDIR.string() + "/ss2.cert";
+  std::vector<Name> certList2;
+  getCertList(subZoneName2, certList2);
+  Name kskCertName2;
+  for (std::vector<Name>::iterator it = certList2.begin();
+       it != certList2.end();
+       it++) {
+    std::string temp = (*it).toUri();
+    size_t found = temp.find("ksk");
+    if (found != std::string::npos) {
+      kskCertName2 = *it;
+      break;
+    }
+  }
+  m_tool.exportCertificate(kskCertName2, output2);
+  m_tool.addRrSet(subZoneName1, output2, time::seconds(4600));
+
+  //simulate the trust chain
+  Data data("test");
+  Name certName = m_keyChain.getDefaultCertificateNameForIdentity(subZoneName2);
+  m_keyChain.sign(data, certName);
+
+  //details of the verification please see the getPublicKeyOfData() function
+  PublicKey pk = getPublicKeyOfData(data);
+  BOOST_CHECK_EQUAL(Validator::verifySignature(data, pk), true);
+
+  m_tool.deleteZone(subZoneName2);
+  m_tool.deleteZone(subZoneName1);
+  m_tool.deleteZone(FAKE_ROOT);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace ndns
+} // namespace ndn
diff --git a/tools/ndns-add-rr-from-file.cpp b/tools/ndns-add-rr-from-file.cpp
new file mode 100644
index 0000000..4fc2066
--- /dev/null
+++ b/tools/ndns-add-rr-from-file.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+
+// @todo combine this command with ndns-add-rr
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  int ttlInt = -1;
+  string zoneStr;
+  string dskStr;
+  string db;
+  string file = "-";
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db")
+      ;
+
+    po::options_description config("Record Options");
+    config.add_options()
+      ("file,f", po::value<string>(&file), "Path to the data. Default is stdin(-)")
+      ("dsk,d", po::value<std::string>(&dskStr), "Set the name of DSK's certificate. "
+        "Default: use default DSK and its default certificate")
+      ("ttl,a", po::value<int>(&ttlInt), "Set ttl of the rrset. Default: 3600 seconds")
+      ;
+
+    options.add(config);
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "host zone name")
+      ;
+
+    po::positional_options_description postion;
+    postion.add("zone", 1);
+    postion.add("file", 1);
+
+    po::options_description cmdlineOptions;
+    cmdlineOptions.add(options).add(hidden);
+
+    // po::options_description config_file_options;
+    // config_file_options.add(config).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdlineOptions).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-add-rr-from-file [-b db] zone [-f file] [-d dskCert] [-a ttl]"
+        " [file]" << std::endl
+                << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zoneName(zoneStr);
+    Name dskName(dskStr);
+    time::seconds ttl;
+    if (ttlInt == -1)
+      ttl = ndns::DEFAULT_CACHE_TTL;
+    else
+      ttl = time::seconds(ttlInt);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.addRrSet(zoneName, file, ttl, dskName);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-add-rr.cpp b/tools/ndns-add-rr.cpp
new file mode 100644
index 0000000..47e7121
--- /dev/null
+++ b/tools/ndns-add-rr.cpp
@@ -0,0 +1,161 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include "util/util.hpp"
+
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+
+#include <string>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  int ttlInt = -1;
+  int versionInt = -1;
+  string zoneStr;
+  Name dsk;
+  string db;
+  string rrLabelStr;
+  string rrTypeStr;
+  string ndnsTypeStr;
+  std::vector<std::string> content;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db")
+      ;
+
+    po::options_description config("Record Options");
+    config.add_options()
+      ("content-type,t", po::value<string>(&ndnsTypeStr), "Set the ndnsType of the resource record."
+        "Options: resp|nack|auth|raw (will try guess type by default)")
+      ("dsk,d", po::value<Name>(&dsk), "Set the name of DSK's certificate. "
+        "Default: use default DSK and its default certificate")
+      ("content,c", po::value<std::vector<std::string>>(&content),
+       "Set the content of resource record. Default: empty string")
+      ("ttl,a", po::value<int>(&ttlInt), "Set ttl of the rrset. Default: 3600 seconds")
+      ("version,v", po::value<int>(&ttlInt), "Set version of the rrset. Default: Unix Timestamp")
+      ;
+
+    // add "Record Options" as a separate section
+    options.add(config);
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "host zone name")
+      ("label", po::value<string>(&rrLabelStr), "label of resource record.")
+      ("type", po::value<string>(&rrTypeStr), "Set the type of resource record.")
+      ;
+
+    po::positional_options_description positional;
+    positional.add("zone", 1);
+    positional.add("label", 1);
+    positional.add("type", 1);
+    positional.add("content", -1);
+
+    po::options_description cmdlineOptions;
+    cmdlineOptions.add(options).add(hidden);
+
+    // po::options_description configFileOptions;
+    // configFileOptions.add(config).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdlineOptions).positional(positional).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-add-rr [options] zone label type [content ...]" << std::endl
+                << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone, label, and type must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("label") == 0) {
+      std::cerr << "Error: label and type must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("type") == 0) {
+      std::cerr << "Error: type must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zoneName(zoneStr);
+    Name label(rrLabelStr);
+    name::Component type(rrTypeStr);
+
+    if (ndnsTypeStr.empty()) {
+      if (rrTypeStr == "NS" || rrTypeStr == "TXT")
+        ndnsTypeStr = "resp";
+      else if (rrTypeStr == "ID-CERT") {
+        ndnsTypeStr = "raw";
+      }
+      else {
+        std::cerr << "Error: content type needs to be explicitly set using --content-type option"
+                  << std::endl;
+        return 1;
+      }
+    }
+    NdnsType ndnsType = ndns::toNdnsType(ndnsTypeStr);
+    time::seconds ttl;
+    if (ttlInt == -1)
+      ttl = ndns::DEFAULT_CACHE_TTL;
+    else
+      ttl = time::seconds(ttlInt);
+    uint64_t version = static_cast<uint64_t>(versionInt);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.addRrSet(zoneName, label, type, ndnsType, version, content, dsk, ttl);
+
+    /// @todo Report success or failure
+    //        May be also show the inserted record in ndns-list-zone format
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-create-zone.cpp b/tools/ndns-create-zone.cpp
new file mode 100644
index 0000000..0893bc7
--- /dev/null
+++ b/tools/ndns-create-zone.cpp
@@ -0,0 +1,133 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include "config.hpp"
+
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  ndn::ndns::log::init();
+  int cacheTtlInt = -1;
+  int certTtlInt = -1;
+  string zoneStr;
+  string parentStr;
+  string dskStr;
+  string kskStr;
+  string db;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db")
+      ;
+
+    po::options_description config("Zone Options");
+    config.add_options()
+      ("cacheTtl,a", po::value<int>(&cacheTtlInt), "Set ttl of records of the zone and its "
+        "DSK ID-CERT. Default: 3600 seconds")
+      ("certTtl,e", po::value<int>(&certTtlInt), "Set ttl of DSK and KSK certificates. "
+        "Default: 365 days")
+      ("parent,p", po::value<std::string>(&parentStr), "Set the parent zone of the zone to be "
+        "created. Default: the zone's direct parent")
+      ("dsk,d", po::value<std::string>(&dskStr), "Set the name of DSK's certificate, "
+        "Default: generate new key and certificate")
+      ("ksk,k", po::value<std::string>(&kskStr), "Set the name of KSK's certificate, "
+        "Default: generate new key and certificate")
+      ;
+
+    options.add(config);
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "name of the zone to be created")
+      ;
+    po::positional_options_description postion;
+    postion.add("zone", 1);
+
+    po::options_description cmdline_options;
+    cmdline_options.add(options).add(hidden);
+
+    // po::options_description config_file_options;
+    // config_file_options.add(config).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-create-zone [-b db] zone [-a cacheTtl] [-e certTtl] [-p parent] "
+        "[-d dskCert] [-k kskCert]" << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zone(zoneStr);
+    Name parent(parentStr);
+    if (!zone.empty() && parentStr.empty())
+      parent = zone.getPrefix(-1);
+
+    Name ksk(kskStr);
+    Name dsk(dskStr);
+
+    time::seconds cacheTtl;
+    time::seconds certTtl;
+    if (cacheTtlInt == -1)
+      cacheTtl = ndns::DEFAULT_CACHE_TTL;
+    else
+      cacheTtl = time::seconds(cacheTtlInt);
+
+    if (certTtlInt == -1)
+      certTtl = ndns::DEFAULT_CERT_TTL;
+    else
+      certTtl = time::seconds(certTtlInt);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.createZone(zone, parent, cacheTtl, certTtl, ksk, dsk);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-delete-zone.cpp b/tools/ndns-delete-zone.cpp
new file mode 100644
index 0000000..12bc7f3
--- /dev/null
+++ b/tools/ndns-delete-zone.cpp
@@ -0,0 +1,88 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  ndn::ndns::log::init();
+  string zoneStr;
+  string db;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database."
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db")
+      ;
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "name of the zone to be deleted")
+      ;
+    po::positional_options_description postion;
+    postion.add("zone", 1);
+
+    po::options_description cmdline_options;
+    cmdline_options.add(options).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-delete-zone zone [-b db]" << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zone(zoneStr);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.deleteZone(zone);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-export-certificate.cpp b/tools/ndns-export-certificate.cpp
new file mode 100644
index 0000000..701aa20
--- /dev/null
+++ b/tools/ndns-export-certificate.cpp
@@ -0,0 +1,103 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  string certStr;
+  string db;
+  string output = "-";
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db");
+
+    po::options_description config("Output Options");
+    config.add_options()
+      ("output,o", po::value<string>(&output), "Set the output path of the to be export cert. "
+        "Default: stdout(-)")
+      ;
+
+    options.add(config);
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("certName", po::value<string>(&certStr), "the name of the certificate")
+      ;
+
+    po::positional_options_description postion;
+    postion.add("certName", 1);
+
+    po::options_description cmdline_options;
+    cmdline_options.add(options).add(hidden);
+
+    // po::options_description config_file_options;
+    // config_file_options.add(config).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-export-certificate [-b db] certificateName [-o output] "
+                << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("certName") == 0) {
+      std::cerr << "Error: certificate name must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name certName(certStr);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.exportCertificate(certName, output);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-get-rr.cpp b/tools/ndns-get-rr.cpp
new file mode 100644
index 0000000..bdf86e0
--- /dev/null
+++ b/tools/ndns-get-rr.cpp
@@ -0,0 +1,109 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  string zoneStr;
+  string db;
+  string rrLabelStr;
+  string rrTypeStr;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db")
+      ;
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "host zone name")
+      ("label", po::value<string>(&rrLabelStr), "label of the resource record.")
+      ("type", po::value<string>(&rrTypeStr), "type of the resource record.")
+      ;
+
+    po::positional_options_description postion;
+    postion.add("zone", 1);
+    postion.add("label", 1);
+    postion.add("type", 1);
+
+    po::options_description cmdline_options;
+    cmdline_options.add(options).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-get-rr zone label type [-b db]" << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("label") == 0) {
+      std::cerr << "Error: label must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("type") == 0) {
+      std::cerr << "Error: type must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zoneName(zoneStr);
+    Name label(rrLabelStr);
+    name::Component type(rrTypeStr);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.getRrSet(zoneName, label, type, std::cout);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-list-all-zones.cpp b/tools/ndns-list-all-zones.cpp
new file mode 100644
index 0000000..98c33f3
--- /dev/null
+++ b/tools/ndns-list-all-zones.cpp
@@ -0,0 +1,80 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+#include <iostream>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  string zoneStr;
+  string db;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db")
+      ;
+
+    po::positional_options_description postion;
+    postion.add("zone", 1);
+
+    po::options_description cmdline_options;
+    cmdline_options.add(options);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdline_options).positional(postion).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-list-all-zones [-b db]" << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    ndn::ndns::ManagementTool tool(db);
+    tool.listAllZones(std::cout);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-list-zone.cpp b/tools/ndns-list-zone.cpp
new file mode 100644
index 0000000..f1a85a2
--- /dev/null
+++ b/tools/ndns-list-zone.cpp
@@ -0,0 +1,107 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+#include <iostream>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  string zoneStr;
+  string db;
+  bool printRaw = false;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db");
+
+    po::options_description config("Output Options");
+    config.add_options()
+      ("printRaw,p", "Set to print raw data")
+      ;
+
+    options.add(config);
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "zone name to investigate")
+      ;
+
+    po::positional_options_description positional;
+    positional.add("zone", 1);
+
+    po::options_description cmdlineOptions;
+    cmdlineOptions.add(options).add(hidden);
+
+    // po::options_description config_file_options;
+    // config_file_options.add(config).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdlineOptions).positional(positional).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-list-zone zone [-b db] [-p printRaw]" << std::endl
+                << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("printRaw") != 0) {
+      printRaw = true;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zoneName(zoneStr);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.listZone(zoneName, std::cout, printRaw);
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
diff --git a/tools/ndns-remove-rr.cpp b/tools/ndns-remove-rr.cpp
new file mode 100644
index 0000000..a3fdf89
--- /dev/null
+++ b/tools/ndns-remove-rr.cpp
@@ -0,0 +1,115 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014, 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.
+ *
+ * NDNS is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NDNS, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mgmt/management-tool.hpp"
+#include "ndns-label.hpp"
+#include "logger.hpp"
+#include <boost/program_options.hpp>
+#include <boost/filesystem.hpp>
+#include <string>
+
+int
+main(int argc, char* argv[])
+{
+  using std::string;
+  using namespace ndn;
+  using namespace ndns;
+
+  ndn::ndns::log::init();
+  string zoneStr;
+  string db;
+  string rrLabelStr;
+  string rrTypeStr;
+  try {
+    namespace po = boost::program_options;
+    po::variables_map vm;
+
+    po::options_description options("Generic Options");
+    options.add_options()
+      ("help,h", "print help message")
+      ("db,b", po::value<std::string>(&db), "Set the path of NDNS server database. "
+        "Default: " DEFAULT_DATABASE_PATH "/ndns.db");
+
+    po::options_description hidden("Hidden Options");
+    hidden.add_options()
+      ("zone", po::value<string>(&zoneStr), "host zone name")
+      ("label", po::value<string>(&rrLabelStr), "label of the resource record.")
+      ("type", po::value<string>(&rrTypeStr), "type of the resource record.")
+      ;
+
+    po::positional_options_description positional;
+    positional.add("zone", 1);
+    positional.add("label", 1);
+    positional.add("type", 1);
+
+    po::options_description cmdlineOptions;
+    cmdlineOptions.add(options).add(hidden);
+
+    // po::options_description configFileOptions;
+    // config_file_options.add(config).add(hidden);
+
+    po::parsed_options parsed =
+      po::command_line_parser(argc, argv).options(cmdlineOptions).positional(positional).run();
+
+    po::store(parsed, vm);
+    po::notify(vm);
+
+    if (vm.count("help")) {
+      std::cout << "Usage: ndns-remove-rr [-b db] zone label type" << std::endl
+                << std::endl;
+      std::cout << options << std::endl;
+      return 0;
+    }
+
+    if (vm.count("zone") == 0) {
+      std::cerr << "Error: zone, label, and type must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("label") == 0) {
+      std::cerr << "Error: label and type must be specified" << std::endl;
+      return 1;
+    }
+
+    if (vm.count("type") == 0) {
+      std::cerr << "Error: type must be specified" << std::endl;
+      return 1;
+    }
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Parameter Error: " << ex.what() << std::endl;
+    return 1;
+  }
+
+  try {
+    Name zoneName(zoneStr);
+    Name label(rrLabelStr);
+    name::Component type(rrTypeStr);
+
+    ndn::ndns::ManagementTool tool(db);
+    tool.removeRrSet(zoneName, label, type);
+
+    /// @todo Report how many records have been removed
+    //        (or that the record was removed or record wasn't found)
+  }
+  catch (const std::exception& ex) {
+    std::cerr << "Error: " << ex.what() << std::endl;
+    return 1;
+  }
+}
