| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /** |
| * Copyright (c) 2014-2015, Regents of the University of California |
| * |
| * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN). |
| * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors. |
| * |
| * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms |
| * of the GNU General Public License as published by the Free Software Foundation, |
| * either version 3 of the License, or (at your option) any later version. |
| * |
| * ndn-group-encrypt 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 General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along with |
| * ndn-group-encrypt, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. |
| * |
| * @author Zhiyi Zhang <dreamerbarrychang@gmail.com> |
| */ |
| |
| #include "group-manager.hpp" |
| #include "encryptor.hpp" |
| #include "encrypted-content.hpp" |
| |
| #include <map> |
| |
| namespace ndn { |
| namespace gep { |
| |
| static const name::Component E_KEY_COMPONENT("E-KEY"); |
| static const name::Component D_KEY_COMPONENT("D-KEY"); |
| static const name::Component READ_COMPONENT("read"); |
| |
| GroupManager::GroupManager(const Name& prefix, const Name& dataType, const std::string& dbDir, |
| const int paramLength, const int freshPeriod) |
| : m_namespace(prefix) |
| , m_db(dbDir) |
| , m_paramLength(paramLength) |
| , m_freshPeriod(freshPeriod) |
| { |
| m_namespace.append(READ_COMPONENT).append(dataType); |
| } |
| |
| std::list<Data> |
| GroupManager::getGroupKey(const TimeStamp& timeslot) |
| { |
| std::map<Name, Buffer> memberKeys; |
| std::list<Data> result; |
| |
| // get time interval |
| Interval finalInterval = calculateInterval(timeslot, memberKeys); |
| if (finalInterval.isValid() == false) |
| return result; |
| |
| std::string startTs = boost::posix_time::to_iso_string(finalInterval.getStartTime()); |
| std::string endTs = boost::posix_time::to_iso_string(finalInterval.getEndTime()); |
| |
| // generate the pri key and pub key |
| Buffer priKeyBuf, pubKeyBuf; |
| generateKeyPairs(priKeyBuf, pubKeyBuf); |
| |
| // add the first element to the result |
| // E-KEY (public key) data packet name convention: |
| // /<data_type>/E-KEY/[start-ts]/[end-ts] |
| Data data = createEKeyData(startTs, endTs, pubKeyBuf); |
| result.push_back(data); |
| |
| // encrypt pri key with pub key from certificate |
| for (const auto& entry : memberKeys) { |
| const Name& keyName = entry.first; |
| const Buffer& certKey = entry.second; |
| |
| // generate the name of the packet |
| // D-KEY (private key) data packet name convention: |
| // /<data_type>/D-KEY/[start-ts]/[end-ts]/[member-name] |
| data = createDKeyData(startTs, endTs, keyName, priKeyBuf, certKey); |
| result.push_back(data); |
| } |
| return result; |
| } |
| |
| void |
| GroupManager::addSchedule(const std::string& scheduleName, const Schedule& schedule) |
| { |
| m_db.addSchedule(scheduleName, schedule); |
| } |
| |
| void |
| GroupManager::deleteSchedule(const std::string& scheduleName) |
| { |
| m_db.deleteSchedule(scheduleName); |
| } |
| |
| void |
| GroupManager::updateSchedule(const std::string& scheduleName, const Schedule& schedule) |
| { |
| m_db.updateSchedule(scheduleName, schedule); |
| } |
| |
| void |
| GroupManager::addMember(const std::string& scheduleName, const Data& memCert) |
| { |
| IdentityCertificate cert(memCert); |
| m_db.addMember(scheduleName, cert.getPublicKeyName(), cert.getPublicKeyInfo().get()); |
| } |
| |
| void |
| GroupManager::removeMember(const Name& identity) |
| { |
| m_db.deleteMember(identity); |
| } |
| |
| void |
| GroupManager::updateMemberSchedule(const Name& identity, const std::string& scheduleName) |
| { |
| m_db.updateMemberSchedule(identity, scheduleName); |
| } |
| |
| Interval |
| GroupManager::calculateInterval(const TimeStamp& timeslot, std::map<Name, Buffer>& memberKeys) |
| { |
| // prepare |
| Interval positiveResult; |
| Interval negativeResult; |
| Interval tempInterval; |
| Interval finalInterval; |
| bool isPositive; |
| memberKeys.clear(); |
| |
| // get the all intervals from schedules |
| for (const std::string& scheduleName : m_db.listAllScheduleNames()) { |
| |
| const Schedule& schedule = m_db.getSchedule(scheduleName); |
| std::tie(isPositive, tempInterval) = schedule.getCoveringInterval(timeslot); |
| |
| if (isPositive) { |
| if (!positiveResult.isValid()) |
| positiveResult = tempInterval; |
| positiveResult && tempInterval; |
| |
| std::map<Name, Buffer> m = m_db.getScheduleMembers(scheduleName); |
| memberKeys.insert(m.begin(), m.end()); |
| } |
| else { |
| if (!negativeResult.isValid()) |
| negativeResult = tempInterval; |
| negativeResult && tempInterval; |
| } |
| } |
| if (!positiveResult.isValid()) { |
| // return invalid interval when there is no member has interval covering the time slot |
| return Interval(false); |
| } |
| |
| // get the final interval result |
| if (negativeResult.isValid()) |
| finalInterval = positiveResult && negativeResult; |
| else |
| finalInterval = positiveResult; |
| |
| return finalInterval; |
| } |
| |
| void |
| GroupManager::generateKeyPairs(Buffer& priKeyBuf, Buffer& pubKeyBuf) const |
| { |
| RandomNumberGenerator rng; |
| RsaKeyParams params(m_paramLength); |
| algo::EncryptParams eparams(tlv::AlgorithmRsaPkcs); |
| DecryptKey<algo::Rsa> privateKey = algo::Rsa::generateKey(rng, params); |
| priKeyBuf = privateKey.getKeyBits(); |
| EncryptKey<algo::Rsa> publicKey = algo::Rsa::deriveEncryptKey(priKeyBuf); |
| pubKeyBuf = publicKey.getKeyBits(); |
| } |
| |
| |
| Data |
| GroupManager::createEKeyData(const std::string& startTs, const std::string& endTs, |
| const Buffer& pubKeyBuf) |
| { |
| Name dataName(m_namespace); |
| dataName.append(E_KEY_COMPONENT).append(startTs).append(endTs); |
| Data data(dataName); |
| data.setFreshnessPeriod(time::hours(m_freshPeriod)); |
| data.setContent(pubKeyBuf.get(), pubKeyBuf.size()); |
| m_keyChain.sign(data); |
| return data; |
| } |
| |
| Data |
| GroupManager::createDKeyData(const std::string& startTs, const std::string& endTs, |
| const Name& keyName, const Buffer& priKeyBuf, |
| const Buffer& certKey) |
| { |
| Name dataName(m_namespace); |
| dataName.append(D_KEY_COMPONENT); |
| dataName.append(startTs).append(endTs).append(keyName.getPrefix(-1)); |
| Data data = Data(dataName); |
| data.setFreshnessPeriod(time::hours(m_freshPeriod)); |
| algo::EncryptParams eparams(tlv::AlgorithmRsaPkcs); |
| algo::encryptData(data, priKeyBuf.buf(), priKeyBuf.size(), keyName, |
| certKey.buf(), certKey.size(), eparams); |
| m_keyChain.sign(data); |
| return data; |
| } |
| |
| } // namespace ndn |
| } // namespace ndn |