blob: 90c6828defb208bcdc66069f5ca2f48c1a6ea9b0 [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><>",
Yingdi Yu9529bc32013-11-01 16:19:25 -070036 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
Yingdi Yu43e71612013-10-30 22:19:31 -070037 "==", "\\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{
Yingdi Yu0b3bd482013-11-01 16:11:20 -070057// #ifdef _DEBUG
58// _LOG_DEBUG("checkVerificationPolicy");
59// verifiedCallback(data);
60// return NULL;
61// #else
Yingdi Yu43e71612013-10-30 22:19:31 -070062 //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();
Yingdi Yu0b3bd482013-11-01 16:11:20 -070077 _LOG_DEBUG("data name: " << data->getName());
78 _LOG_DEBUG("signer name: " << keyLocatorName);
Yingdi Yu43e71612013-10-30 22:19:31 -070079
80 // if data is intro cert
81 if(m_wotPrefixRegex->match(data->getName()))
82 {
Yingdi Yu0b3bd482013-11-01 16:11:20 -070083 _LOG_DEBUG("Intro Cert");
Yingdi Yu43e71612013-10-30 22:19:31 -070084 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
85 map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
86 if(m_trustedIntroducers.end() != it)
87 {
88 if(verifySignature(*data, it->second))
89 verifiedCallback(data);
90 else
91 unverifiedCallback(data);
92 return NULL;
93 }
94 else
95 return prepareRequest(keyName, true, data, stepCount, verifiedCallback, unverifiedCallback);
96 }
97
98 // if data is sync data or chat data
99 if(m_syncPrefixRegex->match(data->getName()) || m_chatDataPolicy->satisfy(*data))
100 {
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700101 _LOG_DEBUG("Sync/Chat Data");
Yingdi Yu43e71612013-10-30 22:19:31 -0700102 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700103 _LOG_DEBUG("keyName: " << keyName.toUri());
Yingdi Yu43e71612013-10-30 22:19:31 -0700104
105 map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
106 if(m_trustedIntroducers.end() != it)
107 {
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700108 _LOG_DEBUG("Find trusted introducer!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700109 if(verifySignature(*data, it->second))
110 verifiedCallback(data);
111 else
112 unverifiedCallback(data);
113 return NULL;
114 }
115
116 it = m_trustedProducers.find(keyName);
117 if(m_trustedProducers.end() != it)
118 {
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700119 _LOG_DEBUG("Find trusted producer!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700120 if(verifySignature(*data, it->second))
121 verifiedCallback(data);
122 else
123 unverifiedCallback(data);
124 return NULL;
125 }
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700126
127 _LOG_DEBUG("Did not find any trusted one!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700128 return prepareRequest(keyName, false, data, stepCount, verifiedCallback, unverifiedCallback);
129 }
130
131 unverifiedCallback(data);
132 return NULL;
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700133// #endif
Yingdi Yu43e71612013-10-30 22:19:31 -0700134}
135
136bool
137SyncPolicyManager::checkSigningPolicy(const Name& dataName,
138 const Name& certificateName)
139{
140
Yingdi Yu43e71612013-10-30 22:19:31 -0700141 return true;
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700142
143// #ifdef _DEBUG
144// _LOG_DEBUG("checkSigningPolicy");
145// return true;
146// #else
147 // return (m_syncPrefixRegex->match(dataName) && certificateName.getPrefix(certificateName.size()-1) == m_signingCertificateName) ? true : false;
148// #endif
Yingdi Yu43e71612013-10-30 22:19:31 -0700149}
150
151Name
152SyncPolicyManager::inferSigningIdentity(const ndn::Name& dataName)
153{ return m_signingIdentity; }
154
155void
156SyncPolicyManager::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
157{
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700158 _LOG_DEBUG("Add intro/producer: " << identityCertificate.getPublicKeyName());
Yingdi Yu43e71612013-10-30 22:19:31 -0700159 if(isIntroducer)
160 m_trustedIntroducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
161 else
162 m_trustedProducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
163}
164
165void
166SyncPolicyManager::addChatDataRule(const Name& prefix,
167 const IdentityCertificate& identityCertificate,
168 bool isIntroducer)
169{
170 // Name dataPrefix = prefix;
171 // dataPrefix.append("chronos").append(m_syncPrefix.get(-1));
172 // Ptr<Regex> dataRegex = Regex::fromName(prefix);
173 // Name certName = identityCertificate.getName();
174 // Name signerName = certName.getPrefix(certName.size()-1);
175 // Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
176
177 // SpecificPolicyRule rule(dataRegex, signerRegex);
178 // map<Name, SpecificPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
179 // if(it != m_chatDataRules.end())
180 // it->second = rule;
181 // else
182 // m_chatDataRules.insert(pair <Name, SpecificPolicyRule > (dataPrefix, rule));
183
184 addTrustAnchor(identityCertificate, isIntroducer);
185}
186
187
188Ptr<const vector<Name> >
189SyncPolicyManager::getAllIntroducerName()
190{
191 Ptr<vector<Name> > nameList = Ptr<vector<Name> >(new vector<Name>);
192
193 map<Name, Publickey>::iterator it = m_trustedIntroducers.begin();
194 for(; it != m_trustedIntroducers.end(); it++)
195 nameList->push_back(it->first);
196
197 return nameList;
198}
199
200Ptr<ValidationRequest>
201SyncPolicyManager::prepareRequest(const Name& keyName,
202 bool forIntroducer,
203 Ptr<Data> data,
204 const int & stepCount,
205 const DataCallback& verifiedCallback,
206 const UnverifiedCallback& unverifiedCallback)
207{
208 Ptr<Name> interestPrefixName = Ptr<Name>(new Name(m_syncPrefix));
209 interestPrefixName->append("WOT").append(keyName).append("INTRO-CERT");
210
211 Ptr<const std::vector<ndn::Name> > nameList = getAllIntroducerName();
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700212 if(0 == nameList->size())
213 {
214 unverifiedCallback(data);
215 return NULL;
216 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700217
218 Name interestName = *interestPrefixName;
219 interestName.append(nameList->at(0));
220
221 if(forIntroducer)
222 interestName.append("INTRODUCER");
223
224 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700225 _LOG_DEBUG("send interest for intro cert: " << interest->getName());
Yingdi Yu43e71612013-10-30 22:19:31 -0700226 interest->setChildSelector(Interest::CHILD_RIGHT);
227
228 DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified,
229 this,
230 _1,
231 forIntroducer,
232 data,
233 verifiedCallback,
234 unverifiedCallback);
235
236 UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified,
237 this,
238 _1,
239 interestPrefixName,
240 forIntroducer,
241 nameList,
242 1,
243 data,
244 verifiedCallback,
245 unverifiedCallback);
246
247
248 Ptr<ValidationRequest> nextStep = Ptr<ValidationRequest>(new ValidationRequest(interest,
249 requestedCertVerifiedCallback,
250 requestedCertUnverifiedCallback,
251 1,
252 m_stepLimit-1)
253 );
254 return nextStep;
255}
256
257void
258SyncPolicyManager::onIntroCertVerified(Ptr<Data> introCertificateData,
259 bool forIntroducer,
260 Ptr<Data> originalData,
261 const DataCallback& verifiedCallback,
262 const UnverifiedCallback& unverifiedCallback)
263{
264 Ptr<SyncIntroCertificate> introCertificate = Ptr<SyncIntroCertificate>(new SyncIntroCertificate(*introCertificateData));
265 if(forIntroducer)
266 m_trustedIntroducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
267 else
268 m_trustedProducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
269
270 if(verifySignature(*originalData, introCertificate->getPublicKeyInfo()))
271 verifiedCallback(originalData);
272 else
273 unverifiedCallback(originalData);
274}
275
276void
277SyncPolicyManager::onIntroCertUnverified(Ptr<Data> introCertificateData,
278 Ptr<Name> interestPrefixName,
279 bool forIntroducer,
280 Ptr<const std::vector<ndn::Name> > introNameList,
281 const int& nextIntroducerIndex,
282 Ptr<Data> originalData,
283 const DataCallback& verifiedCallback,
284 const UnverifiedCallback& unverifiedCallback)
285{
286 Name interestName = *interestPrefixName;
287 if(nextIntroducerIndex < introNameList->size())
288 interestName.append(introNameList->at(nextIntroducerIndex));
289 else
290 unverifiedCallback(originalData);
291
292 if(forIntroducer)
293 interestName.append("INTRODUCER");
294
295 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
296 interest->setChildSelector(Interest::CHILD_RIGHT);
297
298 DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified,
299 this,
300 _1,
301 forIntroducer,
302 originalData,
303 verifiedCallback,
304 unverifiedCallback);
305
306 UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified,
307 this,
308 _1,
309 interestPrefixName,
310 forIntroducer,
311 introNameList,
312 nextIntroducerIndex + 1,
313 originalData,
314 verifiedCallback,
315 unverifiedCallback);
316
317 TimeoutCallback requestedCertTimeoutCallback = boost::bind(&SyncPolicyManager::onIntroCertTimeOut,
318 this,
319 _1,
320 _2,
321 1,
322 requestedCertUnverifiedCallback,
323 originalData);
324
325 Ptr<Closure> closure = Ptr<Closure> (new Closure(requestedCertVerifiedCallback,
326 requestedCertTimeoutCallback,
327 requestedCertUnverifiedCallback,
328 m_stepLimit-1)
329 );
330
331 m_handler->sendInterest(interest, closure);
332}
333
334void
335SyncPolicyManager::onIntroCertTimeOut(Ptr<Closure> closure,
336 Ptr<Interest> interest,
337 int retry,
338 const UnverifiedCallback& unverifiedCallback,
339 Ptr<Data> data)
340{
341 if(retry > 0)
342 {
343 Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
344 boost::bind(&SyncPolicyManager::onIntroCertTimeOut,
345 this,
346 _1,
347 _2,
348 retry - 1,
349 unverifiedCallback,
350 data),
351 closure->m_unverifiedCallback,
352 closure->m_stepCount)
353 );
354 m_handler->sendInterest(interest, newClosure);
355 }
356 else
357 unverifiedCallback(data);
358}