security: Add new v2::KeyChain
Change-Id: I5fdf51ecd96b50db2a7cbf730c6e8b1d9fbe09e9
Refs: #2926
diff --git a/src/security/pib/identity-container.hpp b/src/security/pib/identity-container.hpp
index 94cd370..9e45cf9 100644
--- a/src/security/pib/identity-container.hpp
+++ b/src/security/pib/identity-container.hpp
@@ -153,6 +153,7 @@
mutable std::unordered_map<Name, shared_ptr<detail::IdentityImpl>> m_identities;
shared_ptr<PibImpl> m_pibImpl;
+
friend class Pib;
};
diff --git a/src/security/pib/identity.cpp b/src/security/pib/identity.cpp
index 4797cb6..79cb090 100644
--- a/src/security/pib/identity.cpp
+++ b/src/security/pib/identity.cpp
@@ -40,13 +40,13 @@
}
Key
-Identity::addKey(const uint8_t* key, size_t keyLen, const Name& keyName)
+Identity::addKey(const uint8_t* key, size_t keyLen, const Name& keyName) const
{
return lock()->addKey(key, keyLen, keyName);
}
void
-Identity::removeKey(const Name& keyName)
+Identity::removeKey(const Name& keyName) const
{
return lock()->removeKey(keyName);
}
@@ -64,13 +64,13 @@
}
const Key&
-Identity::setDefaultKey(const Name& keyName)
+Identity::setDefaultKey(const Name& keyName) const
{
return lock()->setDefaultKey(keyName);
}
const Key&
-Identity::setDefaultKey(const uint8_t* key, size_t keyLen, const Name& keyName)
+Identity::setDefaultKey(const uint8_t* key, size_t keyLen, const Name& keyName) const
{
return lock()->setDefaultKey(key, keyLen, keyName);
}
diff --git a/src/security/pib/identity.hpp b/src/security/pib/identity.hpp
index 3d0117d..2bb1706 100644
--- a/src/security/pib/identity.hpp
+++ b/src/security/pib/identity.hpp
@@ -116,14 +116,14 @@
* @throw Pib::Error a key with the same name already exists
*/
Key
- addKey(const uint8_t* key, size_t keyLen, const Name& keyName);
+ addKey(const uint8_t* key, size_t keyLen, const Name& keyName) const;
/**
* @brief Remove a key with @p keyName
* @throw std::invalid_argument @p keyName does not match identity
*/
void
- removeKey(const Name& keyName);
+ removeKey(const Name& keyName) const;
/**
* @brief Set an existing key with @p keyName as the default key.
@@ -132,7 +132,7 @@
* @return The default key
*/
const Key&
- setDefaultKey(const Name& keyName);
+ setDefaultKey(const Name& keyName) const;
/**
* @brief Add a @p key of @p keyLen bytes with @p keyName and set it as the default key
@@ -141,7 +141,7 @@
* @return the default key
*/
const Key&
- setDefaultKey(const uint8_t* key, size_t keyLen, const Name& keyName);
+ setDefaultKey(const uint8_t* key, size_t keyLen, const Name& keyName) const;
private:
/**
@@ -154,6 +154,8 @@
private:
weak_ptr<detail::IdentityImpl> m_impl;
+
+ friend class v2::KeyChain;
};
} // namespace pib
diff --git a/src/security/pib/key.cpp b/src/security/pib/key.cpp
index b4e6daf..0d45140 100644
--- a/src/security/pib/key.cpp
+++ b/src/security/pib/key.cpp
@@ -59,13 +59,13 @@
}
void
-Key::addCertificate(const v2::Certificate& certificate)
+Key::addCertificate(const v2::Certificate& certificate) const
{
return lock()->addCertificate(certificate);
}
void
-Key::removeCertificate(const Name& certName)
+Key::removeCertificate(const Name& certName) const
{
return lock()->removeCertificate(certName);
}
@@ -83,13 +83,13 @@
}
const v2::Certificate&
-Key::setDefaultCertificate(const Name& certName)
+Key::setDefaultCertificate(const Name& certName) const
{
return lock()->setDefaultCertificate(certName);
}
const v2::Certificate&
-Key::setDefaultCertificate(const v2::Certificate& certificate)
+Key::setDefaultCertificate(const v2::Certificate& certificate) const
{
return lock()->setDefaultCertificate(certificate);
}
diff --git a/src/security/pib/key.hpp b/src/security/pib/key.hpp
index 69ceec8..4acc54a 100644
--- a/src/security/pib/key.hpp
+++ b/src/security/pib/key.hpp
@@ -28,7 +28,9 @@
namespace ndn {
namespace security {
+namespace v2 {
class KeyChain;
+} // namespace v2
namespace pib {
@@ -138,14 +140,14 @@
* @throw Pib::Error a certificate with the same name already exists
*/
void
- addCertificate(const v2::Certificate& certificate);
+ addCertificate(const v2::Certificate& certificate) const;
/**
* @brief Remove a certificate with @p certName
* @throw std::invalid_argument @p certName does not match key name
*/
void
- removeCertificate(const Name& certName);
+ removeCertificate(const Name& certName) const;
/**
* @brief Set an existing certificate with @p certName as the default certificate
@@ -154,7 +156,7 @@
* @return the default certificate
*/
const v2::Certificate&
- setDefaultCertificate(const Name& certName);
+ setDefaultCertificate(const Name& certName) const;
/**
* @brief Add @p certificate and set it as the default certificate of the key
@@ -163,7 +165,7 @@
* @return the default certificate
*/
const v2::Certificate&
- setDefaultCertificate(const v2::Certificate& certificate);
+ setDefaultCertificate(const v2::Certificate& certificate) const;
private:
/**
@@ -176,6 +178,8 @@
private:
weak_ptr<detail::KeyImpl> m_impl;
+
+ friend class v2::KeyChain;
};
} // namespace pib
diff --git a/src/security/pib/pib-memory.cpp b/src/security/pib/pib-memory.cpp
index aa93ba7..2d6aa7d 100644
--- a/src/security/pib/pib-memory.cpp
+++ b/src/security/pib/pib-memory.cpp
@@ -27,11 +27,18 @@
namespace security {
namespace pib {
-PibMemory::PibMemory()
+PibMemory::PibMemory(const std::string&)
: m_hasDefaultIdentity(false)
{
}
+const std::string&
+PibMemory::getScheme()
+{
+ static std::string scheme = "pib-memory";
+ return scheme;
+}
+
void
PibMemory::setTpmLocator(const std::string& tpmLocator)
{
diff --git a/src/security/pib/pib-memory.hpp b/src/security/pib/pib-memory.hpp
index 192f000..1252909 100644
--- a/src/security/pib/pib-memory.hpp
+++ b/src/security/pib/pib-memory.hpp
@@ -48,7 +48,15 @@
};
public:
- PibMemory();
+ /**
+ * @brief Create memory based PIB backend
+ * @param location Not used (required by the PIB-registration interface)
+ */
+ explicit
+ PibMemory(const std::string& location = "");
+
+ static const std::string&
+ getScheme();
public: // TpmLocator management
void
diff --git a/src/security/pib/pib-sqlite3.cpp b/src/security/pib/pib-sqlite3.cpp
index b19f32c..238a0f8 100644
--- a/src/security/pib/pib-sqlite3.cpp
+++ b/src/security/pib/pib-sqlite3.cpp
@@ -32,171 +32,171 @@
namespace security {
namespace pib {
-using std::string;
using util::Sqlite3Statement;
-static const string INITIALIZATION =
- "CREATE TABLE IF NOT EXISTS \n"
- " tpmInfo( \n"
- " tpm_locator BLOB \n"
- " ); \n"
- " \n"
- "CREATE TABLE IF NOT EXISTS \n"
- " identities( \n"
- " id INTEGER PRIMARY KEY,\n"
- " identity BLOB NOT NULL, \n"
- " is_default INTEGER DEFAULT 0 \n"
- " ); \n"
- " \n"
- "CREATE UNIQUE INDEX IF NOT EXISTS \n"
- " identityIndex ON identities(identity); \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " identity_default_before_insert_trigger \n"
- " BEFORE INSERT ON identities \n"
- " FOR EACH ROW \n"
- " WHEN NEW.is_default=1 \n"
- " BEGIN \n"
- " UPDATE identities SET is_default=0; \n"
- " END; \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " identity_default_after_insert_trigger \n"
- " AFTER INSERT ON identities \n"
- " FOR EACH ROW \n"
- " WHEN NOT EXISTS \n"
- " (SELECT id \n"
- " FROM identities \n"
- " WHERE is_default=1) \n"
- " BEGIN \n"
- " UPDATE identities \n"
- " SET is_default=1 \n"
- " WHERE identity=NEW.identity; \n"
- " END; \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " identity_default_update_trigger \n"
- " BEFORE UPDATE ON identities \n"
- " FOR EACH ROW \n"
- " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
- " BEGIN \n"
- " UPDATE identities SET is_default=0; \n"
- " END; \n"
- " \n"
- " \n"
- "CREATE TABLE IF NOT EXISTS \n"
- " keys( \n"
- " id INTEGER PRIMARY KEY,\n"
- " identity_id INTEGER NOT NULL, \n"
- " key_name BLOB NOT NULL, \n"
- " key_bits BLOB NOT NULL, \n"
- " is_default INTEGER DEFAULT 0, \n"
- " FOREIGN KEY(identity_id) \n"
- " REFERENCES identities(id) \n"
- " ON DELETE CASCADE \n"
- " ON UPDATE CASCADE \n"
- " ); \n"
- " \n"
- "CREATE UNIQUE INDEX IF NOT EXISTS \n"
- " keyIndex ON keys(key_name); \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " key_default_before_insert_trigger \n"
- " BEFORE INSERT ON keys \n"
- " FOR EACH ROW \n"
- " WHEN NEW.is_default=1 \n"
- " BEGIN \n"
- " UPDATE keys \n"
- " SET is_default=0 \n"
- " WHERE identity_id=NEW.identity_id; \n"
- " END; \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " key_default_after_insert_trigger \n"
- " AFTER INSERT ON keys \n"
- " FOR EACH ROW \n"
- " WHEN NOT EXISTS \n"
- " (SELECT id \n"
- " FROM keys \n"
- " WHERE is_default=1 \n"
- " AND identity_id=NEW.identity_id) \n"
- " BEGIN \n"
- " UPDATE keys \n"
- " SET is_default=1 \n"
- " WHERE key_name=NEW.key_name; \n"
- " END; \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " key_default_update_trigger \n"
- " BEFORE UPDATE ON keys \n"
- " FOR EACH ROW \n"
- " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
- " BEGIN \n"
- " UPDATE keys \n"
- " SET is_default=0 \n"
- " WHERE identity_id=NEW.identity_id; \n"
- " END; \n"
- " \n"
- " \n"
- "CREATE TABLE IF NOT EXISTS \n"
- " certificates( \n"
- " id INTEGER PRIMARY KEY,\n"
- " key_id INTEGER NOT NULL, \n"
- " certificate_name BLOB NOT NULL, \n"
- " certificate_data BLOB NOT NULL, \n"
- " is_default INTEGER DEFAULT 0, \n"
- " FOREIGN KEY(key_id) \n"
- " REFERENCES keys(id) \n"
- " ON DELETE CASCADE \n"
- " ON UPDATE CASCADE \n"
- " ); \n"
- " \n"
- "CREATE UNIQUE INDEX IF NOT EXISTS \n"
- " certIndex ON certificates(certificate_name);\n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " cert_default_before_insert_trigger \n"
- " BEFORE INSERT ON certificates \n"
- " FOR EACH ROW \n"
- " WHEN NEW.is_default=1 \n"
- " BEGIN \n"
- " UPDATE certificates \n"
- " SET is_default=0 \n"
- " WHERE key_id=NEW.key_id; \n"
- " END; \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " cert_default_after_insert_trigger \n"
- " AFTER INSERT ON certificates \n"
- " FOR EACH ROW \n"
- " WHEN NOT EXISTS \n"
- " (SELECT id \n"
- " FROM certificates \n"
- " WHERE is_default=1 \n"
- " AND key_id=NEW.key_id) \n"
- " BEGIN \n"
- " UPDATE certificates \n"
- " SET is_default=1 \n"
- " WHERE certificate_name=NEW.certificate_name;\n"
- " END; \n"
- " \n"
- "CREATE TRIGGER IF NOT EXISTS \n"
- " cert_default_update_trigger \n"
- " BEFORE UPDATE ON certificates \n"
- " FOR EACH ROW \n"
- " WHEN NEW.is_default=1 AND OLD.is_default=0 \n"
- " BEGIN \n"
- " UPDATE certificates \n"
- " SET is_default=0 \n"
- " WHERE key_id=NEW.key_id; \n"
- " END; \n";
+static const std::string INITIALIZATION = R"SQL(
+CREATE TABLE IF NOT EXISTS
+ tpmInfo(
+ tpm_locator BLOB
+ );
-PibSqlite3::PibSqlite3(const string& dir)
+CREATE TABLE IF NOT EXISTS
+ identities(
+ id INTEGER PRIMARY KEY,
+ identity BLOB NOT NULL,
+ is_default INTEGER DEFAULT 0
+ );
+
+CREATE UNIQUE INDEX IF NOT EXISTS
+ identityIndex ON identities(identity);
+
+CREATE TRIGGER IF NOT EXISTS
+ identity_default_before_insert_trigger
+ BEFORE INSERT ON identities
+ FOR EACH ROW
+ WHEN NEW.is_default=1
+ BEGIN
+ UPDATE identities SET is_default=0;
+ END;
+
+CREATE TRIGGER IF NOT EXISTS
+ identity_default_after_insert_trigger
+ AFTER INSERT ON identities
+ FOR EACH ROW
+ WHEN NOT EXISTS
+ (SELECT id
+ FROM identities
+ WHERE is_default=1)
+ BEGIN
+ UPDATE identities
+ SET is_default=1
+ WHERE identity=NEW.identity;
+ END;
+
+CREATE TRIGGER IF NOT EXISTS
+ identity_default_update_trigger
+ BEFORE UPDATE ON identities
+ FOR EACH ROW
+ WHEN NEW.is_default=1 AND OLD.is_default=0
+ BEGIN
+ UPDATE identities SET is_default=0;
+ END;
+
+
+CREATE TABLE IF NOT EXISTS
+ keys(
+ id INTEGER PRIMARY KEY,
+ identity_id INTEGER NOT NULL,
+ key_name BLOB NOT NULL,
+ key_bits BLOB NOT NULL,
+ is_default INTEGER DEFAULT 0,
+ FOREIGN KEY(identity_id)
+ REFERENCES identities(id)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE
+ );
+
+CREATE UNIQUE INDEX IF NOT EXISTS
+ keyIndex ON keys(key_name);
+
+CREATE TRIGGER IF NOT EXISTS
+ key_default_before_insert_trigger
+ BEFORE INSERT ON keys
+ FOR EACH ROW
+ WHEN NEW.is_default=1
+ BEGIN
+ UPDATE keys
+ SET is_default=0
+ WHERE identity_id=NEW.identity_id;
+ END;
+
+CREATE TRIGGER IF NOT EXISTS
+ key_default_after_insert_trigger
+ AFTER INSERT ON keys
+ FOR EACH ROW
+ WHEN NOT EXISTS
+ (SELECT id
+ FROM keys
+ WHERE is_default=1
+ AND identity_id=NEW.identity_id)
+ BEGIN
+ UPDATE keys
+ SET is_default=1
+ WHERE key_name=NEW.key_name;
+ END;
+
+CREATE TRIGGER IF NOT EXISTS
+ key_default_update_trigger
+ BEFORE UPDATE ON keys
+ FOR EACH ROW
+ WHEN NEW.is_default=1 AND OLD.is_default=0
+ BEGIN
+ UPDATE keys
+ SET is_default=0
+ WHERE identity_id=NEW.identity_id;
+ END;
+
+
+CREATE TABLE IF NOT EXISTS
+ certificates(
+ id INTEGER PRIMARY KEY,
+ key_id INTEGER NOT NULL,
+ certificate_name BLOB NOT NULL,
+ certificate_data BLOB NOT NULL,
+ is_default INTEGER DEFAULT 0,
+ FOREIGN KEY(key_id)
+ REFERENCES keys(id)
+ ON DELETE CASCADE
+ ON UPDATE CASCADE
+ );
+
+CREATE UNIQUE INDEX IF NOT EXISTS
+ certIndex ON certificates(certificate_name);
+
+CREATE TRIGGER IF NOT EXISTS
+ cert_default_before_insert_trigger
+ BEFORE INSERT ON certificates
+ FOR EACH ROW
+ WHEN NEW.is_default=1
+ BEGIN
+ UPDATE certificates
+ SET is_default=0
+ WHERE key_id=NEW.key_id;
+ END;
+
+CREATE TRIGGER IF NOT EXISTS
+ cert_default_after_insert_trigger
+ AFTER INSERT ON certificates
+ FOR EACH ROW
+ WHEN NOT EXISTS
+ (SELECT id
+ FROM certificates
+ WHERE is_default=1
+ AND key_id=NEW.key_id)
+ BEGIN
+ UPDATE certificates
+ SET is_default=1
+ WHERE certificate_name=NEW.certificate_name;
+ END;
+
+CREATE TRIGGER IF NOT EXISTS
+ cert_default_update_trigger
+ BEFORE UPDATE ON certificates
+ FOR EACH ROW
+ WHEN NEW.is_default=1 AND OLD.is_default=0
+ BEGIN
+ UPDATE certificates
+ SET is_default=0
+ WHERE key_id=NEW.key_id;
+ END;
+)SQL";
+
+PibSqlite3::PibSqlite3(const std::string& location)
{
// Determine the path of PIB DB
boost::filesystem::path dbDir;
- if (!dir.empty()) {
- dbDir = boost::filesystem::path(dir);
+ if (!location.empty()) {
+ dbDir = boost::filesystem::path(location);
}
#ifdef NDN_CXX_HAVE_TESTS
else if (getenv("TEST_HOME") != nullptr) {
@@ -222,7 +222,7 @@
);
if (result != SQLITE_OK) {
- BOOST_THROW_EXCEPTION(PibImpl::Error("PIB database cannot be opened/created in " + dir));
+ BOOST_THROW_EXCEPTION(PibImpl::Error("PIB database cannot be opened/created in " + location));
}
// enable foreign key
@@ -242,6 +242,13 @@
sqlite3_close(m_database);
}
+const std::string&
+PibSqlite3::getScheme()
+{
+ static std::string scheme = "pib-sqlite3";
+ return scheme;
+}
+
void
PibSqlite3::setTpmLocator(const std::string& tpmLocator)
{
diff --git a/src/security/pib/pib-sqlite3.hpp b/src/security/pib/pib-sqlite3.hpp
index 5571657..d27dab6 100644
--- a/src/security/pib/pib-sqlite3.hpp
+++ b/src/security/pib/pib-sqlite3.hpp
@@ -40,25 +40,28 @@
{
public:
/**
- * @brief Constructor of PibSqlite3
+ * @brief Create sqlite3-based PIB backed
*
- * This method will create a SQLite3 database file under the directory @p dir.
+ * This method will create a SQLite3 database file under the directory @p location.
* If the directory does not exist, it will be created automatically.
* It assumes that the directory does not contain a PIB database of an older version,
* It is user's responsibility to update the older version database or remove the database.
*
- * @param dir The directory where the database file is located. By default, it points to the
- * $HOME/.ndn directory.
+ * @param location The directory where the database file is located. By default, it points to the
+ * $HOME/.ndn directory.
* @throw PibImpl::Error when initialization fails.
*/
explicit
- PibSqlite3(const std::string& dir = "");
+ PibSqlite3(const std::string& location = "");
/**
* @brief Destruct and cleanup internal state
*/
~PibSqlite3();
+ static const std::string&
+ getScheme();
+
public: // TpmLocator management
void
setTpmLocator(const std::string& tpmLocator) final;
diff --git a/src/security/pib/pib.hpp b/src/security/pib/pib.hpp
index 47dbd5c..947e5a5 100644
--- a/src/security/pib/pib.hpp
+++ b/src/security/pib/pib.hpp
@@ -26,9 +26,6 @@
namespace ndn {
namespace security {
-
-class KeyChain;
-
namespace pib {
class PibImpl;
@@ -46,6 +43,10 @@
* the Pib class provides access to identities, and allows setting a default identity. Properties of
* an identity can be accessed after obtaining an Identity object.
*
+ * @note Pib instance is created and managed only by v2::KeyChain. v2::KeyChain::getPib()
+ * returns a const reference to the managed Pib instance, through which it is possible to
+ * retrieve information about identities, keys, and certificates.
+ *
* @throw PibImpl::Error when underlying implementation has non-semantic error.
*/
class Pib : noncopyable
@@ -184,7 +185,7 @@
shared_ptr<PibImpl> m_impl;
- friend class KeyChain;
+ friend class v2::KeyChain;
};
} // namespace pib