Convert to v2::security and adapt to ndn-cxx changes

Change-Id: I54f1b758cfb8f3f6cbc66a1aec5120ae1640b0ec
refs: #3964
diff --git a/src/adjacency-list.cpp b/src/adjacency-list.cpp
index 33626f5..9d02d7e 100644
--- a/src/adjacency-list.cpp
+++ b/src/adjacency-list.cpp
@@ -266,7 +266,7 @@
 }
 
 AdjacencyList::iterator
-AdjacencyList::findAdjacent(const ndn::util::FaceUri& faceUri)
+AdjacencyList::findAdjacent(const ndn::FaceUri& faceUri)
 {
   return std::find_if(m_adjList.begin(),
                       m_adjList.end(),
@@ -275,7 +275,7 @@
 }
 
 uint64_t
-AdjacencyList::getFaceId(const ndn::util::FaceUri& faceUri)
+AdjacencyList::getFaceId(const ndn::FaceUri& faceUri)
 {
   std::list<Adjacent>::iterator it = std::find_if(m_adjList.begin(),
                                                   m_adjList.end(),
diff --git a/src/adjacency-list.hpp b/src/adjacency-list.hpp
index 6b8ea64..6d37a94 100644
--- a/src/adjacency-list.hpp
+++ b/src/adjacency-list.hpp
@@ -149,7 +149,7 @@
   findAdjacent(uint64_t faceId);
 
   AdjacencyList::iterator
-  findAdjacent(const ndn::util::FaceUri& faceUri);
+  findAdjacent(const ndn::FaceUri& faceUri);
 
   /*! \brief Hack to stop developers from using this function
 
@@ -165,7 +165,7 @@
   }
 
   uint64_t
-  getFaceId(const ndn::util::FaceUri& faceUri);
+  getFaceId(const ndn::FaceUri& faceUri);
 
   void
   writeLog();
diff --git a/src/adjacent.cpp b/src/adjacent.cpp
index 913bbbd..0476878 100644
--- a/src/adjacent.cpp
+++ b/src/adjacent.cpp
@@ -52,7 +52,7 @@
   {
   }
 
-Adjacent::Adjacent(const ndn::Name& an, const ndn::util::FaceUri& faceUri,  double lc,
+Adjacent::Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri,  double lc,
                    Status s, uint32_t iton, uint64_t faceId)
     : m_name(an)
     , m_faceUri(faceUri)
diff --git a/src/adjacent.hpp b/src/adjacent.hpp
index dcdefc8..1e6eac5 100644
--- a/src/adjacent.hpp
+++ b/src/adjacent.hpp
@@ -23,7 +23,7 @@
 #include <boost/cstdint.hpp>
 
 #include <ndn-cxx/face.hpp>
-#include <ndn-cxx/util/face-uri.hpp>
+#include <ndn-cxx/net/face-uri.hpp>
 
 #ifndef NLSR_ADJACENT_HPP
 #define NLSR_ADJACENT_HPP
@@ -50,7 +50,7 @@
 
   Adjacent(const ndn::Name& an);
 
-  Adjacent(const ndn::Name& an, const ndn::util::FaceUri& faceUri, double lc,
+  Adjacent(const ndn::Name& an, const ndn::FaceUri& faceUri, double lc,
            Status s, uint32_t iton, uint64_t faceId);
 
   const ndn::Name&
@@ -65,14 +65,14 @@
     m_name = an;
   }
 
-  const ndn::util::FaceUri&
+  const ndn::FaceUri&
   getFaceUri() const
   {
     return m_faceUri;
   }
 
   void
-  setFaceUri(const ndn::util::FaceUri& faceUri)
+  setFaceUri(const ndn::FaceUri& faceUri)
   {
     m_faceUri = faceUri;
   }
@@ -152,7 +152,7 @@
   }
 
   inline bool
-  compareFaceUri(const ndn::util::FaceUri& faceUri)
+  compareFaceUri(const ndn::FaceUri& faceUri)
   {
     return m_faceUri == faceUri;
   }
@@ -166,8 +166,8 @@
 private:
   /*! m_name The NLSR-configured router name of the neighbor */
   ndn::Name m_name;
-  /*! m_connectingFaceUri The NFD-level specification of the Face*/
-  ndn::util::FaceUri m_faceUri;
+  /*! m_faceUri The NFD-level specification of the Face*/
+  ndn::FaceUri m_faceUri;
   /*! m_linkCost The semi-arbitrary cost to traverse the link. */
   double m_linkCost;
   /*! m_status Whether the neighbor is active or not */
diff --git a/src/conf-file-processor.cpp b/src/conf-file-processor.cpp
index 8359d37..d13b415 100644
--- a/src/conf-file-processor.cpp
+++ b/src/conf-file-processor.cpp
@@ -28,7 +28,7 @@
 #include <boost/cstdint.hpp>
 
 #include <ndn-cxx/name.hpp>
-#include <ndn-cxx/util/face-uri.hpp>
+#include <ndn-cxx/net/face-uri.hpp>
 
 #include <iostream>
 #include <fstream>
@@ -496,7 +496,7 @@
         std::string name = CommandAttriTree.get<std::string>("name");
         std::string uriString = CommandAttriTree.get<std::string>("face-uri");
 
-        ndn::util::FaceUri faceUri;
+        ndn::FaceUri faceUri;
         if (! faceUri.parse(uriString)) {
           std::cerr << "parsing failed!" << std::endl;
           return false;
@@ -665,15 +665,15 @@
 
       std::string file = it->second.data();
       path certfilePath = absolute(file, path(m_confFileName).parent_path());
-      std::shared_ptr<ndn::IdentityCertificate> idCert =
-        ndn::io::load<ndn::IdentityCertificate>(certfilePath.string());
+      std::shared_ptr<ndn::security::v2::Certificate> idCert =
+        ndn::io::load<ndn::security::v2::Certificate>(certfilePath.string());
 
       if (idCert == nullptr) {
         std::cerr << "Error: Cannot load cert-to-publish: " << file << "!" << std::endl;
         return false;
       }
 
-      m_nlsr.loadCertToPublish(idCert);
+      m_nlsr.loadCertToPublish(*idCert);
     }
   }
 
diff --git a/src/hello-protocol.cpp b/src/hello-protocol.cpp
index b28620b..fbb4f5b 100644
--- a/src/hello-protocol.cpp
+++ b/src/hello-protocol.cpp
@@ -114,8 +114,11 @@
     data->setFreshnessPeriod(ndn::time::seconds(10)); // 10 sec
     data->setContent(reinterpret_cast<const uint8_t*>(INFO_COMPONENT.c_str()),
                     INFO_COMPONENT.size());
-    m_nlsr.getKeyChain().sign(*data, m_nlsr.getDefaultCertName());
+
+    m_nlsr.getKeyChain().sign(*data, m_nlsr.getSigningInfo());
+
     NLSR_LOG_DEBUG("Sending out data for name: " << interest.getName());
+
     m_nlsr.getNlsrFace().put(*data);
     // increment SENT_HELLO_DATA
     hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
@@ -195,11 +198,12 @@
 }
 
 void
-HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
+HelloProtocol::onContentValidated(const ndn::Data& data)
 {
   // data name: /<neighbor>/NLSR/INFO/<router>/<version>
-  ndn::Name dataName = data->getName();
+  ndn::Name dataName = data.getName();
   NLSR_LOG_DEBUG("Data validation successful for INFO(name): " << dataName);
+
   if (dataName.get(-3).toUri() == INFO_COMPONENT) {
     ndn::Name neighbor = dataName.getPrefix(-4);
 
@@ -225,10 +229,10 @@
 }
 
 void
-HelloProtocol::onContentValidationFailed(const std::shared_ptr<const ndn::Data>& data,
-                                         const std::string& msg)
+HelloProtocol::onContentValidationFailed(const ndn::Data& data,
+                                         const ndn::security::v2::ValidationError& ve)
 {
-  NLSR_LOG_DEBUG("Validation Error: " << msg);
+  NLSR_LOG_DEBUG("Validation Error: " << ve);
 }
 
 } // namespace nlsr
diff --git a/src/hello-protocol.hpp b/src/hello-protocol.hpp
index c042707..ae95a0e 100644
--- a/src/hello-protocol.hpp
+++ b/src/hello-protocol.hpp
@@ -30,6 +30,7 @@
 #include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
 #include <ndn-cxx/mgmt/nfd/control-response.hpp>
 #include <ndn-cxx/util/scheduler.hpp>
+#include <ndn-cxx/security/v2/validation-error.hpp>
 
 namespace nlsr {
 
@@ -128,14 +129,14 @@
    * to contact this neighbor so that we will retry later.
    */
   void
-  onContentValidated(const std::shared_ptr<const ndn::Data>& data);
+  onContentValidated(const ndn::Data& data);
 
 private:
   /*! \brief Log that incoming data couldn't be validated, but do nothing else.
    */
   void
-  onContentValidationFailed(const std::shared_ptr<const ndn::Data>& data,
-                            const std::string& msg);
+  onContentValidationFailed(const ndn::Data& data,
+                            const ndn::security::v2::ValidationError& ve);
 
   /*! \brief Treat a failed Face registration as an INACTIVE neighbor.
    *
diff --git a/src/lsa.cpp b/src/lsa.cpp
index 5c2cc7a..91f6a7a 100644
--- a/src/lsa.cpp
+++ b/src/lsa.cpp
@@ -248,7 +248,7 @@
       ndn::Name adjName(*tok_iter++);
       std::string connectingFaceUri(*tok_iter++);
       double linkCost = boost::lexical_cast<double>(*tok_iter++);
-      Adjacent adjacent(adjName, ndn::util::FaceUri(connectingFaceUri), linkCost,
+      Adjacent adjacent(adjName, ndn::FaceUri(connectingFaceUri), linkCost,
                         Adjacent::STATUS_INACTIVE, 0, 0);
       addAdjacent(adjacent);
     }
diff --git a/src/lsdb.cpp b/src/lsdb.cpp
index 9efc733..6df2346 100644
--- a/src/lsdb.cpp
+++ b/src/lsdb.cpp
@@ -38,9 +38,10 @@
 public:
   LsaContentPublisher(ndn::Face& face,
                       ndn::KeyChain& keyChain,
+                      const ndn::security::SigningInfo& signingInfo,
                       const ndn::time::milliseconds& freshnessPeriod,
                       const std::string& content)
-    : SegmentPublisher(face, keyChain, freshnessPeriod)
+    : SegmentPublisher(face, keyChain, signingInfo, freshnessPeriod)
     , m_content(content)
   {
   }
@@ -1073,12 +1074,12 @@
 {
   LsaContentPublisher publisher(m_nlsr.getNlsrFace(),
                                 m_nlsr.getKeyChain(),
+                                m_nlsr.getSigningInfo(),
                                 m_lsaRefreshTime,
                                 content);
   NLSR_LOG_DEBUG("Sending requested data ( " << content << ")  for interest (" << interest
              << ") to be published and added to face.");
-  publisher.publish(interest.getName(),
-                    ndn::security::signingByCertificate(m_nlsr.getDefaultCertName()));
+  publisher.publish(interest.getName());
 }
 
   // \brief Finds and sends a requested name LSA.
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index da9de61..296c5e0 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -29,7 +29,8 @@
 #include <cstdio>
 #include <unistd.h>
 
-#include <ndn-cxx/util/face-uri.hpp>
+#include <ndn-cxx/net/face-uri.hpp>
+#include <ndn-cxx/signature.hpp>
 
 namespace nlsr {
 
@@ -61,20 +62,14 @@
                          m_routerNameDispatcher,
                          m_nlsrFace,
                          m_keyChain)
-
   , m_helloProtocol(*this, scheduler)
-  , m_certificateCache(new ndn::CertificateCacheTtl(ioService))
-  , m_validator(m_nlsrFace, DEFAULT_BROADCAST_PREFIX, m_certificateCache, m_certStore)
-  , m_controller(m_nlsrFace, m_keyChain, m_validator)
+  , m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(m_nlsrFace))
+  , m_controller(m_nlsrFace, m_keyChain)
   , m_faceDatasetController(m_nlsrFace, m_keyChain)
   , m_prefixUpdateProcessor(m_localhostDispatcher,
                             m_nlsrFace,
                             m_namePrefixList,
-                            m_nlsrLsdb,
-                            DEFAULT_BROADCAST_PREFIX,
-                            m_keyChain,
-                            m_certificateCache,
-                            m_certStore)
+                            m_nlsrLsdb)
   , m_nfdRibCommandProcessor(m_localhostDispatcher,
                              m_namePrefixList,
                              m_nlsrLsdb)
@@ -97,36 +92,17 @@
 Nlsr::onRegistrationSuccess(const ndn::Name& name)
 {
   NLSR_LOG_DEBUG("Successfully registered prefix: " << name);
-
-  if (name.equals(m_confParam.getRouterPrefix())) {
-    // the top-level prefixes are added.
-    try {
-      m_routerNameDispatcher.addTopPrefix(m_confParam.getRouterPrefix(), false, m_signingInfo);
-    }
-    catch (const std::exception& e) {
-      NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
-    }
-  }
-}
-
-void
-Nlsr::onLocalhostRegistrationSuccess(const ndn::Name& name)
-{
-  // All dispatcher-related sub-prefixes *must* be registered before
-  // the top-level prefixes are added.
-  try {
-    m_localhostDispatcher.addTopPrefix(LOCALHOST_PREFIX, false, m_signingInfo);
-  }
-  catch (const std::exception& e) {
-    NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
-  }
 }
 
 void
 Nlsr::setInfoInterestFilter()
 {
   ndn::Name name(m_confParam.getRouterPrefix());
-  NLSR_LOG_DEBUG("Setting interest filter for name: " << name);
+  name.append("NLSR");
+  name.append("INFO");
+
+  NLSR_LOG_DEBUG("Setting interest filter for Hello interest: " << name);
+
   getNlsrFace().setInterestFilter(name,
                                   std::bind(&HelloProtocol::processInterest,
                                             &m_helloProtocol, _1, _2),
@@ -142,7 +118,9 @@
   ndn::Name name = m_confParam.getLsaPrefix();
   name.append(m_confParam.getSiteName());
   name.append(m_confParam.getRouterName());
+
   NLSR_LOG_DEBUG("Setting interest filter for LsaPrefix: " << name);
+
   getNlsrFace().setInterestFilter(name,
                                   std::bind(&Lsdb::processInterest,
                                             &m_nlsrLsdb, _1, _2),
@@ -152,16 +130,29 @@
                                   ndn::nfd::ROUTE_FLAG_CAPTURE);
 }
 
+
+void
+Nlsr::addDispatcherTopPrefix(const ndn::Name& topPrefix)
+{
+  try {
+    if (topPrefix.equals(m_confParam.getRouterPrefix())) {
+      m_routerNameDispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
+    }
+    else {
+      m_localhostDispatcher.addTopPrefix(topPrefix, false, m_signingInfo);
+    }
+  }
+  catch (const std::exception& e) {
+    NLSR_LOG_ERROR("Error setting top-level prefix in dispatcher: " << e.what() << "\n");
+  }
+}
+
 void
 Nlsr::setStrategies()
 {
   const std::string strategy("ndn:/localhost/nfd/strategy/multicast");
 
-  ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
-  broadcastKeyPrefix.append("KEYS");
-
   m_fib.setStrategy(m_confParam.getLsaPrefix(), strategy, 0);
-  m_fib.setStrategy(broadcastKeyPrefix, strategy, 0);
   m_fib.setStrategy(m_confParam.getChronosyncPrefix(), strategy, 0);
 }
 
@@ -207,8 +198,8 @@
                            std::function<void(void)> finally)
 {
   if (currentNeighbor != m_adjacencyList.getAdjList().end()) {
-    ndn::util::FaceUri uri(currentNeighbor->getFaceUri());
-    uri.canonize([this, then, currentNeighbor] (ndn::util::FaceUri canonicalUri) {
+    ndn::FaceUri uri(currentNeighbor->getFaceUri());
+    uri.canonize([this, then, currentNeighbor] (ndn::FaceUri canonicalUri) {
         NLSR_LOG_DEBUG("Canonized URI: " << currentNeighbor->getFaceUri()
                    << " to: " << canonicalUri);
         currentNeighbor->setFaceUri(canonicalUri);
@@ -228,6 +219,18 @@
   }
 }
 
+
+void
+Nlsr::loadCertToPublish(const ndn::security::v2::Certificate& certificate)
+{
+  m_certStore.insert(certificate);
+  m_validator.loadAnchor("Authoritative-Certificate",
+                          ndn::security::v2::Certificate(certificate));
+  m_prefixUpdateProcessor.getValidator().
+                          loadAnchor("Authoritative-Certificate",
+                                      ndn::security::v2::Certificate(certificate));
+}
+
 void
 Nlsr::initialize()
 {
@@ -248,15 +251,24 @@
   m_adjacencyList.writeLog();
   NLSR_LOG_DEBUG(m_namePrefixList);
   // Logging end
+
   initializeKey();
   setStrategies();
+
   NLSR_LOG_DEBUG("Default NLSR identity: " << m_signingInfo.getSignerName());
+
   setInfoInterestFilter();
   setLsaInterestFilter();
 
+  // add top-level prefixes: router and localhost prefix
+  addDispatcherTopPrefix(m_confParam.getRouterPrefix());
+  addDispatcherTopPrefix(LOCALHOST_PREFIX);
+
   initializeFaces(std::bind(&Nlsr::processFaceDataset, this, _1),
                   std::bind(&Nlsr::onFaceDatasetFetchTimeout, this, _1, _2, 0));
 
+  enableIncomingFaceIdIndication();
+
   // Set event intervals
   setFirstHelloInterval(m_confParam.getFirstHelloInterval());
   m_nlsrLsdb.setAdjLsaBuildInterval(m_confParam.getAdjLsaBuildInterval());
@@ -288,44 +300,71 @@
 void
 Nlsr::initializeKey()
 {
-  ndn::Name defaultIdentity = m_confParam.getRouterPrefix();
-  defaultIdentity.append("NLSR");
+  NLSR_LOG_DEBUG("Initializing Key ...");
+
+  ndn::Name nlsrInstanceName = m_confParam.getRouterPrefix();
+  nlsrInstanceName.append("NLSR");
 
   try {
-    m_keyChain.deleteIdentity(defaultIdentity);
+    m_keyChain.deleteIdentity(m_keyChain.getPib().getIdentity(nlsrInstanceName));
+  } catch (const std::exception& e) {
+    NLSR_LOG_WARN(e.what());
+  }
+
+  auto nlsrInstanceIdentity = m_keyChain.createIdentity(nlsrInstanceName);
+  auto nlsrInstanceKey = nlsrInstanceIdentity.getDefaultKey();
+
+  ndn::security::v2::Certificate certificate;
+
+  ndn::Name certificateName = nlsrInstanceKey.getName();
+  certificateName.append("NA");
+  certificateName.appendVersion();
+  certificate.setName(certificateName);
+
+  // set metainfo
+  certificate.setContentType(ndn::tlv::ContentType_Key);
+  certificate.setFreshnessPeriod(ndn::time::days(7300));
+
+  // set content
+  certificate.setContent(nlsrInstanceKey.getPublicKey().data(), nlsrInstanceKey.getPublicKey().size());
+
+  // set signature-info
+  ndn::SignatureInfo signatureInfo;
+  signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(ndn::time::system_clock::TimePoint(),
+                                                                ndn::time::system_clock::now()
+                                                                + ndn::time::days(20 * 365)));
+  try {
+    m_keyChain.sign(certificate,
+                    ndn::security::SigningInfo(m_keyChain.getPib().getIdentity(m_confParam.getRouterPrefix()))
+                                               .setSignatureInfo(signatureInfo));
   }
   catch (const std::exception& e) {
+    NLSR_LOG_WARN("ERROR: Router's " << e.what()
+                  << "NLSR is running without security."
+                  << " If security is enabled NLSR will not converge.");
+
+    std::cerr << "Router's " << e.what() << "NLSR is running without security "
+              << "(Only for testing, should not be used in production.)"
+              << " If security is enabled NLSR will not converge." << std::endl;
   }
-  m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID, defaultIdentity);
 
-  ndn::Name keyName = m_keyChain.generateRsaKeyPairAsDefault(defaultIdentity, true);
+  m_signingInfo = ndn::security::SigningInfo(ndn::security::SigningInfo::SIGNER_TYPE_ID,
+                                             nlsrInstanceName);
 
-  std::shared_ptr<ndn::IdentityCertificate> certificate =
-    std::make_shared<ndn::IdentityCertificate>();
-  std::shared_ptr<ndn::PublicKey> pubKey = m_keyChain.getPublicKey(keyName);
-  ndn::Name certificateName = keyName.getPrefix(-1);
-  certificateName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
-  certificate->setName(certificateName);
-  certificate->setNotBefore(ndn::time::system_clock::now() - ndn::time::days(1));
-  certificate->setNotAfter(ndn::time::system_clock::now() + ndn::time::days(7300)); // ~20 years
-  certificate->setPublicKeyInfo(*pubKey);
-  certificate->addSubjectDescription(ndn::CertificateSubjectDescription(ndn::oid::ATTRIBUTE_NAME,
-                                                                   keyName.toUri()));
-  certificate->encode();
-  m_keyChain.signByIdentity(*certificate, m_confParam.getRouterPrefix());
-
-  m_keyChain.addCertificateAsIdentityDefault(*certificate);
   loadCertToPublish(certificate);
 
-  m_defaultCertName = certificate->getName();
+  m_defaultCertName = certificate.getName();
 }
 
 void
 Nlsr::registerKeyPrefix()
 {
-  ndn::Name keyPrefix = DEFAULT_BROADCAST_PREFIX;
-  keyPrefix.append("KEYS");
-  m_nlsrFace.setInterestFilter(keyPrefix,
+  // Start listening for the interest of this router's NLSR certificate
+  ndn::Name nlsrKeyPrefix = getConfParameter().getRouterPrefix();
+  nlsrKeyPrefix.append("NLSR");
+  nlsrKeyPrefix.append("KEY");
+
+  m_nlsrFace.setInterestFilter(nlsrKeyPrefix,
                                std::bind(&Nlsr::onKeyInterest,
                                          this, _1, _2),
                                std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
@@ -333,52 +372,73 @@
                                m_signingInfo,
                                ndn::nfd::ROUTE_FLAG_CAPTURE);
 
+  // Start listening for the interest of this router's certificate
+  ndn::Name routerKeyPrefix = getConfParameter().getRouterPrefix();
+  routerKeyPrefix.append("KEY");
+
+  m_nlsrFace.setInterestFilter(routerKeyPrefix,
+                                 std::bind(&Nlsr::onKeyInterest,
+                                           this, _1, _2),
+                                 std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
+                                 std::bind(&Nlsr::registrationFailed, this, _1),
+                                 m_signingInfo,
+                                 ndn::nfd::ROUTE_FLAG_CAPTURE);
+
+  // Start listening for the interest of this router's operator's certificate
+  ndn::Name operatorKeyPrefix = getConfParameter().getNetwork();
+  operatorKeyPrefix.append(getConfParameter().getSiteName());
+  operatorKeyPrefix.append(std::string("%C1.Operator"));
+
+  m_nlsrFace.setInterestFilter(operatorKeyPrefix,
+                               std::bind(&Nlsr::onKeyInterest,
+                                         this, _1, _2),
+                               std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
+                               std::bind(&Nlsr::registrationFailed, this, _1),
+                               m_signingInfo,
+                               ndn::nfd::ROUTE_FLAG_CAPTURE);
+
+  // Start listening for the interest of this router's site's certificate
+  ndn::Name siteKeyPrefix = getConfParameter().getNetwork();
+  siteKeyPrefix.append(getConfParameter().getSiteName());
+  siteKeyPrefix.append("KEY");
+
+  m_nlsrFace.setInterestFilter(siteKeyPrefix,
+                               std::bind(&Nlsr::onKeyInterest,
+                                          this, _1, _2),
+                               std::bind(&Nlsr::onKeyPrefixRegSuccess, this, _1),
+                               std::bind(&Nlsr::registrationFailed, this, _1),
+                               m_signingInfo,
+                               ndn::nfd::ROUTE_FLAG_CAPTURE);
 }
 
 void
 Nlsr::registerLocalhostPrefix()
 {
   m_nlsrFace.registerPrefix(LOCALHOST_PREFIX,
-                            std::bind(&Nlsr::onLocalhostRegistrationSuccess, this, _1),
+                            std::bind(&Nlsr::onRegistrationSuccess, this, _1),
                             std::bind(&Nlsr::registrationFailed, this, _1));
 }
 
 void
 Nlsr::onKeyInterest(const ndn::Name& name, const ndn::Interest& interest)
 {
+  NLSR_LOG_DEBUG("Got interest for certificate. Interest: " << interest.getName());
+
   const ndn::Name& interestName = interest.getName();
-  ndn::Name certName = interestName.getSubName(name.size());
+  const ndn::security::v2::Certificate* cert = getCertificate(interestName);
 
-  if (certName[-2].toUri() == "ID-CERT")
-    {
-      certName = certName.getPrefix(-1);
-    }
-  else if (certName[-1].toUri() != "ID-CERT")
-    {
-      NLSR_LOG_DEBUG("certName for interest " << interest << " is malformed,"
-                 << " contains incorrect namespace syntax");
-      return;
-    }
-
-  std::shared_ptr<const ndn::IdentityCertificate> cert = getCertificate(certName);
-
-  if (!static_cast<bool>(cert))
-    {
-      NLSR_LOG_DEBUG("cert is not found for " << interest);
+  if (cert == nullptr) {
+      NLSR_LOG_DEBUG("Certificate is not found for: " << interest);
       return; // cert is not found
-    }
+  }
 
-  std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>();
-  data->setName(interestName);
-  data->setContent(cert->wireEncode());
-  m_keyChain.signWithSha256(*data);
-
-  m_nlsrFace.put(*data);
+  m_nlsrFace.put(*cert);
 }
 
 void
 Nlsr::onKeyPrefixRegSuccess(const ndn::Name& name)
 {
+  NLSR_LOG_DEBUG("KEY prefix: " << name << " registration is successful.");
 }
 
 void
@@ -432,7 +492,7 @@
     case ndn::nfd::FACE_EVENT_CREATED: {
       // Find the neighbor in our adjacency list
       auto adjacent = m_adjacencyList.findAdjacent(
-        ndn::util::FaceUri(faceEventNotification.getRemoteUri()));
+        ndn::FaceUri(faceEventNotification.getRemoteUri()));
       // If we have a neighbor by that FaceUri and it has no FaceId, we
       // have a match.
       if (adjacent != m_adjacencyList.end()) {
@@ -505,10 +565,11 @@
 Nlsr::registerAdjacencyPrefixes(const Adjacent& adj,
                                 const ndn::time::milliseconds& timeout)
 {
-  ndn::util::FaceUri faceUri = adj.getFaceUri();
+  ndn::FaceUri faceUri = adj.getFaceUri();
   double linkCost = adj.getLinkCost();
+  const ndn::Name& adjName = adj.getName();
 
-  m_fib.registerPrefix(adj.getName(), faceUri, linkCost,
+  m_fib.registerPrefix(adjName, faceUri, linkCost,
                        timeout, ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
 
   m_fib.registerPrefix(m_confParam.getChronosyncPrefix(),
@@ -518,12 +579,6 @@
   m_fib.registerPrefix(m_confParam.getLsaPrefix(),
                        faceUri, linkCost, timeout,
                        ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
-
-  ndn::Name broadcastKeyPrefix = DEFAULT_BROADCAST_PREFIX;
-  broadcastKeyPrefix.append("KEYS");
-  m_fib.registerPrefix(broadcastKeyPrefix,
-                       faceUri, linkCost, timeout,
-                       ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
 }
 
 void
@@ -553,8 +608,8 @@
 void
 Nlsr::scheduleDatasetFetch()
 {
-  NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval()
-             << " seconds");
+  NLSR_LOG_DEBUG("Scheduling Dataset Fetch in " << m_confParam.getFaceDatasetFetchInterval());
+
   m_scheduler.scheduleEvent(m_confParam.getFaceDatasetFetchInterval(),
     [this] {
       this->initializeFaces(
@@ -568,6 +623,35 @@
 }
 
 void
+Nlsr::enableIncomingFaceIdIndication()
+{
+  NLSR_LOG_DEBUG("Enabling incoming face id indication for local face.");
+
+  m_controller.start<ndn::nfd::FaceUpdateCommand>(
+    ndn::nfd::ControlParameters()
+      .setFlagBit(ndn::nfd::FaceFlagBit::BIT_LOCAL_FIELDS_ENABLED, true),
+    bind(&Nlsr::onFaceIdIndicationSuccess, this, _1),
+    bind(&Nlsr::onFaceIdIndicationFailure, this, _1));
+}
+
+void
+Nlsr::onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp)
+{
+  NLSR_LOG_DEBUG("Successfully enabled incoming face id indication"
+                 << "for face id " << cp.getFaceId());
+}
+
+void
+Nlsr::onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr)
+{
+  std::ostringstream os;
+  os << "Failed to enable incoming face id indication feature: " <<
+        "(code: " << cr.getCode() << ", reason: " << cr.getText() << ")";
+
+  NLSR_LOG_DEBUG(os.str());
+}
+
+void
 Nlsr::startEventLoop()
 {
   m_nlsrFace.processEvents();
diff --git a/src/nlsr.hpp b/src/nlsr.hpp
index c3ed420..f16e918 100644
--- a/src/nlsr.hpp
+++ b/src/nlsr.hpp
@@ -29,7 +29,6 @@
 #include "lsdb.hpp"
 #include "name-prefix-list.hpp"
 #include "test-access-control.hpp"
-#include "validator.hpp"
 #include "publisher/lsdb-dataset-interest-handler.hpp"
 #include "route/fib.hpp"
 #include "route/name-prefix-table.hpp"
@@ -46,7 +45,10 @@
 
 #include <ndn-cxx/face.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/security/certificate-cache-ttl.hpp>
+#include <ndn-cxx/security/validator-config.hpp>
+#include <ndn-cxx/security/v2/certificate-fetcher-direct-fetch.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <ndn-cxx/security/signing-info.hpp>
 #include <ndn-cxx/util/scheduler.hpp>
 #include <ndn-cxx/mgmt/nfd/face-event-notification.hpp>
 #include <ndn-cxx/mgmt/nfd/face-monitor.hpp>
@@ -54,6 +56,9 @@
 #include <ndn-cxx/mgmt/nfd/face-status.hpp>
 #include <ndn-cxx/data.hpp>
 #include <ndn-cxx/encoding/block.hpp>
+#include <ndn-cxx/encoding/nfd-constants.hpp>
+#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
+#include <ndn-cxx/mgmt/nfd/control-response.hpp>
 
 namespace nlsr {
 
@@ -84,14 +89,19 @@
   onRegistrationSuccess(const ndn::Name& name);
 
   void
-  onLocalhostRegistrationSuccess(const ndn::Name& name);
-
-  void
   setInfoInterestFilter();
 
   void
   setLsaInterestFilter();
 
+  /*! \brief Add top level prefixes for Dispatcher
+   *
+   * All dispatcher-related sub-prefixes *must* be registered before sub-prefixes
+   * must be added before adding top
+   */
+  void
+  addDispatcherTopPrefix(const ndn::Name& topPrefix);
+
   void
   startEventLoop();
 
@@ -275,6 +285,13 @@
   registerAdjacencyPrefixes(const Adjacent& adj,
                             const ndn::time::milliseconds& timeout);
 
+  /*! \brief Add a certificate NLSR claims to be authoritative for to the certificate store.
+   *
+   * \sa CertificateStore
+   */
+  void
+  loadCertToPublish(const ndn::security::v2::Certificate& certificate);
+
   void
   initializeKey();
 
@@ -285,22 +302,12 @@
     m_validator.load(section, filename);
   }
 
-  Validator&
+  ndn::security::ValidatorConfig&
   getValidator()
   {
     return m_validator;
   }
 
-  /*! \brief Add a certificate NLSR claims to be authoritative for to the certificate store.
-   *
-   * \sa CertificateStore
-   */
-  void
-  loadCertToPublish(std::shared_ptr<ndn::IdentityCertificate> certificate)
-  {
-    m_certStore.insert(certificate);
-  }
-
   /*! \brief Find a certificate
    *
    * Find a certificate that NLSR has. First it checks against the
@@ -309,20 +316,16 @@
    * checks the cache of certficates it has already fetched. If none
    * can be found, it will return an empty pointer.
    */
-  std::shared_ptr<const ndn::IdentityCertificate>
-  getCertificate(const ndn::Name& certificateNameWithoutVersion)
+  const ndn::security::v2::Certificate*
+  getCertificate(const ndn::Name& certificateKeyName)
   {
-    shared_ptr<const ndn::IdentityCertificate> cert =
-      m_certStore.find(certificateNameWithoutVersion);
+    const ndn::security::v2::Certificate* cert =
+      m_certStore.find(certificateKeyName);
 
-    if (cert != nullptr) {
-      return cert;
-    }
-
-    return m_certificateCache->getCertificate(certificateNameWithoutVersion);
+    return cert;
   }
 
-  ndn::KeyChain&
+  ndn::security::v2::KeyChain&
   getKeyChain()
   {
     return m_keyChain;
@@ -334,6 +337,12 @@
     return m_defaultCertName;
   }
 
+  const ndn::security::SigningInfo&
+  getSigningInfo()
+  {
+    return m_signingInfo;
+  }
+
   update::PrefixUpdateProcessor&
   getPrefixUpdateProcessor()
   {
@@ -397,13 +406,6 @@
   }
 
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  void
-  addCertificateToCache(std::shared_ptr<ndn::IdentityCertificate> certificate)
-  {
-    if (certificate != nullptr) {
-      m_certificateCache->insertCertificate(certificate);
-    }
-  }
 
   security::CertificateStore&
   getCertificateStore()
@@ -457,13 +459,29 @@
   void
   scheduleDatasetFetch();
 
+  /*! \brief Enables NextHopFaceId indication in NFD for incoming data packet.
+   *
+   * After enabling, when NFD gets a data packet, it will put the incoming face id
+   * of the data in NextHopFaceId field of the packet. The NextHopFaceId will be used
+   * by DirectFetcher to fetch the certificates needed to validate the data packet.
+   * \sa https://redmine.named-data.net/projects/nfd/wiki/NDNLPv2#Consumer-Controlled-Forwarding
+   */
+  void
+  enableIncomingFaceIdIndication();
+
+  void
+  onFaceIdIndicationSuccess(const ndn::nfd::ControlParameters& cp);
+
+  void
+  onFaceIdIndicationFailure(const ndn::nfd::ControlResponse& cr);
+
 public:
   static const ndn::Name LOCALHOST_PREFIX;
 
 private:
   ndn::Face& m_nlsrFace;
   ndn::Scheduler& m_scheduler;
-  ndn::KeyChain& m_keyChain;
+  ndn::security::v2::KeyChain& m_keyChain;
   ConfParameter m_confParam;
   AdjacencyList m_adjacencyList;
   NamePrefixList m_namePrefixList;
@@ -486,20 +504,14 @@
 PUBLIC_WITH_TESTS_ELSE_PRIVATE:
   HelloProtocol m_helloProtocol;
 
+  ndn::security::ValidatorConfig m_validator;
+
 private:
-  /*! \brief Where NLSR caches certificates it has fetched to validate
-   * Data signatures.
-   */
-  std::shared_ptr<ndn::CertificateCacheTtl> m_certificateCache;
   /*! \brief Where NLSR stores certificates it claims to be
    * authoritative for. Usually the router certificate.
    */
   security::CertificateStore m_certStore;
 
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  Validator m_validator;
-
-private:
   ndn::nfd::Controller m_controller;
   ndn::nfd::Controller m_faceDatasetController;
   ndn::security::SigningInfo m_signingInfo;
diff --git a/src/publisher/segment-publisher.hpp b/src/publisher/segment-publisher.hpp
index 59c44b4..2938980 100644
--- a/src/publisher/segment-publisher.hpp
+++ b/src/publisher/segment-publisher.hpp
@@ -40,9 +40,11 @@
 public:
   SegmentPublisher(FaceBase& face,
                    ndn::KeyChain& keyChain,
+                   const ndn::security::SigningInfo& signingInfo,
                    const ndn::time::milliseconds& freshnessPeriod = getDefaultFreshness())
     : m_face(face)
     , m_keyChain(keyChain)
+    , m_signingInfo(signingInfo)
     , m_freshnessPeriod(freshnessPeriod)
   {
   }
@@ -75,8 +77,7 @@
    * final block ID set to a timestamp.
    */
   void
-  publish(const ndn::Name& prefix,
-          const ndn::security::SigningInfo& signingInfo = ndn::security::KeyChain::DEFAULT_SIGNING_INFO)
+  publish(const ndn::Name& prefix)
   {
     ndn::EncodingBuffer buffer;
     generate(buffer);
@@ -107,7 +108,7 @@
         data->setFinalBlockId(segmentName[-1]);
       }
 
-      publishSegment(data, signingInfo);
+      publishSegment(data);
       ++segmentNo;
     } while (segmentBegin < end);
   }
@@ -122,15 +123,16 @@
   /*! \brief Helper function to sign and put data on a Face.
    */
   void
-  publishSegment(std::shared_ptr<ndn::Data>& data, const ndn::security::SigningInfo& signingInfo)
+  publishSegment(std::shared_ptr<ndn::Data>& data)
   {
-    m_keyChain.sign(*data, signingInfo);
+    m_keyChain.sign(*data, m_signingInfo);
     m_face.put(*data);
   }
 
 private:
   FaceBase& m_face;
   ndn::KeyChain& m_keyChain;
+  const ndn::security::SigningInfo& m_signingInfo;
   const ndn::time::milliseconds m_freshnessPeriod;
 };
 
diff --git a/src/route/fib.cpp b/src/route/fib.cpp
index d8a9909..c2ba20d 100644
--- a/src/route/fib.cpp
+++ b/src/route/fib.cpp
@@ -67,7 +67,7 @@
 
     if (isPrefixUpdatable(name)) {
       // Add nexthop to NDN-FIB
-      registerPrefix(name, ndn::util::FaceUri(it->getConnectingFaceUri()),
+      registerPrefix(name, ndn::FaceUri(it->getConnectingFaceUri()),
                      it->getRouteCostAsAdjustedInteger(),
                      ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
                      ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
@@ -196,12 +196,12 @@
 }
 
 void
-Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::util::FaceUri& faceUri,
+Fib::registerPrefix(const ndn::Name& namePrefix, const ndn::FaceUri& faceUri,
                     uint64_t faceCost,
                     const ndn::time::milliseconds& timeout,
                     uint64_t flags, uint8_t times)
 {
-  uint64_t faceId = m_adjacencyList.getFaceId(ndn::util::FaceUri(faceUri));
+  uint64_t faceId = m_adjacencyList.getFaceId(ndn::FaceUri(faceUri));
 
   if (faceId != 0) {
     ndn::nfd::ControlParameters faceParameters;
@@ -231,7 +231,7 @@
 
 void
 Fib::onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
-                           const std::string& message, const ndn::util::FaceUri& faceUri)
+                           const std::string& message, const ndn::FaceUri& faceUri)
 {
   NLSR_LOG_DEBUG(message << ": " << commandSuccessResult.getName() <<
              " Face Uri: " << faceUri << " faceId: " << commandSuccessResult.getFaceId());
@@ -250,7 +250,7 @@
 Fib::onRegistrationFailure(const ndn::nfd::ControlResponse& response,
                            const std::string& message,
                            const ndn::nfd::ControlParameters& parameters,
-                           const ndn::util::FaceUri& faceUri,
+                           const ndn::FaceUri& faceUri,
                            uint8_t times)
 {
   NLSR_LOG_DEBUG(message << ": " << response.getText() << " (code: " << response.getCode() << ")");
@@ -385,7 +385,7 @@
 
   for (const NextHop& hop : entry) {
     registerPrefix(entry.getName(),
-                   ndn::util::FaceUri(hop.getConnectingFaceUri()),
+                   ndn::FaceUri(hop.getConnectingFaceUri()),
                    hop.getRouteCostAsAdjustedInteger(),
                    ndn::time::seconds(m_refreshTime + GRACE_PERIOD),
                    ndn::nfd::ROUTE_FLAG_CAPTURE, 0);
diff --git a/src/route/fib.hpp b/src/route/fib.hpp
index 8cf7aa4..56b53a1 100644
--- a/src/route/fib.hpp
+++ b/src/route/fib.hpp
@@ -55,7 +55,7 @@
 {
 public:
   Fib(ndn::Face& face, ndn::Scheduler& scheduler, AdjacencyList& adjacencyList, ConfParameter& conf,
-      ndn::KeyChain& keyChain)
+      ndn::security::v2::KeyChain& keyChain)
     : m_scheduler(scheduler)
     , m_refreshTime(0)
     , m_controller(face, keyChain)
@@ -131,7 +131,7 @@
    */
   void
   registerPrefix(const ndn::Name& namePrefix,
-                 const ndn::util::FaceUri& faceUri,
+                 const ndn::FaceUri& faceUri,
                  uint64_t faceCost,
                  const ndn::time::milliseconds& timeout,
                  uint64_t flags,
@@ -173,7 +173,7 @@
    */
   void
   onRegistrationSuccess(const ndn::nfd::ControlParameters& commandSuccessResult,
-                        const std::string& message, const ndn::util::FaceUri& faceUri);
+                        const std::string& message, const ndn::FaceUri& faceUri);
 
   /*! \brief Retry a prefix (next-hop) registration up to three (3) times.
    */
@@ -181,7 +181,7 @@
   onRegistrationFailure(const ndn::nfd::ControlResponse& response,
                         const std::string& message,
                         const ndn::nfd::ControlParameters& parameters,
-                        const ndn::util::FaceUri& faceUri,
+                        const ndn::FaceUri& faceUri,
                         uint8_t times);
 
   /*! \brief Log a successful unregistration.
diff --git a/src/security/certificate-store.hpp b/src/security/certificate-store.hpp
index 4b84df6..0445318 100644
--- a/src/security/certificate-store.hpp
+++ b/src/security/certificate-store.hpp
@@ -26,7 +26,7 @@
 #include "../test-access-control.hpp"
 
 #include <ndn-cxx/interest.hpp>
-#include <ndn-cxx/security/v1/identity-certificate.hpp>
+#include <ndn-cxx/security/v2/certificate.hpp>
 
 namespace nlsr {
 namespace security {
@@ -42,21 +42,18 @@
 {
 public:
   void
-  insert(std::shared_ptr<ndn::IdentityCertificate> certificate)
+  insert(const ndn::security::v2::Certificate& certificate)
   {
-    if (certificate != nullptr) {
-      // Key is cert name without version
-      m_certificates[certificate->getName().getPrefix(-1)] = certificate;
-    }
+    m_certificates[certificate.getKeyName()] = certificate;
   }
 
-  std::shared_ptr<const ndn::IdentityCertificate>
-  find(const ndn::Name& certificateNameWithoutVersion) const
+  const ndn::security::v2::Certificate*
+  find(const ndn::Name keyName)
   {
-    CertMap::const_iterator it = m_certificates.find(certificateNameWithoutVersion);
+    CertMap::iterator it = m_certificates.find(keyName);
 
     if (it != m_certificates.end()) {
-      return it->second;
+      return &it->second;
     }
 
     return nullptr;
@@ -70,7 +67,7 @@
   }
 
 private:
-  typedef std::map<ndn::Name, std::shared_ptr<ndn::IdentityCertificate>> CertMap;
+  typedef std::map<ndn::Name, ndn::security::v2::Certificate> CertMap;
   CertMap m_certificates;
 };
 
diff --git a/src/tlv/coordinate-lsa.cpp b/src/tlv/coordinate-lsa.cpp
index 92809fe..02509a0 100644
--- a/src/tlv/coordinate-lsa.cpp
+++ b/src/tlv/coordinate-lsa.cpp
@@ -21,10 +21,12 @@
 
 #include "coordinate-lsa.hpp"
 #include "tlv-nlsr.hpp"
+#include "logger.hpp"
 
 #include <ndn-cxx/util/concepts.hpp>
 #include <ndn-cxx/encoding/block-helpers.hpp>
-#include "logger.hpp"
+
+#include <iostream>
 
 namespace nlsr {
 namespace tlv {
diff --git a/src/update/manager-base.cpp b/src/update/manager-base.cpp
index 5a1034c..a93aaba 100644
--- a/src/update/manager-base.cpp
+++ b/src/update/manager-base.cpp
@@ -55,7 +55,7 @@
                                              const ndn::Interest& interest,
                                              const ndn::mgmt::ControlParameters& parameters,
                                              const ndn::mgmt::CommandContinuation& done)
-    {
+{
   const ndn::nfd::ControlParameters& castParams =
     static_cast<const ndn::nfd::ControlParameters&>(parameters);
 
diff --git a/src/update/manager-base.hpp b/src/update/manager-base.hpp
index 33df589..0dddbd6 100644
--- a/src/update/manager-base.hpp
+++ b/src/update/manager-base.hpp
@@ -103,9 +103,9 @@
 {
 public:
   CommandManagerBase(ndn::mgmt::Dispatcher& m_dispatcher,
-                      NamePrefixList& m_namePrefixList,
-                      Lsdb& lsdb,
-                      const std::string& module);
+                     NamePrefixList& m_namePrefixList,
+                     Lsdb& lsdb,
+                     const std::string& module);
 
   /*! \brief add desired name prefix to the advertised name prefix list
    *         or insert a prefix into the FIB if parameters is valid.
diff --git a/src/update/prefix-update-processor.cpp b/src/update/prefix-update-processor.cpp
index 4ad75dd..478380f 100644
--- a/src/update/prefix-update-processor.cpp
+++ b/src/update/prefix-update-processor.cpp
@@ -24,7 +24,7 @@
 #include "nlsr.hpp"
 #include <ndn-cxx/mgmt/nfd/control-response.hpp>
 #include <ndn-cxx/tag.hpp>
-#include <ndn-cxx/util/io.hpp>
+#include <ndn-cxx/face.hpp>
 
 namespace nlsr {
 namespace update {
@@ -52,13 +52,10 @@
 PrefixUpdateProcessor::PrefixUpdateProcessor(ndn::mgmt::Dispatcher& dispatcher,
                                              ndn::Face& face,
                                              NamePrefixList& namePrefixList,
-                                             Lsdb& lsdb,
-                                             const ndn::Name broadcastPrefix,
-                                             ndn::KeyChain& keyChain,
-                                             std::shared_ptr<ndn::CertificateCacheTtl> certificateCache,
-                                             security::CertificateStore& certStore)
+                                             Lsdb& lsdb)
   : CommandManagerBase(dispatcher, namePrefixList, lsdb, "prefix-update")
-  , m_validator(face, broadcastPrefix, certificateCache, certStore)
+
+  , m_validator(ndn::make_unique<ndn::security::v2::CertificateFetcherDirectFetch>(face))
 {
   NLSR_LOG_DEBUG("Setting dispatcher to capture Interests for: "
     << ndn::Name(Nlsr::LOCALHOST_PREFIX).append("prefix-update"));
@@ -84,17 +81,16 @@
               const ndn::mgmt::AcceptContinuation& accept,
               const ndn::mgmt::RejectContinuation& reject) {
     m_validator.validate(interest,
-      [accept] (const std::shared_ptr<const ndn::Interest>& request) {
+      [accept] (const ndn::Interest& request) {
 
-        auto signer1 = getSignerFromTag(*request);
+        auto signer1 = getSignerFromTag(request);
         std::string signer = signer1.value_or("*");
-        NLSR_LOG_DEBUG("accept " << request->getName() << " signer=" << signer);
+        NLSR_LOG_DEBUG("accept " << request.getName() << " signer=" << signer);
         accept(signer);
       },
-      [reject] (const std::shared_ptr<const ndn::Interest>& request,
-                const std::string& failureInfo) {
-        NLSR_LOG_DEBUG("reject " << request->getName() << " signer=" <<
-                      getSignerFromTag(*request).value_or("?") << ' ' << failureInfo);
+      [reject] (const ndn::Interest& request, const ndn::security::v2::ValidationError& error) {
+        NLSR_LOG_DEBUG("reject " << request.getName() << " signer=" <<
+                        getSignerFromTag(request).value_or("?") << ' ' << error);
         reject(ndn::mgmt::RejectReply::STATUS403);
       });
   };
diff --git a/src/update/prefix-update-processor.hpp b/src/update/prefix-update-processor.hpp
index 52780e6..a602497 100644
--- a/src/update/prefix-update-processor.hpp
+++ b/src/update/prefix-update-processor.hpp
@@ -25,11 +25,11 @@
 #include "manager-base.hpp"
 #include "prefix-update-commands.hpp"
 #include "test-access-control.hpp"
-#include "validator.hpp"
 
-#include <ndn-cxx/security/certificate-cache-ttl.hpp>
+#include <ndn-cxx/util/io.hpp>
 #include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/security/v2/validator.hpp>
+#include <ndn-cxx/security/v2/certificate-storage.hpp>
+#include <ndn-cxx/util/io.hpp>
 
 #include <boost/property_tree/ptree.hpp>
 #include <memory>
@@ -50,11 +50,7 @@
   PrefixUpdateProcessor(ndn::mgmt::Dispatcher& dispatcher,
                         ndn::Face& face,
                         NamePrefixList& namePrefixList,
-                        Lsdb& lsdb,
-                        const ndn::Name broadcastPrefix,
-                        ndn::KeyChain& keyChain,
-                        std::shared_ptr<ndn::CertificateCacheTtl> certificateCache,
-                        security::CertificateStore& certStore);
+                        Lsdb& lsdb);
 
   /*! \brief Load the validator's configuration from a section of a
    * configuration file.
@@ -70,8 +66,7 @@
   void
   loadValidator(ConfigSection section, const std::string& filename);
 
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  Validator&
+  ndn::security::ValidatorConfig&
   getValidator()
   {
     return m_validator;
@@ -88,7 +83,7 @@
   makeAuthorization();
 
 private:
-  Validator m_validator;
+  ndn::security::ValidatorConfig m_validator;
 };
 
 } // namespace update
diff --git a/src/validator.cpp b/src/validator.cpp
deleted file mode 100644
index a73c9ee..0000000
--- a/src/validator.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  The University of Memphis,
- *                           Regents of the University of California
- *
- * This file is part of NLSR (Named-data Link State Routing).
- * See AUTHORS.md for complete list of NLSR authors and contributors.
- *
- * NLSR 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.
- *
- * NLSR 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
- * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "validator.hpp"
-
-namespace nlsr {
-
-void
-Validator::checkPolicy(const ndn::Data& data, int nSteps, const ndn::OnDataValidated& onValidated,
-                       const ndn::OnDataValidationFailed& onValidationFailed,
-                       std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps)
-{
-  if (!m_shouldValidate) {
-    onValidated(data.shared_from_this());
-  }
-  else {
-    ValidatorConfig::checkPolicy(data, nSteps, onValidated, onValidationFailed, nextSteps);
-  }
-}
-
-void
-Validator::afterCheckPolicy(const NextSteps& nextSteps, const OnFailure& onFailure)
-{
-  if (m_face == nullptr) {
-    onFailure("Require more information to validate the packet!");
-    return;
-  }
-
-  for (const std::shared_ptr<ndn::ValidationRequest>& request : nextSteps) {
-
-    ndn::Interest& interest = request->m_interest;
-
-    // Look for certificate in permanent storage
-    std::shared_ptr<const ndn::IdentityCertificate> cert = m_certStore.find(interest.getName());
-
-    if (cert != nullptr) {
-      // If the certificate is found, no reason to express interest
-      std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(interest.getName());
-      data->setContent(cert->wireEncode());
-
-      Validator::onData(interest, *data, request);
-    }
-    else {
-      // Prepend broadcast prefix to interest name
-      ndn::Name broadcastName = m_broadcastPrefix;
-      broadcastName.append(interest.getName());
-      interest.setName(broadcastName);
-
-      // Attempt to fetch the certificate
-      m_face->expressInterest(interest,
-                              std::bind(&Validator::onData, this, _1, _2, request),
-                              std::bind(&Validator::onTimeout, // Nack
-                                        this, _1, request->m_nRetries,
-                                        onFailure,
-                                        request),
-                              std::bind(&Validator::onTimeout,
-                                        this, _1, request->m_nRetries,
-                                        onFailure,
-                                        request));
-    }
-  }
-}
-
-std::shared_ptr<const ndn::Data>
-Validator::preCertificateValidation(const ndn::Data& data)
-{
-  std::shared_ptr<ndn::Data> internalData = std::make_shared<ndn::Data>();
-  internalData->wireDecode(data.getContent().blockFromValue());
-  return internalData;
-}
-
-} // namespace nlsr
diff --git a/src/validator.hpp b/src/validator.hpp
deleted file mode 100644
index c4f2a19..0000000
--- a/src/validator.hpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2017,  The University of Memphis,
- *                           Regents of the University of California,
- *                           Arizona Board of Regents.
- *
- * This file is part of NLSR (Named-data Link State Routing).
- * See AUTHORS.md for complete list of NLSR authors and contributors.
- *
- * NLSR 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.
- *
- * NLSR 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
- * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifndef NLSR_VALIDATOR_HPP
-#define NLSR_VALIDATOR_HPP
-
-#include "common.hpp"
-#include "security/certificate-store.hpp"
-
-#include <ndn-cxx/security/validator-config.hpp>
-
-namespace nlsr {
-
-class Validator : public ndn::ValidatorConfig
-{
-public:
-  class Error : public ndn::ValidatorConfig::Error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : ndn::ValidatorConfig::Error(what)
-    {
-    }
-  };
-
-  explicit
-  Validator(ndn::Face& face,
-            const ndn::Name broadcastPrefix,
-            const std::shared_ptr<ndn::CertificateCache>& cache,
-            security::CertificateStore& certStore,
-            const int stepLimit = 10)
-    : ndn::ValidatorConfig(face, cache, ndn::ValidatorConfig::DEFAULT_GRACE_INTERVAL, stepLimit)
-    , m_shouldValidate(true)
-    , m_broadcastPrefix(broadcastPrefix)
-    , m_certStore(certStore)
-  {
-    m_broadcastPrefix.append("KEYS");
-  }
-
-  virtual
-  ~Validator()
-  {
-  }
-
-  const ndn::Name&
-  getBroadcastPrefix()
-  {
-    return m_broadcastPrefix;
-  }
-
-  void
-  setBroadcastPrefix(const ndn::Name& broadcastPrefix)
-  {
-    m_broadcastPrefix = broadcastPrefix;
-  }
-
-protected:
-  typedef std::vector<std::shared_ptr<ndn::ValidationRequest>> NextSteps;
-
-  void
-  checkPolicy(const ndn::Data& data,
-              int nSteps,
-              const ndn::OnDataValidated& onValidated,
-              const ndn::OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ndn::ValidationRequest>>& nextSteps) override;
-
-  void
-  afterCheckPolicy(const NextSteps& nextSteps,
-                   const OnFailure& onFailure) override;
-
-  std::shared_ptr<const ndn::Data>
-  preCertificateValidation(const ndn::Data& data) override;
-
-PUBLIC_WITH_TESTS_ELSE_PRIVATE:
-  bool m_shouldValidate;
-
-private:
-  ndn::Name m_broadcastPrefix;
-  security::CertificateStore& m_certStore;
-};
-
-} // namespace nlsr
-
-#endif // NLSR_VALIDATOR_HPP