blob: 30951775f755f717951855ebc3c75e14653255c0 [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
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080011#if __clang__
12#pragma clang diagnostic push
13#pragma clang diagnostic ignored "-Wreorder"
14#pragma clang diagnostic ignored "-Wtautological-compare"
15#pragma clang diagnostic ignored "-Wunused-variable"
16#pragma clang diagnostic ignored "-Wunused-function"
17#elif __GNUC__
18#pragma GCC diagnostic ignored "-Wreorder"
19#pragma GCC diagnostic ignored "-Wunused-variable"
20#pragma GCC diagnostic ignored "-Wunused-function"
21#endif
22
23
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070024#include "contact-manager.h"
25
Yingdi Yuaa8d7692013-10-18 17:05:02 -070026#ifndef Q_MOC_RUN
Yingdi Yu64206112013-12-24 11:16:32 +080027#include <ndn-cpp/face.hpp>
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080028#include <ndn-cpp/security/signature/signature-sha256-with-rsa.hpp>
29#include <ndn-cpp/security/verifier.hpp>
Yingdi Yu6a5b9f62013-11-06 23:00:21 -080030#include <cryptopp/base64.h>
Yingdi Yu64206112013-12-24 11:16:32 +080031#include <ndn-cpp-et/policy-manager/identity-policy-rule.hpp>
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070032#include <fstream>
Yingdi Yu64206112013-12-24 11:16:32 +080033#include "endorse-collection.pb.h"
34#include "null-ptrs.h"
Yingdi Yu590fa5d2013-10-18 18:35:09 -070035#include "logging.h"
Yingdi Yuaa8d7692013-10-18 17:05:02 -070036#endif
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070037
38using namespace ndn;
Yingdi Yu64206112013-12-24 11:16:32 +080039using namespace ndn::ptr_lib;
40using namespace std;
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070041
Yingdi Yu590fa5d2013-10-18 18:35:09 -070042INIT_LOGGER("ContactManager");
43
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080044ContactManager::ContactManager(shared_ptr<KeyChain> keyChain,
Yingdi Yuaccbda92013-12-27 08:44:12 +080045 shared_ptr<Face> face,
Yingdi Yuaccbda92013-12-27 08:44:12 +080046 QObject* parent)
47 : QObject(parent),
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080048 m_face(face)
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070049{
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -080050 m_keyChain = keyChain;
Yingdi Yu64206112013-12-24 11:16:32 +080051 m_contactStorage = make_shared<ContactStorage>();
52 m_dnsStorage = make_shared<DnsStorage>();
Yingdi Yuaa8d7692013-10-18 17:05:02 -070053
Yingdi Yu64206112013-12-24 11:16:32 +080054 initializeSecurity();
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070055}
56
57ContactManager::~ContactManager()
Yingdi Yuaccbda92013-12-27 08:44:12 +080058{}
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070059
Yingdi Yu64206112013-12-24 11:16:32 +080060void
61ContactManager::initializeSecurity()
62{
63 m_policyManager = make_shared<SimplePolicyManager>();
64
65 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><ENDORSED>",
66 "^([^<KEY>]*)<KEY>(<>*)[<ksk-.*><dsk-.*>]<ID-CERT>$",
67 "==", "\\1", "\\1\\2", true));
68 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><PROFILE>",
69 "^([^<KEY>]*)<KEY>(<>*)[<ksk-.*><dsk-.*>]<ID-CERT>$",
70 "==", "\\1", "\\1\\2", true));
71 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<PROFILE-CERT>]*)<PROFILE-CERT>",
72 "^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$",
73 "==", "\\1", "\\1\\2", true));
74 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
75 "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>$",
76 ">", "\\1\\2", "\\1", true));
77 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
78 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
79 "==", "\\1", "\\1\\2", true));
80 m_policyManager->addVerificationPolicyRule(make_shared<IdentityPolicyRule>("^(<>*)$",
81 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
82 ">", "\\1", "\\1\\2", true));
Yingdi Yu8fb16a42013-11-10 18:35:09 -080083
Yingdi Yuaa8d7692013-10-18 17:05:02 -070084
Yingdi Yu64206112013-12-24 11:16:32 +080085 m_policyManager->addSigningPolicyRule(make_shared<IdentityPolicyRule>("^([^<DNS>]*)<DNS><PROFILE>",
86 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>",
87 "==", "\\1", "\\1\\2", true));
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070088
Yingdi Yu8fb16a42013-11-10 18:35:09 -080089
Yingdi Yu6a5b9f62013-11-06 23:00:21 -080090 const string TrustAnchor("BIICqgOyEIWlKzDI2xX2hdq5Azheu9IVyewcV4uM7ylfh67Y8MIxF3tDCTx5JgEn\
91HYMuCaYQm6XuaXTlVfDdWff/K7Xebq8IgGxjNBeU9eMf7Gy9iIMrRAOdBG0dBHmo\
9267biGs8F+P1oh1FwKu/FN1AE9vh8HSOJ94PWmjO+6PvITFIXuI3QbcCz8rhvbsfb\
935X/DmfbJ8n8c4X3nVxrBm6fd4z8kOFOvvhgJImvqsow69Uy+38m8gJrmrcWMoPBJ\
94WsNLcEriZCt/Dlg7EqqVrIn6ukylKCvVrxA9vm/cEB74J/N+T0JyMRDnTLm17gpq\
95Gd75rhj+bLmpOMOBT7Nb27wUKq8gcXzeAADy+p1uZG4A+p1LRVkA+vVrc2stMTM4\
96MzMyNTcyMAD6vUlELUNFUlQA+q39PgurHgAAAaID4gKF5vjua9EIr3/Fn8k1AdSc\
97nEryjVDW3ikvYoSwjK7egTkAArq1BSc+C6sdAAHiAery+p1uZG4A+p1LRVkA+vVr\
98c2stMTM4MzMyNTcyMAD6vUlELUNFUlQAAAAAAAGaFr0wggFjMCIYDzIwMTMxMTAx\
99MTcxMTIyWhgPMjAxNDExMDExNzExMjJaMBkwFwYDVQQpExBORE4gVGVzdGJlZCBS\
100b290MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEA06x+elwzWCHa4I3b\
101yrYCMAIVxQpRVLuOXp0h+BS+5GNgMVPi7+40o4zSJG+kiU8CIH1mtj8RQAzBX9hF\
102I5VAyOC8nS8D8YOfBwt2yRDZPgt1E5PpyYUBiDYuq/zmJDL8xjxAlxrMzVOqD/uj\
103/vkkcBM/T1t9Q6p1CpRyq+GMRbV4EAHvH7MFb6bDrH9t8DHEg7NPUCaSQBrd7PvL\
10472P+QdiNH9zs/EiVzAkeMG4iniSXLuYM3z0gMqqcyUUUr6r1F9IBmDO+Kp97nZh8\
105VCL+cnIEwyzAFAupQH5GoXUWGiee8oKWwH2vGHX7u6sWZsCp15NMSG3OC4jUIZOE\
106iVUF1QIBEQAA");
Yingdi Yu0b82a4e2013-10-18 11:29:25 -0700107
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800108 string decoded;
109 CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(TrustAnchor.c_str()),
110 TrustAnchor.size(),
111 true,
112 new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded)));
Yingdi Yu64206112013-12-24 11:16:32 +0800113 Data data;
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800114 data.wireDecode(Block(reinterpret_cast<const uint8_t*>(decoded.c_str()), decoded.size()));
Yingdi Yu64206112013-12-24 11:16:32 +0800115 shared_ptr<IdentityCertificate> anchor = make_shared<IdentityCertificate>(data);
116 m_policyManager->addTrustAnchor(anchor);
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800117
118#ifdef _DEBUG
119
120 const string FakeAnchor("BIICqgOyEIVAaoHnQZIx5osAuY2fKte4HBSrxyam7MY6/kp+w47O1bGdd2KjeZKV\
121zZzQd3EQorDC3KUPbB6ql30jYfspvo4OPSlIuDrkyROaoZ+MSKyzQYpB6CZcTjBa\
122qcWYFOfwUlcWvkbd00X4bkc5PkcWpVdRrx+NCTiq9EXes//hOHpEJHMNsJUi45O+\
1236M4OE6/sNEqs/ryHn2w1vCqwPpG8xzcd0prQUdCH2MGE77F+H0XFDuWp8mrT37Uw\
124DUy7Ltm+7nDTHSQy2J3Zk4Q+0tjxCzSw4owEpwOHr+afdkuE3v9aB2NRQBBDCEmL\
125Ykz4sYX3XE8MVFqRn1HHWCkszjDg+F0UAADy+p1uZG4A+p1LRVkA+vVrc2stMTM4\
126MjkzNDE5OAD6vUlELUNFUlQA+s39/////95rc7MAAAGiA+IChaK1eVvzlkg6BJAw\
127qiOpxRoezQ0hAHOBbPRLeBllxMN7AAK6tQUm3mtztQAB4gHq8vqdbmRuAPqdS0VZ\
128APr1a3NrLTEzODI5MzQxOTgA+r1JRC1DRVJUAAAAAAABmhblMIIBaDAiGA8yMDEz\
129MTAyODAwMDAwMFoYDzIwMzMxMDI4MDAwMDAwWjAcMBoGA1UEKRMTL25kbi9rc2st\
130MTM4MjkzNDE5ODCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2htIFF\
131/PH+SJsGOA6jhpFT74xfLJlgZNJOnKzl27HI2gupE0mainWj/HqVzdGxD6jOOReI\
132sul+eQyEyBYq4e35pLmdJGlux/+UPQ51DD8jg04GrUPewV7+iGm6usp/7xEGHbah\
133H2Grv/bsGrt6aRA8cKmdIc+rehxZCVFtiwSEHTnOWzn3lfZR5xnjF9aGX+uGo1hA\
134gMwu1ECxg4H3O4z1tbTzji5+WH0RDsPRlgzQX6wAQH8btlQyoFJfljEA3QaOtDaB\
135OcfegIlClzutmgJnK9i5ZLz2Mjvx49dlCWAVKg65vOXMLC/33jD9F+V8urwsBlOb\
136F7Wh5ayeo8NBKDsCAwEAAQAA");
137
138 string decoded2;
139 CryptoPP::StringSource ss2(reinterpret_cast<const unsigned char *>(FakeAnchor.c_str()),
140 FakeAnchor.size(),
141 true,
142 new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decoded2)));
Yingdi Yu64206112013-12-24 11:16:32 +0800143 Data data2;
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800144 data2.wireDecode(Block(reinterpret_cast<const uint8_t*>(decoded.c_str()), decoded.size()));
Yingdi Yu64206112013-12-24 11:16:32 +0800145 shared_ptr<IdentityCertificate>anchor2 = make_shared<IdentityCertificate>(data2);
146 m_policyManager->addTrustAnchor(anchor2);
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800147
148#endif
Yingdi Yu0b82a4e2013-10-18 11:29:25 -0700149}
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700150
151
152void
153ContactManager::fetchSelfEndorseCertificate(const ndn::Name& identity)
154{
155 Name interestName = identity;
156 interestName.append("DNS").append("PROFILE");
157
Yingdi Yu64206112013-12-24 11:16:32 +0800158 Interest interest(interestName);
Yingdi Yu64206112013-12-24 11:16:32 +0800159
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800160 OnVerified onVerified = func_lib::bind(&ContactManager::onDnsSelfEndorseCertificateVerified, this, _1, identity);
161 OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactManager::onDnsSelfEndorseCertificateVerifyFailed, this, _1, identity);
162 TimeoutNotify timeoutNotify = func_lib::bind(&ContactManager::onDnsSelfEndorseCertificateTimeoutNotify, this, identity);
Yingdi Yu64206112013-12-24 11:16:32 +0800163
164 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700165}
166
167void
Yingdi Yu64206112013-12-24 11:16:32 +0800168ContactManager::onDnsSelfEndorseCertificateTimeoutNotify(const Name& identity)
169{ emit contactFetchFailed(identity); }
170
171void
172ContactManager::onDnsSelfEndorseCertificateVerified(const shared_ptr<Data>& data,
173 const Name& identity)
174{
175 try{
176 Data plainData;
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800177 plainData.wireDecode(Block(data->getContent().value(), data->getContent().value_size()));
Yingdi Yu64206112013-12-24 11:16:32 +0800178 EndorseCertificate selfEndorseCertificate(plainData);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800179 if(Verifier::verifySignature(plainData, plainData.getSignature(), selfEndorseCertificate.getPublicKeyInfo()))
Yingdi Yu64206112013-12-24 11:16:32 +0800180 emit contactFetched (selfEndorseCertificate);
181 else
182 emit contactFetchFailed (identity);
183 }catch(std::exception& e){
184 _LOG_ERROR("Exception: " << e.what());
185 emit contactFetchFailed (identity);
186 }
187}
188
189void
190ContactManager::onDnsSelfEndorseCertificateVerifyFailed(const shared_ptr<Data>& data,
191 const Name& identity)
192{ emit contactFetchFailed (identity); }
193
194void
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800195ContactManager::fetchCollectEndorse(const ndn::Name& identity)
196{
197 Name interestName = identity;
198 interestName.append("DNS").append("ENDORSED");
199
Yingdi Yu64206112013-12-24 11:16:32 +0800200 Interest interest(interestName);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800201 interest.setInterestLifetime(1000);
Yingdi Yu64206112013-12-24 11:16:32 +0800202
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800203 OnVerified onVerified = func_lib::bind(&ContactManager::onDnsCollectEndorseVerified, this, _1, identity);
204 OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactManager::onDnsCollectEndorseVerifyFailed, this, _1, identity);
205 TimeoutNotify timeoutNotify = func_lib::bind(&ContactManager::onDnsCollectEndorseTimeoutNotify, this, identity);
Yingdi Yu64206112013-12-24 11:16:32 +0800206
207 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800208}
209
210void
Yingdi Yu64206112013-12-24 11:16:32 +0800211ContactManager::onDnsCollectEndorseTimeoutNotify(const Name& identity)
212{
213 emit collectEndorseFetchFailed (identity);
214}
215
216void
217ContactManager::onDnsCollectEndorseVerified(const shared_ptr<Data>& data, const Name& identity)
218{ emit collectEndorseFetched (*data); }
219
220void
221ContactManager::onDnsCollectEndorseVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
222{ emit collectEndorseFetchFailed (identity); }
223
224
225void
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800226ContactManager::fetchKey(const ndn::Name& certName)
227{
228 Name interestName = certName;
229
Yingdi Yu64206112013-12-24 11:16:32 +0800230 Interest interest(interestName);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800231 interest.setInterestLifetime(1000);
Yingdi Yu64206112013-12-24 11:16:32 +0800232
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800233 OnVerified onVerified = func_lib::bind(&ContactManager::onKeyVerified, this, _1, certName);
234 OnVerifyFailed onVerifyFailed = func_lib::bind(&ContactManager::onKeyVerifyFailed, this, _1, certName);
235 TimeoutNotify timeoutNotify = func_lib::bind(&ContactManager::onKeyTimeoutNotify, this, certName);
Yingdi Yu64206112013-12-24 11:16:32 +0800236
237 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
238}
239
240
241void
242ContactManager::onKeyVerified(const shared_ptr<Data>& data, const Name& identity)
243{
244 IdentityCertificate identityCertificate(*data);
245
246 Profile profile(identityCertificate);
247 ProfileData profileData(profile);
248
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800249 Name certificateName = m_keyChain->getDefaultCertificateName();
250 m_keyChain->sign(profileData, certificateName);
Yingdi Yu64206112013-12-24 11:16:32 +0800251
252 try{
253 EndorseCertificate endorseCertificate(identityCertificate, profileData);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800254 m_keyChain->sign(endorseCertificate, certificateName);
Yingdi Yu64206112013-12-24 11:16:32 +0800255 emit contactKeyFetched (endorseCertificate);
256 }catch(std::exception& e){
257 _LOG_ERROR("Exception: " << e.what());
258 return;
259 }
260}
261
262void
263ContactManager::onKeyVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
264{
265 _LOG_DEBUG("Key cannot be verified!");
266 emit contactKeyFetchFailed (identity);
267}
268
269void
270ContactManager::onKeyTimeoutNotify(const Name& identity)
271{
272 _LOG_DEBUG("Key timeout!");
273 emit contactKeyFetchFailed(identity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800274}
275
276void
Yingdi Yuaccbda92013-12-27 08:44:12 +0800277ContactManager::fetchIdCertificate(const Name& certName)
Yingdi Yu908f8412013-11-09 00:03:26 -0800278{
279 Name interestName = certName;
280
Yingdi Yu64206112013-12-24 11:16:32 +0800281 Interest interest(interestName);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800282 interest.setInterestLifetime(1000);
Yingdi Yu64206112013-12-24 11:16:32 +0800283
284 OnVerified onVerified = boost::bind(&ContactManager::onIdCertificateVerified, this, _1, certName);
285 OnVerifyFailed onVerifyFailed = boost::bind(&ContactManager::onIdCertificateVerifyFailed, this, _1, certName);
286 TimeoutNotify timeoutNotify = boost::bind(&ContactManager::onIdCertificateTimeoutNotify, this, certName);
287
288 sendInterest(interest, onVerified, onVerifyFailed, timeoutNotify);
Yingdi Yu908f8412013-11-09 00:03:26 -0800289}
290
291void
Yingdi Yu64206112013-12-24 11:16:32 +0800292ContactManager::onIdCertificateTimeoutNotify(const Name& identity)
Yingdi Yuaccbda92013-12-27 08:44:12 +0800293{
294 emit contactCertificateFetchFailed (identity);
295}
Yingdi Yu64206112013-12-24 11:16:32 +0800296
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800297
298void
Yingdi Yu64206112013-12-24 11:16:32 +0800299ContactManager::onIdCertificateVerified(const shared_ptr<Data>& data, const Name& identity)
Yingdi Yu908f8412013-11-09 00:03:26 -0800300{
301 IdentityCertificate identityCertificate(*data);
302 emit contactCertificateFetched(identityCertificate);
303}
304
305void
Yingdi Yu64206112013-12-24 11:16:32 +0800306ContactManager::onIdCertificateVerifyFailed(const shared_ptr<Data>& data, const Name& identity)
Yingdi Yuaccbda92013-12-27 08:44:12 +0800307{
308 emit contactCertificateFetchFailed (identity);
309}
Yingdi Yu908f8412013-11-09 00:03:26 -0800310
311void
Yingdi Yu64206112013-12-24 11:16:32 +0800312ContactManager::onTargetData(const shared_ptr<const ndn::Interest>& interest,
313 const shared_ptr<Data>& data,
314 int stepCount,
315 const OnVerified& onVerified,
316 const OnVerifyFailed& onVerifyFailed,
317 const TimeoutNotify& timeoutNotify)
318{
319 shared_ptr<ValidationRequest> nextStep = m_policyManager->checkVerificationPolicy(data, stepCount, onVerified, onVerifyFailed);
320
321 if (nextStep)
322 m_face->expressInterest
323 (*nextStep->interest_,
324 bind(&ContactManager::onCertData, this, _1, _2, nextStep),
325 bind(&ContactManager::onCertTimeout, this, _1, onVerifyFailed, data, nextStep));
326
327}
328
329void
330ContactManager::onTargetTimeout(const shared_ptr<const ndn::Interest>& interest,
331 int retry,
332 int stepCount,
333 const OnVerified& onVerified,
334 const OnVerifyFailed& onVerifyFailed,
335 const TimeoutNotify& timeoutNotify)
336{
337 if(retry > 0)
338 sendInterest(*interest, onVerified, onVerifyFailed, timeoutNotify, retry-1, stepCount);
339 else
340 {
341 _LOG_DEBUG("Interest: " << interest->getName().toUri() << " eventually times out!");
342 timeoutNotify();
343 }
344}
345
346void
347ContactManager::onCertData(const shared_ptr<const ndn::Interest>& interest,
348 const shared_ptr<Data>& cert,
349 shared_ptr<ValidationRequest> previousStep)
350{
351 shared_ptr<ValidationRequest> nextStep = m_policyManager->checkVerificationPolicy(cert,
352 previousStep->stepCount_,
353 previousStep->onVerified_,
354 previousStep->onVerifyFailed_);
355
356 if (nextStep)
357 m_face->expressInterest
358 (*nextStep->interest_,
359 bind(&ContactManager::onCertData, this, _1, _2, nextStep),
360 bind(&ContactManager::onCertTimeout, this, _1, previousStep->onVerifyFailed_, cert, nextStep));
361}
362
363void
364ContactManager::onCertTimeout(const shared_ptr<const ndn::Interest>& interest,
365 const OnVerifyFailed& onVerifyFailed,
366 const shared_ptr<Data>& data,
367 shared_ptr<ValidationRequest> nextStep)
368{
369 if(nextStep->retry_ > 0)
370 m_face->expressInterest(*interest,
371 bind(&ContactManager::onCertData,
372 this,
373 _1,
374 _2,
375 nextStep),
376 bind(&ContactManager::onCertTimeout,
377 this,
378 _1,
379 onVerifyFailed,
380 data,
381 nextStep));
382 else
383 onVerifyFailed(data);
384}
385
386void
387ContactManager::sendInterest(const Interest& interest,
388 const OnVerified& onVerified,
389 const OnVerifyFailed& onVerifyFailed,
390 const TimeoutNotify& timeoutNotify,
391 int retry /* = 1 */,
392 int stepCount /* = 0 */)
393{
Yingdi Yuaccbda92013-12-27 08:44:12 +0800394 uint64_t id = m_face->expressInterest(interest,
Yingdi Yu64206112013-12-24 11:16:32 +0800395 boost::bind(&ContactManager::onTargetData,
396 this,
397 _1,
398 _2,
399 stepCount,
400 onVerified,
401 onVerifyFailed,
402 timeoutNotify),
403 boost::bind(&ContactManager::onTargetTimeout,
404 this,
405 _1,
406 retry,
407 stepCount,
408 onVerified,
409 onVerifyFailed,
410 timeoutNotify));
Yingdi Yuaccbda92013-12-27 08:44:12 +0800411
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800412 // _LOG_DEBUG("id: " << id << " entry id: " << m_face->getNode().getEntryIndexForExpressedInterest(interest.getName()));
Yingdi Yu64206112013-12-24 11:16:32 +0800413}
Yingdi Yu908f8412013-11-09 00:03:26 -0800414
415void
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700416ContactManager::updateProfileData(const Name& identity)
417{
418 // Get current profile;
Yingdi Yu64206112013-12-24 11:16:32 +0800419 shared_ptr<Profile> newProfile = m_contactStorage->getSelfProfile(identity);
420 if(CHRONOCHAT_NULL_PROFILE_PTR == newProfile)
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700421 return;
Yingdi Yu64206112013-12-24 11:16:32 +0800422
423 shared_ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
424
425 if(CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR == newEndorseCertificate)
426 return;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700427
428 // Check if profile exists
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800429 try{
430 Block profileDataBlob = m_contactStorage->getSelfEndorseCertificate(identity);
Yingdi Yu64206112013-12-24 11:16:32 +0800431 m_contactStorage->updateSelfEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800432 }catch(ContactStorage::Error &e){
Yingdi Yu64206112013-12-24 11:16:32 +0800433 m_contactStorage->addSelfEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800434 }
Yingdi Yub35b8652013-11-07 11:32:40 -0800435
Yingdi Yu64206112013-12-24 11:16:32 +0800436 publishSelfEndorseCertificateInDNS(*newEndorseCertificate);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700437}
438
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800439void
440ContactManager::updateEndorseCertificate(const ndn::Name& identity, const ndn::Name& signerIdentity)
441{
Yingdi Yu64206112013-12-24 11:16:32 +0800442 shared_ptr<EndorseCertificate> newEndorseCertificate = generateEndorseCertificate(identity, signerIdentity);
443
444 if(CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR == newEndorseCertificate)
445 return;
446
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800447 try{
448 Block oldEndorseCertificateBlob = m_contactStorage->getEndorseCertificate(identity);
Yingdi Yu64206112013-12-24 11:16:32 +0800449 m_contactStorage->updateEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800450 }catch(ContactStorage::Error &e){
Yingdi Yu64206112013-12-24 11:16:32 +0800451 m_contactStorage->addEndorseCertificate(*newEndorseCertificate, identity);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800452 }
453
Yingdi Yu64206112013-12-24 11:16:32 +0800454 publishEndorseCertificateInDNS(*newEndorseCertificate, signerIdentity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800455}
456
Yingdi Yu64206112013-12-24 11:16:32 +0800457shared_ptr<EndorseCertificate>
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800458ContactManager::generateEndorseCertificate(const Name& identity, const Name& signerIdentity)
459{
Yingdi Yu64206112013-12-24 11:16:32 +0800460 shared_ptr<ContactItem> contact = getContact(identity);
461 if(contact == CHRONOCHAT_NULL_CONTACTITEM_PTR)
462 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800463
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800464 Name signerKeyName = m_keyChain->getDefaultKeyNameForIdentity(signerIdentity);
465 Name signerCertName = m_keyChain->getDefaultCertificateNameForIdentity(signerIdentity);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800466
Yingdi Yu64206112013-12-24 11:16:32 +0800467 vector<string> endorseList;
468 m_contactStorage->getEndorseList(identity, endorseList);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800469
Yingdi Yu64206112013-12-24 11:16:32 +0800470
Yingdi Yub35b8652013-11-07 11:32:40 -0800471 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800472 shared_ptr<EndorseCertificate> cert = make_shared<EndorseCertificate>(contact->getSelfEndorseCertificate(), signerKeyName, endorseList);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800473 m_keyChain->sign(*cert, signerCertName);
Yingdi Yu64206112013-12-24 11:16:32 +0800474 return cert;
475 }catch(std::exception& e){
Yingdi Yub35b8652013-11-07 11:32:40 -0800476 _LOG_ERROR("Exception: " << e.what());
Yingdi Yu64206112013-12-24 11:16:32 +0800477 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yub35b8652013-11-07 11:32:40 -0800478 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800479}
480
Yingdi Yu64206112013-12-24 11:16:32 +0800481void
482ContactManager::getContactItemList(vector<shared_ptr<ContactItem> >& contacts)
483{ return m_contactStorage->getAllContacts(contacts); }
Yingdi Yu79c25a22013-10-21 13:38:38 -0700484
Yingdi Yu64206112013-12-24 11:16:32 +0800485shared_ptr<ContactItem>
Yingdi Yud40226b2013-10-23 14:05:12 -0700486ContactManager::getContact(const ndn::Name& contactNamespace)
Yingdi Yu813d4e92013-11-03 16:22:05 -0800487{ return m_contactStorage->getContact(contactNamespace); }
Yingdi Yud40226b2013-10-23 14:05:12 -0700488
Yingdi Yu64206112013-12-24 11:16:32 +0800489shared_ptr<EndorseCertificate>
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700490ContactManager::getSignedSelfEndorseCertificate(const Name& identity,
491 const Profile& profile)
492{
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800493 Name certificateName = m_keyChain->getDefaultCertificateNameForIdentity(identity);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700494 if(0 == certificateName.size())
Yingdi Yu64206112013-12-24 11:16:32 +0800495 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700496
Yingdi Yu64206112013-12-24 11:16:32 +0800497 ProfileData profileData(profile);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800498 m_keyChain->sign(profileData, certificateName);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700499
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800500 shared_ptr<IdentityCertificate> signingCert = m_keyChain->getCertificate(certificateName);
Yingdi Yu64206112013-12-24 11:16:32 +0800501 if(CHRONOCHAT_NULL_IDENTITYCERTIFICATE_PTR == signingCert)
502 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800503
Yingdi Yu64206112013-12-24 11:16:32 +0800504 Name signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signingCert->getName());
Yingdi Yued8cfc42013-11-01 17:37:51 -0700505
Yingdi Yu64206112013-12-24 11:16:32 +0800506 shared_ptr<IdentityCertificate> kskCert;
507 if(signingKeyName.get(-1).toEscapedString().substr(0,4) == string("dsk-"))
Yingdi Yued8cfc42013-11-01 17:37:51 -0700508 {
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800509 SignatureSha256WithRsa dskCertSig(signingCert->getSignature());
Yingdi Yued8cfc42013-11-01 17:37:51 -0700510 // HACK! KSK certificate should be retrieved from network.
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800511 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(dskCertSig.getKeyLocator().getName());
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800512
Yingdi Yu64206112013-12-24 11:16:32 +0800513 // TODO: check null existing cases.
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800514 Name kskCertName = m_keyChain->getDefaultCertificateNameForIdentity(keyName.getPrefix(-1));
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800515
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800516 kskCert = m_keyChain->getCertificate(kskCertName);
Yingdi Yued8cfc42013-11-01 17:37:51 -0700517 }
518 else
519 {
520 kskCert = signingCert;
Yingdi Yued8cfc42013-11-01 17:37:51 -0700521 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700522
Yingdi Yu64206112013-12-24 11:16:32 +0800523 if(CHRONOCHAT_NULL_IDENTITYCERTIFICATE_PTR == kskCert)
524 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yu6a5b9f62013-11-06 23:00:21 -0800525
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700526 vector<string> endorseList;
527 Profile::const_iterator it = profile.begin();
528 for(; it != profile.end(); it++)
529 endorseList.push_back(it->first);
530
Yingdi Yub35b8652013-11-07 11:32:40 -0800531 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800532 shared_ptr<EndorseCertificate> selfEndorseCertificate = make_shared<EndorseCertificate>(*kskCert, profileData, endorseList);
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800533 m_keyChain->sign(*selfEndorseCertificate, kskCert->getName());
Yingdi Yu64206112013-12-24 11:16:32 +0800534
535 return selfEndorseCertificate;
536 }catch(std::exception& e){
Yingdi Yub35b8652013-11-07 11:32:40 -0800537 _LOG_ERROR("Exception: " << e.what());
Yingdi Yu64206112013-12-24 11:16:32 +0800538 return CHRONOCHAT_NULL_ENDORSECERTIFICATE_PTR;
Yingdi Yub35b8652013-11-07 11:32:40 -0800539 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700540}
541
542
543void
Yingdi Yu64206112013-12-24 11:16:32 +0800544ContactManager::publishSelfEndorseCertificateInDNS(const EndorseCertificate& selfEndorseCertificate)
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700545{
Yingdi Yu64206112013-12-24 11:16:32 +0800546 Data data;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700547
Yingdi Yu64206112013-12-24 11:16:32 +0800548 Name keyName = selfEndorseCertificate.getPublicKeyName();
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700549 Name identity = keyName.getSubName(0, keyName.size()-1);
550
Yingdi Yu64206112013-12-24 11:16:32 +0800551 time_t nowSeconds = time(NULL);
552 struct tm current = *gmtime(&nowSeconds);
553 MillisecondsSince1970 version = timegm(&current) * 1000.0;
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700554
555 Name dnsName = identity;
Yingdi Yu64206112013-12-24 11:16:32 +0800556 dnsName.append("DNS").append("PROFILE").appendVersion(version);
557 data.setName(dnsName);
558
559 data.setContent(selfEndorseCertificate.wireEncode());
560
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800561 Name signCertName = m_keyChain->getDefaultCertificateNameForIdentity(identity);
562 m_keyChain->sign(data, signCertName);
Yingdi Yu64206112013-12-24 11:16:32 +0800563
564 m_dnsStorage->updateDnsSelfProfileData(data, identity);
Yingdi Yuc29fb982013-10-20 19:43:10 -0700565
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800566 m_face->put(data);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700567}
568
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800569void
Yingdi Yu64206112013-12-24 11:16:32 +0800570ContactManager::publishEndorseCertificateInDNS(const EndorseCertificate& endorseCertificate, const Name& signerIdentity)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800571{
Yingdi Yu64206112013-12-24 11:16:32 +0800572 Data data;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800573
Yingdi Yu64206112013-12-24 11:16:32 +0800574 Name keyName = endorseCertificate.getPublicKeyName();
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800575 Name endorsee = keyName.getSubName(0, keyName.size()-1);
576
Yingdi Yu64206112013-12-24 11:16:32 +0800577 time_t nowSeconds = time(NULL);
578 struct tm current = *gmtime(&nowSeconds);
579 MillisecondsSince1970 version = timegm(&current) * 1000.0;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800580
581 Name dnsName = signerIdentity;
Yingdi Yu64206112013-12-24 11:16:32 +0800582 dnsName.append("DNS").append(endorsee).append("ENDORSEE").appendVersion(version);
583 data.setName(dnsName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800584
Yingdi Yu64206112013-12-24 11:16:32 +0800585 data.setContent(endorseCertificate.wireEncode());
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800586
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800587 Name signCertName = m_keyChain->getDefaultCertificateNameForIdentity(signerIdentity);
588 m_keyChain->sign(data, signCertName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800589
Yingdi Yu64206112013-12-24 11:16:32 +0800590 m_dnsStorage->updateDnsEndorseOthers(data, signerIdentity, endorsee);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800591
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800592 m_face->put(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800593}
594
595void
596ContactManager::publishEndorsedDataInDns(const Name& identity)
597{
Yingdi Yu64206112013-12-24 11:16:32 +0800598 Data data;
599
600 time_t nowSeconds = time(NULL);
601 struct tm current = *gmtime(&nowSeconds);
602 MillisecondsSince1970 version = timegm(&current) * 1000.0;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800603
604 Name dnsName = identity;
Yingdi Yu64206112013-12-24 11:16:32 +0800605 dnsName.append("DNS").append("ENDORSED").appendVersion(version);
606 data.setName(dnsName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800607
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800608 vector<Buffer> collectEndorseList;
Yingdi Yu64206112013-12-24 11:16:32 +0800609 m_contactStorage->getCollectEndorseList(identity, collectEndorseList);
610
611 Chronos::EndorseCollection endorseCollection;
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800612
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800613 vector<Buffer>::const_iterator it = collectEndorseList.begin();
Yingdi Yu64206112013-12-24 11:16:32 +0800614 for(; it != collectEndorseList.end(); it++)
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800615 {
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800616 string entryStr(reinterpret_cast<const char*>(it->buf()), it->size());
Yingdi Yu64206112013-12-24 11:16:32 +0800617 endorseCollection.add_endorsement()->set_blob(entryStr);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800618 }
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800619
Yingdi Yu64206112013-12-24 11:16:32 +0800620 string encoded;
621 endorseCollection.SerializeToString(&encoded);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800622
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800623 data.setContent(reinterpret_cast<const uint8_t*>(encoded.c_str()), encoded.size());
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800624
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800625 Name signCertName = m_keyChain->getDefaultCertificateNameForIdentity(identity);
626 m_keyChain->sign(data, signCertName);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800627
Yingdi Yu64206112013-12-24 11:16:32 +0800628 m_dnsStorage->updateDnsOthersEndorse(data, identity);
629
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800630 m_face->put(data);
Yingdi Yu8dacdf22013-11-05 23:06:43 -0800631}
632
Yingdi Yu908f8412013-11-09 00:03:26 -0800633void
634ContactManager::addContact(const IdentityCertificate& identityCertificate, const Profile& profile)
635{
Yingdi Yu64206112013-12-24 11:16:32 +0800636 ProfileData profileData(profile);
Yingdi Yu908f8412013-11-09 00:03:26 -0800637
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800638 Name certificateName = m_keyChain->getDefaultCertificateNameForIdentity (m_defaultIdentity);
639 m_keyChain->sign(profileData, certificateName);
Yingdi Yu908f8412013-11-09 00:03:26 -0800640
Yingdi Yu908f8412013-11-09 00:03:26 -0800641
642 try{
Yingdi Yu64206112013-12-24 11:16:32 +0800643 EndorseCertificate endorseCertificate(identityCertificate, profileData);
644
Yingdi Yuc9ffa9f2014-01-13 11:19:47 -0800645 m_keyChain->sign(endorseCertificate, certificateName);
Yingdi Yu64206112013-12-24 11:16:32 +0800646
647 ContactItem contactItem(endorseCertificate);
648
Yingdi Yu908f8412013-11-09 00:03:26 -0800649 m_contactStorage->addContact(contactItem);
Yingdi Yu64206112013-12-24 11:16:32 +0800650
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800651 emit contactAdded(contactItem.getNameSpace());
Yingdi Yu64206112013-12-24 11:16:32 +0800652
653 }catch(std::exception& e){
Yingdi Yu908f8412013-11-09 00:03:26 -0800654 emit warning(e.what());
655 _LOG_ERROR("Exception: " << e.what());
656 return;
657 }
658}
659
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800660void
661ContactManager::removeContact(const ndn::Name& contactNameSpace)
662{
Yingdi Yu64206112013-12-24 11:16:32 +0800663 shared_ptr<ContactItem> contact = getContact(contactNameSpace);
664 if(contact == CHRONOCHAT_NULL_CONTACTITEM_PTR)
Yingdi Yu6ea54e42013-11-12 17:50:21 -0800665 return;
666 m_contactStorage->removeContact(contactNameSpace);
667 emit contactRemoved(contact->getPublicKeyName());
668}
Yingdi Yu908f8412013-11-09 00:03:26 -0800669
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700670
671#if WAF
672#include "contact-manager.moc"
673#include "contact-manager.cpp.moc"
674#endif