Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation Support for Decryption Key #29

Merged
merged 8 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -169,7 +170,8 @@ jobs:
ln -sf /usr/local/opt/[email protected]/include/openssl /usr/local/include
ln -sf /usr/local/opt/[email protected]/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:
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ 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)
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)
Expand Down
11 changes: 2 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions examples/run-examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
75 changes: 47 additions & 28 deletions src/attribute-authority.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "algo/abe-support.hpp"
#include "ndn-crypto/data-enc-dec.hpp"

#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/security/verification-helpers.hpp>

namespace ndn {
Expand All @@ -32,11 +31,12 @@ namespace nacabe {
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) {
Expand Down Expand Up @@ -77,31 +77,50 @@ AttributeAuthority::~AttributeAuthority() = default;
void
AttributeAuthority::onDecryptionKeyRequest(const Interest& request)
{
// naming: /AA-prefix/DKEY/<identity name block>
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/<key name block>
// naming2: /AA-prefix/DKEY/<key name block>/<version>/<segment>
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(-1));
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<const uint8_t> dkSpan = make_span(dkBlock.data(), dkBlock.size());
// 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));
}
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
Expand Down Expand Up @@ -157,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)
{
}

Expand Down
11 changes: 9 additions & 2 deletions src/attribute-authority.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,18 @@
#include <list>
#include <map>

#include <ndn-cxx/util/segmenter.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>

namespace ndn {
namespace nacabe {

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();
Expand All @@ -56,6 +60,9 @@ class AttributeAuthority : noncopyable
Face& m_face;
KeyChain& m_keyChain;
TrustConfig m_trustConfig;
ssize_t m_maxSegmentSize;
std::map<Name, std::vector<std::shared_ptr<Data>>> m_segmentMap;
util::Segmenter m_segmenter{m_keyChain, signingByCertificate(m_cert)};

PUBLIC_WITH_TESTS_ELSE_PROTECTED:
AbeType m_abeType;
Expand Down Expand Up @@ -104,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 <decryptor name, decryptor attributes> into the state.
Expand Down
33 changes: 17 additions & 16 deletions src/consumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "ndn-crypto/data-enc-dec.hpp"

#include <ndn-cxx/security/verification-helpers.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>

namespace ndn {
namespace nacabe {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()));
}
);
};
Expand Down
6 changes: 3 additions & 3 deletions src/trust-config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ TrustConfig::addOrUpdateCertificate(const security::Certificate& certificate)
}
}

optional<security::Certificate>
std::optional<security::Certificate>
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 nullopt;
return std::nullopt;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/trust-config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class TrustConfig
void
addOrUpdateCertificate(const security::Certificate& certificate);

optional<security::Certificate>
std::optional<security::Certificate>
findCertificate(const Name& identityName) const;

private:
Expand Down