security: Adapt PIB to NDN Certificate Format version 2.0
The certificate format can be found at docs/specs/certificate-format.rst
Change-Id: I5656837f09ce327e06a0cb1abdf16ac28fe0b823
Refs: #3202
diff --git a/src/security/pib/pib-sqlite3.cpp b/src/security/pib/pib-sqlite3.cpp
index dc21610..829a509 100644
--- a/src/security/pib/pib-sqlite3.cpp
+++ b/src/security/pib/pib-sqlite3.cpp
@@ -1,6 +1,6 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
@@ -20,10 +20,9 @@
*/
#include "pib-sqlite3.hpp"
-
-#include "common.hpp"
#include "pib.hpp"
-#include "util/sqlite3-statement.hpp"
+#include "../security-common.hpp"
+#include "../../util/sqlite3-statement.hpp"
#include <sqlite3.h>
#include <boost/filesystem.hpp>
@@ -31,6 +30,7 @@
namespace ndn {
namespace security {
+namespace pib {
using std::string;
using util::Sqlite3Statement;
@@ -100,7 +100,6 @@
" id INTEGER PRIMARY KEY,\n"
" identity_id INTEGER NOT NULL, \n"
" key_name BLOB NOT NULL, \n"
- " key_type INTEGER NOT NULL, \n"
" key_bits BLOB NOT NULL, \n"
" is_default INTEGER DEFAULT 0, \n"
" FOREIGN KEY(identity_id) \n"
@@ -203,39 +202,28 @@
" WHERE key_id=NEW.key_id; \n"
" END; \n";
-static Name
-getKeyName(const Name& identity, const name::Component& keyId)
-{
- Name keyName = identity;
- keyName.append(keyId);
- return keyName;
-}
-
PibSqlite3::PibSqlite3(const string& dir)
{
// Determine the path of PIB DB
- boost::filesystem::path actualDir;
- if (dir == "") {
+ boost::filesystem::path dbDir;
+ if (!dir.empty()) {
+ dbDir = boost::filesystem::path(dir);
+ }
#ifdef NDN_CXX_HAVE_TESTS
- if (getenv("TEST_HOME") != nullptr) {
- actualDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
- }
- else
+ else if (getenv("TEST_HOME") != nullptr) {
+ dbDir = boost::filesystem::path(getenv("TEST_HOME")) / ".ndn";
+ }
#endif // NDN_CXX_HAVE_TESTS
- if (getenv("HOME") != nullptr) {
- actualDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
- }
- else {
- actualDir = boost::filesystem::path(".") / ".ndn";
- }
+ else if (getenv("HOME") != nullptr) {
+ dbDir = boost::filesystem::path(getenv("HOME")) / ".ndn";
}
else {
- actualDir = boost::filesystem::path(dir);
+ dbDir = boost::filesystem::current_path() / ".ndn";
}
- boost::filesystem::create_directories(actualDir);
+ boost::filesystem::create_directories(dbDir);
// Open PIB
- int result = sqlite3_open_v2((actualDir / "pib.db").c_str(), &m_database,
+ int result = sqlite3_open_v2((dbDir / "pib.db").c_str(), &m_database,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
"unix-dotfile"
@@ -244,9 +232,9 @@
#endif
);
- if (result != SQLITE_OK)
- BOOST_THROW_EXCEPTION(PibImpl::Error("PIB DB cannot be opened/created: " + dir));
-
+ if (result != SQLITE_OK) {
+ BOOST_THROW_EXCEPTION(PibImpl::Error("PIB database cannot be opened/created in " + dir));
+ }
// enable foreign key
sqlite3_exec(m_database, "PRAGMA foreign_keys=ON", nullptr, nullptr, nullptr);
@@ -272,8 +260,8 @@
statement.bind(1, tpmLocator, SQLITE_TRANSIENT);
statement.step();
- // no row is updated, tpm_locator does not exist, insert it directly
- if (0 == sqlite3_changes(m_database)) {
+ if (sqlite3_changes(m_database) == 0) {
+ // no row is updated, tpm_locator does not exist, insert it directly
Sqlite3Statement insertStatement(m_database, "INSERT INTO tpmInfo (tpm_locator) values (?)");
insertStatement.bind(1, tpmLocator, SQLITE_TRANSIENT);
insertStatement.step();
@@ -349,10 +337,8 @@
}
bool
-PibSqlite3::hasKey(const Name& identity, const name::Component& keyId) const
+PibSqlite3::hasKey(const Name& keyName) const
{
- Name keyName = getKeyName(identity, keyId);
-
Sqlite3Statement statement(m_database, "SELECT id FROM keys WHERE key_name=?");
statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
@@ -360,56 +346,49 @@
}
void
-PibSqlite3::addKey(const Name& identity, const name::Component& keyId, const v1::PublicKey& publicKey)
+PibSqlite3::addKey(const Name& identity, const Name& keyName,
+ const uint8_t* key, size_t keyLen)
{
- if (hasKey(identity, keyId)) {
+ if (hasKey(keyName)) {
return;
}
// ensure identity exists
addIdentity(identity);
- // add key
- Name keyName = getKeyName(identity, keyId);
-
Sqlite3Statement statement(m_database,
- "INSERT INTO keys (identity_id, key_name, key_type, key_bits) "
- "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)");
+ "INSERT INTO keys (identity_id, key_name, key_bits) "
+ "VALUES ((SELECT id FROM identities WHERE identity=?), ?, ?)");
statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
statement.bind(2, keyName.wireEncode(), SQLITE_TRANSIENT);
- statement.bind(3, static_cast<int>(publicKey.getKeyType()));
- statement.bind(4, publicKey.get().buf(), publicKey.get().size(), SQLITE_STATIC);
+ statement.bind(3, key, keyLen, SQLITE_STATIC);
statement.step();
}
void
-PibSqlite3::removeKey(const Name& identity, const name::Component& keyId)
+PibSqlite3::removeKey(const Name& keyName)
{
- Name keyName = getKeyName(identity, keyId);
-
Sqlite3Statement statement(m_database, "DELETE FROM keys WHERE key_name=?");
statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
statement.step();
}
-v1::PublicKey
-PibSqlite3::getKeyBits(const Name& identity, const name::Component& keyId) const
+Buffer
+PibSqlite3::getKeyBits(const Name& keyName) const
{
- Name keyName = getKeyName(identity, keyId);
-
Sqlite3Statement statement(m_database, "SELECT key_bits FROM keys WHERE key_name=?");
statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
if (statement.step() == SQLITE_ROW)
- return v1::PublicKey(statement.getBlob(0), statement.getSize(0));
+ return Buffer(statement.getBlob(0), statement.getSize(0));
else
- BOOST_THROW_EXCEPTION(Pib::Error("Key does not exist"));
+ BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
}
-std::set<name::Component>
+std::set<Name>
PibSqlite3::getKeysOfIdentity(const Name& identity) const
{
- std::set<name::Component> keyNames;
+ std::set<Name> keyNames;
Sqlite3Statement statement(m_database,
"SELECT key_name "
@@ -418,20 +397,17 @@
statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
while (statement.step() == SQLITE_ROW) {
- Name keyName(statement.getBlock(0));
- keyNames.insert(keyName.get(-1));
+ keyNames.insert(Name(statement.getBlock(0)));
}
return keyNames;
}
void
-PibSqlite3::setDefaultKeyOfIdentity(const Name& identity, const name::Component& keyId)
+PibSqlite3::setDefaultKeyOfIdentity(const Name& identity, const Name& keyName)
{
- Name keyName = getKeyName(identity, keyId);
-
- if (!hasKey(identity, keyId)) {
- BOOST_THROW_EXCEPTION(Pib::Error("No such key"));
+ if (!hasKey(keyName)) {
+ BOOST_THROW_EXCEPTION(Pib::Error("Key `" + keyName.toUri() + "` does not exist"));
}
Sqlite3Statement statement(m_database, "UPDATE keys SET is_default=1 WHERE key_name=?");
@@ -439,11 +415,11 @@
statement.step();
}
-name::Component
+Name
PibSqlite3::getDefaultKeyOfIdentity(const Name& identity) const
{
if (!hasIdentity(identity)) {
- BOOST_THROW_EXCEPTION(Pib::Error("Identity does not exist"));
+ BOOST_THROW_EXCEPTION(Pib::Error("Identity `" + identity.toUri() + "` does not exist"));
}
Sqlite3Statement statement(m_database,
@@ -453,11 +429,10 @@
statement.bind(1, identity.wireEncode(), SQLITE_TRANSIENT);
if (statement.step() == SQLITE_ROW) {
- Name keyName(statement.getBlock(0));
- return keyName.get(-1);
+ return Name(statement.getBlock(0));
}
else
- BOOST_THROW_EXCEPTION(Pib::Error("No default key"));
+ BOOST_THROW_EXCEPTION(Pib::Error("No default key for identity `" + identity.toUri() + "`"));
}
bool
@@ -469,23 +444,18 @@
}
void
-PibSqlite3::addCertificate(const v1::IdentityCertificate& certificate)
+PibSqlite3::addCertificate(const v2::Certificate& certificate)
{
- const Name& certName = certificate.getName();
- const Name& keyName = certificate.getPublicKeyName();
-
- name::Component keyId = keyName.get(-1);
- Name identityName = keyName.getPrefix(-1);
-
// ensure key exists
- addKey(identityName, keyId, certificate.getPublicKeyInfo());
+ const Block& content = certificate.getContent();
+ addKey(certificate.getIdentity(), certificate.getKeyName(), content.value(), content.value_size());
Sqlite3Statement statement(m_database,
"INSERT INTO certificates "
"(key_id, certificate_name, certificate_data) "
"VALUES ((SELECT id FROM keys WHERE key_name=?), ?, ?)");
- statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
- statement.bind(2, certName.wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(1, certificate.getKeyName().wireEncode(), SQLITE_TRANSIENT);
+ statement.bind(2, certificate.getName().wireEncode(), SQLITE_TRANSIENT);
statement.bind(3, certificate.wireEncode(), SQLITE_STATIC);
statement.step();
}
@@ -498,7 +468,7 @@
statement.step();
}
-v1::IdentityCertificate
+v2::Certificate
PibSqlite3::getCertificate(const Name& certName) const
{
Sqlite3Statement statement(m_database,
@@ -506,18 +476,16 @@
statement.bind(1, certName.wireEncode(), SQLITE_TRANSIENT);
if (statement.step() == SQLITE_ROW)
- return v1::IdentityCertificate(statement.getBlock(0));
+ return v2::Certificate(statement.getBlock(0));
else
- BOOST_THROW_EXCEPTION(Pib::Error("Certificate does not exit"));
+ BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exit"));
}
std::set<Name>
-PibSqlite3::getCertificatesOfKey(const Name& identity, const name::Component& keyId) const
+PibSqlite3::getCertificatesOfKey(const Name& keyName) const
{
std::set<Name> certNames;
- Name keyName = getKeyName(identity, keyId);
-
Sqlite3Statement statement(m_database,
"SELECT certificate_name "
"FROM certificates JOIN keys ON certificates.key_id=keys.id "
@@ -531,11 +499,10 @@
}
void
-PibSqlite3::setDefaultCertificateOfKey(const Name& identity, const name::Component& keyId,
- const Name& certName)
+PibSqlite3::setDefaultCertificateOfKey(const Name& keyName, const Name& certName)
{
if (!hasCertificate(certName)) {
- BOOST_THROW_EXCEPTION(Pib::Error("Certificate does not exist"));
+ BOOST_THROW_EXCEPTION(Pib::Error("Certificate `" + certName.toUri() + "` does not exist"));
}
Sqlite3Statement statement(m_database,
@@ -544,11 +511,9 @@
statement.step();
}
-v1::IdentityCertificate
-PibSqlite3::getDefaultCertificateOfKey(const Name& identity, const name::Component& keyId) const
+v2::Certificate
+PibSqlite3::getDefaultCertificateOfKey(const Name& keyName) const
{
- Name keyName = getKeyName(identity, keyId);
-
Sqlite3Statement statement(m_database,
"SELECT certificate_data "
"FROM certificates JOIN keys ON certificates.key_id=keys.id "
@@ -556,10 +521,11 @@
statement.bind(1, keyName.wireEncode(), SQLITE_TRANSIENT);
if (statement.step() == SQLITE_ROW)
- return v1::IdentityCertificate(statement.getBlock(0));
+ return v2::Certificate(statement.getBlock(0));
else
- BOOST_THROW_EXCEPTION(Pib::Error("Certificate does not exit"));
+ BOOST_THROW_EXCEPTION(Pib::Error("No default certificate for key `" + keyName.toUri() + "`"));
}
+} // namespace pib
} // namespace security
} // namespace ndn