blob: 2c30921ab897e71b3df5ad729269f24b2190706b [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 Yu0b82a4e2013-10-18 11:29:25 -070014#include <ndn.cxx/wrapper/wrapper.h>
15#include <ndn.cxx/security/keychain.h>
16#include <ndn.cxx/security/identity/basic-identity-storage.h>
17#include <ndn.cxx/security/identity/osx-privatekey-storage.h>
18#include <ndn.cxx/security/policy/simple-policy-manager.h>
19#include <ndn.cxx/security/policy/identity-policy-rule.h>
20#include <ndn.cxx/security/cache/ttl-certificate-cache.h>
21#include <ndn.cxx/security/encryption/basic-encryption-manager.h>
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070022#include <fstream>
Yingdi Yu590fa5d2013-10-18 18:35:09 -070023#include "logging.h"
Yingdi Yuaa8d7692013-10-18 17:05:02 -070024#endif
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070025
26using namespace ndn;
27using namespace ndn::security;
28
Yingdi Yu590fa5d2013-10-18 18:35:09 -070029INIT_LOGGER("ContactManager");
30
Yingdi Yuaa8d7692013-10-18 17:05:02 -070031ContactManager::ContactManager(Ptr<ContactStorage> contactStorage,
Yingdi Yu590fa5d2013-10-18 18:35:09 -070032 Ptr<DnsStorage> dnsStorage,
33 QObject* parent)
34 : QObject(parent)
35 , m_contactStorage(contactStorage)
Yingdi Yuaa8d7692013-10-18 17:05:02 -070036 , m_dnsStorage(dnsStorage)
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070037{
Yingdi Yuaa8d7692013-10-18 17:05:02 -070038 setKeychain();
39
40 m_wrapper = Ptr<Wrapper>(new Wrapper(m_keychain));
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070041}
42
43ContactManager::~ContactManager()
44{
45}
46
Yingdi Yuaa8d7692013-10-18 17:05:02 -070047void
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070048ContactManager::setKeychain()
49{
50 Ptr<OSXPrivatekeyStorage> privateStorage = Ptr<OSXPrivatekeyStorage>::Create();
51 Ptr<IdentityManager> identityManager = Ptr<IdentityManager>(new IdentityManager(Ptr<BasicIdentityStorage>::Create(), privateStorage));
52 Ptr<TTLCertificateCache> certificateCache = Ptr<TTLCertificateCache>(new TTLCertificateCache());
53 Ptr<SimplePolicyManager> policyManager = Ptr<SimplePolicyManager>(new SimplePolicyManager(10, certificateCache));
54 Ptr<EncryptionManager> encryptionManager = Ptr<EncryptionManager>(new BasicEncryptionManager(privateStorage, "/tmp/encryption.db"));
55 Ptr<Keychain> keychain = Ptr<Keychain>(new Keychain(identityManager, policyManager, encryptionManager));
56
Yingdi Yuaa8d7692013-10-18 17:05:02 -070057 policyManager->addVerificationPolicyRule(Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<DNS>]*)<DNS><PROFILE>",
Yingdi Yued8cfc42013-11-01 17:37:51 -070058 "^([^<KEY>]*)<KEY>(<>*)[<ksk-.*><dsk-.*>]<ID-CERT>$",
Yingdi Yuaa8d7692013-10-18 17:05:02 -070059 "==", "\\1", "\\1\\2", true)));
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070060 policyManager->addVerificationPolicyRule(Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<PROFILE-CERT>]*)<PROFILE-CERT>",
Yingdi Yued8cfc42013-11-01 17:37:51 -070061 "^([^<KEY>]*)<KEY>(<>*<ksk-.*>)<ID-CERT>$",
Yingdi Yuaa8d7692013-10-18 17:05:02 -070062 "==", "\\1", "\\1\\2", true)));
Yingdi Yu42f66462013-10-31 17:38:22 -070063 policyManager->addVerificationPolicyRule(Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>",
Yingdi Yued8cfc42013-11-01 17:37:51 -070064 "^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>$",
Yingdi Yuaa8d7692013-10-18 17:05:02 -070065 ">", "\\1\\2", "\\1", true)));
Yingdi Yu42f66462013-10-31 17:38:22 -070066 policyManager->addVerificationPolicyRule(Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<KEY>]*)<KEY><dsk-.*><ID-CERT>",
Yingdi Yued8cfc42013-11-01 17:37:51 -070067 "^([^<KEY>]*)<KEY>(<>*)<ksk-.*><ID-CERT>$",
Yingdi Yuaa8d7692013-10-18 17:05:02 -070068 "==", "\\1", "\\1\\2", true)));
69
70 policyManager->addSigningPolicyRule(Ptr<IdentityPolicyRule>(new IdentityPolicyRule("^([^<DNS>]*)<DNS><PROFILE>",
71 "^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>",
72 "==", "\\1", "\\1\\2", true)));
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070073
74 ifstream is ("trust-anchor.data", ios::binary);
75 is.seekg (0, ios::end);
76 ifstream::pos_type size = is.tellg();
77 char * memblock = new char [size];
78 is.seekg (0, ios::beg);
79 is.read (memblock, size);
80 is.close();
81
82 Ptr<Blob> readBlob = Ptr<Blob>(new Blob(memblock, size));
83 Ptr<Data> readData = Data::decodeFromWire (readBlob);
84 Ptr<IdentityCertificate> anchor = Ptr<IdentityCertificate>(new IdentityCertificate(*readData));
85 policyManager->addTrustAnchor(anchor);
86
87 delete memblock;
88
Yingdi Yuaa8d7692013-10-18 17:05:02 -070089 m_keychain = keychain;
Yingdi Yu0b82a4e2013-10-18 11:29:25 -070090}
Yingdi Yuaa8d7692013-10-18 17:05:02 -070091
92
93void
94ContactManager::fetchSelfEndorseCertificate(const ndn::Name& identity)
95{
96 Name interestName = identity;
97 interestName.append("DNS").append("PROFILE");
98
99 Ptr<Interest> interestPtr = Ptr<Interest>(new Interest(interestName));
Yingdi Yu42f66462013-10-31 17:38:22 -0700100 interestPtr->setChildSelector(Interest::CHILD_RIGHT);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700101 Ptr<Closure> closure = Ptr<Closure> (new Closure(boost::bind(&ContactManager::onDnsSelfEndorseCertificateVerified,
102 this,
103 _1,
104 identity),
105 boost::bind(&ContactManager::onDnsSelfEndorseCertificateTimeout,
106 this,
107 _1,
108 _2,
109 identity,
110 0),
111 boost::bind(&ContactManager::onDnsSelfEndorseCertificateUnverified,
112 this,
113 _1,
114 identity)));
115 m_wrapper->sendInterest(interestPtr, closure);
116}
117
118void
119ContactManager::updateProfileData(const Name& identity)
120{
Yingdi Yued8cfc42013-11-01 17:37:51 -0700121 _LOG_DEBUG("updateProfileData: " << identity.toUri());
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700122 // Get current profile;
123 Ptr<Profile> newProfile = m_contactStorage->getSelfProfile(identity);
124 if(NULL == newProfile)
125 return;
126 Ptr<Blob> newProfileBlob = newProfile->toDerBlob();
127
128 // Check if profile exists
129 Ptr<Blob> profileDataBlob = m_contactStorage->getSelfEndorseCertificate(identity);
130 if(NULL != profileDataBlob)
131 {
132 Ptr<Data> plainData = Data::decodeFromWire(profileDataBlob);
133 EndorseCertificate oldEndorseCertificate(*plainData);
134 // _LOG_DEBUG("Certificate converted!");
135 const Blob& oldProfileBlob = oldEndorseCertificate.getProfileData()->content();
136
137 if(oldProfileBlob == *newProfileBlob)
138 return;
139
140 Ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
141 // _LOG_DEBUG("Signing DONE!");
142 if(NULL == newEndorseCertificate)
143 return;
Yingdi Yu590fa5d2013-10-18 18:35:09 -0700144 _LOG_DEBUG("About to update");
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700145 m_contactStorage->updateSelfEndorseCertificate(newEndorseCertificate, identity);
146
147 publishSelfEndorseCertificateInDNS(newEndorseCertificate);
148 }
149 else
150 {
151 Ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
152 // _LOG_DEBUG("Signing DONE!");
153 if(NULL == newEndorseCertificate)
154 return;
Yingdi Yu590fa5d2013-10-18 18:35:09 -0700155 _LOG_DEBUG("About to Insert");
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700156 m_contactStorage->addSelfEndorseCertificate(newEndorseCertificate, identity);
157
158 publishSelfEndorseCertificateInDNS(newEndorseCertificate);
159 }
160}
161
Yingdi Yu79c25a22013-10-21 13:38:38 -0700162vector<Ptr<ContactItem> >
163ContactManager::getContactItemList()
Yingdi Yu813d4e92013-11-03 16:22:05 -0800164{ return m_contactStorage->getAllContacts(); }
Yingdi Yu79c25a22013-10-21 13:38:38 -0700165
Yingdi Yud40226b2013-10-23 14:05:12 -0700166Ptr<ContactItem>
167ContactManager::getContact(const ndn::Name& contactNamespace)
Yingdi Yu813d4e92013-11-03 16:22:05 -0800168{ return m_contactStorage->getContact(contactNamespace); }
Yingdi Yud40226b2013-10-23 14:05:12 -0700169
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700170Ptr<EndorseCertificate>
171ContactManager::getSignedSelfEndorseCertificate(const Name& identity,
172 const Profile& profile)
173{
174 Ptr<IdentityManager> identityManager = m_keychain->getIdentityManager();
175 Name certificateName = identityManager->getDefaultCertificateNameByIdentity(identity);
176 if(0 == certificateName.size())
177 return NULL;
178
179 Ptr<ProfileData> profileData = Ptr<ProfileData>(new ProfileData(identity, profile));
180 identityManager->signByCertificate(*profileData, certificateName);
181
Yingdi Yued8cfc42013-11-01 17:37:51 -0700182 Ptr<security::IdentityCertificate> signingCert = identityManager->getCertificate(certificateName);
183 Name signingKeyName = security::IdentityCertificate::certificateNameToPublicKeyName(signingCert->getName(), true);
184
185 Ptr<security::IdentityCertificate> kskCert;
186 if(signingKeyName.get(-1).toUri().substr(0,4) == string("dsk-"))
187 {
188 Ptr<const signature::Sha256WithRsa> dskCertSig = DynamicCast<const signature::Sha256WithRsa>(signingCert->getSignature());
189 // HACK! KSK certificate should be retrieved from network.
190 _LOG_DEBUG("keyLocator: " << dskCertSig->getKeyLocator().getKeyName());
191 Name keyName = security::IdentityCertificate::certificateNameToPublicKeyName(dskCertSig->getKeyLocator().getKeyName());
192 _LOG_DEBUG("keyName: " << keyName.toUri());
193 Name kskCertName = identityManager->getPublicStorage()->getDefaultCertificateNameForKey(keyName);
194 _LOG_DEBUG("ksk cert name: " << kskCertName);
195 kskCert = identityManager->getCertificate(kskCertName);
196
197 }
198 else
199 {
200 kskCert = signingCert;
201 _LOG_DEBUG("ksk cert name: " << kskCert->getName().toUri());
202 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700203
204 vector<string> endorseList;
205 Profile::const_iterator it = profile.begin();
206 for(; it != profile.end(); it++)
207 endorseList.push_back(it->first);
208
209 Ptr<EndorseCertificate> selfEndorseCertificate = Ptr<EndorseCertificate>(new EndorseCertificate(*kskCert,
210 kskCert->getNotBefore(),
211 kskCert->getNotAfter(),
212 profileData,
213 endorseList));
214 identityManager->signByCertificate(*selfEndorseCertificate, kskCert->getName());
215
216 return selfEndorseCertificate;
217}
218
219
220void
221ContactManager::onDnsSelfEndorseCertificateVerified(Ptr<Data> data, const Name& identity)
222{
Yingdi Yuc29fb982013-10-20 19:43:10 -0700223 Ptr<Blob> dataContentBlob = Ptr<Blob>(new Blob(data->content().buf(), data->content().size()));
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700224
Yingdi Yuc29fb982013-10-20 19:43:10 -0700225 Ptr<Data> plainData = Data::decodeFromWire(dataContentBlob);
226
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700227 Ptr<EndorseCertificate> selfEndorseCertificate = Ptr<EndorseCertificate>(new EndorseCertificate(*plainData));
Yingdi Yuc29fb982013-10-20 19:43:10 -0700228
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700229 const security::Publickey& ksk = selfEndorseCertificate->getPublicKeyInfo();
Yingdi Yuc29fb982013-10-20 19:43:10 -0700230
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700231 if(security::PolicyManager::verifySignature(*plainData, ksk))
Yingdi Yuc29fb982013-10-20 19:43:10 -0700232 {
Yingdi Yu79c25a22013-10-21 13:38:38 -0700233 // Profile profile = selfEndorseCertificate->getProfileData()->getProfile();
234 // Profile::const_iterator it = profile.getEntries().begin();
235 // it++;
236 // _LOG_DEBUG("Entry Size: " << it->first);
237
Yingdi Yuc29fb982013-10-20 19:43:10 -0700238 emit contactFetched (*selfEndorseCertificate);
239 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700240 else
Yingdi Yuc29fb982013-10-20 19:43:10 -0700241 {
242 emit contactFetchFailed (identity);
243 }
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700244}
245
246void
247ContactManager::onDnsSelfEndorseCertificateUnverified(Ptr<Data> data, const Name& identity)
248{ emit contactFetchFailed (identity); }
249
250void
251ContactManager::onDnsSelfEndorseCertificateTimeout(Ptr<Closure> closure, Ptr<Interest> interest, const Name& identity, int retry)
252{
253 if(retry > 0)
254 {
255 Ptr<Closure> newClosure = Ptr<Closure>(new Closure(closure->m_dataCallback,
256 boost::bind(&ContactManager::onDnsSelfEndorseCertificateTimeout,
257 this,
258 _1,
259 _2,
260 identity,
261 retry - 1),
262 closure->m_unverifiedCallback,
263 closure->m_stepCount)
264 );
265 m_wrapper->sendInterest(interest, newClosure);
266 }
267 else
268 emit contactFetchFailed(identity);
269}
270
271void
272ContactManager::publishSelfEndorseCertificateInDNS(Ptr<EndorseCertificate> selfEndorseCertificate)
273{
274 Ptr<Data> data = Ptr<Data>::Create();
275
276 Name keyName = selfEndorseCertificate->getPublicKeyName();
277 Name identity = keyName.getSubName(0, keyName.size()-1);
278
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700279
280 Name dnsName = identity;
Yingdi Yu42f66462013-10-31 17:38:22 -0700281 dnsName.append("DNS").append("PROFILE").appendVersion();
Yingdi Yuc29fb982013-10-20 19:43:10 -0700282
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700283 data->setName(dnsName);
284 Ptr<Blob> blob = selfEndorseCertificate->encodeToWire();
Yingdi Yuc29fb982013-10-20 19:43:10 -0700285
286 // string encoded;
287 // CryptoPP::StringSource ss(reinterpret_cast<const unsigned char *>(blob->buf()), blob->size(), true,
288 // new CryptoPP::Base64Encoder(new CryptoPP::StringSink(encoded), false));
289
290 // Content content(encoded.c_str(), encoded.size());
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700291 Content content(blob->buf(), blob->size());
292 data->setContent(content);
293
294 m_keychain->signByIdentity(*data, identity);
Yingdi Yu590fa5d2013-10-18 18:35:09 -0700295
296 m_dnsStorage->updateDnsSelfProfileData(*data, identity);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700297
298 Ptr<Blob> dnsBlob = data->encodeToWire();
299
Yingdi Yuc4d08d22013-10-23 23:07:29 -0700300 m_wrapper->putToNdnd(*dnsBlob);
Yingdi Yuaa8d7692013-10-18 17:05:02 -0700301}
302
303
304#if WAF
305#include "contact-manager.moc"
306#include "contact-manager.cpp.moc"
307#endif