From 63fc7b9362f9355adec9cd50f59834e3d2553945 Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Tue, 2 May 2023 23:08:35 +0000 Subject: [PATCH 1/8] add segmentation support for decryption key --- examples/run-examples.sh | 6 ++-- src/attribute-authority.cpp | 69 +++++++++++++++++++++++-------------- src/attribute-authority.hpp | 5 +++ src/consumer.cpp | 33 +++++++++--------- 4 files changed, 70 insertions(+), 43 deletions(-) diff --git a/examples/run-examples.sh b/examples/run-examples.sh index 91ea664..0710f73 100644 --- a/examples/run-examples.sh +++ b/examples/run-examples.sh @@ -6,8 +6,10 @@ if ndnsec list | grep "/example/consumer\|/example/aa\|/example/producer" then - echo "Make sure you do not have identity /example/consumer, /example/aa, /example/producer in the keychain before try again" - exit 1 + echo "cleaning example identities" + ndnsec delete /example/consumer + ndnsec delete /example/aa + ndnsec delete /example/producer fi export NDN_LOG=*=INFO diff --git a/src/attribute-authority.cpp b/src/attribute-authority.cpp index 3cb9fb3..ffd34d0 100644 --- a/src/attribute-authority.cpp +++ b/src/attribute-authority.cpp @@ -23,12 +23,13 @@ #include "algo/abe-support.hpp" #include "ndn-crypto/data-enc-dec.hpp" -#include #include namespace ndn { namespace nacabe { +#define MAX_SEGMENT_SIZE 1500 + NDN_LOG_INIT(nacabe.AttributeAuthority); AttributeAuthority::AttributeAuthority(const security::Certificate& identityCert, Face& face, @@ -77,31 +78,49 @@ AttributeAuthority::~AttributeAuthority() = default; void AttributeAuthority::onDecryptionKeyRequest(const Interest& request) { - // naming: /AA-prefix/DKEY/ - NDN_LOG_INFO("Got DKEY request: " << request.getName()); - Name keyName(request.getName().at(m_cert.getIdentity().size() + 1).blockFromValue()); - NDN_LOG_DEBUG("KeyName --------> " << keyName); - Name identityName = security::extractIdentityFromKeyName(keyName); - - // verify request and generate token - auto optionalCert = m_trustConfig.findCertificate(identityName); - if (!optionalCert) { - NDN_LOG_INFO("DKEY Request Interest cannot be authenticated: no certificate for " << identityName); - return; + // naming1: /AA-prefix/DKEY/ + // naming2: /AA-prefix/DKEY/// + Name requestName = request.getName(); + NDN_LOG_INFO("Got DKEY request: " << requestName); + + Name supposedKeyName(request.getName().at(m_cert.getIdentity().size() + 1).blockFromValue()); + if (requestName.at(-1).isSegment() && requestName.at(-2).isVersion()) { + auto mapIterator = m_segmentMap.find(requestName.getPrefix(-2)); + if (mapIterator != m_segmentMap.end()) { + for (auto data : mapIterator->second) { + if (requestName == data->getName()) { + m_face.put(*data); + } + } + } + } + else if (security::isValidKeyName(supposedKeyName)) { + NDN_LOG_DEBUG("KeyName --------> " << supposedKeyName); + Name identityName = security::extractIdentityFromKeyName(supposedKeyName); + // verify request and generate token + auto optionalCert = m_trustConfig.findCertificate(identityName); + if (!optionalCert) { + NDN_LOG_INFO("DKEY Request Interest cannot be authenticated: no certificate for " << identityName); + return; + } + NDN_LOG_INFO("Find consumer(decryptor) certificate: " << optionalCert->getName()); + auto ABEPrvKey = getPrivateKey(identityName); + auto prvBuffer = ABEPrvKey.toBuffer(); + + // prepare segments + Data result; + Name resultName = Name(request.getName()).appendVersion(); + result.setName(resultName); + result.setFreshnessPeriod(5_s); + Block dkBlock = encryptDataContentWithCK(prvBuffer, optionalCert->getPublicKey()); + span dkSpan = make_span(dkBlock.data(), dkBlock.size()); + auto dkSegments = m_segmenter.segment(dkSpan, resultName, MAX_SEGMENT_SIZE, 4_s); + m_segmentMap.emplace(resultName, dkSegments); + m_face.put(*dkSegments.at(0)); + } + else { + // ignore } - NDN_LOG_INFO("Find consumer(decryptor) certificate: " << optionalCert->getName()); - - auto ABEPrvKey = getPrivateKey(identityName); - auto prvBuffer = ABEPrvKey.toBuffer(); - - // reply interest with encrypted private key - Data result; - Name resultName = Name(request.getName()).appendVersion(); - result.setName(resultName); - result.setFreshnessPeriod(5_s); - result.setContent(encryptDataContentWithCK(prvBuffer, optionalCert->getPublicKey())); - m_keyChain.sign(result, signingByCertificate(m_cert)); - m_face.put(result); } void diff --git a/src/attribute-authority.hpp b/src/attribute-authority.hpp index 82b8b79..ee77077 100644 --- a/src/attribute-authority.hpp +++ b/src/attribute-authority.hpp @@ -29,6 +29,9 @@ #include #include +#include +#include + namespace ndn { namespace nacabe { @@ -56,6 +59,8 @@ class AttributeAuthority : noncopyable Face& m_face; KeyChain& m_keyChain; TrustConfig m_trustConfig; + std::map>> m_segmentMap; + util::Segmenter m_segmenter{m_keyChain, signingByCertificate(m_cert)}; PUBLIC_WITH_TESTS_ELSE_PROTECTED: AbeType m_abeType; diff --git a/src/consumer.cpp b/src/consumer.cpp index 1dccd43..aba8e1b 100644 --- a/src/consumer.cpp +++ b/src/consumer.cpp @@ -24,6 +24,7 @@ #include "ndn-crypto/data-enc-dec.hpp" #include +#include namespace ndn { namespace nacabe { @@ -62,20 +63,20 @@ Consumer::obtainDecryptionKey() interest.setMustBeFresh(true); interest.setCanBePrefix(true); - m_face.expressInterest(interest, - [this] (auto&&, const Data& keyData) { - NDN_LOG_INFO(m_cert.getIdentity() << " get decrypt key data"); - auto prvBlock = decryptDataContent(keyData.getContent(), m_keyChain.getTpm(), m_cert.getName()); - algo::PrivateKey prv; - prv.fromBuffer(Buffer(prvBlock.data(), prvBlock.size())); - m_keyCache = prv; - }, - [this] (auto&&, const auto& nack) { - NDN_LOG_INFO("Nack for " << m_cert.getIdentity() << " decrypt key data with reason " << nack.getReason()); - }, - [this] (auto&&) { - NDN_LOG_INFO("Timeout for " << m_cert.getIdentity() << " decrypt key data"); - }); + auto fetcher = util::SegmentFetcher::start(m_face, interest, m_validator); + fetcher->afterSegmentValidated.connect([](Data data) { + NDN_LOG_DEBUG("Validated " << data.getName()); + }); + fetcher->onComplete.connect([this] (ConstBufferPtr contentBuffer) { + NDN_LOG_DEBUG("SegmentFetcher completed with total fetched size of " << contentBuffer->size()); + auto prvBlock = decryptDataContent(Block(contentBuffer), m_keyChain.getTpm(), m_cert.getName()); + algo::PrivateKey prv; + prv.fromBuffer(Buffer(prvBlock.data(), prvBlock.size())); + m_keyCache = prv; + }); + fetcher->onError.connect([] (uint32_t errorCode, const std::string& errorMsg) { + NDN_LOG_ERROR("Error occurs in segment fetching: " << errorMsg); + }); } bool @@ -121,11 +122,11 @@ Consumer::consume(const Interest& dataInterest, auto dataCallback = [this, consumptionCb, errorCallback] (const Interest&, const Data& data) { m_validator.validate(data, [this, consumptionCb, errorCallback] (const Data& data) { - NDN_LOG_INFO("Decryption key conforms to trust schema"); + NDN_LOG_INFO("Encrypted data conforms to trust schema"); decryptContent(data, consumptionCb, errorCallback); }, [] (auto&&, const ndn::security::ValidationError& error) { - NDN_THROW(std::runtime_error("Fetched decryption key cannot be authenticated: " + error.getInfo())); + NDN_THROW(std::runtime_error("Encrypted data cannot be authenticated: " + error.getInfo())); } ); }; From 1012cb62f06488f879bfd34f1243728a6579426d Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Tue, 2 May 2023 23:51:21 +0000 Subject: [PATCH 2/8] seg: fix bug and parateramize mss --- src/attribute-authority.cpp | 14 +++++++------- src/attribute-authority.hpp | 6 ++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/attribute-authority.cpp b/src/attribute-authority.cpp index ffd34d0..35d3011 100644 --- a/src/attribute-authority.cpp +++ b/src/attribute-authority.cpp @@ -28,16 +28,15 @@ namespace ndn { namespace nacabe { -#define MAX_SEGMENT_SIZE 1500 - NDN_LOG_INIT(nacabe.AttributeAuthority); AttributeAuthority::AttributeAuthority(const security::Certificate& identityCert, Face& face, - KeyChain& keyChain, const AbeType& abeType) + KeyChain& keyChain, const AbeType& abeType, size_t maxSegmentSize) : m_cert(identityCert) , m_face(face) , m_keyChain(keyChain) , m_abeType(abeType) + , m_maxSegmentSize(maxSegmentSize) { // ABE setup if (m_abeType == ABE_TYPE_CP_ABE) { @@ -85,7 +84,7 @@ AttributeAuthority::onDecryptionKeyRequest(const Interest& request) Name supposedKeyName(request.getName().at(m_cert.getIdentity().size() + 1).blockFromValue()); if (requestName.at(-1).isSegment() && requestName.at(-2).isVersion()) { - auto mapIterator = m_segmentMap.find(requestName.getPrefix(-2)); + auto mapIterator = m_segmentMap.find(requestName.getPrefix(-1)); if (mapIterator != m_segmentMap.end()) { for (auto data : mapIterator->second) { if (requestName == data->getName()) { @@ -114,7 +113,8 @@ AttributeAuthority::onDecryptionKeyRequest(const Interest& request) result.setFreshnessPeriod(5_s); Block dkBlock = encryptDataContentWithCK(prvBuffer, optionalCert->getPublicKey()); span dkSpan = make_span(dkBlock.data(), dkBlock.size()); - auto dkSegments = m_segmenter.segment(dkSpan, resultName, MAX_SEGMENT_SIZE, 4_s); + // the freshness period should be configurable, but this value shouldn't affect much + auto dkSegments = m_segmenter.segment(dkSpan, resultName, m_maxSegmentSize, 4_s); m_segmentMap.emplace(resultName, dkSegments); m_face.put(*dkSegments.at(0)); } @@ -176,8 +176,8 @@ CpAttributeAuthority::getPrivateKey(Name identityName) } KpAttributeAuthority::KpAttributeAuthority(const security::Certificate& identityCert, - Face& face, KeyChain& keyChain) - : AttributeAuthority(identityCert, face, keyChain, ABE_TYPE_KP_ABE) + Face& face, KeyChain& keyChain, size_t maxSegmentSize) + : AttributeAuthority(identityCert, face, keyChain, ABE_TYPE_KP_ABE, maxSegmentSize) { } diff --git a/src/attribute-authority.hpp b/src/attribute-authority.hpp index ee77077..09b6e49 100644 --- a/src/attribute-authority.hpp +++ b/src/attribute-authority.hpp @@ -39,7 +39,8 @@ class AttributeAuthority : noncopyable { protected: AttributeAuthority(const security::Certificate& identityCert, Face& m_face, - KeyChain& keyChain, const AbeType& abeType); + KeyChain& keyChain, const AbeType& abeType, + size_t maxSegmentSize = 1500); virtual ~AttributeAuthority(); @@ -59,6 +60,7 @@ class AttributeAuthority : noncopyable Face& m_face; KeyChain& m_keyChain; TrustConfig m_trustConfig; + ssize_t m_maxSegmentSize; std::map>> m_segmentMap; util::Segmenter m_segmenter{m_keyChain, signingByCertificate(m_cert)}; @@ -109,7 +111,7 @@ class CpAttributeAuthority: public AttributeAuthority class KpAttributeAuthority: public AttributeAuthority { public: - KpAttributeAuthority(const security::Certificate& identityCert, Face& m_face, KeyChain& keyChain); + KpAttributeAuthority(const security::Certificate& identityCert, Face& m_face, KeyChain& keyChain, size_t maxSegmentSize = 1500); /** * @brief Add a new policy into the state. From 54addd7c6504f79e492e6b73190b35243e8360dc Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Wed, 3 May 2023 00:02:51 +0000 Subject: [PATCH 3/8] doc: update readme --- README.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index eb7dba5..b36c0da 100644 --- a/README.md +++ b/README.md @@ -113,15 +113,8 @@ To run tests, you must have `-DHAVE_TESTS=True` when you config the project. To run example, you must have `-DBUILD_EXAMPLES=True` when you config the project. ```bash -# in the build directory of NAC-ABE -#run all the tests (including integrate test) -ndnsec key-gen -t r /consumerPrefix1 -ndnsec key-gen /aaPrefix -ndnsec key-gen /producerPrefix - -./examples/kp-aa-example & -./examples/kp-producer-example & -./examples/kp-consumer-example +# in the examples directory of NAC-ABE +bash run-examples.sh ../build ``` ## 3 Documentation From 3dc7749ae6cc6b0a0847c6605b85dd24816a2016 Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Wed, 3 May 2023 14:52:21 -0700 Subject: [PATCH 4/8] cmake: requires ndn-cxx>=0.8.1 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb2a770..2ca9182 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ endif(HAVE_TESTS) # dependencies find_package(PkgConfig REQUIRED) -pkg_check_modules(NDN_CXX REQUIRED libndn-cxx) +pkg_check_modules(NDN_CXX REQUIRED libndn-cxx>=0.8.1) find_package(OpenSSL REQUIRED) find_library(openabe NAMES openabe REQUIRED) From debd6c59aee3963f0c63fd72cb5535b9b350c8dd Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Wed, 10 May 2023 02:51:28 +0000 Subject: [PATCH 5/8] build: move to C++17 --- CMakeLists.txt | 2 +- src/trust-config.cpp | 4 ++-- src/trust-config.hpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ca9182..ae3d263 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ project(nac-abe DESCRIPTION "NDN Name-based access control - attribute based encryption library") # flags -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) if (HAVE_TESTS) add_compile_definitions(HAVE_TESTS) diff --git a/src/trust-config.cpp b/src/trust-config.cpp index 98e826a..3d68398 100644 --- a/src/trust-config.cpp +++ b/src/trust-config.cpp @@ -68,7 +68,7 @@ TrustConfig::addOrUpdateCertificate(const security::Certificate& certificate) } } -optional +std::optional TrustConfig::findCertificate(const Name& identityName) const { auto search = m_knownIdentities.find(identityName); @@ -76,7 +76,7 @@ TrustConfig::findCertificate(const Name& identityName) const return make_optional(search->second); } else { - return nullopt; + return std::nullopt; } } diff --git a/src/trust-config.hpp b/src/trust-config.hpp index e71830d..61fc9f5 100644 --- a/src/trust-config.hpp +++ b/src/trust-config.hpp @@ -37,7 +37,7 @@ class TrustConfig void addOrUpdateCertificate(const security::Certificate& certificate); - optional + std::optional findCertificate(const Name& identityName) const; private: From c43dbb17877368eb806d0051dc95451b0789fbe3 Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Wed, 10 May 2023 03:29:15 +0000 Subject: [PATCH 6/8] ci: disable openabe test build --- .github/workflows/cmake.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index fd1a49a..f75dea9 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -169,7 +169,8 @@ jobs: ln -sf /usr/local/opt/openssl@1.1/include/openssl /usr/local/include ln -sf /usr/local/opt/openssl@1.1/lib/lib* /usr/local/lib NO_DEPS=1 BISON="$(brew --prefix bison)/bin/bison" make - make test + # test is no longer compliable after b8f9d3c8a2620c1185ca972248f7af39c1eae68c + # make test sudo -E make install cd ../NAC-ABE env: From 9c1741e6f66026034b7707c76808ccf1e33e10ea Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Wed, 10 May 2023 03:36:01 +0000 Subject: [PATCH 7/8] ci: disable openabe test build for ubuntu --- .github/workflows/cmake.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index f75dea9..548c9b7 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -55,7 +55,8 @@ jobs: cd ../.. NO_DEPS=1 BISON=$(which bison) make - make test + # test is no longer compliable after b8f9d3c8a2620c1185ca972248f7af39c1eae68c + # make test sudo -E make install cd ../NAC-ABE From 8fad640d483e4203f27c187c15512f0aa73d078b Mon Sep 17 00:00:00 2001 From: Tianyuan Yu Date: Tue, 9 May 2023 21:39:50 -0700 Subject: [PATCH 8/8] trust-config: using cpp optional --- src/trust-config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/trust-config.cpp b/src/trust-config.cpp index 3d68398..dae5e1e 100644 --- a/src/trust-config.cpp +++ b/src/trust-config.cpp @@ -73,7 +73,7 @@ TrustConfig::findCertificate(const Name& identityName) const { auto search = m_knownIdentities.find(identityName); if (search != m_knownIdentities.end()) { - return make_optional(search->second); + return search->second; } else { return std::nullopt;