blob: 85af9a96948ec3929c01194040a15c6f78efbb66 [file] [log] [blame]
Jeff Thompson7ca11f22013-10-04 19:01:30 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2/**
3 * Copyright (C) 2013 Regents of the University of California.
4 * @author: Yingdi Yu <yingdi@cs.ucla.edu>
Jeff Thompson22285ec2013-10-22 17:43:02 -07005 * @author: Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson7ca11f22013-10-04 19:01:30 -07006 * See COPYING for copyright and distribution information.
7 */
8
Jeff Thompsonb7523002013-10-09 10:25:00 -07009// Only compile if ndn-cpp-config.h defines NDN_CPP_HAVE_SQLITE3.
Jeff Thompson6e229042013-10-10 11:09:49 -070010#include <ndn-cpp/ndn-cpp-config.h>
Jeff Thompson1975def2013-10-09 17:06:43 -070011#ifdef NDN_CPP_HAVE_SQLITE3
Jeff Thompson7ca11f22013-10-04 19:01:30 -070012
Jeff Thompson351ac302013-10-19 18:45:00 -070013#include <stdio.h>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070014#include <stdlib.h>
15#include <sstream>
16#include <fstream>
Jeff Thompson3bd90bc2013-10-19 16:40:14 -070017#include <math.h>
Jeff Thompson25b4e612013-10-10 16:03:24 -070018#include <ndn-cpp/security/identity/basic-identity-storage.hpp>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070019#include "../../util/logging.hpp"
Jeff Thompson3bd90bc2013-10-19 16:40:14 -070020#include <ndn-cpp/security/security-exception.hpp>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070021#include "ndn-cpp/data.hpp"
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -070022#include <ndn-cpp/security/certificate/identity-certificate.hpp>
Jeff Thompson3bd90bc2013-10-19 16:40:14 -070023#include "../../c/util/time.h"
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -070024#include <ndn-cpp/sha256-with-rsa-signature.hpp>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070025
26INIT_LOGGER("BasicIdentityStorage");
27
28using namespace std;
29using namespace ndn::ptr_lib;
Jeff Thompson7ca11f22013-10-04 19:01:30 -070030
31namespace ndn
32{
33
34static const string INIT_ID_TABLE = "\
35CREATE TABLE IF NOT EXISTS \n \
36 Identity( \n \
37 identity_name BLOB NOT NULL, \n \
38 default_identity INTEGER DEFAULT 0, \n \
39 \
40 PRIMARY KEY (identity_name) \n \
41 ); \n \
42 \
43CREATE INDEX identity_index ON Identity(identity_name); \n \
44";
45
46static const string INIT_KEY_TABLE = "\
47CREATE TABLE IF NOT EXISTS \n \
48 Key( \n \
49 identity_name BLOB NOT NULL, \n \
50 key_identifier BLOB NOT NULL, \n \
51 key_type INTEGER, \n \
52 public_key BLOB, \n \
53 default_key INTEGER DEFAULT 0, \n \
54 active INTEGER DEFAULT 0, \n \
55 \
56 PRIMARY KEY (identity_name, key_identifier) \n \
57 ); \n \
58 \
59CREATE INDEX key_index ON Key(identity_name); \n \
60";
61
62static const string INIT_CERT_TABLE = "\
63CREATE TABLE IF NOT EXISTS \n \
64 Certificate( \n \
65 cert_name BLOB NOT NULL, \n \
66 cert_issuer BLOB NOT NULL, \n \
67 identity_name BLOB NOT NULL, \n \
68 key_identifier BLOB NOT NULL, \n \
69 not_before TIMESTAMP, \n \
70 not_after TIMESTAMP, \n \
71 certificate_data BLOB NOT NULL, \n \
Jeff Thompson22285ec2013-10-22 17:43:02 -070072 valid_flag INTEGER DEFAULT 1, \n \
Jeff Thompson7ca11f22013-10-04 19:01:30 -070073 default_cert INTEGER DEFAULT 0, \n \
74 \
75 PRIMARY KEY (cert_name) \n \
76 ); \n \
77 \
78CREATE INDEX cert_index ON Certificate(cert_name); \n \
79CREATE INDEX subject ON Certificate(identity_name); \n \
80";
81
82/**
83 * A utility function to call the normal sqlite3_bind_text where the value and length are value.c_str() and value.size().
84 */
85static int sqlite3_bind_text(sqlite3_stmt* statement, int index, const string& value, void(*destructor)(void*))
86{
87 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
88}
89
90BasicIdentityStorage::BasicIdentityStorage()
91{
Jeff Thompson351ac302013-10-19 18:45:00 -070092 // Note: We don't use <filesystem> support because it is not "header-only" and require linking to libraries.
Jeff Thompsonab5440f2013-10-22 11:54:00 -070093 // TODO: Handle non-unix file system paths which don't use '/'.
Jeff Thompson351ac302013-10-19 18:45:00 -070094 const char* home = getenv("HOME");
95 if (!home || *home == '\0')
96 // Don't expect this to happen;
97 home = ".";
98 string homeDir(home);
99 if (homeDir[homeDir.size() - 1] == '/')
100 // Strip the ending '/'.
101 homeDir.erase(homeDir.size() - 1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700102
Jeff Thompsonac64b132013-11-25 15:04:53 -0800103 string identityDir = homeDir + '/' + ".ndnx";
104 // TODO: Handle non-unix file systems which don't have "mkdir -p".
Jeff Thompsonab5440f2013-10-22 11:54:00 -0700105 ::system(("mkdir -p " + identityDir).c_str());
Jeff Thompson351ac302013-10-19 18:45:00 -0700106
Jeff Thompsonac64b132013-11-25 15:04:53 -0800107 int res = sqlite3_open((identityDir + '/' + "ndnsec-identity.db").c_str(), &database_);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700108
109 if (res != SQLITE_OK)
Jeff Thompson351ac302013-10-19 18:45:00 -0700110 throw SecurityException("identity DB cannot be opened/created");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700111
112 //Check if Key table exists;
113 sqlite3_stmt *statement;
114 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Identity'", -1, &statement, 0);
Jeff Thompson351ac302013-10-19 18:45:00 -0700115 res = sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700116
117 bool idTableExists = false;
118 if (res == SQLITE_ROW)
119 idTableExists = true;
120
121 sqlite3_finalize(statement);
122
123 if (!idTableExists) {
124 char *errorMessage = 0;
125 res = sqlite3_exec(database_, INIT_ID_TABLE.c_str(), NULL, NULL, &errorMessage);
126
127 if (res != SQLITE_OK && errorMessage != 0) {
128 _LOG_TRACE("Init \"error\" in Identity: " << errorMessage);
129 sqlite3_free(errorMessage);
130 }
131 }
132
133 //Check if Key table exists;
134 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Key'", -1, &statement, 0);
135 res = sqlite3_step(statement);
136
137 bool keyTableExists = false;
138 if (res == SQLITE_ROW)
139 keyTableExists = true;
140
141 sqlite3_finalize(statement);
142
143 if (!keyTableExists) {
144 char *errorMessage = 0;
145 res = sqlite3_exec(database_, INIT_KEY_TABLE.c_str(), NULL, NULL, &errorMessage);
146
147 if (res != SQLITE_OK && errorMessage != 0) {
148 _LOG_TRACE("Init \"error\" in KEY: " << errorMessage);
149 sqlite3_free(errorMessage);
150 }
151 }
152
153 //Check if Certificate table exists;
154 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'", -1, &statement, 0);
155 res = sqlite3_step(statement);
156
157 bool idCertificateTableExists = false;
158 if (res == SQLITE_ROW)
159 idCertificateTableExists = true;
160
161 sqlite3_finalize(statement);
162
163 if (!idCertificateTableExists) {
164 char *errorMessage = 0;
165 res = sqlite3_exec(database_, INIT_CERT_TABLE.c_str(), NULL, NULL, &errorMessage);
166
167 if (res != SQLITE_OK && errorMessage != 0) {
168 _LOG_TRACE("Init \"error\" in ID-CERT: " << errorMessage);
169 sqlite3_free(errorMessage);
170 }
171 }
172}
173
174BasicIdentityStorage::~BasicIdentityStorage()
175{
176}
177
178bool
179BasicIdentityStorage::doesIdentityExist(const Name& identityName)
180{
181 bool result = false;
182
183 sqlite3_stmt *statement;
184 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Identity WHERE identity_name=?", -1, &statement, 0);
185
186 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
187 int res = sqlite3_step(statement);
188
189 if (res == SQLITE_ROW) {
190 int countAll = sqlite3_column_int(statement, 0);
191 if (countAll > 0)
192 result = true;
193 }
194
195 sqlite3_finalize(statement);
196
197 return result;
198}
199
200void
201BasicIdentityStorage::addIdentity(const Name& identityName)
202{
203 if (doesIdentityExist(identityName))
204 throw SecurityException("Identity already exists");
205
206 sqlite3_stmt *statement;
207
208 sqlite3_prepare_v2(database_, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
209
210 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
211
212 int res = sqlite3_step(statement);
213
214 sqlite3_finalize(statement);
215}
216
217bool
218BasicIdentityStorage::revokeIdentity()
219{
220 //TODO:
221 return false;
222}
223
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700224bool
225BasicIdentityStorage::doesKeyExist(const Name& keyName)
226{
227 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
228 Name identityName = keyName.getSubName(0, keyName.size() - 1);
229
230 sqlite3_stmt *statement;
231 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
232
233 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
234 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
235
236 int res = sqlite3_step(statement);
237
238 bool keyIdExist = false;
239 if (res == SQLITE_ROW) {
240 int countAll = sqlite3_column_int(statement, 0);
241 if (countAll > 0)
242 keyIdExist = true;
243 }
244
245 sqlite3_finalize(statement);
246
247 return keyIdExist;
248}
249
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700250void
251BasicIdentityStorage::addKey(const Name& keyName, KeyType keyType, const Blob& publicKeyDer)
252{
253 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
254 Name identityName = keyName.getSubName(0, keyName.size() - 1);
255
256
257 if (!doesIdentityExist(identityName))
258 addIdentity(identityName);
259
260 if (doesKeyExist(keyName))
261 throw SecurityException("a key with the same name already exists!");
262
263 sqlite3_stmt *statement;
264 sqlite3_prepare_v2(database_, "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
265
266 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
267 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
268 sqlite3_bind_int(statement, 3, (int)keyType);
269 sqlite3_bind_blob(statement, 4, publicKeyDer.buf(), publicKeyDer.size(), SQLITE_TRANSIENT);
270
271 int res = sqlite3_step(statement);
272
273 sqlite3_finalize(statement);
274}
275
276Blob
277BasicIdentityStorage::getKey(const Name& keyName)
278{
279 if (!doesKeyExist(keyName)) {
280 _LOG_DEBUG("keyName does not exist");
281 return Blob();
282 }
283
284 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
285 Name identityName = keyName.getSubName(0, keyName.size() - 1);
286
287 sqlite3_stmt *statement;
288 sqlite3_prepare_v2(database_, "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
289
290 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
291 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
292
293 int res = sqlite3_step(statement);
294
295 Blob result;
296 if (res == SQLITE_ROW)
297 result = Blob(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)), sqlite3_column_bytes(statement, 0));
298
299 sqlite3_finalize(statement);
300
301 return result;
302}
303
304void
305BasicIdentityStorage::activateKey(const Name& keyName)
306{
307 updateKeyStatus(keyName, true);
308}
309
310void
311BasicIdentityStorage::deactivateKey(const Name& keyName)
312{
313 updateKeyStatus(keyName, false);
314}
315
316void
317BasicIdentityStorage::updateKeyStatus(const Name& keyName, bool isActive)
318{
319 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
320 Name identityName = keyName.getSubName(0, keyName.size() - 1);
321
322 sqlite3_stmt *statement;
323 sqlite3_prepare_v2(database_, "UPDATE Key SET active=? WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
324
325 sqlite3_bind_int(statement, 1, (isActive ? 1 : 0));
326 sqlite3_bind_text(statement, 2, identityName.toUri(), SQLITE_TRANSIENT);
327 sqlite3_bind_text(statement, 3, keyId, SQLITE_TRANSIENT);
328
329 int res = sqlite3_step(statement);
330
331 sqlite3_finalize(statement);
332}
333
334bool
335BasicIdentityStorage::doesCertificateExist(const Name& certificateName)
336{
337 sqlite3_stmt *statement;
338 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Certificate WHERE cert_name=?", -1, &statement, 0);
339
340 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
341
342 int res = sqlite3_step(statement);
343
344 bool certExist = false;
345 if (res == SQLITE_ROW) {
346 int countAll = sqlite3_column_int(statement, 0);
347 if (countAll > 0)
348 certExist = true;
349 }
350
351 sqlite3_finalize(statement);
352
353 return certExist;
354}
355
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700356void
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700357BasicIdentityStorage::addAnyCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700358{
359 const Name& certificateName = certificate.getName();
Jeff Thompson22285ec2013-10-22 17:43:02 -0700360 Name keyName = certificate.getPublicKeyName();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700361
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700362 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700363 Name identityName = keyName.getSubName(0, keyName.size() - 1);
364
365 sqlite3_stmt *statement;
366 sqlite3_prepare_v2(database_,
367 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
368 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
369 -1, &statement, 0);
370
371
372 _LOG_DEBUG("certName: " << certificateName.toUri().c_str());
373 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
374
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700375 const Sha256WithRsaSignature* signature = dynamic_cast<const Sha256WithRsaSignature*>(certificate.getSignature());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700376 const Name& signerName = signature->getKeyLocator().getKeyName();
377 sqlite3_bind_text(statement, 2, signerName.toUri(), SQLITE_TRANSIENT);
378
379 sqlite3_bind_text(statement, 3, identityName.toUri(), SQLITE_TRANSIENT);
380 sqlite3_bind_text(statement, 4, keyId, SQLITE_TRANSIENT);
381
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700382 // Convert from milliseconds to seconds since 1/1/1970.
383 sqlite3_bind_int64(statement, 5, (sqlite3_int64)floor(certificate.getNotBefore() / 1000.0));
384 sqlite3_bind_int64(statement, 6, (sqlite3_int64)floor(certificate.getNotAfter() / 1000.0));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700385
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700386 if (!certificate.getDefaultWireEncoding())
387 certificate.wireEncode();
388 sqlite3_bind_blob(statement, 7, certificate.getDefaultWireEncoding().buf(), certificate.getDefaultWireEncoding().size(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700389
390 int res = sqlite3_step(statement);
391
392 sqlite3_finalize(statement);
393}
394
395void
Jeff Thompsonc69163b2013-10-12 13:49:50 -0700396BasicIdentityStorage::addCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700397{
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700398 const Name& certificateName = certificate.getName();
Jeff Thompson22285ec2013-10-22 17:43:02 -0700399 Name keyName = certificate.getPublicKeyName();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700400
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700401 if (!doesKeyExist(keyName))
Jeff Thompson22285ec2013-10-22 17:43:02 -0700402 throw SecurityException("No corresponding Key record for certificate!" + keyName.toUri() + " " + certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700403
404 // Check if certificate has already existed!
405 if (doesCertificateExist(certificateName))
406 throw SecurityException("Certificate has already been installed!");
407
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700408 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
409 Name identity = keyName.getSubName(0, keyName.size() - 1);
410
411 // Check if the public key of certificate is the same as the key record
412
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700413 Blob keyBlob = getKey(keyName);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700414
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700415 if (!keyBlob || (*keyBlob) != *(certificate.getPublicKeyInfo().getKeyDer()))
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700416 throw SecurityException("Certificate does not match the public key!");
417
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700418 // Insert the certificate
419 sqlite3_stmt *statement;
420 sqlite3_prepare_v2(database_,
421 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
422 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
423 -1, &statement, 0);
424
425 _LOG_DEBUG("certName: " << certificateName.toUri().c_str());
426 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
427
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700428 const Sha256WithRsaSignature* signature = dynamic_cast<const Sha256WithRsaSignature*>(certificate.getSignature());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700429 const Name & signerName = signature->getKeyLocator().getKeyName();
430 sqlite3_bind_text(statement, 2, signerName.toUri(), SQLITE_TRANSIENT);
431
432 sqlite3_bind_text(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
433 sqlite3_bind_text(statement, 4, keyId, SQLITE_TRANSIENT);
434
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700435 // Convert from milliseconds to seconds since 1/1/1970.
436 sqlite3_bind_int64(statement, 5, (sqlite3_int64)floor(certificate.getNotBefore() / 1000.0));
437 sqlite3_bind_int64(statement, 6, (sqlite3_int64)floor(certificate.getNotAfter() / 1000.0));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700438
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700439 if (!certificate.getDefaultWireEncoding())
440 certificate.wireEncode();
441 sqlite3_bind_blob(statement, 7, certificate.getDefaultWireEncoding().buf(), certificate.getDefaultWireEncoding().size(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700442
443 int res = sqlite3_step(statement);
444
445 sqlite3_finalize(statement);
446}
447
Jeff Thompson3bd90bc2013-10-19 16:40:14 -0700448shared_ptr<Data>
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700449BasicIdentityStorage::getCertificate(const Name &certificateName, bool allowAny)
450{
451 if (doesCertificateExist(certificateName)) {
452 sqlite3_stmt *statement;
453 if (!allowAny) {
454 sqlite3_prepare_v2(database_,
455 "SELECT certificate_data FROM Certificate \
456 WHERE cert_name=? AND not_before<datetime(?, 'unixepoch') AND not_after>datetime(?, 'unixepoch') and valid_flag=1",
457 -1, &statement, 0);
458
459 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson3bd90bc2013-10-19 16:40:14 -0700460 sqlite3_bind_int64(statement, 2, (sqlite3_int64)floor(ndn_getNowMilliseconds() / 1000.0));
461 sqlite3_bind_int64(statement, 3, (sqlite3_int64)floor(ndn_getNowMilliseconds() / 1000.0));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700462 }
463 else {
464 sqlite3_prepare_v2(database_,
465 "SELECT certificate_data FROM Certificate WHERE cert_name=?", -1, &statement, 0);
466
467 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
468 }
469
470 int res = sqlite3_step(statement);
471
Jeff Thompson4d004792013-10-21 16:56:58 -0700472 shared_ptr<Data> data(new Data());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700473
474 if (res == SQLITE_ROW)
Jeff Thompson3bd90bc2013-10-19 16:40:14 -0700475 data->wireDecode((const uint8_t*)sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700476 sqlite3_finalize(statement);
477
Jeff Thompson3bd90bc2013-10-19 16:40:14 -0700478 return data;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700479 }
480 else {
481 _LOG_DEBUG("Certificate does not exist!");
Jeff Thompson3bd90bc2013-10-19 16:40:14 -0700482 return shared_ptr<Data>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700483 }
Jeff Thompson1975def2013-10-09 17:06:43 -0700484}
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700485
486Name
487BasicIdentityStorage::getDefaultIdentity()
488{
489 sqlite3_stmt *statement;
490 sqlite3_prepare_v2(database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &statement, 0);
491
492 int res = sqlite3_step(statement);
493
494 Name identity;
495
496 if (res == SQLITE_ROW)
497 identity = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
498
499 sqlite3_finalize(statement);
500
501 return identity;
502}
503
504Name
505BasicIdentityStorage::getDefaultKeyNameForIdentity(const Name& identityName)
506{
507 sqlite3_stmt *statement;
508 sqlite3_prepare_v2(database_, "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1", -1, &statement, 0);
509
510 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
511
512 int res = sqlite3_step(statement);
513
514 Name keyName;
515
516 if (res == SQLITE_ROW)
517 keyName = Name(identityName).append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
518
519 sqlite3_finalize(statement);
520
521 return keyName;
522}
523
524Name
525BasicIdentityStorage::getDefaultCertificateNameForKey(const Name& keyName)
526{
527 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
528 Name identityName = keyName.getSubName(0, keyName.size() - 1);
529
530 sqlite3_stmt *statement;
531 sqlite3_prepare_v2(database_, "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1", -1, &statement, 0);
532
533 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
534 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
535
536 int res = sqlite3_step(statement);
537
538 Name certName;
539
540 if (res == SQLITE_ROW)
541 certName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
542
543 sqlite3_finalize(statement);
544
545 return certName;
546}
547
548void
549BasicIdentityStorage::setDefaultIdentity(const Name& identityName)
550{
551 sqlite3_stmt *statement;
552
553 //Reset previous default identity
554 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=0 WHERE default_identity=1", -1, &statement, 0);
555
556 while (sqlite3_step(statement) == SQLITE_ROW)
557 {}
558
559 sqlite3_finalize(statement);
560
561 //Set current default identity
562 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=1 WHERE identity_name=?", -1, &statement, 0);
563
564 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
565
566 sqlite3_step(statement);
567
568 sqlite3_finalize(statement);
569}
570
571void
572BasicIdentityStorage::setDefaultKeyNameForIdentity(const Name& keyName, const Name& identityNameCheck)
573{
574 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
575 Name identityName = keyName.getSubName(0, keyName.size() - 1);
576
577 if (identityNameCheck.size() > 0 && !identityNameCheck.equals(identityName))
578 throw SecurityException("Specified identity name does not match the key name");
579
580 sqlite3_stmt *statement;
581
582 //Reset previous default Key
583 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", -1, &statement, 0);
584
585 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
586
587 while (sqlite3_step(statement) == SQLITE_ROW)
588 {}
589
590 sqlite3_finalize(statement);
591
592 //Set current default Key
593 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
594
595 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
596 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
597
598 sqlite3_step(statement);
599
600 sqlite3_finalize(statement);
601}
602
603void
604BasicIdentityStorage::setDefaultCertificateNameForKey(const Name& keyName, const Name& certificateName)
605{
606 string keyId = keyName.get(keyName.size() - 1).toEscapedString();
607 Name identityName = keyName.getSubName(0, keyName.size() - 1);
608
609 sqlite3_stmt *statement;
610
611 //Reset previous default Key
612 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?", -1, &statement, 0);
613
614 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
615 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
616
617 while (sqlite3_step(statement) == SQLITE_ROW)
618 {}
619
620 sqlite3_finalize(statement);
621
622 //Set current default Key
623 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?", -1, &statement, 0);
624
625 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
626 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
627 sqlite3_bind_text(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
628
629 sqlite3_step(statement);
630
631 sqlite3_finalize(statement);
632}
633
634}
635
Jeff Thompsonb7523002013-10-09 10:25:00 -0700636#endif // NDN_CPP_HAVE_SQLITE3