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 #ifdef NDN_CXX_HAVE_TESTS
220 if (getenv(
"TEST_HOME") !=
nullptr) {
221 actualDir = boost::filesystem::path(getenv(
"TEST_HOME")) /
".ndn";
224 #endif // NDN_CXX_HAVE_TESTS
225 if (getenv(
"HOME") !=
nullptr) {
226 actualDir = boost::filesystem::path(getenv(
"HOME")) /
".ndn";
229 actualDir = boost::filesystem::path(
".") /
".ndn";
233 actualDir = boost::filesystem::path(dir);
235 boost::filesystem::create_directories(actualDir);
238 int result = sqlite3_open_v2((actualDir /
"pib.db").c_str(), &m_database,
239 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
240 #ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
247 if (result != SQLITE_OK)
248 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"PIB DB cannot be opened/created: " + dir));
252 sqlite3_exec(m_database,
"PRAGMA foreign_keys=ON",
nullptr,
nullptr,
nullptr);
255 char* errorMessage =
nullptr;
256 result = sqlite3_exec(m_database, INITIALIZATION.c_str(),
nullptr,
nullptr, &errorMessage);
257 if (result != SQLITE_OK && errorMessage !=
nullptr) {
258 sqlite3_free(errorMessage);
259 BOOST_THROW_EXCEPTION(
PibImpl::Error(
"PIB DB cannot be initialized"));
265 sqlite3_close(m_database);
271 Sqlite3Statement statement(m_database,
"UPDATE tpmInfo SET tpm_locator=?");
272 statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
276 if (0 == sqlite3_changes(m_database)) {
277 Sqlite3Statement insertStatement(m_database,
"INSERT INTO tpmInfo (tpm_locator) values (?)");
278 insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
279 insertStatement.step();
286 Sqlite3Statement statement(m_database,
"SELECT tpm_locator FROM tpmInfo");
287 int res = statement.step();
290 if (res == SQLITE_ROW)
291 return statement.getString(0);
293 BOOST_THROW_EXCEPTION(
Pib::Error(
"TPM info does not exist"));
299 Sqlite3Statement statement(m_database,
"SELECT id FROM identities WHERE identity=?");
300 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
301 return (statement.step() == SQLITE_ROW);
307 Sqlite3Statement statement(m_database,
"INSERT INTO identities (identity) values (?)");
308 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
315 Sqlite3Statement statement(m_database,
"DELETE FROM identities WHERE identity=?");
316 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
323 std::set<Name> identities;
324 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities");
326 while (statement.step() == SQLITE_ROW)
327 identities.insert(
Name(statement.getBlock(0)));
335 Sqlite3Statement statement(m_database,
"UPDATE identities SET is_default=1 WHERE identity=?");
336 statement.bind(1, identityName.
wireEncode(), SQLITE_TRANSIENT);
343 Sqlite3Statement statement(m_database,
"SELECT identity FROM identities WHERE is_default=1");
345 if (statement.step() == SQLITE_ROW)
346 return Name(statement.getBlock(0));
348 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default identity"));
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);
365 if (
hasKey(identity, keyId)) {
375 Sqlite3Statement statement(m_database,
376 "INSERT INTO keys (identity_id, key_name, key_type, key_bits) "
377 "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)");
378 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
379 statement.bind(2, keyName.
wireEncode(), SQLITE_TRANSIENT);
380 statement.bind(3, static_cast<int>(publicKey.
getKeyType()));
381 statement.bind(4, publicKey.
get().
buf(), publicKey.
get().size(), SQLITE_STATIC);
390 Sqlite3Statement statement(m_database,
"DELETE FROM keys WHERE key_name=?");
391 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
400 Sqlite3Statement statement(m_database,
"SELECT key_bits FROM keys WHERE key_name=?");
401 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
403 if (statement.step() == SQLITE_ROW)
404 return v1::PublicKey(statement.getBlob(0), statement.getSize(0));
406 BOOST_THROW_EXCEPTION(
Pib::Error(
"Key does not exist"));
409 std::set<name::Component>
412 std::set<name::Component> keyNames;
414 Sqlite3Statement statement(m_database,
416 "FROM keys JOIN identities ON keys.identity_id=identities.id "
417 "WHERE identities.identity=?");
418 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
420 while (statement.step() == SQLITE_ROW) {
421 Name keyName(statement.getBlock(0));
422 keyNames.insert(keyName.get(-1));
433 if (!
hasKey(identity, keyId)) {
434 BOOST_THROW_EXCEPTION(
Pib::Error(
"No such key"));
437 Sqlite3Statement statement(m_database,
"UPDATE keys SET is_default=1 WHERE key_name=?");
438 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
446 BOOST_THROW_EXCEPTION(
Pib::Error(
"Identity does not exist"));
449 Sqlite3Statement statement(m_database,
451 "FROM keys JOIN identities ON keys.identity_id=identities.id "
452 "WHERE identities.identity=? AND keys.is_default=1");
453 statement.bind(1, identity.
wireEncode(), SQLITE_TRANSIENT);
455 if (statement.step() == SQLITE_ROW) {
456 Name keyName(statement.getBlock(0));
457 return keyName.
get(-1);
460 BOOST_THROW_EXCEPTION(
Pib::Error(
"No default key"));
466 Sqlite3Statement statement(m_database,
"SELECT id FROM certificates WHERE certificate_name=?");
467 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
468 return (statement.step() == SQLITE_ROW);
483 Sqlite3Statement statement(m_database,
484 "INSERT INTO certificates "
485 "(key_id, certificate_name, certificate_data) "
486 "VALUES ((SELECT id FROM keys WHERE key_name=?), ?, ?)");
487 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
488 statement.bind(2, certName.
wireEncode(), SQLITE_TRANSIENT);
489 statement.bind(3, certificate.
wireEncode(), SQLITE_STATIC);
496 Sqlite3Statement statement(m_database,
"DELETE FROM certificates WHERE certificate_name=?");
497 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
504 Sqlite3Statement statement(m_database,
505 "SELECT certificate_data FROM certificates WHERE certificate_name=?");
506 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
508 if (statement.step() == SQLITE_ROW)
511 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate does not exit"));
517 std::set<Name> certNames;
521 Sqlite3Statement statement(m_database,
522 "SELECT certificate_name "
523 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
524 "WHERE keys.key_name=?");
525 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
527 while (statement.step() == SQLITE_ROW)
528 certNames.insert(
Name(statement.getBlock(0)));
535 const Name& certName)
538 BOOST_THROW_EXCEPTION(
Pib::Error(
"Certificate does not exist"));
541 Sqlite3Statement statement(m_database,
542 "UPDATE certificates SET is_default=1 WHERE certificate_name=?");
543 statement.bind(1, certName.
wireEncode(), SQLITE_TRANSIENT);
552 Sqlite3Statement statement(m_database,
553 "SELECT certificate_data "
554 "FROM certificates JOIN keys ON certificates.key_id=keys.id "
555 "WHERE certificates.is_default=1 AND keys.key_name=?");
556 statement.bind(1, keyName.
wireEncode(), SQLITE_TRANSIENT);
558 if (statement.step() == SQLITE_ROW)
561 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 keyId of identity.
represents a non-semantic error
virtual v1::IdentityCertificate getCertificate(const Name &certName) const final
Get a certificate with name certName.
Copyright (c) 2013-2016 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.
const Buffer & get() const
virtual v1::IdentityCertificate getDefaultCertificateOfKey(const Name &identity, const name::Component &keyId) const final
Get the default certificate of a key with id keyId of identity.
virtual void addIdentity(const Name &identity) final
Add an identity.
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)
represents a semantic error
const Name & getName() const
Get name of the Data packet.
virtual v1::PublicKey getKeyBits(const Name &identity, const name::Component &keyId) const final
Get the key bits of a key.
KeyType getKeyType() const
size_t wireEncode(EncodingImpl< TAG > &encoder, bool wantUnsignedPortionOnly=false) const
Fast encoding or block size estimation.
PublicKey & getPublicKeyInfo()
virtual void addKey(const Name &identity, const name::Component &keyId, const v1::PublicKey &publicKey) final
Add a key.
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.
virtual void addCertificate(const v1::IdentityCertificate &certificate) final
Add a certificate.
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.
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 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.
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 Name & getPublicKeyName() const
const Component & get(ssize_t i) const
Get the component at the given index.