diff --git a/AUTHORS.md b/AUTHORS.md
index 3d40a6f..0915877 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -12,3 +12,4 @@ in ndn-tools:
* Junxiao Shi
* Eric Newberry
* Xiaoke Jiang
+* Yingdi Yu
diff --git a/manpages/conf.py b/manpages/conf.py
index 3c0f6bb..d86777a 100644
--- a/manpages/conf.py
+++ b/manpages/conf.py
@@ -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),
]
diff --git a/manpages/ndn-pib.rst b/manpages/ndn-pib.rst
new file mode 100644
index 0000000..e94a7d2
--- /dev/null
+++ b/manpages/ndn-pib.rst
@@ -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
+`__
+
+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
diff --git a/tests/pib/cert-publicher.t.cpp b/tests/pib/cert-publicher.t.cpp
new file mode 100644
index 0000000..f33f325
--- /dev/null
+++ b/tests/pib/cert-publicher.t.cpp
@@ -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
+ * .
+ *
+ * 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
+
+#include
+
+#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 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 cert111 = m_keyChain.getCertificate(certName111);
+ Name keyName11 = cert111->getPublicKeyName();
+
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr 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(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(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
diff --git a/tests/pib/identity-management-time-fixture.cpp b/tests/pib/identity-management-time-fixture.cpp
new file mode 100644
index 0000000..526a2e6
--- /dev/null
+++ b/tests/pib/identity-management-time-fixture.cpp
@@ -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
+ * .
+ *
+ * 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
diff --git a/tests/pib/identity-management-time-fixture.hpp b/tests/pib/identity-management-time-fixture.hpp
new file mode 100644
index 0000000..4ac2e63
--- /dev/null
+++ b/tests/pib/identity-management-time-fixture.hpp
@@ -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
+ * .
+ *
+ * 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
+#include
+#include
+
+#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 m_identities;
+};
+
+} // namespace security
+} // namespace ndn
+
+#endif // NDN_TESTS_IDENTITY_MANAGEMENT_TIME_FIXTURE_HPP
diff --git a/tests/pib/key-cache.t.cpp b/tests/pib/key-cache.t.cpp
new file mode 100644
index 0000000..936c132
--- /dev/null
+++ b/tests/pib/key-cache.t.cpp
@@ -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
+ * .
+ *
+ * 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();
+ auto key2 = make_shared();
+ auto key3 = make_shared();
+ auto key4 = make_shared();
+
+ keyCache.insert(name1, key1);
+ keyCache.insert(name2, key2);
+ keyCache.insert(name3, key3);
+
+ BOOST_CHECK_EQUAL(keyCache.size(), 3);
+ BOOST_CHECK(static_cast(keyCache.find(name1)));
+ BOOST_CHECK(static_cast(keyCache.find(name2)));
+ BOOST_CHECK(static_cast(keyCache.find(name3)));
+ BOOST_CHECK(!static_cast(keyCache.find(name4)));
+
+ keyCache.insert(name1, key1);
+ keyCache.insert(name4, key4);
+ BOOST_CHECK_EQUAL(keyCache.size(), 3);
+ BOOST_CHECK(static_cast(keyCache.find(name1)));
+ BOOST_CHECK(!static_cast(keyCache.find(name2)));
+ BOOST_CHECK(static_cast(keyCache.find(name3)));
+ BOOST_CHECK(static_cast(keyCache.find(name4)));
+
+ keyCache.erase(name1);
+ BOOST_CHECK_EQUAL(keyCache.size(), 2);
+ BOOST_CHECK(!static_cast(keyCache.find(name1)));
+ BOOST_CHECK(static_cast(keyCache.find(name3)));
+ BOOST_CHECK(static_cast(keyCache.find(name4)));
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/pib-db.t.cpp b/tests/pib/pib-db.t.cpp
new file mode 100644
index 0000000..6d826d2
--- /dev/null
+++ b/tests/pib/pib-db.t.cpp
@@ -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
+ * .
+ *
+ * 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
+
+#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 deletedIds;
+ std::vector deletedKeys;
+ std::vector deletedCerts;
+ std::vector 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 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 testUser2Cert = m_keyChain.getCertificate(testUser2CertName);
+
+ BOOST_CHECK_THROW(db.updateMgmtCertificate(*testUser2Cert), PibDb::Error);
+
+ Name testUserKeyName2 = m_keyChain.generateRsaKeyPairAsDefault(testUser);
+ shared_ptr 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 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 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 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 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 cert111 = m_keyChain.getCertificate(certName111);
+ Name keyName11 = cert111->getPublicKeyName();
+
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert112 = m_keyChain.selfSign(keyName11);
+ Name certName112 = cert112->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
+ shared_ptr cert121 = m_keyChain.selfSign(keyName12);
+ Name certName121 = cert121->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr 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 cert211 = m_keyChain.getCertificate(certName211);
+ Name keyName21 = cert211->getPublicKeyName();
+
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert212 = m_keyChain.selfSign(keyName21);
+ Name certName212 = cert212->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
+ shared_ptr cert221 = m_keyChain.selfSign(keyName22);
+ Name certName221 = cert221->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr 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
diff --git a/tests/pib/pib-validator.t.cpp b/tests/pib/pib-validator.t.cpp
new file mode 100644
index 0000000..06fd373
--- /dev/null
+++ b/tests/pib/pib-validator.t.cpp
@@ -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
+ * .
+ *
+ * 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
+
+#include "identity-management-time-fixture.hpp"
+#include
+#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 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 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 interest1 = make_shared(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&) {
+ isProcessed = true;
+ BOOST_CHECK(true);
+ },
+ [this] (const shared_ptr&, const std::string&) {
+ isProcessed = true;
+ BOOST_CHECK(false);
+ });
+ BOOST_CHECK(isProcessed);
+
+ Name command2("/localhost/pib/test/verb/param");
+ shared_ptr interest2 = make_shared(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&) {
+ isProcessed = true;
+ BOOST_CHECK(false);
+ },
+ [this] (const shared_ptr&, const std::string&) {
+ isProcessed = true;
+ BOOST_CHECK(true);
+ });
+ BOOST_CHECK(isProcessed);
+
+ Name command3("/localhost/pib/test/verb/param");
+ shared_ptr interest3 = make_shared(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&) {
+ isProcessed = true;
+ BOOST_CHECK(true);
+ },
+ [this] (const shared_ptr&, const std::string&) {
+ isProcessed = true;
+ BOOST_CHECK(false);
+ });
+ BOOST_CHECK(isProcessed);
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/pib.t.cpp b/tests/pib/pib.t.cpp
new file mode 100644
index 0000000..f4c4e6f
--- /dev/null
+++ b/tests/pib/pib.t.cpp
@@ -0,0 +1,1389 @@
+/* -*- 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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "tools/pib/pib.hpp"
+#include "identity-management-time-fixture.hpp"
+#include
+#include "tools/pib/encoding/pib-encoding.hpp"
+#include
+#include
+
+#include
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+class PibTestFixture : public ndn::security::IdentityManagementTimeFixture
+{
+public:
+ PibTestFixture()
+ : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "PibTest")
+ , face(util::makeDummyClientFace(io, {true, true}))
+ {
+ }
+
+ ~PibTestFixture()
+ {
+ boost::filesystem::remove_all(tmpPath);
+ }
+
+ template
+ shared_ptr
+ generateUnsignedInterest(Param& param, const std::string& user)
+ {
+ Name command("/localhost/pib");
+ command.append(user).append(Param::VERB).append(param.wireEncode());
+ shared_ptr interest = make_shared(command);
+
+ return interest;
+ }
+
+ template
+ shared_ptr
+ generateSignedInterest(Param& param, const std::string& user, const Name& certName)
+ {
+ shared_ptr interest = generateUnsignedInterest(param, user);
+ m_keyChain.sign(*interest, certName);
+
+ return interest;
+ }
+
+ boost::asio::io_service io;
+ std::string owner;
+ boost::filesystem::path tmpPath;
+ shared_ptr face;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestPib, PibTestFixture)
+
+BOOST_AUTO_TEST_CASE(InitCertTest1)
+{
+ // Create a PIB with full parameters
+ owner = "testUser";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK_EQUAL(pib.getOwner(), owner);
+ BOOST_CHECK_EQUAL(pib.getDb().getOwnerName(), owner);
+
+ auto mgmtCert = pib.getMgmtCert();
+ BOOST_CHECK_EQUAL(mgmtCert.getName().getPrefix(-3),
+ Name("/localhost/pib/testUser/mgmt/KEY"));
+ BOOST_CHECK_EQUAL(mgmtCert.getName().get(5).toUri().substr(0, 4), "dsk-");
+
+ auto mgmtCert2 = pib.getDb().getMgmtCertificate();
+ BOOST_REQUIRE(mgmtCert2 != nullptr);
+ BOOST_CHECK(mgmtCert.wireEncode() == mgmtCert2->wireEncode());
+
+ BOOST_CHECK_EQUAL(pib.getDb().getTpmLocator(), m_keyChain.getTpm().getTpmLocator());
+
+ GetParam param01;
+ shared_ptr interest01 = generateUnsignedInterest(param01, owner);
+
+ face->receive(*interest01);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibUser result01;
+ BOOST_REQUIRE_NO_THROW(result01.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK(result01.getMgmtCert().wireEncode() == mgmtCert.wireEncode());
+ BOOST_CHECK_EQUAL(result01.getTpmLocator(), m_keyChain.getTpm().getTpmLocator());
+}
+
+BOOST_AUTO_TEST_CASE(InitCertTest2)
+{
+ // Create a PIB from a database (assume that the database is configured)
+ std::string dbDir = tmpPath.string();
+ std::string tpmLocator = m_keyChain.getTpm().getTpmLocator();
+ owner = "testUser";
+
+ Name testUser("/localhost/pib/testUser/mgmt");
+
+ addIdentity(testUser);
+ Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+ shared_ptr testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+ PibDb db(tmpPath.string());
+ BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+
+ db.updateMgmtCertificate(*testUserCert);
+ BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+ BOOST_CHECK_THROW(Pib(*face, dbDir, tpmLocator, "wrongUser"), Pib::Error);
+
+ db.setTpmLocator(m_keyChain.getTpm().getTpmLocator());
+ BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+ BOOST_CHECK_THROW(Pib(*face, dbDir, "tpm-file:wrong", owner), Pib::Error);
+
+ advanceClocks(io, time::milliseconds(10));
+ m_keyChain.deleteIdentity(testUser);
+ BOOST_CHECK_NO_THROW(Pib(*face, dbDir, tpmLocator, owner));
+}
+
+BOOST_AUTO_TEST_CASE(InitCertTest3)
+{
+ std::string dbDir = tmpPath.string();
+ std::string tpmLocator = m_keyChain.getTpm().getTpmLocator();
+ owner = "testUser";
+
+ Name testUser("/localhost/pib/testUser/mgmt");
+ addIdentity(testUser);
+ Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+ shared_ptr testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+ Pib pib1(*face, dbDir, tpmLocator, owner);
+ BOOST_CHECK_EQUAL(pib1.getMgmtCert().getName().getPrefix(-3),
+ Name("/localhost/pib/testUser/mgmt/KEY"));
+
+ PibDb db(tmpPath.string());
+ db.updateMgmtCertificate(*testUserCert);
+ Pib pib2(*face, dbDir, tpmLocator, owner);
+ BOOST_CHECK_EQUAL(pib2.getMgmtCert().getName(), testUserCertName);
+
+ advanceClocks(io, time::milliseconds(10));
+ m_keyChain.deleteIdentity(testUser);
+ Pib pib3(*face, dbDir, tpmLocator, owner);
+ BOOST_CHECK(pib3.getMgmtCert().getName() != testUserCertName);
+ BOOST_CHECK_EQUAL(pib3.getMgmtCert().getName().getPrefix(-3),
+ Name("/localhost/pib/testUser/mgmt/KEY"));
+}
+
+BOOST_AUTO_TEST_CASE(GetCommandTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ PibDb db(tmpPath.string());
+
+ Name testId("/test/identity");
+ Name testIdCertName00 = m_keyChain.createIdentity(testId);
+ shared_ptr cert00 = m_keyChain.getCertificate(testIdCertName00);
+ Name testIdKeyName0 = cert00->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert01 = m_keyChain.selfSign(testIdKeyName0);
+ Name testIdCertName01 = cert01->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr cert10 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName10 = cert10->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert11 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName11 = cert11->getName();
+
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+ db.addCertificate(*cert00);
+ db.addCertificate(*cert01);
+ db.addCertificate(*cert10);
+ db.addCertificate(*cert11);
+ db.setDefaultIdentity(testId);
+ db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+ db.setDefaultCertNameOfKey(testIdCertName00);
+
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+
+ // Get Param
+ GetParam param01;
+ shared_ptr interest01 = generateUnsignedInterest(param01, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest01);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest01->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibUser result01;
+ BOOST_REQUIRE_NO_THROW(result01.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK(result01.getMgmtCert().wireEncode() == ownerMgmtCert.wireEncode());
+
+
+ GetParam param02;
+ shared_ptr interest02 = generateUnsignedInterest(param02, "non-existing");
+
+ face->sentDatas.clear();
+ face->receive(*interest02);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest02->getName()) == nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+
+
+ GetParam param03(TYPE_ID, testId);
+ shared_ptr interest03 = generateUnsignedInterest(param03, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest03);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest03->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibIdentity result03;
+ BOOST_REQUIRE_NO_THROW(result03.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result03.getIdentity(), testId);
+
+
+ Name wrongId("/wrong/id");
+ GetParam param04(TYPE_ID, wrongId);
+ shared_ptr interest04 = generateUnsignedInterest(param04, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest04);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest04->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result04;
+ BOOST_REQUIRE_NO_THROW(result04.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result04.getErrorCode(), ERR_NON_EXISTING_ID);
+
+
+ GetParam param05(TYPE_KEY, testIdKeyName1);
+ shared_ptr interest05 = generateUnsignedInterest(param05, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest05);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest05->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibPublicKey result05;
+ BOOST_REQUIRE_NO_THROW(result05.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result05.getKeyName(), testIdKeyName1);
+
+
+ Name wrongKeyName1("/wrong/key/name1");
+ GetParam param06(TYPE_KEY, wrongKeyName1);
+ shared_ptr interest06 = generateUnsignedInterest(param06, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest06);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest06->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result06;
+ BOOST_REQUIRE_NO_THROW(result06.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result06.getErrorCode(), ERR_NON_EXISTING_KEY);
+
+
+ GetParam param07(TYPE_CERT, testIdCertName00);
+ shared_ptr interest07 = generateUnsignedInterest(param07, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest07);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest07->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibCertificate result07;
+ BOOST_REQUIRE_NO_THROW(result07.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result07.getCertificate().getName(), testIdCertName00);
+
+
+ Name wrongCertName1("/wrong/cert/name1");
+ GetParam param08(TYPE_CERT, wrongCertName1);
+ shared_ptr interest08 = generateUnsignedInterest(param08, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest08);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest08->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result08;
+ BOOST_REQUIRE_NO_THROW(result08.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result08.getErrorCode(), ERR_NON_EXISTING_CERT);
+
+
+ Name wrongKeyName2;
+ GetParam param09(TYPE_KEY, wrongKeyName2);
+ shared_ptr interest09 = generateUnsignedInterest(param09, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest09);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest09->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result09;
+ BOOST_REQUIRE_NO_THROW(result09.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result09.getErrorCode(), ERR_WRONG_PARAM);
+}
+
+BOOST_AUTO_TEST_CASE(DefaultCommandTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ PibDb db(tmpPath.string());
+
+ Name testId("/test/identity");
+ Name testIdCertName00 = m_keyChain.createIdentity(testId);
+ shared_ptr cert00 = m_keyChain.getCertificate(testIdCertName00);
+ Name testIdKeyName0 = cert00->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert01 = m_keyChain.selfSign(testIdKeyName0);
+ Name testIdCertName01 = cert01->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr cert10 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName10 = cert10->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert11 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName11 = cert11->getName();
+
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+ db.addCertificate(*cert00);
+ db.addCertificate(*cert01);
+ db.addCertificate(*cert10);
+ db.addCertificate(*cert11);
+ db.setDefaultIdentity(testId);
+ db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+ db.setDefaultCertNameOfKey(testIdCertName00);
+
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+
+ // Default Param
+ DefaultParam param11(TYPE_ID, TYPE_USER);
+ shared_ptr interest11 = generateUnsignedInterest(param11, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest11);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest11->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibIdentity result11;
+ BOOST_REQUIRE_NO_THROW(result11.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result11.getIdentity(), testId);
+
+
+ DefaultParam param13(TYPE_ID, TYPE_ID);
+ shared_ptr interest13 = generateUnsignedInterest(param13, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest13);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest13->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result13;
+ BOOST_REQUIRE_NO_THROW(result13.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result13.getErrorCode(), ERR_WRONG_PARAM);
+
+
+ DefaultParam param14(TYPE_KEY, TYPE_ID, testId);
+ shared_ptr interest14 = generateUnsignedInterest(param14, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest14);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest14->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibPublicKey result14;
+ BOOST_REQUIRE_NO_THROW(result14.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result14.getKeyName(), testIdKeyName0);
+
+
+ DefaultParam param15(TYPE_CERT, TYPE_ID, testId);
+ shared_ptr interest15 = generateUnsignedInterest(param15, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest15);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest15->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibCertificate result15;
+ BOOST_REQUIRE_NO_THROW(result15.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result15.getCertificate().getName(), testIdCertName00);
+
+
+ DefaultParam param16(TYPE_CERT, TYPE_USER);
+ shared_ptr interest16 = generateUnsignedInterest(param16, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest16);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest16->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibCertificate result16;
+ BOOST_REQUIRE_NO_THROW(result16.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result16.getCertificate().getName(), testIdCertName00);
+
+
+ DefaultParam param17(TYPE_CERT, TYPE_KEY, testIdKeyName1);
+ shared_ptr interest17 = generateUnsignedInterest(param17, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest17);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest17->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibCertificate result17;
+ BOOST_REQUIRE_NO_THROW(result17.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result17.getCertificate().getName(), testIdCertName10);
+}
+
+BOOST_AUTO_TEST_CASE(ListCommandTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ PibDb db(tmpPath.string());
+
+ Name testId("/test/identity");
+ Name testIdCertName00 = m_keyChain.createIdentity(testId);
+ shared_ptr cert00 = m_keyChain.getCertificate(testIdCertName00);
+ Name testIdKeyName0 = cert00->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert01 = m_keyChain.selfSign(testIdKeyName0);
+ Name testIdCertName01 = cert01->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr cert10 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName10 = cert10->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert11 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName11 = cert11->getName();
+
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), false);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+ db.addCertificate(*cert00);
+ db.addCertificate(*cert01);
+ db.addCertificate(*cert10);
+ db.addCertificate(*cert11);
+ db.setDefaultIdentity(testId);
+ db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+ db.setDefaultCertNameOfKey(testIdCertName00);
+
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName0), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName00), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName01), true);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName10), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+
+ Name wrongId("/wrong/id");
+
+ // List Param
+ ListParam param21;
+ shared_ptr interest21 = generateUnsignedInterest(param21, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest21);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest21->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibNameList result21;
+ BOOST_REQUIRE_NO_THROW(result21.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result21.getNameList().size(), 1);
+
+
+ ListParam param22(TYPE_ID, testId);
+ shared_ptr interest22 = generateUnsignedInterest(param22, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest22);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest22->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibNameList result22;
+ BOOST_REQUIRE_NO_THROW(result22.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result22.getNameList().size(), 2);
+
+
+ ListParam param23(TYPE_ID, wrongId);
+ shared_ptr interest23 = generateUnsignedInterest(param23, owner);
+
+ face->sentDatas.clear();
+ face->receive(*interest23);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest23->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibNameList result23;
+ BOOST_REQUIRE_NO_THROW(result23.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result23.getNameList().size(), 0);
+}
+
+BOOST_AUTO_TEST_CASE(IsUpdateAllowedTest1)
+{
+ // This test case is to check the access control of local management key
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+
+ UpdateQueryProcessor& pro = pib.m_updateProcessor;
+
+ Name target01("/localhost/pib");
+ Name target02("/localhost/pib/alice/mgmt");
+ Name target03("/localhost/pib/alice/mgmt/ok");
+ Name target04("/localhost/pib/alice");
+ Name target05("/test/id");
+ Name target06("/test/id/ksk-123");
+ Name target07("/test/id/KEY/ksk-123/ID-CERT/version");
+ Name signer01 = pib.getMgmtCert().getName().getPrefix(-1);
+ Name signer02("/localhost/pib/bob/mgmt/KEY/ksk-1234/ID-CERT");
+
+ // TYPE_USER is handled separately, isUpdatedAllowed simply returns false
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_USER, target02, signer01, DEFAULT_OPT_NO), false);
+
+ // Test access control of local management key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target01, signer01, DEFAULT_OPT_NO), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target02, signer01, DEFAULT_OPT_NO), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target03, signer01, DEFAULT_OPT_NO), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target04, signer01, DEFAULT_OPT_NO), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target05, signer01, DEFAULT_OPT_NO), true);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, target05, signer02, DEFAULT_OPT_NO), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, target06, signer01, DEFAULT_OPT_NO), true);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, target06, signer02, DEFAULT_OPT_NO), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, target07, signer01, DEFAULT_OPT_NO), true);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, target07, signer02, DEFAULT_OPT_NO), false);
+}
+
+BOOST_AUTO_TEST_CASE(IsUpdateAllowedTest2)
+{
+ // This test case is to check the access control of regular key
+
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ PibDb db(tmpPath.string());
+
+ UpdateQueryProcessor& pro = pib.m_updateProcessor;
+
+ Name parent("/test");
+ addIdentity(parent);
+ Name parentCertName = m_keyChain.getDefaultCertificateNameForIdentity(parent);
+ shared_ptr parentCert = m_keyChain.getCertificate(parentCertName);
+ Name parentSigner = parentCertName.getPrefix(-1);
+
+ advanceClocks(io, time::milliseconds(100));
+ Name parentKeyName2 = m_keyChain.generateRsaKeyPair(parent);
+ shared_ptr parentCert2 = m_keyChain.selfSign(parentKeyName2);
+ Name parentSigner2 = parentCert2->getName().getPrefix(-1);
+
+ db.addIdentity(parent);
+ db.addKey(parentCert->getPublicKeyName(), parentCert->getPublicKeyInfo());
+ db.addKey(parentCert2->getPublicKeyName(), parentCert2->getPublicKeyInfo());
+ db.setDefaultKeyNameOfIdentity(parentCert->getPublicKeyName());
+ db.addCertificate(*parentCert);
+ db.setDefaultCertNameOfKey(parentCert->getName());
+ db.addCertificate(*parentCert2);
+ db.setDefaultCertNameOfKey(parentCert2->getName());
+
+ Name testId("/test/id");
+ addIdentity(testId);
+ Name certName = m_keyChain.getDefaultCertificateNameForIdentity(testId);
+ shared_ptr testCert = m_keyChain.getCertificate(certName);
+ Name testKeyName = testCert->getPublicKeyName();
+ Name testSigner = certName.getPrefix(-1);
+
+ advanceClocks(io, time::milliseconds(100));
+ Name secondKeyName = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr secondCert = m_keyChain.selfSign(secondKeyName);
+ Name secondCertName = secondCert->getName();
+ Name secondSigner = secondCertName.getPrefix(-1);
+
+ db.addIdentity(testId);
+ db.addKey(testKeyName, testCert->getPublicKeyInfo());
+ db.addKey(secondKeyName, secondCert->getPublicKeyInfo());
+ db.setDefaultKeyNameOfIdentity(testKeyName);
+ db.addCertificate(*testCert);
+ db.setDefaultCertNameOfKey(testCert->getName());
+ db.addCertificate(*secondCert);
+ db.setDefaultCertNameOfKey(secondCert->getName());
+
+ Name nonSigner("/non-signer/KEY/ksk-123/ID-CERT");
+
+ // for target type = TYPE_ID
+ // one cannot add non-child
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, nonSigner, DEFAULT_OPT_NO), false);
+ // parent can add child
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_NO), true);
+ // non-default parent key cannot add a child
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner2, DEFAULT_OPT_NO), false);
+ // only DEFAULT_OPT_NO is allowed if target type is TYPE_ID
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_ID), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_KEY), false);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_ID, testId, parentSigner, DEFAULT_OPT_USER), false);
+
+ // for target type = TYPE_KEY
+ // one can add its own key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_NO),
+ true);
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, testSigner, DEFAULT_OPT_NO),
+ true);
+ // one can set its default key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_ID),
+ true);
+ // non-default key cannot add its own key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, secondSigner, DEFAULT_OPT_NO),
+ false);
+ // non-default key cannot set its default key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, secondSigner, DEFAULT_OPT_ID),
+ false);
+ // one can add its child's key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, parentSigner, DEFAULT_OPT_NO),
+ true);
+ // one can set its child's default key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, parentSigner, DEFAULT_OPT_ID),
+ true);
+ // non-default key cannot add its child's key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, secondKeyName, parentSigner2, DEFAULT_OPT_NO),
+ false);
+ // non-default parent key cannot set its child's default key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, parentSigner2, DEFAULT_OPT_ID),
+ false);
+ // DEFAULT_OPT_KEY is not allowed if target type is TYPE_KEY
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_KEY),
+ false);
+ // DEFAULT_OPT_USER is not allowed if signer is no local management key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_KEY, testKeyName, testSigner, DEFAULT_OPT_USER),
+ false);
+
+ // for target type = TYPE_CERT
+ // one can add its own certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_NO),
+ true);
+ // one can set its own default certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_ID),
+ true);
+ // one can set its own key's default certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_KEY),
+ true);
+ // DEFAULT_OPT_USER is not allowed if signer is no local management key
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, testSigner, DEFAULT_OPT_USER),
+ false);
+ // non-default key can add other key's certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, secondSigner, DEFAULT_OPT_NO),
+ false);
+ // non-default key can add its own certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_NO),
+ true);
+ // one can add its child's certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, parentSigner, DEFAULT_OPT_NO),
+ true);
+ // non-default key cannot add its child's certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, certName, parentSigner2, DEFAULT_OPT_NO),
+ false);
+ // non-default key cannot set add its identity default certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_ID),
+ false);
+ // non-default key can set add its own default certificate
+ BOOST_CHECK_EQUAL(pro.isUpdateAllowed(TYPE_CERT, secondCertName, secondSigner, DEFAULT_OPT_KEY),
+ true);
+}
+
+BOOST_AUTO_TEST_CASE(IsDeleteAllowedTest1)
+{
+ // This test case is to check the access control of local management key
+
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+
+ DeleteQueryProcessor& pro = pib.m_deleteProcessor;
+
+ Name target01("/localhost/pib");
+ Name target02("/localhost/pib/alice/Mgmt");
+ Name target03("/localhost/pib/alice/Mgmt/ok");
+ Name target04("/localhost/pib/alice");
+ Name target05("/test/id");
+ Name target06("/test/id/ksk-123");
+ Name target07("/test/id/KEY/ksk-123/ID-CERT/version");
+ Name signer01 = pib.getMgmtCert().getName().getPrefix(-1);
+ Name signer02("/localhost/pib/bob/Mgmt/KEY/ksk-1234/ID-CERT");
+
+ // TYPE_USER is handled separately
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_USER, target02, signer01), false);
+
+ // Test access control of local management key
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target01, signer01), false);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target02, signer01), false);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target03, signer01), false);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target04, signer01), false);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target05, signer01), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, target06, signer01), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, target07, signer01), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, target05, signer02), false);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, target06, signer02), false);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, target07, signer02), false);
+}
+
+BOOST_AUTO_TEST_CASE(IsDeleteAllowedTest2)
+{
+ // This test case is to check the access control of regular key
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ PibDb db(tmpPath.string());
+ DeleteQueryProcessor& pro = pib.m_deleteProcessor;
+
+ Name parent("/test");
+ addIdentity(parent);
+ Name parentCertName = m_keyChain.getDefaultCertificateNameForIdentity(parent);
+ shared_ptr parentCert = m_keyChain.getCertificate(parentCertName);
+ Name parentSigner = parentCertName.getPrefix(-1);
+
+ advanceClocks(io, time::milliseconds(100));
+ Name parentKeyName2 = m_keyChain.generateRsaKeyPair(parent);
+ shared_ptr parentCert2 = m_keyChain.selfSign(parentKeyName2);
+ Name parentSigner2 = parentCert2->getName().getPrefix(-1);
+
+ db.addIdentity(parent);
+ db.addKey(parentCert->getPublicKeyName(), parentCert->getPublicKeyInfo());
+ db.addKey(parentCert2->getPublicKeyName(), parentCert2->getPublicKeyInfo());
+ db.setDefaultKeyNameOfIdentity(parentCert->getPublicKeyName());
+ db.addCertificate(*parentCert);
+ db.setDefaultCertNameOfKey(parentCert->getName());
+ db.addCertificate(*parentCert2);
+ db.setDefaultCertNameOfKey(parentCert2->getName());
+
+ Name testId("/test/id");
+ addIdentity(testId);
+ Name certName = m_keyChain.getDefaultCertificateNameForIdentity(testId);
+ shared_ptr testCert = m_keyChain.getCertificate(certName);
+ Name testKeyName = testCert->getPublicKeyName();
+ Name testSigner = certName.getPrefix(-1);
+
+ advanceClocks(io, time::milliseconds(100));
+ Name secondKeyName = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr secondCert = m_keyChain.selfSign(secondKeyName);
+ Name secondCertName = secondCert->getName();
+ Name secondSigner = secondCertName.getPrefix(-1);
+
+ db.addIdentity(testId);
+ db.addKey(testKeyName, testCert->getPublicKeyInfo());
+ db.addKey(secondKeyName, secondCert->getPublicKeyInfo());
+ db.setDefaultKeyNameOfIdentity(testKeyName);
+ db.addCertificate(*testCert);
+ db.setDefaultCertNameOfKey(testCert->getName());
+ db.addCertificate(*secondCert);
+ db.setDefaultCertNameOfKey(secondCert->getName());
+
+ Name nonSigner("/non-signer/KEY/ksk-123/ID-CERT");
+
+ // one can delete itself
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, testSigner), true);
+ // parent can delete its child
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, parentSigner), true);
+ // non-default key cannot delete its identity
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, secondSigner), false);
+ // non-default key cannot delete its child
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, testId, parentSigner2), false);
+ // one cannot delete its parent
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_ID, parent, testSigner), false);
+
+ // one can delete its own key
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, testSigner), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, testSigner), true);
+ // parent can delete its child's key
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, parentSigner), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, parentSigner), true);
+ // non-default key cannot delete other key
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, secondSigner), false);
+ // non-default key can delete itself
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, secondKeyName, secondSigner), true);
+ // non-default key cannot delete its child's key
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_KEY, testKeyName, parentSigner2), false);
+
+ // one can delete its own certificate
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, testSigner), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, testSigner), true);
+ // non-default key cannot delete other's certificate
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, secondSigner), false);
+ // non-default key can delete its own certificate
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, secondSigner), true);
+ // parent can delete its child's certificate
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, parentSigner), true);
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, secondCertName, parentSigner), true);
+ // non-default parent cannot delete its child's certificate
+ BOOST_CHECK_EQUAL(pro.isDeleteAllowed(TYPE_CERT, certName, parentSigner2), false);
+}
+
+
+BOOST_AUTO_TEST_CASE(UpdateUserTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+
+ m_keyChain.addCertificate(pib.getMgmtCert());
+
+ PibDb db(tmpPath.string());
+
+ Name bob("/localhost/pib/bob/mgmt");
+ addIdentity(bob);
+ Name bobCertName = m_keyChain.getDefaultCertificateNameForIdentity(bob);
+ shared_ptr bobCert = m_keyChain.getCertificate(bobCertName);
+
+ // signer is correct, but user name is wrong, should fall
+ PibUser pibUser1;
+ pibUser1.setMgmtCert(*bobCert);
+ UpdateParam param1(pibUser1);
+ auto interest1 = generateSignedInterest(param1, owner, db.getMgmtCertificate()->getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest1);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest1->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result;
+ BOOST_REQUIRE_NO_THROW(result.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result.getErrorCode(), ERR_WRONG_PARAM);
+
+ // user name is correct, but signer is wrong, should fail
+ PibUser pibUser2;
+ pibUser2.setMgmtCert(pib.getMgmtCert());
+ UpdateParam param2(pibUser2);
+ auto interest2 = generateSignedInterest(param2, owner, bobCertName);
+
+ face->sentDatas.clear();
+ face->receive(*interest2);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest2->getName()) == nullptr); // verification should fail, no response
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+
+ // update an existing user with a new mgmt key, signed by the old mgmt key.
+ advanceClocks(io, time::milliseconds(100));
+ Name ownerSecondKeyName =
+ m_keyChain.generateRsaKeyPair(Name("/localhost/pib/alice/mgmt"), false);
+ shared_ptr ownerSecondCert = m_keyChain.selfSign(ownerSecondKeyName);
+ m_keyChain.addCertificate(*ownerSecondCert);
+
+ PibUser pibUser3;
+ pibUser3.setMgmtCert(*ownerSecondCert);
+ UpdateParam param3(pibUser3);
+ auto interest3 = generateSignedInterest(param3, owner, db.getMgmtCertificate()->getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest3);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest3->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result3;
+ BOOST_REQUIRE_NO_THROW(result3.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK(db.getMgmtCertificate()->wireEncode() == ownerSecondCert->wireEncode());
+
+ // Add an cert and set it as user default cert.
+ Name testId("/test/id");
+ Name testIdCertName = m_keyChain.createIdentity(testId);
+ shared_ptr testIdCert = m_keyChain.getCertificate(testIdCertName);
+ Name testIdKeyName = testIdCert->getPublicKeyName();
+ UpdateParam updateParam(*testIdCert, DEFAULT_OPT_USER);
+ auto interest4 = generateSignedInterest(updateParam, owner, ownerSecondCert->getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest4);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_REQUIRE(cache.find(interest4->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result4;
+ BOOST_REQUIRE_NO_THROW(result4.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
+
+ BOOST_CHECK(pib.getDb().hasCertificate(testIdCertName));
+ BOOST_CHECK(pib.getDb().hasKey(testIdKeyName));
+ BOOST_CHECK(pib.getDb().hasIdentity(testId));
+
+ BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultCertNameOfKey(testIdKeyName));
+ BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultKeyNameOfIdentity(testId));
+ BOOST_REQUIRE_NO_THROW(pib.getDb().getDefaultIdentity());
+
+ BOOST_CHECK_EQUAL(pib.getDb().getDefaultCertNameOfKey(testIdKeyName), testIdCertName);
+ BOOST_CHECK_EQUAL(pib.getDb().getDefaultKeyNameOfIdentity(testId), testIdKeyName);
+ BOOST_CHECK_EQUAL(pib.getDb().getDefaultIdentity(), testId);
+}
+
+BOOST_AUTO_TEST_CASE(UpdateRegularKeyTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ PibDb db(tmpPath.string());
+
+ Name id0("/test/identity0");
+ Name certName000 = m_keyChain.createIdentity(id0);
+ shared_ptr cert000 = m_keyChain.getCertificate(certName000);
+ Name keyName00 = cert000->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert001 = m_keyChain.selfSign(keyName00);
+ Name certName001 = cert001->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name keyName01 = m_keyChain.generateRsaKeyPair(id0);
+ shared_ptr cert010 = m_keyChain.selfSign(keyName01);
+ Name certName010 = cert010->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert011 = m_keyChain.selfSign(keyName01);
+ Name certName011 = cert011->getName();
+ m_keyChain.addCertificate(*cert010);
+
+ advanceClocks(io, time::milliseconds(100));
+ Name id1("/test/identity1");
+ Name certName100 = m_keyChain.createIdentity(id1);
+ shared_ptr cert100 = m_keyChain.getCertificate(certName100);
+ Name keyName10 = cert100->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert101 = m_keyChain.selfSign(keyName10);
+ Name certName101 = cert101->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name keyName11 = m_keyChain.generateRsaKeyPair(id1);
+ shared_ptr cert110 = m_keyChain.selfSign(keyName11);
+ Name certName110 = cert110->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert111 = m_keyChain.selfSign(keyName11);
+ Name certName111 = cert111->getName();
+ m_keyChain.addCertificate(*cert111);
+
+
+ // Add a cert
+ BOOST_CHECK_EQUAL(db.hasIdentity(id0), false);
+ BOOST_CHECK_EQUAL(db.hasKey(keyName00), false);
+ BOOST_CHECK_EQUAL(db.hasCertificate(certName000), false);
+ UpdateParam param1(*cert000);
+ auto interest1 = generateSignedInterest(param1, owner, ownerMgmtCert.getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest1);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest1->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result1;
+ BOOST_REQUIRE_NO_THROW(result1.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result1.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.hasIdentity(id0), true);
+ BOOST_CHECK_EQUAL(db.hasKey(keyName00), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(certName000), true);
+
+ db.addCertificate(*cert100);
+ BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
+ BOOST_CHECK_EQUAL(db.hasKey(keyName10), true);
+ BOOST_CHECK_EQUAL(db.hasCertificate(certName100), true);
+
+ // Set default
+ BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id0);
+ BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id0), keyName00);
+ BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName00), certName000);
+
+ UpdateParam param2(id1, DEFAULT_OPT_USER);
+ auto interest2 = generateSignedInterest(param2, owner, ownerMgmtCert.getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest2);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest2->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result2;
+ BOOST_REQUIRE_NO_THROW(result2.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result2.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
+
+ db.addCertificate(*cert010);
+ UpdateParam param3(keyName01, cert010->getPublicKeyInfo(), DEFAULT_OPT_ID);
+ auto interest3 = generateSignedInterest(param3, owner, ownerMgmtCert.getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest3);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest3->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result3;
+ BOOST_REQUIRE_NO_THROW(result3.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id0), keyName01);
+
+ db.addCertificate(*cert011);
+ UpdateParam param4(*cert011, DEFAULT_OPT_KEY);
+ auto interest4 = generateSignedInterest(param4, owner, ownerMgmtCert.getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest4);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest4->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result4;
+ BOOST_REQUIRE_NO_THROW(result4.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName01), certName011);
+
+ // add key and certificate using regular keys.
+ BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+ UpdateParam param5(keyName11, cert110->getPublicKeyInfo());
+ auto interest5 = generateSignedInterest(param5, owner, cert100->getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest5);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest5->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result5;
+ BOOST_REQUIRE_NO_THROW(result5.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result5.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+
+ // add cert using its own key which has been added before
+ BOOST_CHECK_EQUAL(db.hasCertificate(cert101->getName()), false);
+ UpdateParam param6(*cert101);
+ auto interest6 = generateSignedInterest(param6, owner, cert100->getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest6);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest6->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result6;
+ BOOST_REQUIRE_NO_THROW(result6.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result6.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.hasCertificate(cert101->getName()), true);
+}
+
+BOOST_AUTO_TEST_CASE(DeleteUserTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ PibDb db(tmpPath.string());
+
+ // Delete user should fail
+ DeleteParam param(Name(), TYPE_USER);
+ auto interest = generateSignedInterest(param, owner, ownerMgmtCert.getName());
+
+ face->receive(*interest);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result;
+ BOOST_REQUIRE_NO_THROW(result.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result.getErrorCode(), ERR_WRONG_PARAM);
+}
+
+BOOST_AUTO_TEST_CASE(DeleteRegularKeyTest)
+{
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+ advanceClocks(io, time::milliseconds(10), 10);
+ util::InMemoryStoragePersistent& cache = pib.getResponseCache();
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ PibDb& db = pib.getDb();
+
+ Name testId("/test/identity");
+ Name testIdCertName00 = m_keyChain.createIdentity(testId);
+ shared_ptr cert00 = m_keyChain.getCertificate(testIdCertName00);
+ Name testIdKeyName0 = cert00->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert01 = m_keyChain.selfSign(testIdKeyName0);
+ Name testIdCertName01 = cert01->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr cert10 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName10 = cert10->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert11 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName11 = cert11->getName();
+ m_keyChain.addCertificate(*cert11);
+
+ db.addCertificate(*cert00);
+ db.addCertificate(*cert01);
+ db.addCertificate(*cert10);
+ db.addCertificate(*cert11);
+ db.setDefaultIdentity(testId);
+ db.setDefaultKeyNameOfIdentity(testIdKeyName0);
+ db.setDefaultCertNameOfKey(testIdCertName00);
+ db.setDefaultCertNameOfKey(testIdCertName10);
+
+ // delete a certificate itself
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), true);
+ DeleteParam param1(testIdCertName11, TYPE_CERT);
+ auto interest1 = generateSignedInterest(param1, owner, testIdCertName11);
+
+ face->sentDatas.clear();
+ face->receive(*interest1);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest1->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result1;
+ BOOST_REQUIRE_NO_THROW(result1.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result1.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.hasCertificate(testIdCertName11), false);
+
+ // delete a key itself
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), true);
+ DeleteParam param2(testIdKeyName1, TYPE_KEY);
+ auto interest2 = generateSignedInterest(param2, owner, testIdCertName11);
+
+ face->sentDatas.clear();
+ face->receive(*interest2);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest2->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result2;
+ BOOST_REQUIRE_NO_THROW(result2.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result2.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.hasKey(testIdKeyName1), false);
+
+ // delete an identity using non-default key, should fail
+ db.addCertificate(*cert11);
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+ DeleteParam param3(testId, TYPE_ID);
+ auto interest3 = generateSignedInterest(param3, owner, testIdCertName11);
+
+ face->sentDatas.clear();
+ face->receive(*interest3);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest3->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result3;
+ BOOST_REQUIRE_NO_THROW(result3.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result3.getErrorCode(), ERR_WRONG_SIGNER);
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), true);
+
+ // delete an identity using identity default key, should succeed
+ DeleteParam param4(testId, TYPE_ID);
+ auto interest4 = generateSignedInterest(param4, owner, testIdCertName00);
+
+ face->sentDatas.clear();
+ face->receive(*interest4);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ BOOST_CHECK(cache.find(interest4->getName()) != nullptr);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ PibError result4;
+ BOOST_REQUIRE_NO_THROW(result4.wireDecode(face->sentDatas[0].getContent().blockFromValue()));
+ BOOST_CHECK_EQUAL(result4.getErrorCode(), ERR_SUCCESS);
+ BOOST_CHECK_EQUAL(db.hasIdentity(testId), false);
+}
+
+BOOST_AUTO_TEST_CASE(ReadCommandTest2)
+{
+ // Read Certificates;
+ owner = "alice";
+
+ Pib pib(*face,
+ tmpPath.string(),
+ m_keyChain.getTpm().getTpmLocator(),
+ owner);
+
+ advanceClocks(io, time::milliseconds(10), 100);
+ auto ownerMgmtCert = pib.getMgmtCert();
+ m_keyChain.addCertificate(ownerMgmtCert);
+
+ Name testId("/test/identity");
+ Name testIdCertName00 = m_keyChain.createIdentity(testId);
+ shared_ptr cert00 = m_keyChain.getCertificate(testIdCertName00);
+ Name testIdKeyName0 = cert00->getPublicKeyName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert01 = m_keyChain.selfSign(testIdKeyName0);
+ Name testIdCertName01 = cert01->getName();
+
+ advanceClocks(io, time::milliseconds(100));
+ Name testIdKeyName1 = m_keyChain.generateRsaKeyPair(testId);
+ shared_ptr cert10 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName10 = cert10->getName();
+ advanceClocks(io, time::milliseconds(100));
+ shared_ptr cert11 = m_keyChain.selfSign(testIdKeyName1);
+ Name testIdCertName11 = cert11->getName();
+
+
+ UpdateParam param00(*cert00);
+ UpdateParam param01(*cert01);
+ UpdateParam param10(*cert10);
+ UpdateParam param11(*cert11);
+ auto interest00 = generateSignedInterest(param00, owner, ownerMgmtCert.getName());
+ auto interest01 = generateSignedInterest(param01, owner, ownerMgmtCert.getName());
+ auto interest10 = generateSignedInterest(param10, owner, ownerMgmtCert.getName());
+ auto interest11 = generateSignedInterest(param11, owner, ownerMgmtCert.getName());
+
+ face->sentDatas.clear();
+ face->receive(*interest00);
+ advanceClocks(io, time::milliseconds(10), 10);
+ face->receive(*interest01);
+ advanceClocks(io, time::milliseconds(10), 10);
+ face->receive(*interest10);
+ advanceClocks(io, time::milliseconds(10), 10);
+ face->receive(*interest11);
+ advanceClocks(io, time::milliseconds(10), 10);
+
+ auto interest1 = make_shared(testIdCertName11);
+ face->sentDatas.clear();
+ face->receive(*interest1);
+ advanceClocks(io, time::milliseconds(10), 10);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ BOOST_CHECK(face->sentDatas[0].wireEncode() == cert11->wireEncode());
+
+ auto interest2 = make_shared(testIdCertName11.getPrefix(-1));
+ face->sentDatas.clear();
+ face->receive(*interest2);
+ advanceClocks(io, time::milliseconds(10), 10);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ BOOST_CHECK_EQUAL(face->sentDatas[0].getName().getPrefix(-1),
+ cert11->getName().getPrefix(-1));
+
+ auto interest3 = make_shared(testIdCertName11.getPrefix(-1));
+ pib.getDb().deleteCertificate(testIdCertName11);
+ face->sentDatas.clear();
+ face->receive(*interest3);
+ advanceClocks(io, time::milliseconds(10), 10);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 1);
+ BOOST_CHECK(face->sentDatas[0].wireEncode() == cert10->wireEncode());
+
+ auto interest4 = make_shared(testIdCertName11);
+ face->sentDatas.clear();
+ face->receive(*interest4);
+ advanceClocks(io, time::milliseconds(10), 10);
+ BOOST_REQUIRE_EQUAL(face->sentDatas.size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/pib/response-cache.t.cpp b/tests/pib/response-cache.t.cpp
new file mode 100644
index 0000000..2653579
--- /dev/null
+++ b/tests/pib/response-cache.t.cpp
@@ -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
+ * .
+ *
+ * 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 = make_shared(dataName);
+
+ Name dataNameNoVersion("/test/data");
+ Name anotherDataName("/test/another");
+
+ BOOST_CHECK_EQUAL(static_cast(cache.find(dataNameNoVersion)), false);
+ BOOST_CHECK_EQUAL(static_cast(cache.find(dataName, true)), false);
+
+ cache.insert(*data);
+
+ BOOST_CHECK(static_cast(cache.find(dataNameNoVersion)));
+ BOOST_CHECK(static_cast(cache.find(dataName, true)));
+ BOOST_CHECK_EQUAL(static_cast(cache.find(anotherDataName)), false);
+ BOOST_CHECK_EQUAL(static_cast(cache.find(anotherDataName, true)), false);
+
+ cache.erase(dataNameNoVersion);
+
+ BOOST_CHECK_EQUAL(static_cast(cache.find(dataNameNoVersion)), false);
+ BOOST_CHECK_EQUAL(static_cast(cache.find(dataName, true)), false);
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
diff --git a/tests/wscript b/tests/wscript
index c67d252..e44f2a4 100644
--- a/tests/wscript
+++ b/tests/wscript
@@ -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,
)
diff --git a/tools/pib/cert-publisher.cpp b/tools/pib/cert-publisher.cpp
new file mode 100644
index 0000000..abcd5a2
--- /dev/null
+++ b/tools/pib/cert-publisher.cpp
@@ -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
+ * .
+ *
+ * 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 identities = m_db.listIdentities();
+
+ for (const auto& identity : identities) {
+ std::vector keyNames = m_db.listKeyNamesOfIdentity(identity);
+
+ for (const auto& key : keyNames) {
+ std::vector 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 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
diff --git a/tools/pib/cert-publisher.hpp b/tools/pib/cert-publisher.hpp
new file mode 100644
index 0000000..052895c
--- /dev/null
+++ b/tools/pib/cert-publisher.hpp
@@ -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
+ * .
+ *
+ * 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
+#include
+
+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 m_registeredPrefixes;
+
+ util::signal::ScopedConnection m_certDeletedConnection;
+ util::signal::ScopedConnection m_certInsertedConnection;
+};
+
+} // namespace pib
+} // namespace ndn
+
+#endif // NDN_PIB_CERT_PUBLISHER_HPP
diff --git a/tools/pib/default-query-processor.cpp b/tools/pib/default-query-processor.cpp
new file mode 100644
index 0000000..4909ea2
--- /dev/null
+++ b/tools/pib/default-query-processor.cpp
@@ -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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "default-query-processor.hpp"
+#include "encoding/pib-encoding.hpp"
+
+#include
+
+namespace ndn {
+namespace pib {
+
+using std::string;
+
+const size_t DefaultQueryProcessor::DEFAULT_QUERY_LENGTH = 5;
+
+DefaultQueryProcessor::DefaultQueryProcessor(PibDb& db)
+ : m_db(db)
+{
+}
+
+std::pair
+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(param.getTargetType()));
+ return std::make_pair(true, error.wireEncode());
+ }
+ }
+}
+
+std::pair
+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(param.getOriginType()));
+ return std::make_pair(true, error.wireEncode());
+ }
+}
+
+std::pair
+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(param.getOriginType()));
+ return std::make_pair(true, error.wireEncode());
+ }
+
+ try {
+ Name keyName = m_db.getDefaultKeyNameOfIdentity(identity);
+ shared_ptr 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
+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(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 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
diff --git a/tools/pib/default-query-processor.hpp b/tools/pib/default-query-processor.hpp
new file mode 100644
index 0000000..1938074
--- /dev/null
+++ b/tools/pib/default-query-processor.hpp
@@ -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
+ * .
+ *
+ * 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
+#include
+
+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
+ operator()(const Interest& interest);
+
+private:
+ std::pair
+ processDefaultIdQuery(const DefaultParam& param);
+
+ std::pair
+ processDefaultKeyQuery(const DefaultParam& param);
+
+ std::pair
+ 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
diff --git a/tools/pib/delete-query-processor.cpp b/tools/pib/delete-query-processor.cpp
new file mode 100644
index 0000000..9174784
--- /dev/null
+++ b/tools/pib/delete-query-processor.cpp
@@ -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
+ * .
+ *
+ * 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
+
+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
+DeleteQueryProcessor::operator()(const Interest& interest)
+{
+ const Name& interestName = interest.getName();
+
+ // handle pib query: /localhost/pib/[UserName]/delete/param/
+ 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(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
+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
+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
+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
diff --git a/tools/pib/delete-query-processor.hpp b/tools/pib/delete-query-processor.hpp
new file mode 100644
index 0000000..3336deb
--- /dev/null
+++ b/tools/pib/delete-query-processor.hpp
@@ -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
+ * .
+ *
+ * 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
+#include
+
+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
+ 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
+ processDeleteIdQuery(const DeleteParam& param, const Name& signerName);
+
+ std::pair
+ processDeleteKeyQuery(const DeleteParam& param, const Name& signerName);
+
+ std::pair
+ 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
diff --git a/tools/pib/encoding/default-param.cpp b/tools/pib/encoding/default-param.cpp
new file mode 100644
index 0000000..015bf19
--- /dev/null
+++ b/tools/pib/encoding/default-param.cpp
@@ -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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "default-param.hpp"
+#include
+#include
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of::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
+size_t
+DefaultParam::wireEncode(EncodingImpl& 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(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(EncodingImpl& block) const;
+
+template size_t
+DefaultParam::wireEncode(EncodingImpl& 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(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(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(m_originType));
+ }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/default-param.hpp b/tools/pib/encoding/default-param.hpp
new file mode 100644
index 0000000..1906954
--- /dev/null
+++ b/tools/pib/encoding/default-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
+ * .
+ *
+ * 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
+
+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
+ size_t
+ wireEncode(EncodingImpl& 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
diff --git a/tools/pib/encoding/delete-param.cpp b/tools/pib/encoding/delete-param.cpp
new file mode 100644
index 0000000..41c8f6a
--- /dev/null
+++ b/tools/pib/encoding/delete-param.cpp
@@ -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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "delete-param.hpp"
+#include
+#include
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of::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
+size_t
+DeleteParam::wireEncode(EncodingImpl& 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(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(EncodingImpl& block) const;
+
+template size_t
+DeleteParam::wireEncode(EncodingImpl& 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(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
diff --git a/tools/pib/encoding/delete-param.hpp b/tools/pib/encoding/delete-param.hpp
new file mode 100644
index 0000000..14d8392
--- /dev/null
+++ b/tools/pib/encoding/delete-param.hpp
@@ -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
+ * .
+ *
+ * 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
+
+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
+ size_t
+ wireEncode(EncodingImpl& 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
diff --git a/tools/pib/encoding/get-param.cpp b/tools/pib/encoding/get-param.cpp
new file mode 100644
index 0000000..ea076f9
--- /dev/null
+++ b/tools/pib/encoding/get-param.cpp
@@ -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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "get-param.hpp"
+#include
+#include
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of::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
+size_t
+GetParam::wireEncode(EncodingImpl& 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(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(EncodingImpl& block) const;
+
+template size_t
+GetParam::wireEncode(EncodingImpl& 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(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(m_targetType));
+ }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/get-param.hpp b/tools/pib/encoding/get-param.hpp
new file mode 100644
index 0000000..39a6c0e
--- /dev/null
+++ b/tools/pib/encoding/get-param.hpp
@@ -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
+ * .
+ *
+ * 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
+
+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
+ size_t
+ wireEncode(EncodingImpl& 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
diff --git a/tools/pib/encoding/list-param.cpp b/tools/pib/encoding/list-param.cpp
new file mode 100644
index 0000000..cb604e6
--- /dev/null
+++ b/tools/pib/encoding/list-param.cpp
@@ -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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "list-param.hpp"
+#include
+#include
+
+namespace ndn {
+namespace pib {
+
+static_assert(std::is_base_of::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
+size_t
+ListParam::wireEncode(EncodingImpl& 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(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(EncodingImpl& block) const;
+
+template size_t
+ListParam::wireEncode(EncodingImpl& 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(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(m_originType));
+ }
+}
+
+} // namespace pib
+} // namespace ndn
diff --git a/tools/pib/encoding/list-param.hpp b/tools/pib/encoding/list-param.hpp
new file mode 100644
index 0000000..f94732e
--- /dev/null
+++ b/tools/pib/encoding/list-param.hpp
@@ -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
+ * .
+ *
+ * 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
+
+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
+ size_t
+ wireEncode(EncodingImpl& 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
diff --git a/tools/pib/encoding/pib-common.hpp b/tools/pib/encoding/pib-common.hpp
new file mode 100644
index 0000000..74c5daf
--- /dev/null
+++ b/tools/pib/encoding/pib-common.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
+ * .
+ *
+ * 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
diff --git a/tools/pib/encoding/pib-encoding.cpp b/tools/pib/encoding/pib-encoding.cpp
new file mode 100644
index 0000000..e7c5ca4
--- /dev/null
+++ b/tools/pib/encoding/pib-encoding.cpp
@@ -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
+ * .
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "pib-encoding.hpp"
+#include
+#include
+#include
+#include
+
+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
+size_t
+PibIdentity::wireEncode(EncodingImpl& 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(EncodingImpl& block) const;
+
+template size_t
+PibIdentity::wireEncode