1#include <vanetza/security/exception.hpp>
2#include <vanetza/security/v2/header_field.hpp>
3#include <boost/optional.hpp>
4#include <boost/variant/apply_visitor.hpp>
5#include <boost/variant/static_visitor.hpp>
14HeaderFieldType get_type(
const HeaderField& field)
16 struct HeaderFieldVisitor :
public boost::static_visitor<HeaderFieldType>
18 HeaderFieldType operator()(
const Time64&)
20 return HeaderFieldType::Generation_Time;
22 HeaderFieldType operator()(
const Time64WithStandardDeviation&)
24 return HeaderFieldType::Generation_Time_Confidence;
26 HeaderFieldType operator()(
const Time32&)
28 return HeaderFieldType::Expiration;
30 HeaderFieldType operator()(
const ThreeDLocation&)
32 return HeaderFieldType::Generation_Location;
34 HeaderFieldType operator()(
const std::list<HashedId3>&)
36 return HeaderFieldType::Request_Unrecognized_Certificate;
38 HeaderFieldType operator()(
const IntX&)
40 return HeaderFieldType::Its_Aid;
42 HeaderFieldType operator()(
const SignerInfo&)
44 return HeaderFieldType::Signer_Info;
46 HeaderFieldType operator()(
const std::list<RecipientInfo>&)
48 return HeaderFieldType::Recipient_Info;
50 HeaderFieldType operator()(
const EncryptionParameter&)
52 return HeaderFieldType::Encryption_Parameters;
56 HeaderFieldVisitor visit;
57 return boost::apply_visitor(visit, field);
60size_t get_size(
const HeaderField& field)
62 size_t size =
sizeof(HeaderFieldType);
63 struct HeaderFieldVisitor :
public boost::static_visitor<>
65 void operator()(
const Time64&)
67 m_size =
sizeof(Time64);
69 void operator()(
const Time64WithStandardDeviation& time)
71 m_size =
sizeof(time.time64);
72 m_size +=
sizeof(time.log_std_dev);
74 void operator()(
const Time32&)
76 m_size =
sizeof(Time32);
78 void operator()(
const ThreeDLocation& loc)
80 m_size = get_size(loc);
82 void operator()(
const std::list<HashedId3>& list)
85 for (
auto& elem : list) {
86 m_size += elem.size();
88 m_size += length_coding_size(m_size);
90 void operator()(
const IntX& itsAid)
92 m_size = get_size(itsAid);
94 void operator()(
const SignerInfo& info)
96 m_size = get_size(info);
98 void operator()(
const std::list<RecipientInfo>& list)
100 m_size = get_size(list);
101 m_size += length_coding_size(m_size);
103 void operator()(
const EncryptionParameter& enc)
105 m_size = get_size(enc);
110 HeaderFieldVisitor visit;
111 boost::apply_visitor(visit, field);
112 size += visit.m_size;
116void serialize(OutputArchive& ar,
const HeaderField& field)
118 struct HeaderFieldVisitor :
public boost::static_visitor<>
120 HeaderFieldVisitor(OutputArchive& ar) :
124 void operator()(
const Time64& time)
126 serialize(m_archive, host_cast(time));
128 void operator()(
const Time64WithStandardDeviation& time)
130 serialize(m_archive, host_cast(time.time64));
131 serialize(m_archive, host_cast(time.log_std_dev));
133 void operator()(
const Time32& time)
135 serialize(m_archive, host_cast(time));
137 void operator()(
const ThreeDLocation& loc)
139 serialize(m_archive, loc);
141 void operator()(
const std::list<HashedId3>& list)
144 for (
auto& elem : list) {
147 serialize_length(m_archive, size);
148 for (
auto& elem : list) {
149 m_archive << elem[0];
150 m_archive << elem[1];
151 m_archive << elem[2];
154 void operator()(
const IntX& itsAid)
156 serialize(m_archive, itsAid);
158 void operator()(
const SignerInfo& info)
160 serialize(m_archive, info);
162 void operator()(
const std::list<RecipientInfo>& list)
165 serialize(m_archive, list, SymmetricAlgorithm::AES128_CCM);
167 void operator()(
const EncryptionParameter& param)
169 serialize(m_archive, param);
172 OutputArchive& m_archive;
174 HeaderFieldType type = get_type(field);
176 HeaderFieldVisitor visit(ar);
177 boost::apply_visitor(visit, field);
180std::size_t deserialize(InputArchive& ar, std::list<HeaderField>& list)
182 static const std::size_t size_limit = 1024;
183 const std::size_t size = trim_size(deserialize_length(ar));
184 if (size > size_limit) {
185 ar.fail(InputArchive::ErrorCode::ExcessiveLength);
188 std::size_t read = 0;
189 boost::optional<SymmetricAlgorithm> sym_algo;
190 while (read < size && ar.is_good()) {
192 HeaderFieldType type;
193 deserialize(ar, type);
194 read +=
sizeof(HeaderFieldType);
196 case HeaderFieldType::Generation_Time: {
198 deserialize(ar, time);
200 list.push_back(field);
201 read +=
sizeof(Time64);
204 case HeaderFieldType::Generation_Time_Confidence: {
206 deserialize(ar, time.time64);
207 deserialize(ar, time.log_std_dev);
209 list.push_back(field);
210 read +=
sizeof(Time64);
211 read +=
sizeof(uint8_t);
214 case HeaderFieldType::Expiration: {
216 deserialize(ar, time);
218 list.push_back(field);
219 read +=
sizeof(Time32);
222 case HeaderFieldType::Generation_Location: {
224 read += deserialize(ar, loc);
226 list.push_back(field);
229 case HeaderFieldType::Request_Unrecognized_Certificate: {
230 const std::size_t tmp_size = trim_size(deserialize_length(ar));
232 std::list<HashedId3> hashedList;
233 for (std::size_t c = 0; c < tmp_size; c += 3) {
238 hashedList.push_back(
id);
241 read += length_coding_size(tmp_size);
242 list.push_back(field);
245 case HeaderFieldType::Its_Aid: {
247 read += deserialize(ar, its_aid);
249 list.push_back(field);
252 case HeaderFieldType::Signer_Info: {
254 read += deserialize(ar, info);
256 list.push_back(field);
259 case HeaderFieldType::Recipient_Info: {
260 std::list<RecipientInfo> recipientList;
262 const size_t tmp_size = deserialize(ar, recipientList, sym_algo.get());
264 read += length_coding_size(tmp_size);
265 field = recipientList;
266 list.push_back(field);
268 throw deserialization_error(
"HeaderFields: RecipientInfo read before EncryptionParameters: SymmetricAlgorithm still unknown");
272 case HeaderFieldType::Encryption_Parameters: {
273 EncryptionParameter param;
274 read += deserialize(ar, param);
276 sym_algo = get_type(param);
277 list.push_back(field);
281 throw deserialization_error(
"Unknown HeaderFieldType");
IntX specified in TS 103 097 v1.2.1, section 4.2.1.
ThreeDLocation specified in TS 103 097 v1.2.1, section 4.2.19.
Time64WithStandardDeviation specified in TS 103 097 v1.2.1, section 4.2.16.