diff --git a/core/logger.cpp b/core/logger.cpp
new file mode 100644
index 0000000..6a1e67c
--- /dev/null
+++ b/core/logger.cpp
@@ -0,0 +1,306 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "logger.hpp"
+#include "tlv.hpp"
+#include "conf/config-file.hpp"
+
+namespace nsl {
+
+const int Logger::N_DATA_FETCHING_RETRIAL = 2;
+
+Logger::Logger(ndn::Face& face, const std::string& configFile)
+  : m_face(face)
+  , m_merkleTree(m_db)
+  , m_validator(m_face)
+{
+  conf::ConfigFile conf(configFile);
+  conf.parse();
+
+  m_loggerName = conf.getLoggerName();
+
+  m_treePrefix = m_loggerName;
+  m_treePrefix.append("tree");
+  m_leafPrefix = m_loggerName;
+  m_leafPrefix.append("leaf");
+  m_logPrefix = m_loggerName;
+  m_logPrefix.append("log");
+
+  m_merkleTree.setLoggerName(m_treePrefix);
+  m_merkleTree.loadPendingSubTrees();
+
+  m_db.open(conf.getDbDir());
+
+  // initialize security environment: keychain
+  initializeKeys();
+
+  // load policy checker
+  m_policyChecker.loadPolicy(conf.getPolicy());
+
+  // load validator rules
+  m_validator.load(conf.getValidatorRule(), conf.getConfFileName());
+
+  // register subtree prefix
+  m_face.setInterestFilter(m_treePrefix,
+                           bind(&Logger::onSubTreeInterest, this, _1, _2),
+                           [] (const Name&) {},
+                           [] (const Name&, const std::string&) {});
+
+  // register leaf prefix
+  m_face.setInterestFilter(m_leafPrefix,
+                           bind(&Logger::onLeafInterest, this, _1, _2),
+                           [] (const Name&) {},
+                           [] (const Name&, const std::string&) {});
+
+  // register log prefix
+  m_face.setInterestFilter(m_logPrefix,
+                           bind(&Logger::onLogRequestInterest, this, _1, _2),
+                           [] (const Name&) {},
+                           [] (const Name&, const std::string&) {});
+}
+
+NonNegativeInteger
+Logger::addSelfSignedCert(ndn::IdentityCertificate& cert, const Timestamp& timestamp)
+{
+  if (!ndn::Validator::verifySignature(cert, cert.getPublicKeyInfo()))
+    throw Error("Not self-signed cert");
+
+  NonNegativeInteger dataSeqNo = m_merkleTree.getNextLeafSeqNo();
+  Leaf leaf(cert.getFullName(), timestamp, dataSeqNo, dataSeqNo, m_leafPrefix);
+
+  if (m_merkleTree.addLeaf(dataSeqNo, leaf.getHash())) {
+    bool result = m_db.insertLeafData(leaf, cert);
+    BOOST_ASSERT(result);
+    m_db.getLeaf(dataSeqNo);
+  }
+  else
+    throw Error("Cannot add cert");
+
+  return dataSeqNo;
+}
+
+void
+Logger::initializeKeys()
+{
+  Name certName = m_keyChain.createIdentity(m_loggerName);
+
+  Name dskKeyName = m_keyChain.generateEcdsaKeyPair(m_loggerName);
+  std::vector<ndn::CertificateSubjectDescription> subjectDescription;
+  auto dskCert =
+    m_keyChain.prepareUnsignedIdentityCertificate(dskKeyName, m_loggerName,
+                                                  time::system_clock::now(),
+                                                  time::system_clock::now() + time::days(1),
+                                                  subjectDescription);
+  m_keyChain.sign(*dskCert, certName);
+  m_keyChain.addCertificate(*dskCert);
+  m_dskCert = dskCert;
+}
+
+void
+Logger::onSubTreeInterest(const ndn::InterestFilter& interestFilter, const Interest& interest)
+{
+  Name interestName = interest.getName();
+
+  size_t levelOffset = m_treePrefix.size();
+  size_t seqNoOffset = m_treePrefix.size() + 1;
+
+  if (interestName.size() < seqNoOffset + 1)
+    return; // interest is too short to answer
+
+  NonNegativeInteger level;
+  NonNegativeInteger seqNo;
+
+  try {
+    seqNo = interestName.get(seqNoOffset).toNumber();
+    level = interestName.get(levelOffset).toNumber();
+  }
+  catch (tlv::Error&) {
+    return;
+  }
+
+  Node::Index peakIndex = SubTreeBinary::toSubTreePeakIndex(Node::Index(seqNo, level));
+  shared_ptr<Data> data;
+
+  data = m_merkleTree.getPendingSubTreeData(peakIndex.level);
+
+  if (data != nullptr && interestName.isPrefixOf(data->getName())) {
+    m_face.put(*data);
+    return;
+  }
+
+  data = m_db.getSubTreeData(peakIndex.level, peakIndex.seqNo);
+
+  if (data != nullptr && interestName.isPrefixOf(data->getName())) {
+    m_face.put(*data);
+    return;
+  }
+}
+
+void
+Logger::onLeafInterest(const ndn::InterestFilter& interestFilter, const Interest& interest)
+{
+  Name interestName = interest.getName();
+
+  size_t seqNoOffset = m_leafPrefix.size();
+  size_t hashOffset = m_leafPrefix.size() + 1;
+
+  if (interestName.size() < seqNoOffset + 1)
+    return; // interest is too short to answer
+
+  NonNegativeInteger seqNo;
+
+  try {
+    seqNo = interestName.get(seqNoOffset).toNumber();
+  }
+  catch (tlv::Error&) {
+    return;
+  }
+  auto result = m_db.getLeaf(seqNo);
+
+  if (result.first != nullptr) {
+    if (interestName.size() >= hashOffset + 1) {
+      ndn::ConstBufferPtr leafHash;
+      try {
+        leafHash = make_shared<ndn::Buffer>(interestName.get(hashOffset).value(),
+                                            interestName.get(hashOffset).value_size());
+        ndn::ConstBufferPtr hash = result.first->getHash();
+        if (*hash != *leafHash)
+          return;
+      }
+      catch (tlv::Error&) {
+        return;
+      }
+    }
+    result.first->setLoggerName(m_leafPrefix);
+    m_face.put(*result.first->encode());
+  }
+}
+
+void
+Logger::onLogRequestInterest(const ndn::InterestFilter& interestFilter, const Interest& interest)
+{
+  m_validator.validate(interest,
+                       bind(&Logger::requestValidatedCallback, this, _1),
+                       [] (const shared_ptr<const Interest>&, const std::string&) {});
+}
+
+void
+Logger::requestValidatedCallback(const shared_ptr<const Interest>& interest)
+{
+  BOOST_ASSERT(interest->getName().size() == (m_logPrefix.size() + 6));
+
+  Name request = interest->getName().getPrefix(-4); // TODO: remove sig-related components
+
+  size_t dataOffset = m_logPrefix.size();
+  size_t signerOffset = m_logPrefix.size() + 1;
+
+  if (request.size() < signerOffset + 1)
+    return; // request is too short to answer
+
+  Name dataName;
+  NonNegativeInteger signerSeqNo;
+  try {
+    dataName.wireDecode(request.get(dataOffset).blockFromValue());
+    signerSeqNo = request.get(signerOffset).toNumber();
+  }
+  catch (tlv::Error&) {
+    return;
+  }
+
+  auto result = m_db.getLeaf(signerSeqNo);
+  if (result.first == nullptr || result.second == nullptr)
+    return;
+
+  Interest dataInterest(dataName);
+  m_face.expressInterest(dataInterest,
+                         bind(&Logger::dataReceivedCallback, this, _1, _2,
+                              signerSeqNo, *interest),
+                         bind(&Logger::dataTimeoutCallback, this, _1,
+                              N_DATA_FETCHING_RETRIAL, signerSeqNo, *interest));
+}
+
+void
+Logger::dataReceivedCallback(const Interest& interest, Data& data,
+                             const NonNegativeInteger& signerSeqNo,
+                             const Interest& reqInterest)
+{
+  auto result = m_db.getLeaf(signerSeqNo);
+  BOOST_ASSERT(result.first != nullptr);
+  BOOST_ASSERT(result.second != nullptr);
+
+  Timestamp dataTimestamp = time::toUnixTimestamp(time::system_clock::now()).count() / 1000;
+
+  try {
+    ndn::IdentityCertificate cert(*result.second);
+
+    if (m_policyChecker.check(dataTimestamp, data, result.first->getTimestamp(), cert)) {
+      NonNegativeInteger dataSeqNo = m_merkleTree.getNextLeafSeqNo();
+      Leaf leaf(data.getFullName(), dataTimestamp, dataSeqNo, signerSeqNo, m_leafPrefix);
+
+      if (m_merkleTree.addLeaf(dataSeqNo, leaf.getHash())) {
+        if (data.getContentType() == ndn::tlv::ContentType_Key)
+          m_db.insertLeafData(leaf, data);
+        else
+          m_db.insertLeafData(leaf);
+
+        makeLogResponse(reqInterest, LoggerResponse(dataSeqNo));
+      }
+      else
+        makeLogResponse(reqInterest,
+                        LoggerResponse(tlv::LogResponse_Error_Tree, "cannot add leaf"));
+    }
+    else
+      makeLogResponse(reqInterest,
+                      LoggerResponse(tlv::LogResponse_Error_Policy, "cannot pass policy checking"));
+  }
+  catch (tlv::Error&) {
+    makeLogResponse(reqInterest,
+                    LoggerResponse(tlv::LogResponse_Error_Signer, "signer is wrong"));
+  }
+}
+
+void
+Logger::dataTimeoutCallback(const Interest& interest, int nRetrials,
+                            const NonNegativeInteger& signerSeqNo,
+                            const Interest& reqInterest)
+{
+  if (nRetrials > 0) {
+    m_face.expressInterest(interest,
+                           bind(&Logger::dataReceivedCallback, this, _1, _2,
+                                signerSeqNo, reqInterest),
+                           bind(&Logger::dataTimeoutCallback, this, _1,
+                                nRetrials - 1, signerSeqNo, reqInterest));
+  }
+}
+
+void
+Logger::makeLogResponse(const Interest& reqInterest, const LoggerResponse& response)
+{
+  auto data = make_shared<Data>(reqInterest.getName());
+  data->setContent(response.wireEncode());
+
+  BOOST_ASSERT(m_dskCert != nullptr);
+  m_keyChain.sign(*data, m_dskCert->getName());
+  m_face.put(*data);
+}
+
+
+} // namespace nsl
diff --git a/core/logger.hpp b/core/logger.hpp
new file mode 100644
index 0000000..a53b0aa
--- /dev/null
+++ b/core/logger.hpp
@@ -0,0 +1,140 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#ifndef NSL_CORE_LOGGER_HPP
+#define NSL_CORE_LOGGER_HPP
+
+#include "common.hpp"
+#include "logger-response.hpp"
+#include "db.hpp"
+#include "policy-checker.hpp"
+#include "merkle-tree.hpp"
+#include "util/non-negative-integer.hpp"
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/validator-config.hpp>
+
+namespace nsl {
+
+class Logger
+{
+public:
+  class Error : public std::runtime_error
+  {
+  public:
+    explicit
+    Error(const std::string& what)
+      : std::runtime_error(what)
+    {
+    }
+  };
+
+public:
+  Logger(ndn::Face& face, const std::string& configFile);
+
+  NonNegativeInteger
+  addSelfSignedCert(ndn::IdentityCertificate& cert, const Timestamp& timestamp);
+
+NSL_PUBLIC_WITH_TESTS_ELSE_PRIVATE:
+  void
+  initializeKeys();
+
+  void
+  loadConfiguration(const std::string& filename);
+
+  void
+  onSubTreeInterest(const ndn::InterestFilter& interestFilter, const Interest& interest);
+
+  void
+  onLeafInterest(const ndn::InterestFilter& interestFilter, const Interest& interest);
+
+  void
+  onLogRequestInterest(const ndn::InterestFilter& interestFilter, const Interest& interest);
+
+  void
+  requestValidatedCallback(const shared_ptr<const Interest>& interest);
+
+  void
+  dataReceivedCallback(const Interest& interest, Data& data,
+                       const NonNegativeInteger& signerSeqNo,
+                       const Interest& reqInterest);
+
+  void
+  dataTimeoutCallback(const Interest& interest, int nRetrials,
+                      const NonNegativeInteger& signerSeqNo,
+                      const Interest& reqInterest);
+
+  void
+  makeLogResponse(const Interest& reqInterest, const LoggerResponse& response);
+
+  const Name&
+  getLoggerName() const
+  {
+    return m_loggerName;
+  }
+
+  const Name&
+  getTreePrefix() const
+  {
+    return m_treePrefix;
+  }
+
+  const Name&
+  getLeafPrefix() const
+  {
+    return m_leafPrefix;
+  }
+
+  const Name&
+  getLogPrefix() const
+  {
+    return m_logPrefix;
+  }
+
+  Db&
+  getDb()
+  {
+    return m_db;
+  }
+
+private:
+  static const int N_DATA_FETCHING_RETRIAL;
+
+private:
+  ndn::Face& m_face;
+  Name m_loggerName;
+  Name m_treePrefix;
+  Name m_leafPrefix;
+  Name m_logPrefix;
+
+  Db m_db;
+  MerkleTree  m_merkleTree;
+
+  ndn::KeyChain m_keyChain;
+  shared_ptr<ndn::IdentityCertificate> m_dskCert;
+
+  ndn::ValidatorConfig m_validator;
+  PolicyChecker m_policyChecker;
+};
+
+} // namespace nsl
+
+#endif // NSL_CORE_LOGGER_HPP
diff --git a/daemon/main.cpp b/daemon/main.cpp
index d172f7d..d0b6bd0 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -19,8 +19,71 @@
  * \author Yingdi Yu <yingdi@cs.ucla.edu>
  */
 
+#include "../core/logger.hpp"
+
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+#include <boost/filesystem.hpp>
+
+
 int
 main(int argc, char** argv)
 {
+  namespace po = boost::program_options;
+  namespace fs = boost::filesystem;
+
+  std::string configFile;
+
+  po::options_description description("General Usage\n"
+                                      "  nsl [-h] [-c config]\n"
+                                      "General options");
+  description.add_options()
+    ("help,h", "produce help message")
+    ("config,c", po::value<std::string>(&configFile))
+    ;
+
+  po::variables_map vm;
+  try {
+    po::store(po::parse_command_line(argc, argv, description), vm);
+    po::notify(vm);
+  }
+  catch (const std::exception& e) {
+    std::cerr << "ERROR: " << e.what() << std::endl;
+    std::cerr << description << std::endl;
+    return 1;
+  }
+
+  if (vm.count("help") != 0) {
+    std::cerr << description << std::endl;
+    return 0;
+  }
+
+  if (vm.count("config") == 0) {
+
+    if (!getenv("HOME")) {
+      configFile = "/usr/local/etc/ndn/nsl.conf";
+    }
+    else {
+      configFile = getenv("HOME");
+      configFile += "/.ndn/nsl.conf";
+    }
+
+    if (!fs::exists(fs::path(configFile))) {
+      std::cerr << "ERROR: config file is not available: " << configFile << std::endl;
+      return 1;
+    }
+  }
+
+  try {
+    ndn::Face face;
+    nsl::Logger(face, configFile);
+    face.processEvents();
+  }
+  catch (std::runtime_error& e) {
+    std::cerr << e.what() << std::endl;
+    return 1;
+  }
+
   return 0;
 }
diff --git a/tests/core/logger.t.cpp b/tests/core/logger.t.cpp
new file mode 100644
index 0000000..521be9b
--- /dev/null
+++ b/tests/core/logger.t.cpp
@@ -0,0 +1,335 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California
+ *
+ * This file is part of NSL (NDN Signature Logger).
+ * See AUTHORS.md for complete list of NSL authors and contributors.
+ *
+ * NSL 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.
+ *
+ * NSL 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
+ * NSL, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of nsl authors and contributors.
+ */
+
+#include "logger.hpp"
+#include "identity-fixture.hpp"
+#include "db-fixture.hpp"
+#include <ndn-cxx/util/dummy-client-face.hpp>
+#include <ndn-cxx/util/io.hpp>
+
+#include "boost-test.hpp"
+
+namespace nsl {
+namespace tests {
+
+class LoggerFixture : public IdentityFixture
+                    , public DbFixture
+{
+public:
+  LoggerFixture()
+    : face1(ndn::util::makeDummyClientFace(io, {true, true}))
+    , face2(ndn::util::makeDummyClientFace(io, {true, true}))
+    , readInterestOffset1(0)
+    , readDataOffset1(0)
+    , readInterestOffset2(0)
+    , readDataOffset2(0)
+  {
+  }
+
+  ~LoggerFixture()
+  {
+  }
+
+  bool
+  passPacket()
+  {
+    bool hasPassed = false;
+
+    checkFace(face1->sentInterests, readInterestOffset1, *face2, hasPassed);
+    checkFace(face1->sentDatas, readDataOffset1, *face2, hasPassed);
+    checkFace(face2->sentInterests, readInterestOffset2, *face1, hasPassed);
+    checkFace(face2->sentDatas, readDataOffset2, *face1, hasPassed);
+
+    return hasPassed;
+  }
+
+  template<typename Packet>
+  void
+  checkFace(std::vector<Packet>& receivedPackets,
+            size_t& readPacketOffset,
+            ndn::util::DummyClientFace& receiver,
+            bool& hasPassed)
+  {
+    while (receivedPackets.size() > readPacketOffset) {
+      receiver.receive(receivedPackets[readPacketOffset]);
+      readPacketOffset++;
+      hasPassed = true;
+    }
+  }
+
+  void
+  clear()
+  {
+    face1->sentDatas.clear();
+    face1->sentInterests.clear();
+    face2->sentDatas.clear();
+    face2->sentInterests.clear();
+
+    readInterestOffset1 = 0;
+    readDataOffset1 = 0;
+    readInterestOffset2 = 0;
+    readDataOffset2 = 0;
+  }
+
+public:
+  shared_ptr<ndn::util::DummyClientFace> face1;
+  shared_ptr<ndn::util::DummyClientFace> face2;
+
+  size_t readInterestOffset1;
+  size_t readDataOffset1;
+  size_t readInterestOffset2;
+  size_t readDataOffset2;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestLogger, LoggerFixture)
+
+const std::string CONFIG =
+  "logger-name /test/logger                             \n"
+  "policy                                               \n"
+  "{                                                    \n"
+  "  rule                                               \n"
+  "  {                                                  \n"
+  "    id \"Simple Rule\"                               \n"
+  "    for data                                         \n"
+  "    checker                                          \n"
+  "    {                                                \n"
+  "      type customized                                \n"
+  "      sig-type rsa-sha256                            \n"
+  "      key-locator                                    \n"
+  "      {                                              \n"
+  "        type name                                    \n"
+  "        hyper-relation                               \n"
+  "        {                                            \n"
+  "          k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$ \n"
+  "          k-expand \\\\1\\\\2                        \n"
+  "          h-relation is-strict-prefix-of             \n"
+  "          p-regex ^(<>*)$                            \n"
+  "          p-expand \\\\1                             \n"
+  "        }                                            \n"
+  "      }                                              \n"
+  "    }                                                \n"
+  "  }                                                  \n"
+  "}                                                    \n"
+  "validator                                            \n"
+  "{                                                    \n"
+  "  rule                                               \n"
+  "  {                                                  \n"
+  "    id \"Request Rule\"                              \n"
+  "    for interest                                     \n"
+  "    filter                                           \n"
+  "    {                                                \n"
+  "      type name                                      \n"
+  "      name /test/logger/log                          \n"
+  "      relation is-strict-prefix-of                   \n"
+  "    }                                                \n"
+  "    checker                                          \n"
+  "    {                                                \n"
+  "      type customized                                \n"
+  "      sig-type rsa-sha256                            \n"
+  "      key-locator                                    \n"
+  "      {                                              \n"
+  "        type name                                    \n"
+  "        regex ^[^<KEY>]*<KEY><>*<><ID-CERT>$         \n"
+  "      }                                              \n"
+  "    }                                                \n"
+  "  }                                                  \n"
+  "  rule                                               \n"
+  "  {                                                  \n"
+  "    id \"Simple Rule\"                               \n"
+  "    for data                                         \n"
+  "    checker                                          \n"
+  "    {                                                \n"
+  "      type customized                                \n"
+  "      sig-type rsa-sha256                            \n"
+  "      key-locator                                    \n"
+  "      {                                              \n"
+  "        type name                                    \n"
+  "        hyper-relation                               \n"
+  "        {                                            \n"
+  "          k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$ \n"
+  "          k-expand \\\\1\\\\2                        \n"
+  "          h-relation is-strict-prefix-of             \n"
+  "          p-regex ^(<>*)$                            \n"
+  "          p-expand \\\\1                             \n"
+  "        }                                            \n"
+  "      }                                              \n"
+  "    }                                                \n"
+  "  }                                                  \n"
+  "  trust-anchor                                       \n"
+  "  {                                                  \n"
+  "    type file                                        \n"
+  "    file-name \"trust-anchor.cert\"                  \n"
+  "  }                                                  \n"
+  "}                                                    \n";
+
+BOOST_AUTO_TEST_CASE(Basic)
+{
+  namespace fs = boost::filesystem;
+
+  fs::create_directory(fs::path(TEST_LOGGER_PATH));
+
+  fs::path configPath = fs::path(TEST_LOGGER_PATH) / "logger-test.conf";
+  std::ofstream os(configPath.c_str());
+  os << CONFIG;
+  os.close();
+
+  Name root("/ndn");
+  addIdentity(root);
+  auto rootCert = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(root));
+  fs::path certPath = fs::path(TEST_LOGGER_PATH) / "trust-anchor.cert";
+  ndn::io::save(*rootCert, certPath.string());
+
+  Logger logger(*face1, configPath.string());
+
+  BOOST_CHECK_EQUAL(logger.getLoggerName(), Name("/test/logger"));
+  BOOST_CHECK_EQUAL(logger.getTreePrefix(), Name("/test/logger/tree"));
+  BOOST_CHECK_EQUAL(logger.getLeafPrefix(), Name("/test/logger/leaf"));
+  BOOST_CHECK_EQUAL(logger.getLogPrefix(), Name("/test/logger/log"));
+
+  advanceClocks(time::milliseconds(2), 100);
+
+  Timestamp rootTs = time::toUnixTimestamp(time::system_clock::now()).count() / 1000;
+  NonNegativeInteger rootSeqNo = logger.addSelfSignedCert(*rootCert, rootTs);
+  BOOST_CHECK_EQUAL(rootSeqNo, 0);
+
+  Name leafInterestName("/test/logger/leaf");
+  leafInterestName.appendNumber(0);
+  auto leafInterest = make_shared<Interest>(leafInterestName);
+
+  face1->receive(*leafInterest);
+  advanceClocks(time::milliseconds(2), 100);
+
+  BOOST_CHECK_EQUAL(face1->sentDatas.size(), 1);
+  BOOST_CHECK(leafInterestName.isPrefixOf(face1->sentDatas[0].getName()));
+
+  face1->sentDatas.clear();
+
+  Name treeInterestName("/test/logger/tree");
+  treeInterestName.appendNumber(0);
+  treeInterestName.appendNumber(0);
+  auto treeInterest = make_shared<Interest>(treeInterestName);
+
+  face1->receive(*treeInterest);
+  advanceClocks(time::milliseconds(2), 100);
+
+  BOOST_CHECK_EQUAL(face1->sentDatas.size(), 1);
+  BOOST_CHECK(treeInterestName.isPrefixOf(face1->sentDatas[0].getName()));
+
+  face1->sentDatas.clear();
+
+  Name tld("/ndn/tld");
+  Name tldKeyName = m_keyChain.generateRsaKeyPair(tld);
+  std::vector<ndn::CertificateSubjectDescription> subjectDescription;
+  auto tldCert =
+    m_keyChain.prepareUnsignedIdentityCertificate(tldKeyName, root,
+                                                  time::system_clock::now(),
+                                                  time::system_clock::now() + time::days(1),
+                                                  subjectDescription);
+  m_keyChain.signByIdentity(*tldCert, root);
+  m_keyChain.addCertificate(*tldCert);
+
+  face2->setInterestFilter(tldCert->getName().getPrefix(-1),
+    [&] (const ndn::InterestFilter&, const Interest&) { face2->put(*tldCert); },
+    ndn::RegisterPrefixSuccessCallback(),
+    [] (const Name&, const std::string&) {});
+  advanceClocks(time::milliseconds(2), 100);
+  clear();
+
+  Name logInterestName("/test/logger/log");
+  logInterestName.append(tldCert->getFullName().wireEncode());
+  logInterestName.appendNumber(0);
+  auto logInterest = make_shared<Interest>(logInterestName);
+  m_keyChain.sign(*logInterest, tldCert->getName());
+
+  face1->receive(*logInterest);
+  do {
+    advanceClocks(time::milliseconds(2), 100);
+  } while (passPacket());
+  clear();
+
+  BOOST_CHECK_EQUAL(logger.getDb().getMaxLeafSeq(), 2);
+  auto leafResult1 = logger.getDb().getLeaf(1);
+  BOOST_CHECK(leafResult1.first != nullptr);
+  BOOST_CHECK(leafResult1.second != nullptr);
+
+
+
+  Name leafInterestName2("/test/logger/leaf");
+  leafInterestName2.appendNumber(1);
+  auto leafInterest2 = make_shared<Interest>(leafInterestName2);
+
+  face1->receive(*leafInterest2);
+  advanceClocks(time::milliseconds(2), 100);
+
+  BOOST_CHECK_EQUAL(face1->sentDatas.size(), 1);
+  BOOST_CHECK(leafInterestName2.isPrefixOf(face1->sentDatas[0].getName()));
+  clear();
+
+
+
+  Name treeInterestName2("/test/logger/tree");
+  treeInterestName2.appendNumber(1);
+  treeInterestName2.appendNumber(0);
+  auto treeInterest2 = make_shared<Interest>(treeInterestName2);
+
+  face1->receive(*treeInterest2);
+  advanceClocks(time::milliseconds(2), 100);
+
+  BOOST_CHECK_EQUAL(face1->sentDatas.size(), 1);
+  BOOST_CHECK(treeInterestName2.isPrefixOf(face1->sentDatas[0].getName()));
+  clear();
+
+
+  auto data = make_shared<Data>(Name("/ndn/tld/data"));
+  m_keyChain.sign(*data, tldCert->getName());
+
+  face2->setInterestFilter(data->getName(),
+    [&] (const ndn::InterestFilter&, const Interest&) { face2->put(*data); },
+    ndn::RegisterPrefixSuccessCallback(),
+    [] (const Name&, const std::string&) {});
+  advanceClocks(time::milliseconds(2), 100);
+  clear();
+
+  Name logInterestName2("/test/logger/log");
+  logInterestName2.append(data->getFullName().wireEncode());
+  logInterestName2.appendNumber(1);
+  auto logInterest2 = make_shared<Interest>(logInterestName2);
+  m_keyChain.sign(*logInterest2, tldCert->getName());
+
+  face1->receive(*logInterest2);
+  do {
+    advanceClocks(time::milliseconds(2), 100);
+  } while (passPacket());
+  clear();
+
+  BOOST_CHECK_EQUAL(logger.getDb().getMaxLeafSeq(), 3);
+  auto leafResult2 = logger.getDb().getLeaf(2);
+  BOOST_CHECK(leafResult2.first != nullptr);
+  BOOST_CHECK(leafResult2.second == nullptr);
+
+
+  fs::remove_all(fs::path(TEST_LOGGER_PATH));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace nsl
