29 #include <boost/filesystem.hpp> 30 #include <boost/algorithm/string.hpp> 36 using util::Sqlite3Statement;
39 "CREATE TABLE IF NOT EXISTS \n" 41 " tpm_locator BLOB \n" 44 "CREATE TRIGGER IF NOT EXISTS \n" 45 " tpm_update_trigger \n" 46 " BEFORE UPDATE ON tpmInfo \n" 47 " WHEN NEW.tpm_locator!=OLD.tpm_locator \n" 49 " DELETE FROM certificates; \n" 50 " DELETE FROM keys; \n" 51 " DELETE FROM identities; \n" 55 "CREATE TABLE IF NOT EXISTS \n" 57 " id INTEGER PRIMARY KEY,\n" 58 " identity BLOB NOT NULL, \n" 59 " is_default INTEGER DEFAULT 0 \n" 62 "CREATE UNIQUE INDEX IF NOT EXISTS \n" 63 " identityIndex ON identities(identity); \n" 65 "CREATE TRIGGER IF NOT EXISTS \n" 66 " identity_default_before_insert_trigger \n" 67 " BEFORE INSERT ON identities \n" 69 " WHEN NEW.is_default=1 \n" 71 " UPDATE identities SET is_default=0; \n" 74 "CREATE TRIGGER IF NOT EXISTS \n" 75 " identity_default_after_insert_trigger \n" 76 " AFTER INSERT ON identities \n" 81 " WHERE is_default=1) \n" 83 " UPDATE identities \n" 84 " SET is_default=1 \n" 85 " WHERE identity=NEW.identity; \n" 88 "CREATE TRIGGER IF NOT EXISTS \n" 89 " identity_default_update_trigger \n" 90 " BEFORE UPDATE ON identities \n" 92 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n" 94 " UPDATE identities SET is_default=0; \n" 98 "CREATE TABLE IF NOT EXISTS \n" 100 " id INTEGER PRIMARY KEY,\n" 101 " identity_id INTEGER NOT NULL, \n" 102 " key_name BLOB NOT NULL, \n" 103 " key_type INTEGER NOT NULL, \n" 104 " key_bits BLOB NOT NULL, \n" 105 " is_default INTEGER DEFAULT 0, \n" 106 " FOREIGN KEY(identity_id) \n" 107 " REFERENCES identities(id) \n" 108 " ON DELETE CASCADE \n" 109 " ON UPDATE CASCADE \n" 112 "CREATE UNIQUE INDEX IF NOT EXISTS \n" 113 " keyIndex ON keys(key_name); \n" 115 "CREATE TRIGGER IF NOT EXISTS \n" 116 " key_default_before_insert_trigger \n" 117 " BEFORE INSERT ON keys \n" 119 " WHEN NEW.is_default=1 \n" 122 " SET is_default=0 \n" 123 " WHERE identity_id=NEW.identity_id; \n" 126 "CREATE TRIGGER IF NOT EXISTS \n" 127 " key_default_after_insert_trigger \n" 128 " AFTER INSERT ON keys \n" 130 " WHEN NOT EXISTS \n" 133 " WHERE is_default=1 \n" 134 " AND identity_id=NEW.identity_id) \n" 137 " SET is_default=1 \n" 138 " WHERE key_name=NEW.key_name; \n" 141 "CREATE TRIGGER IF NOT EXISTS \n" 142 " key_default_update_trigger \n" 143 " BEFORE UPDATE ON keys \n" 145 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n" 148 " SET is_default=0 \n" 149 " WHERE identity_id=NEW.identity_id; \n" 153 "CREATE TABLE IF NOT EXISTS \n" 155 " id INTEGER PRIMARY KEY,\n" 156 " key_id INTEGER NOT NULL, \n" 157 " certificate_name BLOB NOT NULL, \n" 158 " certificate_data BLOB NOT NULL, \n" 159 " is_default INTEGER DEFAULT 0, \n" 160 " FOREIGN KEY(key_id) \n" 161 " REFERENCES keys(id) \n" 162 " ON DELETE CASCADE \n" 163 " ON UPDATE CASCADE \n" 166 "CREATE UNIQUE INDEX IF NOT EXISTS \n" 167 " certIndex ON certificates(certificate_name);\n" 169 "CREATE TRIGGER IF NOT EXISTS \n" 170 " cert_default_before_insert_trigger \n" 171 " BEFORE INSERT ON certificates \n" 173 " WHEN NEW.is_default=1 \n" 175 " UPDATE certificates \n" 176 " SET is_default=0 \n" 177 " WHERE key_id=NEW.key_id; \n" 180 "CREATE TRIGGER IF NOT EXISTS \n" 181 " cert_default_after_insert_trigger \n" 182 " AFTER INSERT ON certificates \n" 184 " WHEN NOT EXISTS \n" 186 " FROM certificates \n" 187 " WHERE is_default=1 \n" 188 " AND key_id=NEW.key_id) \n" 190 " UPDATE certificates \n" 191 " SET is_default=1 \n" 192 " WHERE certificate_name=NEW.certificate_name;\n" 195 "CREATE TRIGGER IF NOT EXISTS \n" 196 " cert_default_update_trigger \n" 197 " BEFORE UPDATE ON certificates \n" 199 " WHEN NEW.is_default=1 AND OLD.is_default=0 \n" 201 " UPDATE certificates \n" 202 " SET is_default=0 \n" 203 " WHERE key_id=NEW.key_id; \n" 209 Name keyName = identity;
217 boost::filesystem::path actualDir;
219 if (getenv(
"HOME") ==
nullptr)
220 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"Environment variable HOME is not set"));
222 actualDir = boost::filesystem::path(getenv(
"HOME")) /
".ndn";
223 boost::filesystem::create_directories(actualDir);
226 actualDir = boost::filesystem::path(dir);
227 boost::filesystem::create_directories(actualDir);
230 int result = sqlite3_open_v2((actualDir /
"pib.db").c_str(), &m_database,
231 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
232 #ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
239 if (result != SQLITE_OK)
240 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"PIB DB cannot be opened/created: " + dir));
244 sqlite3_exec(m_database,
"PRAGMA foreign_keys=ON",
nullptr,
nullptr,
nullptr);
247 char* errorMessage =
nullptr;
248 result = sqlite3_exec(m_database, INITIALIZATION.c_str(),
nullptr,
nullptr, &errorMessage);
249 if (result != SQLITE_OK && errorMessage !=
nullptr) {
250 sqlite3_free(errorMessage);
251 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"PIB DB cannot be initialized"));
257 sqlite3_close(m_database);
263 Sqlite3Statement statement(m_database,
"UPDATE tpmInfo SET tpm_locator=?");
264 statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
268 if (0 == sqlite3_changes(m_database)) {
269 Sqlite3Statement insertStatement(m_database,
"INSERT INTO tpmInfo (tpm_locator) values (?)");
270 insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
271 insertStatement.step();
278 Sqlite3Statement statement(m_database,
"SELECT tpm_locator FROM tpmInfo");
279 int res = statement.step();
282 if (res == SQLITE_ROW)
283 return statement.getString(0);
285 BOOST_THROW_EXCEPTION(
Pib::Error(
"TPM info does not exist"));
291 Sqlite3Statement statement(m_database,
"SELECT id FROM identities WHERE identity=?");
292 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
293 return (statement.step() == SQLITE_ROW);
299 Sqlite3Statement statement(m_database,
"INSERT INTO identities (identity) values (?)");
300 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
307 Sqlite3Statement statement(m_database,
"DELETE FROM identities WHERE identity=?");
308 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
315 std::set<Name> identities;
316 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities");
318 while (statement.step() == SQLITE_ROW)
319 identities.insert(
Name(statement.getBlock(0)));
327 Sqlite3Statement statement(m_database,
"UPDATE identities SET is_default=1 WHERE identity=?");
328 statement.bind(1, identityName.
wireEncode(), SQLITE_TRANSIENT);
335 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities WHERE is_default=1");
337 if (statement.step() == SQLITE_ROW)
338 return Name(statement.getBlock(0));
340 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default identity"));
348 Sqlite3Statement statement(m_database,
"SELECT id FROM keys WHERE key_name=?");
349 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
351 return (statement.step() == SQLITE_ROW);
357 if (
hasKey(identity, keyId)) {
367 Sqlite3Statement statement(m_database,
368 "INSERT INTO keys (identity_id, key_name, key_type, key_bits) " 369 "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)");
370 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
371 statement.bind(2, keyName.
wireEncode(), SQLITE_TRANSIENT);
373 statement.bind(4, publicKey.
get().
buf(), publicKey.
get().size(), SQLITE_STATIC);
382 Sqlite3Statement statement(m_database,
"DELETE FROM keys WHERE key_name=?");
383 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
392 Sqlite3Statement statement(m_database,
"SELECT key_bits FROM keys WHERE key_name=?");
393 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
395 if (statement.step() == SQLITE_ROW)
396 return PublicKey(statement.getBlob(0), statement.getSize(0));
398 BOOST_THROW_EXCEPTION(
Pib::Error(
"Key does not exist"));
401 std::set<name::Component>
404 std::set<name::Component> keyNames;
406 Sqlite3Statement statement(m_database,
408 "FROM keys JOIN identities ON keys.identity_id=identities.id " 409 "WHERE identities.identity=?");
410 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
412 while (statement.step() == SQLITE_ROW) {
413 Name keyName(statement.getBlock(0));
414 keyNames.insert(keyName.get(-1));
425 if (!
hasKey(identity, keyId)) {
426 BOOST_THROW_EXCEPTION(
Pib::Error(
"No such key"));
429 Sqlite3Statement statement(m_database,
"UPDATE keys SET is_default=1 WHERE key_name=?");
430 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
438 BOOST_THROW_EXCEPTION(
Pib::Error(
"Identity does not exist"));
441 Sqlite3Statement statement(m_database,
443 "FROM keys JOIN identities ON keys.identity_id=identities.id " 444 "WHERE identities.identity=? AND keys.is_default=1");
445 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
447 if (statement.step() == SQLITE_ROW) {
448 Name keyName(statement.getBlock(0));
449 return keyName.
get(-1);
452 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default key"));
458 Sqlite3Statement statement(m_database,
"SELECT id FROM certificates WHERE certificate_name=?");
459 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
460 return (statement.step() == SQLITE_ROW);
475 Sqlite3Statement statement(m_database,
476 "INSERT INTO certificates " 477 "(key_id, certificate_name, certificate_data) " 478 "VALUES ((SELECT id FROM keys WHERE key_name=?), ?, ?)");
479 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
480 statement.bind(2, certName.
wireEncode(), SQLITE_TRANSIENT);
481 statement.bind(3, certificate.
wireEncode(), SQLITE_STATIC);
488 Sqlite3Statement statement(m_database,
"DELETE FROM certificates WHERE certificate_name=?");
489 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
496 Sqlite3Statement statement(m_database,
497 "SELECT certificate_data FROM certificates WHERE certificate_name=?");
498 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
500 if (statement.step() == SQLITE_ROW)
503 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate does not exit"));
509 std::set<Name> certNames;
513 Sqlite3Statement statement(m_database,
514 "SELECT certificate_name " 515 "FROM certificates JOIN keys ON certificates.key_id=keys.id " 516 "WHERE keys.key_name=?");
517 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
519 while (statement.step() == SQLITE_ROW)
520 certNames.insert(
Name(statement.getBlock(0)));
527 const Name& certName)
530 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate does not exist"));
533 Sqlite3Statement statement(m_database,
534 "UPDATE certificates SET is_default=1 WHERE certificate_name=?");
535 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
544 Sqlite3Statement statement(m_database,
545 "SELECT certificate_data " 546 "FROM certificates JOIN keys ON certificates.key_id=keys.id " 547 "WHERE certificates.is_default=1 AND keys.key_name=?");
548 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
550 if (statement.step() == SQLITE_ROW)
553 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate does not exit"));
virtual bool hasCertificate(const Name &certName) const final
Check the existence of a certificate with name certName.
PibSqlite3(const std::string &dir="")
Constructor of PibSqlite3.
virtual void setDefaultIdentity(const Name &identityName) final
Set an identity with name identityName as the default identity.
virtual void setDefaultCertificateOfKey(const Name &identity, const name::Component &keyId, const Name &certName) final
Set a cert with name certName as the default of a key with id of .
represents a non-semantic error
Copyright (c) 2011-2015 Regents of the University of California.
virtual std::set< Name > getCertificatesOfKey(const Name &identity, const name::Component &keyId) const final
Get a list of certificate names of a key with id keyId of identity.
virtual void addIdentity(const Name &identity) final
Add an identity.
virtual PublicKey getKeyBits(const Name &identity, const name::Component &keyId) const final
Get the key bits of a key.
virtual name::Component getDefaultKeyOfIdentity(const Name &identity) const final
Get the id of the default key of an identity with name identity.
virtual void removeIdentity(const Name &identity) final
Remove an identity.
virtual bool hasKey(const Name &identity, const name::Component &keyId) const final
Check the existence of a key.
size_t wireEncode(EncodingImpl< TAG > &encoder) const
Fast encoding or block size estimation.
static Name getKeyName(const Name &identity, const name::Component &keyId)
PublicKey & getPublicKeyInfo()
represents a semantic error
const Name & getName() const
Get name of the Data packet.
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
virtual IdentityCertificate getDefaultCertificateOfKey(const Name &identity, const name::Component &keyId) const final
Get the default certificate of a key with id of .
virtual std::string getTpmLocator() const final
Get TPM Locator.
virtual std::set< name::Component > getKeysOfIdentity(const Name &identity) const final
Get all the key ids of an identity with name identity.
KeyType getKeyType() const
Name abstraction to represent an absolute name.
virtual void setTpmLocator(const std::string &tpmLocator) final
Set the corresponding TPM information to tpmLocator.
virtual bool hasIdentity(const Name &identity) const final
Check the existence of an identity.
const Name & getPublicKeyName() const
virtual void removeCertificate(const Name &certName) final
Remove a certificate with name certName.
virtual Name getDefaultIdentity() const final
Get the default identity.
virtual std::set< Name > getIdentities() const final
Get the name of all the identities.
virtual void addKey(const Name &identity, const name::Component &keyId, const PublicKey &publicKey) final
Add a key.
virtual void setDefaultKeyOfIdentity(const Name &identity, const name::Component &keyId) final
Set an key with id keyId as the default key of an identity with name identity.
Component holds a read-only name component value.
const Buffer & get() const
virtual IdentityCertificate getCertificate(const Name &certName) const final
Get a certificate with name certName.
Name & append(const uint8_t *value, size_t valueLength)
Append a new component, copying from value of length valueLength.
static const string INITIALIZATION
PartialName getPrefix(ssize_t nComponents) const
Extract a prefix (PartialName) of the name, containing first nComponents components.
virtual void removeKey(const Name &identity, const name::Component &keyId) final
Remove a key.
~PibSqlite3()
Destruct and cleanup internal state.
const Component & get(ssize_t i) const
Get the component at the given index.
virtual void addCertificate(const IdentityCertificate &certificate) final
Add a certificate.