blob: 8d8c437176161f7dcacdee9b9b7eac5fc5db1e88 [file] [log] [blame]
Mickey Sweatt11314b72015-06-10 17:20:19 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Yingdi Yu6ee2d362015-07-16 21:48:05 -07003 * Copyright (c) 2013-2017 Regents of the University of California.
Mickey Sweatt11314b72015-06-10 17:20:19 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * 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.
20 */
21
22#include "pib-sqlite3.hpp"
Mickey Sweatt11314b72015-06-10 17:20:19 -070023#include "pib.hpp"
Yingdi Yu6ee2d362015-07-16 21:48:05 -070024#include "../security-common.hpp"
25#include "../../util/sqlite3-statement.hpp"
Mickey Sweatt11314b72015-06-10 17:20:19 -070026
27#include <sqlite3.h>
28#include <boost/filesystem.hpp>
29#include <boost/algorithm/string.hpp>
30
31namespace ndn {
32namespace security {
Yingdi Yu6ee2d362015-07-16 21:48:05 -070033namespace pib {
Mickey Sweatt11314b72015-06-10 17:20:19 -070034
35using std::string;
36using util::Sqlite3Statement;
37
38static const string INITIALIZATION =
39 "CREATE TABLE IF NOT EXISTS \n"
40 " tpmInfo( \n"
41 " tpm_locator BLOB \n"
42 " ); \n"
43 " \n"
Mickey Sweatt11314b72015-06-10 17:20:19 -070044 "CREATE TABLE IF NOT EXISTS \n"
45 " identities( \n"
46 " id INTEGER PRIMARY KEY,\n"
47 " identity BLOB NOT NULL, \n"
48 " is_default INTEGER DEFAULT 0 \n"
49 " ); \n"
50 " \n"
51 "CREATE UNIQUE INDEX IF NOT EXISTS \n"
52 " identityIndex ON identities(identity); \n"
53 " \n"
54 "CREATE TRIGGER IF NOT EXISTS \n"
55 " identity_default_before_insert_trigger \n"
56 " BEFORE INSERT ON identities \n"
57 " FOR EACH ROW \n"
58 " WHEN NEW.is_default=1 \n"
59 " BEGIN \n"
60 " UPDATE identities SET is_default=0; \n"
61 " END; \n"
62 " \n"
63 "CREATE TRIGGER IF NOT EXISTS \n"
64 " identity_default_after_insert_trigger \n"
65 " AFTER INSERT ON identities \n"
66 " FOR EACH ROW \n"
67 " WHEN NOT EXISTS \n"
68 " (SELECT id \n"
69 " FROM identities \n"
70 " WHERE is_default=1) \n"
71 " BEGIN \n"
72 " UPDATE identities \n"
73 " SET is_default=1 \n"
74 " WHERE identity=NEW.identity; \n"
75 " END; \n"
76 " \n"
77 "CREATE TRIGGER IF NOT EXISTS \n"
78 " identity_default_update_trigger \n"
79 " BEFORE UPDATE ON identities \n"
80 " FOR EACH ROW \n"
81 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
82 " BEGIN \n"
83 " UPDATE identities SET is_default=0; \n"
84 " END; \n"
85 " \n"
86 " \n"
87 "CREATE TABLE IF NOT EXISTS \n"
88 " keys( \n"
89 " id INTEGER PRIMARY KEY,\n"
90 " identity_id INTEGER NOT NULL, \n"
91 " key_name BLOB NOT NULL, \n"
Mickey Sweatt11314b72015-06-10 17:20:19 -070092 " key_bits BLOB NOT NULL, \n"
93 " is_default INTEGER DEFAULT 0, \n"
94 " FOREIGN KEY(identity_id) \n"
95 " REFERENCES identities(id) \n"
96 " ON DELETE CASCADE \n"
97 " ON UPDATE CASCADE \n"
98 " ); \n"
99 " \n"
100 "CREATE UNIQUE INDEX IF NOT EXISTS \n"
101 " keyIndex ON keys(key_name); \n"
102 " \n"
103 "CREATE TRIGGER IF NOT EXISTS \n"
104 " key_default_before_insert_trigger \n"
105 " BEFORE INSERT ON keys \n"
106 " FOR EACH ROW \n"
107 " WHEN NEW.is_default=1 \n"
108 " BEGIN \n"
109 " UPDATE keys \n"
110 " SET is_default=0 \n"
111 " WHERE identity_id=NEW.identity_id; \n"
112 " END; \n"
113 " \n"
114 "CREATE TRIGGER IF NOT EXISTS \n"
115 " key_default_after_insert_trigger \n"
116 " AFTER INSERT ON keys \n"
117 " FOR EACH ROW \n"
118 " WHEN NOT EXISTS \n"
119 " (SELECT id \n"
120 " FROM keys \n"
121 " WHERE is_default=1 \n"
122 " AND identity_id=NEW.identity_id) \n"
123 " BEGIN \n"
124 " UPDATE keys \n"
125 " SET is_default=1 \n"
126 " WHERE key_name=NEW.key_name; \n"
127 " END; \n"
128 " \n"
129 "CREATE TRIGGER IF NOT EXISTS \n"
130 " key_default_update_trigger \n"
131 " BEFORE UPDATE ON keys \n"
132 " FOR EACH ROW \n"
133 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
134 " BEGIN \n"
135 " UPDATE keys \n"
136 " SET is_default=0 \n"
137 " WHERE identity_id=NEW.identity_id; \n"
138 " END; \n"
139 " \n"
140 " \n"
141 "CREATE TABLE IF NOT EXISTS \n"
142 " certificates( \n"
143 " id INTEGER PRIMARY KEY,\n"
144 " key_id INTEGER NOT NULL, \n"
145 " certificate_name BLOB NOT NULL, \n"
146 " certificate_data BLOB NOT NULL, \n"
147 " is_default INTEGER DEFAULT 0, \n"
148 " FOREIGN KEY(key_id) \n"
149 " REFERENCES keys(id) \n"
150 " ON DELETE CASCADE \n"
151 " ON UPDATE CASCADE \n"
152 " ); \n"
153 " \n"
154 "CREATE UNIQUE INDEX IF NOT EXISTS \n"
155 " certIndex ON certificates(certificate_name);\n"
156 " \n"
157 "CREATE TRIGGER IF NOT EXISTS \n"
158 " cert_default_before_insert_trigger \n"
159 " BEFORE INSERT ON certificates \n"
160 " FOR EACH ROW \n"
161 " WHEN NEW.is_default=1 \n"
162 " BEGIN \n"
163 " UPDATE certificates \n"
164 " SET is_default=0 \n"
165 " WHERE key_id=NEW.key_id; \n"
166 " END; \n"
167 " \n"
168 "CREATE TRIGGER IF NOT EXISTS \n"
169 " cert_default_after_insert_trigger \n"
170 " AFTER INSERT ON certificates \n"
171 " FOR EACH ROW \n"
172 " WHEN NOT EXISTS \n"
173 " (SELECT id \n"
174 " FROM certificates \n"
175 " WHERE is_default=1 \n"
176 " AND key_id=NEW.key_id) \n"
177 " BEGIN \n"
178 " UPDATE certificates \n"
179 " SET is_default=1 \n"
180 " WHERE certificate_name=NEW.certificate_name;\n"
181 " END; \n"
182 " \n"
183 "CREATE TRIGGER IF NOT EXISTS \n"
184 " cert_default_update_trigger \n"
185 " BEFORE UPDATE ON certificates \n"
186 " FOR EACH ROW \n"
187 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
188 " BEGIN \n"
189 " UPDATE certificates \n"
190 " SET is_default=0 \n"
191 " WHERE key_id=NEW.key_id; \n"
192 " END; \n";
193
Mickey Sweatt11314b72015-06-10 17:20:19 -0700194PibSqlite3::PibSqlite3(const string& dir)
195{
196 // Determine the path of PIB DB
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700197 boost::filesystem::path dbDir;
198 if (!dir.empty()) {
199 dbDir = boost::filesystem::path(dir);
200 }
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700201#ifdef NDN_CXX_HAVE_TESTS
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700202 else if (getenv("TEST_HOME") != nullptr) {
203 dbDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
204 }
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700205#endif // NDN_CXX_HAVE_TESTS
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700206 else if (getenv("HOME") != nullptr) {
207 dbDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
Mickey Sweatt11314b72015-06-10 17:20:19 -0700208 }
209 else {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700210 dbDir = boost::filesystem::current_path() / ".ndn";
Mickey Sweatt11314b72015-06-10 17:20:19 -0700211 }
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700212 boost::filesystem::create_directories(dbDir);
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700213
Mickey Sweatt11314b72015-06-10 17:20:19 -0700214 // Open PIB
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700215 int result = sqlite3_open_v2((dbDir / "pib.db").c_str(), &m_database,
Mickey Sweatt11314b72015-06-10 17:20:19 -0700216 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
217#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
218 "unix-dotfile"
219#else
220 nullptr
221#endif
222 );
223
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700224 if (result != SQLITE_OK) {
225 BOOST_THROW_EXCEPTION(PibImpl::Error("PIB database cannot be opened/created in " + dir));
226 }
Mickey Sweatt11314b72015-06-10 17:20:19 -0700227
228 // enable foreign key
229 sqlite3_exec(m_database, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
230
231 // initialize PIB tables
232 char* errorMessage = nullptr;
233 result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
234 if (result != SQLITE_OK && errorMessage != nullptr) {
235 sqlite3_free(errorMessage);
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700236 BOOST_THROW_EXCEPTION(PibImpl::Error("PIB DB cannot be initialized"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700237 }
238}
239
240PibSqlite3::~PibSqlite3()
241{
242 sqlite3_close(m_database);
243}
244
245void
246PibSqlite3::setTpmLocator(const std::string& tpmLocator)
247{
248 Sqlite3Statement statement(m_database, "UPDATE tpmInfo SET tpm_locator=?");
249 statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
250 statement.step();
251
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700252 if (sqlite3_changes(m_database) == 0) {
253 // no row is updated, tpm_locator does not exist, insert it directly
Mickey Sweatt11314b72015-06-10 17:20:19 -0700254 Sqlite3Statement insertStatement(m_database, "INSERT INTO tpmInfo (tpm_locator) values (?)");
255 insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
256 insertStatement.step();
257 }
258}
259
260std::string
261PibSqlite3::getTpmLocator() const
262{
263 Sqlite3Statement statement(m_database, "SELECT tpm_locator FROM tpmInfo");
264 int res = statement.step();
Mickey Sweatt11314b72015-06-10 17:20:19 -0700265 if (res == SQLITE_ROW)
266 return statement.getString(0);
267 else
Yingdi Yu7b3b5e92015-08-13 19:52:35 -0700268 return "";
Mickey Sweatt11314b72015-06-10 17:20:19 -0700269}
270
271bool
272PibSqlite3::hasIdentity(const Name& identity) const
273{
274 Sqlite3Statement statement(m_database, "SELECT id FROM identities WHERE identity=?");
275 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
276 return (statement.step() == SQLITE_ROW);
277}
278
279void
280PibSqlite3::addIdentity(const Name& identity)
281{
282 Sqlite3Statement statement(m_database, "INSERT INTO identities (identity) values (?)");
283 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
284 statement.step();
285}
286
287void
288PibSqlite3::removeIdentity(const Name& identity)
289{
290 Sqlite3Statement statement(m_database, "DELETE FROM identities WHERE identity=?");
291 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
292 statement.step();
293}
294
Yingdi Yu7b3b5e92015-08-13 19:52:35 -0700295void
296PibSqlite3::clearIdentities()
297{
298 Sqlite3Statement statement(m_database, "DELETE FROM identities");
299 statement.step();
300}
301
Mickey Sweatt11314b72015-06-10 17:20:19 -0700302std::set<Name>
303PibSqlite3::getIdentities() const
304{
305 std::set<Name> identities;
306 Sqlite3Statement statement(m_database, "SELECT identity FROM identities");
307
308 while (statement.step() == SQLITE_ROW)
309 identities.insert(Name(statement.getBlock(0)));
310
311 return identities;
312}
313
314void
315PibSqlite3::setDefaultIdentity(const Name& identityName)
316{
317 Sqlite3Statement statement(m_database, "UPDATE identities SET is_default=1 WHERE identity=?");
318 statement.bind(1, identityName.wireEncode(), SQLITE_TRANSIENT);
319 statement.step();
320}
321
322Name
323PibSqlite3::getDefaultIdentity() const
324{
325 Sqlite3Statement statement(m_database, "SELECT identity FROM identities WHERE is_default=1");
326
327 if (statement.step() == SQLITE_ROW)
328 return Name(statement.getBlock(0));
329 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700330 BOOST_THROW_EXCEPTION(Pib::Error("No default identity"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700331}
332
333bool
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700334PibSqlite3::hasKey(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700335{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700336 Sqlite3Statement statement(m_database, "SELECT id FROM keys WHERE key_name=?");
337 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
338
339 return (statement.step() == SQLITE_ROW);
340}
341
342void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700343PibSqlite3::addKey(const Name& identity, const Name& keyName,
344 const uint8_t* key, size_t keyLen)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700345{
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700346 if (hasKey(keyName)) {
Mickey Sweatt11314b72015-06-10 17:20:19 -0700347 return;
348 }
349
350 // ensure identity exists
351 addIdentity(identity);
352
Mickey Sweatt11314b72015-06-10 17:20:19 -0700353 Sqlite3Statement statement(m_database,
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700354 "INSERT INTO keys (identity_id, key_name, key_bits) "
355 "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?)");
Mickey Sweatt11314b72015-06-10 17:20:19 -0700356 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
357 statement.bind(2, keyName.wireEncode(), SQLITE_TRANSIENT);
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700358 statement.bind(3, key, keyLen, SQLITE_STATIC);
Mickey Sweatt11314b72015-06-10 17:20:19 -0700359 statement.step();
360}
361
362void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700363PibSqlite3::removeKey(const Name& keyName)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700364{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700365 Sqlite3Statement statement(m_database, "DELETE FROM keys WHERE key_name=?");
366 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
367 statement.step();
368}
369
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700370Buffer
371PibSqlite3::getKeyBits(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700372{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700373 Sqlite3Statement statement(m_database, "SELECT key_bits FROM keys WHERE key_name=?");
374 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
375
376 if (statement.step() == SQLITE_ROW)
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700377 return Buffer(statement.getBlob(0), statement.getSize(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700378 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700379 BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700380}
381
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700382std::set<Name>
Mickey Sweatt11314b72015-06-10 17:20:19 -0700383PibSqlite3::getKeysOfIdentity(const Name& identity) const
384{
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700385 std::set<Name> keyNames;
Mickey Sweatt11314b72015-06-10 17:20:19 -0700386
387 Sqlite3Statement statement(m_database,
388 "SELECT key_name "
389 "FROM keys JOIN identities ON keys.identity_id=identities.id "
390 "WHERE identities.identity=?");
391 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
392
393 while (statement.step() == SQLITE_ROW) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700394 keyNames.insert(Name(statement.getBlock(0)));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700395 }
396
397 return keyNames;
398}
399
400void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700401PibSqlite3::setDefaultKeyOfIdentity(const Name& identity, const Name& keyName)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700402{
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700403 if (!hasKey(keyName)) {
404 BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700405 }
406
407 Sqlite3Statement statement(m_database, "UPDATE keys SET is_default=1 WHERE key_name=?");
408 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
409 statement.step();
410}
411
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700412Name
Mickey Sweatt11314b72015-06-10 17:20:19 -0700413PibSqlite3::getDefaultKeyOfIdentity(const Name& identity) const
414{
415 if (!hasIdentity(identity)) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700416 BOOST_THROW_EXCEPTION(Pib::Error("Identity `" + identity.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700417 }
418
419 Sqlite3Statement statement(m_database,
420 "SELECT key_name "
421 "FROM keys JOIN identities ON keys.identity_id=identities.id "
422 "WHERE identities.identity=? AND keys.is_default=1");
423 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
424
425 if (statement.step() == SQLITE_ROW) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700426 return Name(statement.getBlock(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700427 }
428 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700429 BOOST_THROW_EXCEPTION(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700430}
431
432bool
433PibSqlite3::hasCertificate(const Name& certName) const
434{
435 Sqlite3Statement statement(m_database, "SELECT id FROM certificates WHERE certificate_name=?");
436 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
437 return (statement.step() == SQLITE_ROW);
438}
439
440void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700441PibSqlite3::addCertificate(const v2::Certificate& certificate)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700442{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700443 // ensure key exists
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700444 const Block& content = certificate.getContent();
445 addKey(certificate.getIdentity(), certificate.getKeyName(), content.value(), content.value_size());
Mickey Sweatt11314b72015-06-10 17:20:19 -0700446
447 Sqlite3Statement statement(m_database,
448 "INSERT INTO certificates "
449 "(key_id, certificate_name, certificate_data) "
450 "VALUES ((SELECT id FROM keys WHERE key_name=?), ?, ?)");
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700451 statement.bind(1, certificate.getKeyName().wireEncode(), SQLITE_TRANSIENT);
452 statement.bind(2, certificate.getName().wireEncode(), SQLITE_TRANSIENT);
Mickey Sweatt11314b72015-06-10 17:20:19 -0700453 statement.bind(3, certificate.wireEncode(), SQLITE_STATIC);
454 statement.step();
455}
456
457void
458PibSqlite3::removeCertificate(const Name& certName)
459{
460 Sqlite3Statement statement(m_database, "DELETE FROM certificates WHERE certificate_name=?");
461 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
462 statement.step();
463}
464
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700465v2::Certificate
Mickey Sweatt11314b72015-06-10 17:20:19 -0700466PibSqlite3::getCertificate(const Name& certName) const
467{
468 Sqlite3Statement statement(m_database,
469 "SELECT certificate_data FROM certificates WHERE certificate_name=?");
470 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
471
472 if (statement.step() == SQLITE_ROW)
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700473 return v2::Certificate(statement.getBlock(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700474 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700475 BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exit"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700476}
477
478std::set<Name>
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700479PibSqlite3::getCertificatesOfKey(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700480{
481 std::set<Name> certNames;
482
Mickey Sweatt11314b72015-06-10 17:20:19 -0700483 Sqlite3Statement statement(m_database,
484 "SELECT certificate_name "
485 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
486 "WHERE keys.key_name=?");
487 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
488
489 while (statement.step() == SQLITE_ROW)
490 certNames.insert(Name(statement.getBlock(0)));
491
492 return certNames;
493}
494
495void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700496PibSqlite3::setDefaultCertificateOfKey(const Name& keyName, const Name& certName)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700497{
498 if (!hasCertificate(certName)) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700499 BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700500 }
501
502 Sqlite3Statement statement(m_database,
503 "UPDATE certificates SET is_default=1 WHERE certificate_name=?");
504 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
505 statement.step();
506}
507
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700508v2::Certificate
509PibSqlite3::getDefaultCertificateOfKey(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700510{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700511 Sqlite3Statement statement(m_database,
512 "SELECT certificate_data "
513 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
514 "WHERE certificates.is_default=1 AND keys.key_name=?");
515 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
516
517 if (statement.step() == SQLITE_ROW)
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700518 return v2::Certificate(statement.getBlock(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700519 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700520 BOOST_THROW_EXCEPTION(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700521}
522
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700523} // namespace pib
Mickey Sweatt11314b72015-06-10 17:20:19 -0700524} // namespace security
525} // namespace ndn