33aa16d533999599ce3402fd7ef397dda393c0c6
[strongswan.git] / src / libpts / tcg / swid / tcg_swid_attr_tag_id_inv.c
1 /*
2 * Copyright (C) 2013-2014 Andreas Steffen
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "tcg_swid_attr_tag_id_inv.h"
17
18 #include <pa_tnc/pa_tnc_msg.h>
19 #include <bio/bio_writer.h>
20 #include <bio/bio_reader.h>
21 #include <utils/debug.h>
22
23
24 typedef struct private_tcg_swid_attr_tag_id_inv_t private_tcg_swid_attr_tag_id_inv_t;
25
26 /**
27 * SWID Tag Identifier Inventory
28 * see section 4.8 of TCG TNC SWID Message and Attributes for IF-M
29 *
30 * 1 2 3
31 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
32 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 * | Reserved | Tag ID Count |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 * | Request ID Copy |
36 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 * | EID Epoch |
38 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 * | Last EID |
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | Tag Creator Length | Tag Creator (variable length) |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | Unique Software ID Length |Unique Software ID (var length)|
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | Tag File Path Length | Tag File Path (var. length) |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 */
48
49 #define TCG_SWID_TAG_ID_INV_RESERVED 0x00
50
51 /**
52 * Private data of an tcg_swid_attr_tag_id_inv_t object.
53 */
54 struct private_tcg_swid_attr_tag_id_inv_t {
55
56 /**
57 * Public members of tcg_swid_attr_tag_id_inv_t
58 */
59 tcg_swid_attr_tag_id_inv_t public;
60
61 /**
62 * Vendor-specific attribute type
63 */
64 pen_type_t type;
65
66 /**
67 * Attribute value
68 */
69 chunk_t value;
70
71 /**
72 * Noskip flag
73 */
74 bool noskip_flag;
75
76 /**
77 * Request ID
78 */
79 uint32_t request_id;
80
81 /**
82 * Event ID Epoch
83 */
84 uint32_t eid_epoch;
85
86 /**
87 * Last Event ID
88 */
89 uint32_t last_eid;
90
91 /**
92 * SWID Tag ID Inventory
93 */
94 swid_inventory_t *inventory;
95
96 /**
97 * Reference count
98 */
99 refcount_t ref;
100 };
101
102 METHOD(pa_tnc_attr_t, get_type, pen_type_t,
103 private_tcg_swid_attr_tag_id_inv_t *this)
104 {
105 return this->type;
106 }
107
108 METHOD(pa_tnc_attr_t, get_value, chunk_t,
109 private_tcg_swid_attr_tag_id_inv_t *this)
110 {
111 return this->value;
112 }
113
114 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
115 private_tcg_swid_attr_tag_id_inv_t *this)
116 {
117 return this->noskip_flag;
118 }
119
120 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
121 private_tcg_swid_attr_tag_id_inv_t *this, bool noskip)
122 {
123 this->noskip_flag = noskip;
124 }
125
126 METHOD(pa_tnc_attr_t, build, void,
127 private_tcg_swid_attr_tag_id_inv_t *this)
128 {
129 bio_writer_t *writer;
130 swid_tag_id_t *tag_id;
131 chunk_t tag_creator, unique_sw_id, tag_file_path;
132 enumerator_t *enumerator;
133
134 if (this->value.ptr)
135 {
136 return;
137 }
138
139 writer = bio_writer_create(TCG_SWID_TAG_ID_INV_MIN_SIZE);
140 writer->write_uint8 (writer, TCG_SWID_TAG_ID_INV_RESERVED);
141 writer->write_uint24(writer, this->inventory->get_count(this->inventory));
142 writer->write_uint32(writer, this->request_id);
143 writer->write_uint32(writer, this->eid_epoch);
144 writer->write_uint32(writer, this->last_eid);
145
146 enumerator = this->inventory->create_enumerator(this->inventory);
147 while (enumerator->enumerate(enumerator, &tag_id))
148 {
149 tag_creator = tag_id->get_tag_creator(tag_id);
150 unique_sw_id = tag_id->get_unique_sw_id(tag_id, &tag_file_path);
151 writer->write_data16(writer, tag_creator);
152 writer->write_data16(writer, unique_sw_id);
153 writer->write_data16(writer, tag_file_path);
154 }
155 enumerator->destroy(enumerator);
156
157 this->value = writer->extract_buf(writer);
158 writer->destroy(writer);
159 }
160
161 METHOD(pa_tnc_attr_t, process, status_t,
162 private_tcg_swid_attr_tag_id_inv_t *this, uint32_t *offset)
163 {
164 bio_reader_t *reader;
165 uint32_t tag_id_count;
166 uint8_t reserved;
167 chunk_t tag_creator, unique_sw_id, tag_file_path;
168 swid_tag_id_t *tag_id;
169
170 if (this->value.len < TCG_SWID_TAG_ID_INV_MIN_SIZE)
171 {
172 DBG1(DBG_TNC, "insufficient data for SWID Tag Identifier Inventory");
173 *offset = 0;
174 return FAILED;
175 }
176
177 reader = bio_reader_create(this->value);
178 reader->read_uint8 (reader, &reserved);
179 reader->read_uint24(reader, &tag_id_count);
180 reader->read_uint32(reader, &this->request_id);
181 reader->read_uint32(reader, &this->eid_epoch);
182 reader->read_uint32(reader, &this->last_eid);
183 *offset = TCG_SWID_TAG_ID_INV_MIN_SIZE;
184
185 while (tag_id_count--)
186 {
187 if (!reader->read_data16(reader, &tag_creator))
188 {
189 DBG1(DBG_TNC, "insufficient data for Tag Creator field");
190 return FAILED;
191 }
192 *offset += 2 + tag_creator.len;
193
194 if (!reader->read_data16(reader, &unique_sw_id))
195 {
196 DBG1(DBG_TNC, "insufficient data for Unique Software ID");
197 return FAILED;
198 }
199 *offset += 2 + unique_sw_id.len;
200
201 if (!reader->read_data16(reader, &tag_file_path))
202 {
203 DBG1(DBG_TNC, "insufficient data for Tag File Path");
204 return FAILED;
205 }
206 *offset += 2 + tag_file_path.len;
207
208 tag_id = swid_tag_id_create(tag_creator, unique_sw_id, tag_file_path);
209 this->inventory->add(this->inventory, tag_id);
210 }
211 reader->destroy(reader);
212
213 return SUCCESS;
214 }
215
216 METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
217 private_tcg_swid_attr_tag_id_inv_t *this)
218 {
219 ref_get(&this->ref);
220 return &this->public.pa_tnc_attribute;
221 }
222
223 METHOD(pa_tnc_attr_t, destroy, void,
224 private_tcg_swid_attr_tag_id_inv_t *this)
225 {
226 if (ref_put(&this->ref))
227 {
228 this->inventory->destroy(this->inventory);
229 free(this->value.ptr);
230 free(this);
231 }
232 }
233
234 METHOD(tcg_swid_attr_tag_id_inv_t, add, void,
235 private_tcg_swid_attr_tag_id_inv_t *this, swid_tag_id_t *tag_id)
236 {
237 this->inventory->add(this->inventory, tag_id);
238 }
239
240 METHOD(tcg_swid_attr_tag_id_inv_t, get_request_id, uint32_t,
241 private_tcg_swid_attr_tag_id_inv_t *this)
242 {
243 return this->request_id;
244 }
245
246 METHOD(tcg_swid_attr_tag_id_inv_t, get_last_eid, uint32_t,
247 private_tcg_swid_attr_tag_id_inv_t *this, uint32_t *eid_epoch)
248 {
249 if (eid_epoch)
250 {
251 *eid_epoch = this->eid_epoch;
252 }
253 return this->last_eid;
254 }
255
256 METHOD(tcg_swid_attr_tag_id_inv_t, get_inventory, swid_inventory_t*,
257 private_tcg_swid_attr_tag_id_inv_t *this)
258 {
259 return this->inventory;
260 }
261
262 /**
263 * Described in header.
264 */
265 pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(uint32_t request_id,
266 uint32_t eid_epoch,
267 uint32_t eid)
268 {
269 private_tcg_swid_attr_tag_id_inv_t *this;
270
271 INIT(this,
272 .public = {
273 .pa_tnc_attribute = {
274 .get_type = _get_type,
275 .get_value = _get_value,
276 .get_noskip_flag = _get_noskip_flag,
277 .set_noskip_flag = _set_noskip_flag,
278 .build = _build,
279 .process = _process,
280 .get_ref = _get_ref,
281 .destroy = _destroy,
282 },
283 .add = _add,
284 .get_request_id = _get_request_id,
285 .get_last_eid = _get_last_eid,
286 .get_inventory = _get_inventory,
287 },
288 .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY },
289 .request_id = request_id,
290 .eid_epoch = eid_epoch,
291 .last_eid = eid,
292 .inventory = swid_inventory_create(FALSE),
293 .ref = 1,
294 );
295
296 return &this->public.pa_tnc_attribute;
297 }
298
299
300 /**
301 * Described in header.
302 */
303 pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(chunk_t data)
304 {
305 private_tcg_swid_attr_tag_id_inv_t *this;
306
307 INIT(this,
308 .public = {
309 .pa_tnc_attribute = {
310 .get_type = _get_type,
311 .get_value = _get_value,
312 .get_noskip_flag = _get_noskip_flag,
313 .set_noskip_flag = _set_noskip_flag,
314 .build = _build,
315 .process = _process,
316 .get_ref = _get_ref,
317 .destroy = _destroy,
318 },
319 .add = _add,
320 .get_request_id = _get_request_id,
321 .get_last_eid = _get_last_eid,
322 .get_inventory = _get_inventory,
323 },
324 .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY },
325 .value = chunk_clone(data),
326 .inventory = swid_inventory_create(FALSE),
327 .ref = 1,
328 );
329
330 return &this->public.pa_tnc_attribute;
331 }