blob: 1be311fffd0c560dfeab137fcf9b013515a8abab [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 Afanasyev57e00362016-06-23 13:22:54 -07003 * Copyright (c) 2013-2016 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
Alexander Afanasyev07113802015-01-15 19:14:36 -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;
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700117 if (dir == "") {
118#ifdef NDN_CXX_HAVE_TESTS
119 if (getenv("TEST_HOME") != nullptr) {
120 identityDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
121 }
122 else
123#endif // NDN_CXX_HAVE_TESTS
124 if (getenv("HOME") != nullptr) {
125 identityDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
126 }
127 else {
128 identityDir = boost::filesystem::path(".") / ".ndn";
129 }
130 }
131 else {
132 identityDir = boost::filesystem::path(dir);
133 }
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700134 boost::filesystem::create_directories(identityDir);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700135
Alexander Afanasyev5b60f702014-02-07 12:55:24 -0800136 /// @todo Add define for windows/unix in wscript. The following may completely fail on windows
137 int res = sqlite3_open_v2((identityDir / "ndnsec-public-info.db").c_str(), &m_database,
138 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
Alexander Afanasyev766cea72014-04-24 19:16:42 -0700139#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
Alexander Afanasyev44471462014-02-12 11:21:51 -0800140 "unix-dotfile"
Alexander Afanasyev5b60f702014-02-07 12:55:24 -0800141#else
142 0
143#endif
144 );
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700145 if (res != SQLITE_OK)
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700146 BOOST_THROW_EXCEPTION(Error("identity DB cannot be opened/created"));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700147
Yingdi Yu41546342014-11-30 23:37:53 -0800148
Junxiao Shi98acbb02014-12-02 11:00:42 -0700149 BOOST_ASSERT(m_database != nullptr);
150
Yingdi Yu41546342014-11-30 23:37:53 -0800151 initializeTable("TpmInfo", INIT_TPM_INFO_TABLE); // Check if TpmInfo table exists;
152 initializeTable("Identity", INIT_ID_TABLE); // Check if Identity table exists;
153 initializeTable("Key", INIT_KEY_TABLE); // Check if Key table exists;
154 initializeTable("Certificate", INIT_CERT_TABLE); // Check if Certificate table exists;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700155}
156
Yingdi Yu87581582014-01-14 14:28:39 -0800157SecPublicInfoSqlite3::~SecPublicInfoSqlite3()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700158{
Junxiao Shi98acbb02014-12-02 11:00:42 -0700159 sqlite3_close(m_database);
160 m_database = nullptr;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700161}
162
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700163bool
Yingdi Yu41546342014-11-30 23:37:53 -0800164SecPublicInfoSqlite3::doesTableExist(const string& tableName)
165{
166 // Check if the table exists;
167 bool doesTableExist = false;
168 string checkingString =
169 "SELECT name FROM sqlite_master WHERE type='table' AND name='" + tableName + "'";
170
Yingdi Yua90ba482014-12-09 10:54:43 -0800171 sqlite3_stmt* statement = nullptr;
Yingdi Yu41546342014-11-30 23:37:53 -0800172 sqlite3_prepare_v2(m_database, checkingString.c_str(), -1, &statement, 0);
173
174 int result = sqlite3_step(statement);
175 if (result == SQLITE_ROW)
176 doesTableExist = true;
177 sqlite3_finalize(statement);
178
179 return doesTableExist;
180}
181
182bool
183SecPublicInfoSqlite3::initializeTable(const string& tableName, const string& initCommand)
184{
185 // Create the table if it does not exist
186 if (!doesTableExist(tableName)) {
187 char* errorMessage = 0;
188 int result = sqlite3_exec(m_database, initCommand.c_str(), NULL, NULL, &errorMessage);
189
190 if (result != SQLITE_OK && errorMessage != 0) {
191 sqlite3_free(errorMessage);
192 return false;
193 }
194 }
195
196 return true;
197}
198
199void
200SecPublicInfoSqlite3::deleteTable(const string& tableName)
201{
202 string query = "DROP TABLE IF EXISTS " + tableName;
203
Yingdi Yua90ba482014-12-09 10:54:43 -0800204 sqlite3_stmt* statement = nullptr;
Yingdi Yu41546342014-11-30 23:37:53 -0800205 sqlite3_prepare_v2(m_database, query.c_str(), -1, &statement, 0);
206
207 sqlite3_step(statement);
208 sqlite3_finalize(statement);
209}
210
211void
212SecPublicInfoSqlite3::setTpmLocator(const string& tpmLocator)
213{
214 string currentTpm;
215 try {
216 currentTpm = getTpmLocator();
217 }
218 catch (SecPublicInfo::Error&) {
219 setTpmLocatorInternal(tpmLocator, false); // set tpmInfo without resetting
220 return;
221 }
222
223 if (currentTpm == tpmLocator)
224 return; // if the same, nothing will be changed
225
226 setTpmLocatorInternal(tpmLocator, true); // set tpmInfo and reset pib
227}
228
229string
230SecPublicInfoSqlite3::getTpmLocator()
231{
Yingdi Yua90ba482014-12-09 10:54:43 -0800232 sqlite3_stmt* statement = nullptr;
Yingdi Yu41546342014-11-30 23:37:53 -0800233 sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM TpmInfo", -1, &statement, 0);
234
235 int res = sqlite3_step(statement);
236
237 if (res == SQLITE_ROW) {
238 string tpmLocator = sqlite3_column_string(statement, 0);
239 sqlite3_finalize(statement);
240 return tpmLocator;
241 }
242 else {
243 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700244 BOOST_THROW_EXCEPTION(SecPublicInfo::Error("TPM info does not exist"));
Yingdi Yu41546342014-11-30 23:37:53 -0800245 }
246}
247
248void
249SecPublicInfoSqlite3::setTpmLocatorInternal(const string& tpmLocator, bool needReset)
250{
Yingdi Yua90ba482014-12-09 10:54:43 -0800251 sqlite3_stmt* statement = nullptr;
Yingdi Yu41546342014-11-30 23:37:53 -0800252
253 if (needReset) {
254 deleteTable("Identity");
255 deleteTable("Key");
256 deleteTable("Certificate");
257
258 initializeTable("Identity", INIT_ID_TABLE);
259 initializeTable("Key", INIT_KEY_TABLE);
260 initializeTable("Certificate", INIT_CERT_TABLE);
261
262 sqlite3_prepare_v2(m_database, "UPDATE TpmInfo SET tpm_locator = ?",
263 -1, &statement, 0);
264 sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
265 }
266 else {
267 // no reset implies there is no tpmLocator record, insert one
268 sqlite3_prepare_v2(m_database, "INSERT INTO TpmInfo (tpm_locator) VALUES (?)",
269 -1, &statement, 0);
270 sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
271 }
272
273 sqlite3_step(statement);
274 sqlite3_finalize(statement);
275}
276
277std::string
278SecPublicInfoSqlite3::getPibLocator()
279{
280 return string("pib-sqlite3:").append(m_location);
281}
282
283bool
Yingdi Yu87581582014-01-14 14:28:39 -0800284SecPublicInfoSqlite3::doesIdentityExist(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700285{
286 bool result = false;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700287
Yingdi Yua90ba482014-12-09 10:54:43 -0800288 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700289 sqlite3_prepare_v2(m_database,
290 "SELECT count(*) FROM Identity WHERE identity_name=?",
291 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700292
Yingdi Yu41546342014-11-30 23:37:53 -0800293 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700294 int res = sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700295
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700296 if (res == SQLITE_ROW) {
297 int countAll = sqlite3_column_int(statement, 0);
298 if (countAll > 0)
299 result = true;
300 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700301
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700302 sqlite3_finalize(statement);
303
304 return result;
305}
306
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700307void
Yingdi Yu87581582014-01-14 14:28:39 -0800308SecPublicInfoSqlite3::addIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700309{
Yingdi Yu05842f22014-04-15 19:21:56 -0700310 if (doesIdentityExist(identityName))
311 return;
312
Yingdi Yua90ba482014-12-09 10:54:43 -0800313 sqlite3_stmt* statement = nullptr;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700314
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700315 sqlite3_prepare_v2(m_database,
316 "INSERT OR REPLACE INTO Identity (identity_name) values (?)",
317 -1, &statement, 0);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700318
Yingdi Yu41546342014-11-30 23:37:53 -0800319 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700320
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800321 sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700322
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700323 sqlite3_finalize(statement);
324}
325
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700326bool
Yingdi Yu87581582014-01-14 14:28:39 -0800327SecPublicInfoSqlite3::revokeIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700328{
329 //TODO:
330 return false;
331}
332
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700333bool
Yingdi Yu87581582014-01-14 14:28:39 -0800334SecPublicInfoSqlite3::doesPublicKeyExist(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700335{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700336 if (keyName.empty())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700337 BOOST_THROW_EXCEPTION(Error("Incorrect key name " + keyName.toUri()));
Yingdi Yu88663af2014-01-15 15:21:38 -0800338
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700339 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800340 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700341
Yingdi Yua90ba482014-12-09 10:54:43 -0800342 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700343 sqlite3_prepare_v2(m_database,
344 "SELECT count(*) FROM Key WHERE identity_name=? AND key_identifier=?",
345 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700346
Yingdi Yu41546342014-11-30 23:37:53 -0800347 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
348 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700349
350 int res = sqlite3_step(statement);
351
352 bool keyIdExist = false;
353 if (res == SQLITE_ROW) {
354 int countAll = sqlite3_column_int(statement, 0);
355 if (countAll > 0)
356 keyIdExist = true;
357 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700358
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700359 sqlite3_finalize(statement);
360
361 return keyIdExist;
362}
363
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700364void
Yingdi Yu40b53092014-06-17 17:10:02 -0700365SecPublicInfoSqlite3::addKey(const Name& keyName,
366 const PublicKey& publicKeyDer)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700367{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700368 if (keyName.empty())
Yingdi Yu2e57a582014-02-20 23:34:43 -0800369 return;
Yingdi Yu88663af2014-01-15 15:21:38 -0800370
Yingdi Yu05842f22014-04-15 19:21:56 -0700371 if (doesPublicKeyExist(keyName))
372 return;
373
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700374 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800375 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700376
Yingdi Yu2e57a582014-02-20 23:34:43 -0800377 addIdentity(identityName);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700378
Yingdi Yua90ba482014-12-09 10:54:43 -0800379 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700380 sqlite3_prepare_v2(m_database,
381 "INSERT OR REPLACE INTO Key \
382 (identity_name, key_identifier, key_type, public_key) \
383 values (?, ?, ?, ?)",
384 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700385
Yingdi Yu41546342014-11-30 23:37:53 -0800386 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
387 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu99b2a002015-08-12 12:47:44 -0700388 sqlite3_bind_int(statement, 3, static_cast<int>(publicKeyDer.getKeyType()));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700389 sqlite3_bind_blob(statement, 4,
390 publicKeyDer.get().buf(),
391 publicKeyDer.get().size(),
392 SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700393
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800394 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700395
396 sqlite3_finalize(statement);
397}
398
Yingdi Yu2e57a582014-02-20 23:34:43 -0800399shared_ptr<PublicKey>
Yingdi Yu87581582014-01-14 14:28:39 -0800400SecPublicInfoSqlite3::getPublicKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700401{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700402 if (keyName.empty())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700403 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getPublicKey Empty keyName"));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700404
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700405 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800406 Name identityName = keyName.getPrefix(-1);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700407
Yingdi Yua90ba482014-12-09 10:54:43 -0800408 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700409 sqlite3_prepare_v2(m_database,
410 "SELECT public_key FROM Key WHERE identity_name=? AND key_identifier=?",
411 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700412
Yingdi Yu41546342014-11-30 23:37:53 -0800413 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
414 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700415
416 int res = sqlite3_step(statement);
417
Yingdi Yu2e57a582014-02-20 23:34:43 -0800418 shared_ptr<PublicKey> result;
Yingdi Yua90ba482014-12-09 10:54:43 -0800419 if (res == SQLITE_ROW) {
420 result = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
421 sqlite3_column_bytes(statement, 0));
422 sqlite3_finalize(statement);
423 return result;
424 }
425 else {
426 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700427 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getPublicKey public key does not exist"));
Yingdi Yua90ba482014-12-09 10:54:43 -0800428 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700429}
430
Yingdi Yu40b53092014-06-17 17:10:02 -0700431KeyType
432SecPublicInfoSqlite3::getPublicKeyType(const Name& keyName)
433{
434 if (keyName.empty())
Yingdi Yu99b2a002015-08-12 12:47:44 -0700435 return KeyType::NONE;
Yingdi Yu40b53092014-06-17 17:10:02 -0700436
437 string keyId = keyName.get(-1).toUri();
438 Name identityName = keyName.getPrefix(-1);
439
Yingdi Yua90ba482014-12-09 10:54:43 -0800440 sqlite3_stmt* statement = nullptr;
Yingdi Yu40b53092014-06-17 17:10:02 -0700441 sqlite3_prepare_v2(m_database,
442 "SELECT key_type FROM Key WHERE identity_name=? AND key_identifier=?",
443 -1, &statement, 0);
444
Yingdi Yu41546342014-11-30 23:37:53 -0800445 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
446 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu40b53092014-06-17 17:10:02 -0700447
448 int res = sqlite3_step(statement);
449
Yingdi Yua90ba482014-12-09 10:54:43 -0800450 if (res == SQLITE_ROW) {
451 int typeValue = sqlite3_column_int(statement, 0);
452 sqlite3_finalize(statement);
453 return static_cast<KeyType>(typeValue);
454 }
455 else {
456 sqlite3_finalize(statement);
Yingdi Yu99b2a002015-08-12 12:47:44 -0700457 return KeyType::NONE;
Yingdi Yua90ba482014-12-09 10:54:43 -0800458 }
Yingdi Yu40b53092014-06-17 17:10:02 -0700459}
460
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700461bool
Yingdi Yu87581582014-01-14 14:28:39 -0800462SecPublicInfoSqlite3::doesCertificateExist(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700463{
Yingdi Yua90ba482014-12-09 10:54:43 -0800464 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700465 sqlite3_prepare_v2(m_database,
466 "SELECT count(*) FROM Certificate WHERE cert_name=?",
467 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700468
Yingdi Yu41546342014-11-30 23:37:53 -0800469 sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700470
471 int res = sqlite3_step(statement);
472
473 bool certExist = false;
474 if (res == SQLITE_ROW) {
475 int countAll = sqlite3_column_int(statement, 0);
476 if (countAll > 0)
477 certExist = true;
478 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700479
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700480 sqlite3_finalize(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700481
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700482 return certExist;
483}
484
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700485void
Yingdi Yu87581582014-01-14 14:28:39 -0800486SecPublicInfoSqlite3::addCertificate(const IdentityCertificate& certificate)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700487{
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700488 const Name& certificateName = certificate.getName();
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700489 // KeyName is from IdentityCertificate name, so should be qualified.
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700490 Name keyName =
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700491 IdentityCertificate::certificateNameToPublicKeyName(certificate.getName());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700492
Yingdi Yu40b53092014-06-17 17:10:02 -0700493 addKey(keyName, certificate.getPublicKeyInfo());
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700494
Yingdi Yu05842f22014-04-15 19:21:56 -0700495 if (doesCertificateExist(certificateName))
496 return;
497
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700498 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800499 Name identity = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700500
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700501 // Insert the certificate
Yingdi Yua90ba482014-12-09 10:54:43 -0800502 sqlite3_stmt* statement = nullptr;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700503 sqlite3_prepare_v2(m_database,
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700504 "INSERT OR REPLACE INTO Certificate \
505 (cert_name, cert_issuer, identity_name, key_identifier, \
506 not_before, not_after, certificate_data) \
507 values (?, ?, ?, ?, datetime(?, 'unixepoch'), datetime(?, 'unixepoch'), ?)",
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700508 -1, &statement, 0);
509
Yingdi Yu41546342014-11-30 23:37:53 -0800510 sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700511
Yingdi Yua90ba482014-12-09 10:54:43 -0800512 try {
513 // this will throw an exception if the signature is not the standard one
514 // or there is no key locator present
515 std::string signerName = certificate.getSignature().getKeyLocator().getName().toUri();
516 sqlite3_bind_string(statement, 2, signerName, SQLITE_TRANSIENT);
517 }
518 catch (tlv::Error&) {
519 return;
520 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700521
Yingdi Yu41546342014-11-30 23:37:53 -0800522 sqlite3_bind_string(statement, 3, identity.toUri(), SQLITE_TRANSIENT);
523 sqlite3_bind_string(statement, 4, keyId, SQLITE_STATIC);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700524
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700525 sqlite3_bind_int64(statement, 5,
Yingdi Yua90ba482014-12-09 10:54:43 -0800526 static_cast<sqlite3_int64>(time::toUnixTimestamp(certificate.getNotBefore()).count()));
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700527 sqlite3_bind_int64(statement, 6,
Yingdi Yua90ba482014-12-09 10:54:43 -0800528 static_cast<sqlite3_int64>(time::toUnixTimestamp(certificate.getNotAfter()).count()));
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700529
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700530 sqlite3_bind_blob(statement, 7,
531 certificate.wireEncode().wire(),
532 certificate.wireEncode().size(),
533 SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700534
Alexander Afanasyev736708b2014-01-06 14:45:34 -0800535 sqlite3_step(statement);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700536
537 sqlite3_finalize(statement);
538}
539
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700540shared_ptr<IdentityCertificate>
541SecPublicInfoSqlite3::getCertificate(const Name& certificateName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700542{
Yingdi Yua90ba482014-12-09 10:54:43 -0800543 sqlite3_stmt* statement = nullptr;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700544
545 sqlite3_prepare_v2(m_database,
Yingdi Yu4270f202014-01-28 14:19:16 -0800546 "SELECT certificate_data FROM Certificate WHERE cert_name=?",
547 -1, &statement, 0);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700548
Yingdi Yu41546342014-11-30 23:37:53 -0800549 sqlite3_bind_string(statement, 1, certificateName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700550
Yingdi Yu4270f202014-01-28 14:19:16 -0800551 int res = sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700552
Yingdi Yua90ba482014-12-09 10:54:43 -0800553 if (res == SQLITE_ROW) {
554 shared_ptr<IdentityCertificate> certificate = make_shared<IdentityCertificate>();
555 try {
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700556 certificate->wireDecode(Block(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700557 sqlite3_column_bytes(statement, 0)));
Yingdi Yu4270f202014-01-28 14:19:16 -0800558 }
Yingdi Yua90ba482014-12-09 10:54:43 -0800559 catch (tlv::Error&) {
Yingdi Yu2e57a582014-02-20 23:34:43 -0800560 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700561 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getCertificate certificate cannot be "
562 "decoded"));
Yingdi Yu2e57a582014-02-20 23:34:43 -0800563 }
Yingdi Yua90ba482014-12-09 10:54:43 -0800564
565 sqlite3_finalize(statement);
566 return certificate;
567 }
568 else {
569 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700570 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getCertificate certificate does not "
571 "exist"));
Yingdi Yua90ba482014-12-09 10:54:43 -0800572 }
Jeff Thompson1975def2013-10-09 17:06:43 -0700573}
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700574
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700575
576Name
Yingdi Yu87581582014-01-14 14:28:39 -0800577SecPublicInfoSqlite3::getDefaultIdentity()
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700578{
Yingdi Yua90ba482014-12-09 10:54:43 -0800579 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700580 sqlite3_prepare_v2(m_database,
581 "SELECT identity_name FROM Identity WHERE default_identity=1",
582 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700583
584 int res = sqlite3_step(statement);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700585
Yingdi Yua90ba482014-12-09 10:54:43 -0800586 if (res == SQLITE_ROW) {
587 Name identity(sqlite3_column_string(statement, 0));
588 sqlite3_finalize(statement);
589 return identity;
590 }
591 else {
592 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700593 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getDefaultIdentity no default identity"));
Yingdi Yua90ba482014-12-09 10:54:43 -0800594 }
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700595}
596
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700597void
Yingdi Yu87581582014-01-14 14:28:39 -0800598SecPublicInfoSqlite3::setDefaultIdentityInternal(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700599{
Yingdi Yu2e57a582014-02-20 23:34:43 -0800600 addIdentity(identityName);
601
Yingdi Yua90ba482014-12-09 10:54:43 -0800602 sqlite3_stmt* statement = nullptr;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700603
604 //Reset previous default identity
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700605 sqlite3_prepare_v2(m_database,
606 "UPDATE Identity SET default_identity=0 WHERE default_identity=1",
607 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700608
609 while (sqlite3_step(statement) == SQLITE_ROW)
Yingdi Yua90ba482014-12-09 10:54:43 -0800610 ;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700611
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700612 sqlite3_finalize(statement);
613
614 //Set current default identity
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700615 sqlite3_prepare_v2(m_database,
616 "UPDATE Identity SET default_identity=1 WHERE identity_name=?",
617 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700618
Yingdi Yu41546342014-11-30 23:37:53 -0800619 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700620
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700621 sqlite3_step(statement);
622
623 sqlite3_finalize(statement);
624}
625
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700626Name
Yingdi Yu87581582014-01-14 14:28:39 -0800627SecPublicInfoSqlite3::getDefaultKeyNameForIdentity(const Name& identityName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700628{
Yingdi Yua90ba482014-12-09 10:54:43 -0800629 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700630 sqlite3_prepare_v2(m_database,
631 "SELECT key_identifier FROM Key WHERE identity_name=? AND default_key=1",
632 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700633
Yingdi Yu41546342014-11-30 23:37:53 -0800634 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Yingdi Yu87581582014-01-14 14:28:39 -0800635
636 int res = sqlite3_step(statement);
Yingdi Yu87581582014-01-14 14:28:39 -0800637
Yingdi Yua90ba482014-12-09 10:54:43 -0800638 if (res == SQLITE_ROW) {
639 Name keyName = identityName;
640 keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)),
641 sqlite3_column_bytes(statement, 0)));
642 sqlite3_finalize(statement);
643 return keyName;
644 }
645 else {
646 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700647 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getDefaultKeyNameForIdentity key not "
648 "found"));
Yingdi Yua90ba482014-12-09 10:54:43 -0800649 }
Yingdi Yu87581582014-01-14 14:28:39 -0800650}
651
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700652void
Yingdi Yu87581582014-01-14 14:28:39 -0800653SecPublicInfoSqlite3::setDefaultKeyNameForIdentityInternal(const Name& keyName)
654{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700655 if (!doesPublicKeyExist(keyName))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700656 BOOST_THROW_EXCEPTION(Error("Key does not exist:" + keyName.toUri()));
Yingdi Yu88663af2014-01-15 15:21:38 -0800657
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700658 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800659 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700660
Yingdi Yua90ba482014-12-09 10:54:43 -0800661 sqlite3_stmt* statement = nullptr;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700662
663 //Reset previous default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700664 sqlite3_prepare_v2(m_database,
665 "UPDATE Key SET default_key=0 WHERE default_key=1 and identity_name=?",
666 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700667
Yingdi Yu41546342014-11-30 23:37:53 -0800668 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700669
670 while (sqlite3_step(statement) == SQLITE_ROW)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700671 ;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700672
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700673 sqlite3_finalize(statement);
674
675 //Set current default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700676 sqlite3_prepare_v2(m_database,
677 "UPDATE Key SET default_key=1 WHERE identity_name=? AND key_identifier=?",
678 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700679
Yingdi Yu41546342014-11-30 23:37:53 -0800680 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
681 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700682
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700683 sqlite3_step(statement);
684
685 sqlite3_finalize(statement);
686}
687
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700688Name
Yingdi Yu87581582014-01-14 14:28:39 -0800689SecPublicInfoSqlite3::getDefaultCertificateNameForKey(const Name& keyName)
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700690{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700691 if (keyName.empty())
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700692 BOOST_THROW_EXCEPTION(Error("SecPublicInfoSqlite3::getDefaultCertificateNameForKey wrong key"));
Yingdi Yu88663af2014-01-15 15:21:38 -0800693
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700694 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800695 Name identityName = keyName.getPrefix(-1);
696
Yingdi Yua90ba482014-12-09 10:54:43 -0800697 sqlite3_stmt* statement = nullptr;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700698 sqlite3_prepare_v2(m_database,
699 "SELECT cert_name FROM Certificate \
700 WHERE identity_name=? AND key_identifier=? AND default_cert=1",
701 -1, &statement, 0);
Yingdi Yu87581582014-01-14 14:28:39 -0800702
Yingdi Yu41546342014-11-30 23:37:53 -0800703 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
704 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu87581582014-01-14 14:28:39 -0800705
706 int res = sqlite3_step(statement);
707
Yingdi Yua90ba482014-12-09 10:54:43 -0800708 if (res == SQLITE_ROW) {
709 Name certName(string(reinterpret_cast<const char*>(sqlite3_column_text(statement, 0)),
710 sqlite3_column_bytes(statement, 0)));
711 sqlite3_finalize(statement);
712 return certName;
713 }
714 else {
715 sqlite3_finalize(statement);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700716 BOOST_THROW_EXCEPTION(Error("certificate not found"));
Yingdi Yua90ba482014-12-09 10:54:43 -0800717 }
Yingdi Yu87581582014-01-14 14:28:39 -0800718}
719
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700720void
Yingdi Yu87581582014-01-14 14:28:39 -0800721SecPublicInfoSqlite3::setDefaultCertificateNameForKeyInternal(const Name& certificateName)
722{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700723 if (!doesCertificateExist(certificateName))
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700724 BOOST_THROW_EXCEPTION(Error("certificate does not exist:" + certificateName.toUri()));
Yingdi Yu88663af2014-01-15 15:21:38 -0800725
Yingdi Yu2e57a582014-02-20 23:34:43 -0800726 Name keyName = IdentityCertificate::certificateNameToPublicKeyName(certificateName);
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700727 string keyId = keyName.get(-1).toUri();
Yingdi Yu87581582014-01-14 14:28:39 -0800728 Name identityName = keyName.getPrefix(-1);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700729
Yingdi Yua90ba482014-12-09 10:54:43 -0800730 sqlite3_stmt* statement = nullptr;
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700731
732 //Reset previous default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700733 sqlite3_prepare_v2(m_database,
734 "UPDATE Certificate SET default_cert=0 \
735 WHERE default_cert=1 AND identity_name=? AND key_identifier=?",
736 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700737
Yingdi Yu41546342014-11-30 23:37:53 -0800738 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
739 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700740
741 while (sqlite3_step(statement) == SQLITE_ROW)
Yingdi Yu5ec0ee32014-06-24 16:26:09 -0700742 ;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700743
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700744 sqlite3_finalize(statement);
745
746 //Set current default Key
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700747 sqlite3_prepare_v2(m_database,
748 "UPDATE Certificate SET default_cert=1 \
749 WHERE identity_name=? AND key_identifier=? AND cert_name=?",
750 -1, &statement, 0);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700751
Yingdi Yu41546342014-11-30 23:37:53 -0800752 sqlite3_bind_string(statement, 1, identityName.toUri(), SQLITE_TRANSIENT);
753 sqlite3_bind_string(statement, 2, keyId, SQLITE_TRANSIENT);
754 sqlite3_bind_string(statement, 3, certificateName.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700755
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700756 sqlite3_step(statement);
757
758 sqlite3_finalize(statement);
759}
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800760
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800761void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700762SecPublicInfoSqlite3::getAllIdentities(vector<Name>& nameList, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800763{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700764 sqlite3_stmt* stmt;
765 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700766 sqlite3_prepare_v2(m_database,
767 "SELECT identity_name FROM Identity WHERE default_identity=1",
768 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800769 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700770 sqlite3_prepare_v2(m_database,
771 "SELECT identity_name FROM Identity WHERE default_identity=0",
772 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800773
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700774 while (sqlite3_step(stmt) == SQLITE_ROW)
Yingdi Yua90ba482014-12-09 10:54:43 -0800775 nameList.push_back(Name(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700776 sqlite3_column_bytes(stmt, 0))));
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700777
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700778 sqlite3_finalize(stmt);
Jeff Thompson7ca11f22013-10-04 19:01:30 -0700779}
780
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800781void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700782SecPublicInfoSqlite3::getAllKeyNames(vector<Name>& nameList, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800783{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700784 sqlite3_stmt* stmt;
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800785
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700786 if (isDefault)
787 sqlite3_prepare_v2(m_database,
788 "SELECT identity_name, key_identifier FROM Key WHERE default_key=1",
789 -1, &stmt, 0);
790 else
791 sqlite3_prepare_v2(m_database,
792 "SELECT identity_name, key_identifier FROM Key WHERE default_key=0",
793 -1, &stmt, 0);
794
Yingdi Yua90ba482014-12-09 10:54:43 -0800795 while (sqlite3_step(stmt) == SQLITE_ROW) {
796 Name keyName(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
797 sqlite3_column_bytes(stmt, 0)));
798 keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1)),
799 sqlite3_column_bytes(stmt, 1)));
800 nameList.push_back(keyName);
801 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700802 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800803}
804
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800805void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700806SecPublicInfoSqlite3::getAllKeyNamesOfIdentity(const Name& identity,
807 vector<Name>& nameList,
808 bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800809{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700810 sqlite3_stmt* stmt;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700811
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700812 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700813 sqlite3_prepare_v2(m_database,
814 "SELECT key_identifier FROM Key WHERE default_key=1 and identity_name=?",
815 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800816 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700817 sqlite3_prepare_v2(m_database,
818 "SELECT key_identifier FROM Key WHERE default_key=0 and identity_name=?",
819 -1, &stmt, 0);
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700820
Yingdi Yu41546342014-11-30 23:37:53 -0800821 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800822
Yingdi Yua90ba482014-12-09 10:54:43 -0800823 while (sqlite3_step(stmt) == SQLITE_ROW) {
824 Name keyName(identity);
825 keyName.append(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
826 sqlite3_column_bytes(stmt, 0)));
827 nameList.push_back(keyName);
828 }
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700829 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800830}
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700831
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800832void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700833SecPublicInfoSqlite3::getAllCertificateNames(vector<Name>& nameList, bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800834{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700835 sqlite3_stmt* stmt;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700836
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700837 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700838 sqlite3_prepare_v2(m_database,
839 "SELECT cert_name FROM Certificate WHERE default_cert=1",
840 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800841 else
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700842 sqlite3_prepare_v2(m_database,
843 "SELECT cert_name FROM Certificate WHERE default_cert=0",
844 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800845
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700846 while (sqlite3_step(stmt) == SQLITE_ROW)
Yingdi Yua90ba482014-12-09 10:54:43 -0800847 nameList.push_back(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700848 sqlite3_column_bytes(stmt, 0)));
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800849
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700850 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800851}
852
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800853void
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700854SecPublicInfoSqlite3::getAllCertificateNamesOfKey(const Name& keyName,
855 vector<Name>& nameList,
856 bool isDefault)
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800857{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700858 if (keyName.empty())
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800859 return;
Yingdi Yu88663af2014-01-15 15:21:38 -0800860
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700861 sqlite3_stmt* stmt;
862 if (isDefault)
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700863 sqlite3_prepare_v2(m_database,
864 "SELECT cert_name FROM Certificate \
865 WHERE default_cert=1 and identity_name=? and key_identifier=?",
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 cert_name FROM Certificate \
870 WHERE default_cert=0 and identity_name=? and key_identifier=?",
871 -1, &stmt, 0);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800872
Yingdi Yu87581582014-01-14 14:28:39 -0800873 Name identity = keyName.getPrefix(-1);
Yingdi Yu41546342014-11-30 23:37:53 -0800874 sqlite3_bind_string(stmt, 1, identity.toUri(), SQLITE_TRANSIENT);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700875
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700876 std::string baseKeyName = keyName.get(-1).toUri();
Yingdi Yu41546342014-11-30 23:37:53 -0800877 sqlite3_bind_string(stmt, 2, baseKeyName, SQLITE_TRANSIENT);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800878
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700879 while (sqlite3_step(stmt) == SQLITE_ROW)
Yingdi Yua90ba482014-12-09 10:54:43 -0800880 nameList.push_back(string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)),
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700881 sqlite3_column_bytes(stmt, 0)));
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800882
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700883 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800884}
885
886void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700887SecPublicInfoSqlite3::deleteCertificateInfo(const Name& certName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800888{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700889 if (certName.empty())
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800890 return;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700891
892 sqlite3_stmt* stmt;
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800893 sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE cert_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800894 sqlite3_bind_string(stmt, 1, certName.toUri(), SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800895 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700896 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800897}
898
899void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700900SecPublicInfoSqlite3::deletePublicKeyInfo(const Name& keyName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800901{
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700902 if (keyName.empty())
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800903 return;
904
905 string identity = keyName.getPrefix(-1).toUri();
Alexander Afanasyev9c578182014-05-14 17:28:28 -0700906 string keyId = keyName.get(-1).toUri();
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800907
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700908 sqlite3_stmt* stmt;
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700909 sqlite3_prepare_v2(m_database,
910 "DELETE FROM Certificate WHERE identity_name=? and key_identifier=?",
911 -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800912 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
913 sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800914 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700915 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800916
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700917 sqlite3_prepare_v2(m_database,
918 "DELETE FROM Key WHERE identity_name=? and key_identifier=?",
919 -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800920 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
921 sqlite3_bind_string(stmt, 2, keyId, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800922 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700923 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800924}
925
926void
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700927SecPublicInfoSqlite3::deleteIdentityInfo(const Name& identityName)
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800928{
929 string identity = identityName.toUri();
930
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700931 sqlite3_stmt* stmt;
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800932 sqlite3_prepare_v2(m_database, "DELETE FROM Certificate WHERE identity_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800933 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800934 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700935 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800936
937 sqlite3_prepare_v2(m_database, "DELETE FROM Key WHERE identity_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800938 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800939 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700940 sqlite3_finalize(stmt);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800941
942 sqlite3_prepare_v2(m_database, "DELETE FROM Identity WHERE identity_name=?", -1, &stmt, 0);
Yingdi Yu41546342014-11-30 23:37:53 -0800943 sqlite3_bind_string(stmt, 1, identity, SQLITE_TRANSIENT);
Yingdi Yu28fd32f2014-01-28 19:03:03 -0800944 sqlite3_step(stmt);
Yingdi Yu4b8c6a22014-04-15 23:00:54 -0700945 sqlite3_finalize(stmt);
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800946}
947
Yingdi Yu41546342014-11-30 23:37:53 -0800948std::string
949SecPublicInfoSqlite3::getScheme()
950{
951 return SCHEME;
952}
953
Alexander Afanasyev0c632112013-12-30 15:59:31 -0800954} // namespace ndn