All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
command-interest-validator.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
7 #ifndef NDN_UTIL_COMMAND_INTEREST_VALIDATOR_HPP
8 #define NDN_UTIL_COMMAND_INTEREST_VALIDATOR_HPP
9 
10 #include "../security/validator.hpp"
11 #include "../security/identity-certificate.hpp"
12 #include "../security/sec-rule-specific.hpp"
13 
14 namespace ndn {
15 
17 {
18 public:
19  enum {
24 
26 
27  GRACE_INTERVAL = 3000 // ms
28  };
29 
30  CommandInterestValidator(const time::milliseconds& graceInterval =
31  time::milliseconds(static_cast<int>(GRACE_INTERVAL)))
32  : m_graceInterval(graceInterval < time::milliseconds::zero() ?
33  time::milliseconds(static_cast<int>(GRACE_INTERVAL)) : graceInterval)
34  {
35  }
36 
37  virtual
39  {
40  }
41 
42  void
43  addInterestRule(const std::string& regex, const IdentityCertificate& certificate);
44 
45  void
46  addInterestRule(const std::string& regex, const Name& keyName, const PublicKey& publicKey);
47 
48 protected:
49  virtual void
50  checkPolicy(const Data& data,
51  int stepCount,
52  const OnDataValidated& onValidated,
53  const OnDataValidationFailed& onValidationFailed,
54  std::vector<shared_ptr<ValidationRequest> >& nextSteps)
55  {
56  onValidationFailed(data.shared_from_this(), "No policy for data checking");
57  }
58 
59  virtual void
60  checkPolicy(const Interest& interest,
61  int stepCount,
62  const OnInterestValidated& onValidated,
63  const OnInterestValidationFailed& onValidationFailed,
64  std::vector<shared_ptr<ValidationRequest> >& nextSteps);
65 private:
66  time::milliseconds m_graceInterval; //ms
67  std::map<Name, PublicKey> m_trustAnchorsForInterest;
68  std::list<SecRuleSpecific> m_trustScopeForInterest;
69 
70  typedef std::map<Name, time::system_clock::TimePoint> LastTimestampMap;
71  LastTimestampMap m_lastTimestamp;
72 };
73 
74 inline void
76  const IdentityCertificate& certificate)
77 {
79  addInterestRule(regex, keyName, certificate.getPublicKeyInfo());
80 }
81 
82 inline void
84  const Name& keyName,
85  const PublicKey& publicKey)
86 {
87  m_trustAnchorsForInterest[keyName] = publicKey;
88  shared_ptr<Regex> interestRegex = make_shared<Regex>(regex);
89  shared_ptr<Regex> signerRegex = Regex::fromName(keyName, true);
90  m_trustScopeForInterest.push_back(SecRuleSpecific(interestRegex, signerRegex));
91 }
92 
93 inline void
95  int stepCount,
96  const OnInterestValidated& onValidated,
97  const OnInterestValidationFailed& onValidationFailed,
98  std::vector<shared_ptr<ValidationRequest> >& nextSteps)
99 {
100  const Name& interestName = interest.getName();
101 
102  //Prepare
103  if (interestName.size() < MIN_LENGTH)
104  return onValidationFailed(interest.shared_from_this(),
105  "Interest is not signed: " + interest.getName().toUri());
106  Name keyName;
107  try
108  {
109  Signature signature(interestName[POS_SIG_INFO].blockFromValue(),
110  interestName[POS_SIG_VALUE].blockFromValue());
111 
112  if (signature.getType() != Signature::Sha256WithRsa)
113  return onValidationFailed(interest.shared_from_this(),
114  "Require SignatureSha256WithRsa");
115 
116  SignatureSha256WithRsa sig(signature);
117 
118  const KeyLocator& keyLocator = sig.getKeyLocator();
119 
120  if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
121  return onValidationFailed(interest.shared_from_this(),
122  "Key Locator is not a name");
123 
125 
126  //Check if command is in the trusted scope
127  bool isInScope = false;
128  for (std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
129  scopeIt != m_trustScopeForInterest.end();
130  ++scopeIt)
131  {
132  if (scopeIt->satisfy(interestName, keyName))
133  {
134  isInScope = true;
135  break;
136  }
137  }
138  if (isInScope == false)
139  return onValidationFailed(interest.shared_from_this(),
140  "Signer cannot be authorized for the command: " +
141  keyName.toUri());
142 
143  //Check signature
144  if (!Validator::verifySignature(interestName.wireEncode().value(),
145  interestName.wireEncode().value_size() -
146  interestName[-1].size(),
147  sig, m_trustAnchorsForInterest[keyName]))
148  return onValidationFailed(interest.shared_from_this(),
149  "Signature cannot be validated: " +
150  interest.getName().toUri());
151 
152  //Check if timestamp is valid
153  time::system_clock::TimePoint interestTime =
154  time::fromUnixTimestamp(time::milliseconds(interestName.get(POS_TIMESTAMP).toNumber()));
155 
156  time::system_clock::TimePoint currentTime = time::system_clock::now();
157 
158  LastTimestampMap::iterator timestampIt = m_lastTimestamp.find(keyName);
159  if (timestampIt == m_lastTimestamp.end())
160  {
161  if (!(currentTime - m_graceInterval <= interestTime &&
162  interestTime <= currentTime + m_graceInterval))
163  return onValidationFailed(interest.shared_from_this(),
164  "The command is not in grace interval: " +
165  interest.getName().toUri());
166  }
167  else
168  {
169  if (interestTime <= timestampIt->second)
170  return onValidationFailed(interest.shared_from_this(),
171  "The command is outdated: " +
172  interest.getName().toUri());
173  }
174 
175  //Update timestamp
176  if (timestampIt == m_lastTimestamp.end())
177  {
178  m_lastTimestamp[keyName] = interestTime;
179  }
180  else
181  {
182  timestampIt->second = interestTime;
183  }
184  }
185  catch (Signature::Error& e)
186  {
187  return onValidationFailed(interest.shared_from_this(),
188  "No valid signature");
189  }
190  catch (IdentityCertificate::Error& e)
191  {
192  return onValidationFailed(interest.shared_from_this(),
193  "Cannot locate the signing key");
194  }
195  catch (Tlv::Error& e)
196  {
197  return onValidationFailed(interest.shared_from_this(),
198  "Cannot decode signature related TLVs");
199  }
200 
201  return onValidated(interest.shared_from_this());
202 }
203 
204 } // namespace ndn
205 
206 #endif // NDN_UTIL_COMMAND_INTEREST_VALIDATOR_HPP
Representing of SHA256-with-RSA signature in a data packet.
const Name & getName() const
Definition: interest.hpp:182
static shared_ptr< RegexTopMatcher > fromName(const Name &name, bool hasAnchor=false)
void addInterestRule(const std::string &regex, const IdentityCertificate &certificate)
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
An Interest holds a Name and other fields for an interest.
Definition: interest.hpp:24
PublicKey & getPublicKeyInfo()
const Name & getName() const
Definition: data.hpp:346
uint32_t getType() const
Definition: signature.hpp:50
std::string toUri() const
Encode this name as a URI.
Definition: name.hpp:536
const Name & getName() const
function< void(const shared_ptr< const Data > &)> OnDataValidated
Callback to report a successful Data validation.
const KeyLocator & getKeyLocator() const
function< void(const shared_ptr< const Data > &, const std::string &)> OnDataValidationFailed
Callback to report a failed Data validation.
size_t size() const
Get the number of components.
Definition: name.hpp:329
A Name holds an array of Name::Component and represents an NDN name.
Definition: name.hpp:26
size_t wireEncode(EncodingImpl< T > &block) const
Fast encoding or block size estimation.
Definition: name.hpp:711
time_point TimePoint
Definition: time.hpp:55
CommandInterestValidator(const time::milliseconds &graceInterval=time::milliseconds(static_cast< int >(GRACE_INTERVAL)))
function< void(const shared_ptr< const Interest > &, const std::string &)> OnInterestValidationFailed
Callback to report a failed Interest validation.
system_clock::TimePoint fromUnixTimestamp(const milliseconds &duration)
Convert UNIX timestamp to system_clock::TimePoint.
Definition: time.hpp:116
uint32_t getType() const
Definition: key-locator.hpp:76
static bool verifySignature(const Data &data, const PublicKey &publicKey)
Verify the data using the publicKey.
Definition: validator.cpp:128
virtual void checkPolicy(const Data &data, int stepCount, const OnDataValidated &onValidated, const OnDataValidationFailed &onValidationFailed, std::vector< shared_ptr< ValidationRequest > > &nextSteps)
Check the Data against policy and return the next validation step if necessary.
uint64_t toNumber() const
Interpret this name component as nonNegativeInteger.
Validator is one of the main classes of the security library.
Definition: validator.hpp:27
function< void(const shared_ptr< const Interest > &)> OnInterestValidated
Callback to report a successful Interest validation.
const Component & get(ssize_t i) const
Get the component at the given index.
Definition: name.hpp:340
A Signature is storage for the signature-related information (info and value) in a Data packet...
Definition: signature.hpp:15