security: provide getKeyLocatorName helper function

refs #3920

Change-Id: Iba8fa7776ca63445608f4eb6fa2e4c54307cc99f
diff --git a/src/security/v2/validation-policy.cpp b/src/security/v2/validation-policy.cpp
index 6783f80..25fb1d2 100644
--- a/src/security/v2/validation-policy.cpp
+++ b/src/security/v2/validation-policy.cpp
@@ -59,6 +59,52 @@
   }
 }
 
+static Name
+getKeyLocatorName(const SignatureInfo& si, ValidationState& state)
+{
+  if (!si.hasKeyLocator()) {
+    state.fail({ValidationError::Code::INVALID_KEY_LOCATOR, "KeyLocator is missing"});
+    return Name();
+  }
+
+  const KeyLocator& kl = si.getKeyLocator();
+  if (kl.getType() != KeyLocator::KeyLocator_Name) {
+    state.fail({ValidationError::Code::INVALID_KEY_LOCATOR, "KeyLocator type is not Name"});
+    return Name();
+  }
+
+  return kl.getName();
+}
+
+Name
+getKeyLocatorName(const Data& data, ValidationState& state)
+{
+  return getKeyLocatorName(data.getSignature().getSignatureInfo(), state);
+}
+
+Name
+getKeyLocatorName(const Interest& interest, ValidationState& state)
+{
+  const Name& name = interest.getName();
+  if (name.size() < signed_interest::MIN_SIZE) {
+    state.fail({ValidationError::INVALID_KEY_LOCATOR,
+                "Invalid signed Interest: name too short"});
+    return Name();
+  }
+
+  SignatureInfo si;
+  try {
+    si.wireDecode(name.at(signed_interest::POS_SIG_INFO).blockFromValue());
+  }
+  catch (const tlv::Error& e) {
+    state.fail({ValidationError::Code::INVALID_KEY_LOCATOR,
+                "Invalid signed Interest: " + std::string(e.what())});
+    return Name();
+  }
+
+  return getKeyLocatorName(si, state);
+}
+
 } // namespace v2
 } // namespace security
 } // namespace ndn