blob: 2bd8b27af8eafadc1fb9bd6362a9ace977e1c87a [file] [log] [blame]
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento61a80032020-06-08 18:56:32 -04002/*
Davide Pesavento714dba02022-03-17 20:46:28 -04003 * Copyright (c) 2014-2022, Regents of the University of California
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -04004 *
5 * NAC library is free software: you can redistribute it and/or modify it under the
6 * terms of the GNU Lesser General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option) any later version.
8 *
9 * NAC library is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
12 *
13 * You should have received copies of the GNU General Public License and GNU Lesser
14 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
15 * <http://www.gnu.org/licenses/>.
16 *
17 * See AUTHORS.md for complete list of NAC library authors and contributors.
18 */
19
20#include "encrypted-content.hpp"
21
22#include <ndn-cxx/encoding/block-helpers.hpp>
23#include <ndn-cxx/util/concepts.hpp>
Davide Pesaventoc2649492020-12-22 21:43:35 -050024#include <ndn-cxx/util/exception.hpp>
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040025
Davide Pesaventobde084f2022-04-17 00:21:35 -040026namespace ndn::nac {
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040027
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040028BOOST_CONCEPT_ASSERT((WireEncodable<EncryptedContent>));
29BOOST_CONCEPT_ASSERT((WireDecodable<EncryptedContent>));
Davide Pesaventobde084f2022-04-17 00:21:35 -040030static_assert(std::is_base_of_v<ndn::tlv::Error, EncryptedContent::Error>,
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040031 "EncryptedContent::Error must inherit from tlv::Error");
32
33EncryptedContent::EncryptedContent(const Block& block)
34{
35 wireDecode(block);
36}
37
38EncryptedContent&
39EncryptedContent::setPayload(Block payload)
40{
41 m_wire.reset();
42 if (payload.type() != tlv::EncryptedPayload) {
Davide Pesavento714dba02022-03-17 20:46:28 -040043 m_payload = Block(tlv::EncryptedPayload, payload);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040044 }
45 else {
46 m_payload = std::move(payload);
47 }
48 return *this;
49}
50
51EncryptedContent&
52EncryptedContent::setPayload(ConstBufferPtr payload)
53{
54 m_wire.reset();
55 m_payload = Block(tlv::EncryptedPayload, std::move(payload));
56 return *this;
57}
58
59EncryptedContent&
60EncryptedContent::setIv(Block iv)
61{
62 m_wire.reset();
Alexander Afanasyev1a21e102018-06-13 20:33:21 -040063 if (iv.type() != tlv::InitializationVector) {
Davide Pesavento714dba02022-03-17 20:46:28 -040064 m_iv = Block(tlv::InitializationVector, iv);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040065 }
66 else {
67 m_iv = std::move(iv);
68 }
69 return *this;
70}
71
72EncryptedContent&
73EncryptedContent::setIv(ConstBufferPtr iv)
74{
75 m_wire.reset();
Davide Pesavento714dba02022-03-17 20:46:28 -040076 m_iv = Block(tlv::InitializationVector, std::move(iv));
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040077 return *this;
78}
79
80EncryptedContent&
81EncryptedContent::unsetIv()
82{
83 m_wire.reset();
Davide Pesavento714dba02022-03-17 20:46:28 -040084 m_iv = {};
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040085 return *this;
86}
87
88EncryptedContent&
89EncryptedContent::setPayloadKey(Block key)
90{
91 m_wire.reset();
92 if (key.type() != tlv::EncryptedPayloadKey) {
Davide Pesavento714dba02022-03-17 20:46:28 -040093 m_payloadKey = Block(tlv::EncryptedPayloadKey, key);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -040094 }
95 else {
96 m_payloadKey = std::move(key);
97 }
98 return *this;
99}
100
101EncryptedContent&
102EncryptedContent::setPayloadKey(ConstBufferPtr key)
103{
104 m_wire.reset();
105 m_payloadKey = Block(tlv::EncryptedPayloadKey, std::move(key));
106 return *this;
107}
108
109EncryptedContent&
110EncryptedContent::unsetPayloadKey()
111{
112 m_wire.reset();
Davide Pesavento714dba02022-03-17 20:46:28 -0400113 m_payloadKey = {};
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400114 return *this;
115}
116
117EncryptedContent&
118EncryptedContent::setKeyLocator(Name keyLocator)
119{
120 m_wire.reset();
121 m_keyLocator = std::move(keyLocator);
122 return *this;
123}
124
125EncryptedContent&
126EncryptedContent::unsetKeyLocator()
127{
128 m_wire.reset();
Davide Pesavento714dba02022-03-17 20:46:28 -0400129 m_keyLocator = {};
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400130 return *this;
131}
132
133template<encoding::Tag TAG>
134size_t
Davide Pesavento714dba02022-03-17 20:46:28 -0400135EncryptedContent::wireEncode(EncodingImpl<TAG>& encoder) const
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400136{
137 size_t totalLength = 0;
138
Davide Pesavento61a80032020-06-08 18:56:32 -0400139 if (hasKeyLocator()) {
Davide Pesavento714dba02022-03-17 20:46:28 -0400140 totalLength += m_keyLocator.wireEncode(encoder);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400141 }
142
Davide Pesavento61a80032020-06-08 18:56:32 -0400143 if (hasPayloadKey()) {
Davide Pesavento714dba02022-03-17 20:46:28 -0400144 totalLength += prependBlock(encoder, m_payloadKey);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400145 }
146
Davide Pesavento61a80032020-06-08 18:56:32 -0400147 if (hasIv()) {
Davide Pesavento714dba02022-03-17 20:46:28 -0400148 totalLength += prependBlock(encoder, m_iv);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400149 }
150
Davide Pesavento61a80032020-06-08 18:56:32 -0400151 if (m_payload.isValid()) {
Davide Pesavento714dba02022-03-17 20:46:28 -0400152 totalLength += prependBlock(encoder, m_payload);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400153 }
154 else {
Davide Pesaventoc2649492020-12-22 21:43:35 -0500155 NDN_THROW(Error("Required EncryptedPayload is not set on EncryptedContent"));
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400156 }
157
Davide Pesavento714dba02022-03-17 20:46:28 -0400158 totalLength += encoder.prependVarNumber(totalLength);
159 totalLength += encoder.prependVarNumber(tlv::EncryptedContent);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400160 return totalLength;
161}
162
163const Block&
164EncryptedContent::wireEncode() const
165{
166 if (m_wire.hasWire())
167 return m_wire;
168
169 EncodingEstimator estimator;
170 size_t estimatedSize = wireEncode(estimator);
171
172 EncodingBuffer buffer(estimatedSize, 0);
173 wireEncode(buffer);
174
175 m_wire = buffer.block();
176 return m_wire;
177}
178
179void
180EncryptedContent::wireDecode(const Block& wire)
181{
182 if (!wire.hasWire()) {
Davide Pesaventoc2649492020-12-22 21:43:35 -0500183 NDN_THROW(Error("The supplied block does not contain wire format"));
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400184 }
Davide Pesaventobde084f2022-04-17 00:21:35 -0400185 if (wire.type() != tlv::EncryptedContent) {
186 NDN_THROW(Error("EncryptedContent", wire.type()));
187 }
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400188
Davide Pesaventobde084f2022-04-17 00:21:35 -0400189 *this = {};
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400190 m_wire = wire;
191 m_wire.parse();
192
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400193 auto block = m_wire.find(tlv::EncryptedPayload);
194 if (block != m_wire.elements_end()) {
195 m_payload = *block;
196 }
197 else {
Davide Pesaventoc2649492020-12-22 21:43:35 -0500198 NDN_THROW(Error("Required EncryptedPayload not found in EncryptedContent"));
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400199 }
200
Alexander Afanasyev1a21e102018-06-13 20:33:21 -0400201 block = m_wire.find(tlv::InitializationVector);
Alexander Afanasyev0db0feb2018-06-13 20:33:10 -0400202 if (block != m_wire.elements_end()) {
203 m_iv = *block;
204 }
205
206 block = m_wire.find(tlv::EncryptedPayloadKey);
207 if (block != m_wire.elements_end()) {
208 m_payloadKey = *block;
209 }
210
211 block = m_wire.find(tlv::Name);
212 if (block != m_wire.elements_end()) {
213 m_keyLocator.wireDecode(*block);
214 }
215}
216
Davide Pesaventobde084f2022-04-17 00:21:35 -0400217} // namespace ndn::nac