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