NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.0: NDN, CCN, CCNx, content centric networks
API Documentation
command-interest-validator.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
22 #ifndef NDN_UTIL_COMMAND_INTEREST_VALIDATOR_HPP
23 #define NDN_UTIL_COMMAND_INTEREST_VALIDATOR_HPP
24 
25 #include "../security/validator.hpp"
26 #include "../security/identity-certificate.hpp"
27 #include "../security/sec-rule-specific.hpp"
28 
29 #include <list>
30 
31 namespace ndn {
32 
43 {
44 public:
45  enum {
50 
52 
53  GRACE_INTERVAL = 3000 // ms
54  };
55 
56  CommandInterestValidator(const time::milliseconds& graceInterval =
57  time::milliseconds(static_cast<int>(GRACE_INTERVAL)))
58  : m_graceInterval(graceInterval < time::milliseconds::zero() ?
59  time::milliseconds(static_cast<int>(GRACE_INTERVAL)) : graceInterval)
60  {
61  }
62 
63  virtual
65  {
66  }
67 
74  void
75  addInterestRule(const std::string& regex, const IdentityCertificate& certificate);
76 
84  void
85  addInterestRule(const std::string& regex, const Name& keyName, const PublicKey& publicKey);
86 
93  void
94  addInterestBypassRule(const std::string& regex);
95 
99  void
100  reset();
101 
102 protected:
103  virtual void
104  checkPolicy(const Data& data,
105  int stepCount,
106  const OnDataValidated& onValidated,
107  const OnDataValidationFailed& onValidationFailed,
108  std::vector<shared_ptr<ValidationRequest> >& nextSteps)
109  {
110  onValidationFailed(data.shared_from_this(), "No policy for data checking");
111  }
112 
113  virtual void
114  checkPolicy(const Interest& interest,
115  int stepCount,
116  const OnInterestValidated& onValidated,
117  const OnInterestValidationFailed& onValidationFailed,
118  std::vector<shared_ptr<ValidationRequest> >& nextSteps);
119 private:
120  time::milliseconds m_graceInterval; //ms
121  std::map<Name, PublicKey> m_trustAnchorsForInterest;
122  std::list<SecRuleSpecific> m_trustScopeForInterest;
123 
124  typedef std::map<Name, time::system_clock::TimePoint> LastTimestampMap;
125  LastTimestampMap m_lastTimestamp;
126 };
127 
128 inline void
130  const IdentityCertificate& certificate)
131 {
133  addInterestRule(regex, keyName, certificate.getPublicKeyInfo());
134 }
135 
136 inline void
138  const Name& keyName,
139  const PublicKey& publicKey)
140 {
141  m_trustAnchorsForInterest[keyName] = publicKey;
142  shared_ptr<Regex> interestRegex = make_shared<Regex>(regex);
143  shared_ptr<Regex> signerRegex = Regex::fromName(keyName, true);
144  m_trustScopeForInterest.push_back(SecRuleSpecific(interestRegex, signerRegex));
145 }
146 
147 inline void
149 {
150  shared_ptr<Regex> interestRegex = make_shared<Regex>(regex);
151  m_trustScopeForInterest.push_back(SecRuleSpecific(interestRegex));
152 }
153 
154 inline void
156 {
157  m_trustAnchorsForInterest.clear();
158  m_trustScopeForInterest.clear();
159 }
160 
161 inline void
163  int stepCount,
164  const OnInterestValidated& onValidated,
165  const OnInterestValidationFailed& onValidationFailed,
166  std::vector<shared_ptr<ValidationRequest> >& nextSteps)
167 {
168  const Name& interestName = interest.getName();
169 
170  //Prepare
171  if (interestName.size() < MIN_LENGTH)
172  return onValidationFailed(interest.shared_from_this(),
173  "Interest is not signed: " + interest.getName().toUri());
174  Name keyName;
175  try
176  {
177  Signature signature(interestName[POS_SIG_INFO].blockFromValue(),
178  interestName[POS_SIG_VALUE].blockFromValue());
179 
180  if (signature.getType() != tlv::SignatureSha256WithRsa)
181  return onValidationFailed(interest.shared_from_this(),
182  "Require SignatureSha256WithRsa");
183 
184  SignatureSha256WithRsa sig(signature);
185 
186  const KeyLocator& keyLocator = sig.getKeyLocator();
187 
188  if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
189  return onValidationFailed(interest.shared_from_this(),
190  "Key Locator is not a name");
191 
193 
194  //Check if command is in the trusted scope
195  bool isInScope = false;
196  for (std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
197  scopeIt != m_trustScopeForInterest.end();
198  ++scopeIt)
199  {
200  if (scopeIt->satisfy(interestName, keyName))
201  {
202  if (scopeIt->isExempted())
203  {
204  return onValidated(interest.shared_from_this());
205  }
206 
207  isInScope = true;
208  break;
209  }
210  }
211  if (isInScope == false)
212  return onValidationFailed(interest.shared_from_this(),
213  "Signer cannot be authorized for the command: " +
214  keyName.toUri());
215 
216  //Check signature
217  if (!Validator::verifySignature(interestName.wireEncode().value(),
218  interestName.wireEncode().value_size() -
219  interestName[-1].size(),
220  sig, m_trustAnchorsForInterest[keyName]))
221  return onValidationFailed(interest.shared_from_this(),
222  "Signature cannot be validated: " +
223  interest.getName().toUri());
224 
225  //Check if timestamp is valid
226  time::system_clock::TimePoint interestTime =
227  time::fromUnixTimestamp(time::milliseconds(interestName.get(POS_TIMESTAMP).toNumber()));
228 
230 
231  LastTimestampMap::iterator timestampIt = m_lastTimestamp.find(keyName);
232  if (timestampIt == m_lastTimestamp.end())
233  {
234  if (!(currentTime - m_graceInterval <= interestTime &&
235  interestTime <= currentTime + m_graceInterval))
236  return onValidationFailed(interest.shared_from_this(),
237  "The command is not in grace interval: " +
238  interest.getName().toUri());
239  }
240  else
241  {
242  if (interestTime <= timestampIt->second)
243  return onValidationFailed(interest.shared_from_this(),
244  "The command is outdated: " +
245  interest.getName().toUri());
246  }
247 
248  //Update timestamp
249  if (timestampIt == m_lastTimestamp.end())
250  {
251  m_lastTimestamp[keyName] = interestTime;
252  }
253  else
254  {
255  timestampIt->second = interestTime;
256  }
257  }
258  catch (Signature::Error& e)
259  {
260  return onValidationFailed(interest.shared_from_this(),
261  "No valid signature");
262  }
263  catch (IdentityCertificate::Error& e)
264  {
265  return onValidationFailed(interest.shared_from_this(),
266  "Cannot locate the signing key");
267  }
268  catch (tlv::Error& e)
269  {
270  return onValidationFailed(interest.shared_from_this(),
271  "Cannot decode signature related TLVs");
272  }
273 
274  return onValidated(interest.shared_from_this());
275 }
276 
277 } // namespace ndn
278 
279 #endif // NDN_UTIL_COMMAND_INTEREST_VALIDATOR_HPP
Represent a SHA256-with-RSA signature.
const Name & getName() const
Definition: interest.hpp:216
Copyright (c) 2011-2015 Regents of the University of California.
Helper class to validate CommandInterests.
static shared_ptr< RegexTopMatcher > fromName(const Name &name, bool hasAnchor=false)
void addInterestRule(const std::string &regex, const IdentityCertificate &certificate)
add an Interest rule that allows a specific certificate
static Name certificateNameToPublicKeyName(const Name &certificateName)
Get the public key name from the full certificate name.
const KeyLocator & getKeyLocator() const
Get KeyLocator.
Definition: signature.hpp:134
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Definition: name.cpp:69
represents an Interest packet
Definition: interest.hpp:45
indicates KeyLocator contains a Name
Definition: key-locator.hpp:49
static time_point now() noexcept
Definition: time.cpp:45
PublicKey & getPublicKeyInfo()
const Name & getName() const
Get name of the Data packet.
Definition: data.hpp:343
Table::const_iterator iterator
Definition: cs-internal.hpp:41
uint32_t getType() const
Get signature type.
Definition: signature.hpp:114
void addInterestBypassRule(const std::string &regex)
add an Interest rule that allows any signer
std::string toUri() const
Encode this name as a URI.
Definition: name.cpp:183
const Name & getName() const
get Name element
function< void(const shared_ptr< const Data > &)> OnDataValidated
Callback to report a successful Data validation.
Type getType() 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:408
void reset()
Remove all installed Interest rules (e.g., when reinitialization needed)
Name abstraction to represent an absolute name.
Definition: name.hpp:46
time_point TimePoint
Definition: time.hpp:78
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.cpp:124
static bool verifySignature(const Data &data, const PublicKey &publicKey)
Verify the data using the publicKey.
Definition: validator.cpp:106
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.
represents a Data packet
Definition: data.hpp:39
uint64_t toNumber() const
Interpret this name component as nonNegativeInteger.
Validator is one of the main classes of the security library.
Definition: validator.hpp:46
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:419
represents an error in TLV encoding or decoding
Definition: tlv.hpp:50
A Signature is storage for the signature-related information (info and value) in a Data packet...
Definition: signature.hpp:33