blob: 36964acce790b31b86dcaeccad15d437050ffbe2 [file] [log] [blame]
Yingdi Yu4a557052014-07-09 16:40:37 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shia9181d72017-08-13 16:47:45 +00002/*
Alexander Afanasyev41469752017-01-10 21:51:55 -08003 * Copyright (c) 2013-2017 Regents of the University of California.
Yingdi Yu4a557052014-07-09 16:40:37 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "signature-info.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070023#include "encoding/block-helpers.hpp"
Junxiao Shic2b8d242014-11-04 08:35:29 -070024#include "util/concepts.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070025
Yingdi Yu4a557052014-07-09 16:40:37 -070026namespace ndn {
27
Junxiao Shic2b8d242014-11-04 08:35:29 -070028BOOST_CONCEPT_ASSERT((boost::EqualityComparable<SignatureInfo>));
29BOOST_CONCEPT_ASSERT((WireEncodable<SignatureInfo>));
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070030BOOST_CONCEPT_ASSERT((WireEncodableWithEncodingBuffer<SignatureInfo>));
Junxiao Shic2b8d242014-11-04 08:35:29 -070031BOOST_CONCEPT_ASSERT((WireDecodable<SignatureInfo>));
32static_assert(std::is_base_of<tlv::Error, SignatureInfo::Error>::value,
33 "SignatureInfo::Error must inherit from tlv::Error");
34
Yingdi Yu4a557052014-07-09 16:40:37 -070035SignatureInfo::SignatureInfo()
36 : m_type(-1)
37 , m_hasKeyLocator(false)
38{
39}
40
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060041SignatureInfo::SignatureInfo(tlv::SignatureTypeValue type)
Yingdi Yu4a557052014-07-09 16:40:37 -070042 : m_type(type)
43 , m_hasKeyLocator(false)
44{
45}
46
Steve DiBenedetto54ce6682014-07-22 13:22:57 -060047SignatureInfo::SignatureInfo(tlv::SignatureTypeValue type, const KeyLocator& keyLocator)
Yingdi Yu4a557052014-07-09 16:40:37 -070048 : m_type(type)
49 , m_hasKeyLocator(true)
50 , m_keyLocator(keyLocator)
51{
52}
53
54SignatureInfo::SignatureInfo(const Block& block)
55{
56 wireDecode(block);
57}
58
Alexander Afanasyev74633892015-02-08 18:08:46 -080059template<encoding::Tag TAG>
Yingdi Yu4a557052014-07-09 16:40:37 -070060size_t
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070061SignatureInfo::wireEncode(EncodingImpl<TAG>& encoder) const
Yingdi Yu4a557052014-07-09 16:40:37 -070062{
Junxiao Shia9181d72017-08-13 16:47:45 +000063 // SignatureInfo ::= SIGNATURE-INFO-TLV TLV-LENGTH
64 // SignatureType
65 // KeyLocator?
66 // ValidityPeriod? (if present, stored as first item of m_otherTlvs)
67 // other SignatureType-specific sub-elements*
68
Yingdi Yu4a557052014-07-09 16:40:37 -070069 size_t totalLength = 0;
70
Junxiao Shia9181d72017-08-13 16:47:45 +000071 for (auto i = m_otherTlvs.rbegin(); i != m_otherTlvs.rend(); i++) {
Alexander Afanasyev41469752017-01-10 21:51:55 -080072 totalLength += encoder.prependBlock(*i);
Yingdi Yu4a557052014-07-09 16:40:37 -070073 }
74
75 if (m_hasKeyLocator)
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070076 totalLength += m_keyLocator.wireEncode(encoder);
Yingdi Yu4a557052014-07-09 16:40:37 -070077
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070078 totalLength += prependNonNegativeIntegerBlock(encoder, tlv::SignatureType, m_type);
Yingdi Yu4a557052014-07-09 16:40:37 -070079
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070080 totalLength += encoder.prependVarNumber(totalLength);
81 totalLength += encoder.prependVarNumber(tlv::SignatureInfo);
Yingdi Yu4a557052014-07-09 16:40:37 -070082 return totalLength;
83}
84
Davide Pesavento88a0d812017-08-19 21:31:42 -040085NDN_CXX_DEFINE_WIRE_ENCODE_INSTANTIATIONS(SignatureInfo);
Yingdi Yu4a557052014-07-09 16:40:37 -070086
Yingdi Yu4a557052014-07-09 16:40:37 -070087const Block&
88SignatureInfo::wireEncode() const
89{
90 if (m_wire.hasWire())
91 return m_wire;
92
93 EncodingEstimator estimator;
94 size_t estimatedSize = wireEncode(estimator);
95
96 EncodingBuffer buffer(estimatedSize, 0);
97 wireEncode(buffer);
98
99 m_wire = buffer.block();
100 return m_wire;
101}
102
103void
104SignatureInfo::wireDecode(const Block& wire)
105{
Yingdi Yu4a557052014-07-09 16:40:37 -0700106 m_hasKeyLocator = false;
Junxiao Shia9181d72017-08-13 16:47:45 +0000107 m_otherTlvs.clear();
Yingdi Yu4a557052014-07-09 16:40:37 -0700108
109 m_wire = wire;
110 m_wire.parse();
111
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600112 if (m_wire.type() != tlv::SignatureInfo)
Junxiao Shia9181d72017-08-13 16:47:45 +0000113 BOOST_THROW_EXCEPTION(Error("Decoding SignatureInfo, but TLV-TYPE is " + to_string(m_wire.type())));
Yingdi Yu4a557052014-07-09 16:40:37 -0700114
115 Block::element_const_iterator it = m_wire.elements_begin();
116
117 // the first block must be SignatureType
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600118 if (it != m_wire.elements_end() && it->type() == tlv::SignatureType) {
Yingdi Yu4a557052014-07-09 16:40:37 -0700119 m_type = readNonNegativeInteger(*it);
Junxiao Shia9181d72017-08-13 16:47:45 +0000120 ++it;
Yingdi Yu4a557052014-07-09 16:40:37 -0700121 }
122 else
Junxiao Shia9181d72017-08-13 16:47:45 +0000123 BOOST_THROW_EXCEPTION(Error("Missing SignatureType in SignatureInfo"));
Yingdi Yu4a557052014-07-09 16:40:37 -0700124
125 // the second block could be KeyLocator
Steve DiBenedetto54ce6682014-07-22 13:22:57 -0600126 if (it != m_wire.elements_end() && it->type() == tlv::KeyLocator) {
Yingdi Yu4a557052014-07-09 16:40:37 -0700127 m_keyLocator.wireDecode(*it);
128 m_hasKeyLocator = true;
Junxiao Shia9181d72017-08-13 16:47:45 +0000129 ++it;
Yingdi Yu4a557052014-07-09 16:40:37 -0700130 }
131
Junxiao Shia9181d72017-08-13 16:47:45 +0000132 // store SignatureType-specific sub-elements, if any
Yingdi Yu4a557052014-07-09 16:40:37 -0700133 while (it != m_wire.elements_end()) {
Zhiyi Zhang387e57b2016-08-01 18:50:00 -0700134 m_otherTlvs.push_back(*it);
Junxiao Shia9181d72017-08-13 16:47:45 +0000135 ++it;
Yingdi Yu4a557052014-07-09 16:40:37 -0700136 }
137}
138
Junxiao Shia9181d72017-08-13 16:47:45 +0000139void
140SignatureInfo::setSignatureType(tlv::SignatureTypeValue type)
Yingdi Yu4a557052014-07-09 16:40:37 -0700141{
Junxiao Shia9181d72017-08-13 16:47:45 +0000142 m_wire.reset();
143 m_type = type;
144}
145
146const KeyLocator&
147SignatureInfo::getKeyLocator() const
148{
149 if (m_hasKeyLocator)
150 return m_keyLocator;
151 else
152 BOOST_THROW_EXCEPTION(Error("KeyLocator does not exist in SignatureInfo"));
153}
154
155void
156SignatureInfo::setKeyLocator(const KeyLocator& keyLocator)
157{
158 m_wire.reset();
159 m_keyLocator = keyLocator;
160 m_hasKeyLocator = true;
161}
162
163void
164SignatureInfo::unsetKeyLocator()
165{
166 m_wire.reset();
167 m_keyLocator = KeyLocator();
168 m_hasKeyLocator = false;
169}
170
171security::ValidityPeriod
172SignatureInfo::getValidityPeriod() const
173{
174 if (m_otherTlvs.empty() || m_otherTlvs.front().type() != tlv::ValidityPeriod) {
175 BOOST_THROW_EXCEPTION(Error("ValidityPeriod does not exist in SignatureInfo"));
176 }
177
178 return security::ValidityPeriod(m_otherTlvs.front());
179}
180
181void
182SignatureInfo::setValidityPeriod(const security::ValidityPeriod& validityPeriod)
183{
184 unsetValidityPeriod();
185 m_otherTlvs.push_front(validityPeriod.wireEncode());
186}
187
188void
189SignatureInfo::unsetValidityPeriod()
190{
191 if (!m_otherTlvs.empty() && m_otherTlvs.front().type() == tlv::ValidityPeriod) {
192 m_otherTlvs.pop_front();
193 m_wire.reset();
194 }
195}
196
197const Block&
198SignatureInfo::getTypeSpecificTlv(uint32_t type) const
199{
200 for (const Block& block : m_otherTlvs) {
201 if (block.type() == type)
202 return block;
203 }
204
205 BOOST_THROW_EXCEPTION(Error("TLV-TYPE " + to_string(type) + " sub-element does not exist in SignatureInfo"));
206}
207
208void
209SignatureInfo::appendTypeSpecificTlv(const Block& block)
210{
211 m_wire.reset();
212 m_otherTlvs.push_back(block);
213}
214
215bool
216operator==(const SignatureInfo& lhs, const SignatureInfo& rhs)
217{
218 return lhs.m_type == rhs.m_type &&
219 lhs.m_hasKeyLocator == rhs.m_hasKeyLocator &&
220 lhs.m_keyLocator == rhs.m_keyLocator &&
221 lhs.m_otherTlvs == rhs.m_otherTlvs;
Yingdi Yu4a557052014-07-09 16:40:37 -0700222}
223
Alexander Afanasyev41469752017-01-10 21:51:55 -0800224std::ostream&
225operator<<(std::ostream& os, const SignatureInfo& info)
226{
227 os << static_cast<tlv::SignatureTypeValue>(info.getSignatureType());
228 if (info.hasKeyLocator()) {
229 os << " " << info.getKeyLocator();
230 }
231 if (!info.m_otherTlvs.empty()) {
232 os << " { ";
233 for (const auto& block : info.m_otherTlvs) {
234 os << block.type() << " ";
235 }
236 os << "}";
237 }
238 return os;
239}
240
Yingdi Yu4a557052014-07-09 16:40:37 -0700241} // namespace ndn