security: Add failureInfo in ValidationFailed callback

Change-Id: I98e49fc88665ad7b7c268bd6a8fdddf6b7071021
diff --git a/src/helpers/command-interest-validator.hpp b/src/helpers/command-interest-validator.hpp
index 3c8764e..8c5ecc3 100644
--- a/src/helpers/command-interest-validator.hpp
+++ b/src/helpers/command-interest-validator.hpp
@@ -49,7 +49,7 @@
                const OnDataValidationFailed &onValidationFailed,
                std::vector<shared_ptr<ValidationRequest> > &nextSteps)
   {
-    onValidationFailed(data.shared_from_this());
+    onValidationFailed(data.shared_from_this(), "No policy for data checking");
   }
   
   virtual void
@@ -88,73 +88,64 @@
                                        const OnInterestValidationFailed &onValidationFailed,
                                        std::vector<shared_ptr<ValidationRequest> > &nextSteps)
 {
-  try
+  const Name& interestName = interest.getName();
+  
+  //Prepare 
+  if (interestName.size() < 4)
+    return onValidationFailed(interest.shared_from_this(), 
+                              "Interest is not signed: " + interest.getName().toUri());
+  
+  Signature signature(interestName[POS_SIG_INFO].blockFromValue(), 
+                      interestName[POS_SIG_VALUE].blockFromValue());
+  
+  SignatureSha256WithRsa sig(signature);
+  const Name& keyLocatorName = sig.getKeyLocator().getName();
+  Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
+  
+  //Check if command is in the trusted scope
+  bool inScope = false;  
+  for(std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
+      scopeIt != m_trustScopeForInterest.end();
+      ++scopeIt)
     {
-      const Name& interestName = interest.getName();
-
-      if (interestName.size() < 4)
-        return onValidationFailed(interest.shared_from_this());
-
-      Signature signature(interestName[POS_SIG_INFO].blockFromValue(), 
-                          interestName[POS_SIG_VALUE].blockFromValue());
-    
-      SignatureSha256WithRsa sig(signature);
-      const Name& keyLocatorName = sig.getKeyLocator().getName();
-      Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
-
-      //Check if command is in the trusted scope
-      bool inScope = false;  
-      for(std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
-          scopeIt != m_trustScopeForInterest.end();
-          ++scopeIt)
+      if(scopeIt->satisfy(interestName, keyName))
         {
-          if(scopeIt->satisfy(interestName, keyName))
-            {
-              inScope = true;
-              break;
-            }
+          inScope = true;
+          break;
         }
-      if(inScope == false)
-        {
-          onValidationFailed(interest.shared_from_this());
-          return;
-        }
-
-      //Check if timestamp is valid
-      uint64_t timestamp = interestName.get(POS_TIMESTAMP).toNumber();
-      uint64_t current = static_cast<uint64_t>(time::now()/1000000);
-      std::map<Name, uint64_t>::const_iterator timestampIt = m_lastTimestamp.find(keyName);
-      if(timestampIt == m_lastTimestamp.end())
-        {
-          if(timestamp > (current + m_graceInterval) || (timestamp + m_graceInterval) < current)
-            {
-              onValidationFailed(interest.shared_from_this());
-              return;
-            }
-        }
-      else if(m_lastTimestamp[keyName] >= timestamp)
-        {
-          onValidationFailed(interest.shared_from_this());
-          return;
-        }
-
-      if(!Validator::verifySignature(interestName.wireEncode().value(),
-                                     interestName.wireEncode().value_size() - interestName[-1].size(),
-                                     sig, m_trustAnchorsForInterest[keyName]))
-        {
-          onValidationFailed(interest.shared_from_this());
-          return;
-        }
-
-      m_lastTimestamp[keyName] = timestamp;
-      onValidated(interest.shared_from_this());
-      return;
-
     }
-  catch(...)
+  if(inScope == false)
+    return onValidationFailed(interest.shared_from_this(), 
+                              "Signer cannot be authorized for the command: " + interest.getName().toUri());
+
+  //Check if timestamp is valid
+  uint64_t timestamp = interestName.get(POS_TIMESTAMP).toNumber();
+  uint64_t current = static_cast<uint64_t>(time::now()/1000000);
+  std::map<Name, uint64_t>::const_iterator timestampIt = m_lastTimestamp.find(keyName);
+  if(timestampIt == m_lastTimestamp.end())
     {
-      onValidationFailed(interest.shared_from_this());
+      if(timestamp > (current + m_graceInterval) || (timestamp + m_graceInterval) < current)
+        return onValidationFailed(interest.shared_from_this(), 
+                                  "The command is not in grace interval: " + interest.getName().toUri());
     }
+  else 
+    {
+      if(m_lastTimestamp[keyName] >= timestamp)
+        return onValidationFailed(interest.shared_from_this(), 
+                                  "The command is outdated: " + interest.getName().toUri());
+    }
+
+  //Check signature
+  if(!Validator::verifySignature(interestName.wireEncode().value(),
+                                 interestName.wireEncode().value_size() - interestName[-1].size(),
+                                 sig, m_trustAnchorsForInterest[keyName]))
+    return onValidationFailed(interest.shared_from_this(), 
+                              "Signature cannot be validated: " + interest.getName().toUri());
+
+  //Update timestamp
+  m_lastTimestamp[keyName] = timestamp;
+
+  return onValidated(interest.shared_from_this());
 }
 
 
diff --git a/src/security/validation-request.hpp b/src/security/validation-request.hpp
index 4dc3a11..f64082b 100644
--- a/src/security/validation-request.hpp
+++ b/src/security/validation-request.hpp
@@ -6,8 +6,8 @@
  * See COPYING for copyright and distribution information.
  */
 
-#ifndef NDN_VALIDATION_REQUEST_HPP
-#define NDN_VALIDATION_REQUEST_HPP
+#ifndef NDN_SECURITY_VALIDATION_REQUEST_HPP
+#define NDN_SECURITY_VALIDATION_REQUEST_HPP
 
 #include "../interest.hpp"
 
@@ -15,22 +15,22 @@
 /**
  * An OnVerified function object is used to pass a callback to report a successful Interest validation.
  */
-typedef function< void (const shared_ptr<const Interest> &) > OnInterestValidated;
+typedef function< void (const shared_ptr<const Interest>&) > OnInterestValidated;
   
 /**
  * An OnVerifyFailed function object is used to pass a callback to report a failed Interest validation.
  */
-typedef function< void (const shared_ptr<const Interest> &) > OnInterestValidationFailed;
+typedef function< void (const shared_ptr<const Interest>&, const std::string&) > OnInterestValidationFailed;
 
 /**
  * An OnVerified function object is used to pass a callback to report a successful Data validation.
  */
-typedef function< void (const shared_ptr<const Data> &) > OnDataValidated;
+typedef function< void (const shared_ptr<const Data>&) > OnDataValidated;
   
 /**
  * An OnVerifyFailed function object is used to pass a callback to report a failed Data validation.
  */
-typedef function< void (const shared_ptr<const Data> &) > OnDataValidationFailed;
+typedef function< void (const shared_ptr<const Data>&, const std::string&) > OnDataValidationFailed;
 
 
 class ValidationRequest {
@@ -56,6 +56,6 @@
   int m_stepCount;                          // The stepCount of next step.
 };
 
-}
+} // namespace ndn
 
-#endif
+#endif //NDN_SECURITY_VALIDATION_REQUEST_HPP
diff --git a/src/security/validator-regex.cpp b/src/security/validator-regex.cpp
index 6569b58..85fb534 100644
--- a/src/security/validator-regex.cpp
+++ b/src/security/validator-regex.cpp
@@ -47,31 +47,26 @@
     {
       m_certificateCache->insertCertificate(certificate);
       
-      try{
-        if(verifySignature(*data, certificate->getPublicKeyInfo()))
-          {
-            onValidated(data);
-            return;
-          }
-      }catch(Signature::Error &e){
-        _LOG_DEBUG("ValidatorRegex Error: " << e.what());
-        onValidationFailed(data);
-        return;
-      }
+      if(verifySignature(*data, certificate->getPublicKeyInfo()))
+        return onValidated(data);
+      else
+        return onValidationFailed(data, 
+                                  "Cannot verify signature: " + data->getName().toUri());
     }
   else
     {
       _LOG_DEBUG("Wrong validity:");
-      onValidationFailed(data);
-      return;
+      return onValidationFailed(data, 
+                                "Signing certificate " + signCertificate->getName().toUri() + " is no longer valid.");
     }
 }
 
 void
 ValidatorRegex::onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate, 
+                                              const string& failureInfo,
                                               const shared_ptr<const Data> &data, 
                                               const OnDataValidationFailed &onValidationFailed)
-{ onValidationFailed(data); }
+{ onValidationFailed(data, failureInfo); }
 
 void
 ValidatorRegex::checkPolicy(const Data& data, 
@@ -80,73 +75,72 @@
                             const OnDataValidationFailed &onValidationFailed,
                             vector<shared_ptr<ValidationRequest> > &nextSteps)
 {
-  if(m_stepLimit == stepCount){
-    _LOG_DEBUG("reach the maximum steps of verification");
-    onValidationFailed(data.shared_from_this());
-    return;
-  }
-  
+  if(m_stepLimit == stepCount)
+    return onValidationFailed(data.shared_from_this(), 
+                              "Maximum steps of validation reached: " + data.getName().toUri());
+
   RuleList::iterator it = m_mustFailVerify.begin();
   for(; it != m_mustFailVerify.end(); it++)
     if((*it)->satisfy(data))
-      {
-        onValidationFailed(data.shared_from_this());
-        return;
-      }
+      return onValidationFailed(data.shared_from_this(),
+                                "Comply with mustFail policy: " + data.getName().toUri());
 
   it = m_verifyPolicies.begin();
   for(; it != m_verifyPolicies.end(); it++)
     {
       if((*it)->satisfy(data))
         {
-          try{
-            SignatureSha256WithRsa sig(data.getSignature());                
+          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(verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
-                onValidated(data.shared_from_this());
+              Name keyLocatorName = sig.getKeyLocator().getName();
+              shared_ptr<const Certificate> trustedCert;
+              if(m_trustAnchors.end() == m_trustAnchors.find(keyLocatorName))
+                trustedCert = m_certificateCache->getCertificate(keyLocatorName);
               else
-                onValidationFailed(data.shared_from_this());
+                trustedCert = m_trustAnchors[keyLocatorName];
+            
+              if(static_cast<bool>(trustedCert)){
+                if(verifySignature(data, sig, trustedCert->getPublicKeyInfo()))
+                  return onValidated(data.shared_from_this());
+                else
+                  return onValidationFailed(data.shared_from_this(), 
+                                            "Cannot verify signature: " + data.getName().toUri());
+              }
+              else{
+                // _LOG_DEBUG("KeyLocator is not trust anchor");                
+                OnDataValidated onKeyValidated = bind(&ValidatorRegex::onCertificateValidated, this, 
+                                                      _1, data.shared_from_this(), onValidated, onValidationFailed);
               
-              return;
-            }
-            else{
-              // _LOG_DEBUG("KeyLocator is not trust anchor");                
-              OnDataValidated onKeyValidated = bind(&ValidatorRegex::onCertificateValidated, this, 
-                                                    _1, data.shared_from_this(), onValidated, onValidationFailed);
-              
-              OnDataValidationFailed onKeyValidationFailed = bind(&ValidatorRegex::onCertificateValidationFailed, this, 
-                                                                  _1, data.shared_from_this(), onValidationFailed);              
+                OnDataValidationFailed onKeyValidationFailed = bind(&ValidatorRegex::onCertificateValidationFailed, this, 
+                                                                    _1, _2, data.shared_from_this(), onValidationFailed);              
 
-              shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(Interest(boost::cref(sig.getKeyLocator().getName())), 
-                                                                                      onKeyValidated,
-                                                                                      onKeyValidationFailed,
-                                                                                      3,
-                                                                                      stepCount + 1);
-              nextSteps.push_back(nextStep);
-              return;
+                shared_ptr<ValidationRequest> nextStep = make_shared<ValidationRequest>(Interest(boost::cref(sig.getKeyLocator().getName())), 
+                                                                                        onKeyValidated,
+                                                                                        onKeyValidationFailed,
+                                                                                        3,
+                                                                                        stepCount + 1);
+                nextSteps.push_back(nextStep);
+
+                return;
+              }
             }
-          }catch(SignatureSha256WithRsa::Error &e){
-            _LOG_DEBUG("ValidatorRegex Error: " << e.what());
-            onValidationFailed(data.shared_from_this());
-            return;
-          }catch(KeyLocator::Error &e){
-            _LOG_DEBUG("ValidatorRegex Error: " << e.what());
-            onValidationFailed(data.shared_from_this());
-            return;
-          }
+          catch(SignatureSha256WithRsa::Error &e)
+            {
+              return onValidationFailed(data.shared_from_this(), 
+                                        "Not SignatureSha256WithRsa signature: " + data.getName().toUri());
+            }
+          catch(KeyLocator::Error &e)
+            {
+              return onValidationFailed(data.shared_from_this(),
+                                        "Key Locator is not a name: " + data.getName().toUri());
+            }
         }
     }
 
-  onValidationFailed(data.shared_from_this());
-  return;
+  return onValidationFailed(data.shared_from_this(), 
+                            "No policy found for data: " + data.getName().toUri());
 }
 
 } // namespace ndn
diff --git a/src/security/validator-regex.hpp b/src/security/validator-regex.hpp
index f57d128..f80eb76 100644
--- a/src/security/validator-regex.hpp
+++ b/src/security/validator-regex.hpp
@@ -60,7 +60,7 @@
                const OnInterestValidated &onValidated, 
                const OnInterestValidationFailed &onValidationFailed,
                std::vector<shared_ptr<ValidationRequest> > &nextSteps)
-  { onValidationFailed(interest.shared_from_this()); }
+  { onValidationFailed(interest.shared_from_this(), "No policy for signed interest checking"); }
 
   void
   onCertificateValidated(const shared_ptr<const Data> &signCertificate, 
@@ -69,7 +69,8 @@
                          const OnDataValidationFailed &onValidationFailed);
   
   void
-  onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate, 
+  onCertificateValidationFailed(const shared_ptr<const Data> &signCertificate,
+                                const std::string& failureInfo,
                                 const shared_ptr<const Data> &data, 
                                 const OnDataValidationFailed &onValidationFailed);
   
diff --git a/src/security/validator.cpp b/src/security/validator.cpp
index d0c808b..cabd082 100644
--- a/src/security/validator.cpp
+++ b/src/security/validator.cpp
@@ -40,7 +40,7 @@
         throw Error("Face should be set prior to verify method to call");
       
       vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
-      OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this());
+      OnFailure onFailure = bind(onValidationFailed, interest.shared_from_this(), _1);
       for(; it != nextSteps.end(); it++)
         m_face->expressInterest((*it)->m_interest,
                                 bind(&Validator::onData, this, _1, _2, *it), 
@@ -71,7 +71,7 @@
         throw Error("Face should be set prior to verify method to call");
 
       vector<shared_ptr<ValidationRequest> >::const_iterator it = nextSteps.begin();
-      OnFailure onFailure = bind(onValidationFailed, data.shared_from_this());
+      OnFailure onFailure = bind(onValidationFailed, data.shared_from_this(), _1);
       for(; it != nextSteps.end(); it++)
         m_face->expressInterest((*it)->m_interest,
                                 bind(&Validator::onData, this, _1, _2, *it), 
@@ -107,29 +107,32 @@
                             bind(&Validator::onData, this, _1, _2, nextStep), 
                             bind(&Validator::onTimeout, this, _1, retry - 1, onFailure, nextStep));
   else
-    onFailure();
+    onFailure("Cannot fetch cert: " + interest.getName().toUri());
 }
 
 bool
 Validator::verifySignature(const Data& data, const PublicKey& key)
 {
-  try{
-    switch(data.getSignature().getType()){
-    case Signature::Sha256WithRsa:
-      {
-        SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
-        return verifySignature(data, sigSha256Rsa, key);
-      }
-    default:
-      {
-        _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
-        return false;
+  try
+    {
+      switch(data.getSignature().getType()){
+      case Signature::Sha256WithRsa:
+        {
+          SignatureSha256WithRsa sigSha256Rsa(data.getSignature());
+          return verifySignature(data, sigSha256Rsa, key);
+        }
+      default:
+        {
+          _LOG_DEBUG("verifySignature: Unknown signature type: " << data.getSignature().getType());
+          return false;
+        }
       }
     }
-  }catch(Signature::Error &e){
-    _LOG_DEBUG("verifySignature: " << e.what());
-    return false;
-  }
+  catch(Signature::Error &e)
+    {
+      _LOG_DEBUG("verifySignature: " << e.what());
+      return false;
+    }
   return false;
 }
 
@@ -141,119 +144,89 @@
   if(interestName.size() < 2)
     return false;
 
-  try{
-    const Block& nameBlock = interestName.wireEncode();
+  try
+    {
+      const Block& nameBlock = interestName.wireEncode();
 
-    Signature sig(interestName[-2].blockFromValue(), 
-                  interestName[-1].blockFromValue());
+      Signature sig(interestName[-2].blockFromValue(), 
+                    interestName[-1].blockFromValue());
 
-    switch(sig.getType()){
-    case Signature::Sha256WithRsa:
-      {
-        SignatureSha256WithRsa sigSha256Rsa(sig);
+      switch(sig.getType()){
+      case Signature::Sha256WithRsa:
+        {
+          SignatureSha256WithRsa sigSha256Rsa(sig);
 
-        return verifySignature(nameBlock.value(), 
-                               nameBlock.value_size() - interestName[-1].size(), 
-                               sigSha256Rsa, key);
-      }
-    default:
-      {
-        _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
-        return false;
+          return verifySignature(nameBlock.value(), 
+                                 nameBlock.value_size() - interestName[-1].size(), 
+                                 sigSha256Rsa, key);
+        }
+      default:
+        {
+          _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
+          return false;
+        }
       }
     }
-  }catch(Signature::Error &e){
-    _LOG_DEBUG("verifySignature: " << e.what());
-    return false;
-  }catch(Block::Error &e){
-    _LOG_DEBUG("verifySignature: " << e.what());
-    return false;
-  }
+  catch(Signature::Error &e)
+    {
+      _LOG_DEBUG("verifySignature: " << e.what());
+      return false;
+    }
+  catch(Block::Error &e)
+    {
+      _LOG_DEBUG("verifySignature: " << e.what());
+      return false;
+    }
   return false;
 }
 
 bool
 Validator::verifySignature(const Buffer &data, const Signature &sig, const PublicKey &key)
 {
-  try{
-    switch(sig.getType()){
-    case Signature::Sha256WithRsa:
-      {
-        SignatureSha256WithRsa sigSha256Rsa(sig);
-        return verifySignature(data, sigSha256Rsa, key);
-      }
-    default:
-      {
-        _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
-        return false;
+  try
+    {
+      switch(sig.getType()){
+      case Signature::Sha256WithRsa:
+        {
+          SignatureSha256WithRsa sigSha256Rsa(sig);
+          return verifySignature(data, sigSha256Rsa, key);
+        }
+      default:
+        {
+          _LOG_DEBUG("verifySignature: Unknown signature type: " << sig.getType());
+          return false;
+        }
       }
     }
-  }catch(Signature::Error &e){
-    _LOG_DEBUG("verifySignature: " << e.what());
-    return false;
-  }
+  catch(Signature::Error &e)
+    {
+      _LOG_DEBUG("verifySignature: " << e.what());
+      return false;
+    }
   return false;
 }
 
 bool
-Validator::verifySignature(const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
-{
-  using namespace CryptoPP;
-
-  bool result = false;
-  
-  RSA::PublicKey publicKey;
-  ByteQueue queue;
-
-  queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
-  publicKey.Load(queue);
-
-  RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-  result = verifier.VerifyMessage(data.wireEncode().value(), data.wireEncode().value_size() - data.getSignature().getValue().size(),
-				  sig.getValue().value(), sig.getValue().value_size());
-
-  _LOG_DEBUG("Signature verified? " << data.getName().toUri() << " " << boolalpha << result);
-  
-  return result;
-}
-
-bool
-Validator::verifySignature(const Buffer& data, const SignatureSha256WithRsa& sig, const PublicKey& key)
-{
-  using namespace CryptoPP;
-
-  bool result = false;
-  
-  RSA::PublicKey publicKey;
-  ByteQueue queue;
-
-  queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
-  publicKey.Load(queue);
-
-  RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-  result = verifier.VerifyMessage(data.buf(), data.size(),
-				  sig.getValue().value(), sig.getValue().value_size());
-  
-  return result;
-}
-
-bool
 Validator::verifySignature(const uint8_t* buf, const size_t size, const SignatureSha256WithRsa &sig, const PublicKey &key)
 {
-  using namespace CryptoPP;
+  try
+    {
+      using namespace CryptoPP;
 
-  bool result = false;
-  
-  RSA::PublicKey publicKey;
-  ByteQueue queue;
+      RSA::PublicKey publicKey;
+      ByteQueue queue;
 
-  queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
-  publicKey.Load(queue);
+      queue.Put(reinterpret_cast<const byte*>(key.get().buf()), key.get().size());
+      publicKey.Load(queue);
 
-  RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
-  result = verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
-  
-  return result;
+      RSASS<PKCS1v15, SHA256>::Verifier verifier (publicKey);
+      return verifier.VerifyMessage(buf, size, sig.getValue().value(), sig.getValue().value_size());
+    }
+  catch(CryptoPP::Exception& e)
+    {
+      _LOG_DEBUG("verifySignature: " << e.what());
+      return false;
+    }
 }
 
 } // namespace ndn
diff --git a/src/security/validator.hpp b/src/security/validator.hpp
index 7a75f70..4aae107 100644
--- a/src/security/validator.hpp
+++ b/src/security/validator.hpp
@@ -71,11 +71,15 @@
 
   /// @brief Verify the data using the publicKey against the SHA256-RSA signature.
   static bool
-  verifySignature (const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey);
+  verifySignature (const Data& data, const SignatureSha256WithRsa& sig, const PublicKey& publicKey)
+  { return verifySignature (data.wireEncode().value(), 
+                            data.wireEncode().value_size() - data.getSignature().getValue().size(), 
+                            sig, publicKey); }
 
   /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
   static bool
-  verifySignature (const Buffer &blob, const SignatureSha256WithRsa &sig, const PublicKey &publicKey);
+  verifySignature (const Buffer &blob, const SignatureSha256WithRsa &sig, const PublicKey &publicKey)
+  { return verifySignature (blob.buf(), blob.size(), sig, publicKey); }
   
   /// @brief Verify the blob using the publicKey against the SHA256-RSA signature.
   static bool
@@ -121,7 +125,7 @@
                std::vector<shared_ptr<ValidationRequest> > &nextSteps) = 0;
 
 private:
-  typedef function< void () > OnFailure;
+  typedef function< void (const std::string&) > OnFailure;
   
   /// @brief Process the received certificate.
   void
diff --git a/tests/security/test-signed-interest.cpp b/tests/security/test-signed-interest.cpp
index 3adb0a4..4be5d9f 100644
--- a/tests/security/test-signed-interest.cpp
+++ b/tests/security/test-signed-interest.cpp
@@ -54,8 +54,10 @@
   { m_validity = true; }
 
   void
-  validationFailed(const shared_ptr<const Interest>& interest)
-  { m_validity = false; }
+  validationFailed(const shared_ptr<const Interest>& interest, const string& failureInfo)
+  {
+    m_validity = false; 
+  }
 
   void
   reset()
@@ -67,7 +69,7 @@
 BOOST_FIXTURE_TEST_CASE (CommandInterest, CommandInterestFixture)
 {
   KeyChain keyChain;
-  Name identity("/TestCommandInterest/Validation");
+  Name identity("/TestCommandInterest/Validation/" + boost::lexical_cast<string>(time::now()));
   Name certName;
   BOOST_REQUIRE_NO_THROW(certName = keyChain.createIdentity(identity));
 
@@ -81,7 +83,7 @@
   generator.generateWithIdentity(*commandInterest1, identity);
   validator.validate(*commandInterest1,
   		     bind(&CommandInterestFixture::validated, this, _1),
-  		     bind(&CommandInterestFixture::validationFailed, this, _1));
+  		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
   
   BOOST_CHECK_EQUAL(m_validity, true);
   
@@ -99,7 +101,7 @@
   keyChain.signByIdentity(*commandInterest2, identity);
   validator.validate(*commandInterest2,
   		     bind(&CommandInterestFixture::validated, this, _1),
-  		     bind(&CommandInterestFixture::validationFailed, this, _1));
+  		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
   
   BOOST_CHECK_EQUAL(m_validity, false);
   
@@ -112,7 +114,7 @@
   generator.generateWithIdentity(*commandInterest3, identity2);
   validator.validate(*commandInterest3,
   		     bind(&CommandInterestFixture::validated, this, _1),
-  		     bind(&CommandInterestFixture::validationFailed, this, _1));
+  		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
   
   BOOST_CHECK_EQUAL(m_validity, false);
 
@@ -121,7 +123,7 @@
   generator.generateWithIdentity(*commandInterest4, identity);
   validator.validate(*commandInterest4,
   		     bind(&CommandInterestFixture::validated, this, _1),
-  		     bind(&CommandInterestFixture::validationFailed, this, _1));
+  		     bind(&CommandInterestFixture::validationFailed, this, _1, _2));
   
   BOOST_CHECK_EQUAL(m_validity, false);
 
diff --git a/tests/security/test-validator.cpp b/tests/security/test-validator.cpp
index 5c4fba0..bf55bda 100644
--- a/tests/security/test-validator.cpp
+++ b/tests/security/test-validator.cpp
@@ -22,8 +22,10 @@
 { BOOST_CHECK(true); }
 
 void
-onValidationFailed(const shared_ptr<const Data>& data)
-{ BOOST_CHECK(false); }
+onValidationFailed(const shared_ptr<const Data>& data, const string& failureInfo)
+{ 
+  BOOST_CHECK(false); 
+}
 
 BOOST_AUTO_TEST_CASE (Null)
 {
@@ -43,7 +45,7 @@
   // data must be a shared pointer
   validator.validate(*data,
 		     bind(&onValidated, _1),
-		     bind(&onValidationFailed, _1));
+		     bind(&onValidationFailed, _1, _2));
 
   keyChain.deleteIdentity(identity);
 }