blob: 238a0f8896fcffa198dd1cd155c5620d3a6efa4d [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
Mickey Sweatt11314b72015-06-10 17:20:19 -070035using util::Sqlite3Statement;
36
Yingdi Yufe4733a2015-10-22 14:24:12 -070037static const std::string INITIALIZATION = R"SQL(
38CREATE TABLE IF NOT EXISTS
39 tpmInfo(
40 tpm_locator BLOB
41 );
Mickey Sweatt11314b72015-06-10 17:20:19 -070042
Yingdi Yufe4733a2015-10-22 14:24:12 -070043CREATE TABLE IF NOT EXISTS
44 identities(
45 id INTEGER PRIMARY KEY,
46 identity BLOB NOT NULL,
47 is_default INTEGER DEFAULT 0
48 );
49
50CREATE UNIQUE INDEX IF NOT EXISTS
51 identityIndex ON identities(identity);
52
53CREATE TRIGGER IF NOT EXISTS
54 identity_default_before_insert_trigger
55 BEFORE INSERT ON identities
56 FOR EACH ROW
57 WHEN NEW.is_default=1
58 BEGIN
59 UPDATE identities SET is_default=0;
60 END;
61
62CREATE TRIGGER IF NOT EXISTS
63 identity_default_after_insert_trigger
64 AFTER INSERT ON identities
65 FOR EACH ROW
66 WHEN NOT EXISTS
67 (SELECT id
68 FROM identities
69 WHERE is_default=1)
70 BEGIN
71 UPDATE identities
72 SET is_default=1
73 WHERE identity=NEW.identity;
74 END;
75
76CREATE TRIGGER IF NOT EXISTS
77 identity_default_update_trigger
78 BEFORE UPDATE ON identities
79 FOR EACH ROW
80 WHEN NEW.is_default=1 AND OLD.is_default=0
81 BEGIN
82 UPDATE identities SET is_default=0;
83 END;
84
85
86CREATE TABLE IF NOT EXISTS
87 keys(
88 id INTEGER PRIMARY KEY,
89 identity_id INTEGER NOT NULL,
90 key_name BLOB NOT NULL,
91 key_bits BLOB NOT NULL,
92 is_default INTEGER DEFAULT 0,
93 FOREIGN KEY(identity_id)
94 REFERENCES identities(id)
95 ON DELETE CASCADE
96 ON UPDATE CASCADE
97 );
98
99CREATE UNIQUE INDEX IF NOT EXISTS
100 keyIndex ON keys(key_name);
101
102CREATE TRIGGER IF NOT EXISTS
103 key_default_before_insert_trigger
104 BEFORE INSERT ON keys
105 FOR EACH ROW
106 WHEN NEW.is_default=1
107 BEGIN
108 UPDATE keys
109 SET is_default=0
110 WHERE identity_id=NEW.identity_id;
111 END;
112
113CREATE TRIGGER IF NOT EXISTS
114 key_default_after_insert_trigger
115 AFTER INSERT ON keys
116 FOR EACH ROW
117 WHEN NOT EXISTS
118 (SELECT id
119 FROM keys
120 WHERE is_default=1
121 AND identity_id=NEW.identity_id)
122 BEGIN
123 UPDATE keys
124 SET is_default=1
125 WHERE key_name=NEW.key_name;
126 END;
127
128CREATE TRIGGER IF NOT EXISTS
129 key_default_update_trigger
130 BEFORE UPDATE ON keys
131 FOR EACH ROW
132 WHEN NEW.is_default=1 AND OLD.is_default=0
133 BEGIN
134 UPDATE keys
135 SET is_default=0
136 WHERE identity_id=NEW.identity_id;
137 END;
138
139
140CREATE TABLE IF NOT EXISTS
141 certificates(
142 id INTEGER PRIMARY KEY,
143 key_id INTEGER NOT NULL,
144 certificate_name BLOB NOT NULL,
145 certificate_data BLOB NOT NULL,
146 is_default INTEGER DEFAULT 0,
147 FOREIGN KEY(key_id)
148 REFERENCES keys(id)
149 ON DELETE CASCADE
150 ON UPDATE CASCADE
151 );
152
153CREATE UNIQUE INDEX IF NOT EXISTS
154 certIndex ON certificates(certificate_name);
155
156CREATE TRIGGER IF NOT EXISTS
157 cert_default_before_insert_trigger
158 BEFORE INSERT ON certificates
159 FOR EACH ROW
160 WHEN NEW.is_default=1
161 BEGIN
162 UPDATE certificates
163 SET is_default=0
164 WHERE key_id=NEW.key_id;
165 END;
166
167CREATE TRIGGER IF NOT EXISTS
168 cert_default_after_insert_trigger
169 AFTER INSERT ON certificates
170 FOR EACH ROW
171 WHEN NOT EXISTS
172 (SELECT id
173 FROM certificates
174 WHERE is_default=1
175 AND key_id=NEW.key_id)
176 BEGIN
177 UPDATE certificates
178 SET is_default=1
179 WHERE certificate_name=NEW.certificate_name;
180 END;
181
182CREATE TRIGGER IF NOT EXISTS
183 cert_default_update_trigger
184 BEFORE UPDATE ON certificates
185 FOR EACH ROW
186 WHEN NEW.is_default=1 AND OLD.is_default=0
187 BEGIN
188 UPDATE certificates
189 SET is_default=0
190 WHERE key_id=NEW.key_id;
191 END;
192)SQL";
193
194PibSqlite3::PibSqlite3(const std::string& location)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700195{
196 // Determine the path of PIB DB
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700197 boost::filesystem::path dbDir;
Yingdi Yufe4733a2015-10-22 14:24:12 -0700198 if (!location.empty()) {
199 dbDir = boost::filesystem::path(location);
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700200 }
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) {
Yingdi Yufe4733a2015-10-22 14:24:12 -0700225 BOOST_THROW_EXCEPTION(PibImpl::Error("PIB database cannot be opened/created in " + location));
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700226 }
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
Yingdi Yufe4733a2015-10-22 14:24:12 -0700245const std::string&
246PibSqlite3::getScheme()
247{
248 static std::string scheme = "pib-sqlite3";
249 return scheme;
250}
251
Mickey Sweatt11314b72015-06-10 17:20:19 -0700252void
253PibSqlite3::setTpmLocator(const std::string& tpmLocator)
254{
255 Sqlite3Statement statement(m_database, "UPDATE tpmInfo SET tpm_locator=?");
256 statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
257 statement.step();
258
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700259 if (sqlite3_changes(m_database) == 0) {
260 // no row is updated, tpm_locator does not exist, insert it directly
Mickey Sweatt11314b72015-06-10 17:20:19 -0700261 Sqlite3Statement insertStatement(m_database, "INSERT INTO tpmInfo (tpm_locator) values (?)");
262 insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
263 insertStatement.step();
264 }
265}
266
267std::string
268PibSqlite3::getTpmLocator() const
269{
270 Sqlite3Statement statement(m_database, "SELECT tpm_locator FROM tpmInfo");
271 int res = statement.step();
Mickey Sweatt11314b72015-06-10 17:20:19 -0700272 if (res == SQLITE_ROW)
273 return statement.getString(0);
274 else
Yingdi Yu7b3b5e92015-08-13 19:52:35 -0700275 return "";
Mickey Sweatt11314b72015-06-10 17:20:19 -0700276}
277
278bool
279PibSqlite3::hasIdentity(const Name& identity) const
280{
281 Sqlite3Statement statement(m_database, "SELECT id FROM identities WHERE identity=?");
282 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
283 return (statement.step() == SQLITE_ROW);
284}
285
286void
287PibSqlite3::addIdentity(const Name& identity)
288{
Yingdi Yu03997682015-11-23 16:41:38 -0800289 if (!hasIdentity(identity)) {
290 Sqlite3Statement statement(m_database, "INSERT INTO identities (identity) values (?)");
291 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
292 statement.step();
293 }
294
295 if (!hasDefaultIdentity()) {
296 setDefaultIdentity(identity);
297 }
Mickey Sweatt11314b72015-06-10 17:20:19 -0700298}
299
300void
301PibSqlite3::removeIdentity(const Name& identity)
302{
303 Sqlite3Statement statement(m_database, "DELETE FROM identities WHERE identity=?");
304 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
305 statement.step();
306}
307
Yingdi Yu7b3b5e92015-08-13 19:52:35 -0700308void
309PibSqlite3::clearIdentities()
310{
311 Sqlite3Statement statement(m_database, "DELETE FROM identities");
312 statement.step();
313}
314
Mickey Sweatt11314b72015-06-10 17:20:19 -0700315std::set<Name>
316PibSqlite3::getIdentities() const
317{
318 std::set<Name> identities;
319 Sqlite3Statement statement(m_database, "SELECT identity FROM identities");
320
321 while (statement.step() == SQLITE_ROW)
322 identities.insert(Name(statement.getBlock(0)));
323
324 return identities;
325}
326
327void
328PibSqlite3::setDefaultIdentity(const Name& identityName)
329{
330 Sqlite3Statement statement(m_database, "UPDATE identities SET is_default=1 WHERE identity=?");
331 statement.bind(1, identityName.wireEncode(), SQLITE_TRANSIENT);
332 statement.step();
333}
334
335Name
336PibSqlite3::getDefaultIdentity() const
337{
338 Sqlite3Statement statement(m_database, "SELECT identity FROM identities WHERE is_default=1");
339
340 if (statement.step() == SQLITE_ROW)
341 return Name(statement.getBlock(0));
342 else
Spyridon Mastorakis0d2ed2e2015-07-27 19:09:12 -0700343 BOOST_THROW_EXCEPTION(Pib::Error("No default identity"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700344}
345
346bool
Yingdi Yu03997682015-11-23 16:41:38 -0800347PibSqlite3::hasDefaultIdentity() const
348{
349 Sqlite3Statement statement(m_database, "SELECT identity FROM identities WHERE is_default=1");
350 return (statement.step() == SQLITE_ROW);
351}
352
353bool
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700354PibSqlite3::hasKey(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700355{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700356 Sqlite3Statement statement(m_database, "SELECT id FROM keys WHERE key_name=?");
357 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
358
359 return (statement.step() == SQLITE_ROW);
360}
361
362void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700363PibSqlite3::addKey(const Name& identity, const Name& keyName,
364 const uint8_t* key, size_t keyLen)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700365{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700366 // ensure identity exists
367 addIdentity(identity);
368
Yingdi Yu03997682015-11-23 16:41:38 -0800369 if (!hasKey(keyName)) {
370 Sqlite3Statement statement(m_database,
371 "INSERT INTO keys (identity_id, key_name, key_bits) "
372 "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?)");
373 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
374 statement.bind(2, keyName.wireEncode(), SQLITE_TRANSIENT);
375 statement.bind(3, key, keyLen, SQLITE_STATIC);
376 statement.step();
377 }
378 else {
379 Sqlite3Statement statement(m_database,
380 "UPDATE keys SET key_bits=? WHERE key_name=?");
381 statement.bind(1, key, keyLen, SQLITE_STATIC);
382 statement.bind(2, keyName.wireEncode(), SQLITE_TRANSIENT);
383 statement.step();
384 }
385
386 if (!hasDefaultKeyOfIdentity(identity)) {
387 setDefaultKeyOfIdentity(identity, keyName);
388 }
Mickey Sweatt11314b72015-06-10 17:20:19 -0700389}
390
391void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700392PibSqlite3::removeKey(const Name& keyName)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700393{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700394 Sqlite3Statement statement(m_database, "DELETE FROM keys WHERE key_name=?");
395 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
396 statement.step();
397}
398
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700399Buffer
400PibSqlite3::getKeyBits(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700401{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700402 Sqlite3Statement statement(m_database, "SELECT key_bits FROM keys WHERE key_name=?");
403 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
404
405 if (statement.step() == SQLITE_ROW)
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700406 return Buffer(statement.getBlob(0), statement.getSize(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700407 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700408 BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700409}
410
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700411std::set<Name>
Mickey Sweatt11314b72015-06-10 17:20:19 -0700412PibSqlite3::getKeysOfIdentity(const Name& identity) const
413{
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700414 std::set<Name> keyNames;
Mickey Sweatt11314b72015-06-10 17:20:19 -0700415
416 Sqlite3Statement statement(m_database,
417 "SELECT key_name "
418 "FROM keys JOIN identities ON keys.identity_id=identities.id "
419 "WHERE identities.identity=?");
420 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
421
422 while (statement.step() == SQLITE_ROW) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700423 keyNames.insert(Name(statement.getBlock(0)));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700424 }
425
426 return keyNames;
427}
428
429void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700430PibSqlite3::setDefaultKeyOfIdentity(const Name& identity, const Name& keyName)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700431{
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700432 if (!hasKey(keyName)) {
433 BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700434 }
435
436 Sqlite3Statement statement(m_database, "UPDATE keys SET is_default=1 WHERE key_name=?");
437 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
438 statement.step();
439}
440
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700441Name
Mickey Sweatt11314b72015-06-10 17:20:19 -0700442PibSqlite3::getDefaultKeyOfIdentity(const Name& identity) const
443{
444 if (!hasIdentity(identity)) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700445 BOOST_THROW_EXCEPTION(Pib::Error("Identity `" + identity.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700446 }
447
448 Sqlite3Statement statement(m_database,
449 "SELECT key_name "
450 "FROM keys JOIN identities ON keys.identity_id=identities.id "
451 "WHERE identities.identity=? AND keys.is_default=1");
452 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
453
454 if (statement.step() == SQLITE_ROW) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700455 return Name(statement.getBlock(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700456 }
457 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700458 BOOST_THROW_EXCEPTION(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700459}
460
461bool
Yingdi Yu03997682015-11-23 16:41:38 -0800462PibSqlite3::hasDefaultKeyOfIdentity(const Name& identity) const
463{
464 Sqlite3Statement statement(m_database,
465 "SELECT key_name "
466 "FROM keys JOIN identities ON keys.identity_id=identities.id "
467 "WHERE identities.identity=? AND keys.is_default=1");
468 statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
469
470 return (statement.step() == SQLITE_ROW);
471}
472
473bool
Mickey Sweatt11314b72015-06-10 17:20:19 -0700474PibSqlite3::hasCertificate(const Name& certName) const
475{
476 Sqlite3Statement statement(m_database, "SELECT id FROM certificates WHERE certificate_name=?");
477 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
478 return (statement.step() == SQLITE_ROW);
479}
480
481void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700482PibSqlite3::addCertificate(const v2::Certificate& certificate)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700483{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700484 // ensure key exists
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700485 const Block& content = certificate.getContent();
486 addKey(certificate.getIdentity(), certificate.getKeyName(), content.value(), content.value_size());
Mickey Sweatt11314b72015-06-10 17:20:19 -0700487
Yingdi Yu03997682015-11-23 16:41:38 -0800488 if (!hasCertificate(certificate.getName())) {
489 Sqlite3Statement statement(m_database,
490 "INSERT INTO certificates "
491 "(key_id, certificate_name, certificate_data) "
492 "VALUES ((SELECT id FROM keys WHERE key_name=?), ?, ?)");
493 statement.bind(1, certificate.getKeyName().wireEncode(), SQLITE_TRANSIENT);
494 statement.bind(2, certificate.getName().wireEncode(), SQLITE_TRANSIENT);
495 statement.bind(3, certificate.wireEncode(), SQLITE_STATIC);
496 statement.step();
497 }
498 else {
499 Sqlite3Statement statement(m_database,
500 "UPDATE certificates SET certificate_data=? WHERE certificate_name=?");
501 statement.bind(1, certificate.wireEncode(), SQLITE_STATIC);
502 statement.bind(2, certificate.getName().wireEncode(), SQLITE_TRANSIENT);
503 statement.step();
504 }
505
506 if (!hasDefaultCertificateOfKey(certificate.getKeyName())) {
507 setDefaultCertificateOfKey(certificate.getKeyName(), certificate.getName());
508 }
Mickey Sweatt11314b72015-06-10 17:20:19 -0700509}
510
511void
512PibSqlite3::removeCertificate(const Name& certName)
513{
514 Sqlite3Statement statement(m_database, "DELETE FROM certificates WHERE certificate_name=?");
515 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
516 statement.step();
517}
518
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700519v2::Certificate
Mickey Sweatt11314b72015-06-10 17:20:19 -0700520PibSqlite3::getCertificate(const Name& certName) const
521{
522 Sqlite3Statement statement(m_database,
523 "SELECT certificate_data FROM certificates WHERE certificate_name=?");
524 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
525
526 if (statement.step() == SQLITE_ROW)
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700527 return v2::Certificate(statement.getBlock(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700528 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700529 BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exit"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700530}
531
532std::set<Name>
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700533PibSqlite3::getCertificatesOfKey(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700534{
535 std::set<Name> certNames;
536
Mickey Sweatt11314b72015-06-10 17:20:19 -0700537 Sqlite3Statement statement(m_database,
538 "SELECT certificate_name "
539 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
540 "WHERE keys.key_name=?");
541 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
542
543 while (statement.step() == SQLITE_ROW)
544 certNames.insert(Name(statement.getBlock(0)));
545
546 return certNames;
547}
548
549void
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700550PibSqlite3::setDefaultCertificateOfKey(const Name& keyName, const Name& certName)
Mickey Sweatt11314b72015-06-10 17:20:19 -0700551{
552 if (!hasCertificate(certName)) {
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700553 BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exist"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700554 }
555
556 Sqlite3Statement statement(m_database,
557 "UPDATE certificates SET is_default=1 WHERE certificate_name=?");
558 statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
559 statement.step();
560}
561
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700562v2::Certificate
563PibSqlite3::getDefaultCertificateOfKey(const Name& keyName) const
Mickey Sweatt11314b72015-06-10 17:20:19 -0700564{
Mickey Sweatt11314b72015-06-10 17:20:19 -0700565 Sqlite3Statement statement(m_database,
566 "SELECT certificate_data "
567 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
568 "WHERE certificates.is_default=1 AND keys.key_name=?");
569 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
570
571 if (statement.step() == SQLITE_ROW)
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700572 return v2::Certificate(statement.getBlock(0));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700573 else
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700574 BOOST_THROW_EXCEPTION(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
Mickey Sweatt11314b72015-06-10 17:20:19 -0700575}
576
Yingdi Yu03997682015-11-23 16:41:38 -0800577bool
578PibSqlite3::hasDefaultCertificateOfKey(const Name& keyName) const
579{
580 Sqlite3Statement statement(m_database,
581 "SELECT certificate_data "
582 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
583 "WHERE certificates.is_default=1 AND keys.key_name=?");
584 statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
585
586 return (statement.step() == SQLITE_ROW);
587}
588
Yingdi Yu6ee2d362015-07-16 21:48:05 -0700589} // namespace pib
Mickey Sweatt11314b72015-06-10 17:20:19 -0700590} // namespace security
591} // namespace ndn