24 #include "../security-common.hpp" 25 #include "../../util/sqlite3-statement.hpp" 28 #include <boost/filesystem.hpp> 29 #include <boost/algorithm/string.hpp> 35 using util::Sqlite3Statement;
38 CREATE TABLE IF NOT EXISTS 43 CREATE TABLE IF NOT EXISTS 45 id INTEGER PRIMARY KEY, 46 identity BLOB NOT NULL, 47 is_default INTEGER DEFAULT 0 50 CREATE UNIQUE INDEX IF NOT EXISTS 51 identityIndex ON identities(identity); 53 CREATE TRIGGER IF NOT EXISTS 54 identity_default_before_insert_trigger 55 BEFORE INSERT ON identities 59 UPDATE identities SET is_default=0; 62 CREATE TRIGGER IF NOT EXISTS 63 identity_default_after_insert_trigger 64 AFTER INSERT ON identities 73 WHERE identity=NEW.identity; 76 CREATE TRIGGER IF NOT EXISTS 77 identity_default_update_trigger 78 BEFORE UPDATE ON identities 80 WHEN NEW.is_default=1 AND OLD.is_default=0 82 UPDATE identities SET is_default=0; 86 CREATE TABLE IF NOT EXISTS 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) 99 CREATE UNIQUE INDEX IF NOT EXISTS 100 keyIndex ON keys(key_name); 102 CREATE TRIGGER IF NOT EXISTS 103 key_default_before_insert_trigger 104 BEFORE INSERT ON keys 106 WHEN NEW.is_default=1 110 WHERE identity_id=NEW.identity_id; 113 CREATE TRIGGER IF NOT EXISTS 114 key_default_after_insert_trigger 121 AND identity_id=NEW.identity_id) 125 WHERE key_name=NEW.key_name; 128 CREATE TRIGGER IF NOT EXISTS 129 key_default_update_trigger 130 BEFORE UPDATE ON keys 132 WHEN NEW.is_default=1 AND OLD.is_default=0 136 WHERE identity_id=NEW.identity_id; 140 CREATE TABLE IF NOT EXISTS 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, 153 CREATE UNIQUE INDEX IF NOT EXISTS 154 certIndex ON certificates(certificate_name); 156 CREATE TRIGGER IF NOT EXISTS 157 cert_default_before_insert_trigger 158 BEFORE INSERT ON certificates 160 WHEN NEW.is_default=1 164 WHERE key_id=NEW.key_id; 167 CREATE TRIGGER IF NOT EXISTS 168 cert_default_after_insert_trigger 169 AFTER INSERT ON certificates 175 AND key_id=NEW.key_id) 179 WHERE certificate_name=NEW.certificate_name; 182 CREATE TRIGGER IF NOT EXISTS 183 cert_default_update_trigger 184 BEFORE UPDATE ON certificates 186 WHEN NEW.is_default=1 AND OLD.is_default=0 190 WHERE key_id=NEW.key_id; 197 boost::filesystem::path dbDir;
198 if (!location.empty()) {
199 dbDir = boost::filesystem::path(location);
201 #ifdef NDN_CXX_HAVE_TESTS 202 else if (getenv(
"TEST_HOME") !=
nullptr) {
203 dbDir = boost::filesystem::path(getenv(
"TEST_HOME")) /
".ndn";
205 #endif // NDN_CXX_HAVE_TESTS 206 else if (getenv(
"HOME") !=
nullptr) {
207 dbDir = boost::filesystem::path(getenv(
"HOME")) /
".ndn";
210 dbDir = boost::filesystem::current_path() /
".ndn";
212 boost::filesystem::create_directories(dbDir);
215 int result = sqlite3_open_v2((dbDir /
"pib.db").c_str(), &m_database,
216 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
217 #ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
224 if (result != SQLITE_OK) {
225 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"PIB database cannot be opened/created in " + location));
229 sqlite3_exec(m_database,
"PRAGMA foreign_keys=ON",
nullptr,
nullptr,
nullptr);
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);
236 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"PIB DB cannot be initialized"));
242 sqlite3_close(m_database);
248 static std::string scheme =
"pib-sqlite3";
255 Sqlite3Statement statement(m_database,
"UPDATE tpmInfo SET tpm_locator=?");
256 statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
259 if (sqlite3_changes(m_database) == 0) {
261 Sqlite3Statement insertStatement(m_database,
"INSERT INTO tpmInfo (tpm_locator) values (?)");
262 insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
263 insertStatement.step();
270 Sqlite3Statement statement(m_database,
"SELECT tpm_locator FROM tpmInfo");
271 int res = statement.step();
272 if (res == SQLITE_ROW)
273 return statement.getString(0);
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);
290 Sqlite3Statement statement(m_database,
"INSERT INTO identities (identity) values (?)");
291 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
295 if (!hasDefaultIdentity()) {
303 Sqlite3Statement statement(m_database,
"DELETE FROM identities WHERE identity=?");
304 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
311 Sqlite3Statement statement(m_database,
"DELETE FROM identities");
318 std::set<Name> identities;
319 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities");
321 while (statement.step() == SQLITE_ROW)
322 identities.insert(
Name(statement.getBlock(0)));
330 Sqlite3Statement statement(m_database,
"UPDATE identities SET is_default=1 WHERE identity=?");
331 statement.bind(1, identityName.
wireEncode(), SQLITE_TRANSIENT);
338 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities WHERE is_default=1");
340 if (statement.step() == SQLITE_ROW)
341 return Name(statement.getBlock(0));
343 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default identity"));
347 PibSqlite3::hasDefaultIdentity()
const 349 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities WHERE is_default=1");
350 return (statement.step() == SQLITE_ROW);
356 Sqlite3Statement statement(m_database,
"SELECT id FROM keys WHERE key_name=?");
357 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
359 return (statement.step() == SQLITE_ROW);
364 const uint8_t* key,
size_t keyLen)
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);
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);
386 if (!hasDefaultKeyOfIdentity(identity)) {
394 Sqlite3Statement statement(m_database,
"DELETE FROM keys WHERE key_name=?");
395 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
402 Sqlite3Statement statement(m_database,
"SELECT key_bits FROM keys WHERE key_name=?");
403 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
405 if (statement.step() == SQLITE_ROW)
406 return Buffer(statement.getBlob(0), statement.getSize(0));
408 BOOST_THROW_EXCEPTION(
Pib::Error(
"Key `" + keyName.
toUri() +
"` does not exist"));
414 std::set<Name> keyNames;
416 Sqlite3Statement statement(m_database,
418 "FROM keys JOIN identities ON keys.identity_id=identities.id " 419 "WHERE identities.identity=?");
420 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
422 while (statement.step() == SQLITE_ROW) {
423 keyNames.insert(
Name(statement.getBlock(0)));
433 BOOST_THROW_EXCEPTION(
Pib::Error(
"Key `" + keyName.
toUri() +
"` does not exist"));
436 Sqlite3Statement statement(m_database,
"UPDATE keys SET is_default=1 WHERE key_name=?");
437 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
445 BOOST_THROW_EXCEPTION(
Pib::Error(
"Identity `" + identity.
toUri() +
"` does not exist"));
448 Sqlite3Statement statement(m_database,
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);
454 if (statement.step() == SQLITE_ROW) {
455 return Name(statement.getBlock(0));
458 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default key for identity `" + identity.
toUri() +
"`"));
462 PibSqlite3::hasDefaultKeyOfIdentity(
const Name& identity)
const 464 Sqlite3Statement statement(m_database,
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);
470 return (statement.step() == SQLITE_ROW);
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);
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=?), ?, ?)");
495 statement.bind(3, certificate.
wireEncode(), SQLITE_STATIC);
499 Sqlite3Statement statement(m_database,
500 "UPDATE certificates SET certificate_data=? WHERE certificate_name=?");
501 statement.bind(1, certificate.
wireEncode(), SQLITE_STATIC);
506 if (!hasDefaultCertificateOfKey(certificate.
getKeyName())) {
514 Sqlite3Statement statement(m_database,
"DELETE FROM certificates WHERE certificate_name=?");
515 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
522 Sqlite3Statement statement(m_database,
523 "SELECT certificate_data FROM certificates WHERE certificate_name=?");
524 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
526 if (statement.step() == SQLITE_ROW)
529 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate `" + certName.
toUri() +
"` does not exit"));
535 std::set<Name> certNames;
537 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);
543 while (statement.step() == SQLITE_ROW)
544 certNames.insert(
Name(statement.getBlock(0)));
553 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate `" + certName.
toUri() +
"` does not exist"));
556 Sqlite3Statement statement(m_database,
557 "UPDATE certificates SET is_default=1 WHERE certificate_name=?");
558 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
565 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);
571 if (statement.step() == SQLITE_ROW)
574 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default certificate for key `" + keyName.
toUri() +
"`"));
578 PibSqlite3::hasDefaultCertificateOfKey(
const Name& keyName)
const 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);
586 return (statement.step() == SQLITE_ROW);
represents a non-semantic error
void removeCertificate(const Name &certName) final
Remove a certificate with name certName.
Copyright (c) 2011-2015 Regents of the University of California.
Name getDefaultKeyOfIdentity(const Name &identity) const final
The certificate following the certificate format naming convention.
represents a semantic error
Name getKeyName() const
Get key name.
std::set< Name > getCertificatesOfKey(const Name &keyName) const final
Get a list of certificate names of a key with id keyName.
void clearIdentities() final
Erasing all certificates, keys, and identities.
void addKey(const Name &identity, const Name &keyName, const uint8_t *key, size_t keyLen) final
Add a key.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
Represents a TLV element of NDN packet format.
std::set< Name > getIdentities() const final
Get the name of all the identities.
void setTpmLocator(const std::string &tpmLocator) final
Set the corresponding TPM information to tpmLocator.
Catch-all error for security policy errors that don't fit in other categories.
v2::Certificate getCertificate(const Name &certName) const final
Get a certificate with name certName.
std::string toUri() const
Get URI representation of the name.
std::string getTpmLocator() const final
Get TPM Locator.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
Buffer getKeyBits(const Name &keyName) const final
Get the key bits of a key with name keyName.
static const std::string & getScheme()
void removeIdentity(const Name &identity) final
Remove an identity and related keys and certificates.
void setDefaultIdentity(const Name &identityName) final
Set an identity with name identityName as the default identity.
void setDefaultCertificateOfKey(const Name &keyName, const Name &certName) final
Set a cert with name certName as the default of a key with keyName.
Name getDefaultIdentity() const final
Get the default identity.
Name getIdentity() const
Get identity name.
Represents an absolute name.
size_t value_size() const
Get size of TLV-VALUE aka TLV-LENGTH.
~PibSqlite3()
Destruct and cleanup internal state.
PibSqlite3(const std::string &location="")
Create sqlite3-based PIB backed.
void addIdentity(const Name &identity) final
Add an identity.
void addCertificate(const v2::Certificate &certificate) final
Add a certificate.
const Name & getName() const
Get name.
v2::Certificate getDefaultCertificateOfKey(const Name &keyName) const final
bool hasKey(const Name &keyName) const final
Check the existence of a key with keyName.
const Block & getContent() const
Get Content.
void removeKey(const Name &keyName) final
Remove a key with keyName and related certificates.
void setDefaultKeyOfIdentity(const Name &identity, const Name &keyName) final
Set an key with keyName as the default key of an identity with name identity.
const uint8_t * value() const
Get pointer to TLV-VALUE.
std::set< Name > getKeysOfIdentity(const Name &identity) const final
Get all the key names of an identity with name identity.
static const std::string INITIALIZATION
bool hasIdentity(const Name &identity) const final
Check the existence of an identity.
General-purpose automatically managed/resized buffer.
bool hasCertificate(const Name &certName) const final
Check the existence of a certificate with name certName.