blob: 2072091da6887d690f02571b542279f516611e9f [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.
Yingdi Yu61ec2722014-01-20 14:22:32 -080010#include <ndn-cpp-dev/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
Yingdi Yu874678f2014-01-22 19:30:34 -080013#include <sqlite3.h>
Jeff Thompson351ac302013-10-19 18:45:00 -070014#include <stdio.h>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070015#include <stdlib.h>
16#include <sstream>
17#include <fstream>
Yingdi Yu0b9c3152014-01-26 16:31:18 -080018#include <boost/filesystem.hpp>
Yingdi Yu4f324632014-01-15 18:10:03 -080019#include "../util/logging.hpp"
Alexander Afanasyevd409d592014-01-28 18:36:38 -080020#include "../util/time.hpp"
21
Yingdi Yu61ec2722014-01-20 14:22:32 -080022#include <ndn-cpp-dev/data.hpp>
23#include <ndn-cpp-dev/security/identity-certificate.hpp>
24#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
25#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -080026
Jeff Thompson7ca11f22013-10-04 19:01:30 -070027
Yingdi Yu87581582014-01-14 14:28:39 -080028INIT_LOGGER("BasicKeyMetaInfo");
Jeff Thompson7ca11f22013-10-04 19:01:30 -070029
30using namespace std;
Jeff Thompson7ca11f22013-10-04 19:01:30 -070031
32namespace ndn
33{
34
35static const string INIT_ID_TABLE = "\
36CREATE TABLE IF NOT EXISTS \n \
37 Identity( \n \
38 identity_name BLOB NOT NULL, \n \
39 default_identity INTEGER DEFAULT 0, \n \
40 \
41 PRIMARY KEY (identity_name) \n \
42 ); \n \
43 \
44CREATE INDEX identity_index ON Identity(identity_name); \n \
45";
46
47static const string INIT_KEY_TABLE = "\
48CREATE TABLE IF NOT EXISTS \n \
49 Key( \n \
50 identity_name BLOB NOT NULL, \n \
51 key_identifier BLOB NOT NULL, \n \
52 key_type INTEGER, \n \
53 public_key BLOB, \n \
54 default_key INTEGER DEFAULT 0, \n \
55 active INTEGER DEFAULT 0, \n \
56 \
57 PRIMARY KEY (identity_name, key_identifier) \n \
58 ); \n \
59 \
60CREATE INDEX key_index ON Key(identity_name); \n \
61";
62
63static const string INIT_CERT_TABLE = "\
64CREATE TABLE IF NOT EXISTS \n \
65 Certificate( \n \
66 cert_name BLOB NOT NULL, \n \
67 cert_issuer BLOB NOT NULL, \n \
68 identity_name BLOB NOT NULL, \n \
69 key_identifier BLOB NOT NULL, \n \
70 not_before TIMESTAMP, \n \
71 not_after TIMESTAMP, \n \
72 certificate_data BLOB NOT NULL, \n \
Jeff Thompson22285ec2013-10-22 17:43:02 -070073 valid_flag INTEGER DEFAULT 1, \n \
Jeff Thompson7ca11f22013-10-04 19:01:30 -070074 default_cert INTEGER DEFAULT 0, \n \
75 \
76 PRIMARY KEY (cert_name) \n \
77 ); \n \
78 \
79CREATE INDEX cert_index ON Certificate(cert_name); \n \
80CREATE INDEX subject ON Certificate(identity_name); \n \
81";
82
83/**
84 * A utility function to call the normal sqlite3_bind_text where the value and length are value.c_str() and value.size().
85 */
86static int sqlite3_bind_text(sqlite3_stmt* statement, int index, const string& value, void(*destructor)(void*))
87{
88 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
89}
90
Yingdi Yu87581582014-01-14 14:28:39 -080091SecPublicInfoSqlite3::SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -070092{
Yingdi Yu0b9c3152014-01-26 16:31:18 -080093 boost::filesystem::path identityDir = boost::filesystem::path(getenv("HOME")) / ".ndnx";
94 boost::filesystem::create_directories (identityDir);
Jeff Thompson7ca11f22013-10-04 19:01:30 -070095
Yingdi Yu0b9c3152014-01-26 16:31:18 -080096 int res = sqlite3_open((identityDir / "ndnsec-public-info.db").c_str(), &database_);
Jeff Thompson7ca11f22013-10-04 19:01:30 -070097
98 if (res != SQLITE_OK)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -080099 throw Error("identity DB cannot be opened/created");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700100
101 //Check if Key table exists;
102 sqlite3_stmt *statement;
103 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 -0700104 res = sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700105
106 bool idTableExists = false;
107 if (res == SQLITE_ROW)
108 idTableExists = true;
109
110 sqlite3_finalize(statement);
111
112 if (!idTableExists) {
113 char *errorMessage = 0;
114 res = sqlite3_exec(database_, INIT_ID_TABLE.c_str(), NULL, NULL, &errorMessage);
115
116 if (res != SQLITE_OK && errorMessage != 0) {
117 _LOG_TRACE("Init \"error\" in Identity: " << errorMessage);
118 sqlite3_free(errorMessage);
119 }
120 }
121
122 //Check if Key table exists;
123 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Key'", -1, &statement, 0);
124 res = sqlite3_step(statement);
125
126 bool keyTableExists = false;
127 if (res == SQLITE_ROW)
128 keyTableExists = true;
129
130 sqlite3_finalize(statement);
131
132 if (!keyTableExists) {
133 char *errorMessage = 0;
134 res = sqlite3_exec(database_, INIT_KEY_TABLE.c_str(), NULL, NULL, &errorMessage);
135
136 if (res != SQLITE_OK && errorMessage != 0) {
137 _LOG_TRACE("Init \"error\" in KEY: " << errorMessage);
138 sqlite3_free(errorMessage);
139 }
140 }
141
142 //Check if Certificate table exists;
143 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'", -1, &statement, 0);
144 res = sqlite3_step(statement);
145
146 bool idCertificateTableExists = false;
147 if (res == SQLITE_ROW)
148 idCertificateTableExists = true;
149
150 sqlite3_finalize(statement);
151
152 if (!idCertificateTableExists) {
153 char *errorMessage = 0;
154 res = sqlite3_exec(database_, INIT_CERT_TABLE.c_str(), NULL, NULL, &errorMessage);
155
156 if (res != SQLITE_OK && errorMessage != 0) {
157 _LOG_TRACE("Init \"error\" in ID-CERT: " << errorMessage);
158 sqlite3_free(errorMessage);
159 }
160 }
161}
162
Yingdi Yu87581582014-01-14 14:28:39 -0800163SecPublicInfoSqlite3::~SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700164{
165}
166
167bool
Yingdi Yu87581582014-01-14 14:28:39 -0800168SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700169{
170 bool result = false;
171
172 sqlite3_stmt *statement;
173 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Identity WHERE identity_name=?", -1, &statement, 0);
174
175 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
176 int res = sqlite3_step(statement);
177
178 if (res == SQLITE_ROW) {
179 int countAll = sqlite3_column_int(statement, 0);
180 if (countAll > 0)
181 result = true;
182 }
183
184 sqlite3_finalize(statement);
185
186 return result;
187}
188
189void
Yingdi Yu87581582014-01-14 14:28:39 -0800190SecPublicInfoSqlite3::addIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700191{
192 if (doesIdentityExist(identityName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800193 throw Error("Identity already exists");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700194
195 sqlite3_stmt *statement;
196
197 sqlite3_prepare_v2(database_, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
198
199 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
200
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800201 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700202
203 sqlite3_finalize(statement);
204}
205
206bool
Yingdi Yu87581582014-01-14 14:28:39 -0800207SecPublicInfoSqlite3::revokeIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700208{
209 //TODO:
210 return false;
211}
212
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700213bool
Yingdi Yu87581582014-01-14 14:28:39 -0800214SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700215{
Yingdi Yu88663af2014-01-15 15:21:38 -0800216 if(keyName.empty())
217 throw Error("Incorrect key name " + keyName.toUri());
218
Yingdi Yu87581582014-01-14 14:28:39 -0800219 string keyId = keyName.get(-1).toEscapedString();
220 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700221
222 sqlite3_stmt *statement;
223 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
224
225 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
226 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
227
228 int res = sqlite3_step(statement);
229
230 bool keyIdExist = false;
231 if (res == SQLITE_ROW) {
232 int countAll = sqlite3_column_int(statement, 0);
233 if (countAll > 0)
234 keyIdExist = true;
235 }
236
237 sqlite3_finalize(statement);
238
239 return keyIdExist;
240}
241
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700242void
Yingdi Yu87581582014-01-14 14:28:39 -0800243SecPublicInfoSqlite3::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700244{
Yingdi Yu88663af2014-01-15 15:21:38 -0800245 if(keyName.empty())
246 throw Error("Incorrect key name " + keyName.toUri());
247
Yingdi Yu87581582014-01-14 14:28:39 -0800248 string keyId = keyName.get(-1).toEscapedString();
249 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700250
251
252 if (!doesIdentityExist(identityName))
253 addIdentity(identityName);
254
Yingdi Yu87581582014-01-14 14:28:39 -0800255 if (doesPublicKeyExist(keyName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800256 throw Error("a key with the same name already exists!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700257
258 sqlite3_stmt *statement;
259 sqlite3_prepare_v2(database_, "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
260
261 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
262 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
263 sqlite3_bind_int(statement, 3, (int)keyType);
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800264 sqlite3_bind_blob(statement, 4, publicKeyDer.get().buf(), publicKeyDer.get().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700265
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800266 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700267
268 sqlite3_finalize(statement);
269}
270
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800271ptr_lib::shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800272SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700273{
Yingdi Yu87581582014-01-14 14:28:39 -0800274 if (!doesPublicKeyExist(keyName)) {
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700275 _LOG_DEBUG("keyName does not exist");
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800276 return ptr_lib::shared_ptr<PublicKey>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700277 }
278
Yingdi Yu87581582014-01-14 14:28:39 -0800279 string keyId = keyName.get(-1).toEscapedString();
280 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700281
282 sqlite3_stmt *statement;
283 sqlite3_prepare_v2(database_, "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
284
285 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
286 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
287
288 int res = sqlite3_step(statement);
289
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800290 ptr_lib::shared_ptr<PublicKey> result;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700291 if (res == SQLITE_ROW)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800292 result = ptr_lib::make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)), sqlite3_column_bytes(statement, 0));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700293
294 sqlite3_finalize(statement);
295
296 return result;
297}
298
299void
Yingdi Yu87581582014-01-14 14:28:39 -0800300SecPublicInfoSqlite3::updateKeyStatus(const Name& keyName, bool isActive)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700301{
Yingdi Yu88663af2014-01-15 15:21:38 -0800302 if(keyName.empty())
303 throw Error("Incorrect key name " + keyName.toUri());
304
Yingdi Yu87581582014-01-14 14:28:39 -0800305 string keyId = keyName.get(-1).toEscapedString();
306 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700307
308 sqlite3_stmt *statement;
309 sqlite3_prepare_v2(database_, "UPDATE Key SET active=? WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
310
311 sqlite3_bind_int(statement, 1, (isActive ? 1 : 0));
312 sqlite3_bind_text(statement, 2, identityName.toUri(), SQLITE_TRANSIENT);
313 sqlite3_bind_text(statement, 3, keyId, SQLITE_TRANSIENT);
314
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800315 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700316
317 sqlite3_finalize(statement);
318}
319
320bool
Yingdi Yu87581582014-01-14 14:28:39 -0800321SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700322{
323 sqlite3_stmt *statement;
324 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Certificate WHERE cert_name=?", -1, &statement, 0);
325
326 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
327
328 int res = sqlite3_step(statement);
329
330 bool certExist = false;
331 if (res == SQLITE_ROW) {
332 int countAll = sqlite3_column_int(statement, 0);
333 if (countAll > 0)
334 certExist = true;
335 }
336
337 sqlite3_finalize(statement);
338
339 return certExist;
340}
341
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700342void
Yingdi Yu87581582014-01-14 14:28:39 -0800343SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700344{
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800345 std::string certificateName = certificate.getName().toUri();
Yingdi Yu88663af2014-01-15 15:21:38 -0800346 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
347
348 if(keyName.empty())
349 throw Error("Incorrect key name " + keyName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700350
Yingdi Yu87581582014-01-14 14:28:39 -0800351 std::string keyId = keyName.get(-1).toEscapedString();
352 std::string identityName = keyName.getPrefix(-1).toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700353
354 sqlite3_stmt *statement;
355 sqlite3_prepare_v2(database_,
356 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
357 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
358 -1, &statement, 0);
359
360
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800361 _LOG_DEBUG("certName: " << certificateName);
362 sqlite3_bind_text(statement, 1, certificateName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700363
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800364 // this will throw an exception if the signature is not the standard one or there is no key locator present
365 SignatureSha256WithRsa signature(certificate.getSignature());
366 std::string signerName = signature.getKeyLocator().getName().toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700367
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800368 sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
369
370 sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
371 sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700372
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700373 // Convert from milliseconds to seconds since 1/1/1970.
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800374 sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
375 sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700376
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800377 sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700378
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800379 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700380
381 sqlite3_finalize(statement);
382}
383
384void
Yingdi Yu87581582014-01-14 14:28:39 -0800385SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700386{
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700387 const Name& certificateName = certificate.getName();
Yingdi Yu88663af2014-01-15 15:21:38 -0800388 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700389
Yingdi Yu87581582014-01-14 14:28:39 -0800390 if (!doesPublicKeyExist(keyName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800391 throw Error("No corresponding Key record for certificate!" + keyName.toUri() + " " + certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700392
393 // Check if certificate has already existed!
394 if (doesCertificateExist(certificateName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800395 throw Error("Certificate has already been installed!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700396
Yingdi Yu87581582014-01-14 14:28:39 -0800397 string keyId = keyName.get(-1).toEscapedString();
398 Name identity = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700399
400 // Check if the public key of certificate is the same as the key record
401
Yingdi Yu87581582014-01-14 14:28:39 -0800402 ptr_lib::shared_ptr<PublicKey> pubKey = getPublicKey(keyName);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700403
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800404 if (!pubKey || (*pubKey) != certificate.getPublicKeyInfo())
405 throw Error("Certificate does not match the public key!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700406
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700407 // Insert the certificate
408 sqlite3_stmt *statement;
409 sqlite3_prepare_v2(database_,
410 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
411 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
412 -1, &statement, 0);
413
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800414 _LOG_DEBUG("certName: " << certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700415 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
416
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800417 // this will throw an exception if the signature is not the standard one or there is no key locator present
418 SignatureSha256WithRsa signature(certificate.getSignature());
419 std::string signerName = signature.getKeyLocator().getName().toUri();
420
421 sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700422
423 sqlite3_bind_text(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800424 sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700425
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700426 // Convert from milliseconds to seconds since 1/1/1970.
Yingdi Yu88663af2014-01-15 15:21:38 -0800427 sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
428 sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700429
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800430 sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700431
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800432 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700433
434 sqlite3_finalize(statement);
435}
436
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800437ptr_lib::shared_ptr<IdentityCertificate>
Yingdi Yu88663af2014-01-15 15:21:38 -0800438SecPublicInfoSqlite3::getCertificate(const Name &certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700439{
440 if (doesCertificateExist(certificateName)) {
441 sqlite3_stmt *statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700442
Yingdi Yu88663af2014-01-15 15:21:38 -0800443 sqlite3_prepare_v2(database_,
444 "SELECT certificate_data FROM Certificate \
445 WHERE cert_name=? AND not_before<datetime('now') AND not_after>datetime('now') and valid_flag=1",
446 -1, &statement, 0);
447
448 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700449
450 int res = sqlite3_step(statement);
451
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800452 ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700453 if (res == SQLITE_ROW)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800454 {
455 certificate->wireDecode(Block((const uint8_t*)sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0)));
456 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700457 sqlite3_finalize(statement);
458
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800459 return certificate;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700460 }
461 else {
462 _LOG_DEBUG("Certificate does not exist!");
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800463 return ptr_lib::shared_ptr<IdentityCertificate>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700464 }
Jeff Thompson1975def2013-10-09 17:06:43 -0700465}
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700466
467Name
Yingdi Yu87581582014-01-14 14:28:39 -0800468SecPublicInfoSqlite3::getDefaultIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700469{
470 sqlite3_stmt *statement;
471 sqlite3_prepare_v2(database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &statement, 0);
472
473 int res = sqlite3_step(statement);
474
475 Name identity;
476
477 if (res == SQLITE_ROW)
478 identity = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
479
480 sqlite3_finalize(statement);
481
482 return identity;
483}
484
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700485void
Yingdi Yu87581582014-01-14 14:28:39 -0800486SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700487{
488 sqlite3_stmt *statement;
489
490 //Reset previous default identity
491 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=0 WHERE default_identity=1", -1, &statement, 0);
492
493 while (sqlite3_step(statement) == SQLITE_ROW)
494 {}
495
496 sqlite3_finalize(statement);
497
498 //Set current default identity
499 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=1 WHERE identity_name=?", -1, &statement, 0);
500
501 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
502
503 sqlite3_step(statement);
504
505 sqlite3_finalize(statement);
506}
507
Yingdi Yu87581582014-01-14 14:28:39 -0800508Name
509SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700510{
Yingdi Yu87581582014-01-14 14:28:39 -0800511 sqlite3_stmt *statement;
512 sqlite3_prepare_v2(database_, "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1", -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700513
Yingdi Yu87581582014-01-14 14:28:39 -0800514 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
515
516 int res = sqlite3_step(statement);
517
518 Name keyName;
519
520 if (res == SQLITE_ROW)
521 keyName = Name(identityName).append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
522
523 sqlite3_finalize(statement);
524
525 return keyName;
526}
527
528void
529SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
530{
Yingdi Yu88663af2014-01-15 15:21:38 -0800531 if(keyName.empty())
532 throw Error("Incorrect key name " + keyName.toUri());
533
Yingdi Yu87581582014-01-14 14:28:39 -0800534 string keyId = keyName.get(-1).toEscapedString();
535 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700536
537 sqlite3_stmt *statement;
538
539 //Reset previous default Key
540 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", -1, &statement, 0);
541
542 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
543
544 while (sqlite3_step(statement) == SQLITE_ROW)
545 {}
546
547 sqlite3_finalize(statement);
548
549 //Set current default Key
550 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
551
552 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
553 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
554
555 sqlite3_step(statement);
556
557 sqlite3_finalize(statement);
558}
559
Yingdi Yu87581582014-01-14 14:28:39 -0800560Name
561SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700562{
Yingdi Yu88663af2014-01-15 15:21:38 -0800563 if(keyName.empty())
564 return Name();
565
Yingdi Yu87581582014-01-14 14:28:39 -0800566 string keyId = keyName.get(-1).toEscapedString();
567 Name identityName = keyName.getPrefix(-1);
568
569 sqlite3_stmt *statement;
570 sqlite3_prepare_v2(database_, "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1", -1, &statement, 0);
571
572 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
573 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
574
575 int res = sqlite3_step(statement);
576
577 Name certName;
578
579 if (res == SQLITE_ROW)
580 certName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
581
582 sqlite3_finalize(statement);
583
584 return certName;
585}
586
587void
588SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
589{
590 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
Yingdi Yu88663af2014-01-15 15:21:38 -0800591 if(keyName.empty())
592 throw Error("Incorrect key name for certificate " + certificateName.toUri());
593
Yingdi Yu87581582014-01-14 14:28:39 -0800594 string keyId = keyName.get(-1).toEscapedString();
595 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700596
597 sqlite3_stmt *statement;
598
599 //Reset previous default Key
600 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?", -1, &statement, 0);
601
602 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
603 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
604
605 while (sqlite3_step(statement) == SQLITE_ROW)
606 {}
607
608 sqlite3_finalize(statement);
609
610 //Set current default Key
611 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?", -1, &statement, 0);
612
613 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
614 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
615 sqlite3_bind_text(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
616
617 sqlite3_step(statement);
618
619 sqlite3_finalize(statement);
620}
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800621
622vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800623SecPublicInfoSqlite3::getAllIdentities(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800624{
625 sqlite3_stmt *stmt;
626 if(isDefault)
627 sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &stmt, 0);
628 else
629 sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=0", -1, &stmt, 0);
630
631 vector<Name> nameList;
632 while(sqlite3_step (stmt) == SQLITE_ROW)
633 nameList.push_back(Name(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0))));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700634
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800635 sqlite3_finalize (stmt);
636 return nameList;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700637}
638
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800639vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800640SecPublicInfoSqlite3::getAllKeyNames(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800641{
642 sqlite3_stmt *stmt;
643 if(isDefault)
644 sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=1", -1, &stmt, 0);
645 else
646 sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=0", -1, &stmt, 0);
647
648 vector<Name> nameList;
649 while(sqlite3_step (stmt) == SQLITE_ROW)
650 {
651 Name keyName(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
652 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
653 nameList.push_back(keyName);
654 }
655 sqlite3_finalize (stmt);
656 return nameList;
657}
658
659vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800660SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800661{
662 sqlite3_stmt *stmt;
663 if(isDefault)
664 sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?", -1, &stmt, 0);
665 else
666 sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?", -1, &stmt, 0);
667
668 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size (), SQLITE_TRANSIENT);
669
670 vector<Name> nameList;
671 while(sqlite3_step (stmt) == SQLITE_ROW)
672 {
673 Name keyName(identity);
674 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
675 nameList.push_back(keyName);
676 }
677 sqlite3_finalize (stmt);
678 return nameList;
679}
680
681vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800682SecPublicInfoSqlite3::getAllCertificateNames(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800683{
684 sqlite3_stmt *stmt;
685 if(isDefault)
686 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1", -1, &stmt, 0);
687 else
688 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0", -1, &stmt, 0);
689
690 vector<Name> nameList;
691 while(sqlite3_step (stmt) == SQLITE_ROW)
692 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
693
694 sqlite3_finalize (stmt);
695 return nameList;
696}
697
698vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800699SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800700{
Yingdi Yu88663af2014-01-15 15:21:38 -0800701 if(keyName.empty())
702 return vector<Name>();
703
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800704 sqlite3_stmt *stmt;
705 if(isDefault)
706 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1 and identity_name=? and key_identifier=?", -1, &stmt, 0);
707 else
708 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0 and identity_name=? and key_identifier=?", -1, &stmt, 0);
709
Yingdi Yu87581582014-01-14 14:28:39 -0800710 Name identity = keyName.getPrefix(-1);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800711 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size (), SQLITE_TRANSIENT);
712 std::string baseKeyName = keyName.get(-1).toEscapedString();
713 sqlite3_bind_text(stmt, 2, baseKeyName.c_str(), baseKeyName.size(), SQLITE_TRANSIENT);
714
715 vector<Name> nameList;
716 while(sqlite3_step (stmt) == SQLITE_ROW)
717 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
718
719 sqlite3_finalize (stmt);
720 return nameList;
721}
722
723} // namespace ndn
724
Jeff Thompsonb7523002013-10-09 10:25:00 -0700725#endif // NDN_CPP_HAVE_SQLITE3