blob: 3c8764e2ef531174a430d0bc306deeb5e69357fc [file] [log] [blame]
Alexander Afanasyev9cbf70a2014-02-17 18:07:51 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * See COPYING for copyright and distribution information.
5 */
6
7#ifndef NDN_HELPERS_COMMAND_INTEREST_VALIDATOR_HPP
8#define NDN_HELPERS_COMMAND_INTEREST_VALIDATOR_HPP
9
10#include "../security/validator.hpp"
11#include "../security/identity-certificate.hpp"
12#include "../security/sec-rule-specific.hpp"
13
14namespace ndn {
15
16class CommandInterestValidator : public Validator
17{
18public:
19 enum {
20 POS_SIG_VALUE = -1,
21 POS_SIG_INFO = -2,
22 POS_RANDOM_VAL = -3,
23 POS_TIMESTAMP = -4,
24
25 GRACE_INTERVAL = 3000 // ms
26 };
27
28 CommandInterestValidator(int64_t graceInterval = GRACE_INTERVAL/*ms*/)
29 {
30 m_graceInterval = (graceInterval < 0 ? GRACE_INTERVAL : graceInterval);
31 }
32
33 virtual
34 ~CommandInterestValidator()
35 {
36 }
37
38 void
39 addInterestRule(const std::string& regex, const IdentityCertificate& certificate);
40
41 void
42 addInterestRule(const std::string& regex, const Name& keyName, const PublicKey& publicKey);
43
44protected:
45 virtual void
46 checkPolicy (const Data& data,
47 int stepCount,
48 const OnDataValidated &onValidated,
49 const OnDataValidationFailed &onValidationFailed,
50 std::vector<shared_ptr<ValidationRequest> > &nextSteps)
51 {
52 onValidationFailed(data.shared_from_this());
53 }
54
55 virtual void
56 checkPolicy (const Interest& interest,
57 int stepCount,
58 const OnInterestValidated &onValidated,
59 const OnInterestValidationFailed &onValidationFailed,
60 std::vector<shared_ptr<ValidationRequest> > &nextSteps);
61private:
62 int64_t m_graceInterval; //ms
63 std::map<Name, PublicKey> m_trustAnchorsForInterest;
64 std::list<SecRuleSpecific> m_trustScopeForInterest;
65 std::map<Name, uint64_t> m_lastTimestamp;
66};
67
68inline void
69CommandInterestValidator::addInterestRule(const std::string& regex, const IdentityCertificate& certificate)
70{
71 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
72 addInterestRule(regex, keyName, certificate.getPublicKeyInfo());
73}
74
75inline void
76CommandInterestValidator::addInterestRule(const std::string& regex, const Name& keyName, const PublicKey& publicKey)
77{
78 m_trustAnchorsForInterest[keyName] = publicKey;
79 shared_ptr<Regex> interestRegex = make_shared<Regex>(regex);
80 shared_ptr<Regex> signerRegex = Regex::fromName(keyName, true);
81 m_trustScopeForInterest.push_back(SecRuleSpecific(interestRegex, signerRegex));
82}
83
84inline void
85CommandInterestValidator::checkPolicy (const Interest& interest,
86 int stepCount,
87 const OnInterestValidated &onValidated,
88 const OnInterestValidationFailed &onValidationFailed,
89 std::vector<shared_ptr<ValidationRequest> > &nextSteps)
90{
91 try
92 {
93 const Name& interestName = interest.getName();
94
95 if (interestName.size() < 4)
96 return onValidationFailed(interest.shared_from_this());
97
98 Signature signature(interestName[POS_SIG_INFO].blockFromValue(),
99 interestName[POS_SIG_VALUE].blockFromValue());
100
101 SignatureSha256WithRsa sig(signature);
102 const Name& keyLocatorName = sig.getKeyLocator().getName();
103 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
104
105 //Check if command is in the trusted scope
106 bool inScope = false;
107 for(std::list<SecRuleSpecific>::iterator scopeIt = m_trustScopeForInterest.begin();
108 scopeIt != m_trustScopeForInterest.end();
109 ++scopeIt)
110 {
111 if(scopeIt->satisfy(interestName, keyName))
112 {
113 inScope = true;
114 break;
115 }
116 }
117 if(inScope == false)
118 {
119 onValidationFailed(interest.shared_from_this());
120 return;
121 }
122
123 //Check if timestamp is valid
124 uint64_t timestamp = interestName.get(POS_TIMESTAMP).toNumber();
125 uint64_t current = static_cast<uint64_t>(time::now()/1000000);
126 std::map<Name, uint64_t>::const_iterator timestampIt = m_lastTimestamp.find(keyName);
127 if(timestampIt == m_lastTimestamp.end())
128 {
129 if(timestamp > (current + m_graceInterval) || (timestamp + m_graceInterval) < current)
130 {
131 onValidationFailed(interest.shared_from_this());
132 return;
133 }
134 }
135 else if(m_lastTimestamp[keyName] >= timestamp)
136 {
137 onValidationFailed(interest.shared_from_this());
138 return;
139 }
140
141 if(!Validator::verifySignature(interestName.wireEncode().value(),
142 interestName.wireEncode().value_size() - interestName[-1].size(),
143 sig, m_trustAnchorsForInterest[keyName]))
144 {
145 onValidationFailed(interest.shared_from_this());
146 return;
147 }
148
149 m_lastTimestamp[keyName] = timestamp;
150 onValidated(interest.shared_from_this());
151 return;
152
153 }
154 catch(...)
155 {
156 onValidationFailed(interest.shared_from_this());
157 }
158}
159
160
161} // namespace ndn
162
163#endif // NDN_HELPERS_COMMAND_INTEREST_VALIDATOR_HPP