blob: 9f2ca137d6b3b97611f186878b7828064e598a12 [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 Yu4f324632014-01-15 18:10:03 -080018#include "../util/logging.hpp"
19#include "../c/util/time.h"
Yingdi Yu61ec2722014-01-20 14:22:32 -080020#include <ndn-cpp-dev/data.hpp>
21#include <ndn-cpp-dev/security/identity-certificate.hpp>
22#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
23#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -080024
Jeff Thompson7ca11f22013-10-04 19:01:30 -070025
Yingdi Yu87581582014-01-14 14:28:39 -080026INIT_LOGGER("BasicKeyMetaInfo");
Jeff Thompson7ca11f22013-10-04 19:01:30 -070027
28using namespace std;
Jeff Thompson7ca11f22013-10-04 19:01:30 -070029
30namespace ndn
31{
32
33static const string INIT_ID_TABLE = "\
34CREATE TABLE IF NOT EXISTS \n \
35 Identity( \n \
36 identity_name BLOB NOT NULL, \n \
37 default_identity INTEGER DEFAULT 0, \n \
38 \
39 PRIMARY KEY (identity_name) \n \
40 ); \n \
41 \
42CREATE INDEX identity_index ON Identity(identity_name); \n \
43";
44
45static const string INIT_KEY_TABLE = "\
46CREATE TABLE IF NOT EXISTS \n \
47 Key( \n \
48 identity_name BLOB NOT NULL, \n \
49 key_identifier BLOB NOT NULL, \n \
50 key_type INTEGER, \n \
51 public_key BLOB, \n \
52 default_key INTEGER DEFAULT 0, \n \
53 active INTEGER DEFAULT 0, \n \
54 \
55 PRIMARY KEY (identity_name, key_identifier) \n \
56 ); \n \
57 \
58CREATE INDEX key_index ON Key(identity_name); \n \
59";
60
61static const string INIT_CERT_TABLE = "\
62CREATE TABLE IF NOT EXISTS \n \
63 Certificate( \n \
64 cert_name BLOB NOT NULL, \n \
65 cert_issuer BLOB NOT NULL, \n \
66 identity_name BLOB NOT NULL, \n \
67 key_identifier BLOB NOT NULL, \n \
68 not_before TIMESTAMP, \n \
69 not_after TIMESTAMP, \n \
70 certificate_data BLOB NOT NULL, \n \
Jeff Thompson22285ec2013-10-22 17:43:02 -070071 valid_flag INTEGER DEFAULT 1, \n \
Jeff Thompson7ca11f22013-10-04 19:01:30 -070072 default_cert INTEGER DEFAULT 0, \n \
73 \
74 PRIMARY KEY (cert_name) \n \
75 ); \n \
76 \
77CREATE INDEX cert_index ON Certificate(cert_name); \n \
78CREATE INDEX subject ON Certificate(identity_name); \n \
79";
80
81/**
82 * A utility function to call the normal sqlite3_bind_text where the value and length are value.c_str() and value.size().
83 */
84static int sqlite3_bind_text(sqlite3_stmt* statement, int index, const string& value, void(*destructor)(void*))
85{
86 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
87}
88
Yingdi Yu87581582014-01-14 14:28:39 -080089SecPublicInfoSqlite3::SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -070090{
Jeff Thompson351ac302013-10-19 18:45:00 -070091 // 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 -070092 // TODO: Handle non-unix file system paths which don't use '/'.
Jeff Thompson351ac302013-10-19 18:45:00 -070093 const char* home = getenv("HOME");
94 if (!home || *home == '\0')
95 // Don't expect this to happen;
96 home = ".";
97 string homeDir(home);
98 if (homeDir[homeDir.size() - 1] == '/')
99 // Strip the ending '/'.
100 homeDir.erase(homeDir.size() - 1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700101
Jeff Thompsonac64b132013-11-25 15:04:53 -0800102 string identityDir = homeDir + '/' + ".ndnx";
103 // TODO: Handle non-unix file systems which don't have "mkdir -p".
Jeff Thompsonab5440f2013-10-22 11:54:00 -0700104 ::system(("mkdir -p " + identityDir).c_str());
Jeff Thompson351ac302013-10-19 18:45:00 -0700105
Yingdi Yu04020922014-01-22 12:46:53 -0800106 int res = sqlite3_open((identityDir + '/' + "ndnsec-public-info.db").c_str(), &database_);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700107
108 if (res != SQLITE_OK)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800109 throw Error("identity DB cannot be opened/created");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700110
111 //Check if Key table exists;
112 sqlite3_stmt *statement;
113 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 -0700114 res = sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700115
116 bool idTableExists = false;
117 if (res == SQLITE_ROW)
118 idTableExists = true;
119
120 sqlite3_finalize(statement);
121
122 if (!idTableExists) {
123 char *errorMessage = 0;
124 res = sqlite3_exec(database_, INIT_ID_TABLE.c_str(), NULL, NULL, &errorMessage);
125
126 if (res != SQLITE_OK && errorMessage != 0) {
127 _LOG_TRACE("Init \"error\" in Identity: " << errorMessage);
128 sqlite3_free(errorMessage);
129 }
130 }
131
132 //Check if Key table exists;
133 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Key'", -1, &statement, 0);
134 res = sqlite3_step(statement);
135
136 bool keyTableExists = false;
137 if (res == SQLITE_ROW)
138 keyTableExists = true;
139
140 sqlite3_finalize(statement);
141
142 if (!keyTableExists) {
143 char *errorMessage = 0;
144 res = sqlite3_exec(database_, INIT_KEY_TABLE.c_str(), NULL, NULL, &errorMessage);
145
146 if (res != SQLITE_OK && errorMessage != 0) {
147 _LOG_TRACE("Init \"error\" in KEY: " << errorMessage);
148 sqlite3_free(errorMessage);
149 }
150 }
151
152 //Check if Certificate table exists;
153 sqlite3_prepare_v2(database_, "SELECT name FROM sqlite_master WHERE type='table' And name='Certificate'", -1, &statement, 0);
154 res = sqlite3_step(statement);
155
156 bool idCertificateTableExists = false;
157 if (res == SQLITE_ROW)
158 idCertificateTableExists = true;
159
160 sqlite3_finalize(statement);
161
162 if (!idCertificateTableExists) {
163 char *errorMessage = 0;
164 res = sqlite3_exec(database_, INIT_CERT_TABLE.c_str(), NULL, NULL, &errorMessage);
165
166 if (res != SQLITE_OK && errorMessage != 0) {
167 _LOG_TRACE("Init \"error\" in ID-CERT: " << errorMessage);
168 sqlite3_free(errorMessage);
169 }
170 }
171}
172
Yingdi Yu87581582014-01-14 14:28:39 -0800173SecPublicInfoSqlite3::~SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700174{
175}
176
177bool
Yingdi Yu87581582014-01-14 14:28:39 -0800178SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700179{
180 bool result = false;
181
182 sqlite3_stmt *statement;
183 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Identity WHERE identity_name=?", -1, &statement, 0);
184
185 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
186 int res = sqlite3_step(statement);
187
188 if (res == SQLITE_ROW) {
189 int countAll = sqlite3_column_int(statement, 0);
190 if (countAll > 0)
191 result = true;
192 }
193
194 sqlite3_finalize(statement);
195
196 return result;
197}
198
199void
Yingdi Yu87581582014-01-14 14:28:39 -0800200SecPublicInfoSqlite3::addIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700201{
202 if (doesIdentityExist(identityName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800203 throw Error("Identity already exists");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700204
205 sqlite3_stmt *statement;
206
207 sqlite3_prepare_v2(database_, "INSERT INTO Identity (identity_name) values (?)", -1, &statement, 0);
208
209 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
210
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800211 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700212
213 sqlite3_finalize(statement);
214}
215
216bool
Yingdi Yu87581582014-01-14 14:28:39 -0800217SecPublicInfoSqlite3::revokeIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700218{
219 //TODO:
220 return false;
221}
222
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700223bool
Yingdi Yu87581582014-01-14 14:28:39 -0800224SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700225{
Yingdi Yu88663af2014-01-15 15:21:38 -0800226 if(keyName.empty())
227 throw Error("Incorrect key name " + keyName.toUri());
228
Yingdi Yu87581582014-01-14 14:28:39 -0800229 string keyId = keyName.get(-1).toEscapedString();
230 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700231
232 sqlite3_stmt *statement;
233 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
234
235 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
236 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
237
238 int res = sqlite3_step(statement);
239
240 bool keyIdExist = false;
241 if (res == SQLITE_ROW) {
242 int countAll = sqlite3_column_int(statement, 0);
243 if (countAll > 0)
244 keyIdExist = true;
245 }
246
247 sqlite3_finalize(statement);
248
249 return keyIdExist;
250}
251
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700252void
Yingdi Yu87581582014-01-14 14:28:39 -0800253SecPublicInfoSqlite3::addPublicKey(const Name& keyName, KeyType keyType, const PublicKey& publicKeyDer)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700254{
Yingdi Yu88663af2014-01-15 15:21:38 -0800255 if(keyName.empty())
256 throw Error("Incorrect key name " + keyName.toUri());
257
Yingdi Yu87581582014-01-14 14:28:39 -0800258 string keyId = keyName.get(-1).toEscapedString();
259 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700260
261
262 if (!doesIdentityExist(identityName))
263 addIdentity(identityName);
264
Yingdi Yu87581582014-01-14 14:28:39 -0800265 if (doesPublicKeyExist(keyName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800266 throw Error("a key with the same name already exists!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700267
268 sqlite3_stmt *statement;
269 sqlite3_prepare_v2(database_, "INSERT INTO Key (identity_name, key_identifier, key_type, public_key) values (?, ?, ?, ?)", -1, &statement, 0);
270
271 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
272 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
273 sqlite3_bind_int(statement, 3, (int)keyType);
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800274 sqlite3_bind_blob(statement, 4, publicKeyDer.get().buf(), publicKeyDer.get().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700275
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800276 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700277
278 sqlite3_finalize(statement);
279}
280
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800281ptr_lib::shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800282SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700283{
Yingdi Yu87581582014-01-14 14:28:39 -0800284 if (!doesPublicKeyExist(keyName)) {
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700285 _LOG_DEBUG("keyName does not exist");
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800286 return ptr_lib::shared_ptr<PublicKey>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700287 }
288
Yingdi Yu87581582014-01-14 14:28:39 -0800289 string keyId = keyName.get(-1).toEscapedString();
290 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700291
292 sqlite3_stmt *statement;
293 sqlite3_prepare_v2(database_, "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
294
295 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
296 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
297
298 int res = sqlite3_step(statement);
299
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800300 ptr_lib::shared_ptr<PublicKey> result;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700301 if (res == SQLITE_ROW)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800302 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 -0700303
304 sqlite3_finalize(statement);
305
306 return result;
307}
308
309void
Yingdi Yu87581582014-01-14 14:28:39 -0800310SecPublicInfoSqlite3::updateKeyStatus(const Name& keyName, bool isActive)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700311{
Yingdi Yu88663af2014-01-15 15:21:38 -0800312 if(keyName.empty())
313 throw Error("Incorrect key name " + keyName.toUri());
314
Yingdi Yu87581582014-01-14 14:28:39 -0800315 string keyId = keyName.get(-1).toEscapedString();
316 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700317
318 sqlite3_stmt *statement;
319 sqlite3_prepare_v2(database_, "UPDATE Key SET active=? WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
320
321 sqlite3_bind_int(statement, 1, (isActive ? 1 : 0));
322 sqlite3_bind_text(statement, 2, identityName.toUri(), SQLITE_TRANSIENT);
323 sqlite3_bind_text(statement, 3, keyId, SQLITE_TRANSIENT);
324
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800325 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700326
327 sqlite3_finalize(statement);
328}
329
330bool
Yingdi Yu87581582014-01-14 14:28:39 -0800331SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700332{
333 sqlite3_stmt *statement;
334 sqlite3_prepare_v2(database_, "SELECT count(*) FROM Certificate WHERE cert_name=?", -1, &statement, 0);
335
336 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
337
338 int res = sqlite3_step(statement);
339
340 bool certExist = false;
341 if (res == SQLITE_ROW) {
342 int countAll = sqlite3_column_int(statement, 0);
343 if (countAll > 0)
344 certExist = true;
345 }
346
347 sqlite3_finalize(statement);
348
349 return certExist;
350}
351
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700352void
Yingdi Yu87581582014-01-14 14:28:39 -0800353SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700354{
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800355 std::string certificateName = certificate.getName().toUri();
Yingdi Yu88663af2014-01-15 15:21:38 -0800356 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
357
358 if(keyName.empty())
359 throw Error("Incorrect key name " + keyName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700360
Yingdi Yu87581582014-01-14 14:28:39 -0800361 std::string keyId = keyName.get(-1).toEscapedString();
362 std::string identityName = keyName.getPrefix(-1).toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700363
364 sqlite3_stmt *statement;
365 sqlite3_prepare_v2(database_,
366 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
367 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
368 -1, &statement, 0);
369
370
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800371 _LOG_DEBUG("certName: " << certificateName);
372 sqlite3_bind_text(statement, 1, certificateName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700373
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800374 // this will throw an exception if the signature is not the standard one or there is no key locator present
375 SignatureSha256WithRsa signature(certificate.getSignature());
376 std::string signerName = signature.getKeyLocator().getName().toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700377
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800378 sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
379
380 sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
381 sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700382
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700383 // Convert from milliseconds to seconds since 1/1/1970.
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800384 sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
385 sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700386
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800387 sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700388
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800389 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700390
391 sqlite3_finalize(statement);
392}
393
394void
Yingdi Yu87581582014-01-14 14:28:39 -0800395SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700396{
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700397 const Name& certificateName = certificate.getName();
Yingdi Yu88663af2014-01-15 15:21:38 -0800398 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700399
Yingdi Yu87581582014-01-14 14:28:39 -0800400 if (!doesPublicKeyExist(keyName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800401 throw Error("No corresponding Key record for certificate!" + keyName.toUri() + " " + certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700402
403 // Check if certificate has already existed!
404 if (doesCertificateExist(certificateName))
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800405 throw Error("Certificate has already been installed!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700406
Yingdi Yu87581582014-01-14 14:28:39 -0800407 string keyId = keyName.get(-1).toEscapedString();
408 Name identity = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700409
410 // Check if the public key of certificate is the same as the key record
411
Yingdi Yu87581582014-01-14 14:28:39 -0800412 ptr_lib::shared_ptr<PublicKey> pubKey = getPublicKey(keyName);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700413
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800414 if (!pubKey || (*pubKey) != certificate.getPublicKeyInfo())
415 throw Error("Certificate does not match the public key!");
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700416
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700417 // Insert the certificate
418 sqlite3_stmt *statement;
419 sqlite3_prepare_v2(database_,
420 "INSERT INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data)\
421 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
422 -1, &statement, 0);
423
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800424 _LOG_DEBUG("certName: " << certificateName.toUri());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700425 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
426
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800427 // this will throw an exception if the signature is not the standard one or there is no key locator present
428 SignatureSha256WithRsa signature(certificate.getSignature());
429 std::string signerName = signature.getKeyLocator().getName().toUri();
430
431 sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700432
433 sqlite3_bind_text(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800434 sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700435
Jeff Thompson9f2b9fc2013-10-19 18:00:12 -0700436 // Convert from milliseconds to seconds since 1/1/1970.
Yingdi Yu88663af2014-01-15 15:21:38 -0800437 sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(certificate.getNotBefore() / 1000));
438 sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(certificate.getNotAfter() / 1000));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700439
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800440 sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700441
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800442 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700443
444 sqlite3_finalize(statement);
445}
446
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800447ptr_lib::shared_ptr<IdentityCertificate>
Yingdi Yu88663af2014-01-15 15:21:38 -0800448SecPublicInfoSqlite3::getCertificate(const Name &certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700449{
450 if (doesCertificateExist(certificateName)) {
451 sqlite3_stmt *statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700452
Yingdi Yu88663af2014-01-15 15:21:38 -0800453 sqlite3_prepare_v2(database_,
454 "SELECT certificate_data FROM Certificate \
455 WHERE cert_name=? AND not_before<datetime('now') AND not_after>datetime('now') and valid_flag=1",
456 -1, &statement, 0);
457
458 sqlite3_bind_text(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700459
460 int res = sqlite3_step(statement);
461
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800462 ptr_lib::shared_ptr<IdentityCertificate> certificate = ptr_lib::make_shared<IdentityCertificate>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700463 if (res == SQLITE_ROW)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800464 {
465 certificate->wireDecode(Block((const uint8_t*)sqlite3_column_blob(statement, 0), sqlite3_column_bytes(statement, 0)));
466 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700467 sqlite3_finalize(statement);
468
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800469 return certificate;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700470 }
471 else {
472 _LOG_DEBUG("Certificate does not exist!");
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800473 return ptr_lib::shared_ptr<IdentityCertificate>();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700474 }
Jeff Thompson1975def2013-10-09 17:06:43 -0700475}
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700476
477Name
Yingdi Yu87581582014-01-14 14:28:39 -0800478SecPublicInfoSqlite3::getDefaultIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700479{
480 sqlite3_stmt *statement;
481 sqlite3_prepare_v2(database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &statement, 0);
482
483 int res = sqlite3_step(statement);
484
485 Name identity;
486
487 if (res == SQLITE_ROW)
488 identity = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
489
490 sqlite3_finalize(statement);
491
492 return identity;
493}
494
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700495void
Yingdi Yu87581582014-01-14 14:28:39 -0800496SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700497{
498 sqlite3_stmt *statement;
499
500 //Reset previous default identity
501 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=0 WHERE default_identity=1", -1, &statement, 0);
502
503 while (sqlite3_step(statement) == SQLITE_ROW)
504 {}
505
506 sqlite3_finalize(statement);
507
508 //Set current default identity
509 sqlite3_prepare_v2(database_, "UPDATE Identity SET default_identity=1 WHERE identity_name=?", -1, &statement, 0);
510
511 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
512
513 sqlite3_step(statement);
514
515 sqlite3_finalize(statement);
516}
517
Yingdi Yu87581582014-01-14 14:28:39 -0800518Name
519SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700520{
Yingdi Yu87581582014-01-14 14:28:39 -0800521 sqlite3_stmt *statement;
522 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 -0700523
Yingdi Yu87581582014-01-14 14:28:39 -0800524 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
525
526 int res = sqlite3_step(statement);
527
528 Name keyName;
529
530 if (res == SQLITE_ROW)
531 keyName = Name(identityName).append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
532
533 sqlite3_finalize(statement);
534
535 return keyName;
536}
537
538void
539SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
540{
Yingdi Yu88663af2014-01-15 15:21:38 -0800541 if(keyName.empty())
542 throw Error("Incorrect key name " + keyName.toUri());
543
Yingdi Yu87581582014-01-14 14:28:39 -0800544 string keyId = keyName.get(-1).toEscapedString();
545 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700546
547 sqlite3_stmt *statement;
548
549 //Reset previous default Key
550 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?", -1, &statement, 0);
551
552 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
553
554 while (sqlite3_step(statement) == SQLITE_ROW)
555 {}
556
557 sqlite3_finalize(statement);
558
559 //Set current default Key
560 sqlite3_prepare_v2(database_, "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?", -1, &statement, 0);
561
562 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
563 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
564
565 sqlite3_step(statement);
566
567 sqlite3_finalize(statement);
568}
569
Yingdi Yu87581582014-01-14 14:28:39 -0800570Name
571SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700572{
Yingdi Yu88663af2014-01-15 15:21:38 -0800573 if(keyName.empty())
574 return Name();
575
Yingdi Yu87581582014-01-14 14:28:39 -0800576 string keyId = keyName.get(-1).toEscapedString();
577 Name identityName = keyName.getPrefix(-1);
578
579 sqlite3_stmt *statement;
580 sqlite3_prepare_v2(database_, "SELECT cert_name FROM Certificate WHERE identity_name=? AND key_identifier=? AND default_cert=1", -1, &statement, 0);
581
582 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
583 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
584
585 int res = sqlite3_step(statement);
586
587 Name certName;
588
589 if (res == SQLITE_ROW)
590 certName = Name(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)), sqlite3_column_bytes(statement, 0)));
591
592 sqlite3_finalize(statement);
593
594 return certName;
595}
596
597void
598SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
599{
600 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
Yingdi Yu88663af2014-01-15 15:21:38 -0800601 if(keyName.empty())
602 throw Error("Incorrect key name for certificate " + certificateName.toUri());
603
Yingdi Yu87581582014-01-14 14:28:39 -0800604 string keyId = keyName.get(-1).toEscapedString();
605 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700606
607 sqlite3_stmt *statement;
608
609 //Reset previous default Key
610 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=0 WHERE default_cert=1 AND identity_name=? AND key_identifier=?", -1, &statement, 0);
611
612 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
613 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
614
615 while (sqlite3_step(statement) == SQLITE_ROW)
616 {}
617
618 sqlite3_finalize(statement);
619
620 //Set current default Key
621 sqlite3_prepare_v2(database_, "UPDATE Certificate SET default_cert=1 WHERE identity_name=? AND key_identifier=? AND cert_name=?", -1, &statement, 0);
622
623 sqlite3_bind_text(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
624 sqlite3_bind_text(statement, 2, keyId, SQLITE_TRANSIENT);
625 sqlite3_bind_text(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
626
627 sqlite3_step(statement);
628
629 sqlite3_finalize(statement);
630}
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800631
632vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800633SecPublicInfoSqlite3::getAllIdentities(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800634{
635 sqlite3_stmt *stmt;
636 if(isDefault)
637 sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=1", -1, &stmt, 0);
638 else
639 sqlite3_prepare_v2 (database_, "SELECT identity_name FROM Identity WHERE default_identity=0", -1, &stmt, 0);
640
641 vector<Name> nameList;
642 while(sqlite3_step (stmt) == SQLITE_ROW)
643 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 -0700644
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800645 sqlite3_finalize (stmt);
646 return nameList;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700647}
648
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800649vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800650SecPublicInfoSqlite3::getAllKeyNames(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800651{
652 sqlite3_stmt *stmt;
653 if(isDefault)
654 sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=1", -1, &stmt, 0);
655 else
656 sqlite3_prepare_v2 (database_, "SELECT identity_name, key_identifier FROM Key WHERE default_key=0", -1, &stmt, 0);
657
658 vector<Name> nameList;
659 while(sqlite3_step (stmt) == SQLITE_ROW)
660 {
661 Name keyName(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
662 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)), sqlite3_column_bytes (stmt, 1)));
663 nameList.push_back(keyName);
664 }
665 sqlite3_finalize (stmt);
666 return nameList;
667}
668
669vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800670SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800671{
672 sqlite3_stmt *stmt;
673 if(isDefault)
674 sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?", -1, &stmt, 0);
675 else
676 sqlite3_prepare_v2 (database_, "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?", -1, &stmt, 0);
677
678 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size (), SQLITE_TRANSIENT);
679
680 vector<Name> nameList;
681 while(sqlite3_step (stmt) == SQLITE_ROW)
682 {
683 Name keyName(identity);
684 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
685 nameList.push_back(keyName);
686 }
687 sqlite3_finalize (stmt);
688 return nameList;
689}
690
691vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800692SecPublicInfoSqlite3::getAllCertificateNames(bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800693{
694 sqlite3_stmt *stmt;
695 if(isDefault)
696 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1", -1, &stmt, 0);
697 else
698 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0", -1, &stmt, 0);
699
700 vector<Name> nameList;
701 while(sqlite3_step (stmt) == SQLITE_ROW)
702 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
703
704 sqlite3_finalize (stmt);
705 return nameList;
706}
707
708vector<Name>
Yingdi Yu87581582014-01-14 14:28:39 -0800709SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800710{
Yingdi Yu88663af2014-01-15 15:21:38 -0800711 if(keyName.empty())
712 return vector<Name>();
713
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800714 sqlite3_stmt *stmt;
715 if(isDefault)
716 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=1 and identity_name=? and key_identifier=?", -1, &stmt, 0);
717 else
718 sqlite3_prepare_v2 (database_, "SELECT cert_name FROM Certificate WHERE default_cert=0 and identity_name=? and key_identifier=?", -1, &stmt, 0);
719
Yingdi Yu87581582014-01-14 14:28:39 -0800720 Name identity = keyName.getPrefix(-1);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800721 sqlite3_bind_text(stmt, 1, identity.toUri().c_str(), identity.toUri().size (), SQLITE_TRANSIENT);
722 std::string baseKeyName = keyName.get(-1).toEscapedString();
723 sqlite3_bind_text(stmt, 2, baseKeyName.c_str(), baseKeyName.size(), SQLITE_TRANSIENT);
724
725 vector<Name> nameList;
726 while(sqlite3_step (stmt) == SQLITE_ROW)
727 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)), sqlite3_column_bytes (stmt, 0)));
728
729 sqlite3_finalize (stmt);
730 return nameList;
731}
732
733} // namespace ndn
734
Jeff Thompsonb7523002013-10-09 10:25:00 -0700735#endif // NDN_CPP_HAVE_SQLITE3