security: Adding SecPolicyRegex and related rules

Change-Id: Ia9c709e849c405ed57f622b8afc442ce808991fb
diff --git a/src/security/sec-policy-regex.cpp b/src/security/sec-policy-regex.cpp
new file mode 100644
index 0000000..4b74132
--- /dev/null
+++ b/src/security/sec-policy-regex.cpp
@@ -0,0 +1,151 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "sec-policy-regex.hpp"
+
+#include "verifier.hpp"
+#include "signature-sha256-with-rsa.hpp"
+
+#include "../util/logging.hpp"
+
+INIT_LOGGER("SecPolicyRegex");
+
+using namespace std;
+
+namespace ndn
+{
+
+SecPolicyRegex::SecPolicyRegex(shared_ptr<CertificateCache> certificateCache,
+                                 const int stepLimit)
+  : m_stepLimit(stepLimit)
+  , m_certificateCache(certificateCache)
+{}
+
+void
+SecPolicyRegex::onCertificateVerified(shared_ptr<Data>signCertificate, 
+                                       shared_ptr<Data>data, 
+                                       const OnVerified& onVerified, 
+                                       const OnVerifyFailed& onVerifyFailed)
+{
+  shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>(*signCertificate);
+  
+  if(!certificate->isTooLate() && !certificate->isTooEarly())
+    {
+      m_certificateCache->insertCertificate(certificate);
+      
+      try{
+        if(Verifier::verifySignature(*data, data->getSignature(), certificate->getPublicKeyInfo()))
+          {
+            onVerified();
+            return;
+          }
+      }catch(Signature::Error &e){
+        _LOG_DEBUG("SecPolicyRegex Error: " << e.what());
+        onVerifyFailed();
+        return;
+      }
+    }
+  else
+    {
+      onVerifyFailed();
+      return;
+    }
+}
+
+void
+SecPolicyRegex::onCertificateVerifyFailed(shared_ptr<Data>signCertificate, 
+                                           shared_ptr<Data>data, 
+                                           const OnVerifyFailed& onVerifyFailed)
+{ onVerifyFailed(); }
+
+shared_ptr<ValidationRequest>
+SecPolicyRegex::checkVerificationPolicy(const shared_ptr<Data>& data, 
+                                         int stepCount, 
+                                         const OnVerified& onVerified, 
+                                         const OnVerifyFailed& onVerifyFailed)
+{
+  if(m_stepLimit == stepCount){
+    _LOG_DEBUG("reach the maximum steps of verification");
+    onVerifyFailed();
+    return shared_ptr<ValidationRequest>();
+  }
+  
+  RuleList::iterator it = m_mustFailVerify.begin();
+  for(; it != m_mustFailVerify.end(); it++)
+    {
+      if((*it)->satisfy(*data))
+        {
+          onVerifyFailed();
+          return shared_ptr<ValidationRequest>();
+        }
+    }
+  
+  it = m_verifyPolicies.begin();
+  for(; it != m_verifyPolicies.end(); it++)
+    {
+      if((*it)->satisfy(*data))
+        {
+          try{
+            SignatureSha256WithRsa sig(data->getSignature());                
+            
+            Name keyLocatorName = sig.getKeyLocator().getName();
+            shared_ptr<const Certificate> trustedCert;
+            if(m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
+              trustedCert = m_certificateCache->getCertificate(keyLocatorName);
+            else
+              trustedCert = m_trustAnchors[keyLocatorName];
+            
+            if(static_cast<bool>(trustedCert)){
+              if(Verifier::verifySignature(*data, sig, trustedCert->getPublicKeyInfo()))
+                onVerified();
+              else
+                onVerifyFailed();
+              
+              return shared_ptr<ValidationRequest>();
+            }
+            else{
+              // _LOG_DEBUG("KeyLocator is not trust anchor");                
+              ValidationRequest::OnCertVerified onCertVerified = bind(&SecPolicyRegex::onCertificateVerified, 
+                                                                      this, 
+                                                                      _1, 
+                                                                      data, 
+                                                                      onVerified, 
+                                                                      onVerifyFailed);
+              
+              ValidationRequest::OnCertVerifyFailed onCertVerifyFailed = bind(&SecPolicyRegex::onCertificateVerifyFailed, 
+                                                                              this, 
+                                                                              _1, 
+                                                                              data, 
+                                                                              onVerifyFailed);
+              
+              
+              shared_ptr<Interest> interest = make_shared<Interest>(boost::cref(sig.getKeyLocator().getName()));
+
+              shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(interest, 
+                                                                                                        onCertVerified,
+                                                                                                        onCertVerifyFailed,
+                                                                                                        3,
+                                                                                                        stepCount + 1);
+              return nextStep;
+            }
+          }catch(SignatureSha256WithRsa::Error &e){
+            _LOG_DEBUG("SecPolicyRegex Error: " << e.what());
+            onVerifyFailed();
+            return shared_ptr<ValidationRequest>(); 
+          }catch(KeyLocator::Error &e){
+            _LOG_DEBUG("SecPolicyRegex Error: " << e.what());
+            onVerifyFailed();
+            return shared_ptr<ValidationRequest>(); 
+          }
+        }
+    }
+  
+  onVerifyFailed();
+  return shared_ptr<ValidationRequest>();
+}
+
+}//ndn
diff --git a/src/security/sec-policy-regex.hpp b/src/security/sec-policy-regex.hpp
new file mode 100644
index 0000000..a4d9190
--- /dev/null
+++ b/src/security/sec-policy-regex.hpp
@@ -0,0 +1,87 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_POLICY_REGEX_HPP
+#define NDN_SEC_POLICY_REGEX_HPP
+
+#include "sec-policy.hpp"
+#include "identity-certificate.hpp"
+#include "sec-rule-relative.hpp"
+#include "certificate-cache.hpp"
+#include "../util/regex.hpp"
+
+#include <map>
+
+
+
+
+namespace ndn {
+
+class SecPolicyRegex : public SecPolicy
+{
+public:
+  struct Error : public SecPolicy::Error { Error(const std::string &what) : SecPolicy::Error(what) {} };
+  
+  SecPolicyRegex(shared_ptr<CertificateCache> certificateCache, const int stepLimit = 10);
+  
+  virtual 
+  ~SecPolicyRegex() {}
+  
+  virtual shared_ptr<ValidationRequest>
+  checkVerificationPolicy(const shared_ptr<Data>& data, 
+                          int stepCount, 
+                          const OnVerified& onVerified, 
+                          const OnVerifyFailed& onVerifyFailed);
+      
+  /**
+   * @brief add a rule to check whether the data name and signing certificate name comply with the policy
+   * @param policy the verification policy
+   */
+  inline virtual void
+  addVerificationPolicyRule (shared_ptr<SecRuleRelative> rule);
+    
+  /**
+   * @brief add a trust anchor
+   * @param certificate the trust anchor 
+   */
+  inline virtual void 
+  addTrustAnchor(shared_ptr<IdentityCertificate> certificate);
+
+protected:
+  virtual void
+  onCertificateVerified(shared_ptr<Data> certificate, 
+                        shared_ptr<Data> data, 
+                        const OnVerified& onVerified, 
+                        const OnVerifyFailed& onVerifyFailed);
+  
+  virtual void
+  onCertificateVerifyFailed(shared_ptr<Data>signCertificate, 
+                            shared_ptr<Data>data, 
+                            const OnVerifyFailed& onVerifyFailed);
+  
+protected:
+  typedef std::vector< shared_ptr<SecRuleRelative> > RuleList;
+  typedef std::vector< shared_ptr<Regex> > RegexList;
+
+  int m_stepLimit;
+  shared_ptr<CertificateCache> m_certificateCache;
+  RuleList m_mustFailVerify;
+  RuleList m_verifyPolicies;
+  std::map<Name, shared_ptr<IdentityCertificate> > m_trustAnchors;
+};
+
+void 
+SecPolicyRegex::addVerificationPolicyRule (shared_ptr<SecRuleRelative> rule)
+{ rule->isPositive() ? m_verifyPolicies.push_back(rule) : m_mustFailVerify.push_back(rule); }
+      
+void  
+SecPolicyRegex::addTrustAnchor(shared_ptr<IdentityCertificate> certificate)
+{ m_trustAnchors[certificate->getName().getPrefix(-1)] = certificate; }
+
+}//ndn
+
+#endif
diff --git a/src/security/sec-policy-self-verify.cpp b/src/security/sec-policy-self-verify.cpp
deleted file mode 100644
index 6f7b657..0000000
--- a/src/security/sec-policy-self-verify.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Yingdi Yu <yingdi@cs.ucla.edu>
- * @author: Jeff Thompson <jefft0@remap.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#ifdef TEMPRORARILY_DISABLED
-
-#include "../c/util/crypto.h"
-#include "security/identity-storage.hpp"
-#include "security/sec-policy-self-verify.hpp"
-
-using namespace std;
-
-namespace ndn {
-
-SecPolicySelfVerify::~SecPolicySelfVerify()
-{
-}
-
-ptr_lib::shared_ptr<ValidationRequest>
-SecPolicySelfVerify::checkVerificationPolicy
-  (const ptr_lib::shared_ptr<const Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed)
-{ 
-  // Cast to const Data* so that we use the const version of getSignature() and don't reset the default encoding.
-  const Sha256WithRsaSignature *signature = dynamic_cast<const Sha256WithRsaSignature*>(((const Data*)data.get())->getSignature());
-  if (!signature)
-    throw SecurityException("SecPolicySelfVerify: Signature is not Sha256WithRsaSignature.");
-  
-  if (signature->getKeyLocator().getType() == ndn_KeyLocatorType_KEY) {
-    // Use the public key DER directly.
-    if (verifySha256WithRsaSignature(*data, signature->getKeyLocator().getKeyData()))
-      onVerified(data);
-    else
-      onVerifyFailed(data); 
-  }
-  else if (signature->getKeyLocator().getType() == ndn_KeyLocatorType_KEYNAME && identityStorage_) {
-    // Assume the key name is a certificate name.
-    Blob publicKeyDer = identityStorage_->getKey
-      (IdentityCertificate::certificateNameToPublicKeyName(signature->getKeyLocator().getKeyName()));
-    if (!publicKeyDer)
-      // Can't find the public key with the name.
-      onVerifyFailed(data);
-    
-    if (verifySha256WithRsaSignature(*data, publicKeyDer))
-      onVerified(data);
-    else
-      onVerifyFailed(data); 
-  }
-  else
-    // Can't find a key to verify.
-    onVerifyFailed(data); 
-  
-  // No more steps, so return a null ValidationRequest.
-  return ptr_lib::shared_ptr<ValidationRequest>();
-}
-
-}
-
-#endif // TEMPORARILY_DISABLED
diff --git a/src/security/sec-policy-self-verify.hpp b/src/security/sec-policy-self-verify.hpp
deleted file mode 100644
index 1e95d59..0000000
--- a/src/security/sec-policy-self-verify.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
-/**
- * Copyright (C) 2013 Regents of the University of California.
- * @author: Jeff Thompson <jefft0@remap.ucla.edu>
- * See COPYING for copyright and distribution information.
- */
-
-#ifndef NDN_SEC_POLICY_SELF_VERIFY_HPP
-#define NDN_SEC_POLICY_SELF_VERIFY_HPP
-
-#include "sec-policy.hpp"
-
-namespace ndn {
-
-/**
- * A SecPolicySelfVerify implements a PolicyManager to use the public key DER in the data packet's KeyLocator (if available)
- * or look in the IdentityStorage for the public key with the name in the KeyLocator (if available) and use
- * it to verify the data packet, without searching a certificate chain.  If the public key can't be found, the
- * verification fails.
- */
-class SecPolicySelfVerify : public SecPolicy {
-public:
-  /**
-   * Create a new SecPolicySelfVerify which will look up the public key in the given identityManager.
-   * @param identityManager (optional) The IdentityManager for looking up the public key.  This points to an object must which remain 
-   * valid during the life of this SecPolicySelfVerify.  If omitted, then don't look for a public key with the name 
-   * in the KeyLocator and rely on the KeyLocator having the full public key DER.
-   */
-  SecPolicySelfVerify()
-  {
-  }
-  
-  /**
-   * The virtual destructor.
-   */
-  virtual
-  ~SecPolicySelfVerify();
-
-  /**
-   * Check whether the received data packet complies with the verification policy, and get the indication of the next verification step.
-   * If there is no next verification step, that imlies policy MUST have already made the verification decision.
-   * i.e., either onVerified or onVerifyFailed callback is invoked.
-   * @param data The Data object with the signature to check.
-   * @param stepCount The number of verification steps that have been done, used to track the verification progress.
-   * @param onVerified If the signature is verified, this calls onVerified(data).
-   * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
-   * @return the indication of next verification step, null if there is no further step.
-   */
-  virtual ptr_lib::shared_ptr<ValidationRequest>
-  checkVerificationPolicy
-    (const ptr_lib::shared_ptr<const Data>& data, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
-
-  /**
-   * Check whether the received interest packet complies with the verification policy, and get the indication of the next verification step.
-   * If there is no next verification step, that implies policy MUST have already made the verification decision.
-   * i.e., either onVerified or onVerifyFailed callback is invoked.
-   * @param data The Data object with the signature to check.
-   * @param stepCount The number of verification steps that have been done, used to track the verification progress.
-   * @param onVerified If the signature is verified, this calls onVerified(data).
-   * @param onVerifyFailed If the signature check fails, this calls onVerifyFailed(data).
-   * @return the indication of next verification step, null if there is no further step.
-   */
-  virtual ptr_lib::shared_ptr<ValidationRequest>
-  checkVerificationPolicy
-    (const ptr_lib::shared_ptr<const Interest>& interest, int stepCount, const OnVerified& onVerified, const OnVerifyFailed& onVerifyFailed);
-};
-
-}
-
-#endif
diff --git a/src/security/sec-rule-relative.cpp b/src/security/sec-rule-relative.cpp
new file mode 100644
index 0000000..8da1bd1
--- /dev/null
+++ b/src/security/sec-rule-relative.cpp
@@ -0,0 +1,112 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "sec-rule-relative.hpp"
+
+#include "signature-sha256-with-rsa.hpp"
+#include "security-common.hpp"
+
+#include "../util/logging.hpp"
+
+INIT_LOGGER ("SecRuleRelative");
+
+using namespace std;
+
+namespace ndn
+{
+
+SecRuleRelative::SecRuleRelative (const string& dataRegex, const string& signerRegex, const string& op, 
+                                  const string& dataExpand, const string& signerExpand, bool isPositive)
+  : SecRule(isPositive),
+    m_dataRegex(dataRegex),
+    m_signerRegex(signerRegex),
+    m_op(op),
+    m_dataExpand(dataExpand),
+    m_signerExpand(signerExpand),
+    m_dataNameRegex(dataRegex, dataExpand),
+    m_signerNameRegex(signerRegex, signerExpand)
+{
+  if(op != ">" && op != ">=" && op != "==")
+    throw Error("op is wrong!");
+}
+
+SecRuleRelative::~SecRuleRelative()
+{ }
+
+bool 
+SecRuleRelative::satisfy (const Data& data)
+{
+  Name dataName = data.getName();
+  try{
+    SignatureSha256WithRsa sig(data.getSignature());
+    Name signerName = sig.getKeyLocator().getName ();
+    return satisfy (dataName, signerName); 
+  }catch(SignatureSha256WithRsa::Error &e){
+    return false;
+  }catch(KeyLocator::Error &e){
+    return false;
+  }
+}
+  
+bool 
+SecRuleRelative::satisfy (const Name& dataName, const Name& signerName)
+{
+  if(!m_dataNameRegex.match(dataName))
+    return false;
+  Name expandDataName = m_dataNameRegex.expand();
+
+  if(!m_signerNameRegex.match(signerName))
+    return false;
+  Name expandSignerName =  m_signerNameRegex.expand();
+  
+  bool matched = compare(expandDataName, expandSignerName);
+  
+  return matched;
+}
+
+bool 
+SecRuleRelative::matchDataName (const Data& data)
+{ return m_dataNameRegex.match(data.getName()); }
+
+bool
+SecRuleRelative::matchSignerName (const Data& data)
+{    
+  try{
+    SignatureSha256WithRsa sig(data.getSignature());
+    Name signerName = sig.getKeyLocator().getName ();
+    return m_signerNameRegex.match(signerName); 
+  }catch(SignatureSha256WithRsa::Error &e){
+    return false;
+  }catch(KeyLocator::Error &e){
+    return false;
+  }
+}
+
+bool 
+SecRuleRelative::compare(const Name & dataName, const Name & signerName)
+{  
+  if((dataName == signerName) && ("==" == m_op || ">=" == m_op))
+    return true;
+    
+  Name::const_iterator i = dataName.begin ();
+  Name::const_iterator j = signerName.begin ();
+
+  for (; i != dataName.end () && j != signerName.end (); i++, j++)
+    {
+      if ((i->compare(*j)) == 0)
+        continue;
+      else
+        return false;
+    }
+    
+  if(i == dataName.end())
+    return false;
+  else 
+    return true;
+}
+
+}//ndn
diff --git a/src/security/sec-rule-relative.hpp b/src/security/sec-rule-relative.hpp
new file mode 100644
index 0000000..1d763de
--- /dev/null
+++ b/src/security/sec-rule-relative.hpp
@@ -0,0 +1,58 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+
+#ifndef NDN_SEC_RULE_RELATIVE_HPP
+#define NDN_SEC_RULE_RELATIVE_HPP
+
+#include "sec-rule.hpp"
+#include "../util/regex.hpp"
+
+namespace ndn
+{
+  
+class SecRuleRelative : public SecRule
+{
+public:
+  struct Error : public SecRule::Error { Error(const std::string &what) : SecRule::Error(what) {} };
+  
+  SecRuleRelative(const std::string& dataRegex, const std::string& signerRegex, const std::string& op, 
+                  const std::string& dataExpand, const std::string& signerExpand, bool isPositive);
+  
+  virtual
+  ~SecRuleRelative();
+  
+  virtual bool 
+  matchDataName(const Data& data);
+  
+  virtual bool 
+  matchSignerName(const Data& data);
+  
+  virtual bool
+  satisfy(const Data& data);
+  
+  virtual bool
+  satisfy(const Name& dataName, const Name& signerName);
+  
+private:
+  bool 
+  compare(const Name& dataName, const Name& signerName);
+  
+private:
+  const std::string m_dataRegex;
+  const std::string m_signerRegex;
+  const std::string m_op;
+  const std::string m_dataExpand;
+  const std::string m_signerExpand;
+  
+  Regex m_dataNameRegex;
+  Regex m_signerNameRegex;
+};
+
+}//ndn
+
+#endif
diff --git a/src/security/sec-rule-specific.cpp b/src/security/sec-rule-specific.cpp
new file mode 100644
index 0000000..1479b6d
--- /dev/null
+++ b/src/security/sec-rule-specific.cpp
@@ -0,0 +1,55 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "sec-rule-specific.hpp"
+#include "signature-sha256-with-rsa.hpp"
+
+using namespace ndn;
+using namespace std;
+
+namespace ndn{
+
+SecRuleSpecific::SecRuleSpecific(shared_ptr<Regex> dataRegex,
+                                 shared_ptr<Regex> signerRegex)
+  : SecRule(true)
+  , m_dataRegex(dataRegex)
+  , m_signerRegex(signerRegex)
+{}
+
+SecRuleSpecific::SecRuleSpecific(const SecRuleSpecific& rule)
+  : SecRule(true)
+  , m_dataRegex(rule.m_dataRegex)
+  , m_signerRegex(rule.m_signerRegex)
+{}
+
+bool 
+SecRuleSpecific::matchDataName(const Data& data)
+{ return m_dataRegex->match(data.getName()); }
+
+bool 
+SecRuleSpecific::matchSignerName(const Data& data)
+{ 
+  try{
+    SignatureSha256WithRsa sig(data.getSignature());
+    Name signerName = sig.getKeyLocator().getName ();
+    return m_signerRegex->match(signerName); 
+  }catch(SignatureSha256WithRsa::Error &e){
+    return false;
+  }catch(KeyLocator::Error &e){
+    return false;
+  }
+}
+
+bool
+SecRuleSpecific::satisfy(const Data & data)
+{ return (matchDataName(data) && matchSignerName(data)) ? true : false ; }
+
+bool
+SecRuleSpecific::satisfy(const Name & dataName, const Name & signerName)
+{ return (m_dataRegex->match(dataName) && m_signerRegex->match(signerName)); }
+
+}
diff --git a/src/security/sec-rule-specific.hpp b/src/security/sec-rule-specific.hpp
new file mode 100644
index 0000000..21d00e6
--- /dev/null
+++ b/src/security/sec-rule-specific.hpp
@@ -0,0 +1,47 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_RULE_SPECIFIC_H
+#define NDN_SEC_RULE_SPECIFIC_H
+
+#include "sec-rule.hpp"
+#include "../util/regex.hpp"
+
+namespace ndn{
+
+class SecRuleSpecific : public ndn::SecRule
+{
+  
+public:
+  SecRuleSpecific(ndn::shared_ptr<ndn::Regex> dataRegex,
+                  ndn::shared_ptr<ndn::Regex> signerRegex);
+
+  SecRuleSpecific(const SecRuleSpecific& rule);
+
+  virtual
+  ~SecRuleSpecific() {};
+
+  bool 
+  matchDataName(const ndn::Data& data);
+
+  bool 
+  matchSignerName(const ndn::Data& data);
+
+  bool
+  satisfy(const ndn::Data& data);
+
+  bool
+  satisfy(const ndn::Name& dataName, const ndn::Name& signerName);
+  
+private:
+  ndn::shared_ptr<ndn::Regex> m_dataRegex;
+  ndn::shared_ptr<ndn::Regex> m_signerRegex;
+};
+
+}
+
+#endif
diff --git a/src/security/sec-rule.hpp b/src/security/sec-rule.hpp
new file mode 100644
index 0000000..1e2dbd0
--- /dev/null
+++ b/src/security/sec-rule.hpp
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+/**
+ * Copyright (C) 2013 Regents of the University of California.
+ * @author: Yingdi Yu <yingdi@cs.ucla.edu>
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NDN_SEC_RULE_HPP
+#define NDN_SEC_RULE_HPP
+
+#include "../data.hpp"
+
+namespace ndn
+{
+
+class SecRule
+{
+public:
+  struct Error : public std::runtime_error { Error(const std::string &what) : std::runtime_error(what) {} };
+  
+  SecRule(bool isPositive)
+  : m_isPositive(isPositive)
+  {}
+  
+  virtual 
+  ~SecRule() 
+  {}
+  
+  virtual bool 
+  matchDataName(const Data& data) = 0;
+  
+  virtual bool 
+  matchSignerName(const Data& data) = 0;
+  
+  virtual bool
+  satisfy(const Data& data) = 0;
+  
+  virtual bool
+  satisfy(const Name& dataName, const Name& signerName) = 0;
+  
+  inline bool
+  isPositive();
+  
+protected:
+  bool m_isPositive;
+};
+
+bool
+SecRule::isPositive()
+{
+  return m_isPositive;
+}
+    
+}
+
+#endif