blob: 8b68ac67de4ffd33c3b0c900e3be695f60eaeb4f [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"
20#include "../c/util/time.h"
Yingdi Yu61ec2722014-01-20 14:22:32 -080021#include <ndn-cpp-dev/data.hpp>
22#include <ndn-cpp-dev/security/identity-certificate.hpp>
23#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
24#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -080025
Jeff Thompson7ca11f22013-10-04 19:01:30 -070026
Yingdi Yu87581582014-01-14 14:28:39 -080027INIT_LOGGER("BasicKeyMetaInfo");
Jeff Thompson7ca11f22013-10-04 19:01:30 -070028
29using namespace std;
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
Yingdi Yu87581582014-01-14 14:28:39 -080090SecPublicInfoSqlite3::SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -070091{
Yingdi Yu0b9c3152014-01-26 16:31:18 -080092 boost::filesystem::path identityDir = boost::filesystem::path(getenv("HOME")) / ".ndnx";
93 boost::filesystem::create_directories (identityDir);
Jeff Thompson7ca11f22013-10-04 19:01:30 -070094
Yingdi Yu0b9c3152014-01-26 16:31:18 -080095 int res = sqlite3_open((identityDir / "ndnsec-public-info.db").c_str(), &database_);
Jeff Thompson7ca11f22013-10-04 19:01:30 -070096
97 if (res != SQLITE_OK)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -080098 throw Error("identity DB cannot be opened/created");
Jeff Thompson7ca11f22013-10-04 19:01:30 -070099
100 //Check if Key table exists;
101 sqlite3_stmt *statement;
102 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 -0700103 res = sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700104
105 bool idTableExists = false;
106 if (res == SQLITE_ROW)
107 idTableExists = true;
108
109 sqlite3_finalize(statement);
110
111 if (!idTableExists) {
112 char *errorMessage = 0;
113 res = sqlite3_exec(database_, INIT_ID_TABLE.c_str(), NULL, NULL, &errorMessage);
114
115 if (res != SQLITE_OK && errorMessage != 0) {
116 _LOG_TRACE("Init \"error\" in Identity: " << errorMessage);
117 sqlite3_free(errorMessage);
118 }
119 }
120
121 //Check if Key table exists;
122 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Key'", -1, &statement, 0);
123 res = sqlite3_step(statement);
124
125 bool keyTableExists = false;
126 if (res == SQLITE_ROW)
127 keyTableExists = true;
128
129 sqlite3_finalize(statement);
130
131 if (!keyTableExists) {
132 char *errorMessage = 0;
133 res = sqlite3_exec(database_, INIT_KEY_TABLE.c_str(), NULL, NULL, &errorMessage);
134
135 if (res != SQLITE_OK && errorMessage != 0) {
136 _LOG_TRACE("Init \"error\" in KEY: " << errorMessage);
137 sqlite3_free(errorMessage);
138 }
139 }
140
141 //Check if Certificate table exists;
142 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'", -1, &statement, 0);
143 res = sqlite3_step(statement);
144
145 bool idCertificateTableExists = false;
146 if (res == SQLITE_ROW)
147 idCertificateTableExists = true;
148
149 sqlite3_finalize(statement);
150
151 if (!idCertificateTableExists) {
152 char *errorMessage = 0;
153 res = sqlite3_exec(database_, INIT_CERT_TABLE.c_str(), NULL, NULL, &errorMessage);
154
155 if (res != SQLITE_OK && errorMessage != 0) {
156 _LOG_TRACE("Init \"error\" in ID-CERT: " << errorMessage);
157 sqlite3_free(errorMessage);
158 }
159 }
160}
161
Yingdi Yu87581582014-01-14 14:28:39 -0800162SecPublicInfoSqlite3::~SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700163{
164}
165
166bool
Yingdi Yu87581582014-01-14 14:28:39 -0800167SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700168{
169 bool result = false;
170
171 sqlite3_stmt *statement;
172 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Identity WHERE identity_name=?", -1, &statement, 0);
173
174 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
175 int res = sqlite3_step(statement);
176
177 if (res == SQLITE_ROW) {
178 int countAll = sqlite3_column_int(statement, 0);
179 if (countAll > 0)
180 result = true;
181 }
182
183 sqlite3_finalize(statement);
184
185 return result;
186}
187
188void
Yingdi Yu87581582014-01-14 14:28:39 -0800189SecPublicInfoSqlite3::addIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700190{
191 if (doesIdentityExist(identityName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800192 throw Error("Identity already exists");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700193
194 sqlite3_stmt *statement;
195
196 sqlite3_prepare_v2(database_, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
197
198 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
199
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800200 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700201
202 sqlite3_finalize(statement);
203}
204
205bool
Yingdi Yu87581582014-01-14 14:28:39 -0800206SecPublicInfoSqlite3::revokeIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700207{
208 //TODO:
209 return false;
210}
211
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700212bool
Yingdi Yu87581582014-01-14 14:28:39 -0800213SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700214{
Yingdi Yu88663af2014-01-15 15:21:38 -0800215 if(keyName.empty())
216 throw Error("Incorrect key name " + keyName.toUri());
217
Yingdi Yu87581582014-01-14 14:28:39 -0800218 string keyId = keyName.get(-1).toEscapedString();
219 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700220
221 sqlite3_stmt *statement;
222 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
223
224 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
225 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
226
227 int res = sqlite3_step(statement);
228
229 bool keyIdExist = false;
230 if (res == SQLITE_ROW) {
231 int countAll = sqlite3_column_int(statement, 0);
232 if (countAll > 0)
233 keyIdExist = true;
234 }
235
236 sqlite3_finalize(statement);
237
238 return keyIdExist;
239}
240
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700241void
Yingdi Yu87581582014-01-14 14:28:39 -0800242SecPublicInfoSqlite3::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700243{
Yingdi Yu88663af2014-01-15 15:21:38 -0800244 if(keyName.empty())
245 throw Error("Incorrect key name " + keyName.toUri());
246
Yingdi Yu87581582014-01-14 14:28:39 -0800247 string keyId = keyName.get(-1).toEscapedString();
248 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700249
250
251 if (!doesIdentityExist(identityName))
252 addIdentity(identityName);
253
Yingdi Yu87581582014-01-14 14:28:39 -0800254 if (doesPublicKeyExist(keyName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800255 throw Error("a key with the same name already exists!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700256
257 sqlite3_stmt *statement;
258 sqlite3_prepare_v2(database_, "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
259
260 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
261 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
262 sqlite3_bind_int(statement, 3, (int)keyType);
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800263 sqlite3_bind_blob(statement, 4, publicKeyDer.get().buf(), publicKeyDer.get().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700264
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800265 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700266
267 sqlite3_finalize(statement);
268}
269
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800270ptr_lib::shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800271SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700272{
Yingdi Yu87581582014-01-14 14:28:39 -0800273 if (!doesPublicKeyExist(keyName)) {
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700274 _LOG_DEBUG("keyName does not exist");
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800275 return ptr_lib::shared_ptr<PublicKey>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700276 }
277
Yingdi Yu87581582014-01-14 14:28:39 -0800278 string keyId = keyName.get(-1).toEscapedString();
279 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700280
281 sqlite3_stmt *statement;
282 sqlite3_prepare_v2(database_, "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
283
284 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
285 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
286
287 int res = sqlite3_step(statement);
288
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800289 ptr_lib::shared_ptr<PublicKey> result;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700290 if (res == SQLITE_ROW)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800291 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 -0700292
293 sqlite3_finalize(statement);
294
295 return result;
296}
297
298void
Yingdi Yu87581582014-01-14 14:28:39 -0800299SecPublicInfoSqlite3::updateKeyStatus(const Name& keyName, bool isActive)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700300{
Yingdi Yu88663af2014-01-15 15:21:38 -0800301 if(keyName.empty())
302 throw Error("Incorrect key name " + keyName.toUri());
303
Yingdi Yu87581582014-01-14 14:28:39 -0800304 string keyId = keyName.get(-1).toEscapedString();
305 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700306
307 sqlite3_stmt *statement;
308 sqlite3_prepare_v2(database_, "UPDATE Key SET active=? WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
309
310 sqlite3_bind_int(statement, 1, (isActive ? 1 : 0));
311 sqlite3_bind_text(statement, 2, identityName.toUri(), SQLITE_TRANSIENT);
312 sqlite3_bind_text(statement, 3, keyId, SQLITE_TRANSIENT);
313
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800314 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700315
316 sqlite3_finalize(statement);
317}
318
319bool
Yingdi Yu87581582014-01-14 14:28:39 -0800320SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700321{
322 sqlite3_stmt *statement;
323 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Certificate WHERE cert_name=?", -1, &statement, 0);
324
325 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
326
327 int res = sqlite3_step(statement);
328
329 bool certExist = false;
330 if (res == SQLITE_ROW) {
331 int countAll = sqlite3_column_int(statement, 0);
332 if (countAll > 0)
333 certExist = true;
334 }
335
336 sqlite3_finalize(statement);
337
338 return certExist;
339}
340
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700341void
Yingdi Yu87581582014-01-14 14:28:39 -0800342SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700343{
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800344 std::string certificateName = certificate.getName().toUri();
Yingdi Yu88663af2014-01-15 15:21:38 -0800345 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
346
347 if(keyName.empty())
348 throw Error("Incorrect key name " + keyName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700349
Yingdi Yu87581582014-01-14 14:28:39 -0800350 std::string keyId = keyName.get(-1).toEscapedString();
351 std::string identityName = keyName.getPrefix(-1).toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700352
353 sqlite3_stmt *statement;
354 sqlite3_prepare_v2(database_,
355 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
356 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
357 -1, &statement, 0);
358
359
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800360 _LOG_DEBUG("certName: " << certificateName);
361 sqlite3_bind_text(statement, 1, certificateName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700362
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800363 // this will throw an exception if the signature is not the standard one or there is no key locator present
364 SignatureSha256WithRsa signature(certificate.getSignature());
365 std::string signerName = signature.getKeyLocator().getName().toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700366
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800367 sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
368
369 sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
370 sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700371
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700372 // Convert from milliseconds to seconds since 1/1/1970.
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800373 sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
374 sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700375
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800376 sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700377
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800378 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700379
380 sqlite3_finalize(statement);
381}
382
383void
Yingdi Yu87581582014-01-14 14:28:39 -0800384SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700385{
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700386 const Name& certificateName = certificate.getName();
Yingdi Yu88663af2014-01-15 15:21:38 -0800387 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700388
Yingdi Yu87581582014-01-14 14:28:39 -0800389 if (!doesPublicKeyExist(keyName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800390 throw Error("No corresponding Key record for certificate!" + keyName.toUri() + " " + certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700391
392 // Check if certificate has already existed!
393 if (doesCertificateExist(certificateName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800394 throw Error("Certificate has already been installed!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700395
Yingdi Yu87581582014-01-14 14:28:39 -0800396 string keyId = keyName.get(-1).toEscapedString();
397 Name identity = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700398
399 // Check if the public key of certificate is the same as the key record
400
Yingdi Yu87581582014-01-14 14:28:39 -0800401 ptr_lib::shared_ptr<PublicKey> pubKey = getPublicKey(keyName);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700402
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800403 if (!pubKey || (*pubKey) != certificate.getPublicKeyInfo())
404 throw Error("Certificate does not match the public key!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700405
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700406 // Insert the certificate
407 sqlite3_stmt *statement;
408 sqlite3_prepare_v2(database_,
409 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
410 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
411 -1, &statement, 0);
412
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800413 _LOG_DEBUG("certName: " << certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700414 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
415
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800416 // this will throw an exception if the signature is not the standard one or there is no key locator present
417 SignatureSha256WithRsa signature(certificate.getSignature());
418 std::string signerName = signature.getKeyLocator().getName().toUri();
419
420 sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700421
422 sqlite3_bind_text(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800423 sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700424
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700425 // Convert from milliseconds to seconds since 1/1/1970.
Yingdi Yu88663af2014-01-15 15:21:38 -0800426 sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
427 sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700428
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800429 sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700430
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800431 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700432
433 sqlite3_finalize(statement);
434}
435
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800436ptr_lib::shared_ptr<IdentityCertificate>
Yingdi Yu88663af2014-01-15 15:21:38 -0800437SecPublicInfoSqlite3::getCertificate(const Name &certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700438{
439 if (doesCertificateExist(certificateName)) {
440 sqlite3_stmt *statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700441
Yingdi Yu88663af2014-01-15 15:21:38 -0800442 sqlite3_prepare_v2(database_,
443 "SELECT certificate_data FROM Certificate \
444 WHERE cert_name=? AND not_before<datetime('now') AND not_after>datetime('now') and valid_flag=1",
445 -1, &statement, 0);
446
447 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700448
449 int res = sqlite3_step(statement);
450
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800451 ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700452 if (res == SQLITE_ROW)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800453 {
454 certificate->wireDecode(Block((const uint8_t*)sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0)));
455 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700456 sqlite3_finalize(statement);
457
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800458 return certificate;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700459 }
460 else {
461 _LOG_DEBUG("Certificate does not exist!");
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800462 return ptr_lib::shared_ptr<IdentityCertificate>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700463 }
Jeff Thompson1975def2013-10-09 17:06:43 -0700464}
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700465
466Name
Yingdi Yu87581582014-01-14 14:28:39 -0800467SecPublicInfoSqlite3::getDefaultIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700468{
469 sqlite3_stmt *statement;
470 sqlite3_prepare_v2(database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &statement, 0);
471
472 int res = sqlite3_step(statement);
473
474 Name identity;
475
476 if (res == SQLITE_ROW)
477 identity = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
478
479 sqlite3_finalize(statement);
480
481 return identity;
482}
483
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700484void
Yingdi Yu87581582014-01-14 14:28:39 -0800485SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700486{
487 sqlite3_stmt *statement;
488
489 //Reset previous default identity
490 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=0 WHERE default_identity=1", -1, &statement, 0);
491
492 while (sqlite3_step(statement) == SQLITE_ROW)
493 {}
494
495 sqlite3_finalize(statement);
496
497 //Set current default identity
498 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=1 WHERE identity_name=?", -1, &statement, 0);
499
500 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
501
502 sqlite3_step(statement);
503
504 sqlite3_finalize(statement);
505}
506
Yingdi Yu87581582014-01-14 14:28:39 -0800507Name
508SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700509{
Yingdi Yu87581582014-01-14 14:28:39 -0800510 sqlite3_stmt *statement;
511 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 -0700512
Yingdi Yu87581582014-01-14 14:28:39 -0800513 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
514
515 int res = sqlite3_step(statement);
516
517 Name keyName;
518
519 if (res == SQLITE_ROW)
520 keyName = Name(identityName).append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
521
522 sqlite3_finalize(statement);
523
524 return keyName;
525}
526
527void
528SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
529{
Yingdi Yu88663af2014-01-15 15:21:38 -0800530 if(keyName.empty())
531 throw Error("Incorrect key name " + keyName.toUri());
532
Yingdi Yu87581582014-01-14 14:28:39 -0800533 string keyId = keyName.get(-1).toEscapedString();
534 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700535
536 sqlite3_stmt *statement;
537
538 //Reset previous default Key
539 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", -1, &statement, 0);
540
541 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
542
543 while (sqlite3_step(statement) == SQLITE_ROW)
544 {}
545
546 sqlite3_finalize(statement);
547
548 //Set current default Key
549 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
550
551 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
552 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
553
554 sqlite3_step(statement);
555
556 sqlite3_finalize(statement);
557}
558
Yingdi Yu87581582014-01-14 14:28:39 -0800559Name
560SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700561{
Yingdi Yu88663af2014-01-15 15:21:38 -0800562 if(keyName.empty())
563 return Name();
564
Yingdi Yu87581582014-01-14 14:28:39 -0800565 string keyId = keyName.get(-1).toEscapedString();
566 Name identityName = keyName.getPrefix(-1);
567
568 sqlite3_stmt *statement;
569 sqlite3_prepare_v2(database_, "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1", -1, &statement, 0);
570
571 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
572 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
573
574 int res = sqlite3_step(statement);
575
576 Name certName;
577
578 if (res == SQLITE_ROW)
579 certName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
580
581 sqlite3_finalize(statement);
582
583 return certName;
584}
585
586void
587SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
588{
589 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
Yingdi Yu88663af2014-01-15 15:21:38 -0800590 if(keyName.empty())
591 throw Error("Incorrect key name for certificate " + certificateName.toUri());
592
Yingdi Yu87581582014-01-14 14:28:39 -0800593 string keyId = keyName.get(-1).toEscapedString();
594 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700595
596 sqlite3_stmt *statement;
597
598 //Reset previous default Key
599 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?", -1, &statement, 0);
600
601 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
602 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
603
604 while (sqlite3_step(statement) == SQLITE_ROW)
605 {}
606
607 sqlite3_finalize(statement);
608
609 //Set current default Key
610 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?", -1, &statement, 0);
611
612 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
613 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
614 sqlite3_bind_text(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
615
616 sqlite3_step(statement);
617
618 sqlite3_finalize(statement);
619}
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800620
621vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800622SecPublicInfoSqlite3::getAllIdentities(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800623{
624 sqlite3_stmt *stmt;
625 if(isDefault)
626 sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &stmt, 0);
627 else
628 sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=0", -1, &stmt, 0);
629
630 vector<Name> nameList;
631 while(sqlite3_step (stmt) == SQLITE_ROW)
632 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 -0700633
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800634 sqlite3_finalize (stmt);
635 return nameList;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700636}
637
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800638vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800639SecPublicInfoSqlite3::getAllKeyNames(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800640{
641 sqlite3_stmt *stmt;
642 if(isDefault)
643 sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=1", -1, &stmt, 0);
644 else
645 sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=0", -1, &stmt, 0);
646
647 vector<Name> nameList;
648 while(sqlite3_step (stmt) == SQLITE_ROW)
649 {
650 Name keyName(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
651 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
652 nameList.push_back(keyName);
653 }
654 sqlite3_finalize (stmt);
655 return nameList;
656}
657
658vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800659SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800660{
661 sqlite3_stmt *stmt;
662 if(isDefault)
663 sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?", -1, &stmt, 0);
664 else
665 sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?", -1, &stmt, 0);
666
667 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size (), SQLITE_TRANSIENT);
668
669 vector<Name> nameList;
670 while(sqlite3_step (stmt) == SQLITE_ROW)
671 {
672 Name keyName(identity);
673 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
674 nameList.push_back(keyName);
675 }
676 sqlite3_finalize (stmt);
677 return nameList;
678}
679
680vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800681SecPublicInfoSqlite3::getAllCertificateNames(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800682{
683 sqlite3_stmt *stmt;
684 if(isDefault)
685 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1", -1, &stmt, 0);
686 else
687 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0", -1, &stmt, 0);
688
689 vector<Name> nameList;
690 while(sqlite3_step (stmt) == SQLITE_ROW)
691 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
692
693 sqlite3_finalize (stmt);
694 return nameList;
695}
696
697vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800698SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800699{
Yingdi Yu88663af2014-01-15 15:21:38 -0800700 if(keyName.empty())
701 return vector<Name>();
702
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800703 sqlite3_stmt *stmt;
704 if(isDefault)
705 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1 and identity_name=? and key_identifier=?", -1, &stmt, 0);
706 else
707 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0 and identity_name=? and key_identifier=?", -1, &stmt, 0);
708
Yingdi Yu87581582014-01-14 14:28:39 -0800709 Name identity = keyName.getPrefix(-1);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800710 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size (), SQLITE_TRANSIENT);
711 std::string baseKeyName = keyName.get(-1).toEscapedString();
712 sqlite3_bind_text(stmt, 2, baseKeyName.c_str(), baseKeyName.size(), SQLITE_TRANSIENT);
713
714 vector<Name> nameList;
715 while(sqlite3_step (stmt) == SQLITE_ROW)
716 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
717
718 sqlite3_finalize (stmt);
719 return nameList;
720}
721
722} // namespace ndn
723
Jeff Thompsonb7523002013-10-09 10:25:00 -0700724#endif // NDN_CPP_HAVE_SQLITE3