encrypted-content.cpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2022, Regents of the University of California
4  *
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>
24 #include <ndn-cxx/util/exception.hpp>
25 
26 namespace ndn::nac {
27 
28 BOOST_CONCEPT_ASSERT((WireEncodable<EncryptedContent>));
29 BOOST_CONCEPT_ASSERT((WireDecodable<EncryptedContent>));
30 static_assert(std::is_base_of_v<ndn::tlv::Error, EncryptedContent::Error>,
31  "EncryptedContent::Error must inherit from tlv::Error");
32 
34 {
35  wireDecode(block);
36 }
37 
40 {
41  m_wire.reset();
42  if (payload.type() != tlv::EncryptedPayload) {
43  m_payload = Block(tlv::EncryptedPayload, payload);
44  }
45  else {
46  m_payload = std::move(payload);
47  }
48  return *this;
49 }
50 
52 EncryptedContent::setPayload(ConstBufferPtr payload)
53 {
54  m_wire.reset();
55  m_payload = Block(tlv::EncryptedPayload, std::move(payload));
56  return *this;
57 }
58 
61 {
62  m_wire.reset();
63  if (iv.type() != tlv::InitializationVector) {
64  m_iv = Block(tlv::InitializationVector, iv);
65  }
66  else {
67  m_iv = std::move(iv);
68  }
69  return *this;
70 }
71 
73 EncryptedContent::setIv(ConstBufferPtr iv)
74 {
75  m_wire.reset();
76  m_iv = Block(tlv::InitializationVector, std::move(iv));
77  return *this;
78 }
79 
82 {
83  m_wire.reset();
84  m_iv = {};
85  return *this;
86 }
87 
90 {
91  m_wire.reset();
92  if (key.type() != tlv::EncryptedPayloadKey) {
93  m_payloadKey = Block(tlv::EncryptedPayloadKey, key);
94  }
95  else {
96  m_payloadKey = std::move(key);
97  }
98  return *this;
99 }
100 
103 {
104  m_wire.reset();
105  m_payloadKey = Block(tlv::EncryptedPayloadKey, std::move(key));
106  return *this;
107 }
108 
111 {
112  m_wire.reset();
113  m_payloadKey = {};
114  return *this;
115 }
116 
119 {
120  m_wire.reset();
121  m_keyLocator = std::move(keyLocator);
122  return *this;
123 }
124 
127 {
128  m_wire.reset();
129  m_keyLocator = {};
130  return *this;
131 }
132 
133 template<encoding::Tag TAG>
134 size_t
135 EncryptedContent::wireEncode(EncodingImpl<TAG>& encoder) const
136 {
137  size_t totalLength = 0;
138 
139  if (hasKeyLocator()) {
140  totalLength += m_keyLocator.wireEncode(encoder);
141  }
142 
143  if (hasPayloadKey()) {
144  totalLength += prependBlock(encoder, m_payloadKey);
145  }
146 
147  if (hasIv()) {
148  totalLength += prependBlock(encoder, m_iv);
149  }
150 
151  if (m_payload.isValid()) {
152  totalLength += prependBlock(encoder, m_payload);
153  }
154  else {
155  NDN_THROW(Error("Required EncryptedPayload is not set on EncryptedContent"));
156  }
157 
158  totalLength += encoder.prependVarNumber(totalLength);
159  totalLength += encoder.prependVarNumber(tlv::EncryptedContent);
160  return totalLength;
161 }
162 
163 const Block&
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 
179 void
181 {
182  if (!wire.hasWire()) {
183  NDN_THROW(Error("The supplied block does not contain wire format"));
184  }
185  if (wire.type() != tlv::EncryptedContent) {
186  NDN_THROW(Error("EncryptedContent", wire.type()));
187  }
188 
189  *this = {};
190  m_wire = wire;
191  m_wire.parse();
192 
193  auto block = m_wire.find(tlv::EncryptedPayload);
194  if (block != m_wire.elements_end()) {
195  m_payload = *block;
196  }
197  else {
198  NDN_THROW(Error("Required EncryptedPayload not found in EncryptedContent"));
199  }
200 
201  block = m_wire.find(tlv::InitializationVector);
202  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 
217 } // namespace ndn::nac
EncryptedContent & setPayloadKey(Block key)
EncryptedContent & unsetPayloadKey()
EncryptedContent & unsetKeyLocator()
EncryptedContent & setPayload(Block payload)
bool hasIv() const noexcept
EncryptedContent & setIv(Block iv)
EncryptedContent & setKeyLocator(Name keyLocator)
const Block & wireEncode() const
EncryptedContent & unsetIv()
void wireDecode(const Block &wire)
bool hasPayloadKey() const noexcept
@ EncryptedContent
Definition: common.hpp:74
@ EncryptedPayload
Definition: common.hpp:75
@ InitializationVector
Definition: common.hpp:76
@ EncryptedPayloadKey
Definition: common.hpp:77