blob: c3cd14ee2b3513a76ac33a997dcfaa4ce1cda253 [file] [log] [blame]
Prashanth Swaminathanb2105902015-08-20 14:28:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2015, Regents of the University of California
4 *
5 * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
6 * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
7 *
8 * ndn-group-encrypt is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-group-encrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-group-encrypt, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Prashanth Swaminathan <prashanthsw@gmail.com>
20 */
21
22#ifndef NDN_GEP_PRODUCER_HPP
23#define NDN_GEP_PRODUCER_HPP
24
25#include "producer-db.hpp"
26
27#include <ndn-cxx/security/key-chain.hpp>
28#include <ndn-cxx/face.hpp>
29
30namespace ndn {
31namespace gep {
32
33// @brief Callback returns vector of Data contains content keys encrypted by E-KEYS
34typedef function<void(const std::vector<Data>&)> ProducerEKeyCallback;
35
36/**
37 * @brief Manage content key and data encryption
38 */
39class Producer
40{
41public:
42 struct KeyInfo {
43 time::system_clock::TimePoint beginTimeslot;
44 time::system_clock::TimePoint endTimeslot;
45 Buffer keyBits;
46 };
47
48 struct KeyRequest {
49 KeyRequest(size_t interests)
50 : interestCount(interests)
51 {}
52 size_t interestCount;
53 std::unordered_map<Name, size_t> repeatAttempts;
54 std::vector<Data> encryptedKeys;
55 };
56
57public:
58 /**
59 * @brief Construct a producer
60 *
61 * A producer can produce data with a naming convention:
62 * /<@p prefix>/SAMPLES/<@p dataType>/[timestamp]
63 *
64 * The produced data packet is encrypted with a content key,
65 * which is stored in a database at @p dbPath.
66 *
67 * A producer also need to produce data containing content key
68 * encrypted with E-KEYs. A producer can retrieve E-KEYs through
69 * @p face, and will re-try for at most @p repeatAttemps times when
70 * E-KEY retrieval fails.
71 */
72 Producer(const Name& prefix, const Name& dataType,
73 Face& face, const std::string& dbPath, uint8_t repeatAttempts = 3);
74
75 /**
76 * @brief Create content key
77 *
78 * This method will first check if the content key exists. For existing
79 * content key, the method will return content key name directly.
80 * If the key does not exist, the method will create one and encrypt
81 * it using corresponding E-KEY. The encrypted content keys will be
82 * passed back through @p callback.
83 */
84 Name
85 createContentKey(const time::system_clock::TimePoint& timeslot,
86 const ProducerEKeyCallback& callback);
87
88 /**
89 * @brief Produce an data packet encrypted using corresponding content key
90 *
91 * This method encrypts @p content with a content key covering
92 * @p timeslot, and set @p data with the encrypted content and
93 * appropriate data name.
94 */
95 void
96 produce(Data& data, const time::system_clock::TimePoint& timeslot,
97 const uint8_t* content, size_t contentLen);
98
99private:
100
101 /**
102 * @brief Sends interest through face with necessary callbacks
103 * Uses @p exclude to limit interest if specified
104 */
105 void
106 sendKeyInterest(const Name& name, const time::system_clock::TimePoint& timeslot,
107 KeyRequest& keyRequest, const ProducerEKeyCallback& callback,
108 const Exclude& timeRange = Exclude());
109
110 /**
111 * @brief Updates state in @p keyRequest on timeout
112 */
113 void
114 handleTimeout(const Interest& interest,
115 const time::system_clock::TimePoint& timeslot,
116 KeyRequest& keyRequest, const ProducerEKeyCallback& callback);
117
118 /**
119 * @brief Checks that encryption key contained in @p data fits @p timeslot
120 * Sends refined interest if required
121 */
122 void
123 handleCoveringKey(const Interest& interest, Data& data,
124 const time::system_clock::TimePoint& timeslot,
125 KeyRequest& keyRequest, const ProducerEKeyCallback& callback);
126
127 /**
128 * @brief Encrypts content key for @p timeslot with @p encryptionKey
129 * Fires @p callback if no more interests to process
130 */
131 void
132 encryptContentKey(KeyRequest& keyRequest, const Buffer& encryptionKey,
133 const Name& eKeyName,
134 const time::system_clock::TimePoint& timeslot,
135 const ProducerEKeyCallback& callback);
136
137private:
138 Face& m_face;
139 Name m_namespace;
140 KeyChain m_keychain;
141 std::unordered_map<Name, KeyInfo> m_ekeyInfo;
142 std::unordered_map<uint64_t, KeyRequest> m_keyRequests;
143 ProducerDB m_db;
144 uint8_t m_maxRepeatAttempts;
145};
146
147} // namespace gep
148} // namespace ndn
149
150#endif // NDN_GEP_PRODUCER_HPP