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
