Content Verification and Certificate Verification Done
diff --git a/src/security/nlsr_cert_store.cpp b/src/security/nlsr_cert_store.cpp
index d1e821a..897d44a 100644
--- a/src/security/nlsr_cert_store.cpp
+++ b/src/security/nlsr_cert_store.cpp
@@ -1,4 +1,8 @@
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp> 
+#include <ndn-cpp-dev/security/key-chain.hpp>
 #include "nlsr_cert_store.hpp"
+#include "nlsr_wle.hpp"
+#include "nlsr_km.hpp"
 
 namespace nlsr
 {
@@ -6,9 +10,13 @@
   nlsrCertificateStoreEntryCompare(NlsrCertificateStoreEntry& ncse1,
                                    NlsrCertificateStoreEntry& ncse2)
 
-  {
-    return ncse1.getCert()->getName().toUri() ==
-           ncse2.getCert()->getName().toUri() ;
+  {    
+    int sizeDiff=ncse1.getCert()->getName().size()-
+                                              ncse2.getCert()->getName().size();
+    return (ncse2.getCert()->getName().isPrefixOf(ncse1.getCert()->getName()) &&
+                                               (sizeDiff <= 1 && sizeDiff>= 0));
+  
+    
   }
 
   static bool
@@ -17,8 +25,59 @@
 
   {
     ndn::Name ccn(compCertName);
-    return ( ncse1.getCert()->getName().toUri() == compCertName ||
-             ccn.isPrefixOf(ncse1.getCert()->getName()) );
+    int sizeDiff= ncse1.getCert()->getName().size() -ccn.size();
+    return ( ccn.isPrefixOf(ncse1.getCert()->getName()) &&
+                                               (sizeDiff <= 1 && sizeDiff>= 0));
+  }
+  
+  void 
+  NlsrCertificateStore::updateWaitingList(std::string respCertName)
+  {
+    ndn::Name tmpName(respCertName);
+    respCertName=tmpName.getPrefix(-1).toUri();
+    std::pair<WaitingListEntry, bool> chkWle=
+                              waitingList.getWaitingListEntry(respCertName);
+    if( chkWle.second )
+    {
+      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> sc=
+                                          getCertificateFromStore(respCertName);
+      std::list<std::string> waitees=(chkWle.first).getWaitingCerts();
+      for(std::list<std::string>::iterator it = waitees.begin();
+                                                       it != waitees.end();++it)
+      {
+        KeyManager km;
+        std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> wc=
+                                                 getCertificateFromStore(*(it));
+        if( wc.second && sc.second )
+        {
+          if(km.verifySignature(*(wc.first),sc.first->getPublicKeyInfo()))
+          {
+            //1. Update Certificate Store
+            setCertificateIsVerified(*(it),true);
+            //2. Call updateWaitingList for waitee ( *(it) )
+            updateWaitingList(*(it));
+          }
+        }
+      }
+    }
+    
+    //remove that entry from waiting list
+    waitingList.removeFromWaitingList(respCertName);
+  }
+  
+  void
+  NlsrCertificateStore::updateWaitingList(NlsrCertificateStoreEntry& ncse)
+  {
+    if( ncse.getIsSignerVerified())
+    {
+      updateWaitingList(ncse.getCert()->getName().toUri());
+    }
+    else
+    {
+      ndn::SignatureSha256WithRsa signature(ncse.getCert()->getSignature());
+      waitingList.addtoWaitingList(signature.getKeyLocator().getName().toUri(), 
+                                             ncse.getCert()->getName().toUri());
+    }
   }
 
   bool
@@ -30,14 +89,16 @@
     if(it == certTable.end())
     {
       certTable.push_back(ncse);
+      updateWaitingList(ncse);
       return true;
     }
-    if( it !=  certTable.end() )
+    else if( it !=  certTable.end() )
     {
       if ( (*it).getCertSeqNum() < ncse.getCertSeqNum() )
       {
         certTable.erase(it);
         certTable.push_back(ncse);
+        updateWaitingList(ncse);
         return true;
       }
     }
@@ -52,6 +113,48 @@
     return addCertificate(ncse);
   }
 
+  std::pair<uint32_t, bool>
+  NlsrCertificateStore::getCertificateSeqNum(std::string certName)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it == certTable.end())
+    {
+      return std::make_pair(0,false);
+    }
+    return std::make_pair((*it).getCertSeqNum(),true);
+  }
+  
+ 
+  
+  void 
+  NlsrCertificateStore::setCertificateIsVerified(std::string certName, 
+                                                                bool isVerified)
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it != certTable.end())
+    {
+      it->setIsSignerVerified(true);
+    }
+  }
+  
+  bool
+  NlsrCertificateStore::getCertificateIsVerified( std::string certName )
+  {
+    std::list<NlsrCertificateStoreEntry>::iterator it =
+      std::find_if( certTable.begin(), certTable.end(),
+                    bind(&nlsrCertificateStoreEntryCompareByName, _1, certName));
+    if(it != certTable.end())
+    {
+      return it->getIsSignerVerified();
+    }
+    
+    return false;
+  }
+
   std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
   NlsrCertificateStore::getCertificateFromStore(const std::string certName)
   {
@@ -61,7 +164,7 @@
     if(it == certTable.end())
     {
       ndn::shared_ptr<ndn::IdentityCertificate> cert=
-        ndn::make_shared<ndn::IdentityCertificate>();
+                                    ndn::make_shared<ndn::IdentityCertificate>();
       return std::make_pair(cert,false);
     }
     return std::make_pair((*it).getCert(),true);
@@ -126,5 +229,6 @@
     {
       std::cout<<(*it)<<std::endl;
     }
+    std::cout<<waitingList<<std::endl;
   }
 }
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
index 5c9cabb..d9c9b64 100644
--- a/src/security/nlsr_cert_store.hpp
+++ b/src/security/nlsr_cert_store.hpp
@@ -4,6 +4,7 @@
 #include<list>
 #include <ndn-cpp-dev/security/identity-certificate.hpp>
 #include "nlsr_cse.hpp"
+#include "nlsr_wl.hpp"
 
 namespace nlsr
 {
@@ -11,20 +12,30 @@
   {
   public:
     NlsrCertificateStore()
+        : certTable()
+        , waitingList()
     {}
 
     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);
+                            getCertificateFromStore(const std::string certName);
     std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
-    getCertificateFromStore(const std::string certName, int checkSeqNum);
+           getCertificateFromStore(const std::string certName, int checkSeqNum);
     bool removeCertificateFromStroe(const std::string certName);
     bool isCertificateNewInStore(const std::string certName, int checkSeqNo);
+    std::pair<uint32_t, bool> getCertificateSeqNum(std::string certName);
     void printCertStore();
+    void setCertificateIsVerified(std::string certName, bool isVerified);
+    bool getCertificateIsVerified(std::string certName);
+  private:
+    void updateWaitingList(NlsrCertificateStoreEntry& ncse);
+    void updateWaitingList(std::string respCertName);
+    
   private:
     std::list<NlsrCertificateStoreEntry> certTable;
+    WaitingList waitingList;
   };
 }
 
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
index 8838878..183e934 100644
--- a/src/security/nlsr_km.cpp
+++ b/src/security/nlsr_km.cpp
@@ -4,6 +4,7 @@
 #include <stdexcept>
 #include "nlsr_sm.hpp"
 #include "nlsr_km.hpp"
+#include "nlsr.hpp"
 
 namespace nlsr
 {
@@ -34,13 +35,13 @@
     ndn::KeyChain::deleteIdentity(processIdentity);
     processCertName = ndn::KeyChain::createIdentity(processIdentity);
     cout<<"Certificate Name: "<<processCertName.toUri()<<endl;
-    processKeyName=
-      ndn::IdentityCertificate::certificateNameToPublicKeyName(processCertName);
+    processKeyName=processCertName.getPrefix(-2);
     cout<<"Key Name: "<<processKeyName.toUri()<<endl;
-    ndn::shared_ptr<ndn::IdentityCertificate> cert=getCertificate(processCertName);
+    ndn::shared_ptr<ndn::IdentityCertificate> cert = 
+                                                getCertificate(processCertName);
     signByIdentity(*(cert),routerIdentity);
     certStore.addCertificate(cert, certSeqNo, true);
-    //certStore.printCertStore();
+    certStore.printCertStore();
     return true;
   }
 
@@ -73,22 +74,27 @@
         case KEY_TYPE_ROOT:
           certStore.addCertificate(cert, 10, true);
           rootCertName=certName;
+          std::cout<<"Root Cert: "<<rootCertName<<std::endl;
           break;
         case KEY_TYPE_SITE:
           certStore.addCertificate(cert, 10, true);
           siteCertName=certName;
+          std::cout<<"Site Cert: "<<siteCertName<<std::endl;
           break;
         case KEY_TYPE_OPERATOR:
           certStore.addCertificate(cert, 10, true);
           opCertName=certName;
+          std::cout<<"Operator Cert: "<<opCertName<<std::endl;
           break;
         case KEY_TYPE_ROUTER:
           certStore.addCertificate(cert, certSeqNo, true);
           routerCertName=certName;
+          std::cout<<"Router Cert: "<<routerCertName<<std::endl;
           break;
         case KEY_TYPE_PROCESS:
           certStore.addCertificate(cert, certSeqNo, true);
           processCertName=certName;
+          std::cout<<"Process Cert: "<<processCertName<<std::endl;
           break;
         default:
           break;
@@ -188,12 +194,24 @@
     return certStore.getCertificateFromStore(certName, checkSeqNum);
   }
 
+  std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool>
+  KeyManager::getCertificateFromStore(const std::string certName)
+  {
+    return certStore.getCertificateFromStore(certName);
+  }
+
   bool
   KeyManager::addCertificate(ndn::shared_ptr<ndn::IdentityCertificate> pcert
                              , uint32_t csn, bool isv)
   {
     return certStore.addCertificate(pcert, csn, isv);
   }
+  
+  std::pair<uint32_t, bool> 
+  KeyManager::getCertificateSeqNum(std::string certName)
+  {
+    return certStore.getCertificateSeqNum(certName);
+  }
 
   nlsrKeyType
   KeyManager::getKeyTypeFromName(const std::string keyName)
@@ -300,6 +318,85 @@
     }
     return siteName;
   }
+  
+  std::string 
+  KeyManager::getRootName(const std::string name)
+  {
+    std::string rName;
+    nlsrTokenizer nt(name,"/");
+    std::string rkp(nlsrRootKeyPrefix);
+    nlsrTokenizer ntRkp(rkp,"/");
+    rName=nt.getTokenString(0,ntRkp.getTokenNumber()-1);
+    return rName;
+  }
+  
+  
+  bool
+  KeyManager::verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
+    {
+      std::cout<<"KeyManager::verifyCertPacket Called"<<std::endl;
+      ndn::SignatureSha256WithRsa signature(packet.getSignature());
+      std::string signingCertName=signature.getKeyLocator().getName().toUri();
+      std::string packetName=packet.getName().toUri();
+      
+      std::cout<<"Packet Name: "<<packetName<<std::endl;
+      std::cout<<"Signee Name: "<<signingCertName<<std::endl;
+      
+      int paketCertType=getKeyTypeFromName(packetName);
+      int signingCertType=getKeyTypeFromName(signingCertName);
+      
+      if( signingCertType > paketCertType ) //lower level Cert can not sign
+      {                                     //upper level Cert
+        return false;
+      }
+      
+      if((signingCertType == paketCertType) && (paketCertType != KEY_TYPE_ROOT))
+      {
+        return false;
+      }
+      
+      std::pair<ndn::shared_ptr<ndn::IdentityCertificate>, bool> signee=
+                             certStore.getCertificateFromStore(signingCertName);
+      
+      if( signee.second )
+      {
+        switch(paketCertType)
+        {
+          case KEY_TYPE_ROOT:
+            return ((getRootName(packetName) == nlsrRootKeyPrefix) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()));
+            break;
+          case KEY_TYPE_SITE:
+            return ((getRootName(packetName) == getRootName(signingCertName)) &&
+                      verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                      certStore.getCertificateIsVerified(signingCertName));                   
+            break;
+          case KEY_TYPE_OPERATOR:
+            return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                     certStore.getCertificateIsVerified(signingCertName)); 
+            break;
+          case KEY_TYPE_ROUTER:
+            return ((getSiteName(packetName) == getSiteName(signingCertName)) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                     certStore.getCertificateIsVerified(signingCertName));
+            break;
+          case KEY_TYPE_PROCESS:
+            return ((getRouterName(packetName) == getRouterName(signingCertName)) &&
+                     verifySignature(packet,signee.first->getPublicKeyInfo()) &&
+                     certStore.getCertificateIsVerified(signingCertName));
+            break;
+        }
+      }
+      else
+      {
+        std::cout<<"Certificate Not Found in store. Sending Interest"<<std::endl;
+        pnlsr.getIm().expressInterest(pnlsr, signingCertName, 3,
+                              pnlsr.getConfParameter().getInterestResendTime());
+        return false;
+      }
+      return false;
+    }
 }
 
 
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
index c141fcf..7d75fb2 100644
--- a/src/security/nlsr_km.hpp
+++ b/src/security/nlsr_km.hpp
@@ -14,6 +14,7 @@
 
 namespace nlsr
 {
+  class Nlsr;
   enum nlsrKeyType
   {
     KEY_TYPE_ROOT,
@@ -173,18 +174,14 @@
         std::string routerNameFromPacketName=getRouterName(packetName);
         std::string routerNameFromCertName=getRouterName(signingCertName);
         return ( (routerNameFromPacketName== routerNameFromCertName) &&
-                 verifySignature(packet, signee.first->getPublicKeyInfo()));
+                 verifySignature(packet, signee.first->getPublicKeyInfo()) &&
+                 certStore.getCertificateIsVerified(signingCertName));
       }
       return false;
     }
 
     bool
-    verifyCertPacket(ndn::IdentityCertificate packet)
-    {
-      std::cout<<"KeyManager::verifyCertPacket Called"<<std::endl;
-      return true;
-    }
-
+    verifyCertPacket(Nlsr& pnlsr, ndn::IdentityCertificate& packet);
 
   public:
     template<typename T>
@@ -192,19 +189,17 @@
     verify(T& packet )
     {
       std::cout<<"KeyManager::verify Called"<<std::endl;
-      std::string packetName=packet.getName().toUri();
-      nlsrTokenizer nt(packetName,"/");
-      std::string keyHandle("keys");
-      if ( nt.doesTokenExist(keyHandle) )
-      {
-        return verifyCertPacket(packet);
-      }
-      else
-      {
-        return verifyDataPacket(packet);
-      }
+      
+      return verifyDataPacket(packet);
+      
       return false;
     }
+    
+    bool
+    verify(Nlsr& pnlsr, ndn::IdentityCertificate& packet)
+    {
+      return verifyCertPacket(pnlsr, packet);
+    }
 
     ndn::Name getProcessCertName();
     ndn::Name getRouterCertName();
@@ -213,6 +208,7 @@
     ndn::Name getRootCertName();
 
     uint32_t getCertSeqNo();
+    std::pair<uint32_t, bool> getCertificateSeqNum(std::string certName);
     void setCerSeqNo(uint32_t csn);
     void initCertSeqFromFile(string certSeqFileDir);
     void writeCertSeqToFile();
@@ -231,6 +227,7 @@
     nlsrKeyType getKeyTypeFromName(const std::string keyName);
     std::string getRouterName(const std::string name);
     std::string getSiteName(const std::string name);
+    std::string getRootName(const std::string name);
 
   private:
     ndn::Name processIdentity;
diff --git a/src/security/nlsr_wl.cpp b/src/security/nlsr_wl.cpp
new file mode 100644
index 0000000..39ddfe3
--- /dev/null
+++ b/src/security/nlsr_wl.cpp
@@ -0,0 +1,75 @@
+#include <ndn-cpp-dev/face.hpp>
+#include "nlsr_wl.hpp"
+
+namespace nlsr
+{
+  static bool
+  waitingListCompare(const WaitingListEntry& w1, const std::string& respCert)
+  {
+    return w1.getResponsibleCert() == respCert;
+  }
+  
+  std::pair<WaitingListEntry, bool> 
+  WaitingList::getWaitingListEntry(std::string respCert)
+  {
+    std::list<WaitingListEntry>::iterator it = std::find_if( waitingTable.begin(),
+                waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
+    if( it != waitingTable.end() )
+    {
+      return std::make_pair(*(it),true);
+    }
+    
+    WaitingListEntry wle;
+    return std::make_pair(wle,false);
+    
+  }
+  
+  bool 
+  WaitingList::addtoWaitingList(std::string respCert, std::string waitee)
+  {
+    std::list<WaitingListEntry>::iterator it = std::find_if( waitingTable.begin(),
+                waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
+    if( it == waitingTable.end() )
+    {
+      WaitingListEntry newWle(respCert);
+      newWle.addWaitee(waitee);
+      waitingTable.push_back(newWle);
+      return true;
+    }
+    else
+    {
+      return it->addWaitee(waitee);
+    }
+    return false;
+  }
+  
+  bool 
+  WaitingList::removeFromWaitingList(std::string respCert)
+  {
+    std::list<WaitingListEntry>::iterator it = std::find_if( waitingTable.begin(),
+                waitingTable.end(),ndn::bind(&waitingListCompare, _1, respCert));
+    if( it == waitingTable.end() )
+    {
+      return false;
+    }
+    else
+    {
+      waitingTable.erase(it);
+      return true;
+    }
+    return false;
+  }
+  
+  std::ostream& 
+  operator<<(std::ostream& os, WaitingList wl)
+  {
+    os<<"-------Waiting List--------"<<std::endl;
+    std::list<WaitingListEntry> wles=wl.getWaitingTable();
+    for( std::list<WaitingListEntry> ::iterator it=wles.begin(); 
+                                                        it != wles.end(); ++it)
+    {
+      os<<*(it)<<std::endl;
+    }
+    return os;
+  }
+}
diff --git a/src/security/nlsr_wl.hpp b/src/security/nlsr_wl.hpp
new file mode 100644
index 0000000..c287842
--- /dev/null
+++ b/src/security/nlsr_wl.hpp
@@ -0,0 +1,31 @@
+#ifndef NLSR_WL_HPP
+#define NLSR_WL_HPP
+
+#include "nlsr_wle.hpp"
+
+namespace nlsr
+{
+  class WaitingList
+  {
+    public:
+      WaitingList()
+        : waitingTable()
+      {}
+      
+      std::list<WaitingListEntry>& getWaitingTable()
+      {
+        return waitingTable;
+      }
+      
+      bool addtoWaitingList(std::string respCert, std::string waitee);
+      std::pair<WaitingListEntry, bool> getWaitingListEntry(std::string respCert);
+      bool removeFromWaitingList(std::string respCert);
+      
+    private:
+      std::list<WaitingListEntry> waitingTable;
+  };
+  
+  std::ostream& operator<<(std::ostream& os, WaitingList wl);
+}
+
+#endif
diff --git a/src/security/nlsr_wle.cpp b/src/security/nlsr_wle.cpp
new file mode 100644
index 0000000..df83544
--- /dev/null
+++ b/src/security/nlsr_wle.cpp
@@ -0,0 +1,42 @@
+#include <iostream>
+#include <list>
+#include <ndn-cpp-dev/face.hpp>
+#include "nlsr_wle.hpp"
+
+namespace nlsr
+{
+  static bool
+  waiteeCompare(std::string& w1, std::string& w2)
+  {
+    return w1 == w2 ;
+  }
+  
+  bool
+  WaitingListEntry::addWaitee(std::string waiteeName)
+  {
+    std::list<std::string>::iterator it = std::find_if( waitingCerts.begin(),
+                waitingCerts.end(),ndn::bind(&waiteeCompare, _1, waiteeName));
+    if( it == waitingCerts.end() )
+    {
+      waitingCerts.push_back(waiteeName);
+      return true;
+    }
+    
+    return false;
+  }
+
+  std::ostream& 
+  operator<<(std::ostream& os, const WaitingListEntry& we)
+  {
+    os<<"-------------Wiating List Entry-------------"<<std::endl;
+    os<<"Responsible Certificate: "<<we.getResponsibleCert()<<std::endl;
+    std::list<std::string> waitee=we.getWaitingCerts();
+    int i=1;
+    for(std::list<std::string>::iterator it=waitee.begin(); 
+                                             it!=waitee.end(); ++i, ++it)
+    {
+      os<<"Waite "<<i<<": "<<*(it)<<std::endl;
+    }
+    return os;
+  }
+}
diff --git a/src/security/nlsr_wle.hpp b/src/security/nlsr_wle.hpp
new file mode 100644
index 0000000..c8e6fd6
--- /dev/null
+++ b/src/security/nlsr_wle.hpp
@@ -0,0 +1,47 @@
+#ifndef NLSR_WLE_HPP
+#define NLSR_WLE_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr
+{
+  class WaitingListEntry
+  {
+    public:
+      WaitingListEntry()
+        : responsibleCert()
+        , waitingCerts()
+      {}
+      
+      WaitingListEntry(std::string resCert)
+        : responsibleCert(resCert)
+        , waitingCerts()
+      {}
+      
+      std::string getResponsibleCert() const
+      {
+        return responsibleCert;
+      }
+      
+      void setResponsibleCert(std::string resCert)
+      {
+        responsibleCert=resCert;
+      }
+      
+      std::list<std::string> getWaitingCerts() const
+      {
+        return waitingCerts;
+      }
+      
+      bool addWaitee(std::string waiteeName);
+      
+    private:
+      std::string responsibleCert;
+      std::list<std::string> waitingCerts;
+  };
+  
+  std::ostream& operator<<(std::ostream& os, const WaitingListEntry& we);
+} //end name space
+
+#endif