Data Packet Verification Added
diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
index 92a911d..5365630 100644
--- a/src/communication/nlsr_dm.cpp
+++ b/src/communication/nlsr_dm.cpp
@@ -9,6 +9,7 @@
 #include "nlsr_dm.hpp"
 #include "utility/nlsr_tokenizer.hpp"
 #include "nlsr_lsdb.hpp"
+#include "security/nlsr_km.hpp"
 
 namespace nlsr
 {
@@ -22,12 +23,7 @@
     {
         cout << "I: " << interest.toUri() << endl;
         string dataName(data.getName().toUri());
-        //cout << "D: " << dataName << endl;
-        //cout << "Data Content: " << dataContent << endl;
         nlsrTokenizer nt(dataName,"/");
-        //SignatureSha256WithRsa sig(data.getSignature());
-        //ndn::Name keyName=sig.getKeyLocator().getName();
-        //cout<<"Key Locator Name: "<<keyName.toUri()<<endl;
         string chkString("info");
         if( nt.doesTokenExist(chkString) )
         {
@@ -184,19 +180,16 @@
     void 
     DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
     {
-        std::ofstream outFile("data_received");
-        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
         cout<<" processContentKeys called "<<endl;
-        SignatureSha256WithRsa signature(data.getSignature());
-        cout<<"D: <<"<<data<<endl;
-        cout<<"Key Locator: "<<signature.getKeyLocator().getName().toUri()<<endl;
         ndn::shared_ptr<ndn::IdentityCertificate> cert=ndn::make_shared<ndn::IdentityCertificate>();
         cert->wireDecode(data.getContent().blockFromValue());
         cout<<*(cert)<<endl;
-        
-        if( pnlsr.getKeyManager().verifySignature(*(cert),cert->getPublicKeyInfo()))
-        {
-            cout<<"Verified Data"<<endl;
-        }
+        std::string dataName=data.getName().toUri();
+        nlsrTokenizer nt(dataName,"/");
+        std::string certName=nt.getTokenString(0,nt.getTokenNumber()-3);
+        uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber()-2));
+        cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
+        pnlsr.getKeyManager().addCertificate(cert, seqNum, true);
+        pnlsr.getKeyManager().printCertStore();
     }
 }//namespace nlsr
diff --git a/src/communication/nlsr_im.cpp b/src/communication/nlsr_im.cpp
index 7495265..de551bb 100644
--- a/src/communication/nlsr_im.cpp
+++ b/src/communication/nlsr_im.cpp
@@ -186,15 +186,34 @@
     void
     interestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest)
     {
-        cout<<" processInterestKeys called "<<endl;
-        ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate("dummy");
+        cout<<"processInterestKeys called "<<endl;
+        string intName=interest.getName().toUri();
+        cout<<"Interest Name for Key: "<<intName<<std::endl;
+        nlsrTokenizer nt(intName,"/");
+        std::string certName=nt.getTokenString(0,nt.getTokenNumber()-2);
+        uint32_t seqNum=boost::lexical_cast<uint32_t>(nt.getToken(nt.getTokenNumber()-1));
+        cout<<"Cert Name: "<<certName<<" Seq Num: "<<seqNum<<std::endl;
+        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
+                pnlsr.getKeyManager().getCertificateFromStore(certName,seqNum);
+        if( chkCert.second )
+        {
+           Data data(ndn::Name(interest.getName()).appendVersion()); 
+           data.setFreshnessPeriod(1000); //10 sec
+           data.setContent(chkCert.first->wireEncode());
+           pnlsr.getKeyManager().signData(data);
+           pnlsr.getNlsrFace()->put(data);
+        }
+        //std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> chkCert=
+        /*
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate();
         Data data(ndn::Name(interest.getName()).appendVersion());
         data.setFreshnessPeriod(1000); // 10 sec
         data.setContent(cert->wireEncode());
         pnlsr.getKeyManager().signData(data);
-        std::ofstream outFile("data_sent");
-        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        //std::ofstream outFile("data_sent");
+        //ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
         pnlsr.getNlsrFace()->put(data);
+        */ 
     }
 
 
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
index ac29148..94517ae 100644
--- a/src/communication/nlsr_slh.cpp
+++ b/src/communication/nlsr_slh.cpp
@@ -58,7 +58,8 @@
         if( nt.doesTokenExist(chkString) )
         {
             //process keys update here
-            processKeysUpdateFromSync(updateName,seqNo, pnlsr);
+            std::string certName=nt.getTokenString(0);
+            processKeysUpdateFromSync(certName,seqNo, pnlsr);
         }
     }
 
@@ -108,9 +109,14 @@
     SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
             uint64_t seqNo, Nlsr& pnlsr)
     {
-        string certNamePrefix=certName + "/" + boost::lexical_cast<string>(seqNo);
-        pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
-                                      pnlsr.getConfParameter().getInterestResendTime());
+        cout<<"Cert Name: "<<certName<<std::endl;
+        if ( pnlsr.getKeyManager().isNewCertificate(certName,seqNo) )
+        {
+            string certNamePrefix=certName + "/" + 
+                                             boost::lexical_cast<string>(seqNo);
+            pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
+                              pnlsr.getConfParameter().getInterestResendTime());
+        }
     }
 
     void
@@ -124,7 +130,11 @@
     void
     SyncLogicHandler::publishKeyUpdate(KeyManager& km)
     {
-        publishSyncUpdate(km.getRouterCertName().toUri(),km.getCertSeqNo());
+        publishSyncUpdate(km.getRootCertName().toUri(), 10);
+        publishSyncUpdate(km.getSiteCertName().toUri(), 10);
+        publishSyncUpdate(km.getOperatorCertName().toUri(), 10);
+        publishSyncUpdate(km.getRouterCertName().toUri(), km.getCertSeqNo());
+        publishSyncUpdate(km.getProcessCertName().toUri(),km.getCertSeqNo());
     }
 
     void
diff --git a/src/nlsr.cpp b/src/nlsr.cpp
index 84b5e6d..f28835f 100644
--- a/src/nlsr.cpp
+++ b/src/nlsr.cpp
@@ -1,13 +1,18 @@
-#include <ndn-cpp-dev/face.hpp>
-#include <ndn-cpp-dev/security/key-chain.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
 #include <cstdlib>
 #include <string>
 #include <sstream>
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
 
 #include "nlsr.hpp"
 #include "nlsr_conf_processor.hpp"
 #include "utility/nlsr_logger.hpp"
+#include "security/nlsr_km.hpp"
+#include "security/nlsr_cert_store.hpp"
+#include "security/nlsr_cse.hpp"
 
 
 namespace nlsr
@@ -41,10 +46,31 @@
         nlsrLsdb.setLsaRefreshTime(confParam.getLsaRefreshTime());
         nlsrLsdb.setThisRouterPrefix(confParam.getRouterPrefix());
         fib.setFibEntryRefreshTime(2*confParam.getLsaRefreshTime());
-        km.initKeyManager(confParam);
+        if( ! km.initKeyManager(confParam) )
+        {
+            std::cerr<<"Can not initiate certificate"<<endl;
+        }
+        
         sm.setSeqFileName(confParam.getSeqFileDir());
         sm.initiateSeqNoFromFile();
+        
+        /* debugging purpose start */
+        cout <<	confParam;
+        adl.printAdl();
+        npl.printNpl();
+        /* debugging purpose end */
+        
+        nlsrLsdb.buildAndInstallOwnNameLsa(boost::ref(*this));
+        nlsrLsdb.buildAndInstallOwnCorLsa(boost::ref(*this));
+        setInterestFilterNlsr(confParam.getRouterPrefix());
+        setInterestFilterNlsr(confParam.getChronosyncLsaPrefix()+
+                                                   confParam.getRouterPrefix());
+        setInterestFilterNlsr(confParam.getRootKeyPrefix());
         slh.setSyncPrefix(confParam.getChronosyncSyncPrefix());
+        slh.createSyncSocket(boost::ref(*this));
+        slh.publishKeyUpdate(km);
+    
+        im.scheduleInfoInterest(boost::ref(*this),10);
     }
 
     void
@@ -108,23 +134,7 @@
         return EXIT_FAILURE;
     }
     nlsr_.initNlsr();
-    /* debugging purpose start */
-    cout <<	nlsr_.getConfParameter();
-    nlsr_.getAdl().printAdl();
-    nlsr_.getNpl().printNpl();
-    /* debugging purpose end */
-    nlsr_.getLsdb().buildAndInstallOwnNameLsa(nlsr_);
-    nlsr_.getLsdb().buildAndInstallOwnCorLsa(nlsr_);
-    nlsr_.setInterestFilterNlsr(nlsr_.getConfParameter().getRouterPrefix());
-    nlsr_.setInterestFilterNlsr(nlsr_.getConfParameter().getChronosyncLsaPrefix()+
-                                nlsr_.getConfParameter().getRouterPrefix());
-    nlsr_.setInterestFilterNlsr(nlsr_.getConfParameter().getRootKeyPrefix());
-    nlsr_.getSlh().createSyncSocket(nlsr_);
-    nlsr_.getSlh().publishKeyUpdate(nlsr_.getKeyManager());
-    nlsr_.getSlh().publishRoutingUpdate(nlsr_.getSm(),
-                                        nlsr_.getConfParameter().getChronosyncLsaPrefix()
-                                        + nlsr_.getConfParameter().getRouterPrefix());
-    nlsr_.getIm().scheduleInfoInterest(nlsr_,1);
+    
     try
     {
         nlsr_.startEventLoop();
diff --git a/src/nlsr_conf_param.hpp b/src/nlsr_conf_param.hpp
index 7fc51f2..2bd7cd3 100644
--- a/src/nlsr_conf_param.hpp
+++ b/src/nlsr_conf_param.hpp
@@ -25,6 +25,7 @@
             , maxFacesPerPrefix(0)
             , tunnelType(0)
             , detailedLogging(0)
+            , certDir()
             , debugging(0)
             , isHyperbolicCalc(0)
             , seqFileDir()
@@ -142,6 +143,16 @@
         {
             return logDir;
         }
+        
+        void setCertDir(std::string cd)
+        {
+            certDir=cd;
+        }
+        
+        std::string getCertDir()
+        {
+            return certDir;
+        }
 
         void setSeqFileDir(string ssfd)
         {
@@ -264,6 +275,7 @@
 
         int maxFacesPerPrefix;
         string logDir;
+        string certDir;
         string seqFileDir;
         string logFile;
         int detailedLogging;
diff --git a/src/nlsr_conf_processor.cpp b/src/nlsr_conf_processor.cpp
index e6067f9..13432d0 100644
--- a/src/nlsr_conf_processor.cpp
+++ b/src/nlsr_conf_processor.cpp
@@ -99,10 +99,14 @@
         {
             processConfCommandMaxFacesPerPrefix(pnlsr,nt.getRestOfLine());
         }
-        else if( (nt.getFirstToken() == "logdir"))
+        else if( (nt.getFirstToken() == "log-dir"))
         {
             processConfCommandLogDir(pnlsr,nt.getRestOfLine());
         }
+        else if( (nt.getFirstToken() == "cert-dir"))
+        {
+            processConfCommandCertDir(pnlsr,nt.getRestOfLine());
+        }
         else if( (nt.getFirstToken() == "detailed-logging") )
         {
             processConfCommandDetailedLogging(pnlsr,nt.getRestOfLine());
@@ -364,6 +368,20 @@
         }
         return 0;
     }
+    
+    int
+    ConfFileProcessor::processConfCommandCertDir(Nlsr& pnlsr, string command)
+    {
+        if(command.empty() )
+        {
+            cerr <<" Wrong command format ! [cert-dir /path/to/cert/dir]!"<<endl;
+        }
+        else
+        {
+            pnlsr.getConfParameter().setCertDir(command);
+        }
+        return 0;
+    }
 
     int
     ConfFileProcessor::processConfCommandDebugging(Nlsr& pnlsr, string command)
diff --git a/src/nlsr_conf_processor.hpp b/src/nlsr_conf_processor.hpp
index e97261e..0379b6c 100644
--- a/src/nlsr_conf_processor.hpp
+++ b/src/nlsr_conf_processor.hpp
@@ -21,6 +21,8 @@
         }
 
         int processConfFile(Nlsr& pnlsr);
+        
+    private:    
         int processConfCommand(Nlsr& pnlsr, string command);
         int processConfCommandNetwork(Nlsr& pnlsr, string command);
         int processConfCommandSiteName(Nlsr& pnlsr, string command);
@@ -34,6 +36,7 @@
 
         int processConfCommandChronosyncSyncPrefix(Nlsr& pnlsr, string command);
         int processConfCommandLogDir(Nlsr& pnlsr, string command);
+        int processConfCommandCertDir(Nlsr& pnlsr, string command);
         int processConfCommandDebugging(Nlsr& pnlsr, string command);
         int processConfCommandDetailedLogging(Nlsr& pnlsr, string command);
         int processConfCommandIsHyperbolicCalc(Nlsr& pnlsr, string command);
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
index f9923f2..cc60650 100644
--- a/src/route/nlsr_rt.cpp
+++ b/src/route/nlsr_rt.cpp
@@ -70,6 +70,7 @@
                 clearRoutingTable();
                 clearDryRoutingTable(); // for dry run options
                 // need to update NPT here
+                std::cout<<"Calling Update NPT With new Route"<<std::endl;
                 pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
                 //debugging purpose
                 printRoutingTable();
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
index 5bbef9e..9bd7ca8 100644
--- a/src/security/nlsr_cert_store.hpp
+++ b/src/security/nlsr_cert_store.hpp
@@ -1,6 +1,31 @@
 #ifndef NLSR_CERT_STORE_HPP
 #define NLSR_CERT_STORE_HPP
 
+#include<list>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include "nlsr_cse.hpp"
 
+namespace nlsr
+{
+    class NlsrCertificateStore
+    {
+        public:
+            NlsrCertificateStore()
+            {}
+            
+            bool addCertificate(NlsrCertificateStoreEntry & ncse);
+            bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                                                      , uint32_t csn, bool isv);
+            std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+            getCertificateFromStore(const std::string certName);
+            std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+            getCertificateFromStore(const std::string certName, int checkSeqNum);
+            bool removeCertificateFromStroe(const std::string certName);
+            bool isCertificateNewInStore(const std::string certName, int checkSeqNo);
+            void printCertStore();
+        private:
+            std::list<NlsrCertificateStoreEntry> certTable;
+    };
+}
 
 #endif
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
index 69052eb..e97bbfe 100644
--- a/src/security/nlsr_km.cpp
+++ b/src/security/nlsr_km.cpp
@@ -1,13 +1,21 @@
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
 #include <ndn-cpp-dev/encoding/block.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+#include <stdexcept>
 #include "nlsr_sm.hpp"
 #include "nlsr_km.hpp"
 
 namespace nlsr
 {
-    void
+    bool
     KeyManager::initKeyManager(ConfParameter &cp)
     {
+        initCertSeqFromFile(cp.getSeqFileDir());
+        if( !loadAllCertificates(cp.getCertDir()) )
+        {
+            return false;
+        }
+        nlsrRootKeyPrefix=cp.getRootKeyPrefix();
         string processIdentityName(cp.getRootKeyPrefix());
         processIdentityName += "/";
         processIdentityName += cp.getSiteName();
@@ -15,25 +23,119 @@
         processIdentityName += "R.Start";
         processIdentityName += "/";
         processIdentityName += cp.getRouterName();
+        ndn::Name ri(processIdentityName);
+        std::cout<<"Router Identity: "<<ri.toUri()<<std::endl;
+        routerIdentity=ri;
         processIdentityName += "/";
         processIdentityName += "nlsr";
         cout<<"Proces Identity Name: "<<processIdentityName<<endl;
         ndn::Name identityName(processIdentityName);
-        routerIdentity=identityName;
-        ndn::KeyChain::deleteIdentity(routerIdentity);
-        routerCertName = ndn::KeyChain::createIdentity(routerIdentity);
-        cout<<"Certificate Name: "<<routerCertName.toUri()<<endl;
-        routerKeyName=
-            ndn::IdentityCertificate::certificateNameToPublicKeyName(routerCertName);
-        cout<<"Key Name: "<<routerKeyName.toUri()<<endl;
-        initCertSeqFromFile(cp.getSeqFileDir());
+        processIdentity=identityName;
+        ndn::KeyChain::deleteIdentity(processIdentity);
+        processCertName = ndn::KeyChain::createIdentity(processIdentity);
+        cout<<"Certificate Name: "<<processCertName.toUri()<<endl;
+        processKeyName=
+            ndn::IdentityCertificate::certificateNameToPublicKeyName(processCertName);
+        cout<<"Key Name: "<<processKeyName.toUri()<<endl;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=getCertificate(processCertName);
+        signByIdentity(*(cert),routerIdentity);
+        //initCertSeqFromFile(cp.getSeqFileDir());
+        certStore.addCertificate(cert, certSeqNo, true);
+        certStore.printCertStore();
+        
+        return true;
+    }
+    
+    bool 
+    KeyManager::loadAllCertificates(std::string certDirPath)
+    {
+        std::string filePath=certDirPath;
+        if(filePath.empty())
+        {
+            SequencingManager sm;
+            filePath=sm.getUserHomeDirectory();
+            filePath+="/nlsrCertDir";
+        }
+        
+        return loadCertificate(filePath+"/root.cert", KEY_TYPE_ROOT) 
+               && loadCertificate(filePath+"/site.cert", KEY_TYPE_SITE)
+               && loadCertificate(filePath+"/operator.cert", KEY_TYPE_OPERATOR)
+               && loadCertificate(filePath+"/router.cert", KEY_TYPE_ROUTER) ;
+    }
+    
+    bool 
+    KeyManager::loadCertificate(std::string inputFile, nlsrKeyType keyType)
+    {
+        try
+        {
+            ndn::shared_ptr<ndn::IdentityCertificate> cert = 
+             ndn::io::load<ndn::IdentityCertificate>(inputFile, ndn::io::BASE_64);
+            ndn::Name certName=cert->getName();
+            //certStore.addCertificate(cert, 10, true);
+            switch(keyType)
+            {
+                case KEY_TYPE_ROOT:
+                    certStore.addCertificate(cert, 10, true);
+                    rootCertName=certName;
+                    break;
+                case KEY_TYPE_SITE:
+                    certStore.addCertificate(cert, 10, true);
+                    siteCertName=certName;
+                    break;
+                case KEY_TYPE_OPERATOR:
+                    certStore.addCertificate(cert, 10, true);
+                    opCertName=certName;
+                    break;
+                case KEY_TYPE_ROUTER:
+                    certStore.addCertificate(cert, certSeqNo, true);
+                    routerCertName=certName;
+                    break;
+                case KEY_TYPE_PROCESS:
+                    certStore.addCertificate(cert, certSeqNo, true);
+                    processCertName=certName;
+                    break;
+                default:
+                    break;
+            }
+            return true;
+        }
+        catch(std::exception& e)
+        {
+            return false;
+        }
+        
+        return false;
     }
 
     ndn::Name
+    KeyManager::getProcessCertName()
+    {
+        return processCertName;
+    }
+    
+    ndn::Name 
     KeyManager::getRouterCertName()
     {
         return routerCertName;
     }
+    
+    ndn::Name 
+    KeyManager::getOperatorCertName()
+    {
+        return opCertName;
+    }
+    
+    ndn::Name 
+    KeyManager::getSiteCertName()
+    {
+        return siteCertName;
+    }
+    
+    ndn::Name 
+    KeyManager::getRootCertName()
+    {
+        return rootCertName;
+    }
 
     uint32_t
     KeyManager::getCertSeqNo()
@@ -78,6 +180,133 @@
         outputFile<<certSeqNo;
         outputFile.close();
     }
+    
+    bool 
+    KeyManager::isNewCertificate(std::string certName, int checkSeqNum)
+    {
+        return certStore.isCertificateNewInStore(certName,checkSeqNum);
+    }
+    
+    std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+    KeyManager::getCertificateFromStore(const std::string certName, int checkSeqNum)
+    {
+        return certStore.getCertificateFromStore(certName, checkSeqNum);
+    }
+    
+    bool 
+    KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                                                      , uint32_t csn, bool isv)
+    {
+        return certStore.addCertificate(pcert, csn, isv);
+    }
+    
+    nlsrKeyType 
+    KeyManager::getKeyTypeFromName(const std::string keyName)
+    {
+        nlsrTokenizer nt(keyName,"/");
+        std::string KEY("KEY");
+        std::string opHandle("O.Start");
+        std::string routerHandle("R.Start");
+        std::string processHandle("nlsr");
+        if ( nt.getTokenString(0,nt.getTokenPosition(KEY)-1) == nlsrRootKeyPrefix)
+        {
+            return KEY_TYPE_ROOT;
+        }
+        else if ( nt.doesTokenExist(opHandle) )
+        {
+            return KEY_TYPE_OPERATOR;
+        }
+        else if ( nt.doesTokenExist(routerHandle) && 
+                                             nt.doesTokenExist(processHandle))
+        {
+            return KEY_TYPE_PROCESS;
+        }
+        else if ( nt.doesTokenExist(routerHandle) && 
+                                             !nt.doesTokenExist(processHandle))
+        {
+            return KEY_TYPE_ROUTER;
+        }
+        else
+        {
+            return KEY_TYPE_SITE;
+        }
+    }
+    
+    std::string 
+    KeyManager::getRouterName(const std::string name)
+    {
+        std::string routerName;
+        std::string rkp(nlsrRootKeyPrefix);
+        nlsrTokenizer ntRkp(rkp,"/");
+        nlsrTokenizer nt(name,"/");
+        std::string KEY("KEY");
+        std::string opHandle("O.Start");
+        std::string routerHandle("R.Start");
+        std::string processHandle("nlsr");
+        std::string infoHandle("info");
+        std::string lsaHandle("LSA");
+        
+        if ( nt.doesTokenExist(processHandle) && nt.doesTokenExist(routerHandle))
+        {
+            routerName="/ndn" + 
+                        nt.getTokenString(ntRkp.getTokenNumber(), 
+                                          nt.getTokenPosition(routerHandle)-1) +
+                        nt.getTokenString(nt.getTokenPosition(routerHandle)+1, 
+                                          nt.getTokenPosition(processHandle)-1);
+        }
+        else if(nt.doesTokenExist(routerHandle) && !nt.doesTokenExist(infoHandle)
+                                                && !nt.doesTokenExist(lsaHandle))
+        {
+            routerName="/ndn" + 
+                        nt.getTokenString(ntRkp.getTokenNumber(), 
+                                          nt.getTokenPosition(routerHandle)-1) +
+                        nt.getTokenString(nt.getTokenPosition(routerHandle)+1,
+                                                    nt.getTokenPosition(KEY)-1);
+        }
+        else
+        {
+            if (nt.doesTokenExist(infoHandle) )
+            {
+               routerName=nt.getTokenString(0,nt.getTokenPosition(infoHandle)-1);
+            }
+            else
+            {
+                routerName=nt.getTokenString(nt.getTokenPosition(lsaHandle)+1,
+                                             nt.getTokenNumber()-3);
+            } 
+        }
+        return routerName;
+    }
+        
+    std::string 
+    KeyManager::getSiteName(const std::string name)
+    {
+        std::string siteName;
+        std::string routerName;
+        std::string rkp(nlsrRootKeyPrefix);
+        nlsrTokenizer ntRkp(rkp,"/");
+        nlsrTokenizer nt(name,"/");
+        std::string KEY("KEY");
+        std::string opHandle("O.Start");
+        std::string routerHandle("R.Start");
+        
+        if ( nt.doesTokenExist(routerHandle) )
+        {
+            siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(), 
+                                          nt.getTokenPosition(routerHandle) -1); 
+        }
+        else if ( nt.doesTokenExist(opHandle) )
+        {
+            siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(), 
+                                          nt.getTokenPosition(opHandle) -1);
+        }
+        else
+        {
+           siteName="/ndn" + nt.getTokenString(ntRkp.getTokenNumber(), 
+                                          nt.getTokenPosition(KEY) -1); 
+        }
+        return siteName;
+    }
 }
 
 
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
index 7b3b7ba..5fa7ec6 100644
--- a/src/security/nlsr_km.hpp
+++ b/src/security/nlsr_km.hpp
@@ -5,23 +5,12 @@
 #include <ndn-cpp-dev/data.hpp>
 #include <ndn-cpp-dev/security/key-chain.hpp>
 #include <ndn-cpp-dev/security/validator.hpp>
-#include <ndn-cpp-dev/util/scheduler.hpp>
 #include <ndn-cpp-dev/util/random.hpp>
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
-#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
-
-#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
-#include <ndn-cpp-dev/security/sec-public-info-memory.hpp>
-//TPM
-#include <ndn-cpp-dev/security/sec-tpm-file.hpp>
-#include <ndn-cpp-dev/security/sec-tpm-memory.hpp>
-
-#ifdef NDN_CPP_HAVE_OSX_SECURITY
-#include <ndn-cpp-dev/security/sec-tpm-osx.hpp>
-#endif
-
 #include <list>
 #include "nlsr_conf_param.hpp"
+#include "nlsr_cert_store.hpp"
+#include "utility/nlsr_tokenizer.hpp"
 
 namespace nlsr
 {
@@ -31,7 +20,14 @@
         KEY_TYPE_SITE,
         KEY_TYPE_OPERATOR,
         KEY_TYPE_ROUTER,
-        KEY_TYPE_PROCESS
+        KEY_TYPE_PROCESS,
+        KEY_TYPE_UNKNOWN
+    };
+    
+    enum nlsrContentType
+    {
+        CONTENT_TYPE_DATA,
+        CONTENT_TYPE_CERT
     };
 
     class KeyManager: public ndn::KeyChain, public ndn::Validator
@@ -41,10 +37,14 @@
     public:
         KeyManager()
             : certSeqNo(1)
+            , certStore()
+            , nlsrRootKeyPrefix()
         {
         }
 
-        void initKeyManager(ConfParameter &cp);
+        bool initKeyManager(ConfParameter &cp);
+        
+        
 
         void
         checkPolicy (const ndn::Data& data,
@@ -64,15 +64,31 @@
 
         void signData(ndn::Data& data)
         {
-            ndn::KeyChain::signByIdentity(data,routerIdentity);
-            //ndn::SignatureSha256WithRsa signature(data.getSignature());
-            //signature.setKeyLocator(routerCertName);
+            ndn::KeyChain::signByIdentity(data,processIdentity);
+        }
+        
+        template<typename T>
+        void signByIdentity(T& packet, ndn::Name signeeIdentity)
+        {
+            ndn::KeyChain::signByIdentity(packet,signeeIdentity);
         }
         
         ndn::shared_ptr<ndn::IdentityCertificate>
         getCertificate(ndn::Name certificateName)
         {
-            return ndn::KeyChain::getCertificate(routerCertName);
+            return ndn::KeyChain::getCertificate(certificateName);
+        }
+        
+        ndn::shared_ptr<ndn::IdentityCertificate>
+        getCertificate()
+        {
+            return getCertificate(processCertName);
+        }
+        
+        ndn::Name
+        createIdentity(const ndn::Name identityName)
+        {
+            return ndn::KeyChain::createIdentity(identityName);
         }
 
         ndn::Name
@@ -137,20 +153,118 @@
             }
             return certName;
         }
+        
+        void printCertStore()
+        {
+            certStore.printCertStore();
+        }
+        
+    private:
+        bool
+        verifyDataPacket(ndn::Data packet)
+        {
+            ndn::SignatureSha256WithRsa signature(packet.getSignature());
+            std::string signingCertName=signature.getKeyLocator().getName().toUri();
+            std::string packetName=packet.getName().toUri();
+            
+            std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
+                             certStore.getCertificateFromStore(signingCertName);
+            if( signee.second )
+            {
+                return ( getRouterName(signingCertName)== getRouterName(packetName)
+                       && verifySignature(packet, signee.first->getPublicKeyInfo()));
+            }
+            
+            return false; 
+        }
+        
+        bool 
+        verifyCertPacket(ndn::IdentityCertificate packet)
+        {
+            return true;
+        }
+        
+        template<typename T>
+        bool 
+        verify(T& packet , nlsrContentType contentType,
+                                                     nlsrKeyType signingKeyType)
+        {
+            switch(contentType)
+            {
+                case CONTENT_TYPE_DATA:
+                    return verifyDataPacket(packet);
+                    break;
+                case CONTENT_TYPE_CERT:
+                    return verifyCertPacket(packet);
+                    break;
+            }
+            
+            return false;
+        }
+        
+    public:
+        template<typename T>
+        bool 
+        verify(T& packet )
+        {
+            ndn::SignatureSha256WithRsa signature(packet.getSignature());
+            std::string signingKeyName=signature.getKeyLocator().getName().toUri();
+            std::string packetName=packet.getName().toUri();
+            nlsrTokenizer nt(packetName,"/");
+            std::string keyHandle("keys");
+            if ( nt.doesTokenExist(keyHandle) )
+            {
+                return verify(packet, CONTENT_TYPE_CERT, 
+                                            getKeyTypeFromName(signingKeyName));
+            }
+            else
+            {
+                return verify(packet, CONTENT_TYPE_DATA, 
+                                            getKeyTypeFromName(signingKeyName));
+            }
+            
+            return false;
+        }
 
+        ndn::Name getProcessCertName();
         ndn::Name getRouterCertName();
+        ndn::Name getOperatorCertName();
+        ndn::Name getSiteCertName();
+        ndn::Name getRootCertName();
 
         uint32_t getCertSeqNo();
         void setCerSeqNo(uint32_t csn);
         void initCertSeqFromFile(string certSeqFileDir);
         void writeCertSeqToFile();
+        bool isNewCertificate(std::string certName, int checkSeqNum);
+        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+        getCertificateFromStore(const std::string certName, int checkSeqNum);
+        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+        getCertificateFromStore(const std::string certName);
+        bool addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
+                                                      , uint32_t csn, bool isv);
+        
+        
+    private:
+        bool loadAllCertificates(std::string certDirPath);
+        bool loadCertificate(std::string inputFile, nlsrKeyType keyType);
+        nlsrKeyType getKeyTypeFromName(const std::string keyName);
+        std::string getRouterName(const std::string name);
+        std::string getSiteName(const std::string name);
 
     private:
+        ndn::Name processIdentity;
         ndn::Name routerIdentity;
+        ndn::Name processCertName;
         ndn::Name routerCertName;
-        ndn::Name routerKeyName;
+        ndn::Name opCertName;
+        ndn::Name siteCertName;
+        ndn::Name rootCertName;
+        ndn::Name processKeyName;
         uint32_t certSeqNo;
         string certSeqFileNameWithPath;
+        string nlsrRootKeyPrefix;
+        NlsrCertificateStore certStore;
 
     };
 }
diff --git a/waf-tools/boost.py b/waf-tools/boost.py
index c714b5b..6d79788 100644
--- a/waf-tools/boost.py
+++ b/waf-tools/boost.py
@@ -39,9 +39,9 @@
  - boost libraries will try to be smart and use the (pretty but often not useful) auto-linking feature of MSVC
    So before calling `conf.check_boost` you might want to disabling by adding:
    	conf.env.DEFINES_BOOST += ['BOOST_ALL_NO_LIB']
-   Errors: 
+   Errors:
  - boost might also be compiled with /MT, which links the runtime statically.
-   If you have problems with redefined symbols, 
+   If you have problems with redefined symbols,
 		self.env['DEFINES_%s' % var] += ['BOOST_ALL_NO_LIB']
 		self.env['CXXFLAGS_%s' % var] += ['/MD', '/EHsc']
 Passing `--boost-linkage_autodetect` might help ensuring having a correct linkage in some basic cases.
@@ -59,7 +59,7 @@
 BOOST_VERSION_CODE = '''
 #include <iostream>
 #include <boost/version.hpp>
-int main() { std::cout << BOOST_LIB_VERSION << std::endl; }
+int main() { std::cout << BOOST_LIB_VERSION << ":" << BOOST_VERSION << std::endl; }
 '''
 
 # toolsets from {boost_dir}/tools/build/v2/tools/common.jam
@@ -92,16 +92,14 @@
 
 
 def options(opt):
-        opt = opt.add_option_group('Boost Options')
-    
+	opt = opt.add_option_group('Boost Options')
+
 	opt.add_option('--boost-includes', type='string',
 				   default='', dest='boost_includes',
-				   help='''path to the boost includes root (~boost root)
-				   e.g. /path/to/boost_1_47_0''')
+				   help='''path to the directory where the boost includes are, e.g., /path/to/boost_1_55_0/stage/include''')
 	opt.add_option('--boost-libs', type='string',
 				   default='', dest='boost_libs',
-				   help='''path to the directory where the boost libs are
-				   e.g. /path/to/boost_1_47_0/stage/lib''')
+				   help='''path to the directory where the boost libs are, e.g., /path/to/boost_1_55_0/stage/lib''')
 	opt.add_option('--boost-static', action='store_true',
 				   default=False, dest='boost_static',
 				   help='link with static boost libraries (.lib/.a)')
@@ -109,19 +107,16 @@
 				   default=False, dest='boost_mt',
 				   help='select multi-threaded libraries')
 	opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
-				   help='''select libraries with tags (dgsyp, d for debug),
-				   see doc Boost, Getting Started, chapter 6.1''')
+				   help='''select libraries with tags (dgsyp, d for debug), see doc Boost, Getting Started, chapter 6.1''')
 	opt.add_option('--boost-linkage_autodetect', action="store_true", dest='boost_linkage_autodetect',
 				   help="auto-detect boost linkage options (don't get used to it / might break other stuff)")
 	opt.add_option('--boost-toolset', type='string',
 				   default='', dest='boost_toolset',
-				   help='force a toolset e.g. msvc, vc90, \
-						gcc, mingw, mgw45 (default: auto)')
+				   help='force a toolset e.g. msvc, vc90, gcc, mingw, mgw45 (default: auto)')
 	py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
 	opt.add_option('--boost-python', type='string',
 				   default=py_version, dest='boost_python',
-				   help='select the lib python with this version \
-						(default: %s)' % py_version)
+				   help='select the lib python with this version (default: %s)' % py_version)
 
 
 @conf
@@ -141,11 +136,16 @@
 		except (OSError, IOError):
 			Logs.error("Could not read the file %r" % node.abspath())
 		else:
-			re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"', re.M)
-			m = re_but.search(txt)
-			if m:
-				return m.group(1)
-	return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True)
+			re_but1 = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"', re.M)
+			m1 = re_but1.search(txt)
+
+			re_but2 = re.compile('^#define\\s+BOOST_VERSION\\s+"(.*)"', re.M)
+			m2 = re_but2.search(txt)
+
+			if m1 and m2:
+				return (m1.group(1), m2.group(1))
+
+	return self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[d], execute=True, define_ret=True).split(":")
 
 @conf
 def boost_get_includes(self, *k, **kw):
@@ -285,8 +285,12 @@
 
 	self.start_msg('Checking boost includes')
 	self.env['INCLUDES_%s' % var] = inc = self.boost_get_includes(**params)
-	self.env.BOOST_VERSION = self.boost_get_version(inc)
-	self.end_msg(self.env.BOOST_VERSION)
+	versions = self.boost_get_version(inc)
+	self.env.BOOST_VERSION = versions[0]
+	self.env.BOOST_VERSION_NUMBER = int(versions[1])
+	self.end_msg("%d.%d.%d" % (int(versions[1]) / 100000,
+				   int(versions[1]) / 100 % 1000,
+				   int(versions[1]) % 100))
 	if Logs.verbose:
 		Logs.pprint('CYAN', '	path : %s' % self.env['INCLUDES_%s' % var])
 
@@ -370,4 +374,3 @@
 			self.end_msg("Could not link against boost libraries using supplied options")
 			self.fatal('The configuration failed')
 		self.end_msg('ok')
-
diff --git a/wscript b/wscript
index cdceeaa..a07ff19 100644
--- a/wscript
+++ b/wscript
@@ -63,6 +63,7 @@
         use = 'NDN_CPP BOOST CRYPTOPP SQLITE3 nsync',
         includes = ". src"
         )
+    bld.recurse("CertTool")
 
 @Configure.conf
 def add_supported_cxxflags(self, cxxflags):
@@ -78,4 +79,3 @@
 
     self.end_msg (' '.join (supportedFlags))
     self.env.CXXFLAGS += supportedFlags
-