diff --git a/src/sec-policy-sync.cc b/src/sec-policy-sync.cc
new file mode 100644
index 0000000..5a07b5c
--- /dev/null
+++ b/src/sec-policy-sync.cc
@@ -0,0 +1,462 @@
+/* -*- 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 "sync-intro-certificate.h"
+#include "sync-logging.h"
+#include <ndn-cpp/security/verifier.hpp>
+#include <ndn-cpp/security/signature-sha256-with-rsa.hpp>
+
+#include "sec-policy-sync.h"
+
+using namespace ndn;
+using namespace ndn::ptr_lib;
+using namespace std;
+
+INIT_LOGGER("SecPolicySync");
+
+SecPolicySync::SecPolicySync(const Name& signingIdentity,
+				     const Name& signingCertificateName,
+				     const Name& syncPrefix,
+                                     shared_ptr<Face> face,
+                                     int stepLimit)
+  : m_signingIdentity(signingIdentity)
+  , m_signingCertificateName(signingCertificateName.getPrefix(signingCertificateName.size()-1))
+  , m_syncPrefix(syncPrefix)
+  , m_stepLimit(stepLimit)
+  , m_keyChain(new KeyChain())
+{  
+  Name wotPrefix = syncPrefix;
+  wotPrefix.append("WOT");
+  m_syncPrefixRegex = Regex::fromName(syncPrefix);
+  m_wotPrefixRegex = Regex::fromName(wotPrefix);
+  m_chatDataPolicy = make_shared<SecRuleIdentity>("^[^<%F0.>]*<%F0.>([^<chronos>]*)<chronos><>",
+                                                  "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
+                                                  "==", "\\1", "\\1", true);  
+}
+  
+SecPolicySync::~SecPolicySync()
+{}
+
+bool 
+SecPolicySync::skipVerifyAndTrust (const Data& data)
+{ return false; }
+
+bool
+SecPolicySync::requireVerify (const Data& data)
+{ return true; }
+
+shared_ptr<ValidationRequest>
+SecPolicySync::checkVerificationPolicy(const shared_ptr<Data>& data, 
+					   int stepCount, 
+					   const OnVerified& onVerified,
+					   const OnVerifyFailed& onVerifyFailed)
+{
+  if(stepCount > m_stepLimit)
+    {
+      onVerifyFailed(data);
+      return shared_ptr<ValidationRequest>();
+    }
+
+  try{
+    SignatureSha256WithRsa sig(data->getSignature());
+
+    const Name& keyLocatorName = sig.getKeyLocator().getName();
+  
+    // if data is intro cert
+    if(m_wotPrefixRegex->match(data->getName()))
+      {
+        // _LOG_DEBUG("Intro Cert");
+        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+        map<string, PublicKey>::const_iterator it = m_trustedIntroducers.find(keyName.toUri());
+        if(m_trustedIntroducers.end() != it)
+          {
+            if(Verifier::verifySignature(*data, sig, it->second))
+              onVerified(data);
+            else
+              onVerifyFailed(data);
+            return shared_ptr<ValidationRequest>();
+          }
+        else
+          return prepareRequest(keyName, true, data, stepCount, onVerified, onVerifyFailed);
+      }
+
+    // if data is sync data or chat data
+    if(m_syncPrefixRegex->match(data->getName()) || m_chatDataPolicy->satisfy(*data))
+      {
+        Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+
+        map<string, PublicKey>::const_iterator it = m_trustedIntroducers.find(keyName.toUri());
+        if(m_trustedIntroducers.end() != it)
+          {
+            if(Verifier::verifySignature(*data, sig, it->second))
+              onVerified(data);
+            else
+              onVerifyFailed(data);
+            return shared_ptr<ValidationRequest>();
+          }
+
+        it = m_trustedProducers.find(keyName.toUri());
+        if(m_trustedProducers.end() != it)
+          {
+            if(Verifier::verifySignature(*data, sig, it->second))
+              onVerified(data);
+            else
+              onVerifyFailed(data);
+            return shared_ptr<ValidationRequest>();
+          }
+
+        return prepareRequest(keyName, false, data, stepCount, onVerified, onVerifyFailed);
+      }
+  }catch(SignatureSha256WithRsa::Error &e){
+    _LOG_DEBUG("SecPolicySync Error: " << e.what());
+    onVerifyFailed(data);
+    return shared_ptr<ValidationRequest>();
+  }catch(KeyLocator::Error &e){
+    _LOG_DEBUG("SecPolicySync Error: " << e.what());
+    onVerifyFailed(data);
+    return shared_ptr<ValidationRequest>();
+  }
+    
+  onVerifyFailed(data);
+  return shared_ptr<ValidationRequest>();
+}
+
+bool 
+SecPolicySync::checkSigningPolicy(const Name& dataName, 
+				      const Name& certificateName)
+{ 
+  return true;
+}
+    
+Name 
+SecPolicySync::inferSigningIdentity(const ndn::Name& dataName)
+{ return m_signingIdentity; }
+
+void
+SecPolicySync::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
+{
+  // _LOG_DEBUG("Add intro/producer: " << identityCertificate.getPublicKeyName());
+  if(isIntroducer)
+    m_trustedIntroducers.insert(pair <string, PublicKey > (identityCertificate.getPublicKeyName().toUri(),
+                                                           identityCertificate.getPublicKeyInfo()));
+  else
+    m_trustedProducers.insert(pair <string, PublicKey > (identityCertificate.getPublicKeyName().toUri(),
+                                                         identityCertificate.getPublicKeyInfo()));
+}
+
+void
+SecPolicySync::addChatDataRule(const Name& prefix, 
+                                   const IdentityCertificate& identityCertificate,
+                                   bool isIntroducer)
+{
+  addTrustAnchor(identityCertificate, isIntroducer);
+}
+
+
+shared_ptr<const vector<Name> >
+SecPolicySync::getAllIntroducerName()
+{
+  shared_ptr<vector<Name> > nameList = make_shared<vector<Name> >();
+  
+  map<string, PublicKey>::iterator it =  m_trustedIntroducers.begin();
+  for(; it != m_trustedIntroducers.end(); it++)
+    nameList->push_back(Name(it->first));
+  
+  return nameList;
+}
+
+shared_ptr<ValidationRequest>
+SecPolicySync::prepareRequest(const Name& keyName, 
+				  bool forIntroducer,
+				  shared_ptr<Data> data,
+				  const int & stepCount, 
+				  const OnVerified& onVerified,
+				  const OnVerifyFailed& onVerifyFailed)
+{
+  shared_ptr<Name> interestPrefixName = make_shared<Name>(m_syncPrefix);
+  interestPrefixName->append("WOT").append(keyName).append("INTRO-CERT");
+
+  shared_ptr<const vector<Name> > nameList = getAllIntroducerName();
+  if(0 == nameList->size())
+    {
+      onVerifyFailed(data);
+      return shared_ptr<ValidationRequest>();
+    }
+
+  Name interestName = *interestPrefixName;
+  interestName.append(nameList->at(0));
+
+  if(forIntroducer)
+    interestName.append("INTRODUCER");
+
+  shared_ptr<ndn::Interest> interest = make_shared<ndn::Interest>(interestName);
+  // _LOG_DEBUG("send interest for intro cert: " << interest->getName());
+
+  OnVerified requestedCertVerifiedCallback = boost::bind(&SecPolicySync::onIntroCertVerified, 
+                                                         this, 
+                                                         _1,
+                                                         forIntroducer, 
+                                                         data,
+                                                         onVerified,
+                                                         onVerifyFailed);
+                                                             
+  OnVerifyFailed requestedCertUnverifiedCallback = boost::bind(&SecPolicySync::onIntroCertVerifyFailed, 
+                                                               this, 
+                                                               _1, 
+                                                               interestPrefixName,
+                                                               forIntroducer,
+                                                               nameList,
+                                                               1,
+                                                               data,
+                                                               onVerified,
+                                                               onVerifyFailed);
+
+    
+  shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest, 
+                                                                          requestedCertVerifiedCallback,
+                                                                          requestedCertUnverifiedCallback,
+                                                                          1,
+                                                                          m_stepLimit-1);
+  return nextStep;
+}
+
+void
+SecPolicySync::OnIntroCertInterest(const shared_ptr<const Name>& prefix, 
+                                       const shared_ptr<const ndn::Interest>& interest, 
+                                       Transport& transport, 
+                                       uint64_t registeredPrefixId)
+{
+  map<string, Data>::const_iterator it = m_introCert.find(prefix->toUri());
+
+  if(m_introCert.end() != it)
+    m_face->put(it->second);
+}
+
+void
+SecPolicySync::OnIntroCertRegisterFailed(const shared_ptr<const Name>& prefix)
+{
+}
+
+void
+SecPolicySync::onIntroCertVerified(const shared_ptr<Data>& introCertificateData,
+				       bool forIntroducer,
+				       shared_ptr<Data> originalData,
+				       const OnVerified& onVerified,
+				       const OnVerifyFailed& onVerifyFailed)
+{
+  shared_ptr<SyncIntroCertificate> introCertificate = make_shared<SyncIntroCertificate>(*introCertificateData);
+  if(forIntroducer)
+    {
+      m_trustedIntroducers.insert(pair <string, PublicKey > (introCertificate->getPublicKeyName().toUri(),
+                                                             introCertificate->getPublicKeyInfo()));
+      SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
+                                                introCertificate->getPublicKeyName(),
+                                                m_keyChain->getDefaultKeyNameForIdentity(m_signingIdentity),
+                                                introCertificate->getNotBefore(),
+                                                introCertificate->getNotAfter(),
+                                                introCertificate->getPublicKeyInfo(),
+                                                SyncIntroCertificate::INTRODUCER);
+
+      Name certName = m_keyChain->getDefaultCertificateNameForIdentity(m_signingIdentity);
+      _LOG_DEBUG("Publish Intro Certificate on Verified: " << syncIntroCertificate.getName());
+      m_keyChain->sign(syncIntroCertificate, certName);
+
+      m_face->put(syncIntroCertificate);
+
+      // Name prefix = syncIntroCertificate.getName().getPrefix(syncIntroCertificate.getName().size()-1);
+
+      // map<string, Data>::const_iterator it = m_introCert.find(prefix.toEscapedString());
+      // if(m_introCert.end() != it)
+      //   {
+      //     it->second = syncIntroCertificate;
+      //   }
+      // else
+      //   {         
+      //     m_introCert.insert(pair <string, Data> (prefix.toEscapedString(), syncIntroCertificate));
+      //     m_face->registerPrefix(prefix, 
+      //                           boost::bind(&SecPolicySync::onIntroCertInterest, this, _1, _2, _3, _4), 
+      //                           boost::bind(&SecPolicySync::onIntroCertRegisterFailed, this, _1));
+      //   }
+    }
+  else
+    {
+      m_trustedProducers.insert(pair <string, PublicKey > (introCertificate->getPublicKeyName().toUri(), 
+                                                           introCertificate->getPublicKeyInfo()));
+      SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
+                                                introCertificate->getPublicKeyName(),
+                                                m_keyChain->getDefaultKeyNameForIdentity(m_signingIdentity),
+                                                introCertificate->getNotBefore(),
+                                                introCertificate->getNotAfter(),
+                                                introCertificate->getPublicKeyInfo(),
+                                                SyncIntroCertificate::PRODUCER);
+
+      Name certName = m_keyChain->getDefaultCertificateNameForIdentity(m_signingIdentity);
+      _LOG_DEBUG("Publish Intro Certificate on Verified: " << syncIntroCertificate.getName());
+      m_keyChain->sign(syncIntroCertificate, certName);
+      
+      m_face->put(syncIntroCertificate);
+
+      // Name prefix = syncIntroCertificate.getName().getPrefix(syncIntroCertificate.getName().size()-1);
+
+      // map<string, Data>::const_iterator it = m_introCert.find(prefix.toEscapedString());
+      // if(m_introCert.end() != it)
+      //   {
+      //     it->second = syncIntroCertificate;
+      //   }
+      // else
+      //   {
+      //     m_introCert.insert(pair <string, Data> (prefix.toEscapedString(), syncIntroCertificate));
+      //     m_face->registerPrefix(prefix, 
+      //                           boost::bind(&SecPolicySync::onIntroCertInterest, this, _1, _2, _3, _4), 
+      //                           boost::bind(&SecPolicySync::onIntroCertRegisterFailed, this, _1));
+      //   }
+    }
+
+  try{
+    SignatureSha256WithRsa sig(originalData->getSignature());
+    if(Verifier::verifySignature(*originalData, sig, introCertificate->getPublicKeyInfo()))      
+      onVerified(originalData);    
+    else
+      onVerifyFailed(originalData);
+  }catch(SignatureSha256WithRsa::Error &e){
+    onVerifyFailed(originalData);
+  }catch(KeyLocator::Error &e){
+    onVerifyFailed(originalData);
+  }
+}
+
+void 
+SecPolicySync::onIntroCertVerifyFailed(const shared_ptr<Data>& introCertificateData,
+                                           shared_ptr<Name> interestPrefixName,
+                                           bool forIntroducer,
+                                           shared_ptr<const vector<Name> > introNameList,
+                                           int nextIntroducerIndex,
+                                           shared_ptr<Data> originalData,
+                                           const OnVerified& onVerified,
+                                           const OnVerifyFailed& onVerifyFailed)
+{
+  Name interestName = *interestPrefixName;
+  if(nextIntroducerIndex < introNameList->size())
+    interestName.append(introNameList->at(nextIntroducerIndex));
+  else
+    onVerifyFailed(originalData);
+
+  if(forIntroducer)
+    interestName.append("INTRODUCER");
+  
+  shared_ptr<ndn::Interest> interest = make_shared<ndn::Interest>(interestName);
+
+  OnVerified onRecursiveVerified = boost::bind(&SecPolicySync::onIntroCertVerified, 
+                                      this, 
+                                      _1,
+                                      forIntroducer, 
+                                      originalData,
+                                      onVerified,
+                                      onVerifyFailed);
+
+  OnVerifyFailed onRecursiveVerifyFailed = boost::bind(&SecPolicySync::onIntroCertVerifyFailed, 
+                                              this, 
+                                              _1,
+                                              interestPrefixName,
+                                              forIntroducer,
+                                              introNameList,
+                                              nextIntroducerIndex + 1,
+                                              originalData, 
+                                              onVerified,
+                                              onVerifyFailed);
+        
+  m_face->expressInterest(*interest, 
+                          boost::bind(&SecPolicySync::onIntroCertData,
+                                      this,
+                                      _1,
+                                      _2,     
+                                      m_stepLimit-1,
+                                      onRecursiveVerified,
+                                      onRecursiveVerifyFailed,
+                                      originalData,
+                                      onVerifyFailed),
+                          boost::bind(&SecPolicySync::onIntroCertTimeout, 
+                                      this,
+                                      _1,
+                                      1,
+                                      m_stepLimit-1,
+                                      onRecursiveVerified,
+                                      onRecursiveVerifyFailed,
+                                      originalData,
+                                      onVerifyFailed));
+}
+
+void
+SecPolicySync::onIntroCertData(const shared_ptr<const ndn::Interest> &interest,
+                                   const shared_ptr<Data>& introCertificateData,
+                                   int stepCount,
+                                   const OnVerified& onRecursiveVerified,
+                                   const OnVerifyFailed& onRecursiveVerifyFailed,
+                                   shared_ptr<Data> originalData,
+                                   const OnVerifyFailed& onVerifyFailed)
+{
+  shared_ptr<ValidationRequest> nextStep = checkVerificationPolicy(introCertificateData, stepCount, onRecursiveVerified, onRecursiveVerifyFailed);
+  if (nextStep)
+    m_face->expressInterest
+      (*nextStep->interest_, 
+       boost::bind(&SecPolicySync::onIntroCertData, 
+                   this, 
+                   _1, 
+                   _2,
+                   nextStep->stepCount_,
+                   nextStep->onVerified_, 
+                   nextStep->onVerifyFailed_,
+                   introCertificateData,
+                   onRecursiveVerifyFailed), 
+       boost::bind(&SecPolicySync::onIntroCertTimeout, 
+                   this, 
+                   _1, 
+                   nextStep->retry_, 
+                   nextStep->stepCount_, 
+                   nextStep->onVerified_, 
+                   nextStep->onVerifyFailed_,
+                   introCertificateData,
+                   onRecursiveVerifyFailed));
+}
+
+void
+SecPolicySync::onIntroCertTimeout(const shared_ptr<const ndn::Interest>& interest, 
+				      int retry, 
+                                      int stepCount,
+                                      const OnVerified& onRecursiveVerified,
+                                      const OnVerifyFailed& onRecursiveVerifyFailed,
+                                      shared_ptr<Data> originalData,
+                                      const OnVerifyFailed& onVerifyFailed)
+{
+  if(retry > 0)
+    {
+      m_face->expressInterest(*interest, 
+                              boost::bind(&SecPolicySync::onIntroCertData, 
+                                          this,
+                                          _1,
+                                          _2,
+                                          stepCount,
+                                          onRecursiveVerified,
+                                          onRecursiveVerifyFailed,
+                                          originalData,
+                                          onVerifyFailed),
+                              boost::bind(&SecPolicySync::onIntroCertTimeout, 
+                                          this,
+                                          _1,
+                                          retry - 1,
+                                          stepCount,
+                                          onRecursiveVerified,
+                                          onRecursiveVerifyFailed,
+                                          originalData,
+                                          onVerifyFailed));
+    }
+  else
+    onVerifyFailed(originalData);
+}
