blob: 25c32a1b31c006cc6333e36a41d9d3fe03a47e9a [file] [log] [blame]
Yingdi Yu0b82a4e2013-10-18 11:29:25 -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 "contact-manager.h"
12
Yingdi Yuaa8d7692013-10-18 17:05:02 -070013#ifndef Q_MOC_RUN
Yingdi Yu64206112013-12-24 11:16:32 +080014#include <ndn-cpp/face.hpp>
15#include <ndn-cpp/sha256-with-rsa-signature.hpp>
16#include <ndn-cpp/security/signature/sha256-with-rsa-handler.hpp>
Yingdi Yu6a5b9f62013-11-06 23:00:21 -080017#include <cryptopp/base64.h>
Yingdi Yu64206112013-12-24 11:16:32 +080018#include <ndn-cpp-et/policy-manager/identity-policy-rule.hpp>
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070019#include <fstream>
Yingdi Yu64206112013-12-24 11:16:32 +080020#include "endorse-collection.pb.h"
21#include "null-ptrs.h"
Yingdi Yu590fa5d2013-10-18 18:35:09 -070022#include "logging.h"
Yingdi Yuaa8d7692013-10-18 17:05:02 -070023#endif
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070024
25using namespace ndn;
Yingdi Yu64206112013-12-24 11:16:32 +080026using namespace ndn::ptr_lib;
27using namespace std;
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070028
Yingdi Yu590fa5d2013-10-18 18:35:09 -070029INIT_LOGGER("ContactManager");
30
Yingdi Yu64206112013-12-24 11:16:32 +080031ContactManager::ContactManager(shared_ptr<IdentityManager> identityManager, QObject* parent)
Yingdi Yu590fa5d2013-10-18 18:35:09 -070032 : QObject(parent)
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070033{
Yingdi Yu64206112013-12-24 11:16:32 +080034 m_identityManager = identityManager;
35 m_contactStorage = make_shared<ContactStorage>();
36 m_dnsStorage = make_shared<DnsStorage>();
Yingdi Yuaa8d7692013-10-18 17:05:02 -070037
Yingdi Yu64206112013-12-24 11:16:32 +080038 m_transport = make_shared<TcpTransport>();
39 m_face = make_shared<Face>(m_transport, make_shared<TcpTransport::ConnectionInfo>("localhost"));
40
41 connectToDaemon();
42
43 initializeSecurity();
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070044}
45
46ContactManager::~ContactManager()
47{
48}
49
Yingdi Yuaa8d7692013-10-18 17:05:02 -070050void
Yingdi Yu64206112013-12-24 11:16:32 +080051ContactManager::connectToDaemon()
Yingdi Yub29f78c2013-11-09 20:12:31 -080052{
Yingdi Yu64206112013-12-24 11:16:32 +080053 //Hack! transport does not connect to daemon unless an interest is expressed.
54 Name name("/ndn");
55 shared_ptr<ndn::Interest> interest = make_shared<ndn::Interest>(name);
56 m_face->expressInterest(*interest,
57 bind(&ContactManager::onConnectionData, this, _1, _2),
58 bind(&ContactManager::onConnectionDataTimeout, this, _1));
Yingdi Yub29f78c2013-11-09 20:12:31 -080059}
60
61void
Yingdi Yu64206112013-12-24 11:16:32 +080062ContactManager::onConnectionData(const shared_ptr<const ndn::Interest>& interest,
63 const shared_ptr<Data>& data)
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070064{
Yingdi Yu64206112013-12-24 11:16:32 +080065 _LOG_DEBUG("onConnectionData");
66}
Yingdi Yu6a5b9f62013-11-06 23:00:21 -080067
Yingdi Yu64206112013-12-24 11:16:32 +080068void
69ContactManager::onConnectionDataTimeout(const shared_ptr<const ndn::Interest>& interest)
70{
71 _LOG_DEBUG("onConnectionDataTimeout");
72}
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070073
Yingdi Yu64206112013-12-24 11:16:32 +080074void
75ContactManager::initializeSecurity()
76{
77 m_policyManager = make_shared<SimplePolicyManager>();
78
79 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><ENDORSED>",
80 "^([^<KEY>]*)<KEY>(<>*)[<ksk-.*><dsk-.*>]<ID-CERT>$",
81 "==", "\\1", "\\1\\2", true));
82 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><PROFILE>",
83 "^([^<KEY>]*)<KEY>(<>*)[<ksk-.*><dsk-.*>]<ID-CERT>$",
84 "==", "\\1", "\\1\\2", true));
85 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<PROFILE-CERT>]*)<PROFILE-CERT>",
86 "^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$",
87 "==", "\\1", "\\1\\2", true));
88 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
89 "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>$",
90 ">", "\\1\\2", "\\1", true));
91 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
92 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
93 "==", "\\1", "\\1\\2", true));
94 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^(<>*)$",
95 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
96 ">", "\\1", "\\1\\2", true));
Yingdi Yu8fb16a42013-11-10 18:35:09 -080097
Yingdi Yuaa8d7692013-10-18 17:05:02 -070098
Yingdi Yu64206112013-12-24 11:16:32 +080099 m_policyManager->addSigningPolicyRule(make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><PROFILE>",
100 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>",
101 "==", "\\1", "\\1\\2", true));
Yingdi Yu0b82a4e2013-10-18 11:29:25 -0700102
Yingdi Yu8fb16a42013-11-10 18:35:09 -0800103
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800104 const string TrustAnchor("BIICqgOyEIWlKzDI2xX2hdq5Azheu9IVyewcV4uM7ylfh67Y8MIxF3tDCTx5JgEn\
105HYMuCaYQm6XuaXTlVfDdWff/K7Xebq8IgGxjNBeU9eMf7Gy9iIMrRAOdBG0dBHmo\
10667biGs8F+P1oh1FwKu/FN1AE9vh8HSOJ94PWmjO+6PvITFIXuI3QbcCz8rhvbsfb\
1075X/DmfbJ8n8c4X3nVxrBm6fd4z8kOFOvvhgJImvqsow69Uy+38m8gJrmrcWMoPBJ\
108WsNLcEriZCt/Dlg7EqqVrIn6ukylKCvVrxA9vm/cEB74J/N+T0JyMRDnTLm17gpq\
109Gd75rhj+bLmpOMOBT7Nb27wUKq8gcXzeAADy+p1uZG4A+p1LRVkA+vVrc2stMTM4\
110MzMyNTcyMAD6vUlELUNFUlQA+q39PgurHgAAAaID4gKF5vjua9EIr3/Fn8k1AdSc\
111nEryjVDW3ikvYoSwjK7egTkAArq1BSc+C6sdAAHiAery+p1uZG4A+p1LRVkA+vVr\
112c2stMTM4MzMyNTcyMAD6vUlELUNFUlQAAAAAAAGaFr0wggFjMCIYDzIwMTMxMTAx\
113MTcxMTIyWhgPMjAxNDExMDExNzExMjJaMBkwFwYDVQQpExBORE4gVGVzdGJlZCBS\
114b290MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA06x+elwzWCHa4I3b\
115yrYCMAIVxQpRVLuOXp0h+BS+5GNgMVPi7+40o4zSJG+kiU8CIH1mtj8RQAzBX9hF\
116I5VAyOC8nS8D8YOfBwt2yRDZPgt1E5PpyYUBiDYuq/zmJDL8xjxAlxrMzVOqD/uj\
117/vkkcBM/T1t9Q6p1CpRyq+GMRbV4EAHvH7MFb6bDrH9t8DHEg7NPUCaSQBrd7PvL\
11872P+QdiNH9zs/EiVzAkeMG4iniSXLuYM3z0gMqqcyUUUr6r1F9IBmDO+Kp97nZh8\
119VCL+cnIEwyzAFAupQH5GoXUWGiee8oKWwH2vGHX7u6sWZsCp15NMSG3OC4jUIZOE\
120iVUF1QIBEQAA");
Yingdi Yu0b82a4e2013-10-18 11:29:25 -0700121
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800122 string decoded;
123 CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(TrustAnchor.c_str()),
124 TrustAnchor.size(),
125 true,
126 new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
Yingdi Yu64206112013-12-24 11:16:32 +0800127 Data data;
128 data.wireDecode((const uint8_t*)decoded.c_str(), decoded.size());
129 shared_ptr<IdentityCertificate> anchor = make_shared<IdentityCertificate>(data);
130 m_policyManager->addTrustAnchor(anchor);
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800131
132#ifdef _DEBUG
133
134 const string FakeAnchor("BIICqgOyEIVAaoHnQZIx5osAuY2fKte4HBSrxyam7MY6/kp+w47O1bGdd2KjeZKV\
135zZzQd3EQorDC3KUPbB6ql30jYfspvo4OPSlIuDrkyROaoZ+MSKyzQYpB6CZcTjBa\
136qcWYFOfwUlcWvkbd00X4bkc5PkcWpVdRrx+NCTiq9EXes//hOHpEJHMNsJUi45O+\
1376M4OE6/sNEqs/ryHn2w1vCqwPpG8xzcd0prQUdCH2MGE77F+H0XFDuWp8mrT37Uw\
138DUy7Ltm+7nDTHSQy2J3Zk4Q+0tjxCzSw4owEpwOHr+afdkuE3v9aB2NRQBBDCEmL\
139Ykz4sYX3XE8MVFqRn1HHWCkszjDg+F0UAADy+p1uZG4A+p1LRVkA+vVrc2stMTM4\
140MjkzNDE5OAD6vUlELUNFUlQA+s39/////95rc7MAAAGiA+IChaK1eVvzlkg6BJAw\
141qiOpxRoezQ0hAHOBbPRLeBllxMN7AAK6tQUm3mtztQAB4gHq8vqdbmRuAPqdS0VZ\
142APr1a3NrLTEzODI5MzQxOTgA+r1JRC1DRVJUAAAAAAABmhblMIIBaDAiGA8yMDEz\
143MTAyODAwMDAwMFoYDzIwMzMxMDI4MDAwMDAwWjAcMBoGA1UEKRMTL25kbi9rc2st\
144MTM4MjkzNDE5ODCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2htIFF\
145/PH+SJsGOA6jhpFT74xfLJlgZNJOnKzl27HI2gupE0mainWj/HqVzdGxD6jOOReI\
146sul+eQyEyBYq4e35pLmdJGlux/+UPQ51DD8jg04GrUPewV7+iGm6usp/7xEGHbah\
147H2Grv/bsGrt6aRA8cKmdIc+rehxZCVFtiwSEHTnOWzn3lfZR5xnjF9aGX+uGo1hA\
148gMwu1ECxg4H3O4z1tbTzji5+WH0RDsPRlgzQX6wAQH8btlQyoFJfljEA3QaOtDaB\
149OcfegIlClzutmgJnK9i5ZLz2Mjvx49dlCWAVKg65vOXMLC/33jD9F+V8urwsBlOb\
150F7Wh5ayeo8NBKDsCAwEAAQAA");
151
152 string decoded2;
153 CryptoPP::StringSource ss2(reinterpret_cast<const unsigned char *>(FakeAnchor.c_str()),
154 FakeAnchor.size(),
155 true,
156 new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded2)));
Yingdi Yu64206112013-12-24 11:16:32 +0800157 Data data2;
158 data2.wireDecode((const uint8_t*)decoded2.c_str(), decoded2.size());
159 shared_ptr<IdentityCertificate>anchor2 = make_shared<IdentityCertificate>(data2);
160 m_policyManager->addTrustAnchor(anchor2);
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800161
162#endif
Yingdi Yu0b82a4e2013-10-18 11:29:25 -0700163}
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700164
165
166void
167ContactManager::fetchSelfEndorseCertificate(const ndn::Name& identity)
168{
169 Name interestName = identity;
170 interestName.append("DNS").append("PROFILE");
171
Yingdi Yu64206112013-12-24 11:16:32 +0800172 Interest interest(interestName);
173 interest.setChildSelector(ndn_Interest_CHILD_SELECTOR_RIGHT);
174
175 OnVerified onVerified = boost::bind(&ContactManager::onDnsSelfEndorseCertificateVerified, this, _1, identity);
176 OnVerifyFailed onVerifyFailed = boost::bind(&ContactManager::onDnsSelfEndorseCertificateVerifyFailed, this, _1, identity);
177 TimeoutNotify timeoutNotify = boost::bind(&ContactManager::onDnsSelfEndorseCertificateTimeoutNotify, this, identity);
178
179 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700180}
181
182void
Yingdi Yu64206112013-12-24 11:16:32 +0800183ContactManager::onDnsSelfEndorseCertificateTimeoutNotify(const Name& identity)
184{ emit contactFetchFailed(identity); }
185
186void
187ContactManager::onDnsSelfEndorseCertificateVerified(const shared_ptr<Data>& data,
188 const Name& identity)
189{
190 try{
191 Data plainData;
192 plainData.wireDecode(data->getContent().buf(), data->getContent().size());
193 EndorseCertificate selfEndorseCertificate(plainData);
194 if(Sha256WithRsaHandler::verifySignature(plainData, selfEndorseCertificate.getPublicKeyInfo()))
195 emit contactFetched (selfEndorseCertificate);
196 else
197 emit contactFetchFailed (identity);
198 }catch(std::exception& e){
199 _LOG_ERROR("Exception: " << e.what());
200 emit contactFetchFailed (identity);
201 }
202}
203
204void
205ContactManager::onDnsSelfEndorseCertificateVerifyFailed(const shared_ptr<Data>& data,
206 const Name& identity)
207{ emit contactFetchFailed (identity); }
208
209void
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800210ContactManager::fetchCollectEndorse(const ndn::Name& identity)
211{
212 Name interestName = identity;
213 interestName.append("DNS").append("ENDORSED");
214
Yingdi Yu64206112013-12-24 11:16:32 +0800215 Interest interest(interestName);
216 interest.setChildSelector(ndn_Interest_CHILD_SELECTOR_RIGHT);
217 interest.setInterestLifetimeMilliseconds(1000);
218
219 OnVerified onVerified = boost::bind(&ContactManager::onDnsCollectEndorseVerified, this, _1, identity);
220 OnVerifyFailed onVerifyFailed = boost::bind(&ContactManager::onDnsCollectEndorseVerifyFailed, this, _1, identity);
221 TimeoutNotify timeoutNotify = boost::bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, identity);
222
223 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800224}
225
226void
Yingdi Yu64206112013-12-24 11:16:32 +0800227ContactManager::onDnsCollectEndorseTimeoutNotify(const Name& identity)
228{
229 emit collectEndorseFetchFailed (identity);
230}
231
232void
233ContactManager::onDnsCollectEndorseVerified(const shared_ptr<Data>& data, const Name& identity)
234{ emit collectEndorseFetched (*data); }
235
236void
237ContactManager::onDnsCollectEndorseVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
238{ emit collectEndorseFetchFailed (identity); }
239
240
241void
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800242ContactManager::fetchKey(const ndn::Name& certName)
243{
244 Name interestName = certName;
245
Yingdi Yu64206112013-12-24 11:16:32 +0800246 Interest interest(interestName);
247 interest.setChildSelector(ndn_Interest_CHILD_SELECTOR_RIGHT);
248 interest.setInterestLifetimeMilliseconds(1000);
249
250 OnVerified onVerified = boost::bind(&ContactManager::onKeyVerified, this, _1, certName);
251 OnVerifyFailed onVerifyFailed = boost::bind(&ContactManager::onKeyVerifyFailed, this, _1, certName);
252 TimeoutNotify timeoutNotify = boost::bind(&ContactManager::onKeyTimeoutNotify, this, certName);
253
254 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
255}
256
257
258void
259ContactManager::onKeyVerified(const shared_ptr<Data>& data, const Name& identity)
260{
261 IdentityCertificate identityCertificate(*data);
262
263 Profile profile(identityCertificate);
264 ProfileData profileData(profile);
265
266 Name certificateName = m_identityManager->getDefaultCertificateName();
267 m_identityManager->signByCertificate(profileData, certificateName);
268
269 try{
270 EndorseCertificate endorseCertificate(identityCertificate, profileData);
271 m_identityManager->signByCertificate(endorseCertificate, certificateName);
272 emit contactKeyFetched (endorseCertificate);
273 }catch(std::exception& e){
274 _LOG_ERROR("Exception: " << e.what());
275 return;
276 }
277}
278
279void
280ContactManager::onKeyVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
281{
282 _LOG_DEBUG("Key cannot be verified!");
283 emit contactKeyFetchFailed (identity);
284}
285
286void
287ContactManager::onKeyTimeoutNotify(const Name& identity)
288{
289 _LOG_DEBUG("Key timeout!");
290 emit contactKeyFetchFailed(identity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800291}
292
293void
Yingdi Yu908f8412013-11-09 00:03:26 -0800294ContactManager::fetchIdCertificate(const ndn::Name& certName)
295{
296 Name interestName = certName;
297
Yingdi Yu64206112013-12-24 11:16:32 +0800298 Interest interest(interestName);
299 interest.setChildSelector(ndn_Interest_CHILD_SELECTOR_RIGHT);
300 interest.setInterestLifetimeMilliseconds(1000);
301
302 OnVerified onVerified = boost::bind(&ContactManager::onIdCertificateVerified, this, _1, certName);
303 OnVerifyFailed onVerifyFailed = boost::bind(&ContactManager::onIdCertificateVerifyFailed, this, _1, certName);
304 TimeoutNotify timeoutNotify = boost::bind(&ContactManager::onIdCertificateTimeoutNotify, this, certName);
305
306 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
Yingdi Yu908f8412013-11-09 00:03:26 -0800307}
308
309void
Yingdi Yu64206112013-12-24 11:16:32 +0800310ContactManager::onIdCertificateTimeoutNotify(const Name& identity)
311{ emit contactCertificateFetchFailed (identity); }
312
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800313
314void
Yingdi Yu64206112013-12-24 11:16:32 +0800315ContactManager::onIdCertificateVerified(const shared_ptr<Data>& data, const Name& identity)
Yingdi Yu908f8412013-11-09 00:03:26 -0800316{
317 IdentityCertificate identityCertificate(*data);
318 emit contactCertificateFetched(identityCertificate);
319}
320
321void
Yingdi Yu64206112013-12-24 11:16:32 +0800322ContactManager::onIdCertificateVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
Yingdi Yu908f8412013-11-09 00:03:26 -0800323{ emit contactCertificateFetchFailed (identity); }
324
325void
Yingdi Yu64206112013-12-24 11:16:32 +0800326ContactManager::onTargetData(const shared_ptr<const ndn::Interest>& interest,
327 const shared_ptr<Data>& data,
328 int stepCount,
329 const OnVerified& onVerified,
330 const OnVerifyFailed& onVerifyFailed,
331 const TimeoutNotify& timeoutNotify)
332{
333 shared_ptr<ValidationRequest> nextStep = m_policyManager->checkVerificationPolicy(data, stepCount, onVerified, onVerifyFailed);
334
335 if (nextStep)
336 m_face->expressInterest
337 (*nextStep->interest_,
338 bind(&ContactManager::onCertData, this, _1, _2, nextStep),
339 bind(&ContactManager::onCertTimeout, this, _1, onVerifyFailed, data, nextStep));
340
341}
342
343void
344ContactManager::onTargetTimeout(const shared_ptr<const ndn::Interest>& interest,
345 int retry,
346 int stepCount,
347 const OnVerified& onVerified,
348 const OnVerifyFailed& onVerifyFailed,
349 const TimeoutNotify& timeoutNotify)
350{
351 if(retry > 0)
352 sendInterest(*interest, onVerified, onVerifyFailed, timeoutNotify, retry-1, stepCount);
353 else
354 {
355 _LOG_DEBUG("Interest: " << interest->getName().toUri() << " eventually times out!");
356 timeoutNotify();
357 }
358}
359
360void
361ContactManager::onCertData(const shared_ptr<const ndn::Interest>& interest,
362 const shared_ptr<Data>& cert,
363 shared_ptr<ValidationRequest> previousStep)
364{
365 shared_ptr<ValidationRequest> nextStep = m_policyManager->checkVerificationPolicy(cert,
366 previousStep->stepCount_,
367 previousStep->onVerified_,
368 previousStep->onVerifyFailed_);
369
370 if (nextStep)
371 m_face->expressInterest
372 (*nextStep->interest_,
373 bind(&ContactManager::onCertData, this, _1, _2, nextStep),
374 bind(&ContactManager::onCertTimeout, this, _1, previousStep->onVerifyFailed_, cert, nextStep));
375}
376
377void
378ContactManager::onCertTimeout(const shared_ptr<const ndn::Interest>& interest,
379 const OnVerifyFailed& onVerifyFailed,
380 const shared_ptr<Data>& data,
381 shared_ptr<ValidationRequest> nextStep)
382{
383 if(nextStep->retry_ > 0)
384 m_face->expressInterest(*interest,
385 bind(&ContactManager::onCertData,
386 this,
387 _1,
388 _2,
389 nextStep),
390 bind(&ContactManager::onCertTimeout,
391 this,
392 _1,
393 onVerifyFailed,
394 data,
395 nextStep));
396 else
397 onVerifyFailed(data);
398}
399
400void
401ContactManager::sendInterest(const Interest& interest,
402 const OnVerified& onVerified,
403 const OnVerifyFailed& onVerifyFailed,
404 const TimeoutNotify& timeoutNotify,
405 int retry /* = 1 */,
406 int stepCount /* = 0 */)
407{
408 m_face->expressInterest(interest,
409 boost::bind(&ContactManager::onTargetData,
410 this,
411 _1,
412 _2,
413 stepCount,
414 onVerified,
415 onVerifyFailed,
416 timeoutNotify),
417 boost::bind(&ContactManager::onTargetTimeout,
418 this,
419 _1,
420 retry,
421 stepCount,
422 onVerified,
423 onVerifyFailed,
424 timeoutNotify));
425}
Yingdi Yu908f8412013-11-09 00:03:26 -0800426
427void
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700428ContactManager::updateProfileData(const Name& identity)
429{
430 // Get current profile;
Yingdi Yu64206112013-12-24 11:16:32 +0800431 shared_ptr<Profile> newProfile = m_contactStorage->getSelfProfile(identity);
432 if(CHRONOCHAT_NULL_PROFILE_PTR == newProfile)
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700433 return;
Yingdi Yu64206112013-12-24 11:16:32 +0800434
435 shared_ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
436
437 if(CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR == newEndorseCertificate)
438 return;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700439
440 // Check if profile exists
Yingdi Yu64206112013-12-24 11:16:32 +0800441 Blob profileDataBlob = m_contactStorage->getSelfEndorseCertificate(identity);
442 if(CHRONOCHAT_NULL_BLOB != profileDataBlob)
443 m_contactStorage->updateSelfEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700444 else
Yingdi Yu64206112013-12-24 11:16:32 +0800445 m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yub35b8652013-11-07 11:32:40 -0800446
Yingdi Yu64206112013-12-24 11:16:32 +0800447 publishSelfEndorseCertificateInDNS(*newEndorseCertificate);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700448}
449
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800450void
451ContactManager::updateEndorseCertificate(const ndn::Name& identity, const ndn::Name& signerIdentity)
452{
Yingdi Yu64206112013-12-24 11:16:32 +0800453 Blob oldEndorseCertificateBlob = m_contactStorage->getEndorseCertificate(identity);
454 shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identity, signerIdentity);
455
456 if(CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR == newEndorseCertificate)
457 return;
458
459 if(CHRONOCHAT_NULL_BLOB != oldEndorseCertificateBlob)
460 m_contactStorage->updateEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800461 else
Yingdi Yu64206112013-12-24 11:16:32 +0800462 m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identity);
463
464 publishEndorseCertificateInDNS(*newEndorseCertificate, signerIdentity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800465}
466
Yingdi Yu64206112013-12-24 11:16:32 +0800467shared_ptr<EndorseCertificate>
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800468ContactManager::generateEndorseCertificate(const Name& identity, const Name& signerIdentity)
469{
Yingdi Yu64206112013-12-24 11:16:32 +0800470 shared_ptr<ContactItem> contact = getContact(identity);
471 if(contact == CHRONOCHAT_NULL_CONTACTITEM_PTR)
472 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800473
Yingdi Yu64206112013-12-24 11:16:32 +0800474 Name signerKeyName = m_identityManager->getDefaultKeyNameForIdentity(signerIdentity);
475 Name signerCertName = m_identityManager->getDefaultCertificateNameForIdentity(signerIdentity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800476
Yingdi Yu64206112013-12-24 11:16:32 +0800477 vector<string> endorseList;
478 m_contactStorage->getEndorseList(identity, endorseList);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800479
Yingdi Yu64206112013-12-24 11:16:32 +0800480
Yingdi Yub35b8652013-11-07 11:32:40 -0800481 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800482 shared_ptr<EndorseCertificate> cert = make_shared<EndorseCertificate>(contact->getSelfEndorseCertificate(), signerKeyName, endorseList);
483 m_identityManager->signByCertificate(*cert, signerCertName);
484 return cert;
485 }catch(std::exception& e){
Yingdi Yub35b8652013-11-07 11:32:40 -0800486 _LOG_ERROR("Exception: " << e.what());
Yingdi Yu64206112013-12-24 11:16:32 +0800487 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yub35b8652013-11-07 11:32:40 -0800488 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800489}
490
Yingdi Yu64206112013-12-24 11:16:32 +0800491void
492ContactManager::getContactItemList(vector<shared_ptr<ContactItem> >& contacts)
493{ return m_contactStorage->getAllContacts(contacts); }
Yingdi Yu79c25a22013-10-21 13:38:38 -0700494
Yingdi Yu64206112013-12-24 11:16:32 +0800495shared_ptr<ContactItem>
Yingdi Yud40226b2013-10-23 14:05:12 -0700496ContactManager::getContact(const ndn::Name& contactNamespace)
Yingdi Yu813d4e92013-11-03 16:22:05 -0800497{ return m_contactStorage->getContact(contactNamespace); }
Yingdi Yud40226b2013-10-23 14:05:12 -0700498
Yingdi Yu64206112013-12-24 11:16:32 +0800499shared_ptr<EndorseCertificate>
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700500ContactManager::getSignedSelfEndorseCertificate(const Name& identity,
501 const Profile& profile)
502{
Yingdi Yu64206112013-12-24 11:16:32 +0800503 Name certificateName = m_identityManager->getDefaultCertificateNameForIdentity(identity);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700504 if(0 == certificateName.size())
Yingdi Yu64206112013-12-24 11:16:32 +0800505 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700506
Yingdi Yu64206112013-12-24 11:16:32 +0800507 ProfileData profileData(profile);
508 m_identityManager->signByCertificate(profileData, certificateName);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700509
Yingdi Yu64206112013-12-24 11:16:32 +0800510 shared_ptr<IdentityCertificate> signingCert = m_identityManager->getCertificate(certificateName);
511 if(CHRONOCHAT_NULL_IDENTITYCERTIFICATE_PTR == signingCert)
512 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800513
Yingdi Yu64206112013-12-24 11:16:32 +0800514 Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signingCert->getName());
Yingdi Yued8cfc42013-11-01 17:37:51 -0700515
Yingdi Yu64206112013-12-24 11:16:32 +0800516 shared_ptr<IdentityCertificate> kskCert;
517 if(signingKeyName.get(-1).toEscapedString().substr(0,4) == string("dsk-"))
Yingdi Yued8cfc42013-11-01 17:37:51 -0700518 {
Yingdi Yu64206112013-12-24 11:16:32 +0800519 const Sha256WithRsaSignature* dskCertSig = dynamic_cast<const Sha256WithRsaSignature*>(signingCert->getSignature());
Yingdi Yued8cfc42013-11-01 17:37:51 -0700520 // HACK! KSK certificate should be retrieved from network.
Yingdi Yu64206112013-12-24 11:16:32 +0800521 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(dskCertSig->getKeyLocator().getKeyName());
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800522
Yingdi Yu64206112013-12-24 11:16:32 +0800523 // TODO: check null existing cases.
524 Name kskCertName = m_identityManager->getDefaultCertificateNameForIdentity(keyName.getPrefix(-1));
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800525
Yingdi Yu64206112013-12-24 11:16:32 +0800526 kskCert = m_identityManager->getCertificate(kskCertName);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700527 }
528 else
529 {
530 kskCert = signingCert;
Yingdi Yued8cfc42013-11-01 17:37:51 -0700531 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700532
Yingdi Yu64206112013-12-24 11:16:32 +0800533 if(CHRONOCHAT_NULL_IDENTITYCERTIFICATE_PTR == kskCert)
534 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800535
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700536 vector<string> endorseList;
537 Profile::const_iterator it = profile.begin();
538 for(; it != profile.end(); it++)
539 endorseList.push_back(it->first);
540
Yingdi Yub35b8652013-11-07 11:32:40 -0800541 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800542 shared_ptr<EndorseCertificate> selfEndorseCertificate = make_shared<EndorseCertificate>(*kskCert, profileData, endorseList);
543 m_identityManager->signByCertificate(*selfEndorseCertificate, kskCert->getName());
544
545 return selfEndorseCertificate;
546 }catch(std::exception& e){
Yingdi Yub35b8652013-11-07 11:32:40 -0800547 _LOG_ERROR("Exception: " << e.what());
Yingdi Yu64206112013-12-24 11:16:32 +0800548 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yub35b8652013-11-07 11:32:40 -0800549 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700550}
551
552
553void
Yingdi Yu64206112013-12-24 11:16:32 +0800554ContactManager::publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700555{
Yingdi Yu64206112013-12-24 11:16:32 +0800556 Data data;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700557
Yingdi Yu64206112013-12-24 11:16:32 +0800558 Name keyName = selfEndorseCertificate.getPublicKeyName();
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700559 Name identity = keyName.getSubName(0, keyName.size()-1);
560
Yingdi Yu64206112013-12-24 11:16:32 +0800561 time_t nowSeconds = time(NULL);
562 struct tm current = *gmtime(&nowSeconds);
563 MillisecondsSince1970 version = timegm(&current) * 1000.0;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700564
565 Name dnsName = identity;
Yingdi Yu64206112013-12-24 11:16:32 +0800566 dnsName.append("DNS").append("PROFILE").appendVersion(version);
567 data.setName(dnsName);
568
569 data.setContent(selfEndorseCertificate.wireEncode());
570
571 Name signCertName = m_identityManager->getDefaultCertificateNameForIdentity(identity);
572 m_identityManager->signByCertificate(data, signCertName);
573
574 m_dnsStorage->updateDnsSelfProfileData(data, identity);
Yingdi Yuc29fb982013-10-20 19:43:10 -0700575
Yingdi Yu64206112013-12-24 11:16:32 +0800576 m_transport->send(*data.wireEncode());
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700577}
578
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800579void
Yingdi Yu64206112013-12-24 11:16:32 +0800580ContactManager::publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate, const Name& signerIdentity)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800581{
Yingdi Yu64206112013-12-24 11:16:32 +0800582 Data data;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800583
Yingdi Yu64206112013-12-24 11:16:32 +0800584 Name keyName = endorseCertificate.getPublicKeyName();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800585 Name endorsee = keyName.getSubName(0, keyName.size()-1);
586
Yingdi Yu64206112013-12-24 11:16:32 +0800587 time_t nowSeconds = time(NULL);
588 struct tm current = *gmtime(&nowSeconds);
589 MillisecondsSince1970 version = timegm(&current) * 1000.0;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800590
591 Name dnsName = signerIdentity;
Yingdi Yu64206112013-12-24 11:16:32 +0800592 dnsName.append("DNS").append(endorsee).append("ENDORSEE").appendVersion(version);
593 data.setName(dnsName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800594
Yingdi Yu64206112013-12-24 11:16:32 +0800595 data.setContent(endorseCertificate.wireEncode());
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800596
Yingdi Yu64206112013-12-24 11:16:32 +0800597 Name signCertName = m_identityManager->getDefaultCertificateNameForIdentity(signerIdentity);
598 m_identityManager->signByCertificate(data, signCertName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800599
Yingdi Yu64206112013-12-24 11:16:32 +0800600 m_dnsStorage->updateDnsEndorseOthers(data, signerIdentity, endorsee);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800601
Yingdi Yu64206112013-12-24 11:16:32 +0800602 m_transport->send(*data.wireEncode());
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800603}
604
605void
606ContactManager::publishEndorsedDataInDns(const Name& identity)
607{
Yingdi Yu64206112013-12-24 11:16:32 +0800608 Data data;
609
610 time_t nowSeconds = time(NULL);
611 struct tm current = *gmtime(&nowSeconds);
612 MillisecondsSince1970 version = timegm(&current) * 1000.0;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800613
614 Name dnsName = identity;
Yingdi Yu64206112013-12-24 11:16:32 +0800615 dnsName.append("DNS").append("ENDORSED").appendVersion(version);
616 data.setName(dnsName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800617
Yingdi Yu64206112013-12-24 11:16:32 +0800618 vector<Blob> collectEndorseList;
619 m_contactStorage->getCollectEndorseList(identity, collectEndorseList);
620
621 Chronos::EndorseCollection endorseCollection;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800622
Yingdi Yu64206112013-12-24 11:16:32 +0800623 vector<Blob>::const_iterator it = collectEndorseList.begin();
624 for(; it != collectEndorseList.end(); it++)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800625 {
Yingdi Yu64206112013-12-24 11:16:32 +0800626 string entryStr((const char*)it->buf(), it->size());
627 endorseCollection.add_endorsement()->set_blob(entryStr);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800628 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800629
Yingdi Yu64206112013-12-24 11:16:32 +0800630 string encoded;
631 endorseCollection.SerializeToString(&encoded);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800632
Yingdi Yu64206112013-12-24 11:16:32 +0800633 data.setContent((const uint8_t*)encoded.c_str(), encoded.size());
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800634
Yingdi Yu64206112013-12-24 11:16:32 +0800635 Name signCertName = m_identityManager->getDefaultCertificateNameForIdentity(identity);
636 m_identityManager->signByCertificate(data, signCertName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800637
Yingdi Yu64206112013-12-24 11:16:32 +0800638 m_dnsStorage->updateDnsOthersEndorse(data, identity);
639
640 m_transport->send(*data.wireEncode());
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800641}
642
Yingdi Yu908f8412013-11-09 00:03:26 -0800643void
644ContactManager::addContact(const IdentityCertificate& identityCertificate, const Profile& profile)
645{
Yingdi Yu64206112013-12-24 11:16:32 +0800646 ProfileData profileData(profile);
Yingdi Yu908f8412013-11-09 00:03:26 -0800647
Yingdi Yu64206112013-12-24 11:16:32 +0800648 Name certificateName = m_identityManager->getDefaultCertificateNameForIdentity (m_defaultIdentity);
649 m_identityManager->signByCertificate(profileData, certificateName);
Yingdi Yu908f8412013-11-09 00:03:26 -0800650
Yingdi Yu908f8412013-11-09 00:03:26 -0800651
652 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800653 EndorseCertificate endorseCertificate(identityCertificate, profileData);
654
655 m_identityManager->signByCertificate(endorseCertificate, certificateName);
656
657 ContactItem contactItem(endorseCertificate);
658
Yingdi Yu908f8412013-11-09 00:03:26 -0800659 m_contactStorage->addContact(contactItem);
Yingdi Yu64206112013-12-24 11:16:32 +0800660
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800661 emit contactAdded(contactItem.getNameSpace());
Yingdi Yu64206112013-12-24 11:16:32 +0800662
663 }catch(std::exception& e){
Yingdi Yu908f8412013-11-09 00:03:26 -0800664 emit warning(e.what());
665 _LOG_ERROR("Exception: " << e.what());
666 return;
667 }
668}
669
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800670void
671ContactManager::removeContact(const ndn::Name& contactNameSpace)
672{
Yingdi Yu64206112013-12-24 11:16:32 +0800673 shared_ptr<ContactItem> contact = getContact(contactNameSpace);
674 if(contact == CHRONOCHAT_NULL_CONTACTITEM_PTR)
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800675 return;
676 m_contactStorage->removeContact(contactNameSpace);
677 emit contactRemoved(contact->getPublicKeyName());
678}
Yingdi Yu908f8412013-11-09 00:03:26 -0800679
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700680
681#if WAF
682#include "contact-manager.moc"
683#include "contact-manager.cpp.moc"
684#endif