Move pib service from ndn-cxx to ndn-tools

Code is copied from ndn-cxx:commit:e1c8c4cfffb33dca13c8ca7d7ef04c7401a7cbef,
(gerrit change-id Ieea485c0ebdce9fb9c876cad005cb95fd8e0c899)
with minor changes for changing include paths and building script.

Change-Id: I77b94fe69b20f04c338e7be7387125f709fa9e1a
Refs: #3018
This commit is contained in:
Yingdi Yu committed 2015-07-22 10:56:21 -07:00
1 parent 4bd28fc839
commit 77627ab8ce
49 files changed
+8695

No files matched your search

+1
View File
@@ -12,3 +12,4 @@ in ndn-tools:
* Junxiao Shi <http://www.cs.arizona.edu/people/shijunxiao/>
* Eric Newberry <http://ericnewberry.com/>
* Xiaoke Jiang <http://netarchlab.tsinghua.edu.cn/~shock/>
* Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
+1
View File
@@ -12,4 +12,5 @@ man_pages = [
('ndnpingserver', 'ndnpingserver', 'reachability testing server', None, 1),
('ndndump', 'ndndump', 'traffic analysis tool', None, 8),
('ndn-dissect', 'ndn-dissect', 'NDN packet format inspector', None, 1),
('ndn-pib', 'ndn-pib', 'NDN PIB service', None, 1),
]
+35
View File
@@ -0,0 +1,35 @@
ndn-pib
========
``ndn-pib`` is a public key and certificate management and publishing service.
Usage
-----
::
ndn-pib [-h] -o owner -d database_dir -t tpm_locator
Description
-----------
This command will start a PIB service process which serves signing key lookup/management for local
applications and also public the public key certificate of signing keys. The lookup/management
interface listens on a prefix "/localhost/pib/[OwnerName]" and accept five types of command (get,
default, list, update, delete). More details can be found at `Public key Info Base (PIB) Service
<http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base>`__
Since PIB service is queried through Interest/Data exchange, NFD is required to run before this
command is executed.
This command requires three arguments: ``owner`` specify the owner of the pib service, which is also
the third name component in the local lookup/management prefix; ``database_dir`` is the path to the
database where all the public key, certificate, identity are stored and managed; ``tpm_locator`` is
locator of a TPM which stores the corresponding private key of the public keys in PIB.
Example
-------
::
$ ndn-pib -o alice -d /var/pib -t tpm-file:/var/ndn/tpm
+132
View File
@@ -0,0 +1,132 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "tools/pib/cert-publisher.hpp"
#include "identity-management-time-fixture.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
#include <boost/filesystem.hpp>
#include "tests/test-common.hpp"
namespace ndn {
namespace pib {
namespace tests {
class CertPublisherFixture : public ndn::security::IdentityManagementTimeFixture
{
public:
CertPublisherFixture()
: tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
, db(tmpPath.c_str())
, face(util::makeDummyClientFace(io, {true, true}))
{
}
~CertPublisherFixture()
{
boost::filesystem::remove_all(tmpPath);
}
boost::asio::io_service io;
boost::filesystem::path tmpPath;
PibDb db;
shared_ptr<util::DummyClientFace> face;
};
BOOST_FIXTURE_TEST_SUITE(TestCertPublisher, CertPublisherFixture)
BOOST_AUTO_TEST_CASE(Basic)
{
// Initialize id1
Name id1("/test/identity");
addIdentity(id1);
Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
Name keyName11 = cert111->getPublicKeyName();
advanceClocks(io, time::milliseconds(100));
shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
Name certName112 = cert112->getName();
CertPublisher certPublisher(*face, db);
// Add a certificate
db.addCertificate(*cert111);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
auto interest111 = make_shared<Interest>(cert111->getName().getPrefix(-1));
face->receive(*interest111);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
BOOST_CHECK(face->sentDatas[0].wireEncode() == cert111->wireEncode());
face->sentDatas.clear();
// Add another certificate
db.addCertificate(*cert112);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
auto interest112 = make_shared<Interest>(cert112->getName().getPrefix(-1));
face->receive(*interest112);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
BOOST_CHECK(face->sentDatas[0].wireEncode() == cert111->wireEncode());
face->sentDatas.clear();
Exclude exclude;
exclude.excludeOne(cert111->getName().get(-1));
interest112->setExclude(exclude);
face->receive(*interest112);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
BOOST_CHECK(face->sentDatas[0].wireEncode() == cert112->wireEncode());
face->sentDatas.clear();
// delete a certificate
db.deleteCertificate(certName112);
face->receive(*interest112);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
face->receive(*interest111);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
BOOST_CHECK(face->sentDatas[0].wireEncode() == cert111->wireEncode());
face->sentDatas.clear();
// delete another certificate
db.deleteCertificate(certName111);
face->receive(*interest112);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
face->receive(*interest111);
advanceClocks(io, time::milliseconds(2), 50);
BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace pib
} // namespace ndn
@@ -0,0 +1,58 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "identity-management-time-fixture.hpp"
namespace ndn {
namespace security {
IdentityManagementTimeFixture::IdentityManagementTimeFixture()
: m_keyChainTmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "PibIdMgmtTimeTest")
, m_keyChain(std::string("pib-sqlite3:").append(m_keyChainTmpPath.string()),
std::string("tpm-file:").append(m_keyChainTmpPath.string()))
{
}
IdentityManagementTimeFixture::~IdentityManagementTimeFixture()
{
for (const auto& identity : m_identities) {
m_keyChain.deleteIdentity(identity);
}
boost::filesystem::remove_all(m_keyChainTmpPath);
}
bool
IdentityManagementTimeFixture::addIdentity(const Name& identity, const KeyParams& params)
{
try {
m_keyChain.createIdentity(identity, params);
m_identities.push_back(identity);
return true;
}
catch (std::runtime_error&) {
return false;
}
}
} // namespace security
} // namespace ndn
@@ -0,0 +1,61 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
#define NDN_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
#include <ndn-cxx/security/key-chain.hpp>
#include <vector>
#include <boost/filesystem.hpp>
#include "tests/test-common.hpp"
namespace ndn {
namespace security {
/**
* @brief IdentityManagementTimeFixture is a test suite level fixture.
* Test cases in the suite can use this fixture to create identities.
* Identities added via addIdentity method are automatically deleted
* during test teardown.
*/
class IdentityManagementTimeFixture : public tests::UnitTestTimeFixture
{
public:
IdentityManagementTimeFixture();
~IdentityManagementTimeFixture();
/// @brief add identity, return true if succeed.
bool
addIdentity(const Name& identity, const KeyParams& params = KeyChain::DEFAULT_KEY_PARAMS);
protected:
boost::filesystem::path m_keyChainTmpPath;
KeyChain m_keyChain;
std::vector<Name> m_identities;
};
} // namespace security
} // namespace ndn
#endif // NDN_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
+75
View File
@@ -0,0 +1,75 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "tools/pib/key-cache.hpp"
#include "tests/test-common.hpp"
namespace ndn {
namespace pib {
namespace tests {
BOOST_AUTO_TEST_SUITE(TestKeyCache)
BOOST_AUTO_TEST_CASE(Basic)
{
KeyCache keyCache(3);
Name name1("/1");
Name name2("/2");
Name name3("/3");
Name name4("/4");
auto key1 = make_shared<PublicKey>();
auto key2 = make_shared<PublicKey>();
auto key3 = make_shared<PublicKey>();
auto key4 = make_shared<PublicKey>();
keyCache.insert(name1, key1);
keyCache.insert(name2, key2);
keyCache.insert(name3, key3);
BOOST_CHECK_EQUAL(keyCache.size(), 3);
BOOST_CHECK(static_cast<bool>(keyCache.find(name1)));
BOOST_CHECK(static_cast<bool>(keyCache.find(name2)));
BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
BOOST_CHECK(!static_cast<bool>(keyCache.find(name4)));
keyCache.insert(name1, key1);
keyCache.insert(name4, key4);
BOOST_CHECK_EQUAL(keyCache.size(), 3);
BOOST_CHECK(static_cast<bool>(keyCache.find(name1)));
BOOST_CHECK(!static_cast<bool>(keyCache.find(name2)));
BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
BOOST_CHECK(static_cast<bool>(keyCache.find(name4)));
keyCache.erase(name1);
BOOST_CHECK_EQUAL(keyCache.size(), 2);
BOOST_CHECK(!static_cast<bool>(keyCache.find(name1)));
BOOST_CHECK(static_cast<bool>(keyCache.find(name3)));
BOOST_CHECK(static_cast<bool>(keyCache.find(name4)));
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace pib
} // namespace ndn
+474
View File
@@ -0,0 +1,474 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "tools/pib/pib-db.hpp"
#include "identity-management-time-fixture.hpp"
#include <boost/filesystem.hpp>
#include "tests/test-common.hpp"
namespace ndn {
namespace pib {
namespace tests {
class PibDbTestFixture : public ndn::security::IdentityManagementTimeFixture
{
public:
PibDbTestFixture()
: tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
, db(tmpPath.c_str())
{
}
~PibDbTestFixture()
{
boost::filesystem::remove_all(tmpPath);
}
boost::asio::io_service io;
boost::filesystem::path tmpPath;
PibDb db;
std::vector<Name> deletedIds;
std::vector<Name> deletedKeys;
std::vector<Name> deletedCerts;
std::vector<Name> insertedCerts;
};
BOOST_FIXTURE_TEST_SUITE(TestPibDb, PibDbTestFixture)
BOOST_AUTO_TEST_CASE(MgmtTest)
{
Name testUser("/localhost/pib/test/mgmt");
addIdentity(testUser);
Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
BOOST_CHECK_EQUAL(db.getOwnerName(), "");
BOOST_CHECK(db.getMgmtCertificate() == nullptr);
db.updateMgmtCertificate(*testUserCert);
BOOST_CHECK_EQUAL(db.getOwnerName(), "test");
BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(), testUserCertName);
db.setTpmLocator("tpmLocator");
BOOST_CHECK_EQUAL(db.getTpmLocator(), "tpmLocator");
Name testUser2("/localhost/pib/test2/mgmt");
addIdentity(testUser2);
Name testUser2CertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser2);
shared_ptr<IdentityCertificate> testUser2Cert = m_keyChain.getCertificate(testUser2CertName);
BOOST_CHECK_THROW(db.updateMgmtCertificate(*testUser2Cert), PibDb::Error);
Name testUserKeyName2 = m_keyChain.generateRsaKeyPairAsDefault(testUser);
shared_ptr<IdentityCertificate> testUserCert2 = m_keyChain.selfSign(testUserKeyName2);
BOOST_CHECK_NO_THROW(db.updateMgmtCertificate(*testUserCert2));
BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(),
testUserCert2->getName());
}
BOOST_AUTO_TEST_CASE(IdentityTest)
{
db.identityDeleted.connect([this] (const Name& id) {
this->deletedIds.push_back(id);
});
Name identity("/test/identity");
Name identity2("/test/identity2");
// Add an identity: /test/identity
// Since there is no default identity,
// the new added identity will be set as the default identity.
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
db.addIdentity(identity);
BOOST_CHECK(db.hasIdentity(identity));
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
// Add the second identity: /test/identity2
// Since the default identity exists,
// the new added identity will not be set as the default identity.
db.addIdentity(identity2);
BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
// Set the second identity: /test/identity2 as default explicitly
db.setDefaultIdentity(identity2);
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
// Delete identity /test/identity2, which is also the default one
// This will trigger the identityDeleted signal
// and also causes no default identity.
db.deleteIdentity(identity2);
BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
BOOST_CHECK_EQUAL(db.hasIdentity(identity), true);
BOOST_CHECK_EQUAL(deletedIds.size(), 1);
BOOST_CHECK_EQUAL(deletedIds[0], identity2);
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
deletedIds.clear();
// Add the second identity back
// Since there is no default identity (though another identity still exists),
// the second identity will be set as default.
db.addIdentity(identity2);
BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
// Delete identity /test/identity
db.deleteIdentity(identity);
BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
BOOST_CHECK_EQUAL(deletedIds.size(), 1);
BOOST_CHECK_EQUAL(deletedIds[0], identity);
deletedIds.clear();
// Delete identity /test/identity2
db.deleteIdentity(identity2);
BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
BOOST_CHECK_EQUAL(deletedIds.size(), 1);
BOOST_CHECK_EQUAL(deletedIds[0], identity2);
deletedIds.clear();
}
BOOST_AUTO_TEST_CASE(KeyTest)
{
db.identityDeleted.connect([this] (const Name& id) {
this->deletedIds.push_back(id);
});
db.keyDeleted.connect([this] (const Name& key) {
this->deletedKeys.push_back(key);
});
// Initialize id1
Name id1("/test/identity");
addIdentity(id1);
Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
Name keyName11 = cert111->getPublicKeyName();
PublicKey& key11 = cert111->getPublicKeyInfo();
advanceClocks(io, time::milliseconds(100));
Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
PublicKey& key12 = cert121->getPublicKeyInfo();
// Initialize id2
advanceClocks(io, time::milliseconds(100));
Name id2("/test/identity2");
addIdentity(id2);
Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
Name keyName21 = cert211->getPublicKeyName();
PublicKey& key21 = cert211->getPublicKeyInfo();
advanceClocks(io, time::milliseconds(100));
Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
PublicKey& key22 = cert221->getPublicKeyInfo();
// Add a key, the corresponding identity should be added as well
// Since the PIB does not have any default identity set before,
// the added identity will be set as default.
// Since there is no default key for the identity,
// the added key will be set as default.
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
BOOST_CHECK(db.getKey(keyName11) == nullptr);
db.addKey(keyName11, key11);
BOOST_CHECK(db.hasIdentity(id1));
BOOST_CHECK(db.getKey(keyName11) != nullptr);
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
// Add the second key of /test/identity.
// Since the default key of /test/identity has been set,
// The new added key will not be set as default.
db.addKey(keyName12, key12);
BOOST_CHECK(db.getKey(keyName12) != nullptr);
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
// Explicitly set the second key as the default key of /test/identity
db.setDefaultKeyNameOfIdentity(keyName12);
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
// Delete the second key which is also the default key.
// This will trigger the keyDeleted signal.
// This will also cause no default key for /test/identity
db.deleteKey(keyName12);
BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName22), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName21), false);
BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
BOOST_CHECK_EQUAL(deletedKeys[0], keyName12);
deletedKeys.clear();
// Add the second key back.
// Since there is no default key of /test/identity (although another key still exists)
// The second key will be set as the default key of /test/identity
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
db.addKey(keyName12, key12);
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
// Prepare test for identity deletion
db.addKey(keyName21, key21);
db.addKey(keyName22, key22);
BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
// Delete the identity.
// All keys of the identity should also be deleted,
// and the keyDeleted signal should be triggered twice.
db.deleteIdentity(id1);
BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
deletedKeys.end());
BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
deletedKeys.end());
BOOST_CHECK_EQUAL(deletedIds.size(), 1);
BOOST_CHECK_EQUAL(deletedIds[0], id1);
}
BOOST_AUTO_TEST_CASE(CertTest)
{
db.identityDeleted.connect([this] (const Name& id) {
this->deletedIds.push_back(id);
});
db.keyDeleted.connect([this] (const Name& key) {
this->deletedKeys.push_back(key);
});
db.certificateDeleted.connect([this] (const Name& certificate) {
this->deletedCerts.push_back(certificate);
});
db.certificateInserted.connect([this] (const Name& certificate) {
this->insertedCerts.push_back(certificate);
});
// Initialize id1
Name id1("/test/identity");
addIdentity(id1);
Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
Name keyName11 = cert111->getPublicKeyName();
advanceClocks(io, time::milliseconds(100));
shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
Name certName112 = cert112->getName();
advanceClocks(io, time::milliseconds(100));
Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
Name certName121 = cert121->getName();
advanceClocks(io, time::milliseconds(100));
shared_ptr<IdentityCertificate> cert122 = m_keyChain.selfSign(keyName12);
Name certName122 = cert122->getName();
// Initialize id2
advanceClocks(io, time::milliseconds(100));
Name id2("/test/identity2");
addIdentity(id2);
Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
Name keyName21 = cert211->getPublicKeyName();
advanceClocks(io, time::milliseconds(100));
shared_ptr<IdentityCertificate> cert212 = m_keyChain.selfSign(keyName21);
Name certName212 = cert212->getName();
advanceClocks(io, time::milliseconds(100));
Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
Name certName221 = cert221->getName();
advanceClocks(io, time::milliseconds(100));
shared_ptr<IdentityCertificate> cert222 = m_keyChain.selfSign(keyName22);
Name certName222 = cert222->getName();
// Add a certificate
// This will also add the corresponding key and identity.
// Since there is no default setting before,
// The certificate will be set as the default one of the key, and so be the key and identity
BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
db.addCertificate(*cert111);
BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName111) !=
insertedCerts.end());
insertedCerts.clear();
// Add the second certificate of the same key
// Since default certificate already exists, no default setting changes.
BOOST_CHECK(db.getCertificate(certName112) == nullptr);
db.addCertificate(*cert112);
BOOST_CHECK(db.getCertificate(certName112) != nullptr);
BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName112) !=
insertedCerts.end());
insertedCerts.clear();
// Explicitly set the second certificate as the default one of the key.
db.setDefaultCertNameOfKey(certName112);
BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
// Delete the default certificate
// This will trigger certificateDeleted signal
// and also causes no default certificate for the key.
db.deleteCertificate(certName112);
BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
BOOST_CHECK_EQUAL(deletedCerts.size(), 1);
BOOST_CHECK_EQUAL(deletedCerts[0], certName112);
BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
deletedCerts.clear();
// Add the second certificate back
// Since there is no default certificate of the key (though another certificate still exists),
// the new added certificate will be set as default
db.addCertificate(*cert112);
BOOST_CHECK(db.getCertificate(certName112) != nullptr);
BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
insertedCerts.clear();
// Add entries for delete tests
db.addCertificate(*cert111); // already exists no certInserted signal emitted
db.addCertificate(*cert112); // already exists no certInserted signal emitted
db.addCertificate(*cert121);
db.addCertificate(*cert122);
db.addCertificate(*cert211);
db.addCertificate(*cert212);
db.addCertificate(*cert221);
db.addCertificate(*cert222);
BOOST_CHECK_EQUAL(insertedCerts.size(), 6);
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName121) !=
insertedCerts.end());
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName122) !=
insertedCerts.end());
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName211) !=
insertedCerts.end());
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName212) !=
insertedCerts.end());
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName221) !=
insertedCerts.end());
BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName222) !=
insertedCerts.end());
insertedCerts.clear();
// Delete the key.
// All the related certificates will be deleted as well.
db.deleteKey(keyName11);
BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName122), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName121), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
BOOST_CHECK_EQUAL(deletedCerts.size(), 2);
BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
deletedCerts.end());
BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
deletedCerts.end());
BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
BOOST_CHECK_EQUAL(deletedKeys[0], keyName11);
deletedCerts.clear();
deletedKeys.clear();
// Recover deleted entries
db.addCertificate(*cert111);
db.addCertificate(*cert112);
// Delete the identity
// All the related certificates and keys will be deleted as well.
BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName112), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
db.deleteIdentity(id1);
BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName122), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName121), false);
BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
BOOST_CHECK_EQUAL(deletedCerts.size(), 4);
BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
deletedCerts.end());
BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
deletedCerts.end());
BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName121) !=
deletedCerts.end());
BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName122) !=
deletedCerts.end());
BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
deletedKeys.end());
BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
deletedCerts.end());
BOOST_CHECK_EQUAL(deletedIds.size(), 1);
BOOST_CHECK_EQUAL(deletedIds[0], id1);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace pib
} // namespace ndn
+137
View File
@@ -0,0 +1,137 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "tools/pib/pib-validator.hpp"
#include "tools/pib/encoding/update-param.hpp"
#include "tools/pib/encoding/delete-param.hpp"
#include <ndn-cxx/security/key-chain.hpp>
#include "identity-management-time-fixture.hpp"
#include <boost/filesystem.hpp>
#include "tests/test-common.hpp"
namespace ndn {
namespace pib {
namespace tests {
class PibValidatorFixture : public ndn::security::IdentityManagementTimeFixture
{
public:
PibValidatorFixture()
: tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
, db(tmpPath.c_str())
{
}
~PibValidatorFixture()
{
boost::filesystem::remove_all(tmpPath);
}
boost::asio::io_service io;
boost::filesystem::path tmpPath;
PibDb db;
bool isProcessed;
};
BOOST_FIXTURE_TEST_SUITE(TestPibValidator, PibValidatorFixture)
BOOST_AUTO_TEST_CASE(Basic)
{
PibValidator validator(db);
Name testUser("/localhost/pib/test/mgmt");
BOOST_REQUIRE(addIdentity(testUser, RsaKeyParams()));
Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
advanceClocks(io, time::milliseconds(100));
Name testUser2("/localhost/pib/test2/mgmt");
BOOST_REQUIRE(addIdentity(testUser2, RsaKeyParams()));
db.updateMgmtCertificate(*testUserCert);
advanceClocks(io, time::milliseconds(100));
Name normalId("/normal/id");
BOOST_REQUIRE(addIdentity(normalId, RsaKeyParams()));
Name normalIdCertName = m_keyChain.getDefaultCertificateNameForIdentity(normalId);
shared_ptr<IdentityCertificate> normalIdCert = m_keyChain.getCertificate(normalIdCertName);
db.addIdentity(normalId);
db.addKey(normalIdCert->getPublicKeyName(), normalIdCert->getPublicKeyInfo());
db.addCertificate(*normalIdCert);
Name command1("/localhost/pib/test/verb/param");
shared_ptr<Interest> interest1 = make_shared<Interest>(command1);
m_keyChain.signByIdentity(*interest1, testUser);
// "test" user is trusted for any command about itself, OK.
isProcessed = false;
validator.validate(*interest1,
[this] (const shared_ptr<const Interest>&) {
isProcessed = true;
BOOST_CHECK(true);
},
[this] (const shared_ptr<const Interest>&, const std::string&) {
isProcessed = true;
BOOST_CHECK(false);
});
BOOST_CHECK(isProcessed);
Name command2("/localhost/pib/test/verb/param");
shared_ptr<Interest> interest2 = make_shared<Interest>(command2);
m_keyChain.signByIdentity(*interest2, testUser2);
// "test2" user is NOT trusted for any command about other user, MUST fail
isProcessed = false;
validator.validate(*interest2,
[this] (const shared_ptr<const Interest>&) {
isProcessed = true;
BOOST_CHECK(false);
},
[this] (const shared_ptr<const Interest>&, const std::string&) {
isProcessed = true;
BOOST_CHECK(true);
});
BOOST_CHECK(isProcessed);
Name command3("/localhost/pib/test/verb/param");
shared_ptr<Interest> interest3 = make_shared<Interest>(command3);
m_keyChain.signByIdentity(*interest3, normalId);
// "normalId" is in "test" pib, can be trusted for some commands about "test".
// Detail checking is needed, but it is not the job of Validator, OK.
isProcessed = false;
validator.validate(*interest3,
[this] (const shared_ptr<const Interest>&) {
isProcessed = true;
BOOST_CHECK(true);
},
[this] (const shared_ptr<const Interest>&, const std::string&) {
isProcessed = true;
BOOST_CHECK(false);
});
BOOST_CHECK(isProcessed);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace pib
} // namespace ndn
+1389
View File
File diff suppressed because it is too large. Load diff
+64
View File
@@ -0,0 +1,64 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "tools/pib/response-cache.hpp"
#include "tests/test-common.hpp"
namespace ndn {
namespace pib {
namespace tests {
BOOST_AUTO_TEST_SUITE(TestResponseCache)
BOOST_AUTO_TEST_CASE(Basic)
{
ResponseCache cache;
Name dataName("/test/data");
dataName.appendVersion();
shared_ptr<Data> data = make_shared<Data>(dataName);
Name dataNameNoVersion("/test/data");
Name anotherDataName("/test/another");
BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataNameNoVersion)), false);
BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataName, true)), false);
cache.insert(*data);
BOOST_CHECK(static_cast<bool>(cache.find(dataNameNoVersion)));
BOOST_CHECK(static_cast<bool>(cache.find(dataName, true)));
BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(anotherDataName)), false);
BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(anotherDataName, true)), false);
cache.erase(dataNameNoVersion);
BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataNameNoVersion)), false);
BOOST_CHECK_EQUAL(static_cast<bool>(cache.find(dataName, true)), false);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace pib
} // namespace ndn
+1
View File
@@ -10,4 +10,5 @@ def build(bld):
source=bld.path.ant_glob(['*.cpp'] + ['%s/**/*.cpp' % tool for tool in bld.env['BUILD_TOOLS']]),
use=['core-objects'] + ['%s-objects' % tool for tool in bld.env['BUILD_TOOLS']],
headers='../common.hpp boost-test.hpp',
defines='TMP_TESTS_PATH=\"%s/tmp-tests\"' % bld.bldnode,
)
+128
View File
@@ -0,0 +1,128 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "cert-publisher.hpp"
namespace ndn {
namespace pib {
CertPublisher::CertPublisher(Face& face, PibDb& db)
: m_face(face)
, m_db(db)
{
startPublishAll();
m_certDeletedConnection =
m_db.certificateDeleted.connect(bind(&CertPublisher::stopPublish, this, _1));
m_certInsertedConnection =
m_db.certificateInserted.connect(bind(&CertPublisher::startPublish, this, _1));
}
CertPublisher::~CertPublisher()
{
for (const auto& it : m_registeredPrefixes)
m_face.unsetInterestFilter(it.second);
}
void
CertPublisher::startPublishAll()
{
// For now we have to register the prefix of certificates separately.
// The reason is that certificates do not share the same prefix that
// can aggregate the certificates publishing without attracting interests
// for non-PIB data.
std::vector<Name> identities = m_db.listIdentities();
for (const auto& identity : identities) {
std::vector<Name> keyNames = m_db.listKeyNamesOfIdentity(identity);
for (const auto& key : keyNames) {
std::vector<Name> certNames = m_db.listCertNamesOfKey(key);
for (const auto& certName : certNames)
startPublish(certName);
}
}
}
void
CertPublisher::registerCertPrefix(const Name& certName)
{
BOOST_ASSERT(!certName.empty());
const Name& prefix = certName.getPrefix(-1);
if (m_registeredPrefixes.find(prefix) == m_registeredPrefixes.end()) {
m_registeredPrefixes[prefix] =
m_face.setInterestFilter(certName.getPrefix(-1),
bind(&CertPublisher::processInterest, this, _1, _2),
[] (const Name& name) {},
[=] (const Name& name, const std::string& msg) {
if (m_registeredPrefixes.erase(prefix) == 0) {
// registration no longer needed - certificates deleted
return;
}
// retry
registerCertPrefix(certName);
});
}
}
void
CertPublisher::processInterest(const InterestFilter& interestFilter,
const Interest& interest)
{
shared_ptr<const Data> certificate = m_responseCache.find(interest);
if (certificate != nullptr) {
m_face.put(*certificate);
}
}
void
CertPublisher::startPublish(const Name& certName)
{
m_responseCache.insert(*m_db.getCertificate(certName));
registerCertPrefix(certName);
}
void
CertPublisher::stopPublish(const Name& certName)
{
BOOST_ASSERT(!certName.empty());
m_responseCache.erase(certName);
// clear the listener if this is the only cert using the prefix
const Name& prefix = certName.getPrefix(-1); // strip version component
if (m_responseCache.find(prefix) != nullptr)
return;
auto it = m_registeredPrefixes.find(prefix);
BOOST_ASSERT(it != m_registeredPrefixes.end());
m_face.unsetInterestFilter(it->second);
m_registeredPrefixes.erase(it);
}
} // namespace pib
} // namespace ndn
+99
View File
@@ -0,0 +1,99 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_CERT_PUBLISHER_HPP
#define NDN_PIB_CERT_PUBLISHER_HPP
#include "pib-db.hpp"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
namespace ndn {
namespace pib {
/// @brief implements the certificate publisher
class CertPublisher : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param face The face pib used to receive queries and serve certificates.
* @param pibDb Database which holds the certificates.
*/
CertPublisher(Face& face, PibDb& pibDb);
~CertPublisher();
private:
void
startPublishAll();
/**
* @brief add an interest filter for the certificate
*/
void
registerCertPrefix(const Name& certName);
void
processInterest(const InterestFilter& interestFilter,
const Interest& interest);
void
startPublish(const Name& certName);
/**
* @brief callback when a certificate is deleted
*
* The method will remove the cert from in-memory storage
* and also unset interest filter if the removed cert
* is the only one with the registered prefix.
*
* @param certName removed certificate name
*/
void
stopPublish(const Name& certName);
private:
Face& m_face;
PibDb& m_db;
util::InMemoryStoragePersistent m_responseCache;
std::map<Name, const RegisteredPrefixId*> m_registeredPrefixes;
util::signal::ScopedConnection m_certDeletedConnection;
util::signal::ScopedConnection m_certInsertedConnection;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_CERT_PUBLISHER_HPP
+199
View File
@@ -0,0 +1,199 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "default-query-processor.hpp"
#include "encoding/pib-encoding.hpp"
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
using std::string;
const size_t DefaultQueryProcessor::DEFAULT_QUERY_LENGTH = 5;
DefaultQueryProcessor::DefaultQueryProcessor(PibDb& db)
: m_db(db)
{
}
std::pair<bool, Block>
DefaultQueryProcessor::operator()(const Interest& interest)
{
const Name& interestName = interest.getName();
// handle pib query: /localhost/pib/[UserName]/default/param
if (interestName.size() != DEFAULT_QUERY_LENGTH) {
// malformed interest, discard
return std::make_pair(false, Block());
}
DefaultParam param;
try {
param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
}
catch (const tlv::Error& e) {
PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
return std::make_pair(true, error.wireEncode());
}
switch (param.getTargetType()) {
case TYPE_ID:
return processDefaultIdQuery(param);
case TYPE_KEY:
return processDefaultKeyQuery(param);
case TYPE_CERT:
return processDefaultCertQuery(param);
default:
{
PibError error(ERR_WRONG_PARAM,
"target type is not supported: " +
boost::lexical_cast<string>(param.getTargetType()));
return std::make_pair(true, error.wireEncode());
}
}
}
std::pair<bool, Block>
DefaultQueryProcessor::processDefaultIdQuery(const DefaultParam& param)
{
if (param.getOriginType() == TYPE_USER) {
try {
PibIdentity result(m_db.getDefaultIdentity());
return std::make_pair(true, result.wireEncode());
}
catch (PibDb::Error&) {
PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
return std::make_pair(true, error.wireEncode());
}
}
else {
PibError error(ERR_WRONG_PARAM,
"origin type of id target must be USER(0), but gets: " +
boost::lexical_cast<string>(param.getOriginType()));
return std::make_pair(true, error.wireEncode());
}
}
std::pair<bool, Block>
DefaultQueryProcessor::processDefaultKeyQuery(const DefaultParam& param)
{
Name identity;
if (param.getOriginType() == TYPE_ID)
identity = param.getOriginName();
else if (param.getOriginType() == TYPE_USER) {
try {
identity = m_db.getDefaultIdentity();
}
catch (PibDb::Error&) {
PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
return std::make_pair(true, error.wireEncode());
}
}
else {
PibError error(ERR_WRONG_PARAM,
"origin type of key target must be ID(1) or USER(0), but gets: " +
boost::lexical_cast<string>(param.getOriginType()));
return std::make_pair(true, error.wireEncode());
}
try {
Name keyName = m_db.getDefaultKeyNameOfIdentity(identity);
shared_ptr<PublicKey> key = m_db.getKey(keyName);
if (key == nullptr) {
PibError error(ERR_NO_DEFAULT_KEY, "default key does not exist");
return std::make_pair(true, error.wireEncode());
}
PibPublicKey result(keyName, *key);
return std::make_pair(true, result.wireEncode());
}
catch (PibDb::Error& e) {
PibError error(ERR_NO_DEFAULT_KEY,
"default key does not exist: " + string(e.what()));
return std::make_pair(true, error.wireEncode());
}
}
std::pair<bool, Block>
DefaultQueryProcessor::processDefaultCertQuery(const DefaultParam& param)
{
Name identity;
if (param.getOriginType() == TYPE_USER) {
try {
identity = m_db.getDefaultIdentity();
}
catch (PibDb::Error&) {
PibError error(ERR_NO_DEFAULT_ID, "default identity does not exist");
return std::make_pair(true, error.wireEncode());
}
}
else if (param.getOriginType() == TYPE_ID)
identity = param.getOriginName();
else if (param.getOriginType() != TYPE_KEY) {
PibError error(ERR_WRONG_PARAM,
"origin type of cert target must be KEY(2), ID(1) or USER(0), but gets: " +
boost::lexical_cast<string>(param.getOriginType()));
return std::make_pair(true, error.wireEncode());
}
Name keyName;
if (param.getOriginType() == TYPE_KEY) {
keyName = param.getOriginName();
if (keyName.size() < 1) {
PibError error(ERR_WRONG_PARAM,
"key name must contain key id component");
return std::make_pair(true, error.wireEncode());
}
}
else {
try {
keyName = m_db.getDefaultKeyNameOfIdentity(identity);
}
catch (PibDb::Error&) {
PibError error(ERR_NO_DEFAULT_KEY, "default key does not exist");
return std::make_pair(true, error.wireEncode());
}
}
try {
Name certName = m_db.getDefaultCertNameOfKey(keyName);
shared_ptr<IdentityCertificate> certificate = m_db.getCertificate(certName);
if (certificate == nullptr) {
PibError error (ERR_NO_DEFAULT_CERT, "default cert does not exist");
return std::make_pair(true, error.wireEncode());
}
PibCertificate result(*certificate);
return std::make_pair(true, result.wireEncode());
}
catch (PibDb::Error&) {
PibError error(ERR_NO_DEFAULT_CERT, "default cert does not exist");
return std::make_pair(true, error.wireEncode());
}
}
} // namespace pib
} // namespace ndn
+76
View File
@@ -0,0 +1,76 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_DEFAULT_QUERY_PROCESSOR_HPP
#define NDN_PIB_DEFAULT_QUERY_PROCESSOR_HPP
#include "pib-db.hpp"
#include "encoding/default-param.hpp"
#include <ndn-cxx/interest.hpp>
#include <utility>
namespace ndn {
namespace pib {
class DefaultQueryProcessor : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param db The pib database.
*/
explicit
DefaultQueryProcessor(PibDb& db);
std::pair<bool, Block>
operator()(const Interest& interest);
private:
std::pair<bool, Block>
processDefaultIdQuery(const DefaultParam& param);
std::pair<bool, Block>
processDefaultKeyQuery(const DefaultParam& param);
std::pair<bool, Block>
processDefaultCertQuery(const DefaultParam& param);
private:
static const size_t DEFAULT_QUERY_LENGTH;
const PibDb& m_db;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_DEFAULT_QUERY_PROCESSOR_HPP
+205
View File
@@ -0,0 +1,205 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "delete-query-processor.hpp"
#include "encoding/pib-encoding.hpp"
#include "pib.hpp"
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
using std::string;
const size_t DeleteQueryProcessor::DELETE_QUERY_LENGTH = 9;
const Name DeleteQueryProcessor::PIB_PREFIX("/localhost/pib");
DeleteQueryProcessor::DeleteQueryProcessor(PibDb& db)
: m_db(db)
{
}
std::pair<bool, Block>
DeleteQueryProcessor::operator()(const Interest& interest)
{
const Name& interestName = interest.getName();
// handle pib query: /localhost/pib/[UserName]/delete/param/<signed_interest_related_components>
if (interestName.size() != DELETE_QUERY_LENGTH) {
// malformed interest, discard
return std::make_pair(false, Block());
}
try {
DeleteParam param;
param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
SignatureInfo sigInfo;
sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
// sigInfo must have KeyLocator.Name if the interest passed validation.
Name signerName;
signerName = sigInfo.getKeyLocator().getName();
switch (param.getTargetType()) {
case TYPE_USER:
return std::make_pair(true, PibError(ERR_WRONG_PARAM, "not allowed to delete user").wireEncode());
case TYPE_ID:
return processDeleteIdQuery(param, signerName);
case TYPE_KEY:
return processDeleteKeyQuery(param, signerName);
case TYPE_CERT:
return processDeleteCertQuery(param, signerName);
default:
{
PibError error(ERR_WRONG_PARAM,
"target type is not supported: " +
boost::lexical_cast<string>(param.getTargetType()));
return std::make_pair(true, error.wireEncode());
}
}
}
catch (const PibDb::Error& e) {
PibError error(ERR_INTERNAL_ERROR, e.what());
return std::make_pair(true, error.wireEncode());
}
catch (const tlv::Error& e) {
PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
return std::make_pair(true, error.wireEncode());
}
}
std::pair<bool, Block>
DeleteQueryProcessor::processDeleteIdQuery(const DeleteParam& param, const Name& signerName)
{
Name identity = param.getTargetName();
if (!isDeleteAllowed(TYPE_ID, identity, signerName)) {
PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
return std::make_pair(true, error.wireEncode());
}
m_db.deleteIdentity(identity);
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
std::pair<bool, Block>
DeleteQueryProcessor::processDeleteKeyQuery(const DeleteParam& param, const Name& signerName)
{
const Name& keyName = param.getTargetName();
if (!isDeleteAllowed(TYPE_KEY, keyName, signerName)) {
PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
return std::make_pair(true, error.wireEncode());
}
m_db.deleteKey(keyName);
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
std::pair<bool, Block>
DeleteQueryProcessor::processDeleteCertQuery(const DeleteParam& param, const Name& signerName)
{
const Name& certName = param.getTargetName();
if (!isDeleteAllowed(TYPE_CERT, certName, signerName)) {
PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
return std::make_pair(true, error.wireEncode());
}
m_db.deleteCertificate(certName);
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
bool
DeleteQueryProcessor::isDeleteAllowed(const pib::Type targetType,
const Name& targetName,
const Name& signer) const
{
// sanity checking, user cannot be deleted.
if (targetType == TYPE_USER)
return false;
// Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
// that prefix will be rejected.
if (PIB_PREFIX.isPrefixOf(targetName))
return false;
// Rules for other items:
//
// signer | deleting privilege
// =========================+===============================================
// local mgmt key | any id, key, and cert
// -------------------------+-----------------------------------------------
// default key of an id | any id, key, and cert under the id's namespace
// -------------------------+-----------------------------------------------
// non-default key of an id | any cert of the key
const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
const Name& signerId = signerKeyName.getPrefix(-1);
bool hasSignerDefaultKey = true;
Name signerDefaultKeyName;
try {
signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
}
catch (PibDb::Error&) {
hasSignerDefaultKey = false;
}
Name mgmtCertName;
try {
mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
}
catch (PibDb::Error&) {
return false;
}
if (signer == mgmtCertName) {
// signer is current management key, anything is allowed.
return true;
}
else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
// signer is an identity's default key
if (!signerId.isPrefixOf(targetName))
return false;
else
return true;
}
else {
// non-default key
if (targetType == TYPE_CERT) {
// check if it is for the key's cert
if (IdentityCertificate::certificateNameToPublicKeyName(targetName) == signerKeyName)
return true;
}
else if (targetType == TYPE_KEY) {
// check if it is for the key itself
if (targetName == signerKeyName)
return true;
}
return false;
}
}
} // namespace pib
} // namespace ndn
+93
View File
@@ -0,0 +1,93 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_DELETE_QUERY_PROCESSOR_HPP
#define NDN_PIB_DELETE_QUERY_PROCESSOR_HPP
#include "pib-db.hpp"
#include "encoding/delete-param.hpp"
#include <ndn-cxx/interest.hpp>
#include <utility>
namespace ndn {
namespace pib {
class Pib;
/// @brief Processing unit for PIB delete query
class DeleteQueryProcessor : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param db The pib database.
*/
explicit
DeleteQueryProcessor(PibDb& db);
std::pair<bool, Block>
operator()(const Interest& interest);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/**
* @brief Determine if a delete command is allowed.
*
* @param targetType The type of the target that will be deleted.
* @param targetName The name of the target that will be deleted.
* @param signer The name of the command signer.
*/
bool
isDeleteAllowed(const pib::Type targetType,
const Name& targetName,
const Name& signer) const;
private:
std::pair<bool, Block>
processDeleteIdQuery(const DeleteParam& param, const Name& signerName);
std::pair<bool, Block>
processDeleteKeyQuery(const DeleteParam& param, const Name& signerName);
std::pair<bool, Block>
processDeleteCertQuery(const DeleteParam& param, const Name& signerName);
private:
static const size_t DELETE_QUERY_LENGTH;
static const Name PIB_PREFIX;
PibDb& m_db;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_DELETE_QUERY_PROCESSOR_HPP
+168
View File
@@ -0,0 +1,168 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "default-param.hpp"
#include <ndn-cxx/encoding/block-helpers.hpp>
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
static_assert(std::is_base_of<tlv::Error, DefaultParam::Error>::value,
"DefaultParam::Error must inherit from tlv::Error");
const std::string DefaultParam::VERB("default");
DefaultParam::DefaultParam()
: m_targetType(TYPE_DEFAULT)
, m_originType(TYPE_DEFAULT)
{
}
DefaultParam::DefaultParam(const pib::Type targetType,
const pib::Type originType,
const Name& originName)
: m_targetType(targetType)
, m_originType(originType)
, m_originName(originName)
{
}
DefaultParam::DefaultParam(const Block& wire)
{
wireDecode(wire);
}
const Name&
DefaultParam::getOriginName() const
{
if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
return m_originName;
else
throw Error("DefaultParam::getOriginName: origin name does not exist");
}
template<bool T>
size_t
DefaultParam::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
switch (m_originType) {
case TYPE_ID:
case TYPE_KEY:
case TYPE_CERT:
{
totalLength += m_originName.wireEncode(block);
break;
}
case TYPE_USER:
break;
default:
throw Error("DefaultParam::wireEncode: unsupported PibType: " +
boost::lexical_cast<std::string>(m_originType));
}
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::DefaultParam);
return totalLength;
}
template size_t
DefaultParam::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
DefaultParam::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
DefaultParam::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
DefaultParam::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw Error("The supplied block does not contain wire format");
}
m_wire = wire;
m_wire.parse();
if (m_wire.type() != tlv::pib::DefaultParam)
throw Error("Unexpected TLV type when decoding DefaultParam");
Block::element_const_iterator it = m_wire.elements_begin();
// the first block must be PibType
if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
it++;
}
else
throw Error("DefaultParam requires the first sub-TLV to be PibType");
// the second block must be PibType
if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
it++;
}
else
throw Error("DefaultParam requires the second sub-TLV to be PibType");
switch (m_originType) {
case TYPE_ID:
case TYPE_KEY:
case TYPE_CERT:
{
if (it != m_wire.elements_end()) {
// the third block, if exists, must be Name
m_originName.wireDecode(*it);
return;
}
else {
throw Error("DefaultParam requires the third sub-TLV to be Name");
}
}
case TYPE_USER:
return;
default:
throw Error("DefaultParam::wireDecode: unsupported PibType: " +
boost::lexical_cast<std::string>(m_originType));
}
}
} // namespace pib
} // namespace ndn
+128
View File
@@ -0,0 +1,128 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_DEFAULT_PARAM_HPP
#define NDN_PIB_DEFAULT_PARAM_HPP
#include "pib-common.hpp"
#include <ndn-cxx/name.hpp>
namespace ndn {
namespace pib {
/**
* @brief DefaultParam is the abstraction of PIB Default parameter.
*
* PibDefaultParam := PIB-DEFAULT-PARAM-TYPE TLV-LENGTH
* PibType // target type
* PibType // origin type
* Name? // origin name
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Default-Parameters
*/
class DefaultParam : noncopyable
{
public:
class Error : public tlv::Error
{
public:
explicit
Error(const std::string& what)
: tlv::Error(what)
{
}
};
DefaultParam();
DefaultParam(const pib::Type targetType,
const pib::Type originType,
const Name& originName = Name());
explicit
DefaultParam(const Block& wire);
tlv::pib::ParamType
getParamType() const
{
return tlv::pib::DefaultParam;
}
pib::Type
getTargetType() const
{
return m_targetType;
}
pib::Type
getOriginType() const
{
return m_originType;
}
/**
* @brief Get target name
*
* @throws Error if origin name does not exist
*/
const Name&
getOriginName() const;
/// @brief Encode to a wire format or estimate wire format
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
/**
* @brief Encode to a wire format
*
* @throws Error if encoding fails
*/
const Block&
wireEncode() const;
/**
* @brief Decode GetParam from a wire encoded block
*
* @throws Error if decoding fails
*/
void
wireDecode(const Block& wire);
public:
static const std::string VERB;
private:
pib::Type m_targetType;
pib::Type m_originType;
Name m_originName;
mutable Block m_wire;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_DEFAULT_PARAM_HPP
+129
View File
@@ -0,0 +1,129 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "delete-param.hpp"
#include <ndn-cxx/encoding/block-helpers.hpp>
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
static_assert(std::is_base_of<tlv::Error, DeleteParam::Error>::value,
"DeleteParam::Error must inherit from tlv::Error");
const std::string DeleteParam::VERB("delete");
DeleteParam::DeleteParam()
: m_targetType(TYPE_DEFAULT)
{
}
DeleteParam::DeleteParam(const Name& name, pib::Type type)
: m_targetType(type)
, m_targetName(name)
{
}
DeleteParam::DeleteParam(const Block& wire)
{
wireDecode(wire);
}
template<bool T>
size_t
DeleteParam::wireEncode(EncodingImpl<T>& block) const
{
if (m_targetType != TYPE_ID &&
m_targetType != TYPE_KEY &&
m_targetType != TYPE_CERT &&
m_targetType != TYPE_USER)
throw Error("DeleteParam::wireEncode: Wrong Type value: " +
boost::lexical_cast<std::string>(m_targetType));
size_t totalLength = 0;
totalLength += m_targetName.wireEncode(block);
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::DeleteParam);
return totalLength;
}
template size_t
DeleteParam::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
DeleteParam::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
DeleteParam::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
DeleteParam::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw Error("The supplied block does not contain wire format");
}
m_wire = wire;
m_wire.parse();
if (m_wire.type() != tlv::pib::DeleteParam)
throw Error("Unexpected TLV type when decoding DeleteParam");
Block::element_const_iterator it = m_wire.elements_begin();
// the first block must be Type
if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
it++;
}
else
throw Error("DeleteParam requires the first sub-TLV to be Type");
// the second block must be Name
if (it != m_wire.elements_end() && it->type() == tlv::Name) {
m_targetName.wireDecode(*it);
it++;
}
else
throw Error("DeleteParam requires the second sub-TLV to be Name");
if (it != m_wire.elements_end())
throw Error("DeleteParam must not contain more than two sub-TLVs");
}
} // namespace pib
} // namespace ndn
+114
View File
@@ -0,0 +1,114 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_DELETE_PARAM_HPP
#define NDN_PIB_DELETE_PARAM_HPP
#include "pib-common.hpp"
#include <ndn-cxx/name.hpp>
namespace ndn {
namespace pib {
/**
* @brief DeleteParam is the abstraction of PIB Delete parameter.
*
* PibDeleteParam := PIB-DELETE-PARAM-TYPE TLV-LENGTH
* PibType
* Name
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Delete-Parameters
*/
class DeleteParam : noncopyable
{
public:
class Error : public tlv::Error
{
public:
explicit
Error(const std::string& what)
: tlv::Error(what)
{
}
};
DeleteParam();
explicit
DeleteParam(const Name& name, const pib::Type type = TYPE_ID);
explicit
DeleteParam(const Block& wire);
tlv::pib::ParamType
getParamType() const
{
return tlv::pib::DeleteParam;
}
pib::Type
getTargetType() const
{
return m_targetType;
}
const Name&
getTargetName() const
{
return m_targetName;
}
/// @brief Encode to a wire format or estimate wire format
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
/**
* @brief Encode to a wire format
*
* @throws Error if encoding fails
*/
const Block&
wireEncode() const;
/**
* @brief Decode GetParam from a wire encoded block
*
* @throws Error if decoding fails
*/
void
wireDecode(const Block& wire);
public:
static const std::string VERB;
private:
pib::Type m_targetType;
Name m_targetName;
mutable Block m_wire;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_DELETE_PARAM_HPP
+156
View File
@@ -0,0 +1,156 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "get-param.hpp"
#include <boost/lexical_cast.hpp>
#include <ndn-cxx/encoding/block-helpers.hpp>
namespace ndn {
namespace pib {
static_assert(std::is_base_of<tlv::Error, GetParam::Error>::value,
"GetParam::Error must inherit from tlv::Error");
const std::string GetParam::VERB("get");
GetParam::GetParam()
: m_targetType(TYPE_USER)
{
}
GetParam::GetParam(const pib::Type targetType, const Name& targetName)
: m_targetType(targetType)
, m_targetName(targetName)
{
}
GetParam::GetParam(const Block& wire)
{
wireDecode(wire);
}
const Name&
GetParam::getTargetName() const
{
if (m_targetType == TYPE_ID || m_targetType == TYPE_KEY || m_targetType == TYPE_CERT)
return m_targetName;
else
throw Error("GetParam::getTargetName: target name does not exist");
}
template<bool T>
size_t
GetParam::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
switch (m_targetType) {
case TYPE_ID:
case TYPE_KEY:
case TYPE_CERT:
{
totalLength += m_targetName.wireEncode(block);
break;
}
case TYPE_USER:
break;
default:
throw Error("GetParam::wireEncode: unsupported PibType: " +
boost::lexical_cast<std::string>(m_targetType));
}
// Encode Type
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_targetType);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::GetParam);
return totalLength;
}
template size_t
GetParam::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
GetParam::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
GetParam::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
GetParam::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw Error("The supplied block does not contain wire format");
}
m_wire = wire;
m_wire.parse();
if (m_wire.type() != tlv::pib::GetParam)
throw Error("Unexpected TLV type when decoding GetParam");
Block::element_const_iterator it = m_wire.elements_begin();
// the first block must be Type
if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
m_targetType = static_cast<pib::Type>(readNonNegativeInteger(*it));
it++;
}
else
throw Error("GetParam requires the first sub-TLV to be PibType");
switch (m_targetType) {
case TYPE_ID:
case TYPE_KEY:
case TYPE_CERT:
{
if (it != m_wire.elements_end()) {
// the second block, if exists, must be Name
m_targetName.wireDecode(*it);
return;
}
else {
throw Error("GetParam requires the second sub-TLV to be Name");
}
}
case TYPE_USER:
return;
default:
throw Error("GetParam::wireDecode: unsupported PibType: " +
boost::lexical_cast<std::string>(m_targetType));
}
}
} // namespace pib
} // namespace ndn
+115
View File
@@ -0,0 +1,115 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_GET_PARAM_HPP
#define NDN_PIB_GET_PARAM_HPP
#include "pib-common.hpp"
#include <ndn-cxx/name.hpp>
namespace ndn {
namespace pib {
/**
* @brief GetParam is the abstraction of PIB Get parameter.
*
* PibGetParam := PIB-GET-PARAM-TYPE TLV-LENGTH
* PibType
* Name?
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Get-Parameters
*/
class GetParam : noncopyable
{
public:
class Error : public tlv::Error
{
public:
explicit
Error(const std::string& what)
: tlv::Error(what)
{
}
};
GetParam();
GetParam(const pib::Type targetType, const Name& targetName);
explicit
GetParam(const Block& wire);
tlv::pib::ParamType
getParamType() const
{
return tlv::pib::GetParam;
}
pib::Type
getTargetType() const
{
return m_targetType;
}
/**
* @brief Get target name
*
* @throws Error if target name does not exist
*/
const Name&
getTargetName() const;
/// @brief Encode to a wire format or estimate wire format
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
/**
* @brief Encode to a wire format
*
* @throws Error if encoding fails
*/
const Block&
wireEncode() const;
/**
* @brief Decode GetParam from a wire encoded block
*
* @throws Error if decoding fails
*/
void
wireDecode(const Block& wire);
public:
static const std::string VERB;
private:
pib::Type m_targetType;
Name m_targetName;
mutable Block m_wire;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_GET_PARAM_HPP
+155
View File
@@ -0,0 +1,155 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "list-param.hpp"
#include <ndn-cxx/encoding/block-helpers.hpp>
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
static_assert(std::is_base_of<tlv::Error, ListParam::Error>::value,
"ListParam::Error must inherit from tlv::Error");
const std::string ListParam::VERB("list");
ListParam::ListParam()
: m_originType(TYPE_USER)
{
}
ListParam::ListParam(const pib::Type originType, const Name& originName)
: m_originType(originType)
, m_originName(originName)
{
}
ListParam::ListParam(const Block& wire)
{
wireDecode(wire);
}
const Name&
ListParam::getOriginName() const
{
if (m_originType == TYPE_ID || m_originType == TYPE_KEY || m_originType == TYPE_CERT)
return m_originName;
else
throw Error("ListParam::getOriginName: origin name does not exist");
}
template<bool T>
size_t
ListParam::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
switch (m_originType) {
case TYPE_ID:
case TYPE_KEY:
case TYPE_CERT:
{
totalLength += m_originName.wireEncode(block);
break;
}
case TYPE_USER:
break;
default:
throw Error("ListParam::wireEncode: unsupported PibType: " +
boost::lexical_cast<std::string>(m_originType));
}
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::Type, m_originType);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::ListParam);
return totalLength;
}
template size_t
ListParam::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
ListParam::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
ListParam::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
ListParam::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw Error("The supplied block does not contain wire format");
}
m_wire = wire;
m_wire.parse();
if (m_wire.type() != tlv::pib::ListParam)
throw Error("Unexpected TLV type when decoding ListParam");
Block::element_const_iterator it = m_wire.elements_begin();
// the first block must be PibType
if (it != m_wire.elements_end() && it->type() == tlv::pib::Type) {
m_originType = static_cast<pib::Type>(readNonNegativeInteger(*it));
it++;
}
else
throw Error("ListParam requires the first sub-TLV to be PibType");
switch (m_originType) {
case TYPE_ID:
case TYPE_KEY:
case TYPE_CERT:
{
if (it != m_wire.elements_end()) {
// the second block, if exists, must be Name
m_originName.wireDecode(*it);
return;
}
else {
throw Error("ListParam requires the second sub-TLV to be Name");
}
}
case TYPE_USER:
return;
default:
throw Error("ListParam::wireDecode: unsupported PibType: " +
boost::lexical_cast<std::string>(m_originType));
}
}
} // namespace pib
} // namespace ndn
+118
View File
@@ -0,0 +1,118 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_LIST_PARAM_HPP
#define NDN_PIB_LIST_PARAM_HPP
#include "pib-common.hpp"
#include <ndn-cxx/name.hpp>
namespace ndn {
namespace pib {
/**
* @brief ListParam is the abstraction of PIB List parameter.
*
* PibListParam := PIB-LIST-PARAM-TYPE TLV-LENGTH
* PibType // origin type
* Name? // origin name
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
*/
class ListParam : noncopyable
{
public:
class Error : public tlv::Error
{
public:
explicit
Error(const std::string& what)
: tlv::Error(what)
{
}
};
ListParam();
ListParam(const pib::Type originType, const Name& originName);
explicit
ListParam(const Block& wire);
tlv::pib::ParamType
getParamType() const
{
return tlv::pib::ListParam;
}
pib::Type
getOriginType() const
{
return m_originType;
}
/**
* @brief Get target name
*
* @throws Error if origin name does not exist
*/
const Name&
getOriginName() const;
/// @brief Encode to a wire format or estimate wire format
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
/**
* @brief Encode to a wire format
*
* @throws Error if encoding fails
*/
const Block&
wireEncode() const;
/**
* @brief Decode GetParam from a wire encoded block
*
* @throws Error if decoding fails
*/
void
wireDecode(const Block& wire);
public:
static const std::string VERB;
private:
pib::Type m_originType;
Name m_originName;
mutable Block m_wire;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_LIST_PARAM_HPP
+128
View File
@@ -0,0 +1,128 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_PIB_COMMON_HPP
#define NDN_PIB_PIB_COMMON_HPP
namespace ndn {
namespace pib {
/// @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
enum {
OFFSET_USER = 2,
OFFSET_VERB = 3,
OFFSET_PARAM = 4,
OFFSET_TIMESTAMP = 5,
OFFSET_NONCE = 6,
OFFSET_SIG_INFO = 7,
OFFSET_SIG_VALUE = 8,
MIN_PIB_INTEREST_SIZE = 5,
SIGNED_PIB_INTEREST_SIZE = 9
};
enum Type {
TYPE_USER = 0,
TYPE_ID = 1,
TYPE_KEY = 2,
TYPE_CERT = 3,
TYPE_DEFAULT = 255
};
enum DefaultOpt {
DEFAULT_OPT_NO = 0,
DEFAULT_OPT_KEY = 1, // 0x01
DEFAULT_OPT_ID = 3, // 0x03
DEFAULT_OPT_USER = 7 // 0x07
};
enum DefaultOptMask {
DEFAULT_OPT_KEY_MASK = 0x1,
DEFAULT_OPT_ID_MASK = 0x2,
DEFAULT_OPT_USER_MASK = 0x4
};
enum ErrCode {
ERR_SUCCESS = 0,
// Invalid query
ERR_INCOMPLETE_COMMAND = 1,
ERR_WRONG_VERB = 2,
ERR_WRONG_PARAM = 3,
ERR_WRONG_SIGNER = 4,
ERR_INTERNAL_ERROR = 5,
// Non existing entity
ERR_NON_EXISTING_USER = 128,
ERR_NON_EXISTING_ID = 129,
ERR_NON_EXISTING_KEY = 130,
ERR_NON_EXISTING_CERT = 131,
// No default setting
ERR_NO_DEFAULT_ID = 256,
ERR_NO_DEFAULT_KEY = 257,
ERR_NO_DEFAULT_CERT = 258,
// Delete default setting
ERR_DELETE_DEFAULT_SETTING = 384
};
} // namespace pib
namespace tlv {
namespace pib {
enum ParamType {
GetParam = 128, // 0x80
DefaultParam = 129, // 0x81
ListParam = 130, // 0x82
UpdateParam = 131, // 0x83
DeleteParam = 132 // 0x84
};
enum EntityType {
User = 144, // 0x90
Identity = 145, // 0x91
PublicKey = 146, // 0x92
Certificate = 147 // 0x93
};
// Other
enum {
Bytes = 148, // 0x94
DefaultOpt = 149, // 0x95
NameList = 150, // 0x96
Type = 151, // 0x97
Error = 152, // 0x98
TpmLocator = 153, // 0x99
// ErrorCode
ErrorCode = 252 // 0xfc
};
} // namespace pib
} // namespace tlv
} // namespace ndn
#endif // NDN_PIB_PIB_COMMON_HPP
+525
View File
@@ -0,0 +1,525 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "pib-encoding.hpp"
#include <ndn-cxx/encoding/block-helpers.hpp>
#include <ndn-cxx/encoding/encoding-buffer.hpp>
#include <vector>
#include <string>
namespace ndn {
namespace pib {
using std::vector;
using std::string;
PibIdentity::PibIdentity()
{
}
PibIdentity::PibIdentity(const Name& identity)
: m_identity(identity)
{
}
PibIdentity::PibIdentity(const Block& wire)
{
wireDecode(wire);
}
template<bool T>
size_t
PibIdentity::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = m_identity.wireEncode(block);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::Identity);
return totalLength;
}
template size_t
PibIdentity::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
PibIdentity::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
PibIdentity::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
PibIdentity::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw tlv::Error("The supplied block does not contain wire format");
}
if (wire.type() != tlv::pib::Identity)
throw tlv::Error("Unexpected TLV type when decoding PibIdentity");
m_wire = wire;
m_identity.wireDecode(m_wire.blockFromValue());
}
PibPublicKey::PibPublicKey()
: m_isValueSet(false)
{
}
PibPublicKey::PibPublicKey(const Name& keyName, const PublicKey& key)
: m_isValueSet(true)
, m_keyName(keyName)
, m_key(key)
{
}
PibPublicKey::PibPublicKey(const Block& wire)
{
wireDecode(wire);
}
const Name&
PibPublicKey::getKeyName() const
{
if (m_isValueSet)
return m_keyName;
else
throw tlv::Error("PibPublicKey::getKeyName: keyName is not set");
}
const PublicKey&
PibPublicKey::getPublicKey() const
{
if (m_isValueSet)
return m_key;
else
throw tlv::Error("PibPublicKey::getPublicKey: key is not set");
}
template<bool T>
size_t
PibPublicKey::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = prependByteArrayBlock(block, tlv::pib::Bytes,
m_key.get().buf(), m_key.get().size());
totalLength += m_keyName.wireEncode(block);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::PublicKey);
return totalLength;
}
template size_t
PibPublicKey::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
PibPublicKey::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
PibPublicKey::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
PibPublicKey::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw tlv::Error("The supplied block does not contain wire format");
}
if (wire.type() != tlv::pib::PublicKey)
throw tlv::Error("Unexpected TLV type when decoding PibPublicKey");
m_wire = wire;
m_wire.parse();
Block::element_const_iterator it = m_wire.elements_begin();
if (it != m_wire.elements_end() && it->type() == tlv::Name) {
m_keyName.wireDecode(*it);
it++;
}
else
throw tlv::Error("PibPublicKey requires the first sub-TLV to be Name");
if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
m_key = PublicKey(it->value(), it->value_size());
it++;
}
else
throw tlv::Error("PibPublicKey requires the second sub-TLV to be Bytes");
m_isValueSet = true;
if (it != m_wire.elements_end())
throw tlv::Error("PibPublicKey must contain only two sub-TLVs");
}
PibCertificate::PibCertificate()
: m_isValueSet(false)
{
}
PibCertificate::PibCertificate(const IdentityCertificate& certificate)
: m_isValueSet(true)
, m_certificate(certificate)
{
}
PibCertificate::PibCertificate(const Block& wire)
{
wireDecode(wire);
}
const IdentityCertificate&
PibCertificate::getCertificate() const
{
if (m_isValueSet)
return m_certificate;
else
throw tlv::Error("PibCertificate::getCertificate: certificate is not set");
}
template<bool T>
size_t
PibCertificate::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = prependBlock(block, m_certificate.wireEncode());
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::Certificate);
return totalLength;
}
template size_t
PibCertificate::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
PibCertificate::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
PibCertificate::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
PibCertificate::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw tlv::Error("The supplied block does not contain wire format");
}
if (wire.type() != tlv::pib::Certificate)
throw tlv::Error("Unexpected TLV type when decoding PibCertificate");
m_wire = wire;
m_certificate.wireDecode(m_wire.blockFromValue());
m_isValueSet = true;
}
PibNameList::PibNameList()
{
}
PibNameList::PibNameList(const std::vector<Name>& names)
: m_names(names)
{
}
PibNameList::PibNameList(const Block& wire)
{
wireDecode(wire);
}
template<bool T>
size_t
PibNameList::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
for (vector<Name>::const_reverse_iterator it = m_names.rbegin();
it != m_names.rend(); it++) {
totalLength += it->wireEncode(block);
}
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::NameList);
return totalLength;
}
template size_t
PibNameList::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
PibNameList::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
PibNameList::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
PibNameList::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw tlv::Error("The supplied block does not contain wire format");
}
if (wire.type() != tlv::pib::NameList)
throw tlv::Error("Unexpected TLV type when decoding PibNameList");
m_wire = wire;
m_wire.parse();
for (Block::element_const_iterator it = m_wire.elements_begin();
it != m_wire.elements_end(); it++) {
if (it->type() == tlv::Name) {
Name name;
name.wireDecode(*it);
m_names.push_back(name);
}
}
}
PibError::PibError()
: m_errCode(ERR_SUCCESS)
{
}
PibError::PibError(const pib::ErrCode errCode, const std::string& msg)
: m_errCode(errCode)
, m_msg(msg)
{
}
PibError::PibError(const Block& wire)
{
wireDecode(wire);
}
template<bool T>
size_t
PibError::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
totalLength += prependByteArrayBlock(block, tlv::pib::Bytes,
reinterpret_cast<const uint8_t*>(m_msg.c_str()),
m_msg.size());
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::ErrorCode, m_errCode);
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::Error);
return totalLength;
}
template size_t
PibError::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
PibError::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
PibError::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
PibError::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw tlv::Error("The supplied block does not contain wire format");
}
if (wire.type() != tlv::pib::Error)
throw tlv::Error("Unexpected TLV type when decoding Error");
m_wire = wire;
m_wire.parse();
Block::element_const_iterator it = m_wire.elements_begin();
if (it != m_wire.elements_end() && it->type() == tlv::pib::ErrorCode) {
m_errCode = static_cast<pib::ErrCode>(readNonNegativeInteger(*it));
it++;
}
else
throw tlv::Error("PibError requires the first sub-TLV to be ErrorCode");
if (it != m_wire.elements_end() && it->type() == tlv::pib::Bytes) {
m_msg = string(reinterpret_cast<const char*>(it->value()), it->value_size());
it++;
}
else
throw tlv::Error("PibError requires the second sub-TLV to be Bytes");
}
PibUser::PibUser()
{
}
PibUser::PibUser(const Block& wire)
{
wireDecode(wire);
}
void
PibUser::setMgmtCert(const IdentityCertificate& mgmtCert)
{
m_wire.reset();
m_mgmtCert = mgmtCert;
}
void
PibUser::setTpmLocator(const std::string& tpmLocator)
{
m_wire.reset();
m_tpmLocator = tpmLocator;
}
template<bool T>
size_t
PibUser::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
if (!m_tpmLocator.empty())
totalLength = prependByteArrayBlock(block, tlv::pib::TpmLocator,
reinterpret_cast<const uint8_t*>(m_tpmLocator.c_str()),
m_tpmLocator.size());
totalLength += prependBlock(block, m_mgmtCert.wireEncode());
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::User);
return totalLength;
}
template size_t
PibUser::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
PibUser::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
PibUser::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
PibUser::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw tlv::Error("The supplied block does not contain wire format");
}
if (wire.type() != tlv::pib::User)
throw tlv::Error("Unexpected TLV type when decoding Content");
m_wire = wire;
m_wire.parse();
Block::element_const_iterator it = m_wire.elements_begin();
if (it != m_wire.elements_end() && it->type() == tlv::Data) {
m_mgmtCert.wireDecode(*it);
it++;
}
else
throw tlv::Error("PibError requires the first sub-TLV to be Data");
if (it != m_wire.elements_end() && it->type() == tlv::pib::TpmLocator) {
m_tpmLocator = string(reinterpret_cast<const char*>(it->value()), it->value_size());
}
}
} // namespace pib
} // namespace ndn
+316
View File
@@ -0,0 +1,316 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_PIB_ENCODING_HPP
#define NDN_PIB_PIB_ENCODING_HPP
#include "pib-common.hpp"
#include <ndn-cxx/security/identity-certificate.hpp>
namespace ndn {
namespace pib {
/**
* @brief Abstraction of pib::Identity TLV.
*
* This class is copyable since it is used by a variety of pib parameters
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
*/
class PibIdentity
{
public:
PibIdentity();
explicit
PibIdentity(const Name& identity);
explicit
PibIdentity(const Block& wire);
const Name&
getIdentity() const
{
return m_identity;
}
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
const Block&
wireEncode() const;
/**
* @brief Decode PibIdentity from a wire encoded block
*
* @throws tlv::Error if decoding fails
*/
void
wireDecode(const Block& wire);
private:
Name m_identity;
mutable Block m_wire;
};
/**
* @brief Abstraction of pib::PublicKey TLV.
*
* This class is copyable since it is used by a variety of pib parameters
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
*/
class PibPublicKey
{
public:
PibPublicKey();
PibPublicKey(const Name& keyName, const PublicKey& key);
explicit
PibPublicKey(const Block& wire);
const Name&
getKeyName() const;
const PublicKey&
getPublicKey() const;
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
const Block&
wireEncode() const;
/**
* @brief Decode PibPublicKey from a wire encoded block
*
* @throws tlv::Error if decoding fails
*/
void
wireDecode(const Block& wire);
private:
bool m_isValueSet;
Name m_keyName;
PublicKey m_key;
mutable Block m_wire;
};
/**
* @brief Abstraction of pib::Certificate TLV.
*
* This class is copyable since it is used by a variety of pib parameters
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
*/
class PibCertificate
{
public:
PibCertificate();
explicit
PibCertificate(const IdentityCertificate& certificate);
explicit
PibCertificate(const Block& wire);
const IdentityCertificate&
getCertificate() const;
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
const Block&
wireEncode() const;
/**
* @brief Decode PibCertificate from a wire encoded block
*
* @throws tlv::Error if decoding fails
*/
void
wireDecode(const Block& wire);
private:
bool m_isValueSet;
IdentityCertificate m_certificate;
mutable Block m_wire;
};
/**
* @brief Abstraction of pib::NameList TLV.
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#List-Parameters
*/
class PibNameList : noncopyable
{
public:
PibNameList();
explicit
PibNameList(const std::vector<Name>& names);
explicit
PibNameList(const Block& wire);
const std::vector<Name>&
getNameList() const
{
return m_names;
}
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
const Block&
wireEncode() const;
/**
* @brief Decode PibCertificate from a wire encoded block
*
* @throws tlv::Error if decoding fails
*/
void
wireDecode(const Block& wire);
private:
std::vector<Name> m_names;
mutable Block m_wire;
};
/**
* @brief Abstraction of pib::Error TLV.
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
*/
class PibError : noncopyable
{
public:
PibError();
explicit
PibError(const pib::ErrCode errCode, const std::string& msg = "");
explicit
PibError(const Block& wire);
pib::ErrCode
getErrorCode() const
{
return m_errCode;
}
const std::string&
getErrorMsg() const
{
return m_msg;
}
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
const Block&
wireEncode() const;
/**
* @brief Decode PibCertificate from a wire encoded block
*
* @throws tlv::Error if decoding fails
*/
void
wireDecode(const Block& wire);
private:
pib::ErrCode m_errCode;
std::string m_msg;
mutable Block m_wire;
};
/**
* @brief Abstraction of pib::User TLV.
*
* This class is copyable since it is used by a variety of pib parameters
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Query-Responses
*/
class PibUser
{
public:
PibUser();
explicit
PibUser(const Block& wire);
void
setMgmtCert(const IdentityCertificate& mgmtCert);
const IdentityCertificate&
getMgmtCert() const
{
return m_mgmtCert;
}
void
setTpmLocator(const std::string& tpmLocator);
const std::string&
getTpmLocator() const
{
return m_tpmLocator;
}
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
const Block&
wireEncode() const;
/**
* @brief Decode PibCertificate from a wire encoded block
*
* @throws tlv::Error if decoding fails
*/
void
wireDecode(const Block& wire);
private:
IdentityCertificate m_mgmtCert;
std::string m_tpmLocator;
mutable Block m_wire;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_PIB_ENCODING_HPP
+235
View File
@@ -0,0 +1,235 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "update-param.hpp"
#include <ndn-cxx/encoding/block-helpers.hpp>
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
static_assert(std::is_base_of<tlv::Error, UpdateParam::Error>::value,
"UpdateParam::Error must inherit from tlv::Error");
const std::string UpdateParam::VERB("update");
UpdateParam::UpdateParam()
: m_defaultOpt(DEFAULT_OPT_NO)
{
}
UpdateParam::UpdateParam(const PibUser& user)
: m_entityType(tlv::pib::User)
, m_user(user)
, m_defaultOpt(DEFAULT_OPT_NO)
{
}
UpdateParam::UpdateParam(const Name& identity, DefaultOpt defaultOpt)
: m_entityType(tlv::pib::Identity)
, m_identity(identity)
, m_defaultOpt(defaultOpt)
{
}
UpdateParam::UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt)
: m_entityType(tlv::pib::PublicKey)
, m_key(keyName, key)
, m_defaultOpt(defaultOpt)
{
}
UpdateParam::UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt)
: m_entityType(tlv::pib::Certificate)
, m_certificate(certificate)
, m_defaultOpt(defaultOpt)
{
}
UpdateParam::UpdateParam(const Block& wire)
{
wireDecode(wire);
}
const PibUser&
UpdateParam::getUser() const
{
if (m_entityType == tlv::pib::User)
return m_user;
else
throw Error("UpdateParam::getUser: entityType must be User");
}
const PibIdentity&
UpdateParam::getIdentity() const
{
if (m_entityType == tlv::pib::Identity)
return m_identity;
else
throw Error("UpdateParam::getIdentity: entityType must be Identity");
}
const PibPublicKey&
UpdateParam::getPublicKey() const
{
if (m_entityType == tlv::pib::PublicKey)
return m_key;
else
throw Error("UpdateParam::getPublicKey: entityType must be PublicKey");
}
const PibCertificate&
UpdateParam::getCertificate() const
{
if (m_entityType == tlv::pib::Certificate)
return m_certificate;
else
throw Error("UpdateParam::getCertificate: entityType must be Certificate");
}
template<bool T>
size_t
UpdateParam::wireEncode(EncodingImpl<T>& block) const
{
size_t totalLength = 0;
totalLength += prependNonNegativeIntegerBlock(block, tlv::pib::DefaultOpt, m_defaultOpt);
// Encode Entity
switch (m_entityType) {
case tlv::pib::Identity:
{
totalLength += m_identity.wireEncode(block);
break;
}
case tlv::pib::PublicKey:
{
totalLength += m_key.wireEncode(block);
break;
}
case tlv::pib::Certificate:
{
totalLength += m_certificate.wireEncode(block);
break;
}
case tlv::pib::User:
{
totalLength += m_user.wireEncode(block);
break;
}
default:
throw Error("UpdateParam::wireEncode: unsupported entity type: " +
boost::lexical_cast<std::string>(m_entityType));
}
totalLength += block.prependVarNumber(totalLength);
totalLength += block.prependVarNumber(tlv::pib::UpdateParam);
return totalLength;
}
template size_t
UpdateParam::wireEncode<true>(EncodingImpl<true>& block) const;
template size_t
UpdateParam::wireEncode<false>(EncodingImpl<false>& block) const;
const Block&
UpdateParam::wireEncode() const
{
if (m_wire.hasWire())
return m_wire;
EncodingEstimator estimator;
size_t estimatedSize = wireEncode(estimator);
EncodingBuffer buffer(estimatedSize, 0);
wireEncode(buffer);
m_wire = buffer.block();
return m_wire;
}
void
UpdateParam::wireDecode(const Block& wire)
{
if (!wire.hasWire()) {
throw Error("The supplied block does not contain wire format");
}
m_wire = wire;
m_wire.parse();
if (m_wire.type() != tlv::pib::UpdateParam)
throw Error("Unexpected TLV type when decoding UpdateParam");
Block::element_const_iterator it = m_wire.elements_begin();
// the first block must be Entity
if (it != m_wire.elements_end()) {
switch (it->type()) {
case tlv::pib::Identity:
{
m_entityType = tlv::pib::Identity;
m_identity.wireDecode(*it);
break;
}
case tlv::pib::PublicKey:
{
m_entityType = tlv::pib::PublicKey;
m_key.wireDecode(*it);
break;
}
case tlv::pib::Certificate:
{
m_entityType = tlv::pib::Certificate;
m_certificate.wireDecode(*it);
break;
}
case tlv::pib::User:
{
m_entityType = tlv::pib::User;
m_user.wireDecode(*it);
break;
}
default:
throw Error("The first sub-TLV of UpdateParam is not an entity type");
}
it++;
}
else
throw Error("UpdateParam requires the first sub-TLV to be an entity type");
// the second block must be DefaultOpt
if (it != m_wire.elements_end() && it->type() == tlv::pib::DefaultOpt) {
m_defaultOpt = static_cast<pib::DefaultOpt>(readNonNegativeInteger(*it));
it++;
}
else
throw Error("UpdateParam requires the second sub-TLV to be DefaultOpt");
if (it != m_wire.elements_end())
throw Error("UpdateParam must not contain more than two sub-TLVs");
}
} // namespace pib
} // namespace ndn
+136
View File
@@ -0,0 +1,136 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_UPDATE_PARAM_HPP
#define NDN_PIB_UPDATE_PARAM_HPP
#include "pib-common.hpp"
#include "pib-encoding.hpp"
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/security/identity-certificate.hpp>
namespace ndn {
namespace pib {
/**
* @brief UpdateParam is the abstraction of PIB Update parameter.
*
* PibUpdateParam := PIB-UPDATE-PARAM-TYPE TLV-LENGTH
* (PibIdentity | PibPublicKey | PibCertificate)
* PibDefaultOpt
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base#Update-Parameters
*/
class UpdateParam : noncopyable
{
public:
class Error : public tlv::Error
{
public:
explicit
Error(const std::string& what)
: tlv::Error(what)
{
}
};
UpdateParam();
explicit
UpdateParam(const PibUser& user);
explicit
UpdateParam(const Name& identity, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
UpdateParam(const Name& keyName, const PublicKey& key, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
explicit
UpdateParam(const IdentityCertificate& certificate, DefaultOpt defaultOpt = DEFAULT_OPT_NO);
explicit
UpdateParam(const Block& wire);
tlv::pib::ParamType
getParamType() const
{
return tlv::pib::UpdateParam;
}
tlv::pib::EntityType
getEntityType() const
{
return m_entityType;
}
const PibUser&
getUser() const;
const PibIdentity&
getIdentity() const;
const PibPublicKey&
getPublicKey() const;
const PibCertificate&
getCertificate() const;
pib::DefaultOpt
getDefaultOpt() const
{
return m_defaultOpt;
}
/// @brief Encode to a wire format or estimate wire format
template<bool T>
size_t
wireEncode(EncodingImpl<T>& block) const;
/// @brief Encode to a wire format
const Block&
wireEncode() const;
/**
* @brief Decode GetParam from a wire encoded block
*
* @throws Error if decoding fails
*/
void
wireDecode(const Block& wire);
public:
static const std::string VERB;
private:
tlv::pib::EntityType m_entityType;
PibUser m_user;
PibIdentity m_identity;
PibPublicKey m_key;
PibCertificate m_certificate;
pib::DefaultOpt m_defaultOpt;
mutable Block m_wire;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_UPDATE_PARAM_HPP
+132
View File
@@ -0,0 +1,132 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "get-query-processor.hpp"
#include "encoding/pib-encoding.hpp"
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
const Name GetQueryProcessor::PIB_PREFIX("/localhost/pib");
const size_t GetQueryProcessor::GET_QUERY_LENGTH = 5;
GetQueryProcessor::GetQueryProcessor(PibDb& db)
: m_db(db)
{
}
std::pair<bool, Block>
GetQueryProcessor::operator()(const Interest& interest)
{
const Name& interestName = interest.getName();
// handle pib query: /localhost/pib/[UserName]/get/param
if (interestName.size() != GET_QUERY_LENGTH) {
// malformed interest, discard
return std::make_pair(false, Block());
}
GetParam param;
try {
param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
}
catch (const tlv::Error& e) {
PibError error(ERR_WRONG_PARAM, "error in parsing param: " + std::string(e.what()));
return std::make_pair(true, error.wireEncode());
}
switch (param.getTargetType()) {
case TYPE_ID:
return processGetIdQuery(param);
case TYPE_KEY:
return processGetKeyQuery(param);
case TYPE_CERT:
return processGetCertQuery(param);
case TYPE_USER:
if (interest.getName().get(2).toUri() != m_db.getOwnerName())
return std::make_pair(false, Block());
else
return processGetUserQuery(param);
default:
{
PibError error(ERR_WRONG_PARAM, "requested type is not supported:" +
boost::lexical_cast<std::string>(param.getTargetType()));
return std::make_pair(true, error.wireEncode());
}
}
}
std::pair<bool, Block>
GetQueryProcessor::processGetIdQuery(const GetParam& param)
{
if (!m_db.hasIdentity(param.getTargetName())) {
PibError error(ERR_NON_EXISTING_ID, "requested id does not exist");
return std::make_pair(true, error.wireEncode());
}
PibIdentity result(param.getTargetName());
return std::make_pair(true, result.wireEncode());
}
std::pair<bool, Block>
GetQueryProcessor::processGetKeyQuery(const GetParam& param)
{
if (param.getTargetName().empty()) {
PibError error(ERR_WRONG_PARAM, "key name does not have id-component");
return std::make_pair(true, error.wireEncode());
}
shared_ptr<PublicKey> key = m_db.getKey(param.getTargetName());
if (key == nullptr) {
PibError error(ERR_NON_EXISTING_KEY, "requested key does not exist");
return std::make_pair(true, error.wireEncode());
}
PibPublicKey result(param.getTargetName(), *key);
return std::make_pair(true, result.wireEncode());
}
std::pair<bool, Block>
GetQueryProcessor::processGetCertQuery(const GetParam& param)
{
shared_ptr<IdentityCertificate> certificate = m_db.getCertificate(param.getTargetName());
if (certificate == nullptr) {
PibError error(ERR_NON_EXISTING_CERT, "requested certificate does not exist");
return std::make_pair(true, error.wireEncode());
}
PibCertificate result(*certificate);
return std::make_pair(true, result.wireEncode());
}
std::pair<bool, Block>
GetQueryProcessor::processGetUserQuery(const GetParam& param)
{
PibUser result;
result.setMgmtCert(*m_db.getMgmtCertificate());
result.setTpmLocator(m_db.getTpmLocator());
return std::make_pair(true, result.wireEncode());
}
} // namespace pib
} // namespace ndn
+82
View File
@@ -0,0 +1,82 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_GET_QUERY_PROCESSOR_HPP
#define NDN_PIB_GET_QUERY_PROCESSOR_HPP
#include "pib-db.hpp"
#include "encoding/get-param.hpp"
#include <ndn-cxx/interest.hpp>
#include <utility>
namespace ndn {
namespace pib {
/// @brief implements the PIB service
class GetQueryProcessor : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param db The pib database.
* @param owner Owner of the pib database.
*/
explicit
GetQueryProcessor(PibDb& db);
std::pair<bool, Block>
operator()(const Interest& interest);
private:
std::pair<bool, Block>
processGetUserQuery(const GetParam& param);
std::pair<bool, Block>
processGetIdQuery(const GetParam& param);
std::pair<bool, Block>
processGetKeyQuery(const GetParam& param);
std::pair<bool, Block>
processGetCertQuery(const GetParam& param);
private:
static const Name PIB_PREFIX;
static const size_t GET_QUERY_LENGTH;
const PibDb& m_db;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_GET_QUERY_PROCESSOR_HPP
+106
View File
@@ -0,0 +1,106 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "key-cache.hpp"
namespace ndn {
namespace pib {
KeyCacheEntry::KeyCacheEntry(const Name& name, shared_ptr<PublicKey> key)
: name(name)
, key(key)
{
BOOST_ASSERT(static_cast<bool>(key));
}
KeyCache::KeyCache(size_t capacity)
: m_capacity(capacity)
{
}
void
KeyCache::insert(const Name& name, shared_ptr<PublicKey> key)
{
// check if key exist
KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
if (it != m_keys.get<byName>().end()) {
adjustLru(it);
return;
}
// evict key when capacity is reached
if (size() >= m_capacity)
evictKey();
// insert entry
m_keys.insert(KeyCacheEntry(name, key));
}
shared_ptr<PublicKey>
KeyCache::find(const Name& name) const
{
// check if key exist
KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
if (it == m_keys.get<byName>().end())
return shared_ptr<PublicKey>();
else {
// adjust lru
shared_ptr<PublicKey> key = it->key;
adjustLru(it);
return key;
}
}
void
KeyCache::erase(const Name& name)
{
// check if key exist
KeyContainer::index<byName>::type::iterator it = m_keys.get<byName>().find(name);
if (it != m_keys.get<byName>().end()) {
m_keys.erase(it);
}
}
size_t
KeyCache::size() const
{
return m_keys.size();
}
void
KeyCache::evictKey()
{
if (!m_keys.get<byUsedTime>().empty()) {
KeyContainer::index<byUsedTime>::type::iterator it = m_keys.get<byUsedTime>().begin();
m_keys.erase(m_keys.project<0>(it));
}
}
void
KeyCache::adjustLru(KeyContainer::iterator it) const
{
KeyCacheEntry entry = std::move(*it);
m_keys.erase(it);
m_keys.insert(entry);
}
} // namespace pib
} // namespace ndn
+108
View File
@@ -0,0 +1,108 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_KEY_CACHE_HPP
#define NDN_PIB_KEY_CACHE_HPP
#include <ndn-cxx/name.hpp>
#include <ndn-cxx/util/time.hpp>
#include <ndn-cxx/security/public-key.hpp>
#include <stack>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
namespace ndn {
namespace pib {
struct KeyCacheEntry
{
KeyCacheEntry(const Name& name, shared_ptr<PublicKey> key);
Name name;
shared_ptr<PublicKey> key;
};
class byName;
class byUsedTime;
typedef boost::multi_index::multi_index_container<
KeyCacheEntry,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<
boost::multi_index::tag<byName>,
boost::multi_index::member<KeyCacheEntry, Name, &KeyCacheEntry::name>,
std::hash<Name>
>,
boost::multi_index::sequenced<
boost::multi_index::tag<byUsedTime>
>
>
> KeyContainer;
class KeyCache : noncopyable
{
public:
explicit
KeyCache(size_t capacity = getDefaultCapacity());
void
insert(const Name& name, shared_ptr<PublicKey> key);
shared_ptr<PublicKey>
find(const Name& name) const;
void
erase(const Name& name);
size_t
size() const;
private:
static size_t
getDefaultCapacity()
{
return 100;
}
void
evictKey();
void
adjustLru(KeyContainer::iterator it) const;
void
freeEntry(KeyContainer::iterator it);
private:
size_t m_capacity;
mutable KeyContainer m_keys;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_KEY_CACHE_HPP
+98
View File
@@ -0,0 +1,98 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "list-query-processor.hpp"
#include "encoding/pib-encoding.hpp"
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
using std::string;
using std::vector;
const size_t ListQueryProcessor::LIST_QUERY_LENGTH = 5;
ListQueryProcessor::ListQueryProcessor(PibDb& db)
: m_db(db)
{
}
std::pair<bool, Block>
ListQueryProcessor::operator()(const Interest& interest)
{
const Name& interestName = interest.getName();
// handle pib query: /localhost/pib/[UserName]/list/param
if (interestName.size() != MIN_PIB_INTEREST_SIZE) {
// malformed interest, discard
return std::make_pair(false, Block());
}
ListParam param;
try {
param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
}
catch (const tlv::Error& e) {
PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
return std::make_pair(true, error.wireEncode());
}
vector<Name> nameList;
switch (param.getOriginType()) {
case TYPE_USER:
{
nameList = m_db.listIdentities();
break;
}
case TYPE_ID:
{
nameList = m_db.listKeyNamesOfIdentity(param.getOriginName());
break;
}
case TYPE_KEY:
{
const Name& keyName = param.getOriginName();
if (keyName.empty()) {
PibError error(ERR_WRONG_PARAM,
"key name must contain key id component");
return std::make_pair(true, error.wireEncode());
}
nameList = m_db.listCertNamesOfKey(keyName);
break;
}
default:
{
PibError error(ERR_WRONG_PARAM,
"origin type is not supported: " +
boost::lexical_cast<string>(param.getOriginType()));
return std::make_pair(true, error.wireEncode());
}
}
PibNameList result(nameList);
return std::make_pair(true, result.wireEncode());
}
} // namespace pib
} // namespace ndn
+66
View File
@@ -0,0 +1,66 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_LIST_QUERY_PROCESSOR_HPP
#define NDN_PIB_LIST_QUERY_PROCESSOR_HPP
#include "pib-db.hpp"
#include "encoding/list-param.hpp"
#include <ndn-cxx/interest.hpp>
#include <utility>
namespace ndn {
namespace pib {
class ListQueryProcessor : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param db The pib database.
*/
explicit
ListQueryProcessor(PibDb& db);
std::pair<bool, Block>
operator()(const Interest& interest);
private:
static const size_t LIST_QUERY_LENGTH;
const PibDb& m_db;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_LIST_QUERY_PROCESSOR_HPP
+127
View File
@@ -0,0 +1,127 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "pib.hpp"
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/util/config-file.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include <boost/program_options/parsers.hpp>
#include <boost/filesystem.hpp>
namespace ndn {
namespace pib {
int
main(int argc, char** argv)
{
namespace po = boost::program_options;
namespace fs = boost::filesystem;
std::string owner;
std::string dbDir;
std::string tpmLocator;
Face face;
std::cerr << "hello" << std::endl;
po::options_description description(
"General Usage\n"
" ndn-pib [-h] -o owner -d database_dir -t tpm_locator\n"
"General options");
description.add_options()
("help,h", "produce help message")
("owner,o", po::value<std::string>(&owner),
"Name of the owner, PIB will listen to /localhost/pib/[owner].")
("database,d", po::value<std::string>(&dbDir),
"Absolute path to the directory of PIB database, /<database_dir>/pib.db")
("tpm,t", po::value<std::string>(&tpmLocator),
"URI of the tpm. e.g., tpm-file:/var")
;
po::variables_map vm;
try {
po::store(po::parse_command_line(argc, argv, description), vm);
po::notify(vm);
}
catch (const std::exception& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
std::cerr << description << std::endl;
return 1;
}
if (vm.count("help") != 0) {
std::cerr << description << std::endl;
return 0;
}
try {
if (vm.count("owner") == 0 && vm.count("database") == 0 && vm.count("tpm") == 0) {
if (std::getenv("HOME")) {
fs::path pibDir(std::getenv("HOME"));
pibDir /= ".ndn/pib";
dbDir = pibDir.string();
}
else {
std::cerr << "ERROR: HOME variable is not set" << std::endl;
return 1;
}
tpmLocator = KeyChain::getDefaultTpmLocator();
if (std::getenv("USER")) {
owner = std::string(std::getenv("USER"));
}
else {
std::cerr << "ERROR: HOME variable is not set" << std::endl;
return 1;
}
}
else if (vm.count("owner") == 0 || vm.count("database") == 0 ||
vm.count("tpm") == 0) {
std::cerr << description << std::endl;
return 1;
}
Pib pib(face, dbDir, tpmLocator, owner);
face.processEvents();
}
catch (std::runtime_error& e) {
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
return 0;
}
} // namespace pib
} // namespace ndn
int
main(int argc, char** argv)
{
ndn::pib::main(argc, argv);
}
+825
View File
@@ -0,0 +1,825 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "pib-db.hpp"
#include <sqlite3.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
namespace ndn {
namespace pib {
using std::string;
using std::vector;
using std::set;
const Name PibDb::NON_EXISTING_IDENTITY("/localhost/reserved/non-existing-identity");
const Name PibDb::NON_EXISTING_KEY("/localhost/reserved/non-existing-key");
const Name PibDb::NON_EXISTING_CERTIFICATE("/localhost/reserved/non-existing-certificate");
const Name PibDb::LOCALHOST_PIB("/localhost/pib");
const name::Component PibDb::MGMT_LABEL("mgmt");
static const string INITIALIZATION =
"CREATE TABLE IF NOT EXISTS \n"
" mgmt( \n"
" id INTEGER PRIMARY KEY,\n"
" owner BLOB NOT NULL, \n"
" tpm_locator BLOB, \n"
" local_management_cert BLOB NOT NULL \n"
" ); \n"
"CREATE TRIGGER IF NOT EXISTS \n"
" mgmt_insert_trigger \n"
" BEFORE INSERT ON mgmt \n"
" FOR EACH ROW \n"
" BEGIN \n"
" DELETE FROM mgmt; \n"
" END; \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"
"CREATE UNIQUE INDEX IF NOT EXISTS \n"
" identityIndex ON identities(identity); \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"
"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"
"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"
"CREATE TRIGGER IF NOT EXISTS \n"
" identity_delete_trigger \n"
" AFTER DELETE ON identities \n"
" FOR EACH ROW \n"
" BEGIN \n"
" SELECT identityDeleted (OLD.identity); \n"
" END; \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_type INTEGER 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"
"CREATE UNIQUE INDEX IF NOT EXISTS \n"
" keyIndex ON keys(key_name); \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"
"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"
"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"
"CREATE TRIGGER IF NOT EXISTS \n"
" key_delete_trigger \n"
" AFTER DELETE ON keys \n"
" FOR EACH ROW \n"
" BEGIN \n"
" SELECT keyDeleted (OLD.key_name); \n"
" END; \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"
"CREATE UNIQUE INDEX IF NOT EXISTS \n"
" certIndex ON certificates(certificate_name);\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"
"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"
"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"
"CREATE TRIGGER IF NOT EXISTS \n"
" cert_delete_trigger \n"
" AFTER DELETE ON certificates \n"
" FOR EACH ROW \n"
" BEGIN \n"
" SELECT certDeleted (OLD.certificate_name);\n"
" END; \n"
"CREATE TRIGGER IF NOT EXISTS \n"
" cert_insert_trigger \n"
" AFTER INSERT ON certificates \n"
" FOR EACH ROW \n"
" BEGIN \n"
" SELECT certInserted (NEW.certificate_name);\n"
" END; \n";
/**
* A utility function to call the normal sqlite3_bind_text where the value and length are
* value.c_str() and value.size().
*/
static int
sqlite3_bind_string(sqlite3_stmt* statement,
int index,
const string& value,
void(*destructor)(void*))
{
return sqlite3_bind_text(statement, index, value.c_str(), value.size(), destructor);
}
/**
* A utility function to call the normal sqlite3_bind_blob where the value and length are
* block.wire() and block.size().
*/
static int
sqlite3_bind_block(sqlite3_stmt* statement,
int index,
const Block& block,
void(*destructor)(void*))
{
return sqlite3_bind_blob(statement, index, block.wire(), block.size(), destructor);
}
/**
* A utility function to generate string by calling the normal sqlite3_column_text.
*/
static string
sqlite3_column_string(sqlite3_stmt* statement, int column)
{
return string(reinterpret_cast<const char*>(sqlite3_column_text(statement, column)),
sqlite3_column_bytes(statement, column));
}
/**
* A utility function to generate block by calling the normal sqlite3_column_text.
*/
static Block
sqlite3_column_block(sqlite3_stmt* statement, int column)
{
return Block(sqlite3_column_blob(statement, column), sqlite3_column_bytes(statement, column));
}
PibDb::PibDb(const string& dbDir)
{
// Determine the path of PIB DB
boost::filesystem::path dir;
if (dbDir == "") {
dir = boost::filesystem::path(getenv("HOME")) / ".ndn";
boost::filesystem::create_directories(dir);
}
else {
dir = boost::filesystem::path(dbDir);
boost::filesystem::create_directories(dir);
}
// Open PIB
int result = sqlite3_open_v2((dir / "pib.db").c_str(), &m_database,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
#ifdef NDN_CXX_DISABLE_SQLITE3_FS_LOCKING
"unix-dotfile"
#else
nullptr
#endif
);
if (result != SQLITE_OK)
throw Error("PIB DB cannot be opened/created: " + dbDir);
// enable foreign key
sqlite3_exec(m_database, "PRAGMA foreign_keys = ON", nullptr, nullptr, nullptr);
// initialize PIB specific tables
char* errorMessage = nullptr;
result = sqlite3_exec(m_database, INITIALIZATION.c_str(), nullptr, nullptr, &errorMessage);
if (result != SQLITE_OK && errorMessage != nullptr) {
sqlite3_free(errorMessage);
throw Error("PIB DB cannot be initialized");
}
// create delete trigger functions
createDbDeleteTrigger();
getOwnerName();
}
void
PibDb::createDbDeleteTrigger()
{
int res = 0;
res = sqlite3_create_function(m_database, "identityDeleted", -1, SQLITE_UTF8,
reinterpret_cast<void*>(this),
PibDb::identityDeletedFun, nullptr, nullptr);
if (res != SQLITE_OK)
throw Error("Cannot create function ``identityDeleted''");
res = sqlite3_create_function(m_database, "keyDeleted", -1, SQLITE_UTF8,
reinterpret_cast<void*>(this),
PibDb::keyDeletedFun, nullptr, nullptr);
if (res != SQLITE_OK)
throw Error("Cannot create function ``keyDeleted''");
res = sqlite3_create_function(m_database, "certDeleted", -1, SQLITE_UTF8,
reinterpret_cast<void*>(this),
PibDb::certDeletedFun, nullptr, nullptr);
if (res != SQLITE_OK)
throw Error("Cannot create function ``certDeleted''");
res = sqlite3_create_function(m_database, "certInserted", -1, SQLITE_UTF8,
reinterpret_cast<void*>(this),
PibDb::certInsertedFun, nullptr, nullptr);
if (res != SQLITE_OK)
throw Error("Cannot create function ``certInserted''");
}
void
PibDb::identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
{
BOOST_ASSERT(argc == 1);
PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
Name identity(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
pibDb->identityDeleted(identity);
}
void
PibDb::keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
{
BOOST_ASSERT(argc == 1);
PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
Name keyName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
pibDb->keyDeleted(keyName);
}
void
PibDb::certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
{
BOOST_ASSERT(argc == 1);
PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
pibDb->certificateDeleted(certName);
}
void
PibDb::certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv)
{
BOOST_ASSERT(argc == 1);
PibDb* pibDb = reinterpret_cast<PibDb*>(sqlite3_user_data(context));
Name certName(Block(sqlite3_value_blob(argv[0]), sqlite3_value_bytes(argv[0])));
pibDb->certificateInserted(certName);
}
void
PibDb::updateMgmtCertificate(const IdentityCertificate& certificate)
{
const Name& keyName = certificate.getPublicKeyName();
// Name of mgmt key should be "/localhost/pib/[UserName]/mgmt/[KeyID]"
if (keyName.size() != 5 ||
keyName.compare(0, 2, LOCALHOST_PIB) ||
keyName.get(3) != MGMT_LABEL)
throw Error("PibDb::updateMgmtCertificate: certificate does not follow the naming convention");
string owner = keyName.get(2).toUri();
sqlite3_stmt* statement;
if (!m_owner.empty()) {
if (m_owner != owner)
throw Error("PibDb::updateMgmtCertificate: owner name does not match");
else {
sqlite3_prepare_v2(m_database,
"UPDATE mgmt SET local_management_cert=? WHERE owner=?",
-1, &statement, nullptr);
}
}
else {
sqlite3_prepare_v2(m_database,
"INSERT INTO mgmt (local_management_cert, owner) VALUES (?, ?)",
-1, &statement, nullptr);
}
sqlite3_bind_block(statement, 1, certificate.wireEncode(), SQLITE_TRANSIENT);
sqlite3_bind_string(statement, 2, owner, SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
m_owner = owner;
mgmtCertificateChanged();
}
string
PibDb::getOwnerName() const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database, "SELECT owner FROM mgmt", -1, &statement, nullptr);
if (sqlite3_step(statement) == SQLITE_ROW) {
m_owner = sqlite3_column_string(statement, 0);
}
sqlite3_finalize(statement);
return m_owner;
}
shared_ptr<IdentityCertificate>
PibDb::getMgmtCertificate() const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database, "SELECT local_management_cert FROM mgmt", -1, &statement, nullptr);
shared_ptr<IdentityCertificate> certificate;
if (sqlite3_step(statement) == SQLITE_ROW) {
certificate = make_shared<IdentityCertificate>();
certificate->wireDecode(sqlite3_column_block(statement, 0));
}
sqlite3_finalize(statement);
return certificate;
}
void
PibDb::setTpmLocator(const std::string& tpmLocator)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"UPDATE mgmt SET tpm_locator=? WHERE owner=?",
-1, &statement, nullptr);
sqlite3_bind_string(statement, 1, tpmLocator, SQLITE_TRANSIENT);
sqlite3_bind_string(statement, 2, m_owner, SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
std::string
PibDb::getTpmLocator() const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database, "SELECT tpm_locator FROM mgmt", -1, &statement, nullptr);
string tpmLocator;
if (sqlite3_step(statement) == SQLITE_ROW) {
tpmLocator = sqlite3_column_string(statement, 0);
}
sqlite3_finalize(statement);
return tpmLocator;
}
int64_t
PibDb::addIdentity(const Name& identity)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"INSERT INTO identities (identity) values (?)",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
return sqlite3_last_insert_rowid(m_database);
}
void
PibDb::deleteIdentity(const Name& identity)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"DELETE FROM identities WHERE identity=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
bool
PibDb::hasIdentity(const Name& identity) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT id FROM identities WHERE identity=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
int result = sqlite3_step(statement);
sqlite3_finalize(statement);
if (result == SQLITE_ROW)
return true;
else
return false;
}
void
PibDb::setDefaultIdentity(const Name& identity)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"UPDATE identities SET is_default=1 WHERE identity=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
Name
PibDb::getDefaultIdentity() const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT identity FROM identities WHERE is_default=1",
-1, &statement, nullptr);
Name identity = NON_EXISTING_IDENTITY;
if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
identity = Name(sqlite3_column_block(statement, 0));
}
sqlite3_finalize(statement);
return identity;
}
vector<Name>
PibDb::listIdentities() const
{
vector<Name> identities;
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database, "SELECT identity FROM identities", -1, &statement, nullptr);
identities.clear();
while (sqlite3_step(statement) == SQLITE_ROW) {
Name name(sqlite3_column_block(statement, 0));
identities.push_back(name);
}
sqlite3_finalize(statement);
return identities;
}
int64_t
PibDb::addKey(const Name& keyName, const PublicKey& key)
{
if (keyName.empty())
return 0;
Name&& identity = keyName.getPrefix(-1);
if (!hasIdentity(identity))
addIdentity(identity);
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"INSERT INTO keys (identity_id, key_name, key_type, key_bits) \
values ((SELECT id FROM identities WHERE identity=?), ?, ?, ?)",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
sqlite3_bind_block(statement, 2, keyName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_bind_int(statement, 3, key.getKeyType());
sqlite3_bind_blob(statement, 4, key.get().buf(), key.get().size(), SQLITE_STATIC);
sqlite3_step(statement);
sqlite3_finalize(statement);
return sqlite3_last_insert_rowid(m_database);
}
shared_ptr<PublicKey>
PibDb::getKey(const Name& keyName) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT key_bits FROM keys WHERE key_name=?"
, -1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
shared_ptr<PublicKey> key;
if (sqlite3_step(statement) == SQLITE_ROW) {
key = make_shared<PublicKey>(static_cast<const uint8_t*>(sqlite3_column_blob(statement, 0)),
sqlite3_column_bytes(statement, 0));
}
sqlite3_finalize(statement);
return key;
}
void
PibDb::deleteKey(const Name& keyName)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"DELETE FROM keys WHERE key_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
bool
PibDb::hasKey(const Name& keyName) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT id FROM keys WHERE key_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
int result = sqlite3_step(statement);
sqlite3_finalize(statement);
if (result == SQLITE_ROW)
return true;
else
return false;
}
void
PibDb::setDefaultKeyNameOfIdentity(const Name& keyName)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"UPDATE keys SET is_default=1 WHERE key_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
Name
PibDb::getDefaultKeyNameOfIdentity(const Name& identity) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
WHERE identities.identity=? AND keys.is_default=1",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
Name keyName = NON_EXISTING_KEY;
if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
keyName = Name(sqlite3_column_block(statement, 0));
}
sqlite3_finalize(statement);
return keyName;
}
vector<Name>
PibDb::listKeyNamesOfIdentity(const Name& identity) const
{
vector<Name> keyNames;
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT key_name FROM keys JOIN identities ON keys.identity_id=identities.id\
WHERE identities.identity=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, identity.wireEncode(), SQLITE_TRANSIENT);
keyNames.clear();
while (sqlite3_step(statement) == SQLITE_ROW) {
Name keyName(sqlite3_column_block(statement, 0));
keyNames.push_back(keyName);
}
sqlite3_finalize(statement);
return keyNames;
}
int64_t
PibDb::addCertificate(const IdentityCertificate& certificate)
{
const Name& certName = certificate.getName();
const Name& keyName = certificate.getPublicKeyName();
if (!hasKey(keyName))
addKey(keyName, certificate.getPublicKeyInfo());
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"INSERT INTO certificates \
(key_id, certificate_name, certificate_data) \
values ((SELECT id FROM keys WHERE key_name=?), ?, ?)",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_bind_block(statement, 2, certName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_bind_block(statement, 3, certificate.wireEncode(), SQLITE_STATIC);
sqlite3_step(statement);
sqlite3_finalize(statement);
return sqlite3_last_insert_rowid(m_database);
}
shared_ptr<IdentityCertificate>
PibDb::getCertificate(const Name& certificateName) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT certificate_data FROM certificates WHERE certificate_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
shared_ptr<IdentityCertificate> certificate;
if (sqlite3_step(statement) == SQLITE_ROW) {
certificate = make_shared<IdentityCertificate>();
certificate->wireDecode(sqlite3_column_block(statement, 0));
}
sqlite3_finalize(statement);
return certificate;
}
void
PibDb::deleteCertificate(const Name& certificateName)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"DELETE FROM certificates WHERE certificate_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
bool
PibDb::hasCertificate(const Name& certificateName) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT id FROM certificates WHERE certificate_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
int result = sqlite3_step(statement);
sqlite3_finalize(statement);
if (result == SQLITE_ROW)
return true;
else
return false;
}
void
PibDb::setDefaultCertNameOfKey(const Name& certificateName)
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"UPDATE certificates SET is_default=1 WHERE certificate_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, certificateName.wireEncode(), SQLITE_TRANSIENT);
sqlite3_step(statement);
sqlite3_finalize(statement);
}
Name
PibDb::getDefaultCertNameOfKey(const Name& keyName) const
{
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT certificate_name\
FROM certificates JOIN keys ON certificates.key_id=keys.id\
WHERE keys.key_name=? AND certificates.is_default=1",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
Name certName = NON_EXISTING_CERTIFICATE;
if (sqlite3_step(statement) == SQLITE_ROW && sqlite3_column_bytes(statement, 0) != 0) {
certName = Name(sqlite3_column_block(statement, 0));
}
sqlite3_finalize(statement);
return certName;
}
vector<Name>
PibDb::listCertNamesOfKey(const Name& keyName) const
{
vector<Name> certNames;
sqlite3_stmt* statement;
sqlite3_prepare_v2(m_database,
"SELECT certificate_name\
FROM certificates JOIN keys ON certificates.key_id=keys.id\
WHERE keys.key_name=?",
-1, &statement, nullptr);
sqlite3_bind_block(statement, 1, keyName.wireEncode(), SQLITE_TRANSIENT);
certNames.clear();
while (sqlite3_step(statement) == SQLITE_ROW) {
Name name(sqlite3_column_block(statement, 0));
certNames.push_back(name);
}
sqlite3_finalize(statement);
return certNames;
}
} // namespace pib
} // namespace ndn
+265
View File
@@ -0,0 +1,265 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_PIB_DB_HPP
#define NDN_PIB_PIB_DB_HPP
#include "core/common.hpp"
#include <ndn-cxx/security/identity-certificate.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <set>
#include <vector>
struct sqlite3;
struct sqlite3_context;
struct Mem;
typedef Mem sqlite3_value;
namespace ndn {
namespace pib {
/// @brief Callback to report changes on user info.
typedef function<void(const std::string&)> UserChangedEventHandler;
/// @brief Callback to report that a key is deleted.
typedef function<void(const std::string&, const Name&,
const name::Component&)> KeyDeletedEventHandler;
/**
* @brief PibDb is a class to manage the database of PIB service.
*
* only public key related information is stored in this database.
* Detail information can be found at:
* http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
*/
class PibDb : noncopyable
{
public:
util::signal::Signal<PibDb> mgmtCertificateChanged;
util::signal::Signal<PibDb, Name> certificateDeleted;
util::signal::Signal<PibDb, Name> keyDeleted;
util::signal::Signal<PibDb, Name> identityDeleted;
util::signal::Signal<PibDb, Name> certificateInserted;
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
explicit
PibDb(const std::string& dbDir = "");
public: // Owner management
/**
* @brief Update owner's management certificate
*
* Since owner name is encoded in the management certificate,
* this method can also set the owner name if it is not set.
* If the owner name is set but does not match the one in the
* supplied certificate, it throws @p Error.
*
* @throws Error if supplied certificate is wrong
*/
void
updateMgmtCertificate(const IdentityCertificate& certificate);
/**
* @brief Get owner name
*
* return empty string when owner name is not set.
*/
std::string
getOwnerName() const;
/** @brief Get the management cert
*
* return nullptr when the management cert is not set
*/
shared_ptr<IdentityCertificate>
getMgmtCertificate() const;
/// @brief Set TPM locator
void
setTpmLocator(const std::string& tpmLocator);
/**
* @brief Get TPM locator
*
* return empty string when tpmLocator is not set.
*/
std::string
getTpmLocator() const;
public: // Identity management
/**
* @brief Add an identity
*
* @return row id of the added identity, 0 if insert fails.
*/
int64_t
addIdentity(const Name& identity);
/// @brief Delete an identity
void
deleteIdentity(const Name& identity);
/// @brief Check if an identity exists
bool
hasIdentity(const Name& identity) const;
/// @brief Get all identities
std::vector<Name>
listIdentities() const;
/// @brief Set the default identity
void
setDefaultIdentity(const Name& identity);
/**
* @brief Get the default identity
*
* @return default identity or /localhost/reserved/non-existing-identity if no default identity
*/
Name
getDefaultIdentity() const;
public: // Key management
/// @brief Add key
int64_t
addKey(const Name& keyName, const PublicKey& key);
/// @brief Delete key
void
deleteKey(const Name& keyName);
/// @brief Check if a key exists
bool
hasKey(const Name& keyName) const;
/**
* @brief Get key
*
* @return shared pointer to the key, nullptr if the key does not exit
*/
shared_ptr<PublicKey>
getKey(const Name& keyName) const;
/// @brief Get all the key names of an identity
std::vector<Name>
listKeyNamesOfIdentity(const Name& identity) const;
/// @brief Set an identity's default key name
void
setDefaultKeyNameOfIdentity(const Name& keyName);
/**
* @brief Get the default key name of an identity
*
* @return default key name or /localhost/reserved/non-existing-key if no default key
*/
Name
getDefaultKeyNameOfIdentity(const Name& identity) const;
public: // Certificate management
/// @brief Add a certificate
int64_t
addCertificate(const IdentityCertificate& certificate);
/// @brief Delete a certificate
void
deleteCertificate(const Name& certificateName);
/// @brief Check if the certificate exist
bool
hasCertificate(const Name& certificateName) const;
/**
* @brief Get a certificate
*
* @return shared pointer to the certificate, nullptr if the certificate does not exist
*/
shared_ptr<IdentityCertificate>
getCertificate(const Name& certificateName) const;
/// @brief Get all the cert names of a key
std::vector<Name>
listCertNamesOfKey(const Name& keyName) const;
/// @brief Set a key's default certificate name
void
setDefaultCertNameOfKey(const Name& certificateName);
/**
* @brief Get a key's default certificate name
*
* @return default certificate name or /localhost/reserved/non-existing-certificate if no default
* certificate.
*/
Name
getDefaultCertNameOfKey(const Name& keyName) const;
private:
void
createDbDeleteTrigger();
private:
static void
identityDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
static void
keyDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
static void
certDeletedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
static void
certInsertedFun(sqlite3_context* context, int argc, sqlite3_value** argv);
public:
static const Name NON_EXISTING_IDENTITY;
static const Name NON_EXISTING_KEY;
static const Name NON_EXISTING_CERTIFICATE;
private:
static const Name LOCALHOST_PIB;
static const name::Component MGMT_LABEL;
private:
sqlite3* m_database;
mutable std::string m_owner;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_PIB_DB_HPP
+163
View File
@@ -0,0 +1,163 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "pib-validator.hpp"
#include "encoding/pib-common.hpp"
#include "encoding/update-param.hpp"
#include <set>
#include <string>
namespace ndn {
namespace pib {
using std::set;
using std::string;
PibValidator::PibValidator(const PibDb& db, size_t maxCacheSize)
: m_db(db)
, m_isMgmtReady(false)
{
m_owner = m_db.getOwnerName();
m_mgmtCert = m_db.getMgmtCertificate();
if (!m_owner.empty() && m_mgmtCert != nullptr)
m_isMgmtReady = true;
m_mgmtChangeConnection =
const_cast<PibDb&>(m_db).mgmtCertificateChanged.connect([this] () {
m_owner = m_db.getOwnerName();
m_mgmtCert = m_db.getMgmtCertificate();
if (!m_owner.empty() && m_mgmtCert != nullptr)
m_isMgmtReady = true;
});
m_keyDeletedConnection =
const_cast<PibDb&>(m_db).keyDeleted.connect([this] (Name keyName) {
m_keyCache.erase(keyName);
});
}
PibValidator::~PibValidator()
{
}
void
PibValidator::checkPolicy(const Interest& interest,
int nSteps,
const OnInterestValidated& onValidated,
const OnInterestValidationFailed& onValidationFailed,
std::vector<shared_ptr<ValidationRequest>>& nextSteps)
{
if (!m_isMgmtReady)
return onValidationFailed(interest.shared_from_this(), "PibDb is not initialized");
const Name& interestName = interest.getName();
if (interestName.size() != SIGNED_PIB_INTEREST_SIZE) {
return onValidationFailed(interest.shared_from_this(),
"Interest is not signed: " + interest.getName().toUri());
}
// Check if the user exists in PIB
string user = interestName.get(OFFSET_USER).toUri();
if (user != m_owner)
return onValidationFailed(interest.shared_from_this(), "Wrong user: " + user);
// Verify signature
try {
Signature signature(interestName[OFFSET_SIG_INFO].blockFromValue(),
interestName[OFFSET_SIG_VALUE].blockFromValue());
// KeyLocator is required to contain the name of signing certificate (w/o version)
if (!signature.hasKeyLocator())
return onValidationFailed(interest.shared_from_this(), "No valid KeyLocator");
const KeyLocator& keyLocator = signature.getKeyLocator();
if (keyLocator.getType() != KeyLocator::KeyLocator_Name)
return onValidationFailed(interest.shared_from_this(), "Key Locator is not a name");
// Check if PIB has the corresponding public key
shared_ptr<PublicKey> publicKey;
if (keyLocator.getName() == m_mgmtCert->getName().getPrefix(-1)) {
// the signing key is mgmt key.
publicKey = make_shared<PublicKey>(m_mgmtCert->getPublicKeyInfo());
}
else {
// the signing key is normal key.
Name keyName = IdentityCertificate::certificateNameToPublicKeyName(keyLocator.getName());
shared_ptr<PublicKey> key = m_keyCache.find(keyName);
if (key != nullptr) {
// the signing key is cached.
publicKey = key;
}
else {
// the signing key is not cached.
publicKey = m_db.getKey(keyName);
if (publicKey == nullptr) {
// the signing key does not exist in PIB.
return onValidationFailed(interest.shared_from_this(), "Public key is not trusted");
}
else {
// the signing key is retrieved from PIB.
m_keyCache.insert(keyName, publicKey);
}
}
}
if (verifySignature(interest, signature, *publicKey))
onValidated(interest.shared_from_this());
else
onValidationFailed(interest.shared_from_this(), "Cannot verify signature");
}
catch (KeyLocator::Error&) {
return onValidationFailed(interest.shared_from_this(),
"No valid KeyLocator");
}
catch (Signature::Error&) {
return onValidationFailed(interest.shared_from_this(),
"No valid signature");
}
catch (IdentityCertificate::Error&) {
return onValidationFailed(interest.shared_from_this(),
"Cannot determine the signing key");
}
catch (tlv::Error&) {
return onValidationFailed(interest.shared_from_this(),
"Cannot decode signature");
}
}
void
PibValidator::checkPolicy(const Data& data,
int nSteps,
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed,
std::vector<shared_ptr<ValidationRequest>>& nextSteps)
{
// Pib does not express any interest, therefor should not validate any data.
onValidationFailed(data.shared_from_this(),
"PibValidator should not receive data packet");
}
} // namespace pib
} // namespace ndn
+81
View File
@@ -0,0 +1,81 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_PIB_VALIDATOR_HPP
#define NDN_PIB_PIB_VALIDATOR_HPP
#include "pib-db.hpp"
#include "key-cache.hpp"
#include <ndn-cxx/security/validator.hpp>
#include <unordered_map>
namespace ndn {
namespace pib {
/*
* @brief The validator to verify the command interests to PIB service
*
* @sa http://redmine.named-data.net/projects/ndn-cxx/wiki/PublicKey_Info_Base
*/
class PibValidator : public Validator
{
struct UserKeyCache;
public:
explicit
PibValidator(const PibDb& pibDb,
size_t maxCacheSize = 1000);
~PibValidator();
protected:
virtual void
checkPolicy(const Interest& interest,
int nSteps,
const OnInterestValidated& onValidated,
const OnInterestValidationFailed& onValidationFailed,
std::vector<shared_ptr<ValidationRequest>>& nextSteps);
virtual void
checkPolicy(const Data& data,
int nSteps,
const OnDataValidated& onValidated,
const OnDataValidationFailed& onValidationFailed,
std::vector<shared_ptr<ValidationRequest>>& nextSteps);
private:
const PibDb& m_db;
bool m_isMgmtReady;
std::string m_owner;
shared_ptr<IdentityCertificate> m_mgmtCert;
KeyCache m_keyCache;
util::signal::ScopedConnection m_mgmtChangeConnection;
util::signal::ScopedConnection m_keyDeletedConnection;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_PIB_VALIDATOR_HPP
+282
View File
@@ -0,0 +1,282 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "pib.hpp"
#include "encoding/pib-encoding.hpp"
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/util/crypto.hpp>
#include <ndn-cxx/util/concepts.hpp>
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
using std::string;
using std::vector;
using std::set;
const Name Pib::PIB_PREFIX("/localhost/pib");
const Name Pib::EMPTY_SIGNER_NAME;
const name::Component Pib::MGMT_LABEL("mgmt");
// \todo make this a static method in KeyChain
static inline void
signWithDigestSha256(Data& data)
{
DigestSha256 sig;
data.setSignature(sig);
Block sigValue(tlv::SignatureValue,
crypto::sha256(data.wireEncode().value(),
data.wireEncode().value_size() -
data.getSignature().getValue().size()));
data.setSignatureValue(sigValue);
data.wireEncode();
}
Pib::Pib(Face& face,
const std::string& dbDir,
const std::string& tpmLocator,
const std::string& owner)
: m_db(dbDir)
, m_tpm(nullptr)
, m_owner(owner)
, m_validator(m_db)
, m_face(face)
, m_certPublisher(m_face, m_db)
, m_getProcessor(m_db)
, m_defaultProcessor(m_db)
, m_listProcessor(m_db)
, m_updateProcessor(m_db, *this)
, m_deleteProcessor(m_db)
{
if (!m_db.getOwnerName().empty() && m_db.getOwnerName() != owner)
throw Error("owner argument differs from OwnerName in database");
if (!m_db.getTpmLocator().empty() && m_db.getTpmLocator() != tpmLocator)
throw Error("tpmLocator argument differs from TpmLocator in database");
initializeTpm(tpmLocator);
initializeMgmtCert();
m_db.setTpmLocator(tpmLocator);
registerPrefix();
}
Pib::~Pib()
{
m_face.unsetInterestFilter(m_pibMgmtFilterId);
m_face.unsetInterestFilter(m_pibGetFilterId);
m_face.unsetInterestFilter(m_pibDefaultFilterId);
m_face.unsetInterestFilter(m_pibListFilterId);
m_face.unsetInterestFilter(m_pibUpdateFilterId);
m_face.unsetInterestFilter(m_pibDeleteFilterId);
m_face.unsetInterestFilter(m_pibPrefixId);
}
void
Pib::setMgmtCert(std::shared_ptr<IdentityCertificate> mgmtCert)
{
if (mgmtCert != nullptr)
m_mgmtCert = mgmtCert;
}
void
Pib::initializeTpm(const string& tpmLocator)
{
m_tpm = KeyChain::createTpm(tpmLocator);
}
void
Pib::initializeMgmtCert()
{
shared_ptr<IdentityCertificate> mgmtCert = m_db.getMgmtCertificate();
if (mgmtCert == nullptr ||
!m_tpm->doesKeyExistInTpm(mgmtCert->getPublicKeyName(), KEY_CLASS_PRIVATE)) {
// If mgmt cert is set, or corresponding private key of the current mgmt cert is missing,
// generate new mgmt cert
// key name: /localhost/pib/[UserName]/mgmt/dsk-...
Name mgmtKeyName = PIB_PREFIX;
mgmtKeyName.append(m_owner).append(MGMT_LABEL);
std::ostringstream oss;
oss << "dsk-" << time::toUnixTimestamp(time::system_clock::now()).count();
mgmtKeyName.append(oss.str());
// self-sign pib root key
m_mgmtCert = prepareCertificate(mgmtKeyName, RsaKeyParams(),
time::system_clock::now(),
time::system_clock::now() + time::days(7300));
// update management certificate in database
m_db.updateMgmtCertificate(*m_mgmtCert);
}
else
m_mgmtCert = mgmtCert;
}
shared_ptr<IdentityCertificate>
Pib::prepareCertificate(const Name& keyName, const KeyParams& keyParams,
const time::system_clock::TimePoint& notBefore,
const time::system_clock::TimePoint& notAfter,
const Name& signerName)
{
// Generate mgmt key
m_tpm->generateKeyPairInTpm(keyName, keyParams);
shared_ptr<PublicKey> publicKey = m_tpm->getPublicKeyFromTpm(keyName);
// Set mgmt cert
auto certificate = make_shared<IdentityCertificate>();
Name certName = keyName.getPrefix(-1);
certName.append("KEY").append(keyName.get(-1)).append("ID-CERT").appendVersion();
certificate->setName(certName);
certificate->setNotBefore(notBefore);
certificate->setNotAfter(notAfter);
certificate->setPublicKeyInfo(*publicKey);
CertificateSubjectDescription subjectName(oid::ATTRIBUTE_NAME, keyName.getPrefix(-1).toUri());
certificate->addSubjectDescription(subjectName);
certificate->encode();
Name signingKeyName;
KeyLocator keyLocator;
if (signerName == EMPTY_SIGNER_NAME) {
// Self-sign mgmt cert
keyLocator = KeyLocator(certificate->getName().getPrefix(-1));
signingKeyName = keyName;
}
else {
keyLocator = KeyLocator(signerName.getPrefix(-1));
signingKeyName = IdentityCertificate::certificateNameToPublicKeyName(signerName);
}
SignatureSha256WithRsa signature(keyLocator);
certificate->setSignature(signature);
EncodingBuffer encoder;
certificate->wireEncode(encoder, true);
Block signatureValue = m_tpm->signInTpm(encoder.buf(), encoder.size(),
signingKeyName, DIGEST_ALGORITHM_SHA256);
certificate->wireEncode(encoder, signatureValue);
return certificate;
}
void
Pib::registerPrefix()
{
// register pib prefix
Name pibPrefix = PIB_PREFIX;
pibPrefix.append(m_owner);
m_pibPrefixId =
m_face.registerPrefix(pibPrefix,
[] (const Name& name) {},
[] (const Name& name, const string& msg) {
throw Error("cannot register pib prefix");
});
// set interest filter for management certificate
m_pibMgmtFilterId =
m_face.setInterestFilter(Name(pibPrefix).append(MGMT_LABEL),
[this] (const InterestFilter&, const Interest& interest) {
if (m_mgmtCert != nullptr) {
m_face.put(*m_mgmtCert);
}
});
// set interest filter for get command
m_pibGetFilterId = registerProcessor(Name(pibPrefix).append(GetParam::VERB), m_getProcessor);
// set interest filter for default command
m_pibDefaultFilterId = registerProcessor(Name(pibPrefix).append(DefaultParam::VERB),
m_defaultProcessor);
// set interest filter for list command
m_pibListFilterId = registerProcessor(Name(pibPrefix).append(ListParam::VERB),
m_listProcessor);
// set interest filter for update command
m_pibUpdateFilterId = registerSignedCommandProcessor(Name(pibPrefix).append(UpdateParam::VERB),
m_updateProcessor);
// set interest filter for delete command
m_pibDeleteFilterId = registerSignedCommandProcessor(Name(pibPrefix).append(DeleteParam::VERB),
m_deleteProcessor);
}
template<class Processor>
const InterestFilterId*
Pib::registerProcessor(const Name& prefix, Processor& process)
{
return m_face.setInterestFilter(prefix,
[&] (const InterestFilter&, const Interest& interest) {
processCommand(process, interest);
});
}
template<class Processor>
const InterestFilterId*
Pib::registerSignedCommandProcessor(const Name& prefix, Processor& process)
{
const InterestFilterId* filterId =
m_face.setInterestFilter(prefix,
[&] (const InterestFilter&, const Interest& interest) {
m_validator.validate(interest,
[&] (const shared_ptr<const Interest>& interest) {
processCommand(process, *interest);
},
[] (const shared_ptr<const Interest>&, const string&) {});
});
return filterId;
}
template<class Processor>
void
Pib::processCommand(Processor& process, const Interest& interest)
{
std::pair<bool, Block> result = process(interest);
if (result.first)
returnResult(Name(interest.getName()).appendVersion(),
result.second);
}
void
Pib::returnResult(const Name& dataName, const Block& content)
{
shared_ptr<Data> data = make_shared<Data>(dataName);
data->setFreshnessPeriod(time::milliseconds::zero());
data->setContent(content);
signWithDigestSha256(*data);
// Put data into response cache
m_responseCache.insert(*data);
// Put data to face.
m_face.put(*data);
}
} // namespace pib
} // namespace ndn
+178
View File
@@ -0,0 +1,178 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_PIB_HPP
#define NDN_PIB_PIB_HPP
#include "pib-db.hpp"
#include "pib-validator.hpp"
#include "cert-publisher.hpp"
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/util/in-memory-storage-persistent.hpp>
#include "get-query-processor.hpp"
#include "default-query-processor.hpp"
#include "list-query-processor.hpp"
#include "update-query-processor.hpp"
#include "delete-query-processor.hpp"
#include <ndn-cxx/security/sec-tpm.hpp>
namespace ndn {
namespace pib {
/// @brief implements the PIB service
class Pib : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param face The face pib used to receive queries and serve certificates.
* @param dbDir Absolute path to the directory of the pib database.
* @param tpmLocator URI to locate the TPM for pib service.
* @param owner Owner of the pib database.
*/
Pib(Face& face,
const std::string& dbDir,
const std::string& tpmLocator,
const std::string& owner);
~Pib();
void
setMgmtCert(std::shared_ptr<IdentityCertificate> mgmtCert);
PUBLIC_WITH_TESTS_ELSE_PROTECTED:
PibDb&
getDb()
{
return m_db;
}
SecTpm&
getTpm()
{
return *m_tpm;
}
util::InMemoryStoragePersistent&
getResponseCache()
{
return m_responseCache;
}
const std::string&
getOwner() const
{
return m_owner;
}
const IdentityCertificate&
getMgmtCert() const
{
BOOST_ASSERT(m_mgmtCert != nullptr);
return *m_mgmtCert;
}
private: // initialization
/// @brief initialize the PIB's own TPM.
void
initializeTpm(const std::string& tpmLocator);
/// @brief initialize management certificate
void
initializeMgmtCert();
std::shared_ptr<IdentityCertificate>
prepareCertificate(const Name& keyName, const KeyParams& keyParams,
const time::system_clock::TimePoint& notBefore,
const time::system_clock::TimePoint& notAfter,
const Name& signerName = EMPTY_SIGNER_NAME);
/// @brief register prefix for PIB query and management certificate
void
registerPrefix();
template<class Processor>
const InterestFilterId*
registerProcessor(const Name& prefix, Processor& process);
template<class Processor>
const InterestFilterId*
registerSignedCommandProcessor(const Name& prefix, Processor& process);
template<class Processor>
void
processCommand(Processor& process, const Interest& interest);
void
returnResult(const Name& dataName, const Block& content);
private:
static const Name EMPTY_SIGNER_NAME;
static const Name PIB_PREFIX;
static const name::Component MGMT_LABEL;
PibDb m_db;
std::unique_ptr<SecTpm> m_tpm;
std::string m_owner;
std::shared_ptr<IdentityCertificate> m_mgmtCert;
PibValidator m_validator;
Face& m_face;
CertPublisher m_certPublisher;
util::InMemoryStoragePersistent m_responseCache;
const RegisteredPrefixId* m_pibPrefixId;
const InterestFilterId* m_pibMgmtFilterId;
const InterestFilterId* m_pibGetFilterId;
const InterestFilterId* m_pibDefaultFilterId;
const InterestFilterId* m_pibListFilterId;
const InterestFilterId* m_pibUpdateFilterId;
const InterestFilterId* m_pibDeleteFilterId;
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
GetQueryProcessor m_getProcessor;
DefaultQueryProcessor m_defaultProcessor;
ListQueryProcessor m_listProcessor;
UpdateQueryProcessor m_updateProcessor;
DeleteQueryProcessor m_deleteProcessor;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_PIB_HPP
+73
View File
@@ -0,0 +1,73 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "response-cache.hpp"
namespace ndn {
namespace pib {
using std::map;
ResponseCache::ResponseCache()
{
}
shared_ptr<const Data>
ResponseCache::find(const Name& dataName, bool hasVersion) const
{
if (!hasVersion) {
Storage::const_iterator it = m_storage.find(dataName);
if (it != m_storage.end())
return it->second;
else
return shared_ptr<const Data>();
}
else {
Storage::const_iterator it = m_storage.find(dataName.getPrefix(-1));
if (it != m_storage.end() && it->second->getName() == dataName)
return it->second;
else
return shared_ptr<const Data>();
}
}
void
ResponseCache::insert(const Data& data)
{
data.getName().at(-1).toVersion(); // ensures last component is version
m_storage[data.getName().getPrefix(-1)] = data.shared_from_this();
}
void
ResponseCache::erase(const Name& dataNameWithoutVersion)
{
m_storage.erase(dataNameWithoutVersion);
}
void
ResponseCache::clear()
{
m_storage.clear();
}
} // namespace pib
} // namespace ndn
+74
View File
@@ -0,0 +1,74 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2014 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_RESPONSE_CACHE_HPP
#define NDN_PIB_RESPONSE_CACHE_HPP
#include <ndn-cxx/data.hpp>
#include <map>
namespace ndn {
namespace pib {
/**
* @brief ResponseCache is an abstraction of a cache of response made before
*
* ResponseCache is used to reduce the number of PibDb lookup and Data signing
* operations.
*
* Eventually, it should be replaced by a formal application level cache. This
* one is only a temporary module and is used for test.
*/
class ResponseCache : noncopyable
{
public:
ResponseCache();
shared_ptr<const Data>
find(const Name& dataName, bool hasVersion = false) const;
/**
* @brief Insert a data packet into cache
*
* Name of the inserted data must end with a version component
*
* @param data Data to insert. It MUST have been created with make_shared.
*/
void
insert(const Data& data);
void
erase(const Name& dataNameWithoutVersion);
void
clear();
private:
typedef std::map<Name, shared_ptr<const Data> > Storage;
Storage m_storage;
};
} // namespace ndn
} // namespace pib
#endif // NDN_PIB_RESPONSE_CACHE_HPP
+267
View File
@@ -0,0 +1,267 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#include "update-query-processor.hpp"
#include "encoding/pib-encoding.hpp"
#include "pib.hpp"
#include <boost/lexical_cast.hpp>
namespace ndn {
namespace pib {
using std::string;
const size_t UpdateQueryProcessor::UPDATE_QUERY_LENGTH = 9;
const Name UpdateQueryProcessor::PIB_PREFIX("/localhost/pib");
UpdateQueryProcessor::UpdateQueryProcessor(PibDb& db, Pib& pib)
: m_db(db)
, m_pib(pib)
{
}
std::pair<bool, Block>
UpdateQueryProcessor::operator()(const Interest& interest)
{
const Name& interestName = interest.getName();
// handle pib query: /localhost/pib/[UserName]/update/param/<signed_interest_related_components>
if (interestName.size() != UPDATE_QUERY_LENGTH) {
// malformed interest, discard
return std::make_pair(false, Block());
}
try {
UpdateParam param;
param.wireDecode(interestName.get(OFFSET_PARAM).blockFromValue());
SignatureInfo sigInfo;
sigInfo.wireDecode(interestName.get(OFFSET_SIG_INFO).blockFromValue());
// sigInfo must have KeyLocator.Name if the interest passed validation.
Name signerName;
signerName = sigInfo.getKeyLocator().getName();
switch (param.getEntityType()) {
case tlv::pib::User:
return processUpdateUserQuery(param, signerName);
case tlv::pib::Identity:
return processUpdateIdQuery(param, signerName);
case tlv::pib::PublicKey:
return processUpdateKeyQuery(param, signerName);
case tlv::pib::Certificate:
return processUpdateCertQuery(param, signerName);
default:
{
PibError error(ERR_WRONG_PARAM,
"entity type is not supported: " +
boost::lexical_cast<string>(param.getEntityType()));
return std::make_pair(true, error.wireEncode());
}
}
}
catch (const PibDb::Error& e) {
PibError error(ERR_INTERNAL_ERROR, e.what());
return std::make_pair(true, error.wireEncode());
}
catch (const tlv::Error& e) {
PibError error(ERR_WRONG_PARAM, "error in parsing param: " + string(e.what()));
return std::make_pair(true, error.wireEncode());
}
}
std::pair<bool, Block>
UpdateQueryProcessor::processUpdateUserQuery(const UpdateParam& param, const Name& signerName)
{
Name expectedId = m_db.getMgmtCertificate()->getPublicKeyName().getPrefix(-1);
Name targetId = param.getUser().getMgmtCert().getPublicKeyName().getPrefix(-1);
Name signerId = IdentityCertificate::certificateNameToPublicKeyName(signerName).getPrefix(-1);
if (expectedId == targetId && expectedId == signerId) {
m_db.updateMgmtCertificate(param.getUser().getMgmtCert());
m_pib.setMgmtCert(make_shared<IdentityCertificate>(param.getUser().getMgmtCert()));
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
PibError error(ERR_WRONG_PARAM, "not allowed to update user");
return std::make_pair(true, error.wireEncode());
}
std::pair<bool, Block>
UpdateQueryProcessor::processUpdateIdQuery(const UpdateParam& param, const Name& signerName)
{
const Name& identity = param.getIdentity().getIdentity();
if (!isUpdateAllowed(TYPE_ID, identity, signerName, param.getDefaultOpt())) {
PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
return std::make_pair(true, error.wireEncode());
}
// add the identity
m_db.addIdentity(identity);
// set the identity as user default if it is requested.
const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
if (DEFAULT_OPT_USER_MASK & defaultOpt) {
m_db.setDefaultIdentity(identity);
}
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
std::pair<bool, Block>
UpdateQueryProcessor::processUpdateKeyQuery(const UpdateParam& param, const Name& signerName)
{
const Name& keyName = param.getPublicKey().getKeyName();
if (!isUpdateAllowed(TYPE_KEY, keyName, signerName, param.getDefaultOpt())) {
PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
return std::make_pair(true, error.wireEncode());
}
Name identity = keyName.getPrefix(-1);
// add the key
m_db.addKey(keyName, param.getPublicKey().getPublicKey());
const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
if (DEFAULT_OPT_ID_MASK & defaultOpt) // set the key as identity default if requested.
m_db.setDefaultKeyNameOfIdentity(keyName);
if (DEFAULT_OPT_USER_MASK & defaultOpt) // set the identity as user default if requested.
m_db.setDefaultIdentity(identity);
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
std::pair<bool, Block>
UpdateQueryProcessor::processUpdateCertQuery(const UpdateParam& param, const Name& signerName)
{
const IdentityCertificate& cert = param.getCertificate().getCertificate();
const Name& certName = cert.getName();
if (!isUpdateAllowed(TYPE_CERT, certName, signerName, param.getDefaultOpt())) {
PibError error(ERR_WRONG_SIGNER, "signer is not trusted for this command");
return std::make_pair(true, error.wireEncode());
}
const Name& keyName = cert.getPublicKeyName();
Name identity = keyName.getPrefix(-1);
// add certificate
m_db.addCertificate(cert);
const pib::DefaultOpt& defaultOpt = param.getDefaultOpt();
if (DEFAULT_OPT_KEY_MASK & defaultOpt) // set the cert as key default if requested.
m_db.setDefaultCertNameOfKey(certName);
if (DEFAULT_OPT_ID_MASK & defaultOpt) // set the key as identity default if requested.
m_db.setDefaultKeyNameOfIdentity(keyName);
if (DEFAULT_OPT_USER_MASK & defaultOpt) // set the identity as user default if requested.
m_db.setDefaultIdentity(identity);
return std::make_pair(true, PibError(ERR_SUCCESS).wireEncode());
}
bool
UpdateQueryProcessor::isUpdateAllowed(const pib::Type targetType,
const Name& targetName,
const Name& signer,
const pib::DefaultOpt defaultOpt) const
{
// Any identity with prefix /localhost/pib is reserved. Any operation with a targetName under
// that prefix will be rejected.
if (PIB_PREFIX.isPrefixOf(targetName))
return false;
// A request is wrong if
// 1) it wants to change the default setting of an identity, but the target is not key nor cert
// 2) it wants to change the default setting of a key, but the target is not cert
if ((defaultOpt == DEFAULT_OPT_ID && (targetType != TYPE_KEY && targetType != TYPE_CERT)) ||
(defaultOpt == DEFAULT_OPT_KEY && targetType != TYPE_CERT))
return false;
// Rules for other items:
//
// signer | adding privilege | default setting privilege
// ================+==========================+============================================
// local mgmt key | any id, key, and cert | the default id,
// | | the default key of any id,
// | | the default cert of any key of any id
// ----------------+--------------------------+--------------------------------------------
// default key of | any id, key, and cert | the default key of the id and its sub ids,
// an id | under the id's namespace | the default cert of any key of the id
// | | and its sub ids
// ----------------+--------------------------+--------------------------------------------
// non-default key | any cert of the key | the default cert of the key
// of an id
const Name& signerKeyName = IdentityCertificate::certificateNameToPublicKeyName(signer);
const Name& signerId = signerKeyName.getPrefix(-1);
bool hasSignerDefaultKey = true;
Name signerDefaultKeyName;
try {
signerDefaultKeyName = m_db.getDefaultKeyNameOfIdentity(signerId);
}
catch (PibDb::Error&) {
hasSignerDefaultKey = false;
}
Name mgmtCertName;
try {
mgmtCertName = m_db.getMgmtCertificate()->getName().getPrefix(-1);
}
catch (PibDb::Error&) {
return false;
}
if (signer == mgmtCertName) {
// signer is current management key, anything is allowed.
return true;
}
else if (hasSignerDefaultKey && signerDefaultKeyName == signerKeyName) {
// signer is an identity's default key
if (!signerId.isPrefixOf(targetName))
return false;
// check default setting
// user default setting is not allowed
if (defaultOpt == DEFAULT_OPT_USER)
return false;
else
return true;
}
else {
// non-default key
if (targetType != TYPE_CERT)
return false;
// check if it is for the key's cert
if (IdentityCertificate::certificateNameToPublicKeyName(targetName) != signerKeyName)
return false;
if (defaultOpt == DEFAULT_OPT_USER || defaultOpt == DEFAULT_OPT_ID)
return false;
else
return true;
}
}
} // namespace pib
} // namespace ndn
+98
View File
@@ -0,0 +1,98 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2013-2015 Regents of the University of California.
*
* This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
*
* ndn-cxx library is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received copies of the GNU General Public License and GNU Lesser
* General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
* <http://www.gnu.org/licenses/>.
*
* See AUTHORS.md for complete list of ndn-cxx authors and contributors.
*/
#ifndef NDN_PIB_UPDATE_QUERY_PROCESSOR_HPP
#define NDN_PIB_UPDATE_QUERY_PROCESSOR_HPP
#include "pib-db.hpp"
#include "encoding/update-param.hpp"
#include <ndn-cxx/interest.hpp>
#include <utility>
namespace ndn {
namespace pib {
class Pib;
/// @brief Processing unit for PIB update query
class UpdateQueryProcessor : noncopyable
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
/**
* @brief Constructor
*
* @param db The pib database.
*/
UpdateQueryProcessor(PibDb& db, Pib& pib);
std::pair<bool, Block>
operator()(const Interest& interest);
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
/**
* @brief Determine if an update command is allowed.
*
* @param targetType The type of the target that will be updated.
* @param targetName The name of the target that will be updated.
* @param signer The name of the command signer.
* @param defaultOpt The default settings that is requested to update.
*/
bool
isUpdateAllowed(const pib::Type targetType,
const Name& targetName,
const Name& signer,
const pib::DefaultOpt defaultOpt) const;
private:
std::pair<bool, Block>
processUpdateUserQuery(const UpdateParam& param, const Name& signerName);
std::pair<bool, Block>
processUpdateIdQuery(const UpdateParam& param, const Name& signerName);
std::pair<bool, Block>
processUpdateKeyQuery(const UpdateParam& param, const Name& signerName);
std::pair<bool, Block>
processUpdateCertQuery(const UpdateParam& param, const Name& signerName);
private:
static const size_t UPDATE_QUERY_LENGTH;
static const Name PIB_PREFIX;
PibDb& m_db;
Pib& m_pib;
};
} // namespace pib
} // namespace ndn
#endif // NDN_PIB_UPDATE_QUERY_PROCESSOR_HPP
+19
View File
@@ -0,0 +1,19 @@
# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
top = '../..'
def build(bld):
bld(features=['cxx'],
name="pib-objects",
target="pib-objects",
source=bld.path.ant_glob('**/*.cpp', excl=['ndn-pib.cpp']),
use='core-objects',
install_path=None,
)
bld(features=['cxx', 'cxxprogram'],
target='ndn-pib',
source='ndn-pib.cpp',
use='pib-objects',
)