23 #include <ndn-cxx/security/signing-helpers.hpp>
24 #include <ndn-cxx/util/logger.hpp>
25 #include <ndn-cxx/util/random.hpp>
29 NDN_LOG_INIT(nac.AccessManager);
32 KeyChain& keyChain, Face& face)
33 : m_identity(identity)
34 , m_keyChain(keyChain)
39 auto nacId = m_keyChain.createIdentity(Name(identity.getName()).append(
NAC).append(dataset), RsaKeyParams());
40 m_nacKey = nacId.getDefaultKey();
41 if (m_nacKey.getKeyType() != KeyType::RSA) {
42 NDN_LOG_INFO(
"Cannot re-use existing KEK/KDK pair, as it is not an RSA key, regenerating");
43 m_nacKey = m_keyChain.createKey(nacId, RsaKeyParams());
45 auto nacKeyId = m_nacKey.getName().at(-1);
47 auto kekPrefix = Name(m_nacKey.getIdentity()).append(
KEK);
49 auto kek = std::make_shared<Data>(m_nacKey.getDefaultCertificate());
50 kek->setName(Name(kekPrefix).append(nacKeyId));
52 m_keyChain.sign(*kek, signingByIdentity(m_identity));
56 auto serveFromIms = [
this] (
const Name&,
const Interest& interest) {
57 auto data = m_ims.find(interest);
58 if (data !=
nullptr) {
59 NDN_LOG_DEBUG(
"Serving " << data->getName() <<
" from InMemoryStorage");
63 NDN_LOG_DEBUG(
"Didn't find data for " << interest.getName());
68 auto handleError = [] (
const Name& prefix,
const std::string& msg) {
69 NDN_LOG_ERROR(
"Failed to register prefix " << prefix <<
": " << msg);
72 m_kekReg = m_face.setInterestFilter(kekPrefix, serveFromIms, handleError);
74 auto kdkPrefix = Name(m_nacKey.getIdentity()).append(
KDK).append(nacKeyId);
75 m_kdkReg = m_face.setInterestFilter(kdkPrefix, serveFromIms, handleError);
81 Name kdkName(m_nacKey.getIdentity());
84 .append(m_nacKey.getName().at(-1))
86 .append(memberCert.getKeyName());
88 const size_t secretLength = 32;
89 uint8_t secret[secretLength + 1];
90 random::generateSecureBytes({secret, secretLength});
92 for (
size_t i = 0; i < secretLength; ++i) {
97 secret[secretLength] = 0;
99 auto kdkData = m_keyChain.exportSafeBag(m_nacKey.getDefaultCertificate(),
100 reinterpret_cast<const char*
>(secret), secretLength);
103 memberKey.loadPkcs8(memberCert.getPublicKey());
107 content.
setPayloadKey(memberKey.encrypt({secret, secretLength}));
109 auto kdk = std::make_shared<Data>(kdkName);
113 m_keyChain.sign(*kdk, signingByIdentity(m_identity));
123 m_ims.erase(Name(m_nacKey.getName()).append(
KDK).append(
ENCRYPTED_BY).append(identity));
AccessManager(const Identity &identity, const Name &dataset, KeyChain &keyChain, Face &face)
Data addMember(const Certificate &memberCert)
Authorize a member identified by its certificate memberCert to decrypt data under the policy.
void removeMember(const Name &identity)
Remove member with name identity from the group.
EncryptedContent & setPayloadKey(Block key)
EncryptedContent & setPayload(Block payload)
size_t wireEncode(EncodingImpl< TAG > &block) const
const name::Component KDK
constexpr time::seconds DEFAULT_KEK_FRESHNESS_PERIOD
constexpr time::seconds DEFAULT_KDK_FRESHNESS_PERIOD
const name::Component ENCRYPTED_BY
const name::Component KEK
const name::Component NAC