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;
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);
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));
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 const std::size_t size = trim_size(deserialize_length(ar));
183 std::size_t read = 0;
184 boost::optional<SymmetricAlgorithm> sym_algo;
185 while (read < size) {
187 HeaderFieldType type;
188 deserialize(ar, type);
189 read +=
sizeof(HeaderFieldType);
191 case HeaderFieldType::Generation_Time: {
193 deserialize(ar, time);
195 list.push_back(field);
196 read +=
sizeof(Time64);
199 case HeaderFieldType::Generation_Time_Confidence: {
200 Time64WithStandardDeviation time;
201 deserialize(ar, time.time64);
202 deserialize(ar, time.log_std_dev);
204 list.push_back(field);
205 read +=
sizeof(Time64);
206 read +=
sizeof(uint8_t);
209 case HeaderFieldType::Expiration: {
211 deserialize(ar, time);
213 list.push_back(field);
214 read +=
sizeof(Time32);
217 case HeaderFieldType::Generation_Location: {
219 read += deserialize(ar, loc);
221 list.push_back(field);
224 case HeaderFieldType::Request_Unrecognized_Certificate: {
225 const std::size_t tmp_size = trim_size(deserialize_length(ar));
227 std::list<HashedId3> hashedList;
228 for (std::size_t c = 0; c < tmp_size; c += 3) {
233 hashedList.push_back(
id);
236 read += length_coding_size(tmp_size);
237 list.push_back(field);
240 case HeaderFieldType::Its_Aid: {
242 read += deserialize(ar, its_aid);
244 list.push_back(field);
247 case HeaderFieldType::Signer_Info: {
249 read += deserialize(ar, info);
251 list.push_back(field);
254 case HeaderFieldType::Recipient_Info: {
255 std::list<RecipientInfo> recipientList;
257 const size_t tmp_size = deserialize(ar, recipientList, sym_algo.get());
259 read += length_coding_size(tmp_size);
260 field = recipientList;
261 list.push_back(field);
263 throw deserialization_error(
"HeaderFields: RecipientInfo read before EncryptionParameters: SymmetricAlgorithm still unknown");
267 case HeaderFieldType::Encryption_Parameters: {
268 EncryptionParameter param;
269 read += deserialize(ar, param);
271 sym_algo = get_type(param);
272 list.push_back(field);
276 throw deserialization_error(
"Unknown HeaderFieldType");