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:
1 parent
4bd28fc839
commit
77627ab8ce
49 files changed
+8695
No files matched your search
@@ -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/>
|
||||
@@ -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),
|
||||
]
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
File diff suppressed because it is too large.
Load diff
@@ -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
|
||||
@@ -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,
|
||||
)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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',
|
||||
)
|
||||
Reference in new issue
Block a user