blob: 86726d3f2dda47501898ac10372abad000da0706 [file] [log] [blame]
Yingdi Yu43e71612013-10-30 22:19:31 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/*
3 * Copyright (c) 2013, Regents of the University of California
4 * Yingdi Yu
5 *
6 * BSD license, See the LICENSE file for more information
7 *
8 * Author: Yingdi Yu <yingdi@cs.ucla.edu>
9 */
10
11#include "sync-policy-manager.h"
12
13#include "sync-intro-certificate.h"
14#include "sync-logging.h"
15
16using namespace ndn;
17using namespace ndn::security;
18using namespace std;
19
20INIT_LOGGER("SyncPolicyManager");
21
22SyncPolicyManager::SyncPolicyManager(const Name& signingIdentity,
23 const Name& signingCertificateName,
24 const Name& syncPrefix,
25 int stepLimit)
26 : m_signingIdentity(signingIdentity)
27 , m_signingCertificateName(signingCertificateName.getPrefix(signingCertificateName.size()-1))
28 , m_syncPrefix(syncPrefix)
29 , m_stepLimit(stepLimit)
30{
31 Name wotPrefix = syncPrefix;
32 wotPrefix.append("WOT");
33 m_syncPrefixRegex = Regex::fromName(syncPrefix);
34 m_wotPrefixRegex = Regex::fromName(wotPrefix);
35 m_chatDataPolicy = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^[^<FH>]*<FH>([^<chronos>]*)<chronos><>",
36 "^(<>*)<KEY><DSK-.*><ID-CERT><>$",
37 "==", "\\1", "\\1", true));
38}
39
40SyncPolicyManager::~SyncPolicyManager()
41{}
42
43bool
44SyncPolicyManager::skipVerifyAndTrust (const Data& data)
45{ return false; }
46
47bool
48SyncPolicyManager::requireVerify (const Data& data)
49{ return true; }
50
51Ptr<ValidationRequest>
52SyncPolicyManager::checkVerificationPolicy(Ptr<Data> data,
53 const int& stepCount,
54 const DataCallback& verifiedCallback,
55 const UnverifiedCallback& unverifiedCallback)
56{
57#ifdef _DEBUG
58 _LOG_DEBUG("checkVerificationPolicy");
59 verifiedCallback(data);
60 return NULL;
61#else
62 //TODO:
63 if(stepCount > m_stepLimit)
64 {
65 unverifiedCallback(data);
66 return NULL;
67 }
68
69 Ptr<const signature::Sha256WithRsa> sha256sig = DynamicCast<const signature::Sha256WithRsa> (data->getSignature());
70 if(KeyLocator::KEYNAME != sha256sig->getKeyLocator().getType())
71 {
72 unverifiedCallback(data);
73 return NULL;
74 }
75
76 const Name& keyLocatorName = sha256sig->getKeyLocator().getKeyName();
77
78 // if data is intro cert
79 if(m_wotPrefixRegex->match(data->getName()))
80 {
81 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
82 map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
83 if(m_trustedIntroducers.end() != it)
84 {
85 if(verifySignature(*data, it->second))
86 verifiedCallback(data);
87 else
88 unverifiedCallback(data);
89 return NULL;
90 }
91 else
92 return prepareRequest(keyName, true, data, stepCount, verifiedCallback, unverifiedCallback);
93 }
94
95 // if data is sync data or chat data
96 if(m_syncPrefixRegex->match(data->getName()) || m_chatDataPolicy->satisfy(*data))
97 {
98 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
99
100 map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
101 if(m_trustedIntroducers.end() != it)
102 {
103 if(verifySignature(*data, it->second))
104 verifiedCallback(data);
105 else
106 unverifiedCallback(data);
107 return NULL;
108 }
109
110 it = m_trustedProducers.find(keyName);
111 if(m_trustedProducers.end() != it)
112 {
113 if(verifySignature(*data, it->second))
114 verifiedCallback(data);
115 else
116 unverifiedCallback(data);
117 return NULL;
118 }
119
120 return prepareRequest(keyName, false, data, stepCount, verifiedCallback, unverifiedCallback);
121 }
122
123 unverifiedCallback(data);
124 return NULL;
125#endif
126}
127
128bool
129SyncPolicyManager::checkSigningPolicy(const Name& dataName,
130 const Name& certificateName)
131{
132
133#ifdef _DEBUG
134 _LOG_DEBUG("checkSigningPolicy");
135 return true;
136#else
137 return (m_syncPrefixRegex->match(dataName) && certificateName == m_signingCertificateName) ? true : false;
138#endif
139}
140
141Name
142SyncPolicyManager::inferSigningIdentity(const ndn::Name& dataName)
143{ return m_signingIdentity; }
144
145void
146SyncPolicyManager::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
147{
148 if(isIntroducer)
149 m_trustedIntroducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
150 else
151 m_trustedProducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
152}
153
154void
155SyncPolicyManager::addChatDataRule(const Name& prefix,
156 const IdentityCertificate& identityCertificate,
157 bool isIntroducer)
158{
159 // Name dataPrefix = prefix;
160 // dataPrefix.append("chronos").append(m_syncPrefix.get(-1));
161 // Ptr<Regex> dataRegex = Regex::fromName(prefix);
162 // Name certName = identityCertificate.getName();
163 // Name signerName = certName.getPrefix(certName.size()-1);
164 // Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
165
166 // SpecificPolicyRule rule(dataRegex, signerRegex);
167 // map<Name, SpecificPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
168 // if(it != m_chatDataRules.end())
169 // it->second = rule;
170 // else
171 // m_chatDataRules.insert(pair <Name, SpecificPolicyRule > (dataPrefix, rule));
172
173 addTrustAnchor(identityCertificate, isIntroducer);
174}
175
176
177Ptr<const vector<Name> >
178SyncPolicyManager::getAllIntroducerName()
179{
180 Ptr<vector<Name> > nameList = Ptr<vector<Name> >(new vector<Name>);
181
182 map<Name, Publickey>::iterator it = m_trustedIntroducers.begin();
183 for(; it != m_trustedIntroducers.end(); it++)
184 nameList->push_back(it->first);
185
186 return nameList;
187}
188
189Ptr<ValidationRequest>
190SyncPolicyManager::prepareRequest(const Name& keyName,
191 bool forIntroducer,
192 Ptr<Data> data,
193 const int & stepCount,
194 const DataCallback& verifiedCallback,
195 const UnverifiedCallback& unverifiedCallback)
196{
197 Ptr<Name> interestPrefixName = Ptr<Name>(new Name(m_syncPrefix));
198 interestPrefixName->append("WOT").append(keyName).append("INTRO-CERT");
199
200 Ptr<const std::vector<ndn::Name> > nameList = getAllIntroducerName();
201
202 Name interestName = *interestPrefixName;
203 interestName.append(nameList->at(0));
204
205 if(forIntroducer)
206 interestName.append("INTRODUCER");
207
208 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
209 interest->setChildSelector(Interest::CHILD_RIGHT);
210
211 DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified,
212 this,
213 _1,
214 forIntroducer,
215 data,
216 verifiedCallback,
217 unverifiedCallback);
218
219 UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified,
220 this,
221 _1,
222 interestPrefixName,
223 forIntroducer,
224 nameList,
225 1,
226 data,
227 verifiedCallback,
228 unverifiedCallback);
229
230
231 Ptr<ValidationRequest> nextStep = Ptr<ValidationRequest>(new ValidationRequest(interest,
232 requestedCertVerifiedCallback,
233 requestedCertUnverifiedCallback,
234 1,
235 m_stepLimit-1)
236 );
237 return nextStep;
238}
239
240void
241SyncPolicyManager::onIntroCertVerified(Ptr<Data> introCertificateData,
242 bool forIntroducer,
243 Ptr<Data> originalData,
244 const DataCallback& verifiedCallback,
245 const UnverifiedCallback& unverifiedCallback)
246{
247 Ptr<SyncIntroCertificate> introCertificate = Ptr<SyncIntroCertificate>(new SyncIntroCertificate(*introCertificateData));
248 if(forIntroducer)
249 m_trustedIntroducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
250 else
251 m_trustedProducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
252
253 if(verifySignature(*originalData, introCertificate->getPublicKeyInfo()))
254 verifiedCallback(originalData);
255 else
256 unverifiedCallback(originalData);
257}
258
259void
260SyncPolicyManager::onIntroCertUnverified(Ptr<Data> introCertificateData,
261 Ptr<Name> interestPrefixName,
262 bool forIntroducer,
263 Ptr<const std::vector<ndn::Name> > introNameList,
264 const int& nextIntroducerIndex,
265 Ptr<Data> originalData,
266 const DataCallback& verifiedCallback,
267 const UnverifiedCallback& unverifiedCallback)
268{
269 Name interestName = *interestPrefixName;
270 if(nextIntroducerIndex < introNameList->size())
271 interestName.append(introNameList->at(nextIntroducerIndex));
272 else
273 unverifiedCallback(originalData);
274
275 if(forIntroducer)
276 interestName.append("INTRODUCER");
277
278 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
279 interest->setChildSelector(Interest::CHILD_RIGHT);
280
281 DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified,
282 this,
283 _1,
284 forIntroducer,
285 originalData,
286 verifiedCallback,
287 unverifiedCallback);
288
289 UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified,
290 this,
291 _1,
292 interestPrefixName,
293 forIntroducer,
294 introNameList,
295 nextIntroducerIndex + 1,
296 originalData,
297 verifiedCallback,
298 unverifiedCallback);
299
300 TimeoutCallback requestedCertTimeoutCallback = boost::bind(&SyncPolicyManager::onIntroCertTimeOut,
301 this,
302 _1,
303 _2,
304 1,
305 requestedCertUnverifiedCallback,
306 originalData);
307
308 Ptr<Closure> closure = Ptr<Closure> (new Closure(requestedCertVerifiedCallback,
309 requestedCertTimeoutCallback,
310 requestedCertUnverifiedCallback,
311 m_stepLimit-1)
312 );
313
314 m_handler->sendInterest(interest, closure);
315}
316
317void
318SyncPolicyManager::onIntroCertTimeOut(Ptr<Closure> closure,
319 Ptr<Interest> interest,
320 int retry,
321 const UnverifiedCallback& unverifiedCallback,
322 Ptr<Data> data)
323{
324 if(retry > 0)
325 {
326 Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
327 boost::bind(&SyncPolicyManager::onIntroCertTimeOut,
328 this,
329 _1,
330 _2,
331 retry - 1,
332 unverifiedCallback,
333 data),
334 closure->m_unverifiedCallback,
335 closure->m_stepCount)
336 );
337 m_handler->sendInterest(interest, newClosure);
338 }
339 else
340 unverifiedCallback(data);
341}