blob: 68d0e9cfe6dfd63170d7c418e497b1fd7f340c75 [file] [log] [blame]
Zhiyi Zhang19a11d22018-04-12 22:58:20 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2018, Regents of the University of California
4 *
5 * This file is part of gep (Group-based Encryption Protocol for NDN).
6 * See AUTHORS.md for complete list of gep authors and contributors.
7 *
8 * gep 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 * gep 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 * gep, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * @author Yingdi Yu <yingdi@cs.ucla.edu>
20 * @author Zhiyi Zhang <zhiyi@cs.ucla.edu>
21 */
22
Prashanthc0029b62015-04-27 14:00:08 -070023#include "encrypted-content.hpp"
24#include <ndn-cxx/encoding/block-helpers.hpp>
25#include <ndn-cxx/util/concepts.hpp>
Prashanthc0029b62015-04-27 14:00:08 -070026#include <boost/lexical_cast.hpp>
27
28namespace ndn {
29namespace gep {
30
31BOOST_CONCEPT_ASSERT((boost::EqualityComparable<EncryptedContent>));
32BOOST_CONCEPT_ASSERT((WireEncodable<EncryptedContent>));
33BOOST_CONCEPT_ASSERT((WireDecodable<EncryptedContent>));
34static_assert(std::is_base_of<ndn::tlv::Error, EncryptedContent::Error>::value,
35 "EncryptedContent::Error must inherit from tlv::Error");
36
37EncryptedContent::EncryptedContent()
38 : m_type(-1)
39 , m_hasKeyLocator(false)
40{
41}
42
Zhiyi Zhang19a11d22018-04-12 22:58:20 -070043EncryptedContent::EncryptedContent(tlv::AlgorithmTypeValue type,
44 const KeyLocator& keyLocator,
45 const uint8_t* payload,
46 size_t payloadLen,
47 const uint8_t* iv,
48 size_t ivLen)
Prashanthc0029b62015-04-27 14:00:08 -070049 : m_type(type)
50 , m_hasKeyLocator(true)
51 , m_keyLocator(keyLocator)
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -070052 , m_payload(payload, payloadLen)
Prashanthc0029b62015-04-27 14:00:08 -070053{
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -070054 if (iv != nullptr && ivLen != 0)
55 m_iv = Buffer(iv, ivLen);
Prashanthc0029b62015-04-27 14:00:08 -070056}
57
58EncryptedContent::EncryptedContent(const Block& block)
59{
60 wireDecode(block);
61}
62
63void
64EncryptedContent::setAlgorithmType(tlv::AlgorithmTypeValue type)
65{
66 m_wire.reset();
67 m_type = type;
68}
69
70void
71EncryptedContent::setKeyLocator(const KeyLocator& keyLocator)
72{
73 m_wire.reset();
74 m_keyLocator = keyLocator;
75 m_hasKeyLocator = true;
76}
77
78const KeyLocator&
79EncryptedContent::getKeyLocator() const
80{
81 if (m_hasKeyLocator)
82 return m_keyLocator;
83 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -070084 BOOST_THROW_EXCEPTION(Error("KeyLocator does not exist"));
Prashanthc0029b62015-04-27 14:00:08 -070085}
86
87void
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -070088EncryptedContent::setInitialVector(const uint8_t* iv, size_t ivLen)
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -070089{
90 m_wire.reset();
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -070091 m_iv = Buffer(iv, ivLen);
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -070092}
93
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -070094const Buffer&
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -070095EncryptedContent::getInitialVector() const
96{
97 return m_iv;
98}
99
100void
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700101EncryptedContent::setPayload(const uint8_t* payload, size_t payloadLen)
Prashanthc0029b62015-04-27 14:00:08 -0700102{
103 m_wire.reset();
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700104 m_payload = Buffer(payload, payloadLen);
Prashanthc0029b62015-04-27 14:00:08 -0700105}
106
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700107const Buffer&
Prashanthc0029b62015-04-27 14:00:08 -0700108EncryptedContent::getPayload() const
109{
110 return m_payload;
111}
112
113template<encoding::Tag TAG>
114size_t
115EncryptedContent::wireEncode(EncodingImpl<TAG>& block) const
116{
117 size_t totalLength = 0;
118
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700119 if (m_payload.size() != 0)
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700120 totalLength +=
121 block.prependByteArrayBlock(tlv::EncryptedPayload, m_payload.data(), m_payload.size());
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -0700122 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700123 BOOST_THROW_EXCEPTION(Error("EncryptedContent does not have a payload"));
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -0700124
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700125 if (m_iv.size() != 0) {
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700126 totalLength += block.prependByteArrayBlock(tlv::InitialVector, m_iv.data(), m_iv.size());
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700127 }
Prashanthc0029b62015-04-27 14:00:08 -0700128
129 if (m_type != -1)
130 totalLength += prependNonNegativeIntegerBlock(block, tlv::EncryptionAlgorithm, m_type);
131 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700132 BOOST_THROW_EXCEPTION(Error("EncryptedContent does not have an encryption algorithm"));
Prashanthc0029b62015-04-27 14:00:08 -0700133
134 if (m_hasKeyLocator)
135 totalLength += m_keyLocator.wireEncode(block);
136 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700137 BOOST_THROW_EXCEPTION(Error("EncryptedContent does not have a key locator"));
Prashanthc0029b62015-04-27 14:00:08 -0700138
139 totalLength += block.prependVarNumber(totalLength);
140 totalLength += block.prependVarNumber(tlv::EncryptedContent);
141 return totalLength;
142}
143
144const Block&
145EncryptedContent::wireEncode() const
146{
147 if (m_wire.hasWire())
148 return m_wire;
149
150 EncodingEstimator estimator;
151 size_t estimatedSize = wireEncode(estimator);
152
153 EncodingBuffer buffer(estimatedSize, 0);
154 wireEncode(buffer);
155
156 m_wire = buffer.block();
157 return m_wire;
158}
159
160void
161EncryptedContent::wireDecode(const Block& wire)
162{
163 if (!wire.hasWire()) {
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700164 BOOST_THROW_EXCEPTION(Error("The supplied block does not contain wire format"));
Prashanthc0029b62015-04-27 14:00:08 -0700165 }
166
167 m_hasKeyLocator = false;
168
169 m_wire = wire;
170 m_wire.parse();
171
172 if (m_wire.type() != tlv::EncryptedContent)
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700173 BOOST_THROW_EXCEPTION(Error("Unexpected TLV type when decoding Name"));
Prashanthc0029b62015-04-27 14:00:08 -0700174
175 Block::element_const_iterator it = m_wire.elements_begin();
176
177 if (it != m_wire.elements_end() && it->type() == ndn::tlv::KeyLocator) {
178 m_keyLocator.wireDecode(*it);
179 m_hasKeyLocator = true;
180 it++;
181 }
182 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700183 BOOST_THROW_EXCEPTION(Error("EncryptedContent does not have key locator"));
Prashanthc0029b62015-04-27 14:00:08 -0700184
185 if (it != m_wire.elements_end() && it->type() == tlv::EncryptionAlgorithm) {
186 m_type = readNonNegativeInteger(*it);
187 it++;
188 }
189 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700190 BOOST_THROW_EXCEPTION(Error("EncryptedContent does not have encryption algorithm"));
Prashanthc0029b62015-04-27 14:00:08 -0700191
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -0700192 if (it != m_wire.elements_end() && it->type() == tlv::InitialVector) {
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700193 m_iv = Buffer(it->value_begin(), it->value_end());
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -0700194 it++;
195 }
196 else
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700197 m_iv = Buffer();
Prashanth Swaminathanb1b95962015-07-06 13:13:08 -0700198
Prashanthc0029b62015-04-27 14:00:08 -0700199 if (it != m_wire.elements_end() && it->type() == tlv::EncryptedPayload) {
Prashanth Swaminathand5b3eae2015-07-09 15:37:05 -0700200 m_payload = Buffer(it->value_begin(), it->value_end());
Prashanthc0029b62015-04-27 14:00:08 -0700201 it++;
202 }
203 else
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700204 BOOST_THROW_EXCEPTION(Error("EncryptedContent has missing payload"));
Prashanthc0029b62015-04-27 14:00:08 -0700205
206 if (it != m_wire.elements_end()) {
Zhiyi Zhang19a11d22018-04-12 22:58:20 -0700207 BOOST_THROW_EXCEPTION(Error("EncryptedContent has extraneous sub-TLVs"));
Prashanthc0029b62015-04-27 14:00:08 -0700208 }
209}
210
211bool
212EncryptedContent::operator==(const EncryptedContent& rhs) const
213{
214 return (wireEncode() == rhs.wireEncode());
215}
216
217} // namespace gep
218} // namespace ndn