Vanetza
 
Loading...
Searching...
No Matches
header_field.cpp
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>
6
7namespace vanetza
8{
9namespace security
10{
11namespace v2
12{
13
14HeaderFieldType get_type(const HeaderField& field)
15{
16 struct HeaderFieldVisitor : public boost::static_visitor<HeaderFieldType>
17 {
18 HeaderFieldType operator()(const Time64&)
19 {
20 return HeaderFieldType::Generation_Time;
21 }
22 HeaderFieldType operator()(const Time64WithStandardDeviation&)
23 {
24 return HeaderFieldType::Generation_Time_Confidence;
25 }
26 HeaderFieldType operator()(const Time32&)
27 {
28 return HeaderFieldType::Expiration;
29 }
30 HeaderFieldType operator()(const ThreeDLocation&)
31 {
32 return HeaderFieldType::Generation_Location;
33 }
34 HeaderFieldType operator()(const std::list<HashedId3>&)
35 {
36 return HeaderFieldType::Request_Unrecognized_Certificate;
37 }
38 HeaderFieldType operator()(const IntX&)
39 {
40 return HeaderFieldType::Its_Aid;
41 }
42 HeaderFieldType operator()(const SignerInfo&)
43 {
44 return HeaderFieldType::Signer_Info;
45 }
46 HeaderFieldType operator()(const std::list<RecipientInfo>&)
47 {
48 return HeaderFieldType::Recipient_Info;
49 }
50 HeaderFieldType operator()(const EncryptionParameter&)
51 {
52 return HeaderFieldType::Encryption_Parameters;
53 }
54 };
55
56 HeaderFieldVisitor visit;
57 return boost::apply_visitor(visit, field);
58}
59
60size_t get_size(const HeaderField& field)
61{
62 size_t size = sizeof(HeaderFieldType);
63 struct HeaderFieldVisitor : public boost::static_visitor<>
64 {
65 void operator()(const Time64&)
66 {
67 m_size = sizeof(Time64);
68 }
69 void operator()(const Time64WithStandardDeviation& time)
70 {
71 m_size = sizeof(time.time64);
72 m_size += sizeof(time.log_std_dev);
73 }
74 void operator()(const Time32&)
75 {
76 m_size = sizeof(Time32);
77 }
78 void operator()(const ThreeDLocation& loc)
79 {
80 m_size = get_size(loc);
81 }
82 void operator()(const std::list<HashedId3>& list)
83 {
84 m_size = 0;
85 for (auto& elem : list) {
86 m_size += elem.size();
87 }
88 m_size += length_coding_size(m_size);
89 }
90 void operator()(const IntX& itsAid)
91 {
92 m_size = get_size(itsAid);
93 }
94 void operator()(const SignerInfo& info)
95 {
96 m_size = get_size(info);
97 }
98 void operator()(const std::list<RecipientInfo>& list)
99 {
100 m_size = get_size(list);
101 m_size += length_coding_size(m_size);
102 }
103 void operator()(const EncryptionParameter& enc)
104 {
105 m_size = get_size(enc);
106 }
107 size_t m_size;
108 };
109
110 HeaderFieldVisitor visit;
111 boost::apply_visitor(visit, field);
112 size += visit.m_size;
113 return size;
114}
115
116void serialize(OutputArchive& ar, const HeaderField& field)
117{
118 struct HeaderFieldVisitor : public boost::static_visitor<>
119 {
120 HeaderFieldVisitor(OutputArchive& ar) :
121 m_archive(ar)
122 {
123 }
124 void operator()(const Time64& time)
125 {
126 serialize(m_archive, host_cast(time));
127 }
128 void operator()(const Time64WithStandardDeviation& time)
129 {
130 serialize(m_archive, host_cast(time.time64));
131 serialize(m_archive, host_cast(time.log_std_dev));
132 }
133 void operator()(const Time32& time)
134 {
135 serialize(m_archive, host_cast(time));
136 }
137 void operator()(const ThreeDLocation& loc)
138 {
139 serialize(m_archive, loc);
140 }
141 void operator()(const std::list<HashedId3>& list)
142 {
143 size_t size = 0;
144 for (auto& elem : list) {
145 size += elem.size();
146 }
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];
152 }
153 }
154 void operator()(const IntX& itsAid)
155 {
156 serialize(m_archive, itsAid);
157 }
158 void operator()(const SignerInfo& info)
159 {
160 serialize(m_archive, info);
161 }
162 void operator()(const std::list<RecipientInfo>& list)
163 {
164 // TODO: only works until further symmetric algorithms are introduced
165 serialize(m_archive, list, SymmetricAlgorithm::AES128_CCM);
166 }
167 void operator()(const EncryptionParameter& param)
168 {
169 serialize(m_archive, param);
170 }
171
172 OutputArchive& m_archive;
173 };
174 HeaderFieldType type = get_type(field);
175 serialize(ar, type);
176 HeaderFieldVisitor visit(ar);
177 boost::apply_visitor(visit, field);
178}
179
180std::size_t deserialize(InputArchive& ar, std::list<HeaderField>& list)
181{
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) {
186 HeaderField field;
187 HeaderFieldType type;
188 deserialize(ar, type);
189 read += sizeof(HeaderFieldType);
190 switch (type) {
191 case HeaderFieldType::Generation_Time: {
192 Time64 time;
193 deserialize(ar, time);
194 field = time;
195 list.push_back(field);
196 read += sizeof(Time64);
197 break;
198 }
199 case HeaderFieldType::Generation_Time_Confidence: {
200 Time64WithStandardDeviation time;
201 deserialize(ar, time.time64);
202 deserialize(ar, time.log_std_dev);
203 field = time;
204 list.push_back(field);
205 read += sizeof(Time64);
206 read += sizeof(uint8_t);
207 break;
208 }
209 case HeaderFieldType::Expiration: {
210 Time32 time;
211 deserialize(ar, time);
212 field = time;
213 list.push_back(field);
214 read += sizeof(Time32);
215 break;
216 }
217 case HeaderFieldType::Generation_Location: {
218 ThreeDLocation loc;
219 read += deserialize(ar, loc);
220 field = loc;
221 list.push_back(field);
222 break;
223 }
224 case HeaderFieldType::Request_Unrecognized_Certificate: {
225 const std::size_t tmp_size = trim_size(deserialize_length(ar));
226 read += tmp_size;
227 std::list<HashedId3> hashedList;
228 for (std::size_t c = 0; c < tmp_size; c += 3) {
229 HashedId3 id;
230 ar >> id[0];
231 ar >> id[1];
232 ar >> id[2];
233 hashedList.push_back(id);
234 }
235 field = hashedList;
236 read += length_coding_size(tmp_size);
237 list.push_back(field);
238 break;
239 }
240 case HeaderFieldType::Its_Aid: {
241 IntX its_aid;
242 read += deserialize(ar, its_aid);
243 field = its_aid;
244 list.push_back(field);
245 break;
246 }
247 case HeaderFieldType::Signer_Info: {
248 SignerInfo info;
249 read += deserialize(ar, info);
250 field = info;
251 list.push_back(field);
252 break;
253 }
254 case HeaderFieldType::Recipient_Info: {
255 std::list<RecipientInfo> recipientList;
256 if (sym_algo) {
257 const size_t tmp_size = deserialize(ar, recipientList, sym_algo.get());
258 read += tmp_size;
259 read += length_coding_size(tmp_size);
260 field = recipientList;
261 list.push_back(field);
262 } else {
263 throw deserialization_error("HeaderFields: RecipientInfo read before EncryptionParameters: SymmetricAlgorithm still unknown");
264 }
265 break;
266 }
267 case HeaderFieldType::Encryption_Parameters: {
268 EncryptionParameter param;
269 read += deserialize(ar, param);
270 field = param;
271 sym_algo = get_type(param);
272 list.push_back(field);
273 break;
274 }
275 default:
276 throw deserialization_error("Unknown HeaderFieldType");
277 break;
278 }
279 }
280 return size;
281}
282
283} // namespace v2
284} // namespace security
285} // namespace vanetza