build: reanimate the dead

Fix build with ndn-cxx 0.7.1 and ChronoSync 0.5.3

* Adapt to new API
* Upgrade to Qt5
* Several other bugs

Refs: #4563, #4087
Change-Id: Ic55d687caade08f557f9b9ec3e9569bc96798710
diff --git a/src/browse-contact-dialog.cpp b/src/browse-contact-dialog.cpp
index 481b418..bf9df24 100644
--- a/src/browse-contact-dialog.cpp
+++ b/src/browse-contact-dialog.cpp
@@ -19,7 +19,7 @@
 
 namespace chronochat {
 
-using ndn::IdentityCertificate;
+using ndn::security::Certificate;
 
 BrowseContactDialog::BrowseContactDialog(QWidget *parent)
   : QDialog(parent)
@@ -106,7 +106,7 @@
 }
 
 void
-BrowseContactDialog::onIdCertReady(const IdentityCertificate& idCert)
+BrowseContactDialog::onIdCertReady(const Certificate& idCert)
 {
   Profile profile(idCert);
 
diff --git a/src/browse-contact-dialog.hpp b/src/browse-contact-dialog.hpp
index a087538..4a081e0 100644
--- a/src/browse-contact-dialog.hpp
+++ b/src/browse-contact-dialog.hpp
@@ -17,7 +17,7 @@
 #include <QTableWidgetItem>
 
 #ifndef Q_MOC_RUN
-#include <ndn-cxx/security/identity-certificate.hpp>
+#include <ndn-cxx/security/certificate.hpp>
 #include <boost/thread/locks.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #endif
@@ -61,7 +61,7 @@
   onNameListReady(const QStringList& nameList);
 
   void
-  onIdCertReady(const ndn::IdentityCertificate& idCert);
+  onIdCertReady(const ndn::security::Certificate & idCert);
 
 signals:
   void
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
index 67305f2..234e4a3 100644
--- a/src/chat-dialog-backend.cpp
+++ b/src/chat-dialog-backend.cpp
@@ -16,12 +16,10 @@
 #ifndef Q_MOC_RUN
 #include <boost/iostreams/stream.hpp>
 #include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/security/validator-regex.hpp>
-#include "logging.h"
+#include "cryptopp.hpp"
 #endif
 
-
-INIT_LOGGER("ChatDialogBackend");
+using namespace CryptoPP;
 
 namespace chronochat {
 
@@ -117,26 +115,8 @@
   m_scheduler = unique_ptr<ndn::Scheduler>(new ndn::Scheduler(m_face->getIoService()));
 
   // initialize validator
-  shared_ptr<ndn::IdentityCertificate> anchor = loadTrustAnchor();
-
-  if (static_cast<bool>(anchor)) {
-    shared_ptr<ndn::ValidatorRegex> validator =
-      make_shared<ndn::ValidatorRegex>(m_face.get()); // TODO: Change to Face*
-    validator->addDataVerificationRule(
-      make_shared<ndn::SecRuleRelative>("^<>*<%F0.>(<>*)$",
-                                        "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                        ">", "\\1", "\\1\\2", true));
-    validator->addDataVerificationRule(
-      make_shared<ndn::SecRuleRelative>("(<>*)$",
-                                        "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                        ">", "\\1", "\\1\\2", true));
-    validator->addTrustAnchor(anchor);
-
-    m_validator = validator;
-  }
-  else
-    m_validator = shared_ptr<ndn::Validator>();
-
+  m_validator = make_shared<ndn::security::ValidatorConfig>(*m_face);
+  m_validator->load("security/validation-chat.conf");
 
   // create a new SyncSocket
   m_sock = make_shared<chronosync::Socket>(m_chatroomPrefix,
@@ -147,12 +127,12 @@
                                            m_validator);
 
   // schedule a new join event
-  m_scheduler->scheduleEvent(time::milliseconds(600),
-                             bind(&ChatDialogBackend::sendJoin, this));
+  m_scheduler->schedule(time::milliseconds(600),
+                        bind(&ChatDialogBackend::sendJoin, this));
 
   // cancel existing hello event if it exists
-  if (m_helloEventId != nullptr) {
-    m_scheduler->cancelEvent(m_helloEventId);
+  if (m_helloEventId) {
+    m_helloEventId.cancel();
     m_helloEventId.reset();
   }
 }
@@ -178,19 +158,6 @@
   QIODevice& m_source;
 };
 
-shared_ptr<ndn::IdentityCertificate>
-ChatDialogBackend::loadTrustAnchor()
-{
-  QFile anchorFile(":/security/anchor.cert");
-
-  if (!anchorFile.open(QIODevice::ReadOnly)) {
-    return {};
-  }
-
-  boost::iostreams::stream<IoDeviceSource> anchorFileStream(anchorFile);
-  return ndn::io::load<ndn::IdentityCertificate>(anchorFileStream);
-}
-
 void
 ChatDialogBackend::exitChatroom() {
   if (m_joined)
@@ -212,8 +179,6 @@
 void
 ChatDialogBackend::processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
 {
-  _LOG_DEBUG("<<< processing Tree Update");
-
   if (updates.empty()) {
     return;
   }
@@ -232,27 +197,18 @@
     if (updates[i].high - updates[i].low < 3) {
       for (chronosync::SeqNo seq = updates[i].low; seq <= updates[i].high; ++seq) {
         m_sock->fetchData(updates[i].session, seq,
-                          [this] (const shared_ptr<const ndn::Data>& data) {
-                            this->processChatData(data, true, true);
-                          },
-                          [this] (const shared_ptr<const ndn::Data>& data, const std::string& msg) {
-                            this->processChatData(data, true, false);
-                          },
-                          ndn::OnTimeout(),
+                          bind(&ChatDialogBackend::processChatData, this, _1, true, true),
+                          bind(&ChatDialogBackend::processChatData, this, _1, true, false),
+                          [] (const ndn::Interest& interest) {},
                           2);
-        _LOG_DEBUG("<<< Fetching " << updates[i].session << "/" << seq);
       }
     }
     else {
       // There are too many msgs to fetch, let's just fetch the latest one
       m_sock->fetchData(updates[i].session, updates[i].high,
-                        [this] (const shared_ptr<const ndn::Data>& data) {
-                          this->processChatData(data, false, true);
-                        },
-                        [this] (const shared_ptr<const ndn::Data>& data, const std::string& msg) {
-                          this->processChatData(data, false, false);
-                        },
-                        ndn::OnTimeout(),
+                        bind(&ChatDialogBackend::processChatData, this, _1, true, true),
+                        bind(&ChatDialogBackend::processChatData, this, _1, true, false),
+                        [] (const ndn::Interest& interest) {},
                         2);
     }
 
@@ -264,25 +220,23 @@
 }
 
 void
-ChatDialogBackend::processChatData(const ndn::shared_ptr<const ndn::Data>& data,
+ChatDialogBackend::processChatData(const ndn::Data& data,
                                    bool needDisplay,
                                    bool isValidated)
 {
   ChatMessage msg;
 
   try {
-    msg.wireDecode(data->getContent().blockFromValue());
+    msg.wireDecode(data.getContent().blockFromValue());
   }
-  catch (tlv::Error) {
-    _LOG_DEBUG("Errrrr.. Can not parse msg with name: " <<
-               data->getName() << ". what is happening?");
+  catch (tlv::Error&) {
     // nasty stuff: as a remedy, we'll form some standard msg for inparsable msgs
     msg.setNick("inconnu");
     msg.setMsgType(ChatMessage::OTHER);
     return;
   }
 
-  Name remoteSessionPrefix = data->getName().getPrefix(-1);
+  Name remoteSessionPrefix = data.getName().getPrefix(-1);
 
   if (msg.getMsgType() == ChatMessage::LEAVE) {
     BackendRoster::iterator it = m_roster.find(remoteSessionPrefix);
@@ -290,7 +244,7 @@
     if (it != m_roster.end()) {
       // cancel timeout event
       if (static_cast<bool>(it->second.timeoutEventId))
-        m_scheduler->cancelEvent(it->second.timeoutEventId);
+        it->second.timeoutEventId.cancel();
 
       // notify frontend to remove the remote session (node)
       emit sessionRemoved(QString::fromStdString(remoteSessionPrefix.toUri()),
@@ -312,17 +266,17 @@
       BOOST_ASSERT(false);
     }
 
-    uint64_t seqNo = data->getName().get(-1).toNumber();
+    uint64_t seqNo = data.getName().get(-1).toNumber();
 
     // If a timeout event has been scheduled, cancel it.
     if (static_cast<bool>(it->second.timeoutEventId))
-      m_scheduler->cancelEvent(it->second.timeoutEventId);
+      it->second.timeoutEventId.cancel();
 
     // (Re)schedule another timeout event after 3 HELLO_INTERVAL;
     it->second.timeoutEventId =
-      m_scheduler->scheduleEvent(HELLO_INTERVAL * 3,
-                                 bind(&ChatDialogBackend::remoteSessionTimeout,
-                                      this, remoteSessionPrefix));
+      m_scheduler->schedule(HELLO_INTERVAL * 3,
+                            bind(&ChatDialogBackend::remoteSessionTimeout,
+                                 this, remoteSessionPrefix));
 
     // If chat message, notify the frontend
     if (msg.getMsgType() == ChatMessage::CHAT) {
@@ -414,8 +368,8 @@
   prepareControlMessage(msg, ChatMessage::JOIN);
   sendMsg(msg);
 
-  m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
-                                              bind(&ChatDialogBackend::sendHello, this));
+  m_helloEventId = m_scheduler->schedule(HELLO_INTERVAL,
+                                         bind(&ChatDialogBackend::sendHello, this));
   emit newChatroomForDiscovery(Name::Component(m_chatroomName));
 }
 
@@ -426,8 +380,8 @@
   prepareControlMessage(msg, ChatMessage::HELLO);
   sendMsg(msg);
 
-  m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
-                                              bind(&ChatDialogBackend::sendHello, this));
+  m_helloEventId = m_scheduler->schedule(HELLO_INTERVAL,
+                                         bind(&ChatDialogBackend::sendHello, this));
 }
 
 void
@@ -489,7 +443,7 @@
 {
   std::stringstream os;
 
-  CryptoPP::StringSource(digest->buf(), digest->size(), true,
+  CryptoPP::StringSource(digest->data(), digest->size(), true,
                          new CryptoPP::HexEncoder(new CryptoPP::FileSink(os), false));
   return os.str();
 }
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
index ae7b3da..e9543bb 100644
--- a/src/chat-dialog-backend.hpp
+++ b/src/chat-dialog-backend.hpp
@@ -18,8 +18,9 @@
 #include "chatroom-info.hpp"
 #include "chat-message.hpp"
 #include <mutex>
-#include <socket.hpp>
+#include <ChronoSync/socket.hpp>
 #include <boost/thread.hpp>
+#include <ndn-cxx/security/validator-config.hpp>
 #endif
 
 namespace chronochat {
@@ -35,7 +36,7 @@
   ndn::Name sessionPrefix;
   bool hasNick;
   std::string userNick;
-  ndn::EventId timeoutEventId;
+  ndn::scheduler::EventId timeoutEventId;
 };
 
 class ChatDialogBackend : public QThread
@@ -61,9 +62,6 @@
   void
   initializeSync();
 
-  shared_ptr<ndn::IdentityCertificate>
-  loadTrustAnchor();
-
   void
   exitChatroom();
 
@@ -74,7 +72,7 @@
   processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
 
   void
-  processChatData(const ndn::shared_ptr<const ndn::Data>& data,
+  processChatData(const ndn::Data& data,
                   bool needDisplay,
                   bool isValidated);
 
@@ -160,24 +158,24 @@
   bool m_isNfdConnected;
   shared_ptr<ndn::Face> m_face;
 
-  Name m_localRoutingPrefix;             // routable local prefix
-  Name m_chatroomPrefix;                 // chatroom sync prefix
-  Name m_userChatPrefix;                 // user chat prefix
-  Name m_routableUserChatPrefix;         // routable user chat prefix
+  Name m_localRoutingPrefix;                                    // routable local prefix
+  Name m_chatroomPrefix;                                        // chatroom sync prefix
+  Name m_userChatPrefix;                                        // user chat prefix
+  Name m_routableUserChatPrefix;                                // routable user chat prefix
 
-  std::string m_chatroomName;            // chatroom name
-  std::string m_nick;                    // user nick
+  std::string m_chatroomName;                                   // chatroom name
+  std::string m_nick;                                           // user nick
 
-  Name m_signingId;                      // signing identity
-  shared_ptr<ndn::Validator> m_validator;// validator
-  shared_ptr<chronosync::Socket> m_sock; // SyncSocket
+  Name m_signingId;                                             // signing identity
+  shared_ptr<ndn::security::ValidatorConfig> m_validator;       // validator
+  shared_ptr<chronosync::Socket> m_sock;                        // SyncSocket
 
-  unique_ptr<ndn::Scheduler> m_scheduler;// scheduler
-  ndn::EventId m_helloEventId;           // event id of timeout
+  unique_ptr<ndn::Scheduler> m_scheduler;                       // scheduler
+  ndn::scheduler::EventId m_helloEventId;                       // event id of timeout
 
-  bool m_joined;                         // true if in a chatroom
+  bool m_joined;                                                // true if in a chatroom
 
-  BackendRoster m_roster;                // User roster
+  BackendRoster m_roster;                                       // User roster
 
   std::mutex m_resumeMutex;
   std::mutex m_nfdConnectionMutex;
diff --git a/src/chat-message.cpp b/src/chat-message.cpp
index 21707d2..7932321 100644
--- a/src/chat-message.cpp
+++ b/src/chat-message.cpp
@@ -23,7 +23,7 @@
   this->wireDecode(chatMsgWire);
 }
 
-template<bool T>
+template<ndn::encoding::Tag T>
 size_t
 ChatMessage::wireEncode(ndn::EncodingImpl<T>& encoder) const
 {
diff --git a/src/chat-message.hpp b/src/chat-message.hpp
index 860ce9f..778f505 100644
--- a/src/chat-message.hpp
+++ b/src/chat-message.hpp
@@ -86,7 +86,7 @@
   setTimestamp(const time_t timestamp);
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& encoder) const;
 
diff --git a/src/chatroom-discovery-backend.cpp b/src/chatroom-discovery-backend.cpp
index 371a119..67dd7fa 100644
--- a/src/chatroom-discovery-backend.cpp
+++ b/src/chatroom-discovery-backend.cpp
@@ -113,11 +113,11 @@
                                                 this, _1));
 
   // add an timer to refresh front end
-  if (m_refreshPanelId != nullptr) {
-    m_scheduler->cancelEvent(m_refreshPanelId);
+  if (m_refreshPanelId) {
+    m_refreshPanelId.cancel();
   }
-  m_refreshPanelId = m_scheduler->scheduleEvent(REFRESH_INTERVAL,
-                                                [this] { sendChatroomList(); });
+  m_refreshPanelId = m_scheduler->schedule(REFRESH_INTERVAL,
+                                           [this] { sendChatroomList(); });
 }
 
 void
@@ -142,10 +142,10 @@
 }
 
 void
-ChatroomDiscoveryBackend::processChatroomData(const ndn::shared_ptr<const ndn::Data>& data)
+ChatroomDiscoveryBackend::processChatroomData(const ndn::Data& data)
 {
   // extract chatroom name by get(-3)
-  Name::Component chatroomName = data->getName().get(-3);
+  Name::Component chatroomName = data.getName().get(-3);
   auto it = m_chatroomList.find(chatroomName);
   if (it == m_chatroomList.end()) {
     m_chatroomList[chatroomName].chatroomName = chatroomName.toUri();
@@ -163,16 +163,15 @@
     }
     else {
       it->second.count = 0;
-      if (m_routableUserDiscoveryPrefix < data->getName()) {
+      if (m_routableUserDiscoveryPrefix < data.getName()) {
         // when two managers exist, the one with "smaller" name take the control
         sendUpdate(chatroomName);
         return;
       }
       else {
-        if (it->second.helloTimeoutEventId != nullptr) {
-          m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+        if (it->second.helloTimeoutEventId) {
+          it->second.helloTimeoutEventId.cancel();
         }
-        it->second.helloTimeoutEventId = nullptr;
         it->second.isManager = false;
       }
 
@@ -180,35 +179,34 @@
   }
 
   else if (it->second.isParticipant) {
-    if (it->second.localChatroomTimeoutEventId != nullptr)
-      m_scheduler->cancelEvent(it->second.localChatroomTimeoutEventId);
+    if (it->second.localChatroomTimeoutEventId)
+      it->second.localChatroomTimeoutEventId.cancel();
 
     // If a user start a random timer it means that he think his own chatroom is not alive
     // But when he receive some packet, it means that this chatroom is alive, so he can
     // cancel the timer
-    if (it->second.managerSelectionTimeoutEventId != nullptr)
-      m_scheduler->cancelEvent(it->second.managerSelectionTimeoutEventId);
-    it->second.managerSelectionTimeoutEventId = nullptr;
+    if (it->second.managerSelectionTimeoutEventId)
+      it->second.managerSelectionTimeoutEventId.cancel();
 
     it->second.localChatroomTimeoutEventId =
-      m_scheduler->scheduleEvent(HELLO_INTERVAL * 3,
-                                 bind(&ChatroomDiscoveryBackend::localSessionTimeout,
-                                      this, chatroomName));
+      m_scheduler->schedule(HELLO_INTERVAL * 3,
+                            bind(&ChatroomDiscoveryBackend::localSessionTimeout,
+                                 this, chatroomName));
   }
   else {
-    if (!data->getContent().empty()) {
+    if (data.hasContent()) {
       ChatroomInfo chatroom;
-      chatroom.wireDecode(data->getContent().blockFromValue());
+      chatroom.wireDecode(data.getContent().blockFromValue());
       it->second.info = chatroom;
     }
 
-    if (it->second.remoteChatroomTimeoutEventId != nullptr)
-      m_scheduler->cancelEvent(it->second.remoteChatroomTimeoutEventId);
+    if (it->second.remoteChatroomTimeoutEventId)
+      it->second.remoteChatroomTimeoutEventId.cancel();
 
     it->second.remoteChatroomTimeoutEventId =
-      m_scheduler->scheduleEvent(HELLO_INTERVAL * 5,
-                                 bind(&ChatroomDiscoveryBackend::remoteSessionTimeout,
-                                      this, chatroomName));
+      m_scheduler->schedule(HELLO_INTERVAL * 5,
+                            bind(&ChatroomDiscoveryBackend::remoteSessionTimeout,
+                                 this, chatroomName));
   }
   // if this is a chatroom that haven't been print on the discovery panel, print it.
   if(!it->second.isPrint) {
@@ -224,9 +222,9 @@
   if (it == m_chatroomList.end() || it->second.isParticipant == false)
     return;
   it->second.managerSelectionTimeoutEventId =
-    m_scheduler->scheduleEvent(time::milliseconds(m_rangeUniformRandom()),
-                               bind(&ChatroomDiscoveryBackend::randomSessionTimeout,
-                                    this, chatroomName));
+    m_scheduler->schedule(time::milliseconds(m_rangeUniformRandom()),
+                          bind(&ChatroomDiscoveryBackend::randomSessionTimeout,
+                               this, chatroomName));
 }
 
 void
@@ -252,15 +250,15 @@
   if (it != m_chatroomList.end() && it->second.isManager) {
     ndn::Block buf = it->second.info.wireEncode();
 
-    if (it->second.helloTimeoutEventId != nullptr) {
-      m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+    if (it->second.helloTimeoutEventId) {
+      it->second.helloTimeoutEventId.cancel();
     }
 
     m_sock->publishData(buf.wire(), buf.size(), FRESHNESS_PERIOD, it->second.chatroomPrefix);
 
     it->second.helloTimeoutEventId =
-      m_scheduler->scheduleEvent(HELLO_INTERVAL,
-                                 bind(&ChatroomDiscoveryBackend::sendUpdate, this, chatroomName));
+      m_scheduler->schedule(HELLO_INTERVAL,
+                            bind(&ChatroomDiscoveryBackend::sendUpdate, this, chatroomName));
     // if this is a chatroom that haven't been print on the discovery panel, print it.
     if(!it->second.isPrint) {
       sendChatroomList();
@@ -318,8 +316,8 @@
     it->second.info.removeParticipant(sessionPrefix);
     if (it->second.info.getParticipants().size() == 0) {
       // Before deleting the chatroom, cancel the hello event timer if exist
-      if (it->second.helloTimeoutEventId != nullptr)
-        m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
+      if (it->second.helloTimeoutEventId)
+        it->second.helloTimeoutEventId.cancel();
 
       m_chatroomList.erase(chatroomName);
       Name prefix = sessionPrefix;
@@ -334,18 +332,16 @@
       it->second.isManager = false;
       it->second.isPrint = false;
       it->second.count = 0;
-      if (it->second.helloTimeoutEventId != nullptr)
-        m_scheduler->cancelEvent(it->second.helloTimeoutEventId);
-      it->second.helloTimeoutEventId = nullptr;
+      if (it->second.helloTimeoutEventId)
+        it->second.helloTimeoutEventId.cancel();
 
-      if (it->second.localChatroomTimeoutEventId != nullptr)
-        m_scheduler->cancelEvent(it->second.localChatroomTimeoutEventId);
-      it->second.localChatroomTimeoutEventId = nullptr;
+      if (it->second.localChatroomTimeoutEventId)
+        it->second.localChatroomTimeoutEventId.cancel();
 
       it->second.remoteChatroomTimeoutEventId =
-      m_scheduler->scheduleEvent(HELLO_INTERVAL * 5,
-                                bind(&ChatroomDiscoveryBackend::remoteSessionTimeout,
-                                     this, chatroomName));
+      m_scheduler->schedule(HELLO_INTERVAL * 5,
+                            bind(&ChatroomDiscoveryBackend::remoteSessionTimeout,
+                                 this, chatroomName));
     }
 
     if (it->second.isManager) {
@@ -381,9 +377,9 @@
     m_chatroomList[chatroomName].isManager = false;
     m_chatroomList[chatroomName].count = 0;
     m_chatroomList[chatroomName].isPrint = false;
-    m_scheduler->scheduleEvent(time::milliseconds(600),
-                               bind(&ChatroomDiscoveryBackend::randomSessionTimeout, this,
-                                    chatroomName));
+    m_scheduler->schedule(time::milliseconds(600),
+                          bind(&ChatroomDiscoveryBackend::randomSessionTimeout, this,
+                               chatroomName));
   }
   else {
     // Entering an existing chatroom
@@ -391,15 +387,14 @@
     it->second.isManager = false;
     it->second.chatroomPrefix = newPrefix;
 
-    if (it->second.remoteChatroomTimeoutEventId != nullptr)
-      m_scheduler->cancelEvent(it->second.remoteChatroomTimeoutEventId);
+    if (it->second.remoteChatroomTimeoutEventId)
+     it->second.remoteChatroomTimeoutEventId.cancel();
     it->second.isPrint = false;
-    it->second.remoteChatroomTimeoutEventId = nullptr;
 
     it->second.localChatroomTimeoutEventId =
-      m_scheduler->scheduleEvent(HELLO_INTERVAL * 3,
-                                 bind(&ChatroomDiscoveryBackend::localSessionTimeout,
-                                      this, chatroomName));
+      m_scheduler->schedule(HELLO_INTERVAL * 3,
+                            bind(&ChatroomDiscoveryBackend::localSessionTimeout,
+                                 this, chatroomName));
     emit chatroomInfoRequest(chatroomName.toUri(), false);
   }
 }
@@ -421,18 +416,10 @@
 void
 ChatroomDiscoveryBackend::onIdentityUpdated(const QString& identity)
 {
-  m_chatroomList.clear();
   m_identity = Name(identity.toStdString());
   m_userDiscoveryPrefix.clear();
   m_userDiscoveryPrefix.append(m_identity).append("CHRONOCHAT-DISCOVERYDATA");
   updatePrefixes();
-
-  {
-    std::lock_guard<std::mutex>lock(m_resumeMutex);
-    m_shouldResume = true;
-  }
-
-  m_face->getIoService().stop();
 }
 
 void
@@ -444,11 +431,11 @@
   }
 
   emit chatroomListReady(chatroomList);
-  if (m_refreshPanelId != nullptr) {
-    m_scheduler->cancelEvent(m_refreshPanelId);
+  if (m_refreshPanelId) {
+    m_refreshPanelId.cancel();
   }
-  m_refreshPanelId = m_scheduler->scheduleEvent(REFRESH_INTERVAL,
-                                                [this] { sendChatroomList(); });
+  m_refreshPanelId = m_scheduler->schedule(REFRESH_INTERVAL,
+                                           [this] { sendChatroomList(); });
 }
 
 void
diff --git a/src/chatroom-discovery-backend.hpp b/src/chatroom-discovery-backend.hpp
index d6bf843..ad471ac 100644
--- a/src/chatroom-discovery-backend.hpp
+++ b/src/chatroom-discovery-backend.hpp
@@ -18,7 +18,7 @@
 #include "chatroom-info.hpp"
 #include <boost/random.hpp>
 #include <mutex>
-#include <socket.hpp>
+#include <ChronoSync/socket.hpp>
 #include <boost/thread.hpp>
 #endif
 
@@ -30,13 +30,13 @@
   Name chatroomPrefix;
   ChatroomInfo info;
   // For a chatroom's user to check whether his own chatroom is alive
-  ndn::EventId localChatroomTimeoutEventId;
+  ndn::scheduler::EventId localChatroomTimeoutEventId;
   // If the manager no longer exist, set a random timer to compete for manager
-  ndn::EventId managerSelectionTimeoutEventId;
+  ndn::scheduler::EventId managerSelectionTimeoutEventId;
   // For a user to check the status of the chatroom that he is not in.
-  ndn::EventId remoteChatroomTimeoutEventId;
+  ndn::scheduler::EventId remoteChatroomTimeoutEventId;
   // If the user is manager, he will need the helloEventId to keep track of hello message
-  ndn::EventId helloTimeoutEventId;
+  ndn::scheduler::EventId helloTimeoutEventId;
   // To tell whether the user is in this chatroom
   bool isParticipant;
   // To tell whether the user is the manager
@@ -75,7 +75,7 @@
   processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
 
   void
-  processChatroomData(const ndn::shared_ptr<const ndn::Data>& data);
+  processChatroomData(const ndn::Data& data);
 
   void
   localSessionTimeout(const Name::Component& chatroomName);
@@ -228,7 +228,7 @@
   shared_ptr<ndn::Face> m_face;
 
   unique_ptr<ndn::Scheduler> m_scheduler;            // scheduler
-  ndn::EventId m_refreshPanelId;
+  ndn::scheduler::EventId m_refreshPanelId;
   shared_ptr<chronosync::Socket> m_sock; // SyncSocket
 
   ChatroomList m_chatroomList;
diff --git a/src/chatroom-info.cpp b/src/chatroom-info.cpp
index 81302bb..aa8efcc 100644
--- a/src/chatroom-info.cpp
+++ b/src/chatroom-info.cpp
@@ -25,7 +25,7 @@
   this->wireDecode(chatroomWire);
 }
 
-template<bool T>
+template<ndn::encoding::Tag T>
 size_t
 ChatroomInfo::wireEncode(ndn::EncodingImpl<T>& encoder) const
 {
diff --git a/src/chatroom-info.hpp b/src/chatroom-info.hpp
index dca4090..81e0fde 100644
--- a/src/chatroom-info.hpp
+++ b/src/chatroom-info.hpp
@@ -95,7 +95,7 @@
   setManager(const Name& manager);
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& encoder) const;
 
diff --git a/src/common.hpp b/src/common.hpp
index c8461df..3b14f79 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -28,7 +28,6 @@
 #include <vector>
 #include <string>
 
-#include <ndn-cxx/common.hpp>
 #include <ndn-cxx/interest.hpp>
 #include <ndn-cxx/data.hpp>
 
@@ -61,7 +60,6 @@
 using ndn::Interest;
 using ndn::Data;
 using ndn::Name;
-using ndn::Exclude;
 using ndn::Block;
 using ndn::Signature;
 using ndn::KeyLocator;
diff --git a/src/conf.cpp b/src/conf.cpp
index fba36b8..d02fe08 100644
--- a/src/conf.cpp
+++ b/src/conf.cpp
@@ -23,7 +23,7 @@
   this->wireDecode(confWire);
 }
 
-template<bool T>
+template<ndn::encoding::Tag T>
 size_t
 Conf::wireEncode(ndn::EncodingImpl<T>& block) const
 {
diff --git a/src/conf.hpp b/src/conf.hpp
index 0626bf1..3b4f394 100644
--- a/src/conf.hpp
+++ b/src/conf.hpp
@@ -60,7 +60,7 @@
   setNick(const std::string& nick);
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& block) const;
 
diff --git a/src/contact-manager.cpp b/src/contact-manager.cpp
index 811130e..2bb5153 100644
--- a/src/contact-manager.cpp
+++ b/src/contact-manager.cpp
@@ -19,9 +19,11 @@
 
 #ifndef Q_MOC_RUN
 #include <ndn-cxx/encoding/buffer-stream.hpp>
-#include <ndn-cxx/util/crypto.hpp>
-#include <ndn-cxx/security/sec-rule-relative.hpp>
-#include <ndn-cxx/security/validator-regex.hpp>
+#include <ndn-cxx/face.hpp>
+#include <ndn-cxx/security/validator.hpp>
+#include <ndn-cxx/security/validator-null.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <ndn-cxx/security/verification-helpers.hpp>
 #include "cryptopp.hpp"
 #include <boost/asio.hpp>
 #include <boost/tokenizer.hpp>
@@ -31,8 +33,6 @@
 
 namespace fs = boost::filesystem;
 
-// INIT_LOGGER("chronochat.ContactManager");
-
 namespace chronochat {
 
 using std::string;
@@ -41,21 +41,13 @@
 
 using ndn::Face;
 using ndn::OBufferStream;
-using ndn::IdentityCertificate;
-using ndn::Validator;
-using ndn::ValidatorRegex;
-using ndn::SecRuleRelative;
-using ndn::OnDataValidated;
-using ndn::OnDataValidationFailed;
-using ndn::OnInterestValidated;
-using ndn::OnInterestValidationFailed;
+using ndn::security::Certificate;
 
 
 ContactManager::ContactManager(Face& face,
                                QObject* parent)
   : QObject(parent)
   , m_face(face)
-  , m_dnsListenerId(0)
 {
   initializeSecurity();
 }
@@ -64,76 +56,11 @@
 {
 }
 
-// private methods
-shared_ptr<IdentityCertificate>
-ContactManager::loadTrustAnchor()
-{
-  shared_ptr<IdentityCertificate> anchor;
-
-  QFile anchorFile(":/security/anchor.cert");
-
-  if (!anchorFile.open(QIODevice::ReadOnly)) {
-    emit warning(QString("Cannot load trust anchor!"));
-    return anchor;
-  }
-
-  qint64 fileSize = anchorFile.size();
-  char* buf = new char[fileSize];
-  anchorFile.read(buf, fileSize);
-
-  try {
-    using namespace CryptoPP;
-
-    OBufferStream os;
-    StringSource(reinterpret_cast<const uint8_t*>(buf), fileSize, true,
-                 new Base64Decoder(new FileSink(os)));
-    anchor = make_shared<IdentityCertificate>();
-    anchor->wireDecode(Block(os.buf()));
-  }
-  catch (CryptoPP::Exception& e) {
-    emit warning(QString("Cannot load trust anchor!"));
-  }
-  catch (IdentityCertificate::Error& e) {
-    emit warning(QString("Cannot load trust anchor!"));
-  }
-  catch(Block::Error& e) {
-    emit warning(QString("Cannot load trust anchor!"));
-  }
-
-  delete [] buf;
-
-  return anchor;
-}
-
 void
 ContactManager::initializeSecurity()
 {
-  shared_ptr<IdentityCertificate> anchor = loadTrustAnchor();
-
-  shared_ptr<ValidatorRegex> validator = make_shared<ValidatorRegex>(boost::ref(m_face));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><ENDORSED>",
-                                                                  "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
-                                                                  "==", "\\1", "\\1\\2", true));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><><ENDORSEE>",
-                                                                  "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
-                                                                  "==", "\\1", "\\1\\2", true));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><PROFILE>",
-                                                                  "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$",
-                                                                  "==", "\\1", "\\1\\2", true));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<PROFILE-CERT>]*)<PROFILE-CERT>",
-                                                                  "^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$",
-                                                                  "==", "\\1", "\\1\\2", true));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
-                                                                  "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>$",
-                                                                  ">", "\\1\\2", "\\1", true));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
-                                                                  "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                                                  "==", "\\1", "\\1\\2", true));
-  validator->addDataVerificationRule(make_shared<SecRuleRelative>("^(<>*)$",
-                                                                  "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                                                  ">", "\\1", "\\1\\2", true));
-  validator->addTrustAnchor(anchor);
-  m_validator = validator;
+  m_validator = make_shared<ndn::security::ValidatorConfig>(m_face);
+  m_validator->load("security/validation-contact-manager.conf");
 }
 
 void
@@ -144,11 +71,12 @@
 
   Interest interest(interestName);
   interest.setInterestLifetime(time::milliseconds(1000));
+  interest.setCanBePrefix(true);
   interest.setMustBeFresh(true);
 
-  OnDataValidated onValidated =
+  ndn::security::DataValidationSuccessCallback onValidated =
     bind(&ContactManager::onDnsCollectEndorseValidated, this, _1, identity);
-  OnDataValidationFailed onValidationFailed =
+  ndn::security::DataValidationFailureCallback onValidationFailed =
     bind(&ContactManager::onDnsCollectEndorseValidationFailed, this, _1, _2, identity);
   TimeoutNotify timeoutNotify =
     bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, _1, identity);
@@ -163,19 +91,21 @@
     m_bufferedContacts[identity].m_endorseCollection;
 
   if(certIndex >= endorseCollection->getCollectionEntries().size())
-    prepareEndorseInfo(identity);
+    return prepareEndorseInfo(identity);
 
   Name interestName(endorseCollection->getCollectionEntries()[certIndex].certName);
 
   Interest interest(interestName);
   interest.setInterestLifetime(time::milliseconds(1000));
-  interest.setMustBeFresh(true);
+  interest.setMustBeFresh(false);
 
   m_face.expressInterest(interest,
                          bind(&ContactManager::onEndorseCertificateInternal,
                               this, _1, _2, identity, certIndex,
                               endorseCollection->getCollectionEntries()[certIndex].hash),
                          bind(&ContactManager::onEndorseCertificateInternalTimeout,
+                              this, _1, identity, certIndex),
+                         bind(&ContactManager::onEndorseCertificateInternalTimeout,
                               this, _1, identity, certIndex));
 }
 
@@ -202,7 +132,7 @@
     m_bufferedContacts[identity].m_endorseCertList.end();
 
   for (; cIt != cEnd; cIt++, endorseCertCount++) {
-    shared_ptr<Contact> contact = getContact((*cIt)->getSigner().getPrefix(-1));
+    shared_ptr<Contact> contact = getContact((*cIt)->getSigner());
     if (!static_cast<bool>(contact))
       continue;
 
@@ -210,16 +140,17 @@
         !contact->canBeTrustedFor(profile.getIdentityName()))
       continue;
 
-    if (!Validator::verifySignature(**cIt, contact->getPublicKey()))
+    if (!(*cIt)->isValid())
+      continue;
+
+    if (!ndn::security::verifySignature(**cIt, contact->getPublicKey().data(), contact->getPublicKey().size()))
       continue;
 
     const Profile& tmpProfile = (*cIt)->getProfile();
-    if (tmpProfile != profile)
-      continue;
-
     const vector<string>& endorseList = (*cIt)->getEndorseList();
     for (vector<string>::const_iterator eIt = endorseList.begin(); eIt != endorseList.end(); eIt++)
-      endorseCount[*eIt] += 1;
+      if (tmpProfile.get(*eIt) == profile.get(*eIt))
+        endorseCount[*eIt] += 1;
   }
 
   for (Profile::const_iterator pIt = profile.begin(); pIt != profile.end(); pIt++) {
@@ -232,35 +163,36 @@
 }
 
 void
-ContactManager::onDnsSelfEndorseCertValidated(const shared_ptr<const Data>& data,
+ContactManager::onDnsSelfEndorseCertValidated(const Data& data,
                                               const Name& identity)
 {
   try {
     Data plainData;
-    plainData.wireDecode(data->getContent().blockFromValue());
+    plainData.wireDecode(data.getContent().blockFromValue());
     shared_ptr<EndorseCertificate> selfEndorseCertificate =
       make_shared<EndorseCertificate>(boost::cref(plainData));
-    if (Validator::verifySignature(plainData, selfEndorseCertificate->getPublicKeyInfo())) {
+
+    if (ndn::security::verifySignature(plainData, *selfEndorseCertificate)) {
       m_bufferedContacts[identity].m_selfEndorseCert = selfEndorseCertificate;
       fetchCollectEndorse(identity);
     }
     else
-      emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
+      emit contactInfoFetchFailed(QString::fromStdString(identity.toUri() + ": verification failed"));
   }
   catch(Block::Error& e) {
-    emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
+    emit contactInfoFetchFailed(QString::fromStdString(identity.toUri() + ": block error " + e.what()));
   }
   catch(EndorseCertificate::Error& e) {
-    emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
+    emit contactInfoFetchFailed(QString::fromStdString(identity.toUri() + ": cert error " + e.what()));
   }
   catch(Data::Error& e) {
-    emit contactInfoFetchFailed(QString::fromStdString(identity.toUri()));
+    emit contactInfoFetchFailed(QString::fromStdString(identity.toUri() + ": data error " + e.what()));
   }
 }
 
 void
-ContactManager::onDnsSelfEndorseCertValidationFailed(const shared_ptr<const Data>& data,
-                                                     const string& failInfo,
+ContactManager::onDnsSelfEndorseCertValidationFailed(const Data& data,
+                                                     const ndn::security::ValidationError& error,
                                                      const Name& identity)
 {
   // If we cannot validate the Self-Endorse-Certificate, we may retry or fetch id-cert,
@@ -278,23 +210,23 @@
 }
 
 void
-ContactManager::onDnsCollectEndorseValidated(const shared_ptr<const Data>& data,
+ContactManager::onDnsCollectEndorseValidated(const Data& data,
                                              const Name& identity)
 {
   try {
     shared_ptr<EndorseCollection> endorseCollection =
-      make_shared<EndorseCollection>(data->getContent());
+      make_shared<EndorseCollection>(data.getContent().blockFromValue());
     m_bufferedContacts[identity].m_endorseCollection = endorseCollection;
     fetchEndorseCertificateInternal(identity, 0);
   }
-  catch (tlv::Error) {
+  catch (std::runtime_error&) {
     prepareEndorseInfo(identity);
   }
 }
 
 void
-ContactManager::onDnsCollectEndorseValidationFailed(const shared_ptr<const Data>& data,
-                                                    const string& failInfo,
+ContactManager::onDnsCollectEndorseValidationFailed(const Data& data,
+                                                    const ndn::security::ValidationError& error,
                                                     const Name& identity)
 {
   prepareEndorseInfo(identity);
@@ -308,7 +240,7 @@
 }
 
 void
-ContactManager::onEndorseCertificateInternal(const Interest& interest, Data& data,
+ContactManager::onEndorseCertificateInternal(const Interest& interest, const Data& data,
                                              const Name& identity, size_t certIndex,
                                              string hash)
 {
@@ -350,10 +282,12 @@
       interestName.append("DNS").append(m_identity.wireEncode()).append("ENDORSEE");
 
       Interest interest(interestName);
+      interest.setMustBeFresh(true);
       interest.setInterestLifetime(time::milliseconds(1000));
 
-      OnDataValidated onValidated = bind(&ContactManager::onDnsEndorseeValidated, this, _1);
-      OnDataValidationFailed onValidationFailed =
+      ndn::security::DataValidationSuccessCallback onValidated =
+        bind(&ContactManager::onDnsEndorseeValidated, this, _1);
+      ndn::security::DataValidationFailureCallback onValidationFailed =
         bind(&ContactManager::onDnsEndorseeValidationFailed, this, _1, _2);
       TimeoutNotify timeoutNotify = bind(&ContactManager::onDnsEndorseeTimeoutNotify, this, _1);
 
@@ -363,10 +297,10 @@
 }
 
 void
-ContactManager::onDnsEndorseeValidated(const shared_ptr<const Data>& data)
+ContactManager::onDnsEndorseeValidated(const Data& data)
 {
   Data endorseData;
-  endorseData.wireDecode(data->getContent().blockFromValue());
+  endorseData.wireDecode(data.getContent().blockFromValue());
 
   EndorseCertificate endorseCertificate(endorseData);
   m_contactStorage->updateCollectEndorse(endorseCertificate);
@@ -375,8 +309,8 @@
 }
 
 void
-ContactManager::onDnsEndorseeValidationFailed(const shared_ptr<const Data>& data,
-                                              const string& failInfo)
+ContactManager::onDnsEndorseeValidationFailed(const Data& data,
+                                              const ndn::security::ValidationError& error)
 {
   decreaseCollectStatus();
 }
@@ -409,28 +343,30 @@
 
   shared_ptr<Data> data = make_shared<Data>();
   data->setName(dnsName);
+  data->setFreshnessPeriod(time::milliseconds(1000));
 
   EndorseCollection endorseCollection;
   m_contactStorage->getCollectEndorse(endorseCollection);
 
   data->setContent(endorseCollection.wireEncode());
-  m_keyChain.signByIdentity(*data, m_identity);
+
+  m_keyChain.sign(*data, ndn::security::signingByIdentity(m_identity));
 
   m_contactStorage->updateDnsOthersEndorse(*data);
   m_face.put(*data);
 }
 
 void
-ContactManager::onIdentityCertValidated(const shared_ptr<const Data>& data)
+ContactManager::onIdentityCertValidated(const Data& data)
 {
-  shared_ptr<IdentityCertificate> cert = make_shared<IdentityCertificate>(boost::cref(*data));
+  shared_ptr<Certificate> cert = make_shared<Certificate>(boost::cref(data));
   m_bufferedIdCerts[cert->getName()] = cert;
   decreaseIdCertCount();
 }
 
 void
-ContactManager::onIdentityCertValidationFailed(const shared_ptr<const Data>& data,
-                                               const string& failInfo)
+ContactManager::onIdentityCertValidationFailed(const Data& data,
+                                               const ndn::security::ValidationError& error)
 {
   // _LOG_DEBUG("ContactManager::onIdentityCertValidationFailed " << data->getName());
   decreaseIdCertCount();
@@ -472,20 +408,20 @@
 shared_ptr<EndorseCertificate>
 ContactManager::getSignedSelfEndorseCertificate(const Profile& profile)
 {
-  Name certificateName = m_keyChain.getDefaultCertificateNameForIdentity(m_identity);
-
-  shared_ptr<IdentityCertificate> signingCert = m_keyChain.getCertificate(certificateName);
-
+  auto signCert = m_keyChain.getPib().getIdentity(m_identity)
+                            .getDefaultKey().getDefaultCertificate();
   vector<string> endorseList;
   for (Profile::const_iterator it = profile.begin(); it != profile.end(); it++)
     endorseList.push_back(it->first);
 
   shared_ptr<EndorseCertificate> selfEndorseCertificate =
-    make_shared<EndorseCertificate>(boost::cref(*signingCert),
+    make_shared<EndorseCertificate>(boost::cref(signCert),
                                     boost::cref(profile),
                                     boost::cref(endorseList));
 
-  m_keyChain.sign(*selfEndorseCertificate, certificateName);
+  m_keyChain.sign(*selfEndorseCertificate,
+                  ndn::security::signingByIdentity(m_identity).setSignatureInfo(
+                    selfEndorseCertificate->getSignatureInfo()));
 
   return selfEndorseCertificate;
 }
@@ -501,7 +437,7 @@
   data->setContent(selfEndorseCertificate.wireEncode());
   data->setFreshnessPeriod(time::milliseconds(1000));
 
-  m_keyChain.signByIdentity(*data, m_identity);
+  m_keyChain.sign(*data, ndn::security::signingByIdentity(m_identity));
 
   m_contactStorage->updateDnsSelfProfileData(*data);
   m_face.put(*data);
@@ -510,11 +446,14 @@
 shared_ptr<EndorseCertificate>
 ContactManager::generateEndorseCertificate(const Name& identity)
 {
+  auto signCert = m_keyChain.getPib().getIdentity(m_identity)
+                            .getDefaultKey().getDefaultCertificate();
+
   shared_ptr<Contact> contact = getContact(identity);
   if (!static_cast<bool>(contact))
     return shared_ptr<EndorseCertificate>();
 
-  Name signerKeyName = m_keyChain.getDefaultKeyNameForIdentity(m_identity);
+  Name signerKeyName = m_identity;
 
   vector<string> endorseList;
   m_contactStorage->getEndorseList(identity, endorseList);
@@ -524,10 +463,13 @@
                                                           contact->getPublicKey(),
                                                           contact->getNotBefore(),
                                                           contact->getNotAfter(),
+                                                          signCert.getKeyId(),
                                                           signerKeyName,
                                                           contact->getProfile(),
                                                           endorseList));
-  m_keyChain.signByIdentity(*cert, m_identity);
+  m_keyChain.sign(*cert,
+                  ndn::security::signingByIdentity(m_identity)
+                    .setSignatureInfo(cert->getSignatureInfo()));
   return cert;
 
 }
@@ -535,7 +477,7 @@
 void
 ContactManager::publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate)
 {
-  Name endorsee = endorseCertificate.getPublicKeyName().getPrefix(-1);
+  Name endorsee = endorseCertificate.getKeyName().getPrefix(-4);
   Name dnsName = m_identity;
   dnsName.append("DNS")
     .append(endorsee.wireEncode())
@@ -545,8 +487,9 @@
   shared_ptr<Data> data = make_shared<Data>();
   data->setName(dnsName);
   data->setContent(endorseCertificate.wireEncode());
+  data->setFreshnessPeriod(time::milliseconds(1000));
 
-  m_keyChain.signByIdentity(*data, m_identity);
+  m_keyChain.sign(*data, ndn::security::signingByIdentity(m_identity));
 
   m_contactStorage->updateDnsEndorseOthers(*data, dnsName.get(-3).toUri());
   m_face.put(*data);
@@ -554,8 +497,8 @@
 
 void
 ContactManager::sendInterest(const Interest& interest,
-                             const OnDataValidated& onValidated,
-                             const OnDataValidationFailed& onValidationFailed,
+                             const ndn::security::DataValidationSuccessCallback& onValidated,
+                             const ndn::security::DataValidationFailureCallback& onValidationFailed,
                              const TimeoutNotify& timeoutNotify,
                              int retry /* = 1 */)
 {
@@ -563,24 +506,25 @@
                          bind(&ContactManager::onTargetData,
                               this, _1, _2, onValidated, onValidationFailed),
                          bind(&ContactManager::onTargetTimeout,
+                              this, _1, retry, onValidated, onValidationFailed, timeoutNotify),
+                         bind(&ContactManager::onTargetTimeout,
                               this, _1, retry, onValidated, onValidationFailed, timeoutNotify));
 }
 
 void
 ContactManager::onTargetData(const Interest& interest,
                              const Data& data,
-                             const OnDataValidated& onValidated,
-                             const OnDataValidationFailed& onValidationFailed)
+                             const ndn::security::DataValidationSuccessCallback& onValidated,
+                             const ndn::security::DataValidationFailureCallback& onValidationFailed)
 {
-  // _LOG_DEBUG("On receiving data: " << data.getName());
   m_validator->validate(data, onValidated, onValidationFailed);
 }
 
 void
 ContactManager::onTargetTimeout(const Interest& interest,
                                 int retry,
-                                const OnDataValidated& onValidated,
-                                const OnDataValidationFailed& onValidationFailed,
+                                const ndn::security::DataValidationSuccessCallback& onValidated,
+                                const ndn::security::DataValidationFailureCallback& onValidationFailed,
                                 const TimeoutNotify& timeoutNotify)
 {
   // _LOG_DEBUG("On interest timeout: " << interest.getName());
@@ -621,6 +565,29 @@
   emit warning(QString(failInfo.c_str()));
 }
 
+void
+ContactManager::onKeyInterest(const Name& prefix, const Interest& interest)
+{
+  const Name& interestName = interest.getName();
+  shared_ptr<Certificate> data;
+
+  try {
+    ndn::security::Certificate cert = m_keyChain.getPib()
+                                                .getIdentity(m_identity)
+                                                .getDefaultKey()
+                                                .getDefaultCertificate();
+    if (cert.getKeyName() == interestName)
+      return m_face.put(cert);
+  } catch (ndn::security::Pib::Error&) {}
+
+  data = m_contactStorage->getSelfEndorseCertificate();
+  if (static_cast<bool>(data) && data->getKeyName().equals(interestName))
+    return m_face.put(*data);
+
+  data = m_contactStorage->getCollectEndorseByName(interestName);
+  if (static_cast<bool>(data))
+    return m_face.put(*data);
+}
 
 // public slots
 void
@@ -632,22 +599,42 @@
 
   Name dnsPrefix;
   dnsPrefix.append(m_identity).append("DNS");
-  const ndn::RegisteredPrefixId* dnsListenerId =
+  auto dnsListenerId = make_shared<ndn::RegisteredPrefixHandle>(
     m_face.setInterestFilter(dnsPrefix,
-                             bind(&ContactManager::onDnsInterest,
-                                  this, _1, _2),
-                             bind(&ContactManager::onDnsRegisterFailed,
-                                  this, _1, _2));
+                             bind(&ContactManager::onDnsInterest, this, _1, _2),
+                             bind(&ContactManager::onDnsRegisterFailed, this, _1, _2)));
+
+  Name keyPrefix;
+  keyPrefix.append(m_identity).append("KEY");
+  auto keyListenerId = make_shared<ndn::RegisteredPrefixHandle>(
+    m_face.setInterestFilter(keyPrefix,
+                             bind(&ContactManager::onKeyInterest, this, _1, _2),
+                             bind(&ContactManager::onDnsRegisterFailed, this, _1, _2)));
+
+  Name profileCertPrefix;
+  profileCertPrefix.append(m_identity).append("PROFILE-CERT");
+  auto profileCertListenerId = make_shared<ndn::RegisteredPrefixHandle>(
+    m_face.setInterestFilter(profileCertPrefix,
+                             bind(&ContactManager::onKeyInterest, this, _1, _2),
+                             bind(&ContactManager::onDnsRegisterFailed, this, _1, _2)));
 
   if (m_dnsListenerId != 0)
-    m_face.unsetInterestFilter(m_dnsListenerId);
-
+    m_dnsListenerId->unregister();
   m_dnsListenerId = dnsListenerId;
 
+  if (m_keyListenerId != 0)
+    m_keyListenerId->unregister();
+  m_keyListenerId = keyListenerId;
+
+  if (m_profileCertListenerId != 0)
+    m_profileCertListenerId->unregister();
+  m_profileCertListenerId = profileCertListenerId;
+
   m_contactList.clear();
   m_contactStorage->getAllContacts(m_contactList);
 
   m_bufferedContacts.clear();
+  onWaitForContactList();
 
   collectEndorsement();
 }
@@ -666,9 +653,9 @@
   interest.setInterestLifetime(time::milliseconds(1000));
   interest.setMustBeFresh(true);
 
-  OnDataValidated onValidated =
+  ndn::security::DataValidationSuccessCallback onValidated =
     bind(&ContactManager::onDnsSelfEndorseCertValidated, this, _1, identityName);
-  OnDataValidationFailed onValidationFailed =
+  ndn::security::DataValidationFailureCallback onValidationFailed =
     bind(&ContactManager::onDnsSelfEndorseCertValidationFailed, this, _1, _2, identityName);
   TimeoutNotify timeoutNotify =
     bind(&ContactManager::onDnsSelfEndorseCertTimeoutNotify, this, _1, identityName);
@@ -725,11 +712,15 @@
 void
 ContactManager::onRefreshBrowseContact()
 {
+  return;
+
+#if 0
+  // The following no longer works as we don't serve such a list anymore
   vector<string> bufferedIdCertNames;
   try {
     using namespace boost::asio::ip;
     tcp::iostream request_stream;
-    request_stream.expires_from_now(boost::posix_time::milliseconds(5000));
+    request_stream.expires_from_now(std::chrono::milliseconds(5000));
     request_stream.connect("ndncert.named-data.net","80");
     if (!request_stream) {
       emit warning(QString::fromStdString("Fail to fetch certificate directory! #1"));
@@ -800,15 +791,16 @@
     interest.setInterestLifetime(time::milliseconds(1000));
     interest.setMustBeFresh(true);
 
-    OnDataValidated onValidated =
+    ndn::security::DataValidationSuccessCallback onValidated =
     bind(&ContactManager::onIdentityCertValidated, this, _1);
-    OnDataValidationFailed onValidationFailed =
+    ndn::security::DataValidationFailureCallback onValidationFailed =
     bind(&ContactManager::onIdentityCertValidationFailed, this, _1, _2);
     TimeoutNotify timeoutNotify =
     bind(&ContactManager::onIdentityCertTimeoutNotify, this, _1);
 
     sendInterest(interest, onValidated, onValidationFailed, timeoutNotify, 0);
   }
+#endif
 }
 
 void
@@ -823,7 +815,7 @@
 ContactManager::onAddFetchedContactIdCert(const QString& qCertName)
 {
   Name certName(qCertName.toStdString());
-  Name identity = IdentityCertificate::certificateNameToPublicKeyName(certName).getPrefix(-1);
+  Name identity = certName.getPrefix(-1);
 
   BufferedIdCerts::const_iterator it = m_bufferedIdCerts.find(certName);
   if (it != m_bufferedIdCerts.end()) {
@@ -901,7 +893,7 @@
 ContactManager::onUpdateEndorseCertificate(const QString& identity)
 {
   Name identityName(identity.toStdString());
-  shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identityName);
+  shared_ptr<Certificate> newEndorseCertificate = generateEndorseCertificate(identityName);
 
   if (!static_cast<bool>(newEndorseCertificate))
     return;
diff --git a/src/contact-manager.hpp b/src/contact-manager.hpp
index 5ef7983..b475eb4 100644
--- a/src/contact-manager.hpp
+++ b/src/contact-manager.hpp
@@ -22,7 +22,8 @@
 #include "endorse-info.hpp"
 #include "endorse-collection.hpp"
 #include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/security/validator.hpp>
+#include <ndn-cxx/security/validator-config.hpp>
+#include <ndn-cxx/face.hpp>
 #include <boost/thread/locks.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #endif
@@ -54,9 +55,6 @@
     contactList.insert(contactList.end(), m_contactList.begin(), m_contactList.end());
   }
 private:
-  shared_ptr<ndn::IdentityCertificate>
-  loadTrustAnchor();
-
   void
   initializeSecurity();
 
@@ -71,12 +69,12 @@
 
   // PROFILE: self-endorse-certificate
   void
-  onDnsSelfEndorseCertValidated(const shared_ptr<const Data>& selfEndorseCertificate,
+  onDnsSelfEndorseCertValidated(const Data& selfEndorseCertificate,
                                 const Name& identity);
 
   void
-  onDnsSelfEndorseCertValidationFailed(const shared_ptr<const Data>& selfEndorseCertificate,
-                                       const std::string& failInfo,
+  onDnsSelfEndorseCertValidationFailed(const Data& selfEndorseCertificate,
+                                       const ndn::security::ValidationError& error,
                                        const Name& identity);
 
   void
@@ -84,11 +82,11 @@
 
   // ENDORSED: endorse-collection
   void
-  onDnsCollectEndorseValidated(const shared_ptr<const Data>& data, const Name& identity);
+  onDnsCollectEndorseValidated(const Data& data, const Name& identity);
 
   void
-  onDnsCollectEndorseValidationFailed(const shared_ptr<const Data>& data,
-                                      const std::string& failInfo,
+  onDnsCollectEndorseValidationFailed(const Data& data,
+                                      const ndn::security::ValidationError& error,
                                       const Name& identity);
 
   void
@@ -97,7 +95,7 @@
 
   // PROFILE-CERT: endorse-certificate
   void
-  onEndorseCertificateInternal(const Interest& interest, Data& data,
+  onEndorseCertificateInternal(const Interest& interest, const Data& data,
                                const Name& identity, size_t certIndex,
                                std::string hash);
 
@@ -111,11 +109,11 @@
   collectEndorsement();
 
   void
-  onDnsEndorseeValidated(const shared_ptr<const Data>& data);
+  onDnsEndorseeValidated(const Data& data);
 
   void
-  onDnsEndorseeValidationFailed(const shared_ptr<const Data>& data,
-                                const std::string& failInfo);
+  onDnsEndorseeValidationFailed(const Data& data,
+                                const ndn::security::ValidationError& error);
 
   void
   onDnsEndorseeTimeoutNotify(const Interest& interest);
@@ -128,10 +126,11 @@
 
   // Identity certificate
   void
-  onIdentityCertValidated(const shared_ptr<const Data>& data);
+  onIdentityCertValidated(const Data& data);
 
   void
-  onIdentityCertValidationFailed(const shared_ptr<const Data>& data, const std::string& failInfo);
+  onIdentityCertValidationFailed(const Data& data,
+                                 const ndn::security::ValidationError& error);
 
   void
   onIdentityCertTimeoutNotify(const Interest& interest);
@@ -156,22 +155,22 @@
   // Communication
   void
   sendInterest(const Interest& interest,
-               const ndn::OnDataValidated& onValidated,
-               const ndn::OnDataValidationFailed& onValidationFailed,
+               const ndn::security::DataValidationSuccessCallback& onValidated,
+               const ndn::security::DataValidationFailureCallback& onValidationFailed,
                const TimeoutNotify& timeoutNotify,
                int retry = 1);
 
   void
   onTargetData(const Interest& interest,
                const Data& data,
-               const ndn::OnDataValidated& onValidated,
-               const ndn::OnDataValidationFailed& onValidationFailed);
+               const ndn::security::DataValidationSuccessCallback& onValidated,
+               const ndn::security::DataValidationFailureCallback& onValidationFailed);
 
   void
   onTargetTimeout(const Interest& interest,
                   int retry,
-                  const ndn::OnDataValidated& onValidated,
-                  const ndn::OnDataValidationFailed& onValidationFailed,
+                  const ndn::security::DataValidationSuccessCallback& onValidated,
+                  const ndn::security::DataValidationFailureCallback& onValidationFailed,
                   const TimeoutNotify& timeoutNotify);
 
   // DNS listener
@@ -181,6 +180,9 @@
   void
   onDnsRegisterFailed(const Name& prefix, const std::string& failInfo);
 
+  void
+  onKeyInterest(const Name& prefix, const Interest& interest);
+
 signals:
   void
   contactEndorseInfoReady(const EndorseInfo& endorseInfo);
@@ -195,7 +197,7 @@
   nameListReady(const QStringList& certNameList);
 
   void
-  idCertReady(const ndn::IdentityCertificate& idCert);
+  idCertReady(const ndn::security::Certificate& idCert);
 
   void
   contactAliasListReady(const QStringList& aliasList);
@@ -263,14 +265,14 @@
   };
 
   typedef std::map<Name, FetchedInfo> BufferedContacts;
-  typedef std::map<Name, shared_ptr<ndn::IdentityCertificate> > BufferedIdCerts;
+  typedef std::map<Name, shared_ptr<ndn::security::Certificate> > BufferedIdCerts;
 
   typedef boost::recursive_mutex RecLock;
   typedef boost::unique_lock<RecLock> UniqueRecLock;
 
   // Conf
   shared_ptr<ContactStorage> m_contactStorage;
-  shared_ptr<ndn::Validator> m_validator;
+  shared_ptr<ndn::security::ValidatorConfig> m_validator;
   ndn::Face& m_face;
   ndn::KeyChain m_keyChain;
   Name m_identity;
@@ -281,7 +283,9 @@
   BufferedIdCerts m_bufferedIdCerts;
 
   // Tmp Dns
-  const ndn::RegisteredPrefixId* m_dnsListenerId;
+  shared_ptr<ndn::RegisteredPrefixHandle> m_dnsListenerId;
+  shared_ptr<ndn::RegisteredPrefixHandle> m_keyListenerId;
+  shared_ptr<ndn::RegisteredPrefixHandle> m_profileCertListenerId;
 
   RecLock m_collectCountMutex;
   size_t m_collectCount;
diff --git a/src/contact-panel.hpp b/src/contact-panel.hpp
index d164391..7eec224 100644
--- a/src/contact-panel.hpp
+++ b/src/contact-panel.hpp
@@ -14,6 +14,7 @@
 #include <QDialog>
 #include <QStringListModel>
 #include <QSqlTableModel>
+#include <QItemSelection>
 
 #include "set-alias-dialog.hpp"
 #include "endorse-combobox-delegate.hpp"
diff --git a/src/contact-storage.cpp b/src/contact-storage.cpp
index d59a707..d5e0fe2 100644
--- a/src/contact-storage.cpp
+++ b/src/contact-storage.cpp
@@ -13,11 +13,8 @@
 
 #include <boost/filesystem.hpp>
 #include "cryptopp.hpp"
-#include "logging.h"
 
 
-// INIT_LOGGER ("chronochat.ContactStorage");
-
 namespace chronochat {
 
 namespace fs = boost::filesystem;
@@ -25,8 +22,6 @@
 using std::string;
 using std::vector;
 
-using ndn::PublicKey;
-
 // user's own profile;
 const string INIT_SP_TABLE =
   "CREATE TABLE IF NOT EXISTS                          "
@@ -159,7 +154,7 @@
 static Block
 sqlite3_column_block(sqlite3_stmt* statement, int column)
 {
-  return Block(reinterpret_cast<const char*>(sqlite3_column_blob(statement, column)),
+  return Block(reinterpret_cast<const uint8_t*>(sqlite3_column_blob(statement, column)),
                sqlite3_column_bytes(statement, column));
 }
 
@@ -257,6 +252,27 @@
   sqlite3_finalize(stmt);
 }
 
+shared_ptr<EndorseCertificate>
+ContactStorage::getSelfEndorseCertificate()
+{
+  shared_ptr<EndorseCertificate> cert;
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2(m_db,
+                     "SELECT endorse_data FROM SelfEndorse where identity=?",
+                      -1, &stmt, 0);
+  sqlite3_bind_string(stmt, 1, m_identity.toUri(), SQLITE_TRANSIENT);
+
+  if (sqlite3_step(stmt) == SQLITE_ROW) {
+    cert = make_shared<EndorseCertificate>();
+    cert->wireDecode(sqlite3_column_block(stmt, 0));
+  }
+
+  sqlite3_finalize(stmt);
+
+  return cert;
+}
+
 void
 ContactStorage::addEndorseCertificate(const EndorseCertificate& endorseCertificate,
                                       const Name& identity)
@@ -283,7 +299,7 @@
   sqlite3_prepare_v2(m_db,
                      "INSERT OR REPLACE INTO CollectEndorse \
                       (endorser, endorse_name, endorse_data) \
-                      VALUES (?, ?, ?, ?)",
+                      VALUES (?, ?, ?)",
                      -1, &stmt, 0);
   sqlite3_bind_string(stmt, 1, endorserName.toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_string(stmt, 2, certName.toUri(), SQLITE_TRANSIENT);
@@ -315,6 +331,27 @@
   sqlite3_finalize(stmt);
 }
 
+shared_ptr<EndorseCertificate>
+ContactStorage::getCollectEndorseByName(const Name& name)
+{
+  shared_ptr<EndorseCertificate> cert;
+
+  sqlite3_stmt *stmt;
+  sqlite3_prepare_v2(m_db,
+                     "SELECT endorse_name, endorse_data FROM CollectEndorse where endorse_name=?",
+                      -1, &stmt, 0);
+  sqlite3_bind_string(stmt, 1, name.toUri(), SQLITE_TRANSIENT);
+
+  if (sqlite3_step(stmt) == SQLITE_ROW) {
+    cert = make_shared<EndorseCertificate>();
+    cert->wireDecode(sqlite3_column_block(stmt, 1));
+  }
+
+  sqlite3_finalize(stmt);
+
+  return cert;
+}
+
 void
 ContactStorage::getEndorseList(const Name& identity, vector<string>& endorseList)
 {
@@ -375,8 +412,8 @@
   sqlite3_bind_string(stmt, 2, contact.getAlias(), SQLITE_TRANSIENT);
   sqlite3_bind_string(stmt, 3, contact.getPublicKeyName().toUri(), SQLITE_TRANSIENT);
   sqlite3_bind_text(stmt, 4,
-                    reinterpret_cast<const char*>(contact.getPublicKey().get().buf()),
-                    contact.getPublicKey().get().size(), SQLITE_TRANSIENT);
+                    reinterpret_cast<const char*>(contact.getPublicKey().data()),
+                    contact.getPublicKey().size(), SQLITE_TRANSIENT);
   sqlite3_bind_int64(stmt, 5, time::toUnixTimestamp(contact.getNotBefore()).count());
   sqlite3_bind_int64(stmt, 6, time::toUnixTimestamp(contact.getNotAfter()).count());
   sqlite3_bind_int(stmt, 7, (isIntroducer ? 1 : 0));
@@ -433,7 +470,7 @@
   if (sqlite3_step(stmt) == SQLITE_ROW) {
     string alias = sqlite3_column_string(stmt, 0);
     string keyName = sqlite3_column_string(stmt, 1);
-    PublicKey key(sqlite3_column_text(stmt, 2), sqlite3_column_bytes (stmt, 2));
+    ndn::Buffer key(sqlite3_column_text(stmt, 2), sqlite3_column_bytes (stmt, 2));
     time::system_clock::TimePoint notBefore =
       time::fromUnixTimestamp(time::milliseconds(sqlite3_column_int64 (stmt, 3)));
     time::system_clock::TimePoint notAfter =
@@ -445,6 +482,9 @@
   }
   sqlite3_finalize(stmt);
 
+  if (!static_cast<bool>(contact))
+    return contact;
+
   sqlite3_prepare_v2(m_db,
                      "SELECT profile_type, profile_value FROM ContactProfile \
                       where profile_identity=?",
diff --git a/src/contact-storage.hpp b/src/contact-storage.hpp
index aa137b4..10bb117 100644
--- a/src/contact-storage.hpp
+++ b/src/contact-storage.hpp
@@ -44,6 +44,9 @@
   void
   addSelfEndorseCertificate(const EndorseCertificate& endorseCertificate);
 
+  shared_ptr<EndorseCertificate>
+  getSelfEndorseCertificate();
+
   void
   addEndorseCertificate(const EndorseCertificate& endorseCertificate, const Name& identity);
 
@@ -53,6 +56,9 @@
   void
   getCollectEndorse(EndorseCollection& endorseCollection);
 
+  shared_ptr<EndorseCertificate>
+  getCollectEndorseByName(const Name& name);
+
   void
   getEndorseList(const Name& identity, std::vector<std::string>& endorseList);
 
diff --git a/src/contact.hpp b/src/contact.hpp
index 8583d16..b0fe674 100644
--- a/src/contact.hpp
+++ b/src/contact.hpp
@@ -12,9 +12,10 @@
 #define CHRONOCHAT_CONTACT_HPP
 
 #include "common.hpp"
-#include <ndn-cxx/security/identity-certificate.hpp>
+#include <ndn-cxx/security/certificate.hpp>
 #include <ndn-cxx/util/regex.hpp>
 #include "endorse-certificate.hpp"
+#include "profile.hpp"
 
 namespace chronochat {
 
@@ -24,39 +25,51 @@
   typedef std::map<Name, shared_ptr<ndn::Regex> >::const_iterator const_iterator;
   typedef std::map<Name, shared_ptr<ndn::Regex> >::iterator iterator;
 
-  Contact(const ndn::IdentityCertificate& identityCertificate,
+  Contact(const ndn::security::Certificate& identityCertificate,
           bool isIntroducer = false,
           const std::string& alias = "")
-    : m_notBefore(identityCertificate.getNotBefore())
-    , m_notAfter(identityCertificate.getNotAfter())
+    : m_notBefore(time::system_clock::now())
+    , m_notAfter(time::system_clock::now() + time::days(3650))
     , m_isIntroducer(isIntroducer)
     , m_profile(identityCertificate)
   {
+    m_keyName = identityCertificate.getKeyName();
+    m_namespace = m_keyName.getPrefix(-2);
+    m_publicKey = identityCertificate.getPublicKey();
+
     m_name = m_profile.get("name");
+    m_name = m_name.empty() ? m_namespace.toUri() : m_name;
     m_alias = alias.empty() ? m_name : alias;
     m_institution = m_profile.get("institution");
 
-    m_keyName = identityCertificate.getPublicKeyName();
-    m_namespace = m_keyName.getPrefix(-1);
-    m_publicKey = identityCertificate.getPublicKeyInfo();
+    try {
+      m_notBefore = identityCertificate.getValidityPeriod().getPeriod().first;
+      m_notAfter = identityCertificate.getValidityPeriod().getPeriod().second;
+    } catch (tlv::Error&) {}
   }
 
   Contact(const EndorseCertificate& endorseCertificate,
           bool isIntroducer = false,
           const std::string& alias = "")
-    : m_notBefore(endorseCertificate.getNotBefore())
-    , m_notAfter(endorseCertificate.getNotAfter())
+    : m_notBefore(time::system_clock::now())
+    , m_notAfter(time::system_clock::now() + time::days(3650))
     , m_isIntroducer(isIntroducer)
   {
     m_profile = endorseCertificate.getProfile();
 
+    m_keyName = endorseCertificate.getKeyName().getPrefix(-1).append("KEY");
+    m_namespace = m_keyName.getPrefix(-3);
+    m_publicKey = endorseCertificate.getPublicKey();
+
     m_name = m_profile.get("name");
+    m_name = m_name.empty() ? m_namespace.toUri() : m_name;
     m_alias = alias.empty() ? m_name : alias;
     m_institution = m_profile.get("institution");
 
-    m_keyName = endorseCertificate.getPublicKeyName();;
-    m_namespace = m_keyName.getPrefix(-1);
-    m_publicKey = endorseCertificate.getPublicKeyInfo();
+    try {
+      m_notBefore = endorseCertificate.getValidityPeriod().getPeriod().first;
+      m_notAfter = endorseCertificate.getValidityPeriod().getPeriod().second;
+    } catch (tlv::Error&) {}
   }
 
   Contact(const Name& identity,
@@ -64,7 +77,7 @@
           const Name& keyName,
           const time::system_clock::TimePoint& notBefore,
           const time::system_clock::TimePoint& notAfter,
-          const ndn::PublicKey& key,
+          const ndn::Buffer& key,
           bool isIntroducer)
     : m_namespace(identity)
     , m_alias(alias)
@@ -126,7 +139,7 @@
     return m_keyName;
   }
 
-  const ndn::PublicKey&
+  const ndn::Buffer&
   getPublicKey() const
   {
     return m_publicKey;
@@ -224,7 +237,7 @@
   std::string m_name;
   std::string m_institution;
   Name m_keyName;
-  ndn::PublicKey m_publicKey;
+  ndn::Buffer m_publicKey;
   time::system_clock::TimePoint m_notBefore;
   time::system_clock::TimePoint m_notAfter;
 
diff --git a/src/controller-backend.cpp b/src/controller-backend.cpp
index a432366..7c6b8a5 100644
--- a/src/controller-backend.cpp
+++ b/src/controller-backend.cpp
@@ -13,22 +13,17 @@
 
 #ifndef Q_MOC_RUN
 #include <ndn-cxx/util/segment-fetcher.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <ndn-cxx/security/certificate-fetcher-offline.hpp>
 #include "invitation.hpp"
-#include "logging.h"
+#include <iostream>
 #endif
 
-
-INIT_LOGGER("ControllerBackend");
-
 namespace chronochat {
 
 using std::string;
 
 using ndn::Face;
-using ndn::IdentityCertificate;
-using ndn::OnInterestValidated;
-using ndn::OnInterestValidationFailed;
-
 
 static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
   ndn::name::Component::fromEscapedString("%F0%2E");
@@ -39,7 +34,6 @@
   : QThread(parent)
   , m_shouldResume(false)
   , m_contactManager(m_face)
-  , m_invitationListenerId(0)
 {
   // connection to contact manager
   connect(this, SIGNAL(identityUpdated(const QString&)),
@@ -48,6 +42,7 @@
   connect(&m_contactManager, SIGNAL(contactIdListReady(const QStringList&)),
           this, SLOT(onContactIdListReady(const QStringList&)));
 
+  m_validator = make_shared<ndn::security::ValidatorNull>();
 }
 
 ControllerBackend::~ControllerBackend()
@@ -141,31 +136,32 @@
   invitationPrefix.append(m_identity).append("CHRONOCHAT-INVITATION");
   requestPrefix.append(m_identity).append("CHRONOCHAT-INVITATION-REQUEST");
 
-  const ndn::RegisteredPrefixId* invitationListenerId =
-    m_face.setInterestFilter(invitationPrefix,
+  auto invitationListenerId =
+    make_shared<ndn::RegisteredPrefixHandle>(m_face.setInterestFilter(invitationPrefix,
                              bind(&ControllerBackend::onInvitationInterest,
                                   this, _1, _2, offset),
                              bind(&ControllerBackend::onInvitationRegisterFailed,
-                                  this, _1, _2));
+                                  this, _1, _2)));
 
   if (m_invitationListenerId != 0) {
-    m_face.unregisterPrefix(m_invitationListenerId,
-                            bind(&ControllerBackend::onInvitationPrefixReset, this),
-                            bind(&ControllerBackend::onInvitationPrefixResetFailed, this, _1));
+    invitationListenerId->unregister(
+      bind(&ControllerBackend::onInvitationPrefixReset, this),
+      bind(&ControllerBackend::onInvitationPrefixResetFailed, this, _1));
   }
 
   m_invitationListenerId = invitationListenerId;
 
-  const ndn::RegisteredPrefixId* requestListenerId =
-    m_face.setInterestFilter(requestPrefix,
-                             bind(&ControllerBackend::onInvitationRequestInterest,
-                                  this, _1, _2, offset),
-                             [] (const Name& prefix, const std::string& failInfo) {});
+  auto requestListenerId =
+    make_shared<ndn::RegisteredPrefixHandle>(
+      m_face.setInterestFilter(requestPrefix,
+                               bind(&ControllerBackend::onInvitationRequestInterest,
+                                    this, _1, _2, offset),
+                               [] (const Name& prefix, const std::string& failInfo) {}));
 
   if (m_requestListenerId != 0) {
-    m_face.unregisterPrefix(m_requestListenerId,
-                            []{},
-                            [] (const std::string& failInfo) {});
+    m_requestListenerId->unregister(
+      []{},
+      [] (const std::string& failInfo) {});
   }
 
   m_requestListenerId = requestListenerId;
@@ -210,11 +206,10 @@
     return;
   }
 
-  OnInterestValidated onValidated = bind(&ControllerBackend::onInvitationValidated, this, _1);
-  OnInterestValidationFailed onFailed = bind(&ControllerBackend::onInvitationValidationFailed,
-                                             this, _1, _2);
-
-  m_validator.validate(*invitationInterest, onValidated, onFailed);
+  m_validator->validate(
+    *invitationInterest,
+    bind(&ControllerBackend::onInvitationValidated, this, _1),
+    bind(&ControllerBackend::onInvitationValidationFailed, this, _1, _2));
 }
 
 void
@@ -248,20 +243,20 @@
 }
 
 void
-ControllerBackend::onInvitationValidated(const shared_ptr<const Interest>& interest)
+ControllerBackend::onInvitationValidated(const Interest& interest)
 {
-  Invitation invitation(interest->getName());
+  Invitation invitation(interest.getName());
   // Should be obtained via a method of ContactManager.
-  string alias = invitation.getInviterCertificate().getPublicKeyName().getPrefix(-1).toUri();
+  string alias = invitation.getInviterCertificate().getKeyName().getPrefix(-1).toUri();
 
   emit invitationValidated(QString::fromStdString(alias),
                            QString::fromStdString(invitation.getChatroom()),
-                           interest->getName());
+                           interest.getName());
 }
 
 void
-ControllerBackend::onInvitationValidationFailed(const shared_ptr<const Interest>& interest,
-                                                string failureInfo)
+ControllerBackend::onInvitationValidationFailed(const Interest& interest,
+                                                const ndn::security::ValidationError& failureInfo)
 {
   // _LOG_DEBUG("Invitation: " << interest->getName() <<
   //            " cannot not be validated due to: " << failureInfo);
@@ -317,7 +312,7 @@
 }
 
 void
-ControllerBackend::onRequestResponse(const Interest& interest, Data& data)
+ControllerBackend::onRequestResponse(const Interest& interest, const Data& data)
 {
   size_t i;
   Name interestName = interest.getName();
@@ -344,6 +339,7 @@
   if (resendTimes < MAXIMUM_REQUEST)
     m_face.expressInterest(interest,
                            bind(&ControllerBackend::onRequestResponse, this, _1, _2),
+                           bind(&ControllerBackend::onRequestTimeout, this, _1, resendTimes + 1),
                            bind(&ControllerBackend::onRequestTimeout, this, _1, resendTimes + 1));
   else
     emit invitationRequestResult("Invitation request times out.");
@@ -384,11 +380,11 @@
   interest.setInterestLifetime(time::milliseconds(1000));
   interest.setMustBeFresh(true);
 
-  ndn::util::SegmentFetcher::fetch(m_face,
-                                   interest,
-                                   m_nullValidator,
-                                   bind(&ControllerBackend::onLocalPrefix, this, _1),
-                                   bind(&ControllerBackend::onLocalPrefixError, this, _1, _2));
+  auto fetcher = ndn::util::SegmentFetcher::start(m_face,
+                                                  interest,
+                                                  m_nullValidator);
+  fetcher->onComplete.connect(bind(&ControllerBackend::onLocalPrefix, this, _1));
+  fetcher->onError.connect(bind(&ControllerBackend::onLocalPrefixError, this, _1, _2));
 }
 
 void
@@ -411,7 +407,7 @@
 ControllerBackend::onInvitationResponded(const ndn::Name& invitationName, bool accepted)
 {
   shared_ptr<Data> response = make_shared<Data>();
-  shared_ptr<IdentityCertificate> chatroomCert;
+  shared_ptr<ndn::security::Certificate> chatroomCert;
 
   // generate reply;
   if (accepted) {
@@ -422,8 +418,8 @@
 
     // We should create a particular certificate for this chatroom,
     //but let's use default one for now.
-    chatroomCert
-      = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(m_identity));
+    chatroomCert = make_shared<ndn::security::Certificate>(
+      m_keyChain.createIdentity(m_identity).getDefaultKey().getDefaultCertificate());
 
     response->setContent(chatroomCert->wireEncode());
     response->setFreshnessPeriod(time::milliseconds(1000));
@@ -433,7 +429,7 @@
     response->setFreshnessPeriod(time::milliseconds(1000));
   }
 
-  m_keyChain.signByIdentity(*response, m_identity);
+  m_keyChain.sign(*response, ndn::security::signingByIdentity(m_identity));
 
   // Check if we need a wrapper
   Name invitationRoutingPrefix = getInvitationRoutingPrefix();
@@ -451,7 +447,7 @@
     wrappedData->setContent(response->wireEncode());
     wrappedData->setFreshnessPeriod(time::milliseconds(1000));
 
-    m_keyChain.signByIdentity(*wrappedData, m_identity);
+    m_keyChain.sign(*wrappedData, ndn::security::signingByIdentity(m_identity));
     m_face.put(*wrappedData);
   }
 
@@ -469,7 +465,8 @@
   else
     response->setContent(ndn::makeNonNegativeIntegerBlock(tlv::Content, 0));
 
-  m_keyChain.signByIdentity(*response, m_identity);
+  response->setFreshnessPeriod(time::milliseconds(1000));
+  m_keyChain.sign(*response, ndn::security::signingByIdentity(m_identity));
   m_ims.insert(*response);
   m_face.put(*response);
 }
@@ -491,6 +488,7 @@
   interest.getNonce();
   m_face.expressInterest(interest,
                          bind(&ControllerBackend::onRequestResponse, this, _1, _2),
+                         bind(&ControllerBackend::onRequestTimeout, this, _1, 0),
                          bind(&ControllerBackend::onRequestTimeout, this, _1, 0));
 }
 
@@ -500,10 +498,10 @@
   ContactList contactList;
 
   m_contactManager.getContactList(contactList);
-  m_validator.cleanTrustAnchor();
+  // m_validator.cleanTrustAnchor();
 
-  for (ContactList::const_iterator it  = contactList.begin(); it != contactList.end(); it++)
-    m_validator.addTrustAnchor((*it)->getPublicKeyName(), (*it)->getPublicKey());
+  // for (ContactList::const_iterator it  = contactList.begin(); it != contactList.end(); it++)
+    // m_validator.addTrustAnchor((*it)->getPublicKeyName(), (*it)->getPublicKey());
 
 }
 
diff --git a/src/controller-backend.hpp b/src/controller-backend.hpp
index be2cf25..18b1cd8 100644
--- a/src/controller-backend.hpp
+++ b/src/controller-backend.hpp
@@ -20,10 +20,10 @@
 #include "common.hpp"
 #include "contact-manager.hpp"
 #include "invitation.hpp"
-#include "validator-invitation.hpp"
 #include <ndn-cxx/security/key-chain.hpp>
-#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
+#include <ndn-cxx/ims/in-memory-storage-persistent.hpp>
 #include <ndn-cxx/security/validator-null.hpp>
+#include <ndn-cxx/face.hpp>
 #include <boost/thread.hpp>
 #include <mutex>
 #endif
@@ -74,11 +74,11 @@
   onInvitationRegisterFailed(const Name& prefix, const std::string& failInfo);
 
   void
-  onInvitationValidated(const shared_ptr<const Interest>& interest);
+  onInvitationValidated(const Interest& interest);
 
   void
-  onInvitationValidationFailed(const shared_ptr<const Interest>& interest,
-                               std::string failureInfo);
+  onInvitationValidationFailed(const Interest& interest,
+                               const ndn::security::ValidationError& failureInfo);
 
   void
   onLocalPrefix(const ndn::ConstBufferPtr& data);
@@ -90,7 +90,7 @@
   updateLocalPrefix(const Name& localPrefix);
 
   void
-  onRequestResponse(const Interest& interest, Data& data);
+  onRequestResponse(const Interest& interest, const Data& data);
 
   void
   onRequestTimeout(const Interest& interest, int& resendTimes);
@@ -166,12 +166,12 @@
 
   // Security related;
   ndn::KeyChain m_keyChain;
-  ValidatorInvitation m_validator;
-  ndn::ValidatorNull m_nullValidator;
+  shared_ptr<ndn::security::Validator> m_validator;
+  ndn::security::ValidatorNull m_nullValidator;
 
   // RegisteredPrefixId
-  const ndn::RegisteredPrefixId* m_invitationListenerId;
-  const ndn::RegisteredPrefixId* m_requestListenerId;
+  shared_ptr<ndn::RegisteredPrefixHandle> m_invitationListenerId;
+  shared_ptr<ndn::RegisteredPrefixHandle> m_requestListenerId;
 
   // ChatRoomList
   QStringList m_chatDialogList;
@@ -180,7 +180,7 @@
   std::mutex m_resumeMutex;
   std::mutex m_nfdConnectionMutex;
 
-  ndn::util::InMemoryStoragePersistent m_ims;
+  ndn::InMemoryStoragePersistent m_ims;
 };
 
 } // namespace chronochat
diff --git a/src/controller.cpp b/src/controller.cpp
index b45e1dd..d41b65d 100644
--- a/src/controller.cpp
+++ b/src/controller.cpp
@@ -28,7 +28,7 @@
 INIT_LOGGER("chronochat.Controller");
 
 Q_DECLARE_METATYPE(ndn::Name)
-Q_DECLARE_METATYPE(ndn::IdentityCertificate)
+Q_DECLARE_METATYPE(ndn::security::Certificate)
 Q_DECLARE_METATYPE(chronochat::EndorseInfo)
 Q_DECLARE_METATYPE(ndn::Interest)
 Q_DECLARE_METATYPE(size_t)
@@ -57,8 +57,8 @@
   , m_discoveryPanel(new DiscoveryPanel(this))
 {
   qRegisterMetaType<ndn::Name>("ndn.Name");
-  qRegisterMetaType<ndn::IdentityCertificate>("ndn.IdentityCertificate");
-  qRegisterMetaType<chronochat::EndorseInfo>("chronochat.EndorseInfo");
+  qRegisterMetaType<ndn::security::Certificate>("ndn.security.v2.Certificate");
+  qRegisterMetaType<chronochat::EndorseInfo>("EndorseInfo");
   qRegisterMetaType<ndn::Interest>("ndn.Interest");
   qRegisterMetaType<size_t>("size_t");
   qRegisterMetaType<chronochat::ChatroomInfo>("chronochat.Chatroom");
@@ -126,8 +126,8 @@
           m_browseContactDialog, SLOT(onIdCertNameListReady(const QStringList&)));
   connect(m_backend.getContactManager(), SIGNAL(nameListReady(const QStringList&)),
           m_browseContactDialog, SLOT(onNameListReady(const QStringList&)));
-  connect(m_backend.getContactManager(), SIGNAL(idCertReady(const ndn::IdentityCertificate&)),
-          m_browseContactDialog, SLOT(onIdCertReady(const ndn::IdentityCertificate&)));
+  connect(m_backend.getContactManager(), SIGNAL(idCertReady(const ndn::security::Certificate&)),
+          m_browseContactDialog, SLOT(onIdCertReady(const ndn::security::Certificate&)));
 
   // Connection to ContactPanel
   connect(m_contactPanel, SIGNAL(waitForContactList()),
@@ -322,15 +322,15 @@
     else
       m_nick = m_identity.get(-1).toUri();
   }
-  catch (tlv::Error) {
+  catch (tlv::Error&) {
     try {
       ndn::KeyChain keyChain;
-      m_identity = keyChain.getDefaultIdentity();
+      m_identity = keyChain.getPib().getDefaultIdentity().getName();
     }
-    catch (ndn::KeyChain::Error) {
+    catch (ndn::security::pib::Pib::Error&) {
       m_identity.clear();
       m_identity.append("chronochat-tmp-identity")
-        .append(getRandomString());
+                .append(getRandomString());
     }
     m_nick = m_identity.get(-1).toUri();
   }
@@ -423,8 +423,8 @@
 void
 Controller::updateMenu()
 {
-  QMenu* menu = new QMenu(this);
-  QMenu* closeMenu = 0;
+  m_trayIconMenu->clear();
+  QMenu* menu = m_trayIconMenu;
 
   menu->addAction(m_startChatroom);
   menu->addAction(m_chatroomDiscoveryAction);
@@ -448,23 +448,18 @@
   menu->addAction(m_updateLocalPrefixAction);
   menu->addSeparator();
   menu->addAction(m_minimizeAction);
-  closeMenu = menu->addMenu("Close chatroom");
+  m_closeMenu = menu->addMenu("Close chatroom");
   {
     ChatActionList::const_iterator it = m_closeActionList.begin();
     ChatActionList::const_iterator end = m_closeActionList.end();
     if (it == end)
-      closeMenu->setEnabled(false);
+      m_closeMenu->setEnabled(false);
     else
       for (; it != end; it++)
-        closeMenu->addAction(it->second);
+        m_closeMenu->addAction(it->second);
   }
   menu->addSeparator();
   menu->addAction(m_quitAction);
-
-  m_trayIcon->setContextMenu(menu);
-  delete m_trayIconMenu;
-  m_trayIconMenu = menu;
-  m_closeMenu = closeMenu;
 }
 
 string
@@ -616,6 +611,7 @@
 void
 Controller::onProfileEditorAction()
 {
+  m_profileEditor->resetPanel();
   m_profileEditor->show();
   m_profileEditor->raise();
 }
@@ -770,6 +766,8 @@
 void
 Controller::onRemoveChatDialog(const QString& chatroomName)
 {
+  emit removeChatroom(chatroomName);
+
   ChatDialogList::iterator it = m_chatDialogList.find(chatroomName.toStdString());
   if (it != m_chatDialogList.end()) {
     ChatDialog* deletedChat = it->second;
@@ -804,7 +802,7 @@
   if (m_isInConnectionDetection)
     return;
   // begin a thread
-  
+
   m_isInConnectionDetection = true;
   m_nfdConnectionChecker = new NfdConnectionChecker(this);
 
diff --git a/src/digest-tree-scene.cpp b/src/digest-tree-scene.cpp
index 17bc67a..55d9a36 100644
--- a/src/digest-tree-scene.cpp
+++ b/src/digest-tree-scene.cpp
@@ -12,10 +12,10 @@
 #include "digest-tree-scene.hpp"
 
 #include <QtGui>
+#include <QGraphicsTextItem>
 
 #ifndef Q_MOC_RUN
 #include <vector>
-#include <iostream>
 #include <assert.h>
 #include <boost/lexical_cast.hpp>
 #include <memory>
@@ -28,7 +28,7 @@
 
 //DisplayUserPtr DisplayUserNullPtr;
 
-DigestTreeScene::DigestTreeScene(QWidget *parent)
+DigestTreeScene::DigestTreeScene(QObject *parent)
   : QGraphicsScene(parent)
 {
   m_previouslyUpdatedUser = DisplayUserNullPtr;
diff --git a/src/digest-tree-scene.hpp b/src/digest-tree-scene.hpp
index 0e69528..562feeb 100644
--- a/src/digest-tree-scene.hpp
+++ b/src/digest-tree-scene.hpp
@@ -12,7 +12,7 @@
 #ifndef CHRONOCHAT_DIGEST_TREE_SCENE_HPP
 #define CHRONOCHAT_DIGEST_TREE_SCENE_HPP
 
-#include <QtGui/QGraphicsScene>
+#include <QGraphicsScene>
 #include <QColor>
 #include <QMap>
 
@@ -44,7 +44,7 @@
   Q_OBJECT
 
 public:
-  DigestTreeScene(QWidget *parent = 0);
+  DigestTreeScene(QObject *parent = 0);
 
   void
   processSyncUpdate(const std::vector<chronochat::NodeInfo>& nodeInfos,
diff --git a/src/discovery-panel.cpp b/src/discovery-panel.cpp
index b7c0ed6..06c7cf7 100644
--- a/src/discovery-panel.cpp
+++ b/src/discovery-panel.cpp
@@ -21,7 +21,6 @@
 
 namespace chronochat {
 
-static const time::seconds REFRESH_INTERVAL(60);
 static const ndn::Name::Component ROUTING_HINT_SEPARATOR =
   ndn::name::Component::fromEscapedString("%F0%2E");
 
@@ -91,7 +90,6 @@
 void
 DiscoveryPanel::onIdentityUpdated(const QString& identity)
 {
-  resetPanel();
 }
 
 void
diff --git a/src/discovery-panel.hpp b/src/discovery-panel.hpp
index 1b5bd92..473283f 100644
--- a/src/discovery-panel.hpp
+++ b/src/discovery-panel.hpp
@@ -13,6 +13,7 @@
 
 #include <QDialog>
 #include <QStringListModel>
+#include <QItemSelection>
 
 #ifndef Q_MOC_RUN
 #include "chatroom-info.hpp"
diff --git a/src/endorse-certificate.cpp b/src/endorse-certificate.cpp
index cbeb18c..f9286c6 100644
--- a/src/endorse-certificate.cpp
+++ b/src/endorse-certificate.cpp
@@ -12,6 +12,8 @@
 #include "endorse-certificate.hpp"
 #include <boost/iostreams/stream.hpp>
 #include <ndn-cxx/encoding/buffer-stream.hpp>
+#include <ndn-cxx/security/additional-description.hpp>
+#include <ndn-cxx/security/validity-period.hpp>
 #include "endorse-extension.hpp"
 #include <list>
 
@@ -20,16 +22,9 @@
 using std::vector;
 using std::string;
 
-using ndn::PublicKey;
-using ndn::IdentityCertificate;
-using ndn::CertificateSubjectDescription;
-using ndn::CertificateExtension;
-using ndn::OID;
+using ndn::security::Certificate;
 using ndn::OBufferStream;
 
-const OID EndorseCertificate::PROFILE_EXT_OID("1.3.6.1.5.32.2.1");
-const OID EndorseCertificate::ENDORSE_EXT_OID("1.3.6.1.5.32.2.2");
-
 const vector<string> EndorseCertificate::DEFAULT_ENDORSE_LIST;
 
 EndorseExtension&
@@ -51,107 +46,132 @@
   return endorseExtension;
 }
 
-EndorseCertificate::EndorseCertificate(const IdentityCertificate& kskCertificate,
+EndorseCertificate::EndorseCertificate(const Certificate& kskCertificate,
                                        const Profile& profile,
                                        const vector<string>& endorseList)
   : Certificate()
   , m_profile(profile)
   , m_endorseList(endorseList)
 {
-  m_keyName = IdentityCertificate::certificateNameToPublicKeyName(kskCertificate.getName());
-  m_signer = m_keyName;
+  setName(kskCertificate.getKeyName().getPrefix(-2)
+                        .append("PROFILE-CERT")
+                        .append("KEY")
+                        .append(kskCertificate.getKeyId())
+                        .append("self")
+                        .appendTimestamp());
 
-  Name dataName = m_keyName;
-  dataName.append("PROFILE-CERT").append(m_signer.wireEncode()).appendVersion();
-  setName(dataName);
+  m_signer = kskCertificate.getKeyName();
 
-  setNotBefore(kskCertificate.getNotBefore());
-  setNotAfter(kskCertificate.getNotAfter());
-  addSubjectDescription(CertificateSubjectDescription(OID("2.5.4.41"), m_keyName.toUri()));
-  setPublicKeyInfo(kskCertificate.getPublicKeyInfo());
+  setMetaInfo(kskCertificate.getMetaInfo());
+  setContent(kskCertificate.getPublicKey().data(), kskCertificate.getPublicKey().size());
 
-  Block profileWire = m_profile.wireEncode();
-  addExtension(CertificateExtension(PROFILE_EXT_OID, true, ndn::Buffer(profileWire.wire(),
-                                                                       profileWire.size())));
+  ndn::security::AdditionalDescription description;
+  description.set("2.5.4.41", getKeyName().toUri());
+  description.set("signer", m_signer.toUri());
 
   EndorseExtension endorseExtension;
   endorseExtension << m_endorseList;
-  Block endorseWire = endorseExtension.wireEncode();
-  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, ndn::Buffer(endorseWire.wire(),
-                                                                       endorseWire.size())));
 
-  encode();
+  ndn::SignatureInfo signatureInfo;
+  signatureInfo.addCustomTlv(description.wireEncode());
+  signatureInfo.addCustomTlv(m_profile.wireEncode());
+
+  if (m_endorseList.size() > 0)
+    signatureInfo.addCustomTlv(endorseExtension.wireEncode());
+
+  try {
+    signatureInfo.setValidityPeriod(kskCertificate.getValidityPeriod());
+  } catch (tlv::Error&) {
+    signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(
+      time::system_clock::now(), time::system_clock::now() + time::days(3650)));
+  }
+
+  setSignatureInfo(signatureInfo);
 }
 
 EndorseCertificate::EndorseCertificate(const EndorseCertificate& endorseCertificate,
                                        const Name& signer,
                                        const vector<string>& endorseList)
   : Certificate()
-  , m_keyName(endorseCertificate.m_keyName)
   , m_signer(signer)
   , m_profile(endorseCertificate.m_profile)
   , m_endorseList(endorseList)
 {
-  Name dataName = m_keyName;
-  dataName.append("PROFILE-CERT").append(m_signer.wireEncode()).appendVersion();
-  setName(dataName);
+  setName(endorseCertificate.getName()
+                 .getPrefix(-2)
+                 .append(m_signer.wireEncode())
+                 .appendVersion());
 
-  setNotBefore(endorseCertificate.getNotBefore());
-  setNotAfter(endorseCertificate.getNotAfter());
-  addSubjectDescription(CertificateSubjectDescription(OID("2.5.4.41"), m_keyName.toUri()));
-  setPublicKeyInfo(endorseCertificate.getPublicKeyInfo());
+  setMetaInfo(endorseCertificate.getMetaInfo());
+  setContent(endorseCertificate.getPublicKey().data(), endorseCertificate.getPublicKey().size());
 
-  Block profileWire = m_profile.wireEncode();
-  addExtension(CertificateExtension(PROFILE_EXT_OID, true, ndn::Buffer(profileWire.wire(),
-                                                                       profileWire.size())));
+  ndn::security::AdditionalDescription description;
+  description.set("2.5.4.41", getKeyName().toUri());
+  description.set("signer", m_signer.toUri());
 
   EndorseExtension endorseExtension;
   endorseExtension << m_endorseList;
-  Block endorseWire = endorseExtension.wireEncode();
-  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, ndn::Buffer(endorseWire.wire(),
-                                                                       endorseWire.size())));
 
-  encode();
+  ndn::SignatureInfo signatureInfo;
+  signatureInfo.addCustomTlv(description.wireEncode());
+  signatureInfo.addCustomTlv(m_profile.wireEncode());
+
+  if (m_endorseList.size() > 0)
+    signatureInfo.addCustomTlv(endorseExtension.wireEncode());
+
+  try {
+    signatureInfo.setValidityPeriod(endorseCertificate.getValidityPeriod());
+  } catch (tlv::Error&) {
+    signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(
+      time::system_clock::now(), time::system_clock::now() + time::days(3650)));
+  }
+
+  setSignatureInfo(signatureInfo);
 }
 
 EndorseCertificate::EndorseCertificate(const Name& keyName,
-                                       const PublicKey& key,
+                                       const ndn::Buffer& key,
                                        const time::system_clock::TimePoint& notBefore,
                                        const time::system_clock::TimePoint& notAfter,
+                                       const Name::Component& signerKeyId,
                                        const Name& signer,
                                        const Profile& profile,
                                        const vector<string>& endorseList)
   : Certificate()
-  , m_keyName(keyName)
   , m_signer(signer)
   , m_profile(profile)
   , m_endorseList(endorseList)
 {
-  Name dataName = m_keyName;
-  dataName.append("PROFILE-CERT").append(m_signer.wireEncode()).appendVersion();
-  setName(dataName);
+  setName(keyName.getPrefix(-2)
+                 .append("PROFILE-CERT")
+                 .append("KEY")
+                 .append(signerKeyId)
+                 .append(m_signer.wireEncode())
+                 .appendVersion());
 
-  setNotBefore(notBefore);
-  setNotAfter(notAfter);
-  addSubjectDescription(CertificateSubjectDescription(OID("2.5.4.41"), m_keyName.toUri()));
-  setPublicKeyInfo(key);
+  setContent(key.data(), key.size());
 
-  Block profileWire = m_profile.wireEncode();
-  addExtension(CertificateExtension(PROFILE_EXT_OID, true, ndn::Buffer(profileWire.wire(),
-                                                                       profileWire.size())));
+  ndn::security::AdditionalDescription description;
+  description.set("2.5.4.41", keyName.toUri());
+  description.set("signer", m_signer.toUri());
 
   EndorseExtension endorseExtension;
   endorseExtension << m_endorseList;
-  Block endorseWire = endorseExtension.wireEncode();
-  addExtension(CertificateExtension(ENDORSE_EXT_OID, true, ndn::Buffer(endorseWire.wire(),
-                                                                       endorseWire.size())));
 
-  encode();
+  ndn::SignatureInfo signatureInfo;
+  signatureInfo.addCustomTlv(description.wireEncode());
+  signatureInfo.addCustomTlv(m_profile.wireEncode());
+
+  if (m_endorseList.size() > 0)
+    signatureInfo.addCustomTlv(endorseExtension.wireEncode());
+
+  signatureInfo.setValidityPeriod(ndn::security::ValidityPeriod(notBefore, notAfter));
+
+  setSignatureInfo(signatureInfo);
 }
 
 EndorseCertificate::EndorseCertificate(const EndorseCertificate& endorseCertificate)
   : Certificate(endorseCertificate)
-  , m_keyName(endorseCertificate.m_keyName)
   , m_signer(endorseCertificate.m_signer)
   , m_profile(endorseCertificate.m_profile)
   , m_endorseList(endorseCertificate.m_endorseList)
@@ -161,25 +181,22 @@
 EndorseCertificate::EndorseCertificate(const Data& data)
   : Certificate(data)
 {
-  const Name& dataName = data.getName();
 
-  if(dataName.size() < 3 || dataName.get(-3).toUri() != "PROFILE-CERT")
-    throw Error("No PROFILE-CERT component in data name!");
+  auto additionalWire = getSignatureInfo().getCustomTlv(tlv::AdditionalDescription);
+  if (additionalWire) {
+    ndn::security::AdditionalDescription additional(*additionalWire);
+    m_signer = additional.get("signer");
+  }
 
-  m_keyName = dataName.getPrefix(-3);
-  m_signer.wireDecode(dataName.get(-2).blockFromValue());
+  auto profileWire = getSignatureInfo().getCustomTlv(tlv::Profile);
+  if (profileWire) {
+    m_profile = Profile(*profileWire);
+  }
 
-
-  for (const auto& entry : m_extensionList) {
-    if (PROFILE_EXT_OID == entry.getOid()) {
-      m_profile.wireDecode(Block(entry.getValue().buf(), entry.getValue().size()));
-    }
-    if (ENDORSE_EXT_OID == entry.getOid()) {
-      EndorseExtension endorseExtension;
-      endorseExtension.wireDecode(Block(entry.getValue().buf(), entry.getValue().size()));
-
-      endorseExtension >> m_endorseList;
-    }
+  auto endorseExtensionBlock = getSignatureInfo().getCustomTlv(tlv::EndorseExtension);
+  if (endorseExtensionBlock) {
+    EndorseExtension endorseExtension(*endorseExtensionBlock);
+    endorseExtension >> m_endorseList;
   }
 }
 
diff --git a/src/endorse-certificate.hpp b/src/endorse-certificate.hpp
index 51b3b50..defc8a8 100644
--- a/src/endorse-certificate.hpp
+++ b/src/endorse-certificate.hpp
@@ -16,14 +16,14 @@
 
 namespace chronochat {
 
-class EndorseCertificate : public ndn::Certificate
+class EndorseCertificate : public ndn::security::Certificate
 {
 public:
-  class Error : public ndn::Certificate::Error
+  class Error : public ndn::security::Certificate::Error
   {
   public:
     Error(const std::string& what)
-      : ndn::Certificate::Error(what)
+      : ndn::security::Certificate::Error(what)
     {
     }
   };
@@ -32,7 +32,7 @@
 
   EndorseCertificate() {}
 
-  EndorseCertificate(const ndn::IdentityCertificate& kskCertificate,
+  EndorseCertificate(const ndn::security::Certificate& kskCertificate,
                      const Profile& profile,
                      const std::vector<std::string>& endorseList = DEFAULT_ENDORSE_LIST);
 
@@ -41,9 +41,10 @@
                      const std::vector<std::string>& endorseList = DEFAULT_ENDORSE_LIST);
 
   EndorseCertificate(const Name& keyName,
-                     const ndn::PublicKey& key,
+                     const ndn::Buffer& key,
                      const time::system_clock::TimePoint& notBefore,
                      const time::system_clock::TimePoint& notAfter,
+                     const Name::Component& signerKeyId,
                      const Name& signer,
                      const Profile& profile,
                      const std::vector<std::string>& endorseList = DEFAULT_ENDORSE_LIST);
@@ -75,21 +76,10 @@
     return m_endorseList;
   }
 
-  const Name&
-  getPublicKeyName () const
-  {
-    return m_keyName;
-  }
-
 private:
-  static const ndn::OID PROFILE_EXT_OID;
-  static const ndn::OID ENDORSE_EXT_OID;
-
-  Name m_keyName;
-  Name m_signer; // signing key name
+  Name m_signer;
   Profile m_profile;
   std::vector<std::string> m_endorseList;
-
 };
 
 } // namespace chronochat
diff --git a/src/endorse-collection.cpp b/src/endorse-collection.cpp
index c8dafe6..9b937a7 100644
--- a/src/endorse-collection.cpp
+++ b/src/endorse-collection.cpp
@@ -23,7 +23,7 @@
   this->wireDecode(endorseWire);
 }
 
-template<bool T>
+template<ndn::encoding::Tag T>
 size_t
 EndorseCollection::wireEncode(ndn::EncodingImpl<T>& block) const
 {
diff --git a/src/endorse-collection.hpp b/src/endorse-collection.hpp
index 42a0979..dd16bc3 100644
--- a/src/endorse-collection.hpp
+++ b/src/endorse-collection.hpp
@@ -60,7 +60,7 @@
   addCollectionEntry(const Name& certName, const std::string& hash);
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& block) const;
 
diff --git a/src/endorse-combobox-delegate.cpp b/src/endorse-combobox-delegate.cpp
index 1888baf..319135a 100644
--- a/src/endorse-combobox-delegate.cpp
+++ b/src/endorse-combobox-delegate.cpp
@@ -68,7 +68,7 @@
                                const QStyleOptionViewItem& option,
                                const QModelIndex& index) const
 {
-  QStyleOptionViewItemV4 myOption = option;
+  QStyleOptionViewItem myOption = option;
   QString text = m_items[index.model()->data(index, Qt::EditRole).toUInt()].c_str();
 
   myOption.text = text;
diff --git a/src/endorse-extension.cpp b/src/endorse-extension.cpp
index ac862ac..0c9f6c4 100644
--- a/src/endorse-extension.cpp
+++ b/src/endorse-extension.cpp
@@ -23,7 +23,7 @@
   this->wireDecode(endorseWire);
 }
 
-template<bool T>
+template<ndn::encoding::Tag T>
 size_t
 EndorseExtension::wireEncode(ndn::EncodingImpl<T>& block) const
 {
diff --git a/src/endorse-extension.hpp b/src/endorse-extension.hpp
index 844c55c..c8bd11e 100644
--- a/src/endorse-extension.hpp
+++ b/src/endorse-extension.hpp
@@ -57,7 +57,7 @@
   removeEntry(const std::string& entry);
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& block) const;
 
diff --git a/src/endorse-info.cpp b/src/endorse-info.cpp
index 985c304..1aa9385 100644
--- a/src/endorse-info.cpp
+++ b/src/endorse-info.cpp
@@ -24,7 +24,7 @@
   this->wireDecode(endorseWire);
 }
 
-template<bool T>
+template<ndn::encoding::Tag T>
 size_t
 EndorseInfo::wireEncode(ndn::EncodingImpl<T>& block) const
 {
diff --git a/src/endorse-info.hpp b/src/endorse-info.hpp
index 921e711..a794c63 100644
--- a/src/endorse-info.hpp
+++ b/src/endorse-info.hpp
@@ -60,7 +60,7 @@
   addEndorsement(const std::string& type, const std::string& value, const std::string& count);
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& block) const;
 
diff --git a/src/invitation.cpp b/src/invitation.cpp
index f311ad0..e7d2ac5 100644
--- a/src/invitation.cpp
+++ b/src/invitation.cpp
@@ -18,7 +18,7 @@
 
 using std::string;
 
-using ndn::IdentityCertificate;
+using ndn::security::Certificate;
 
 const size_t  Invitation::NAME_SIZE_MIN         = 7;
 const ssize_t Invitation::SIGNATURE             = -1;
@@ -51,7 +51,7 @@
 Invitation::Invitation(const Name& inviteeNameSpace,
                        const string& chatroom,
                        const Name& inviterRoutingPrefix,
-                       const IdentityCertificate& inviterCertificate)
+                       const Certificate& inviterCertificate)
   : m_inviteeNameSpace(inviteeNameSpace)
   , m_chatroom(chatroom)
   , m_inviterRoutingPrefix(inviterRoutingPrefix)
diff --git a/src/invitation.hpp b/src/invitation.hpp
index f7967ed..c9d3731 100644
--- a/src/invitation.hpp
+++ b/src/invitation.hpp
@@ -14,7 +14,7 @@
 
 #include "common.hpp"
 
-#include <ndn-cxx/security/identity-certificate.hpp>
+#include <ndn-cxx/security/certificate.hpp>
 
 namespace chronochat {
 
@@ -58,7 +58,7 @@
   Invitation(const Name& inviteeNameSpace,
              const std::string& chatroom,
              const Name& inviterRoutingPrefix,
-             const ndn::IdentityCertificate& inviterCertificate);
+             const ndn::security::Certificate& inviterCertificate);
 
   Invitation(const Invitation& invitation);
 
@@ -85,7 +85,7 @@
     return m_inviterRoutingPrefix;
   }
 
-  const ndn::IdentityCertificate&
+  const ndn::security::Certificate&
   getInviterCertificate() const
   {
     return m_inviterCertificate;
@@ -109,7 +109,7 @@
   Name m_inviteeNameSpace;
   std::string m_chatroom;
   Name m_inviterRoutingPrefix;
-  ndn::IdentityCertificate m_inviterCertificate;
+  ndn::security::Certificate m_inviterCertificate;
   uint64_t m_timestamp;
 };
 
diff --git a/src/main.cpp b/src/main.cpp
index 9674146..90f1d9d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,10 +10,9 @@
 
 #include <QApplication>
 #include <QTextCodec>
-// #include <QSystemTrayIcon>
 
 #include "controller.hpp"
-#include "logging.h"
+#include <iostream>
 #include <ndn-cxx/face.hpp>
 #include <boost/thread/thread.hpp>
 
@@ -43,9 +42,6 @@
 {
   NewApp app(argc, argv);
 
-  QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
-  QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
-
   chronochat::Controller controller;
 
   app.setQuitOnLastWindowClosed(false);
diff --git a/src/nfd-connection-checker.cpp b/src/nfd-connection-checker.cpp
index 023c0b2..eda7197 100644
--- a/src/nfd-connection-checker.cpp
+++ b/src/nfd-connection-checker.cpp
@@ -42,6 +42,7 @@
                               [&] (const Interest& interest, const Data& data) {
                                 m_face->shutdown();
                               },
+                              NULL,
                               [] (const Interest& interest) {});
       m_face->processEvents(time::milliseconds::zero(), true);
     }
diff --git a/src/profile-editor.cpp b/src/profile-editor.cpp
index a55a12c..f0b067d 100644
--- a/src/profile-editor.cpp
+++ b/src/profile-editor.cpp
@@ -40,26 +40,31 @@
 ProfileEditor::~ProfileEditor()
 {
     delete ui;
-    delete m_tableModel;
+
+    if (m_tableModel)
+      delete m_tableModel;
 }
 
 void
 ProfileEditor::onCloseDBModule()
 {
-  // _LOG_DEBUG("close db module");
   if (m_tableModel) {
     delete m_tableModel;
-    // _LOG_DEBUG("tableModel closed");
+    m_tableModel = 0;
   }
 }
 
 void
 ProfileEditor::onIdentityUpdated(const QString& identity)
 {
-  m_tableModel = new QSqlTableModel();
-
   m_identity = identity;
   ui->identityInput->setText(identity);
+}
+
+void
+ProfileEditor::resetPanel()
+{
+  m_tableModel = new QSqlTableModel();
 
   m_tableModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
   m_tableModel->setTable("SelfProfile");
diff --git a/src/profile-editor.hpp b/src/profile-editor.hpp
index 5323f5c..a18f8fc 100644
--- a/src/profile-editor.hpp
+++ b/src/profile-editor.hpp
@@ -39,6 +39,9 @@
   void
   onIdentityUpdated(const QString& identity);
 
+  void
+  resetPanel();
+
 private slots:
   void
   onAddClicked();
diff --git a/src/profile.cpp b/src/profile.cpp
index 38f7b63..dc89fa9 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -11,6 +11,7 @@
 
 #include "profile.hpp"
 #include "logging.h"
+#include <ndn-cxx/security/additional-description.hpp>
 
 namespace chronochat {
 
@@ -18,8 +19,7 @@
 using std::string;
 using std::map;
 
-using ndn::IdentityCertificate;
-using ndn::CertificateSubjectDescription;
+using ndn::security::Certificate;
 
 const std::string Profile::OID_NAME("2.5.4.41");
 const std::string Profile::OID_ORG("2.5.4.11");
@@ -28,33 +28,34 @@
 const std::string Profile::OID_ADVISOR("2.5.4.80");
 const std::string Profile::OID_EMAIL("1.2.840.113549.1.9.1");
 
-Profile::Profile(const IdentityCertificate& identityCertificate)
+Profile::Profile(const Certificate& identityCertificate)
 {
-  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(identityCertificate.getName());
+  Name keyName = identityCertificate.getKeyName();
 
-  m_entries[string("IDENTITY")] = keyName.getPrefix(-1).toUri();
+  m_entries[string("IDENTITY")] = keyName.getPrefix(-2).toUri();
 
-  const vector<CertificateSubjectDescription>& subList =
-    identityCertificate.getSubjectDescriptionList();
+  auto additionalWire = identityCertificate.getSignatureInfo().getCustomTlv(tlv::AdditionalDescription);
+  if (additionalWire) {
+    ndn::security::AdditionalDescription additional(*additionalWire);
 
-  for (vector<CertificateSubjectDescription>::const_iterator it = subList.begin();
-       it != subList.end(); it++) {
-    const string oidStr = it->getOidString();
-    string valueStr = it->getValue();
-    if (oidStr == OID_NAME)
-      m_entries["name"] = valueStr;
-    else if (oidStr == OID_ORG)
-      m_entries["institution"] = valueStr;
-    else if (oidStr == OID_GROUP)
-      m_entries["group"] = valueStr;
-    else if (oidStr == OID_HOMEPAGE)
-      m_entries["homepage"] = valueStr;
-    else if (oidStr == OID_ADVISOR)
-      m_entries["advisor"] = valueStr;
-    else if (oidStr == OID_EMAIL)
-      m_entries["email"] = valueStr;
-    else
-      m_entries[oidStr] = valueStr;
+    for (auto it = additional.begin(); it != additional.end(); it++) {
+      const string oidStr = it->first;
+      string valueStr = it->second;
+      if (oidStr == OID_NAME)
+        m_entries["name"] = valueStr;
+      else if (oidStr == OID_ORG)
+        m_entries["institution"] = valueStr;
+      else if (oidStr == OID_GROUP)
+        m_entries["group"] = valueStr;
+      else if (oidStr == OID_HOMEPAGE)
+        m_entries["homepage"] = valueStr;
+      else if (oidStr == OID_ADVISOR)
+        m_entries["advisor"] = valueStr;
+      else if (oidStr == OID_EMAIL)
+        m_entries["email"] = valueStr;
+      else
+        m_entries[oidStr] = valueStr;
+    }
   }
 }
 
@@ -77,7 +78,12 @@
 {
 }
 
-template<bool T>
+Profile::Profile(const Block& profileWire)
+{
+  this->wireDecode(profileWire);
+}
+
+template<ndn::encoding::Tag T>
 size_t
 Profile::wireEncode(ndn::EncodingImpl<T>& block) const
 {
diff --git a/src/profile.hpp b/src/profile.hpp
index a89a800..43dba96 100644
--- a/src/profile.hpp
+++ b/src/profile.hpp
@@ -18,7 +18,7 @@
 #include <ndn-cxx/util/concepts.hpp>
 #include <ndn-cxx/encoding/block.hpp>
 #include <ndn-cxx/encoding/encoding-buffer.hpp>
-#include <ndn-cxx/security/identity-certificate.hpp>
+#include <ndn-cxx/security/certificate.hpp>
 
 namespace chronochat {
 
@@ -44,7 +44,7 @@
   {
   }
 
-  Profile(const ndn::IdentityCertificate& identityCertificate);
+  Profile(const ndn::security::Certificate& identityCertificate);
 
   Profile(const Name& identityName);
 
@@ -54,6 +54,8 @@
 
   Profile(const Profile& profile);
 
+  Profile(const Block& profileWire);
+
   ~Profile()
   {
   }
@@ -117,7 +119,7 @@
   operator!=(const Profile& profile) const;
 
 private:
-  template<bool T>
+  template<ndn::encoding::Tag T>
   size_t
   wireEncode(ndn::EncodingImpl<T>& block) const;
 
diff --git a/src/tree-layout.cpp b/src/tree-layout.cpp
index 166019f..9bf3627 100644
--- a/src/tree-layout.cpp
+++ b/src/tree-layout.cpp
@@ -11,7 +11,6 @@
  */
 
 #include "tree-layout.hpp"
-#include <iostream>
 
 namespace chronochat {
 
diff --git a/src/trust-tree-scene.cpp b/src/trust-tree-scene.cpp
index 718b207..3a23718 100644
--- a/src/trust-tree-scene.cpp
+++ b/src/trust-tree-scene.cpp
@@ -11,6 +11,7 @@
 #include "trust-tree-scene.hpp"
 
 #include <QtGui>
+#include <QGraphicsTextItem>
 
 #ifndef Q_MOC_RUN
 #include <assert.h>
@@ -21,7 +22,7 @@
 
 static const double Pi = 3.14159265358979323846264338327950288419717;
 
-TrustTreeScene::TrustTreeScene(QWidget* parent)
+TrustTreeScene::TrustTreeScene(QObject* parent)
   : QGraphicsScene(parent)
 {
 }
diff --git a/src/trust-tree-scene.hpp b/src/trust-tree-scene.hpp
index c8c21c6..0412914 100644
--- a/src/trust-tree-scene.hpp
+++ b/src/trust-tree-scene.hpp
@@ -11,7 +11,7 @@
 #ifndef CHRONOCHAT_TRUST_TREE_SCENE_HPP
 #define CHRONOCHAT_TRUST_TREE_SCENE_HPP
 
-#include <QtGui/QGraphicsScene>
+#include <QGraphicsScene>
 #include <QColor>
 #include <QMap>
 
@@ -29,7 +29,7 @@
   Q_OBJECT
 
 public:
-  TrustTreeScene(QWidget* parent = 0);
+  TrustTreeScene(QObject* parent = 0);
 
   void
   plotTrustTree(chronochat::TrustTreeNodeList& nodeList);
diff --git a/src/validator-invitation.cpp b/src/validator-invitation.cpp
deleted file mode 100644
index 20d7116..0000000
--- a/src/validator-invitation.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "validator-invitation.hpp"
-#include "invitation.hpp"
-
-#include "logging.h"
-
-namespace chronochat {
-
-using std::vector;
-
-using ndn::CertificateCache;
-using ndn::SecRuleRelative;
-using ndn::OnDataValidated;
-using ndn::OnDataValidationFailed;
-using ndn::OnInterestValidated;
-using ndn::OnInterestValidationFailed;
-using ndn::ValidationRequest;
-using ndn::IdentityCertificate;
-
-const shared_ptr<CertificateCache> ValidatorInvitation::DefaultCertificateCache =
-  shared_ptr<CertificateCache>();
-
-ValidatorInvitation::ValidatorInvitation()
-  : Validator()
-  , m_invitationReplyRule("^([^<CHRONOCHAT-INVITATION>]*)<CHRONOCHAT-INVITATION>",
-                          "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
-                          "==", "\\1", "\\1\\2", true)
-  , m_invitationInterestRule("^[^<CHRONOCHAT-INVITATION>]*<CHRONOCHAT-INVITATION><>{6}$")
-  , m_innerKeyRegex("^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT><>$", "\\1\\2")
-{
-}
-
-void
-ValidatorInvitation::addTrustAnchor(const Name& keyName, const ndn::PublicKey& key)
-{
-  m_trustAnchors[keyName] = key;
-}
-
-void
-ValidatorInvitation::removeTrustAnchor(const Name& keyName)
-{
-  m_trustAnchors.erase(keyName);
-}
-
-void
-ValidatorInvitation::cleanTrustAnchor()
-{
-  m_trustAnchors.clear();
-}
-
-void
-ValidatorInvitation::checkPolicy (const Data& data,
-                                  int stepCount,
-                                  const OnDataValidated& onValidated,
-                                  const OnDataValidationFailed& onValidationFailed,
-                                  vector<shared_ptr<ValidationRequest> >& nextSteps)
-{
-  const Signature& signature = data.getSignature();
-
-  if (signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name)
-    return onValidationFailed(data.shared_from_this(),
-                              "Key Locator is not a name: " + data.getName().toUri());
-
-  const Name & keyLocatorName = signature.getKeyLocator().getName();
-
-  if (!m_invitationReplyRule.satisfy(data.getName(), keyLocatorName))
-    return onValidationFailed(data.shared_from_this(),
-                              "Does not comply with the invitation rule: " +
-                              data.getName().toUri() + " signed by: " +
-                              keyLocatorName.toUri());
-
-  Data innerData;
-  innerData.wireDecode(data.getContent().blockFromValue());
-
-  return internalCheck(data.wireEncode().value(),
-                       data.wireEncode().value_size() - data.getSignature().getValue().size(),
-                       signature,
-                       keyLocatorName,
-                       innerData,
-                       bind(onValidated, data.shared_from_this()),
-                       bind(onValidationFailed, data.shared_from_this(), _1));
-}
-
-void
-ValidatorInvitation::checkPolicy (const Interest& interest,
-                                  int stepCount,
-                                  const OnInterestValidated& onValidated,
-                                  const OnInterestValidationFailed& onValidationFailed,
-                                  vector<shared_ptr<ValidationRequest> >& nextSteps)
-{
-  const Name& interestName  = interest.getName();
-
-  if (!m_invitationInterestRule.match(interestName))
-    return onValidationFailed(interest.shared_from_this(),
-                              "Invalid interest name: " +  interest.getName().toUri());
-
-  Name signedName = interestName.getPrefix(-1);
-  ndn::Buffer signedBlob = ndn::Buffer(signedName.wireEncode().value(),
-                                       signedName.wireEncode().value_size());
-
-  Block signatureBlock = interestName.get(Invitation::SIGNATURE).blockFromValue();
-  Block signatureInfo = interestName.get(Invitation::KEY_LOCATOR).blockFromValue();
-  Signature signature(signatureInfo, signatureBlock);
-
-  if (signature.getKeyLocator().getType() != KeyLocator::KeyLocator_Name)
-    return onValidationFailed(interest.shared_from_this(),
-                              "KeyLocator is not a name: " + interest.getName().toUri());
-
-  const Name & keyLocatorName = signature.getKeyLocator().getName();
-
-  Data innerData;
-  innerData.wireDecode(interestName.get(Invitation::INVITER_CERT).blockFromValue());
-
-  return internalCheck(signedBlob.buf(), signedBlob.size(),
-                       signature,
-                       keyLocatorName,
-                       innerData,
-                       bind(onValidated, interest.shared_from_this()),
-                       bind(onValidationFailed, interest.shared_from_this(), _1));
-}
-
-void
-ValidatorInvitation::internalCheck(const uint8_t* buf, size_t size,
-                                   const Signature& signature,
-                                   const Name& keyLocatorName,
-                                   const Data& innerData,
-                                   const OnValidated& onValidated,
-                                   const OnValidationFailed& onValidationFailed)
-{
-  Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-
-  TrustAnchors::const_iterator keyIt = m_trustAnchors.find(signingKeyName);
-  if (keyIt == m_trustAnchors.end())
-    return onValidationFailed("Cannot reach any trust anchor");
-
-  if (!Validator::verifySignature(buf, size, signature, keyIt->second))
-    return onValidationFailed("Cannot verify outer signature");
-
-  // Temporarily disabled, we should get it back when we create a specific key for the chatroom.
-  // if(!Validator::verifySignature(innerData, m_trustAnchors[signingKeyName]))
-  //   return onValidationFailed("Cannot verify inner signature");
-
-  if (!m_innerKeyRegex.match(innerData.getName()) ||
-      m_innerKeyRegex.expand() != signingKeyName.getPrefix(-1))
-    return onValidationFailed("Inner certificate does not comply with the rule");
-
-  return onValidated();
-}
-
-} // namespace chronochat
diff --git a/src/validator-invitation.hpp b/src/validator-invitation.hpp
deleted file mode 100644
index 03890a0..0000000
--- a/src/validator-invitation.hpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef CHRONOCHAT_VALIDATOR_INVITATION_HPP
-#define CHRONOCHAT_VALIDATOR_INVITATION_HPP
-
-#include "common.hpp"
-
-#include <ndn-cxx/security/validator.hpp>
-#include <ndn-cxx/security/certificate-cache.hpp>
-#include <ndn-cxx/security/sec-rule-relative.hpp>
-
-#include "endorse-certificate.hpp"
-
-namespace chronochat {
-
-class ValidatorInvitation : public ndn::Validator
-{
-  typedef function<void(const std::string&)> OnValidationFailed;
-  typedef function<void()> OnValidated;
-
-public:
-  class Error : public ndn::Validator::Error
-  {
-  public:
-    Error(const std::string& what)
-      : ndn::Validator::Error(what)
-    {
-    }
-  };
-
-  static const shared_ptr<ndn::CertificateCache> DefaultCertificateCache;
-
-  ValidatorInvitation();
-
-  virtual
-  ~ValidatorInvitation()
-  {
-  }
-
-  void
-  addTrustAnchor(const Name& keyName, const ndn::PublicKey& key);
-
-  void
-  removeTrustAnchor(const Name& keyName);
-
-  void
-  cleanTrustAnchor();
-
-protected:
-  void
-  checkPolicy(const Data& data,
-              int stepCount,
-              const ndn::OnDataValidated& onValidated,
-              const ndn::OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ndn::ValidationRequest> >& nextSteps);
-
-  void
-  checkPolicy(const Interest& interest,
-              int stepCount,
-              const ndn::OnInterestValidated& onValidated,
-              const ndn::OnInterestValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ndn::ValidationRequest> >& nextSteps);
-
-private:
-  void
-  internalCheck(const uint8_t* buf, size_t size,
-                const Signature& sig,
-                const Name& keyLocatorName,
-                const Data& innerData,
-                const OnValidated& onValidated,
-                const OnValidationFailed& onValidationFailed);
-
-private:
-  typedef std::map<Name, ndn::PublicKey> TrustAnchors;
-
-  ndn::SecRuleRelative m_invitationReplyRule;
-  ndn::Regex m_invitationInterestRule;
-  ndn::Regex m_innerKeyRegex;
-  TrustAnchors m_trustAnchors;
-};
-
-} // namespace chronochat
-
-#endif // CHRONOCHAT_VALIDATOR_INVITATION_HPP
diff --git a/src/validator-panel.cpp b/src/validator-panel.cpp
deleted file mode 100644
index c3c429d..0000000
--- a/src/validator-panel.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#include "validator-panel.hpp"
-
-#include "logging.h"
-
-namespace chronochat {
-
-using std::vector;
-
-using ndn::CertificateCache;
-using ndn::SecRuleRelative;
-using ndn::OnDataValidated;
-using ndn::OnDataValidationFailed;
-using ndn::ValidationRequest;
-using ndn::IdentityCertificate;
-
-const shared_ptr<CertificateCache> ValidatorPanel::DEFAULT_CERT_CACHE =
-  shared_ptr<CertificateCache>();
-
-ValidatorPanel::ValidatorPanel(int stepLimit,
-                               const shared_ptr<CertificateCache> certificateCache)
-  : m_stepLimit(stepLimit)
-  , m_certificateCache(certificateCache)
-{
-  m_endorseeRule = make_shared<SecRuleRelative>("^([^<DNS>]*)<DNS><>*<ENDORSEE><>$",
-                                                "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
-                                                "==", "\\1", "\\1\\2", true);
-}
-
-void
-ValidatorPanel::addTrustAnchor(const EndorseCertificate& cert)
-{
-  m_trustAnchors[cert.getPublicKeyName()] = cert.getPublicKeyInfo();
-}
-
-void
-ValidatorPanel::removeTrustAnchor(const Name& keyName)
-{
-  m_trustAnchors.erase(keyName);
-}
-
-void
-ValidatorPanel::checkPolicy (const Data& data,
-                             int stepCount,
-                             const OnDataValidated& onValidated,
-                             const OnDataValidationFailed& onValidationFailed,
-                             vector<shared_ptr<ValidationRequest> >& nextSteps)
-{
-  if (m_stepLimit == stepCount) {
-    onValidationFailed(data.shared_from_this(),
-                       "Reach maximum validation steps: " + data.getName().toUri());
-    return;
-  }
-
-  const KeyLocator& keyLocator = data.getSignature().getKeyLocator();
-
-  if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
-    return onValidationFailed(data.shared_from_this(),
-                              "Key Locator is not a name: " + data.getName().toUri());
-
-  const Name& keyLocatorName = keyLocator.getName();
-
-  if (m_endorseeRule->satisfy(data.getName(), keyLocatorName)) {
-    Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-
-    if (m_trustAnchors.end() != m_trustAnchors.find(keyName) &&
-        Validator::verifySignature(data, data.getSignature(), m_trustAnchors[keyName]))
-      onValidated(data.shared_from_this());
-    else
-      onValidationFailed(data.shared_from_this(),
-                         "Cannot verify signature:" + data.getName().toUri());
-  }
-  else
-    onValidationFailed(data.shared_from_this(),
-                       "Does not satisfy rule: " + data.getName().toUri());
-
-  return;
-}
-
-} // namespace chronochat
diff --git a/src/validator-panel.hpp b/src/validator-panel.hpp
deleted file mode 100644
index ab42fe1..0000000
--- a/src/validator-panel.hpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/*
- * Copyright (c) 2013, Regents of the University of California
- *                     Yingdi Yu
- *
- * BSD license, See the LICENSE file for more information
- *
- * Author: Yingdi Yu <yingdi@cs.ucla.edu>
- */
-
-#ifndef CHRONOCHAT_VALIDATOR_PANEL_HPP
-#define CHRONOCHAT_VALIDATOR_PANEL_HPP
-
-#include "common.hpp"
-
-#include <ndn-cxx/security/validator.hpp>
-#include <ndn-cxx/security/sec-rule-relative.hpp>
-#include <ndn-cxx/security/certificate-cache.hpp>
-
-#include "endorse-certificate.hpp"
-
-namespace chronochat {
-
-class ValidatorPanel : public ndn::Validator
-{
-public:
-
-  static const shared_ptr<ndn::CertificateCache> DEFAULT_CERT_CACHE;
-
-  ValidatorPanel(int stepLimit = 10,
-                 const shared_ptr<ndn::CertificateCache> cache = DEFAULT_CERT_CACHE);
-
-  ~ValidatorPanel()
-  {
-  }
-
-  void
-  addTrustAnchor(const EndorseCertificate& selfEndorseCertificate);
-
-  void
-  removeTrustAnchor(const Name& keyName);
-
-protected:
-  virtual void
-  checkPolicy(const Data& data,
-              int stepCount,
-              const ndn::OnDataValidated& onValidated,
-              const ndn::OnDataValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ndn::ValidationRequest> >& nextSteps);
-
-  virtual void
-  checkPolicy(const Interest& interest,
-              int stepCount,
-              const ndn::OnInterestValidated& onValidated,
-              const ndn::OnInterestValidationFailed& onValidationFailed,
-              std::vector<shared_ptr<ndn::ValidationRequest> >& nextSteps)
-  {
-    onValidationFailed(interest.shared_from_this(),
-                       "No rules for interest.");
-  }
-
-private:
-  int m_stepLimit;
-  shared_ptr<ndn::CertificateCache> m_certificateCache;
-  shared_ptr<ndn::SecRuleRelative> m_endorseeRule;
-  std::map<Name, ndn::PublicKey> m_trustAnchors;
-};
-
-} // namespace chronochat
-
-#endif // CHRONOCHAT_VALIDATOR_PANEL_HPP