security: Fix bug of checking signed interest in ValidatorConfig

If signatureInfo or signatureValue is malformed, decoding process will throw
an excetpion. This commit enables ValidatorConfig to catch the exception and
invoke onValidationFailed.

Refs: #1493

Change-Id: Ic0f960bece458a7c993f380586fc4aed10640732
diff --git a/src/security/conf/checker.hpp b/src/security/conf/checker.hpp
index 3fa8d94..b1aaf7b 100644
--- a/src/security/conf/checker.hpp
+++ b/src/security/conf/checker.hpp
@@ -94,10 +94,23 @@
         const OnInterestChecked& onValidated,
         const OnInterestCheckFailed& onValidationFailed)
   {
-    const Name& interestName = interest.getName();
-    Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
-                        interestName[INTEREST_SIG_VALUE].blockFromValue());
-    return check(interest, signature, onValidated, onValidationFailed);
+    try
+      {
+        const Name& interestName = interest.getName();
+        Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
+                            interestName[INTEREST_SIG_VALUE].blockFromValue());
+        return check(interest, signature, onValidated, onValidationFailed);
+      }
+    catch (const Tlv::Error& e)
+      {
+        onValidationFailed(interest.shared_from_this(), "Cannot decode signature related TLVs");
+        return -1;
+      }
+    catch (const Signature::Error& e)
+      {
+        onValidationFailed(interest.shared_from_this(), "No valid signature");
+        return -1;
+      }
   }
 
 private:
@@ -201,10 +214,23 @@
         const OnInterestChecked& onValidated,
         const OnInterestCheckFailed& onValidationFailed)
   {
-    const Name& interestName = interest.getName();
-    Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
-                        interestName[INTEREST_SIG_VALUE].blockFromValue());
-    return check(interest, signature, onValidated, onValidationFailed);
+    try
+      {
+        const Name& interestName = interest.getName();
+        Signature signature(interestName[INTEREST_SIG_INFO].blockFromValue(),
+                            interestName[INTEREST_SIG_VALUE].blockFromValue());
+        return check(interest, signature, onValidated, onValidationFailed);
+      }
+    catch (const Tlv::Error& e)
+      {
+        onValidationFailed(interest.shared_from_this(), "Cannot decode signature related TLVs");
+        return -1;
+      }
+    catch (const Signature::Error& e)
+      {
+        onValidationFailed(interest.shared_from_this(), "No valid signature");
+        return -1;
+      }
   }
 
 private:
diff --git a/tests-integrated/security/test-validator-config.cpp b/tests-integrated/security/test-validator-config.cpp
index e8849a9..ecde534 100644
--- a/tests-integrated/security/test-validator-config.cpp
+++ b/tests-integrated/security/test-validator-config.cpp
@@ -667,10 +667,13 @@
   shared_ptr<Data> data2 = make_shared<Data>(dataName2);
   BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*data2, identity2));
 
+  Name interestName("/TestValidatorConfig/FixedSingerChecker/fakeSigInfo/fakeSigValue");
+  shared_ptr<Interest> interest = make_shared<Interest>(interestName);
+
   const std::string CONFIG =
     "rule\n"
     "{\n"
-    "  id \"Simple3 Rule\"\n"
+    "  id \"FixedSingerChecker Data Rule\"\n"
     "  for data\n"
     "  filter"
     "  {\n"
@@ -688,6 +691,27 @@
     "      file-name \"trust-anchor-7.cert\"\n"
     "    }\n"
     "  }\n"
+    "}\n"
+    "rule\n"
+    "{\n"
+    "  id \"FixedSingerChecker Interest Rule\"\n"
+    "  for interest\n"
+    "  filter"
+    "  {\n"
+    "    type name\n"
+    "    name /TestValidatorConfig/FixedSingerChecker\n"
+    "    relation is-strict-prefix-of\n"
+    "  }\n"
+    "  checker\n"
+    "  {\n"
+    "    type fixed-signer\n"
+    "    sig-type rsa-sha256\n"
+    "    signer\n"
+    "    {\n"
+    "      type file\n"
+    "      file-name \"trust-anchor-7.cert\"\n"
+    "    }\n"
+    "  }\n"
     "}\n";
   const boost::filesystem::path CONFIG_PATH =
     (boost::filesystem::current_path() / std::string("unit-test-nfd.conf"));
@@ -705,6 +729,10 @@
                      bind(&onIntentionalFailureValidated, _1),
                      bind(&onIntentionalFailureInvalidated, _1, _2));
 
+  validator.validate(*interest,
+                     bind(&onIntentionalFailureValidated2, _1),
+                     bind(&onIntentionalFailureInvalidated2, _1, _2));
+
 
   keyChain.deleteIdentity(identity1);
   keyChain.deleteIdentity(identity2);
@@ -776,6 +804,8 @@
   shared_ptr<Interest> interest3 = make_shared<Interest>(interestName3);
   BOOST_CHECK_NO_THROW(keyChain.signByIdentity(*interest3, root));
 
+  Name interestName4("/localhost/nrd/register/option/timestamp/nonce/fakeSigInfo/fakeSigValue");
+  shared_ptr<Interest> interest4 = make_shared<Interest>(interestName4);
 
   const std::string CONFIG =
     "rule\n"
@@ -825,17 +855,22 @@
   shared_ptr<ValidatorConfig> validator = shared_ptr<ValidatorConfig>(new ValidatorConfig(face2));
   validator->load(CONFIG, CONFIG_PATH.native());
 
+  // should succeed
   scheduler.scheduleEvent(time::milliseconds(200),
                           bind(&FacesFixture::validate3, this,
                                validator, interest1));
-
+  // should fail
   scheduler.scheduleEvent(time::milliseconds(400),
                           bind(&FacesFixture::validate4, this,
                                validator, interest2));
-
+  // should succeed
   scheduler.scheduleEvent(time::milliseconds(600),
                           bind(&FacesFixture::validate3, this,
                                validator, interest3));
+  // should fail
+  scheduler.scheduleEvent(time::milliseconds(600),
+                          bind(&FacesFixture::validate4, this,
+                               validator, interest4));
 
   BOOST_REQUIRE_NO_THROW(face->processEvents());