blob: 58d6267fe2c4e5e0206495c69f3db0af55b8eb65 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Jeff Thompson7ca11f22013-10-04 19:01:30 -07002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -070020 *
21 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
22 * @author Jeff Thompson <jefft0@remap.ucla.edu>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070023 */
24
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080025#include "sec-public-info-sqlite3.hpp"
26#include "identity-certificate.hpp"
27#include "signature-sha256-with-rsa.hpp"
Yingdi Yuc8f883c2014-06-20 23:25:22 -070028#include "signature-sha256-with-ecdsa.hpp"
Alexander Afanasyeve2dcdfd2014-02-07 15:53:28 -080029#include "../data.hpp"
30
Yingdi Yu874678f2014-01-22 19:30:34 -080031#include <sqlite3.h>
Jeff Thompson351ac302013-10-19 18:45:00 -070032#include <stdio.h>
Jeff Thompson7ca11f22013-10-04 19:01:30 -070033#include <stdlib.h>
34#include <sstream>
35#include <fstream>
Yingdi Yu0b9c3152014-01-26 16:31:18 -080036#include <boost/filesystem.hpp>
Alexander Afanasyevd409d592014-01-28 18:36:38 -080037
Yingdi Yufc40d872014-02-18 12:56:04 -080038namespace ndn {
Jeff Thompson7ca11f22013-10-04 19:01:30 -070039
Yingdi Yu5ec0ee32014-06-24 16:26:09 -070040using std::string;
41using std::vector;
42
Yingdi Yu41546342014-11-30 23:37:53 -080043const std::string SecPublicInfoSqlite3::SCHEME("pib-sqlite3:");
Jeff Thompson7ca11f22013-10-04 19:01:30 -070044
Yingdi Yu41546342014-11-30 23:37:53 -080045static const string INIT_TPM_INFO_TABLE =
46 "CREATE TABLE IF NOT EXISTS "
47 " TpmInfo( "
48 " tpm_locator BLOB NOT NULL,"
49 " PRIMARY KEY (tpm_locator) "
50 " ); ";
Jeff Thompson7ca11f22013-10-04 19:01:30 -070051
Yingdi Yu41546342014-11-30 23:37:53 -080052static const string INIT_ID_TABLE =
53 "CREATE TABLE IF NOT EXISTS "
54 " Identity( "
55 " identity_name BLOB NOT NULL, "
56 " default_identity INTEGER DEFAULT 0, "
57 " PRIMARY KEY (identity_name) "
58 " ); "
59 "CREATE INDEX identity_index ON Identity(identity_name);";
60
61static const string INIT_KEY_TABLE =
62 "CREATE TABLE IF NOT EXISTS "
63 " Key( "
64 " identity_name BLOB NOT NULL, "
65 " key_identifier BLOB NOT NULL, "
66 " key_type INTEGER, "
67 " public_key BLOB, "
68 " default_key INTEGER DEFAULT 0, "
69 " active INTEGER DEFAULT 0, "
70 " PRIMARY KEY (identity_name, key_identifier)"
71 " ); "
72 "CREATE INDEX key_index ON Key(identity_name); ";
73
74
75static const string INIT_CERT_TABLE =
76 "CREATE TABLE IF NOT EXISTS "
77 " Certificate( "
78 " cert_name BLOB NOT NULL, "
79 " cert_issuer BLOB NOT NULL, "
80 " identity_name BLOB NOT NULL, "
81 " key_identifier BLOB NOT NULL, "
82 " not_before TIMESTAMP, "
83 " not_after TIMESTAMP, "
84 " certificate_data BLOB NOT NULL, "
85 " valid_flag INTEGER DEFAULT 1, "
86 " default_cert INTEGER DEFAULT 0, "
87 " PRIMARY KEY (cert_name) "
88 " ); "
89 "CREATE INDEX cert_index ON Certificate(cert_name); "
90 "CREATE INDEX subject ON Certificate(identity_name);";
Jeff Thompson7ca11f22013-10-04 19:01:30 -070091
92/**
Yingdi Yu4b8c6a22014-04-15 23:00:54 -070093 * A utility function to call the normal sqlite3_bind_text where the value and length are
94 * value.c_str() and value.size().
Jeff Thompson7ca11f22013-10-04 19:01:30 -070095 */
Alexander Afanasyevdb4affc2014-07-15 13:37:16 -070096static int
Yingdi Yu41546342014-11-30 23:37:53 -080097sqlite3_bind_string(sqlite3_stmt* statement,
98 int index,
99 const string& value,
100 void(*destructor)(void*))
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700101{
102 return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
103}
104
Yingdi Yu41546342014-11-30 23:37:53 -0800105static string
106sqlite3_column_string(sqlite3_stmt* statement, int column)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700107{
Yingdi Yu41546342014-11-30 23:37:53 -0800108 return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
109 sqlite3_column_bytes(statement, column));
110}
111
112SecPublicInfoSqlite3::SecPublicInfoSqlite3(const std::string& dir)
113 : SecPublicInfo(dir)
114 , m_database(nullptr)
115{
116 boost::filesystem::path identityDir;
117 if (dir == "")
118 identityDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
119 else
120 identityDir = boost::filesystem::path(dir) / ".ndn";
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700121 boost::filesystem::create_directories(identityDir);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700122
Alexander Afanasyev5b60f702014-02-07 12:55:24 -0800123 /// @todo Add define for windows/unix in wscript. The following may completely fail on windows
124 int res = sqlite3_open_v2((identityDir / "ndnsec-public-info.db").c_str(), &m_database,
125 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700126#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
Alexander Afanasyev44471462014-02-12 11:21:51 -0800127 "unix-dotfile"
Alexander Afanasyev5b60f702014-02-07 12:55:24 -0800128#else
129 0
130#endif
131 );
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700132 if (res != SQLITE_OK)
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800133 throw Error("identity DB cannot be opened/created");
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134
Yingdi Yu41546342014-11-30 23:37:53 -0800135
Junxiao Shi98acbb02014-12-02 11:00:42 -0700136 BOOST_ASSERT(m_database != nullptr);
137
Yingdi Yu41546342014-11-30 23:37:53 -0800138 initializeTable("TpmInfo", INIT_TPM_INFO_TABLE); // Check if TpmInfo table exists;
139 initializeTable("Identity", INIT_ID_TABLE); // Check if Identity table exists;
140 initializeTable("Key", INIT_KEY_TABLE); // Check if Key table exists;
141 initializeTable("Certificate", INIT_CERT_TABLE); // Check if Certificate table exists;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700142}
143
Yingdi Yu87581582014-01-14 14:28:39 -0800144SecPublicInfoSqlite3::~SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700145{
Junxiao Shi98acbb02014-12-02 11:00:42 -0700146 sqlite3_close(m_database);
147 m_database = nullptr;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700148}
149
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700150bool
Yingdi Yu41546342014-11-30 23:37:53 -0800151SecPublicInfoSqlite3::doesTableExist(const string& tableName)
152{
153 // Check if the table exists;
154 bool doesTableExist = false;
155 string checkingString =
156 "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "'";
157
158 sqlite3_stmt* statement;
159 sqlite3_prepare_v2(m_database, checkingString.c_str(), -1, &statement, 0);
160
161 int result = sqlite3_step(statement);
162 if (result == SQLITE_ROW)
163 doesTableExist = true;
164 sqlite3_finalize(statement);
165
166 return doesTableExist;
167}
168
169bool
170SecPublicInfoSqlite3::initializeTable(const string& tableName, const string& initCommand)
171{
172 // Create the table if it does not exist
173 if (!doesTableExist(tableName)) {
174 char* errorMessage = 0;
175 int result = sqlite3_exec(m_database, initCommand.c_str(), NULL, NULL, &errorMessage);
176
177 if (result != SQLITE_OK && errorMessage != 0) {
178 sqlite3_free(errorMessage);
179 return false;
180 }
181 }
182
183 return true;
184}
185
186void
187SecPublicInfoSqlite3::deleteTable(const string& tableName)
188{
189 string query = "DROP TABLE IF EXISTS " + tableName;
190
191 sqlite3_stmt* statement;
192 sqlite3_prepare_v2(m_database, query.c_str(), -1, &statement, 0);
193
194 sqlite3_step(statement);
195 sqlite3_finalize(statement);
196}
197
198void
199SecPublicInfoSqlite3::setTpmLocator(const string& tpmLocator)
200{
201 string currentTpm;
202 try {
203 currentTpm = getTpmLocator();
204 }
205 catch (SecPublicInfo::Error&) {
206 setTpmLocatorInternal(tpmLocator, false); // set tpmInfo without resetting
207 return;
208 }
209
210 if (currentTpm == tpmLocator)
211 return; // if the same, nothing will be changed
212
213 setTpmLocatorInternal(tpmLocator, true); // set tpmInfo and reset pib
214}
215
216string
217SecPublicInfoSqlite3::getTpmLocator()
218{
219 sqlite3_stmt* statement;
220 sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM TpmInfo", -1, &statement, 0);
221
222 int res = sqlite3_step(statement);
223
224 if (res == SQLITE_ROW) {
225 string tpmLocator = sqlite3_column_string(statement, 0);
226 sqlite3_finalize(statement);
227 return tpmLocator;
228 }
229 else {
230 sqlite3_finalize(statement);
231 throw SecPublicInfo::Error("TPM info does not exist");
232 }
233}
234
235void
236SecPublicInfoSqlite3::setTpmLocatorInternal(const string& tpmLocator, bool needReset)
237{
238 sqlite3_stmt* statement;
239
240 if (needReset) {
241 deleteTable("Identity");
242 deleteTable("Key");
243 deleteTable("Certificate");
244
245 initializeTable("Identity", INIT_ID_TABLE);
246 initializeTable("Key", INIT_KEY_TABLE);
247 initializeTable("Certificate", INIT_CERT_TABLE);
248
249 sqlite3_prepare_v2(m_database, "UPDATE TpmInfo SET tpm_locator = ?",
250 -1, &statement, 0);
251 sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
252 }
253 else {
254 // no reset implies there is no tpmLocator record, insert one
255 sqlite3_prepare_v2(m_database, "INSERT INTO TpmInfo (tpm_locator) VALUES (?)",
256 -1, &statement, 0);
257 sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
258 }
259
260 sqlite3_step(statement);
261 sqlite3_finalize(statement);
262}
263
264std::string
265SecPublicInfoSqlite3::getPibLocator()
266{
267 return string("pib-sqlite3:").append(m_location);
268}
269
270bool
Yingdi Yu87581582014-01-14 14:28:39 -0800271SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700272{
273 bool result = false;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700274
275 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700276 sqlite3_prepare_v2(m_database,
277 "SELECT count(*) FROM Identity WHERE identity_name=?",
278 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700279
Yingdi Yu41546342014-11-30 23:37:53 -0800280 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700281 int res = sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700282
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700283 if (res == SQLITE_ROW) {
284 int countAll = sqlite3_column_int(statement, 0);
285 if (countAll > 0)
286 result = true;
287 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700288
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700289 sqlite3_finalize(statement);
290
291 return result;
292}
293
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700294void
Yingdi Yu87581582014-01-14 14:28:39 -0800295SecPublicInfoSqlite3::addIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700296{
Yingdi Yu05842f22014-04-15 19:21:56 -0700297 if (doesIdentityExist(identityName))
298 return;
299
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700300 sqlite3_stmt* statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700301
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700302 sqlite3_prepare_v2(m_database,
303 "INSERT OR REPLACE INTO Identity (identity_name) values (?)",
304 -1, &statement, 0);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700305
Yingdi Yu41546342014-11-30 23:37:53 -0800306 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700307
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800308 sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700309
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700310 sqlite3_finalize(statement);
311}
312
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700313bool
Yingdi Yu87581582014-01-14 14:28:39 -0800314SecPublicInfoSqlite3::revokeIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700315{
316 //TODO:
317 return false;
318}
319
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700320bool
Yingdi Yu87581582014-01-14 14:28:39 -0800321SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700322{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700323 if (keyName.empty())
Yingdi Yu88663af2014-01-15 15:21:38 -0800324 throw Error("Incorrect key name " + keyName.toUri());
325
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700326 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800327 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700328
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700329 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700330 sqlite3_prepare_v2(m_database,
331 "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?",
332 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700333
Yingdi Yu41546342014-11-30 23:37:53 -0800334 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
335 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700336
337 int res = sqlite3_step(statement);
338
339 bool keyIdExist = false;
340 if (res == SQLITE_ROW) {
341 int countAll = sqlite3_column_int(statement, 0);
342 if (countAll > 0)
343 keyIdExist = true;
344 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700345
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700346 sqlite3_finalize(statement);
347
348 return keyIdExist;
349}
350
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700351void
Yingdi Yu40b53092014-06-17 17:10:02 -0700352SecPublicInfoSqlite3::addKey(const Name& keyName,
353 const PublicKey& publicKeyDer)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700354{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700355 if (keyName.empty())
Yingdi Yu2e57a582014-02-20 23:34:43 -0800356 return;
Yingdi Yu88663af2014-01-15 15:21:38 -0800357
Yingdi Yu05842f22014-04-15 19:21:56 -0700358 if (doesPublicKeyExist(keyName))
359 return;
360
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700361 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800362 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700363
Yingdi Yu2e57a582014-02-20 23:34:43 -0800364 addIdentity(identityName);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700365
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700366 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700367 sqlite3_prepare_v2(m_database,
368 "INSERT OR REPLACE INTO Key \
369 (identity_name, key_identifier, key_type, public_key) \
370 values (?, ?, ?, ?)",
371 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700372
Yingdi Yu41546342014-11-30 23:37:53 -0800373 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
374 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu40b53092014-06-17 17:10:02 -0700375 sqlite3_bind_int(statement, 3, publicKeyDer.getKeyType());
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700376 sqlite3_bind_blob(statement, 4,
377 publicKeyDer.get().buf(),
378 publicKeyDer.get().size(),
379 SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700380
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800381 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700382
383 sqlite3_finalize(statement);
384}
385
Yingdi Yu2e57a582014-02-20 23:34:43 -0800386shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800387SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700388{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700389 if (keyName.empty())
Yingdi Yu2e57a582014-02-20 23:34:43 -0800390 {
Yingdi Yu2e57a582014-02-20 23:34:43 -0800391 throw Error("SecPublicInfoSqlite3::getPublicKey Empty keyName");
392 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700393
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700394 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800395 Name identityName = keyName.getPrefix(-1);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700396
397 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700398 sqlite3_prepare_v2(m_database,
399 "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?",
400 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700401
Yingdi Yu41546342014-11-30 23:37:53 -0800402 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
403 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700404
405 int res = sqlite3_step(statement);
406
Yingdi Yu2e57a582014-02-20 23:34:43 -0800407 shared_ptr<PublicKey> result;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700408 if (res == SQLITE_ROW)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800409 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700410 result =
411 make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
412 sqlite3_column_bytes(statement, 0));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800413 sqlite3_finalize(statement);
414 return result;
415 }
416 else
417 {
418 sqlite3_finalize(statement);
419 throw Error("SecPublicInfoSqlite3::getPublicKey public key does not exist");
420 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700421}
422
Yingdi Yu40b53092014-06-17 17:10:02 -0700423KeyType
424SecPublicInfoSqlite3::getPublicKeyType(const Name& keyName)
425{
426 if (keyName.empty())
427 return KEY_TYPE_NULL;
428
429 string keyId = keyName.get(-1).toUri();
430 Name identityName = keyName.getPrefix(-1);
431
432 sqlite3_stmt* statement;
433 sqlite3_prepare_v2(m_database,
434 "SELECT key_type FROM Key WHERE identity_name=? AND key_identifier=?",
435 -1, &statement, 0);
436
Yingdi Yu41546342014-11-30 23:37:53 -0800437 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
438 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu40b53092014-06-17 17:10:02 -0700439
440 int res = sqlite3_step(statement);
441
442 if (res == SQLITE_ROW)
443 {
444 int typeValue = sqlite3_column_int(statement, 0);
445 sqlite3_finalize(statement);
446 return static_cast<KeyType>(typeValue);
447 }
448 else
449 {
450 sqlite3_finalize(statement);
451 return KEY_TYPE_NULL;
452 }
453
454}
455
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700456bool
Yingdi Yu87581582014-01-14 14:28:39 -0800457SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700458{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700459 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700460 sqlite3_prepare_v2(m_database,
461 "SELECT count(*) FROM Certificate WHERE cert_name=?",
462 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700463
Yingdi Yu41546342014-11-30 23:37:53 -0800464 sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700465
466 int res = sqlite3_step(statement);
467
468 bool certExist = false;
469 if (res == SQLITE_ROW) {
470 int countAll = sqlite3_column_int(statement, 0);
471 if (countAll > 0)
472 certExist = true;
473 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700474
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700475 sqlite3_finalize(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700476
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700477 return certExist;
478}
479
Yingdi Yu2e57a582014-02-20 23:34:43 -0800480// void
481// SecPublicInfoSqlite3::addAnyCertificate(const IdentityCertificate& certificate)
482// {
483// std::string certificateName = certificate.getName().toUri();
484// Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
Yingdi Yu88663af2014-01-15 15:21:38 -0800485
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700486// if (keyName.empty())
Yingdi Yu2e57a582014-02-20 23:34:43 -0800487// return;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700488
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700489// std::string keyId = keyName.get(-1).toUri();
Yingdi Yu2e57a582014-02-20 23:34:43 -0800490// std::string identityName = keyName.getPrefix(-1).toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700491
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700492// sqlite3_stmt* statement;
493// sqlite3_prepare_v2(m_database,
Alexander Afanasyev1dd95c52014-03-22 19:11:36 -0700494// "INSERT OR REPLACE INTO Certificate (cert_name, cert_issuer, identity_name, key_identifier, not_before, not_after, certificate_data) "
495// "VALUES (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
Yingdi Yu2e57a582014-02-20 23:34:43 -0800496// -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700497
Yingdi Yu2e57a582014-02-20 23:34:43 -0800498// sqlite3_bind_text(statement, 1, certificateName, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700499
Yingdi Yu2e57a582014-02-20 23:34:43 -0800500// try
501// {
502// SignatureSha256WithRsa signature(certificate.getSignature());
503// std::string signerName = signature.getKeyLocator().getName().toUri();
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700504
Yingdi Yu2e57a582014-02-20 23:34:43 -0800505// sqlite3_bind_text(statement, 2, signerName, SQLITE_STATIC);
506// }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700507// catch (KeyLocator::Error& e)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800508// {
Yingdi Yu2e57a582014-02-20 23:34:43 -0800509// return;
510// }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700511// catch (SignatureSha256WithRsa::Error& e)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800512// {
Yingdi Yu2e57a582014-02-20 23:34:43 -0800513// return;
514// }
Alexander Afanasyevfab95ed2014-01-05 23:26:30 -0800515
Yingdi Yu2e57a582014-02-20 23:34:43 -0800516// sqlite3_bind_text(statement, 3, identityName, SQLITE_STATIC);
517// sqlite3_bind_text(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700518
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700519// // Convert from time::milliseconds to time::seconds since 1/1/1970.
520// sqlite3_bind_int64(statement, 5, static_cast<sqlite3_int64>(
521// time::toUnixTimestamp(certificate.getNotBefore()).count()));
522// sqlite3_bind_int64(statement, 6, static_cast<sqlite3_int64>(
523// time::toUnixTimestamp(certificate.getNotAfter()).count()));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700524
Yingdi Yu2e57a582014-02-20 23:34:43 -0800525// sqlite3_bind_blob(statement, 7, certificate.wireEncode().wire(), certificate.wireEncode().size(), SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700526
Yingdi Yu2e57a582014-02-20 23:34:43 -0800527// sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700528
Yingdi Yu2e57a582014-02-20 23:34:43 -0800529// sqlite3_finalize(statement);
530// }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700531
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700532void
Yingdi Yu87581582014-01-14 14:28:39 -0800533SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700534{
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700535 const Name& certificateName = certificate.getName();
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700536 // KeyName is from IdentityCertificate name, so should be qualified.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700537 Name keyName =
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700538 IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700539
Yingdi Yu40b53092014-06-17 17:10:02 -0700540 addKey(keyName, certificate.getPublicKeyInfo());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700541
Yingdi Yu05842f22014-04-15 19:21:56 -0700542 if (doesCertificateExist(certificateName))
543 return;
544
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700545 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800546 Name identity = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700547
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700548 // Insert the certificate
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700549 sqlite3_stmt* statement;
550 sqlite3_prepare_v2(m_database,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700551 "INSERT OR REPLACE INTO Certificate \
552 (cert_name, cert_issuer, identity_name, key_identifier, \
553 not_before, not_after, certificate_data) \
554 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700555 -1, &statement, 0);
556
Yingdi Yu41546342014-11-30 23:37:53 -0800557 sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700558
Yingdi Yu2e57a582014-02-20 23:34:43 -0800559 try
560 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700561 // this will throw an exception if the signature is not the standard one
562 // or there is no key locator present
Yingdi Yu4a557052014-07-09 16:40:37 -0700563 std::string signerName = certificate.getSignature().getKeyLocator().getName().toUri();
Yingdi Yu41546342014-11-30 23:37:53 -0800564 sqlite3_bind_string(statement, 2, signerName, SQLITE_TRANSIENT);
Yingdi Yu2e57a582014-02-20 23:34:43 -0800565 }
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600566 catch (tlv::Error& e)
Yingdi Yu4a557052014-07-09 16:40:37 -0700567 {
568 return;
569 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700570
Yingdi Yu41546342014-11-30 23:37:53 -0800571 sqlite3_bind_string(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
572 sqlite3_bind_string(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700573
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700574 sqlite3_bind_int64(statement, 5,
575 static_cast<sqlite3_int64>(
576 time::toUnixTimestamp(certificate.getNotBefore()).count()));
577 sqlite3_bind_int64(statement, 6,
578 static_cast<sqlite3_int64>(
579 time::toUnixTimestamp(certificate.getNotAfter()).count()));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700580
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700581 sqlite3_bind_blob(statement, 7,
582 certificate.wireEncode().wire(),
583 certificate.wireEncode().size(),
584 SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700585
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800586 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700587
588 sqlite3_finalize(statement);
589}
590
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700591shared_ptr<IdentityCertificate>
592SecPublicInfoSqlite3::getCertificate(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700593{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700594 sqlite3_stmt* statement;
595
596 sqlite3_prepare_v2(m_database,
Yingdi Yu4270f202014-01-28 14:19:16 -0800597 "SELECT certificate_data FROM Certificate WHERE cert_name=?",
598 -1, &statement, 0);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700599
Yingdi Yu41546342014-11-30 23:37:53 -0800600 sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700601
Yingdi Yu4270f202014-01-28 14:19:16 -0800602 int res = sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700603
Yingdi Yu4270f202014-01-28 14:19:16 -0800604 if (res == SQLITE_ROW)
605 {
Yingdi Yu2e57a582014-02-20 23:34:43 -0800606 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700607 certificate->wireDecode(Block(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700608 sqlite3_column_bytes(statement, 0)));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800609 sqlite3_finalize(statement);
610 return certificate;
Yingdi Yu4270f202014-01-28 14:19:16 -0800611 }
Yingdi Yu2e57a582014-02-20 23:34:43 -0800612 else
613 {
614 sqlite3_finalize(statement);
615 throw Error("SecPublicInfoSqlite3::getCertificate certificate does not exist");
616 }
Jeff Thompson1975def2013-10-09 17:06:43 -0700617}
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700618
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700619
620Name
Yingdi Yu87581582014-01-14 14:28:39 -0800621SecPublicInfoSqlite3::getDefaultIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700622{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700623 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700624 sqlite3_prepare_v2(m_database,
625 "SELECT identity_name FROM Identity WHERE default_identity=1",
626 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700627
628 int res = sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700629
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700630 if (res == SQLITE_ROW)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800631 {
Yingdi Yu41546342014-11-30 23:37:53 -0800632 Name identity(sqlite3_column_string(statement, 0));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800633 sqlite3_finalize(statement);
634 return identity;
635 }
636 else
637 {
638 sqlite3_finalize(statement);
639 throw Error("SecPublicInfoSqlite3::getDefaultIdentity no default identity");
640 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700641}
642
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700643void
Yingdi Yu87581582014-01-14 14:28:39 -0800644SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700645{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800646 addIdentity(identityName);
647
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700648 sqlite3_stmt* statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700649
650 //Reset previous default identity
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700651 sqlite3_prepare_v2(m_database,
652 "UPDATE Identity SET default_identity=0 WHERE default_identity=1",
653 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700654
655 while (sqlite3_step(statement) == SQLITE_ROW)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700656 {
657 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700658
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700659 sqlite3_finalize(statement);
660
661 //Set current default identity
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700662 sqlite3_prepare_v2(m_database,
663 "UPDATE Identity SET default_identity=1 WHERE identity_name=?",
664 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700665
Yingdi Yu41546342014-11-30 23:37:53 -0800666 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700667
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700668 sqlite3_step(statement);
669
670 sqlite3_finalize(statement);
671}
672
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700673Name
Yingdi Yu87581582014-01-14 14:28:39 -0800674SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700675{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700676 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700677 sqlite3_prepare_v2(m_database,
678 "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1",
679 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700680
Yingdi Yu41546342014-11-30 23:37:53 -0800681 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Yingdi Yu87581582014-01-14 14:28:39 -0800682
683 int res = sqlite3_step(statement);
Yingdi Yu87581582014-01-14 14:28:39 -0800684
685 if (res == SQLITE_ROW)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800686 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700687 Name keyName = identityName;
688 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)),
689 sqlite3_column_bytes(statement, 0)));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800690 sqlite3_finalize(statement);
691 return keyName;
692 }
693 else
694 {
695 sqlite3_finalize(statement);
696 throw Error("SecPublicInfoSqlite3::getDefaultKeyNameForIdentity key not found");
697 }
Yingdi Yu87581582014-01-14 14:28:39 -0800698}
699
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700700void
Yingdi Yu87581582014-01-14 14:28:39 -0800701SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
702{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700703 if (!doesPublicKeyExist(keyName))
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700704 throw Error("Key does not exist:" + keyName.toUri());
Yingdi Yu88663af2014-01-15 15:21:38 -0800705
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700706 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800707 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700708
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700709 sqlite3_stmt* statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700710
711 //Reset previous default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700712 sqlite3_prepare_v2(m_database,
713 "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?",
714 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700715
Yingdi Yu41546342014-11-30 23:37:53 -0800716 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700717
718 while (sqlite3_step(statement) == SQLITE_ROW)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700719 ;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700720
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700721 sqlite3_finalize(statement);
722
723 //Set current default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700724 sqlite3_prepare_v2(m_database,
725 "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?",
726 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700727
Yingdi Yu41546342014-11-30 23:37:53 -0800728 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
729 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700730
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700731 sqlite3_step(statement);
732
733 sqlite3_finalize(statement);
734}
735
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700736Name
Yingdi Yu87581582014-01-14 14:28:39 -0800737SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700738{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700739 if (keyName.empty())
Yingdi Yu2e57a582014-02-20 23:34:43 -0800740 throw Error("SecPublicInfoSqlite3::getDefaultCertificateNameForKey wrong key");
Yingdi Yu88663af2014-01-15 15:21:38 -0800741
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700742 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800743 Name identityName = keyName.getPrefix(-1);
744
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700745 sqlite3_stmt* statement;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700746 sqlite3_prepare_v2(m_database,
747 "SELECT cert_name FROM Certificate \
748 WHERE identity_name=? AND key_identifier=? AND default_cert=1",
749 -1, &statement, 0);
Yingdi Yu87581582014-01-14 14:28:39 -0800750
Yingdi Yu41546342014-11-30 23:37:53 -0800751 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
752 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu87581582014-01-14 14:28:39 -0800753
754 int res = sqlite3_step(statement);
755
Yingdi Yu87581582014-01-14 14:28:39 -0800756 if (res == SQLITE_ROW)
Yingdi Yu2e57a582014-02-20 23:34:43 -0800757 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700758 Name certName(string(reinterpret_cast<const char *>(sqlite3_column_text(statement, 0)),
759 sqlite3_column_bytes(statement, 0)));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800760 sqlite3_finalize(statement);
761 return certName;
762 }
763 else
764 {
765 sqlite3_finalize(statement);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700766 throw Error("certificate not found");
Yingdi Yu2e57a582014-02-20 23:34:43 -0800767 }
Yingdi Yu87581582014-01-14 14:28:39 -0800768}
769
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700770void
Yingdi Yu87581582014-01-14 14:28:39 -0800771SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
772{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700773 if (!doesCertificateExist(certificateName))
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700774 throw Error("certificate does not exist:" + certificateName.toUri());
Yingdi Yu88663af2014-01-15 15:21:38 -0800775
Yingdi Yu2e57a582014-02-20 23:34:43 -0800776 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700777 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800778 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700779
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700780 sqlite3_stmt* statement;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700781
782 //Reset previous default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700783 sqlite3_prepare_v2(m_database,
784 "UPDATE Certificate SET default_cert=0 \
785 WHERE default_cert=1 AND identity_name=? AND key_identifier=?",
786 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700787
Yingdi Yu41546342014-11-30 23:37:53 -0800788 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
789 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700790
791 while (sqlite3_step(statement) == SQLITE_ROW)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700792 ;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700793
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700794 sqlite3_finalize(statement);
795
796 //Set current default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700797 sqlite3_prepare_v2(m_database,
798 "UPDATE Certificate SET default_cert=1 \
799 WHERE identity_name=? AND key_identifier=? AND cert_name=?",
800 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700801
Yingdi Yu41546342014-11-30 23:37:53 -0800802 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
803 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
804 sqlite3_bind_string(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700805
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700806 sqlite3_step(statement);
807
808 sqlite3_finalize(statement);
809}
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800810
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800811void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700812SecPublicInfoSqlite3::getAllIdentities(vector<Name>& nameList, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800813{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700814 sqlite3_stmt* stmt;
815 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700816 sqlite3_prepare_v2(m_database,
817 "SELECT identity_name FROM Identity WHERE default_identity=1",
818 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800819 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700820 sqlite3_prepare_v2(m_database,
821 "SELECT identity_name FROM Identity WHERE default_identity=0",
822 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800823
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700824 while (sqlite3_step(stmt) == SQLITE_ROW)
825 nameList.push_back(Name(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)),
826 sqlite3_column_bytes(stmt, 0))));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700827
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700828 sqlite3_finalize(stmt);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700829}
830
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800831void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700832SecPublicInfoSqlite3::getAllKeyNames(vector<Name>& nameList, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800833{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700834 sqlite3_stmt* stmt;
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800835
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700836 if (isDefault)
837 sqlite3_prepare_v2(m_database,
838 "SELECT identity_name, key_identifier FROM Key WHERE default_key=1",
839 -1, &stmt, 0);
840 else
841 sqlite3_prepare_v2(m_database,
842 "SELECT identity_name, key_identifier FROM Key WHERE default_key=0",
843 -1, &stmt, 0);
844
845 while (sqlite3_step(stmt) == SQLITE_ROW)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800846 {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700847 Name keyName(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)),
848 sqlite3_column_bytes(stmt, 0)));
849 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1)),
850 sqlite3_column_bytes(stmt, 1)));
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800851 nameList.push_back(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700852 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700853 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800854}
855
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800856void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700857SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity,
858 vector<Name>& nameList,
859 bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800860{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700861 sqlite3_stmt* stmt;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700862
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700863 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700864 sqlite3_prepare_v2(m_database,
865 "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?",
866 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800867 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700868 sqlite3_prepare_v2(m_database,
869 "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?",
870 -1, &stmt, 0);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700871
Yingdi Yu41546342014-11-30 23:37:53 -0800872 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800873
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700874 while (sqlite3_step(stmt) == SQLITE_ROW)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800875 {
876 Name keyName(identity);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700877 keyName.append(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)),
878 sqlite3_column_bytes(stmt, 0)));
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800879 nameList.push_back(keyName);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700880 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700881 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800882}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700883
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800884void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700885SecPublicInfoSqlite3::getAllCertificateNames(vector<Name>& nameList, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800886{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700887 sqlite3_stmt* stmt;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700888
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700889 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700890 sqlite3_prepare_v2(m_database,
891 "SELECT cert_name FROM Certificate WHERE default_cert=1",
892 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800893 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700894 sqlite3_prepare_v2(m_database,
895 "SELECT cert_name FROM Certificate WHERE default_cert=0",
896 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800897
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700898 while (sqlite3_step(stmt) == SQLITE_ROW)
899 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)),
900 sqlite3_column_bytes(stmt, 0)));
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800901
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700902 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800903}
904
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800905void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700906SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName,
907 vector<Name>& nameList,
908 bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800909{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700910 if (keyName.empty())
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800911 return;
Yingdi Yu88663af2014-01-15 15:21:38 -0800912
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700913 sqlite3_stmt* stmt;
914 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700915 sqlite3_prepare_v2(m_database,
916 "SELECT cert_name FROM Certificate \
917 WHERE default_cert=1 and identity_name=? and key_identifier=?",
918 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800919 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700920 sqlite3_prepare_v2(m_database,
921 "SELECT cert_name FROM Certificate \
922 WHERE default_cert=0 and identity_name=? and key_identifier=?",
923 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800924
Yingdi Yu87581582014-01-14 14:28:39 -0800925 Name identity = keyName.getPrefix(-1);
Yingdi Yu41546342014-11-30 23:37:53 -0800926 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700927
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700928 std::string baseKeyName = keyName.get(-1).toUri();
Yingdi Yu41546342014-11-30 23:37:53 -0800929 sqlite3_bind_string(stmt, 2, baseKeyName, SQLITE_TRANSIENT);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800930
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700931 while (sqlite3_step(stmt) == SQLITE_ROW)
932 nameList.push_back(string(reinterpret_cast<const char *>(sqlite3_column_text(stmt, 0)),
933 sqlite3_column_bytes(stmt, 0)));
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800934
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700935 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800936}
937
938void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700939SecPublicInfoSqlite3::deleteCertificateInfo(const Name& certName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800940{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700941 if (certName.empty())
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800942 return;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700943
944 sqlite3_stmt* stmt;
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800945 sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE cert_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800946 sqlite3_bind_string(stmt, 1, certName.toUri(), SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800947 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700948 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800949}
950
951void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700952SecPublicInfoSqlite3::deletePublicKeyInfo(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800953{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700954 if (keyName.empty())
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800955 return;
956
957 string identity = keyName.getPrefix(-1).toUri();
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700958 string keyId = keyName.get(-1).toUri();
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800959
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700960 sqlite3_stmt* stmt;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700961 sqlite3_prepare_v2(m_database,
962 "DELETE FROM Certificate WHERE identity_name=? and key_identifier=?",
963 -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800964 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
965 sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800966 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700967 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800968
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700969 sqlite3_prepare_v2(m_database,
970 "DELETE FROM Key WHERE identity_name=? and key_identifier=?",
971 -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800972 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
973 sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800974 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700975 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800976}
977
978void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700979SecPublicInfoSqlite3::deleteIdentityInfo(const Name& identityName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800980{
981 string identity = identityName.toUri();
982
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700983 sqlite3_stmt* stmt;
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800984 sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE identity_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800985 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800986 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700987 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800988
989 sqlite3_prepare_v2(m_database, "DELETE FROM Key WHERE identity_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800990 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800991 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700992 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800993
994 sqlite3_prepare_v2(m_database, "DELETE FROM Identity WHERE identity_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800995 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800996 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700997 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800998}
999
Yingdi Yu41546342014-11-30 23:37:53 -08001000std::string
1001SecPublicInfoSqlite3::getScheme()
1002{
1003 return SCHEME;
1004}
1005
Alexander Afanasyev0c632112013-12-30 15:59:31 -08001006} // namespace ndn