blob: a788b665537523675ff73b7de18f4da2e85525b9 [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"
Yingdi Yu7bfcd652013-11-12 13:15:33 -080015#include <ndn.cxx/security/identity/identity-manager.h>
Yingdi Yu43e71612013-10-30 22:19:31 -070016
17using namespace ndn;
18using namespace ndn::security;
19using namespace std;
20
21INIT_LOGGER("SyncPolicyManager");
22
23SyncPolicyManager::SyncPolicyManager(const Name& signingIdentity,
24 const Name& signingCertificateName,
25 const Name& syncPrefix,
26 int stepLimit)
27 : m_signingIdentity(signingIdentity)
28 , m_signingCertificateName(signingCertificateName.getPrefix(signingCertificateName.size()-1))
29 , m_syncPrefix(syncPrefix)
30 , m_stepLimit(stepLimit)
Yingdi Yu7bfcd652013-11-12 13:15:33 -080031 , m_identityManager(Ptr<security::IdentityManager>::Create())
Yingdi Yu43e71612013-10-30 22:19:31 -070032{
33 Name wotPrefix = syncPrefix;
34 wotPrefix.append("WOT");
35 m_syncPrefixRegex = Regex::fromName(syncPrefix);
36 m_wotPrefixRegex = Regex::fromName(wotPrefix);
Yingdi Yu4526a2e2013-11-06 16:36:01 -080037 m_chatDataPolicy = Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^[^<%F0.>]*<%F0.>([^<chronos>]*)<chronos><>",
Yingdi Yu9529bc32013-11-01 16:19:25 -070038 "^([^<KEY>]*)<KEY>(<>*)[<dsk-.*><ksk-.*>]<ID-CERT>$",
Yingdi Yu43e71612013-10-30 22:19:31 -070039 "==", "\\1", "\\1", true));
40}
41
42SyncPolicyManager::~SyncPolicyManager()
43{}
44
45bool
46SyncPolicyManager::skipVerifyAndTrust (const Data& data)
47{ return false; }
48
49bool
50SyncPolicyManager::requireVerify (const Data& data)
51{ return true; }
52
53Ptr<ValidationRequest>
54SyncPolicyManager::checkVerificationPolicy(Ptr<Data> data,
55 const int& stepCount,
56 const DataCallback& verifiedCallback,
57 const UnverifiedCallback& unverifiedCallback)
58{
Yingdi Yu0b3bd482013-11-01 16:11:20 -070059// #ifdef _DEBUG
60// _LOG_DEBUG("checkVerificationPolicy");
61// verifiedCallback(data);
62// return NULL;
63// #else
Yingdi Yu43e71612013-10-30 22:19:31 -070064 //TODO:
65 if(stepCount > m_stepLimit)
66 {
67 unverifiedCallback(data);
68 return NULL;
69 }
70
71 Ptr<const signature::Sha256WithRsa> sha256sig = DynamicCast<const signature::Sha256WithRsa> (data->getSignature());
72 if(KeyLocator::KEYNAME != sha256sig->getKeyLocator().getType())
73 {
74 unverifiedCallback(data);
75 return NULL;
76 }
77
78 const Name& keyLocatorName = sha256sig->getKeyLocator().getKeyName();
Yingdi Yu1baf6e02013-11-07 11:35:32 -080079 // _LOG_DEBUG("data name: " << data->getName());
80 // _LOG_DEBUG("signer name: " << keyLocatorName);
Yingdi Yu43e71612013-10-30 22:19:31 -070081
82 // if data is intro cert
83 if(m_wotPrefixRegex->match(data->getName()))
84 {
Yingdi Yu1baf6e02013-11-07 11:35:32 -080085 // _LOG_DEBUG("Intro Cert");
Yingdi Yu43e71612013-10-30 22:19:31 -070086 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
87 map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
88 if(m_trustedIntroducers.end() != it)
89 {
90 if(verifySignature(*data, it->second))
91 verifiedCallback(data);
92 else
93 unverifiedCallback(data);
94 return NULL;
95 }
96 else
97 return prepareRequest(keyName, true, data, stepCount, verifiedCallback, unverifiedCallback);
98 }
99
100 // if data is sync data or chat data
101 if(m_syncPrefixRegex->match(data->getName()) || m_chatDataPolicy->satisfy(*data))
102 {
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800103 // _LOG_DEBUG("Sync/Chat Data");
Yingdi Yu43e71612013-10-30 22:19:31 -0700104 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocatorName);
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800105 // _LOG_DEBUG("keyName: " << keyName.toUri());
Yingdi Yu43e71612013-10-30 22:19:31 -0700106
107 map<Name, Publickey>::const_iterator it = m_trustedIntroducers.find(keyName);
108 if(m_trustedIntroducers.end() != it)
109 {
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800110 // _LOG_DEBUG("Find trusted introducer!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700111 if(verifySignature(*data, it->second))
112 verifiedCallback(data);
113 else
114 unverifiedCallback(data);
115 return NULL;
116 }
117
118 it = m_trustedProducers.find(keyName);
119 if(m_trustedProducers.end() != it)
120 {
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800121 // _LOG_DEBUG("Find trusted producer!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700122 if(verifySignature(*data, it->second))
123 verifiedCallback(data);
124 else
125 unverifiedCallback(data);
126 return NULL;
127 }
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700128
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800129 // _LOG_DEBUG("Did not find any trusted one!");
Yingdi Yu43e71612013-10-30 22:19:31 -0700130 return prepareRequest(keyName, false, data, stepCount, verifiedCallback, unverifiedCallback);
131 }
132
133 unverifiedCallback(data);
134 return NULL;
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700135// #endif
Yingdi Yu43e71612013-10-30 22:19:31 -0700136}
137
138bool
139SyncPolicyManager::checkSigningPolicy(const Name& dataName,
140 const Name& certificateName)
141{
142
Yingdi Yu43e71612013-10-30 22:19:31 -0700143 return true;
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700144
145// #ifdef _DEBUG
146// _LOG_DEBUG("checkSigningPolicy");
147// return true;
148// #else
149 // return (m_syncPrefixRegex->match(dataName) && certificateName.getPrefix(certificateName.size()-1) == m_signingCertificateName) ? true : false;
150// #endif
Yingdi Yu43e71612013-10-30 22:19:31 -0700151}
152
153Name
154SyncPolicyManager::inferSigningIdentity(const ndn::Name& dataName)
155{ return m_signingIdentity; }
156
157void
158SyncPolicyManager::addTrustAnchor(const IdentityCertificate& identityCertificate, bool isIntroducer)
159{
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800160 // _LOG_DEBUG("Add intro/producer: " << identityCertificate.getPublicKeyName());
Yingdi Yu43e71612013-10-30 22:19:31 -0700161 if(isIntroducer)
162 m_trustedIntroducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
163 else
164 m_trustedProducers.insert(pair <Name, Publickey > (identityCertificate.getPublicKeyName(), identityCertificate.getPublicKeyInfo()));
165}
166
167void
168SyncPolicyManager::addChatDataRule(const Name& prefix,
169 const IdentityCertificate& identityCertificate,
170 bool isIntroducer)
171{
172 // Name dataPrefix = prefix;
173 // dataPrefix.append("chronos").append(m_syncPrefix.get(-1));
174 // Ptr<Regex> dataRegex = Regex::fromName(prefix);
175 // Name certName = identityCertificate.getName();
176 // Name signerName = certName.getPrefix(certName.size()-1);
177 // Ptr<Regex> signerRegex = Regex::fromName(signerName, true);
178
179 // SpecificPolicyRule rule(dataRegex, signerRegex);
180 // map<Name, SpecificPolicyRule>::iterator it = m_chatDataRules.find(dataPrefix);
181 // if(it != m_chatDataRules.end())
182 // it->second = rule;
183 // else
184 // m_chatDataRules.insert(pair <Name, SpecificPolicyRule > (dataPrefix, rule));
185
186 addTrustAnchor(identityCertificate, isIntroducer);
187}
188
189
190Ptr<const vector<Name> >
191SyncPolicyManager::getAllIntroducerName()
192{
193 Ptr<vector<Name> > nameList = Ptr<vector<Name> >(new vector<Name>);
194
195 map<Name, Publickey>::iterator it = m_trustedIntroducers.begin();
196 for(; it != m_trustedIntroducers.end(); it++)
197 nameList->push_back(it->first);
198
199 return nameList;
200}
201
202Ptr<ValidationRequest>
203SyncPolicyManager::prepareRequest(const Name& keyName,
204 bool forIntroducer,
205 Ptr<Data> data,
206 const int & stepCount,
207 const DataCallback& verifiedCallback,
208 const UnverifiedCallback& unverifiedCallback)
209{
210 Ptr<Name> interestPrefixName = Ptr<Name>(new Name(m_syncPrefix));
211 interestPrefixName->append("WOT").append(keyName).append("INTRO-CERT");
212
213 Ptr<const std::vector<ndn::Name> > nameList = getAllIntroducerName();
Yingdi Yu0b3bd482013-11-01 16:11:20 -0700214 if(0 == nameList->size())
215 {
216 unverifiedCallback(data);
217 return NULL;
218 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700219
220 Name interestName = *interestPrefixName;
221 interestName.append(nameList->at(0));
222
223 if(forIntroducer)
224 interestName.append("INTRODUCER");
225
226 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
Yingdi Yu1baf6e02013-11-07 11:35:32 -0800227 // _LOG_DEBUG("send interest for intro cert: " << interest->getName());
Yingdi Yu43e71612013-10-30 22:19:31 -0700228 interest->setChildSelector(Interest::CHILD_RIGHT);
229
230 DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified,
231 this,
232 _1,
233 forIntroducer,
234 data,
235 verifiedCallback,
236 unverifiedCallback);
237
238 UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified,
239 this,
240 _1,
241 interestPrefixName,
242 forIntroducer,
243 nameList,
244 1,
245 data,
246 verifiedCallback,
247 unverifiedCallback);
248
249
250 Ptr<ValidationRequest> nextStep = Ptr<ValidationRequest>(new ValidationRequest(interest,
251 requestedCertVerifiedCallback,
252 requestedCertUnverifiedCallback,
253 1,
254 m_stepLimit-1)
255 );
256 return nextStep;
257}
258
259void
260SyncPolicyManager::onIntroCertVerified(Ptr<Data> introCertificateData,
261 bool forIntroducer,
262 Ptr<Data> originalData,
263 const DataCallback& verifiedCallback,
264 const UnverifiedCallback& unverifiedCallback)
265{
266 Ptr<SyncIntroCertificate> introCertificate = Ptr<SyncIntroCertificate>(new SyncIntroCertificate(*introCertificateData));
267 if(forIntroducer)
Yingdi Yu7bfcd652013-11-12 13:15:33 -0800268 {
269 m_trustedIntroducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
270 SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
271 introCertificate->getPublicKeyName(),
272 m_identityManager->getDefaultKeyNameForIdentity(m_signingIdentity),
273 introCertificate->getNotBefore(),
274 introCertificate->getNotAfter(),
275 introCertificate->getPublicKeyInfo(),
276 SyncIntroCertificate::INTRODUCER);
277 // : SyncIntroCertificate::PRODUCER)
278 ndn::Name certName = m_identityManager->getDefaultCertificateNameByIdentity(m_signingIdentity);
279 _LOG_DEBUG("Publish Intro Certificate on Verified: " << syncIntroCertificate.getName());
280 m_identityManager->signByCertificate(syncIntroCertificate, certName);
281 m_handler->putToNdnd(*syncIntroCertificate.encodeToWire());
282 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700283 else
Yingdi Yu7bfcd652013-11-12 13:15:33 -0800284 {
285 m_trustedProducers.insert(pair <Name, Publickey > (introCertificate->getPublicKeyName(), introCertificate->getPublicKeyInfo()));
286 SyncIntroCertificate syncIntroCertificate(m_syncPrefix,
287 introCertificate->getPublicKeyName(),
288 m_identityManager->getDefaultKeyNameForIdentity(m_signingIdentity),
289 introCertificate->getNotBefore(),
290 introCertificate->getNotAfter(),
291 introCertificate->getPublicKeyInfo(),
292 SyncIntroCertificate::PRODUCER);
293 // : SyncIntroCertificate::PRODUCER)
294 ndn::Name certName = m_identityManager->getDefaultCertificateNameByIdentity(m_signingIdentity);
295 _LOG_DEBUG("Publish Intro Certificate on Verified: " << syncIntroCertificate.getName());
296 m_identityManager->signByCertificate(syncIntroCertificate, certName);
297 m_handler->putToNdnd(*syncIntroCertificate.encodeToWire());
298 }
Yingdi Yu43e71612013-10-30 22:19:31 -0700299
300 if(verifySignature(*originalData, introCertificate->getPublicKeyInfo()))
301 verifiedCallback(originalData);
302 else
303 unverifiedCallback(originalData);
304}
305
306void
307SyncPolicyManager::onIntroCertUnverified(Ptr<Data> introCertificateData,
308 Ptr<Name> interestPrefixName,
309 bool forIntroducer,
310 Ptr<const std::vector<ndn::Name> > introNameList,
311 const int& nextIntroducerIndex,
312 Ptr<Data> originalData,
313 const DataCallback& verifiedCallback,
314 const UnverifiedCallback& unverifiedCallback)
315{
316 Name interestName = *interestPrefixName;
317 if(nextIntroducerIndex < introNameList->size())
318 interestName.append(introNameList->at(nextIntroducerIndex));
319 else
320 unverifiedCallback(originalData);
321
322 if(forIntroducer)
323 interestName.append("INTRODUCER");
324
325 Ptr<Interest> interest = Ptr<Interest>(new Interest(interestName));
326 interest->setChildSelector(Interest::CHILD_RIGHT);
327
328 DataCallback requestedCertVerifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertVerified,
329 this,
330 _1,
331 forIntroducer,
332 originalData,
333 verifiedCallback,
334 unverifiedCallback);
335
336 UnverifiedCallback requestedCertUnverifiedCallback = boost::bind(&SyncPolicyManager::onIntroCertUnverified,
337 this,
338 _1,
339 interestPrefixName,
340 forIntroducer,
341 introNameList,
342 nextIntroducerIndex + 1,
343 originalData,
344 verifiedCallback,
345 unverifiedCallback);
346
347 TimeoutCallback requestedCertTimeoutCallback = boost::bind(&SyncPolicyManager::onIntroCertTimeOut,
348 this,
349 _1,
350 _2,
351 1,
352 requestedCertUnverifiedCallback,
353 originalData);
354
355 Ptr<Closure> closure = Ptr<Closure> (new Closure(requestedCertVerifiedCallback,
356 requestedCertTimeoutCallback,
357 requestedCertUnverifiedCallback,
358 m_stepLimit-1)
359 );
360
361 m_handler->sendInterest(interest, closure);
362}
363
364void
365SyncPolicyManager::onIntroCertTimeOut(Ptr<Closure> closure,
366 Ptr<Interest> interest,
367 int retry,
368 const UnverifiedCallback& unverifiedCallback,
369 Ptr<Data> data)
370{
371 if(retry > 0)
372 {
373 Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
374 boost::bind(&SyncPolicyManager::onIntroCertTimeOut,
375 this,
376 _1,
377 _2,
378 retry - 1,
379 unverifiedCallback,
380 data),
381 closure->m_unverifiedCallback,
382 closure->m_stepCount)
383 );
384 m_handler->sendInterest(interest, newClosure);
385 }
386 else
387 unverifiedCallback(data);
388}