blob: e040d809e21b4da9905cd07008cd0354b1cfd030 [file] [log] [blame]
Yingdi Yu48e8c0c2014-03-19 12:01:55 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
5 * See COPYING for copyright and distribution information.
6 */
7
8#ifndef NDN_SECURITY_CONF_KEY_LOCATOR_CHECKER_HPP
9#define NDN_SECURITY_CONF_KEY_LOCATOR_CHECKER_HPP
10
11#include "../../common.hpp"
12#include "../../data.hpp"
13#include "../../interest.hpp"
14#include <boost/algorithm/string.hpp>
15
16#include "common.hpp"
17
18namespace ndn {
19namespace security {
20namespace conf {
21
22class KeyLocatorCheckerFactory;
23
24class KeyLocatorChecker
25{
26public:
27 enum Relation
28 {
29 RELATION_EQUAL,
30 RELATION_IS_PREFIX_OF,
Alexander Afanasyevb78bc4d2014-04-09 21:20:52 -070031 RELATION_IS_STRICT_PREFIX_OF
Yingdi Yu48e8c0c2014-03-19 12:01:55 -070032 };
33
34 virtual
35 ~KeyLocatorChecker()
36 {
37 }
38
39 bool
40 check(const Data& data,
41 const KeyLocator& keyLocator,
42 std::string& failInfo)
43 {
44 return check(data.getName(), keyLocator, failInfo);
45 }
46
47 bool
48 check(const Interest& interest,
49 const KeyLocator& keyLocator,
50 std::string& failInfo)
51 {
52 if (interest.getName().size() < 2)
53 {
54 failInfo = "No Signature";
55 return false;
56 }
57
58 Name signedName = interest.getName().getPrefix(-2);
59 return check(signedName, keyLocator, failInfo);
60 }
61
62protected:
63
64 virtual bool
65 check(const Name& packetName,
66 const KeyLocator& keyLocator,
67 std::string& failInfo) = 0;
68
69 bool
70 checkRelation(const Relation& relation, const Name& name1, const Name& name2)
71 {
72 switch (relation)
73 {
74 case RELATION_EQUAL:
75 return (name1 == name2);
76 case RELATION_IS_PREFIX_OF:
77 return name1.isPrefixOf(name2);
78 case RELATION_IS_STRICT_PREFIX_OF:
79 return (name1.isPrefixOf(name2) && name1 != name2);
80 default:
81 return false;
82 }
83 }
84};
85
86class RelationKeyLocatorNameChecker : public KeyLocatorChecker
87{
88public:
89 RelationKeyLocatorNameChecker(const Name& name,
90 const KeyLocatorChecker::Relation& relation)
91 : m_name(name)
92 , m_relation(relation)
93 {
94 }
95
96protected:
97 virtual bool
98 check(const Name& packetName,
99 const KeyLocator& keyLocator,
100 std::string& failInfo)
101 {
102 try
103 {
104 if (checkRelation(m_relation, m_name, keyLocator.getName()))
105 return true;
106
107 failInfo = "KeyLocatorChecker failed!";
108 return false;
109 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700110 catch (KeyLocator::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700111 {
112 failInfo = "KeyLocator does not have name";
113 return false;
114 }
115 }
116
117private:
118 Name m_name;
119 KeyLocatorChecker::Relation m_relation;
120};
121
122class RegexKeyLocatorNameChecker : public KeyLocatorChecker
123{
124public:
125 RegexKeyLocatorNameChecker(const Regex& regex)
126 : m_regex(regex)
127 {
128 }
129
130protected:
131 virtual bool
132 check(const Name& packetName,
133 const KeyLocator& keyLocator,
134 std::string& failInfo)
135 {
136 try
137 {
138 if (m_regex.match(keyLocator.getName()))
139 return true;
140
141 failInfo = "KeyLocatorChecker failed!";
142 return false;
143 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700144 catch (KeyLocator::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700145 {
146 failInfo = "KeyLocator does not have name";
147 return false;
148 }
149 }
150
151private:
152 Regex m_regex;
153};
154
155class HyperKeyLocatorNameChecker : public KeyLocatorChecker
156{
157public:
158 HyperKeyLocatorNameChecker(const std::string& pExpr, const std::string pExpand,
159 const std::string& kExpr, const std::string kExpand,
160 const Relation& hyperRelation)
161 : m_hyperPRegex(new Regex(pExpr, pExpand))
162 , m_hyperKRegex(new Regex(kExpr, kExpand))
163 , m_hyperRelation(hyperRelation)
164 {
165 }
166
167protected:
168 virtual bool
169 check(const Name& packetName,
170 const KeyLocator& keyLocator,
171 std::string& failInfo)
172 {
173 try
174 {
175 if (m_hyperPRegex->match(packetName) &&
176 m_hyperKRegex->match(keyLocator.getName()) &&
177 checkRelation(m_hyperRelation,
178 m_hyperKRegex->expand(),
179 m_hyperPRegex->expand()))
180 return true;
181
182 failInfo = "KeyLocatorChecker failed!";
183 return false;
184 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700185 catch (KeyLocator::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700186 {
187 failInfo = "KeyLocator does not have name";
188 return false;
189 }
190
191 }
192
193private:
194 shared_ptr<Regex> m_hyperPRegex;
195 shared_ptr<Regex> m_hyperKRegex;
196 Relation m_hyperRelation;
197};
198
199
200class KeyLocatorCheckerFactory
201{
202public:
203 static shared_ptr<KeyLocatorChecker>
204 create(const ConfigSection& configSection, const std::string& filename)
205 {
206 ConfigSection::const_iterator propertyIt = configSection.begin();
207
208 // Get checker.key-locator.type
209 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "type"))
210 throw Error("Expect <checker.key-locator.type>!");
211
212 std::string type = propertyIt->second.data();
213
214 if (boost::iequals(type, "name"))
215 return createKeyLocatorNameChecker(configSection, filename);
216 else
217 throw Error("Unsupported checker.key-locator.type: " + type);
218 }
219
220private:
221 static shared_ptr<KeyLocatorChecker>
222 createKeyLocatorNameChecker(const ConfigSection& configSection,
223 const std::string& filename)
224 {
225 ConfigSection::const_iterator propertyIt = configSection.begin();
226 propertyIt++;
227
228 if (propertyIt == configSection.end())
229 throw Error("Expect more checker.key-locator properties");
230
231 if (boost::iequals(propertyIt->first, "name"))
232 {
233 Name name;
234 try
235 {
236 name = Name(propertyIt->second.data());
237 }
238 catch (Name::Error& e)
239 {
240 throw Error("Invalid checker.key-locator.name: "
241 + propertyIt->second.data());
242 }
243 propertyIt++;
244
245 if (propertyIt == configSection.end() || !boost::iequals(propertyIt->first, "relation"))
246 throw Error("Expect <checker.key-locator.relation>!");
247
248 std::string relationString = propertyIt->second.data();
249 propertyIt++;
250
251 KeyLocatorChecker::Relation relation;
252 if (boost::iequals(relationString, "equal"))
253 relation = KeyLocatorChecker::RELATION_EQUAL;
254 else if (boost::iequals(relationString, "is-prefix-of"))
255 relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
256 else if (boost::iequals(relationString, "is-strict-prefix-of"))
257 relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
258 else
259 throw Error("Unsupported relation: " + relationString);
260
261 if (propertyIt != configSection.end())
262 throw Error("Expect the end of checker.key-locator!");
263
264 return shared_ptr<RelationKeyLocatorNameChecker>
265 (new RelationKeyLocatorNameChecker(name, relation));
266 }
267 else if (boost::iequals(propertyIt->first, "regex"))
268 {
269 std::string regexString = propertyIt->second.data();
270 propertyIt++;
271
272 if (propertyIt != configSection.end())
273 throw Error("Expect the end of checker.key-locator!");
274
275 try
276 {
277 return shared_ptr<RegexKeyLocatorNameChecker>
278 (new RegexKeyLocatorNameChecker(regexString));
279 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700280 catch (Regex::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700281 {
282 throw Error("Invalid checker.key-locator.regex: " + regexString);
283 }
284 }
285 else if (boost::iequals(propertyIt->first, "hyper-relation"))
286 {
287 const ConfigSection& hSection = propertyIt->second;
288
289 ConfigSection::const_iterator hPropertyIt = hSection.begin();
290
291 // Get k-regex
292 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-regex"))
293 throw Error("Expect <checker.key-locator.hyper-relation.k-regex>!");
294
295 std::string kRegex = hPropertyIt->second.data();
296 hPropertyIt++;
297
298 // Get k-expand
299 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "k-expand"))
300 throw Error("Expect <checker.key-locator.hyper-relation.k-expand>!");
301
302 std::string kExpand = hPropertyIt->second.data();
303 hPropertyIt++;
304
305 // Get h-relation
306 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "h-relation"))
307 throw Error("Expect <checker.key-locator.hyper-relation.h-relation>!");
308
309 std::string hRelation = hPropertyIt->second.data();
310 hPropertyIt++;
311
312 // Get p-regex
313 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-regex"))
314 throw Error("Expect <checker.key-locator.hyper-relation.p-regex>!");
315
316 std::string pRegex = hPropertyIt->second.data();
317 hPropertyIt++;
318
319 // Get p-expand
320 if (hPropertyIt == hSection.end() || !boost::iequals(hPropertyIt->first, "p-expand"))
321 throw Error("Expect <checker.key-locator.hyper-relation.p-expand>!");
322
323 std::string pExpand = hPropertyIt->second.data();
324 hPropertyIt++;
325
326 if (hPropertyIt != hSection.end())
327 throw Error("Expect the end of checker.key-locator.hyper-relation!");
328
329 KeyLocatorChecker::Relation relation;
330 if (boost::iequals(hRelation, "equal"))
331 relation = KeyLocatorChecker::RELATION_EQUAL;
332 else if (boost::iequals(hRelation, "is-prefix-of"))
333 relation = KeyLocatorChecker::RELATION_IS_PREFIX_OF;
334 else if (boost::iequals(hRelation, "is-strict-prefix-of"))
335 relation = KeyLocatorChecker::RELATION_IS_STRICT_PREFIX_OF;
336 else
337 throw Error("Unsupported checker.key-locator.hyper-relation.h-relation: "
338 + hRelation);
339
340 try
341 {
342 return shared_ptr<HyperKeyLocatorNameChecker>
343 (new HyperKeyLocatorNameChecker(pRegex, pExpand,
344 kRegex, kExpand,
345 relation));
346 }
Alexander Afanasyev2a7f7202014-04-23 14:25:29 -0700347 catch (Regex::Error& e)
Yingdi Yu48e8c0c2014-03-19 12:01:55 -0700348 {
349 throw Error("Invalid regex for key-locator.hyper-relation");
350 }
351 }
352 else
353 throw Error("Unsupported checker.key-locator");
354 }
355};
356
357
358} // namespace conf
359} // namespace security
360} // namespace ndn
361
362#endif // NDN_SECURITY_CONF_KEY_LOCATOR_CHECKER_HPP