blob: 3197d9cbcc0dafa38e1bbf4cf275afea04b99402 [file] [log] [blame]
Yingdi Yud04ed1a2013-10-14 14:07:03 -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-storage.h"
12#include "exception.h"
13
14#include <string>
15#include <boost/filesystem.hpp>
Yingdi Yu92e8e482013-10-17 21:13:03 -070016#include <ndn.cxx/fields/signature-sha256-with-rsa.h>
17#include <ndn.cxx/security/exception.h>
18#include <ndn.cxx/helpers/der/exception.h>
Yingdi Yu3b318c12013-10-15 17:54:00 -070019#include "logging.h"
Yingdi Yud04ed1a2013-10-14 14:07:03 -070020
21using namespace std;
22using namespace ndn;
23namespace fs = boost::filesystem;
24
Yingdi Yu3b318c12013-10-15 17:54:00 -070025INIT_LOGGER ("ContactStorage");
26
27const string INIT_SP_TABLE = "\
28CREATE TABLE IF NOT EXISTS \n \
29 SelfProfile( \n \
Yingdi Yu54dcecc2013-10-17 15:07:17 -070030 profile_identity BLOB NOT NULL, \n \
Yingdi Yu3b318c12013-10-15 17:54:00 -070031 profile_type BLOB NOT NULL, \n \
Yingdi Yu54dcecc2013-10-17 15:07:17 -070032 profile_value BLOB NOT NULL, \n \
33 \
34 PRIMARY KEY (profile_identity, profile_type) \n \
Yingdi Yu3b318c12013-10-15 17:54:00 -070035 ); \n \
36 \
Yingdi Yu54dcecc2013-10-17 15:07:17 -070037CREATE INDEX sp_index ON SelfProfile(profile_identity,profile_type); \n \
Yingdi Yu3b318c12013-10-15 17:54:00 -070038";
39
40const string INIT_PD_TABLE = "\
41CREATE TABLE IF NOT EXISTS \n \
42 ProfileData( \n \
43 identity BLOB NOT NULL UNIQUE, \n \
44 profile_data BLOB NOT NULL, \n \
45 \
46 PRIMARY KEY (identity) \n \
47 ); \n \
48CREATE INDEX pd_index ON ProfileData(identity); \n \
49";
Yingdi Yud04ed1a2013-10-14 14:07:03 -070050
51const string INIT_TC_TABLE = "\
52CREATE TABLE IF NOT EXISTS \n \
53 TrustedContact( \n \
54 contact_namespace BLOB NOT NULL, \n \
55 contact_alias BLOB NOT NULL, \n \
56 self_certificate BLOB NOT NULL, \n \
57 trust_scope BLOB NOT NULL, \n \
58 \
59 PRIMARY KEY (contact_namespace) \n \
60 ); \n \
61 \
62CREATE INDEX tc_index ON TrustedContact(contact_namespace); \n \
63";
64
65const string INIT_NC_TABLE = "\
66CREATE TABLE IF NOT EXISTS \n \
67 NormalContact( \n \
68 contact_namespace BLOB NOT NULL, \n \
69 contact_alias BLOB NOT NULL, \n \
70 self_certificate BLOB NOT NULL, \n \
71 \
72 PRIMARY KEY (contact_namespace) \n \
73 ); \n \
74 \
75CREATE INDEX nc_index ON NormalContact(contact_namespace); \n \
76";
77
Yingdi Yu3b318c12013-10-15 17:54:00 -070078ContactStorage::ContactStorage(Ptr<security::IdentityManager> identityManager)
79 : m_identityManager(identityManager)
Yingdi Yud04ed1a2013-10-14 14:07:03 -070080{
81 fs::path chronosDir = fs::path(getenv("HOME")) / ".chronos";
82 fs::create_directories (chronosDir);
83
84 int res = sqlite3_open((chronosDir / "chronos.db").c_str (), &m_db);
85 if (res != SQLITE_OK)
86 throw LnException("Chronos DB cannot be open/created");
87
Yingdi Yu3b318c12013-10-15 17:54:00 -070088 // Check if SelfProfile table exists
Yingdi Yud04ed1a2013-10-14 14:07:03 -070089 sqlite3_stmt *stmt;
Yingdi Yu3b318c12013-10-15 17:54:00 -070090 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='SelfProfile'", -1, &stmt, 0);
91 res = sqlite3_step (stmt);
92
93 bool spTableExist = false;
94 if (res == SQLITE_ROW)
95 spTableExist = true;
96 sqlite3_finalize (stmt);
97
98 if(!spTableExist)
99 {
100 char *errmsg = 0;
101 res = sqlite3_exec (m_db, INIT_SP_TABLE.c_str (), NULL, NULL, &errmsg);
102 if (res != SQLITE_OK && errmsg != 0)
103 throw LnException("Init \"error\" in SelfProfile");
104 }
105
106 // Check if ProfileData table exists
107 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='ProfileData'", -1, &stmt, 0);
108 res = sqlite3_step (stmt);
109
110 bool pdTableExist = false;
111 if (res == SQLITE_ROW)
112 pdTableExist = true;
113 sqlite3_finalize (stmt);
114
115 if(!pdTableExist)
116 {
117 char *errmsg = 0;
118 res = sqlite3_exec (m_db, INIT_PD_TABLE.c_str (), NULL, NULL, &errmsg);
119 if (res != SQLITE_OK && errmsg != 0)
120 throw LnException("Init \"error\" in ProfileData");
121 }
122
123
124 // Check if TrustedContact table exists
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700125 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='TrustedContact'", -1, &stmt, 0);
126 res = sqlite3_step (stmt);
127
128 bool tcTableExist = false;
129 if (res == SQLITE_ROW)
130 tcTableExist = true;
131 sqlite3_finalize (stmt);
132
133 if(!tcTableExist)
134 {
135 char *errmsg = 0;
136 res = sqlite3_exec (m_db, INIT_TC_TABLE.c_str (), NULL, NULL, &errmsg);
137 if (res != SQLITE_OK && errmsg != 0)
138 throw LnException("Init \"error\" in TrustedContact");
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700139 }
140
141 // Check if NormalContact table exists
142 sqlite3_prepare_v2 (m_db, "SELECT name FROM sqlite_master WHERE type='table' And name='NormalContact'", -1, &stmt, 0);
143 res = sqlite3_step (stmt);
144
145 bool ncTableExist = false;
146 if (res == SQLITE_ROW)
147 ncTableExist = true;
148 sqlite3_finalize (stmt);
149
150 if(!ncTableExist)
151 {
152 char *errmsg = 0;
153 res = sqlite3_exec (m_db, INIT_NC_TABLE.c_str (), NULL, NULL, &errmsg);
154
155 if (res != SQLITE_OK && errmsg != 0)
156 throw LnException("Init \"error\" in NormalContact");
157 }
158}
159
Yingdi Yu3b318c12013-10-15 17:54:00 -0700160bool
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700161ContactStorage::doesSelfEntryExist(const Name& identity, const string& profileType)
Yingdi Yu3b318c12013-10-15 17:54:00 -0700162{
163 bool result = false;
164
165 sqlite3_stmt *stmt;
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700166 sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM SelfProfile WHERE profile_type=? and profile_identity=?", -1, &stmt, 0);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700167 sqlite3_bind_text(stmt, 1, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700168 sqlite3_bind_text(stmt, 2, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700169
170 int res = sqlite3_step (stmt);
171
172 if (res == SQLITE_ROW)
173 {
174 int countAll = sqlite3_column_int (stmt, 0);
175 if (countAll > 0)
176 result = true;
177 }
178 sqlite3_finalize (stmt);
179 return result;
180}
181
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700182// void
183// ContactStorage::setSelfProfileIdentity(const Name& identity)
184// {
185// string profileType("IDENTITY");
186// Blob identityBlob(identity.toUri().c_str(), identity.toUri().size());
Yingdi Yu3b318c12013-10-15 17:54:00 -0700187
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700188// sqlite3_stmt *stmt;
189// if(doesSelfEntryExist(profileType))
190// {
191// sqlite3_prepare_v2 (m_db, "UPDATE SelfProfile SET profile_value=? WHERE profile_type=?", -1, &stmt, 0);
192// sqlite3_bind_text(stmt, 1, identityBlob.buf(), identityBlob.size(), SQLITE_TRANSIENT);
193// sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
194// }
195// else
196// {
197// sqlite3_prepare_v2 (m_db, "INSERT INTO SelfProfile (profile_type, profile_value) values (?, ?)", -1, &stmt, 0);
198// sqlite3_bind_text(stmt, 1, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
199// sqlite3_bind_text(stmt, 2, identityBlob.buf(), identityBlob.size(), SQLITE_TRANSIENT);
200// }
201// sqlite3_step (stmt);
202// sqlite3_finalize (stmt);
203// }
Yingdi Yu3b318c12013-10-15 17:54:00 -0700204
205void
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700206ContactStorage::setSelfProfileEntry(const Name& identity, const string& profileType, const Blob& profileValue)
Yingdi Yu3b318c12013-10-15 17:54:00 -0700207{
Yingdi Yu3b318c12013-10-15 17:54:00 -0700208 sqlite3_stmt *stmt;
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700209 if(doesSelfEntryExist(identity, profileType))
Yingdi Yu3b318c12013-10-15 17:54:00 -0700210 {
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700211 sqlite3_prepare_v2 (m_db, "UPDATE SelfProfile SET profile_value=? WHERE profile_type=? and profile_identity=?", -1, &stmt, 0);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700212 sqlite3_bind_text(stmt, 1, profileValue.buf(), profileValue.size(), SQLITE_TRANSIENT);
213 sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700214 sqlite3_bind_text(stmt, 3, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700215 }
216 else
217 {
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700218 sqlite3_prepare_v2 (m_db, "INSERT INTO SelfProfile (profile_identity, profile_type, profile_value) values (?, ?, ?)", -1, &stmt, 0);
219 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
220 sqlite3_bind_text(stmt, 2, profileType.c_str(), profileType.size(), SQLITE_TRANSIENT);
221 sqlite3_bind_text(stmt, 3, profileValue.buf(), profileValue.size(), SQLITE_TRANSIENT);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700222 }
223 sqlite3_step (stmt);
224 sqlite3_finalize (stmt);
225}
226
227Ptr<Profile>
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700228ContactStorage::getSelfProfile(const Name& identity)
Yingdi Yu3b318c12013-10-15 17:54:00 -0700229{
Yingdi Yu3b318c12013-10-15 17:54:00 -0700230 sqlite3_stmt *stmt;
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700231 Ptr<Profile> profile = Ptr<Profile>(new Profile(identity));
Yingdi Yu3b318c12013-10-15 17:54:00 -0700232
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700233 sqlite3_prepare_v2(m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_identity=", -1, &stmt, 0);
234 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700235
236 while( sqlite3_step (stmt) == SQLITE_ROW)
237 {
238 string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
239 Blob profileValue(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1));
240
241 profile->setProfileEntry(profileType, profileValue );
242 }
243
244 return profile;
245}
246
Yingdi Yud04ed1a2013-10-14 14:07:03 -0700247void
248ContactStorage::addTrustedContact(const TrustedContact& trustedContact)
249{
250 if(doesTrustedContactExist(trustedContact.getNameSpace()))
251 throw LnException("Trusted Contact has already existed");
252
253 sqlite3_stmt *stmt;
254 sqlite3_prepare_v2 (m_db,
255 "INSERT INTO TrustedContact (contact_namespace, contact_alias, self_certificate, trust_scope) values (?, ?, ?, ?)",
256 -1,
257 &stmt,
258 0);
259
260 sqlite3_bind_text(stmt, 1, trustedContact.getNameSpace().toUri().c_str(), trustedContact.getNameSpace().toUri().size (), SQLITE_TRANSIENT);
261 sqlite3_bind_text(stmt, 2, trustedContact.getAlias().c_str(), trustedContact.getAlias().size(), SQLITE_TRANSIENT);
262 Ptr<Blob> selfCertificateBlob = trustedContact.getSelfEndorseCertificate().encodeToWire();
263 sqlite3_bind_text(stmt, 3, selfCertificateBlob->buf(), selfCertificateBlob->size(), SQLITE_TRANSIENT);
264 Ptr<Blob> trustScopeBlob = trustedContact.getTrustScopeBlob();
265 sqlite3_bind_text(stmt, 4, trustScopeBlob->buf(), trustScopeBlob->size(),SQLITE_TRANSIENT);
266
267 int res = sqlite3_step (stmt);
268 sqlite3_finalize (stmt);
269}
270
271void
272ContactStorage::addNormalContact(const ContactItem& normalContact)
273{
274 if(doesNormalContactExist(normalContact.getNameSpace()))
275 throw LnException("Normal Contact has already existed");
276
277 sqlite3_stmt *stmt;
278 sqlite3_prepare_v2 (m_db,
279 "INSERT INTO NormalContact (contact_namespace, contact_alias, self_certificate) values (?, ?, ?)",
280 -1,
281 &stmt,
282 0);
283
284 sqlite3_bind_text(stmt, 1, normalContact.getNameSpace().toUri().c_str(), normalContact.getNameSpace().toUri().size (), SQLITE_TRANSIENT);
285 sqlite3_bind_text(stmt, 2, normalContact.getAlias().c_str(), normalContact.getAlias().size(), SQLITE_TRANSIENT);
286 Ptr<Blob> selfCertificateBlob = normalContact.getSelfEndorseCertificate().encodeToWire();
287 sqlite3_bind_text(stmt, 3, selfCertificateBlob->buf(), selfCertificateBlob->size(), SQLITE_TRANSIENT);
288
289 int res = sqlite3_step (stmt);
290 sqlite3_finalize (stmt);
291}
292
293bool
294ContactStorage::doesContactExist(const Name& name, bool normal)
295{
296 bool result = false;
297
298 sqlite3_stmt *stmt;
299 if(normal)
300 sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM NormalContact WHERE contact_namespace=?", -1, &stmt, 0);
301 else
302 sqlite3_prepare_v2 (m_db, "SELECT count(*) FROM TrustedContact WHERE contact_namespace=?", -1, &stmt, 0);
303 sqlite3_bind_text(stmt, 1, name.toUri().c_str(), name.toUri().size(), SQLITE_TRANSIENT);
304
305 int res = sqlite3_step (stmt);
306
307 if (res == SQLITE_ROW)
308 {
309 int countAll = sqlite3_column_int (stmt, 0);
310 if (countAll > 0)
311 result = true;
312 }
313 sqlite3_finalize (stmt);
314 return result;
315}
316
317vector<Ptr<TrustedContact> >
318ContactStorage::getAllTrustedContacts() const
319{
320 vector<Ptr<TrustedContact> > trustedContacts;
321
322 sqlite3_stmt *stmt;
323 sqlite3_prepare_v2 (m_db,
324 "SELECT contact_alias, self_certificate, trust_scope FROM TrustedContact",
325 -1,
326 &stmt,
327 0);
328
329 while( sqlite3_step (stmt) == SQLITE_ROW)
330 {
331 string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
332 Ptr<Blob> certBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
333 Ptr<Data> certData = Data::decodeFromWire(certBlob);
334 EndorseCertificate endorseCertificate(*certData);
335 string trustScope(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2)), sqlite3_column_bytes (stmt, 2));
336
337 trustedContacts.push_back(Ptr<TrustedContact>(new TrustedContact(endorseCertificate, trustScope, alias)));
338 }
339
340 return trustedContacts;
341}
342
343vector<Ptr<ContactItem> >
344ContactStorage::getAllNormalContacts() const
345{
346 vector<Ptr<ContactItem> > normalContacts;
347
348 sqlite3_stmt *stmt;
349 sqlite3_prepare_v2 (m_db,
350 "SELECT contact_alias, self_certificate FROM NormalContact",
351 -1,
352 &stmt,
353 0);
354
355 while( sqlite3_step (stmt) == SQLITE_ROW)
356 {
357 string alias(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
358 Ptr<Blob> certBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
359 Ptr<Data> certData = Data::decodeFromWire(certBlob);
360 EndorseCertificate endorseCertificate(*certData);
361
362 normalContacts.push_back(Ptr<ContactItem>(new ContactItem(endorseCertificate, alias)));
363 }
364
365 return normalContacts;
366}
Yingdi Yu3b318c12013-10-15 17:54:00 -0700367
368void
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700369ContactStorage::updateProfileData(const Name& identity) const
Yingdi Yu3b318c12013-10-15 17:54:00 -0700370{
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700371 // Get current profile;
372 Ptr<Profile> newProfile = getSelfProfile(identity);
373 if(NULL == newProfile)
374 return;
375 Ptr<Blob> newProfileBlob = newProfile->toDerBlob();
376
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700377 // Check if profile exists
Yingdi Yu3b318c12013-10-15 17:54:00 -0700378 sqlite3_stmt *stmt;
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700379 sqlite3_prepare_v2 (m_db, "SELECT profile_data FROM ProfileData where identity=?", -1, &stmt, 0);
380 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700381
382 if(sqlite3_step (stmt) != SQLITE_ROW)
383 {
384 sqlite3_finalize (stmt);
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700385
Yingdi Yu92e8e482013-10-17 21:13:03 -0700386 Ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700387 _LOG_DEBUG("Signing DONE!");
Yingdi Yu92e8e482013-10-17 21:13:03 -0700388 if(NULL == newEndorseCertificate)
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700389 return;
Yingdi Yu92e8e482013-10-17 21:13:03 -0700390 Ptr<Blob> newEndorseCertificateBlob = newEndorseCertificate->encodeToWire();
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700391
392 _LOG_DEBUG("Before Inserting!");
393
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700394 sqlite3_prepare_v2 (m_db, "INSERT INTO ProfileData (identity, profile_data) values (?, ?)", -1, &stmt, 0);
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700395 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu92e8e482013-10-17 21:13:03 -0700396 sqlite3_bind_text(stmt, 2, newEndorseCertificateBlob->buf(), newEndorseCertificateBlob->size(), SQLITE_TRANSIENT);
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700397 sqlite3_step(stmt);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700398 }
399 else
400 {
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700401 Ptr<Blob> profileDataBlob = Ptr<Blob>(new Blob(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
402 Ptr<Data> plainData = Data::decodeFromWire(profileDataBlob);
Yingdi Yu92e8e482013-10-17 21:13:03 -0700403 EndorseCertificate oldEndorseCertificate(*plainData);
404 // _LOG_DEBUG("Certificate converted!");
405 const Blob& oldProfileBlob = oldEndorseCertificate.getProfileData()->content();
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700406 sqlite3_finalize (stmt);
407
408 if(oldProfileBlob == *newProfileBlob)
409 return;
410
Yingdi Yu92e8e482013-10-17 21:13:03 -0700411 Ptr<EndorseCertificate> newEndorseCertificate = getSignedSelfEndorseCertificate(identity, *newProfile);
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700412 _LOG_DEBUG("Signing DONE!");
Yingdi Yu92e8e482013-10-17 21:13:03 -0700413 if(NULL == newEndorseCertificate)
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700414 return;
Yingdi Yu92e8e482013-10-17 21:13:03 -0700415 Ptr<Blob> newEndorseCertificateBlob = newEndorseCertificate->encodeToWire();
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700416
417 _LOG_DEBUG("Before Updating!");
418
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700419 sqlite3_prepare_v2 (m_db, "UPDATE ProfileData SET profile_data=? WHERE identity=?", -1, &stmt, 0);
Yingdi Yu92e8e482013-10-17 21:13:03 -0700420 sqlite3_bind_text(stmt, 1, newEndorseCertificateBlob->buf(), newEndorseCertificateBlob->size(), SQLITE_TRANSIENT);
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700421 sqlite3_bind_text(stmt, 2, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu8f7325a2013-10-17 17:03:46 -0700422 sqlite3_step(stmt);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700423 }
424}
425
426Ptr<Profile>
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700427ContactStorage::getSelfProfile(const Name& identity) const
428{
Yingdi Yu3b318c12013-10-15 17:54:00 -0700429 Ptr<Profile> profile = Ptr<Profile>(new Profile(identity));
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700430 sqlite3_stmt *stmt;
431 sqlite3_prepare_v2 (m_db, "SELECT profile_type, profile_value FROM SelfProfile WHERE profile_identity=?", -1, &stmt, 0);
432 sqlite3_bind_text (stmt, 1, identity.toUri().c_str(), identity.toUri().size(), SQLITE_TRANSIENT);
Yingdi Yu3b318c12013-10-15 17:54:00 -0700433
434 while( sqlite3_step (stmt) == SQLITE_ROW)
435 {
436 string profileType(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0));
437 Blob profileValue(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1));
438 profile->setProfileEntry(profileType, profileValue);
439 }
440
441 return profile;
442}
443
Yingdi Yu92e8e482013-10-17 21:13:03 -0700444Ptr<EndorseCertificate>
445ContactStorage::getSignedSelfEndorseCertificate(const Name& identity,
446 const Profile& profile) const
Yingdi Yu3b318c12013-10-15 17:54:00 -0700447{
448 Name certificateName = m_identityManager->getDefaultCertificateNameByIdentity(identity);
Yingdi Yu54dcecc2013-10-17 15:07:17 -0700449 if(0 == certificateName.size())
450 return NULL;
451
Yingdi Yu3b318c12013-10-15 17:54:00 -0700452 Ptr<ProfileData> profileData = Ptr<ProfileData>(new ProfileData(identity, profile));
453 m_identityManager->signByCertificate(*profileData, certificateName);
454
Yingdi Yu92e8e482013-10-17 21:13:03 -0700455 Ptr<security::IdentityCertificate> dskCert = m_identityManager->getCertificate(certificateName);
456 Ptr<const signature::Sha256WithRsa> dskCertSig = boost::dynamic_pointer_cast<const signature::Sha256WithRsa>(dskCert->getSignature());
Yingdi Yu9236c432013-10-18 11:29:25 -0700457 // HACK! KSK certificate should be retrieved from network.
Yingdi Yu92e8e482013-10-17 21:13:03 -0700458 Ptr<security::IdentityCertificate> kskCert = m_identityManager->getCertificate(dskCertSig->getKeyLocator().getKeyName());
459
460 vector<string> endorseList;
461 Profile::const_iterator it = profile.begin();
462 for(; it != profile.end(); it++)
463 endorseList.push_back(it->first);
464
465 Ptr<EndorseCertificate> selfEndorseCertificate = Ptr<EndorseCertificate>(new EndorseCertificate(*kskCert,
466 kskCert->getNotBefore(),
467 kskCert->getNotAfter(),
468 profileData,
469 endorseList));
470 m_identityManager->signByCertificate(*selfEndorseCertificate, kskCert->getName());
471
472 return selfEndorseCertificate;
Yingdi Yu3b318c12013-10-15 17:54:00 -0700473}
474