Skip to content

Commit

Permalink
half-finished to the new design
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhiyi-Zhang committed Sep 29, 2018
1 parent 20cb79e commit 72ace6c
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 92 deletions.
5 changes: 3 additions & 2 deletions src/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ using namespace ndn::tlv;
} // namespace tlv

const ndn::name::Component NAME_COMPONENT_BY("ENC-BY");
const ndn::name::Component NAME_COMPONENT_E_KEY("E-KEY");
const ndn::name::Component NAME_COMPONENT_D_KEY("D-KEY");
const ndn::name::Component NAME_COMPONENT_E_KEY("KEK");
const ndn::name::Component NAME_COMPONENT_D_KEY("KDK");
const ndn::name::Component NAME_COMPONENT_NAC("NAC");

} // namespace nac
} // namespace ndn
Expand Down
34 changes: 31 additions & 3 deletions src/data-enc-dec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@
namespace ndn {
namespace nac {


Block
encryptDataContent(const uint8_t* payload, size_t payloadLen,
const uint8_t* key, size_t keyLen)
encryptDataContentWithCK(const uint8_t* payload, size_t payloadLen,
const uint8_t* key, size_t keyLen)
{
// first create AES key and encrypt the payload
AesKeyParams param;
Expand All @@ -55,6 +54,35 @@ encryptDataContent(const uint8_t* payload, size_t payloadLen,
return content;
}

std::tuple<Block, Block>
encryptDataContent(const uint8_t* payload, size_t payloadLen,
const uint8_t* key, size_t keyLen)
{
// first create AES key and encrypt the payload
AesKeyParams param;
auto aesKey = crypto::Aes::generateKey(param);
auto iv = crypto::Aes::generateIV();
auto encryptedPayload = crypto::Aes::encrypt(aesKey.data(), aesKey.size(),
payload, payloadLen, iv);

// second use RSA key to encrypt the AES key
auto encryptedAesKey = crypto::Rsa::encrypt(key, keyLen, aesKey.data(), aesKey.size());

// create encrypted content block
auto encryptedBlock = makeBinaryBlock(ENCRYPTED_PAYLOAD,
encryptedPayload.data(), encryptedPayload.size());
encryptedBlock.encode();

// create ck block
auto CKBlock = makeEmptyBlock(ENCRYPTED_CK);
CKBlock.push_back(makeBinaryBlock(ENCRYPTED_AES_KEY,
encryptedAesKey.data(), encryptedAesKey.size()));
CKBlock.push_back(makeBinaryBlock(INITIAL_VECTOR,
iv.data(), iv.size()));
CKBlock.encode();
return std::make_tuple(encryptedBlock, CKBlock);
}


Buffer
decryptDataContent(const Block& dataBlock,
Expand Down
10 changes: 8 additions & 2 deletions src/data-enc-dec.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,24 @@
#define NAC_DATA_ENC_DEC_HPP

#include "common.hpp"
#include <tuple>

namespace ndn {
namespace nac {

enum {
ENCRYPTED_PAYLOAD = 630,
ENCRYPTED_AES_KEY = 631,
INITIAL_VECTOR = 632
INITIAL_VECTOR = 632,
ENCRYPTED_CK = 633,
CK_LOCATOR = 634
};


Block
encryptDataContentWithCK(const uint8_t* payload, size_t payloadLen,
const uint8_t* key, size_t keyLen);

std::tuple<Block, Block>
encryptDataContent(const uint8_t* payload, size_t payloadLen,
const uint8_t* key, size_t keyLen);

Expand Down
40 changes: 21 additions & 19 deletions src/owner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "crypto/rsa.hpp"
#include <ndn-cxx/encoding/block-helpers.hpp>
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/util/random.hpp>

namespace ndn {
namespace nac {
Expand All @@ -37,56 +38,57 @@ Owner::Owner(const security::v2::Certificate& identityCert,

shared_ptr<Data>
Owner::generateDecKeyData(const Name& prefix,
const Name& asymmeticKeyName,
const Name& granularity,
const security::v2::Certificate& consumerCert)
{
Buffer encKey = consumerCert.getPublicKey();
Buffer payload;
auto search = m_decKeys.find(asymmeticKeyName);
auto search = m_decKeys.find(granularity);
if (search != m_decKeys.end()) {
payload = m_decKeys[asymmeticKeyName];
payload = m_decKeys[granularity];
}
else {
RsaKeyParams params;
payload = crypto::Rsa::generateKey(params);
m_decKeys[asymmeticKeyName] = payload;
m_encKeys[asymmeticKeyName] = crypto::Rsa::deriveEncryptKey(payload);
m_decKeys[granularity] = payload;
m_encKeys[granularity] = crypto::Rsa::deriveEncryptKey(payload);
}

// Naming Convention: /prefix/consumer-identity/D-KEY/asymmeticKeyName
// Naming Convention: /prefix/NAC/granularity/KDK/<key-id>/ENC-BY
// consumer-identity/KEY/<key-id>
auto dKeyData = make_shared<Data>();
Name name(prefix);
name.append(security::v2::extractIdentityFromCertName(consumerCert.getName()))
.append(NAME_COMPONENT_D_KEY)
.append(asymmeticKeyName);
name.append(NAME_COMPONENT_NAC).append(granularity).append(NAME_COMPONENT_D_KEY)
.append(security::v2::extractKeyNameFromCertName(consumerCert.getName()));
dKeyData->setName(name);
dKeyData->setContent(encryptDataContent(payload.data(), payload.size(),
encKey.data(), encKey.size()));
dKeyData->setContent(encryptDataContentWithCK(payload.data(), payload.size(),
encKey.data(), encKey.size()));
m_keyChain.sign(*dKeyData, signingByCertificate(m_cert));
return dKeyData;
}

shared_ptr<Data>
Owner::generateEncKeyData(const Name& prefix,
const Name& asymmeticKeyName)
const Name& granularity)
{
Buffer payload;
auto search = m_encKeys.find(asymmeticKeyName);
auto search = m_encKeys.find(granularity);
if (search != m_encKeys.end()) {
payload = m_encKeys[asymmeticKeyName];
payload = m_encKeys[granularity];
}
else {
RsaKeyParams params;
auto decKey = crypto::Rsa::generateKey(params);
m_decKeys[asymmeticKeyName] = decKey;
m_encKeys[asymmeticKeyName] = crypto::Rsa::deriveEncryptKey(decKey);
payload = m_encKeys[asymmeticKeyName];
m_decKeys[granularity] = decKey;
m_encKeys[granularity] = crypto::Rsa::deriveEncryptKey(decKey);
payload = m_encKeys[granularity];
}

// Naming Convention: /prefix/E-KEY/asymmeticKeyName
// Naming Convention: /prefix/NAC/granularity/KEK/<key-id>
auto eKeyData = make_shared<Data>();
Name name(prefix);
name.append(NAME_COMPONENT_E_KEY).append(asymmeticKeyName);
name.append(NAME_COMPONENT_NAC).append(granularity)
.append(NAME_COMPONENT_E_KEY).append(std::to_string(random::generateSecureWord32()));;
eKeyData->setName(name);
eKeyData->setContent(makeBinaryBlock(tlv::Content, payload.data(), payload.size()));
m_keyChain.sign(*eKeyData, signingByCertificate(m_cert));
Expand Down
53 changes: 39 additions & 14 deletions src/producer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "producer.hpp"
#include "data-enc-dec.hpp"
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/util/random.hpp>

namespace ndn {
namespace nac {
Expand All @@ -33,38 +34,62 @@ Producer::Producer(const security::v2::Certificate& identityCert,
{
}

shared_ptr<Data>
Producer::produce(const Name& prefix,
std::tuple<shared_ptr<Data>, shared_ptr<Data>>
Producer::produce(const Name& name,
const uint8_t* payload, size_t payloadLen,
const Name& asymmetricKeyName, const Buffer& encryptionKey)
{
// prepare
Block encryptedContent;
Block encryptedCK;
std::tie(encryptedContent, encryptedCK) = encryptDataContent(payload, payloadLen,
encryptionKey.data(),
encryptionKey.size());
Name ckName = security::v2::extractIdentityFromCertName(m_cert.getName());
ckName.append("CK").append(std::to_string(random::generateSecureWord32()));


// data packet
auto data = make_shared<Data>();
Name dataName(prefix);
dataName.append(NAME_COMPONENT_BY).append(asymmetricKeyName);
data->setName(dataName);
data->setContent(encryptDataContent(payload, payloadLen,
encryptionKey.data(), encryptionKey.size()));
data->setName(name);
auto content = makeEmptyBlock(tlv::Content);
auto ckNameBlock = ckName.wireEncode();
content.push_back(ckNameBlock);
content.push_back(encryptedContent);
content.encode();
data->setContent(content);
m_keyChain.sign(*data, signingByCertificate(m_cert));
return data;


// ck data packet
auto ckData = make_shared<Data>();
Name ckDataName = ckName;
ckDataName.append(NAME_COMPONENT_BY).append(asymmetricKeyName);
ckData->setName(ckDataName);
ckData->setContent(encryptedCK);
m_keyChain.sign(*ckData, signingByCertificate(m_cert));
return std::make_tuple(data, ckData);
}

std::tuple<Name, Buffer>
Producer::parseEKeyData(const Data& eKeyData)
{
int index = 0;
// Naming Convention: /prefix/NAC/granularity/KEK/<key-id>

int nac_index = 0;
for (size_t i = 0; i < eKeyData.getName().size(); i++) {
if (eKeyData.getName().get(i) == NAME_COMPONENT_E_KEY) {
index = i;
if (eKeyData.getName().get(i) == NAME_COMPONENT_NAC) {
nac_index = i;
}
}
if (index == 0) {
if (nac_index == 0) {
BOOST_THROW_EXCEPTION(Error("Unrecognized incoming E-KEY Data Name"));
}

Name asymmetricKeyName = eKeyData.getName().getSubName(index + 1);
Name kekName = eKeyData.getName().getSubName(nac_index + 1);
auto content = eKeyData.getContent();
Buffer encKey(content.value(), content.value_size());
return std::make_tuple(asymmetricKeyName, encKey);
return std::make_tuple(kekName, encKey);
}


Expand Down
8 changes: 4 additions & 4 deletions src/producer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ class Producer
/**
* @brief Produce a content Data packet
* @note Naming Convention:
* /prefix/ENC-BY/asymmetricKeyName
* /name
* @note The generated Data packet carries the encrypted payload. The app
* developer should get the E-KEY Data from the data owner and invoke
* Producer::parseEKeyData to get the key name and the key buffer.
* The generated Data packet will be signed with producer's identity cert.
*
* @param prefix The Data packet prefix
* @param name The Data packet name
* @param payload The payload bytes
* @param payloadLen The payload bytes length
* @param asymmetricKeyName The name of D-KEY and E-KEY. Obtained from
Expand All @@ -62,8 +62,8 @@ class Producer
* Obtained from Producer::parseEKeyData.
* @return The generated content Data
*/
shared_ptr<Data>
produce(const Name& prefix,
std::tuple<shared_ptr<Data>, shared_ptr<Data>>
produce(const Name& name,
const uint8_t* payload, size_t payloadLen,
const Name& asymmetricKeyName, const Buffer& encryptionKey);

Expand Down
20 changes: 10 additions & 10 deletions tests/unit-tests/consumer.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ BOOST_AUTO_TEST_CASE(PreparePackets)
auto contentData = producer.produce(Name("/producer/location"), plaintext, sizeof(plaintext),
keyName, keyBuffer);

auto request = Consumer::constructDKeyInterest(*contentData, Name("/owner"), Name("/consumer"));
BOOST_CHECK_EQUAL(request->getName(), Name("/owner/consumer/D-KEY/location/8am/9am"));
// auto request = Consumer::constructDKeyInterest(*contentData, Name("/owner"), Name("/consumer"));
// BOOST_CHECK_EQUAL(request->getName(), Name("/owner/consumer/D-KEY/location/8am/9am"));

auto dKey = Consumer::decryptDKeyData(*dKeyData, consumerPriKey);
auto dKeys = owner.getDecryptionKeys();
auto rightDKey = dKeys[Name("/location/8am/9am")];
BOOST_CHECK_EQUAL_COLLECTIONS(dKey.begin(), dKey.end(),
rightDKey.begin(), rightDKey.end());
// auto dKey = Consumer::decryptDKeyData(*dKeyData, consumerPriKey);
// auto dKeys = owner.getDecryptionKeys();
// auto rightDKey = dKeys[Name("/location/8am/9am")];
// BOOST_CHECK_EQUAL_COLLECTIONS(dKey.begin(), dKey.end(),
// rightDKey.begin(), rightDKey.end());

auto afterDec = Consumer::decryptContentData(*contentData, dKey);
BOOST_CHECK_EQUAL_COLLECTIONS(plaintext, plaintext + sizeof(plaintext),
afterDec.begin(), afterDec.end());
// auto afterDec = Consumer::decryptContentData(*contentData, dKey);
// BOOST_CHECK_EQUAL_COLLECTIONS(plaintext, plaintext + sizeof(plaintext),
// afterDec.begin(), afterDec.end());
}

BOOST_AUTO_TEST_SUITE_END()
Expand Down
4 changes: 2 additions & 2 deletions tests/unit-tests/data-enc-dec.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ BOOST_AUTO_TEST_CASE(EncryptionDecryption)
auto priKey = crypto::Rsa::generateKey(params);
auto pubKey = crypto::Rsa::deriveEncryptKey(priKey);

auto dataBlock = encryptDataContent(plaintext, sizeof(plaintext),
pubKey.data(), pubKey.size());
auto dataBlock = encryptDataContentWithCK(plaintext, sizeof(plaintext),
pubKey.data(), pubKey.size());

Buffer encryptedAesKey(dataBlock.get(ENCRYPTED_AES_KEY).value(),
dataBlock.get(ENCRYPTED_AES_KEY).value_size());
Expand Down
51 changes: 29 additions & 22 deletions tests/unit-tests/owner.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ BOOST_FIXTURE_TEST_SUITE(TestOwner, IdentityManagementTimeFixture)
BOOST_AUTO_TEST_CASE(PreparePackets)
{
RsaKeyParams params;
auto ownerId = addIdentity(Name("/owner"), params);
auto ownerId = addIdentity(Name("/access-controller"));
auto ownerKey = ownerId.getDefaultKey();
auto ownerCert = ownerKey.getDefaultCertificate();

Expand All @@ -47,35 +47,42 @@ BOOST_AUTO_TEST_CASE(PreparePackets)
auto consumerPriKey = crypto::Rsa::generateKey(params);
auto consumerPubKey = crypto::Rsa::deriveEncryptKey(consumerPriKey);
security::v2::Certificate consumerCert;
consumerCert.setName(Name("/consumer/KEY/key001/self/cert001"));
consumerCert.setName(Name("/consumer/KEY/key001/self/001"));
consumerCert.setContent(makeBinaryBlock(tlv::Content,
consumerPubKey.data(), consumerPubKey.size()));
signData(consumerCert);

Owner owner(ownerCert, m_keyChain);
auto dKeyData = owner.generateDecKeyData(Name("/owner"), Name("/location/8am/9am"), consumerCert);
auto eKeyData = owner.generateEncKeyData(Name("/owner"), Name("/location/8am/9am"));
auto dKeyData = owner.generateDecKeyData(Name("/access-controller"), Name("/producer/dataset1/example"), consumerCert);

BOOST_CHECK_EQUAL(dKeyData->getName(),
Name("/owner/consumer/D-KEY/location/8am/9am"));
BOOST_CHECK_EQUAL(eKeyData->getName(),
Name("/owner/E-KEY/location/8am/9am"));
std::cout << "dKeyData Data \n" << *dKeyData;
std::cout << "dKeyData Data size :" << dKeyData->wireEncode().size() << std::endl;
std::cout << "dKeyData Data name size :" << dKeyData->getName().wireEncode().size() << std::endl;
std::cout << "===============================\n";

auto dKey = Consumer::decryptDKeyData(*dKeyData, consumerPriKey);
auto dKeys = owner.getDecryptionKeys();
auto rightDKey = dKeys[Name("/location/8am/9am")];
BOOST_CHECK_EQUAL_COLLECTIONS(dKey.begin(), dKey.end(),
rightDKey.begin(), rightDKey.end());

Producer producer(producerCert, m_keyChain);
Name keyName;
Buffer keyBuffer;
std::tie(keyName, keyBuffer) = producer.parseEKeyData(*eKeyData);
BOOST_CHECK_EQUAL(keyName, Name("/location/8am/9am"));
auto eKeys = owner.getEncryptionKeys();
auto rightEKey = eKeys[keyName];
BOOST_CHECK_EQUAL_COLLECTIONS(rightEKey.begin(), rightEKey.end(),
keyBuffer.begin(), keyBuffer.end());
// auto eKeyData = owner.generateEncKeyData(Name("/access-controller"), Name("/producer/dataset1/example"));

// BOOST_CHECK_EQUAL(dKeyData->getName(),
// Name("/owner/consumer/D-KEY/location/8am/9am"));
// BOOST_CHECK_EQUAL(eKeyData->getName(),
// Name("/owner/E-KEY/location/8am/9am"));

// auto dKey = Consumer::decryptDKeyData(*dKeyData, consumerPriKey);
// auto dKeys = owner.getDecryptionKeys();
// auto rightDKey = dKeys[Name("/location/8am/9am")];
// BOOST_CHECK_EQUAL_COLLECTIONS(dKey.begin(), dKey.end(),
// rightDKey.begin(), rightDKey.end());

// Producer producer(producerCert, m_keyChain);
// Name keyName;
// Buffer keyBuffer;
// std::tie(keyName, keyBuffer) = producer.parseEKeyData(*eKeyData);
// BOOST_CHECK_EQUAL(keyName, Name("/location/8am/9am"));
// auto eKeys = owner.getEncryptionKeys();
// auto rightEKey = eKeys[keyName];
// BOOST_CHECK_EQUAL_COLLECTIONS(rightEKey.begin(), rightEKey.end(),
// keyBuffer.begin(), keyBuffer.end());
}

BOOST_AUTO_TEST_SUITE_END()
Expand Down
Loading

0 comments on commit 72ace6c

Please sign in to comment.