fbb94c6c2ce02a980451810a3b69559f743bf275
[strongswan.git] / src / libpts / tcg / swid / tcg_swid_attr_tag_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_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_inv_t private_tcg_swid_attr_tag_inv_t;
25
26 /**
27 * SWID Tag Inventory
28 * see section 4.10 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 File Path Length | Tag File Path (var length) |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | Tag Length |
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | Tag (Variable) |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 */
48
49 #define TCG_SWID_TAG_INV_RESERVED 0x00
50
51 /**
52 * Private data of an tcg_swid_attr_tag_inv_t object.
53 */
54 struct private_tcg_swid_attr_tag_inv_t {
55
56 /**
57 * Public members of tcg_swid_attr_tag_inv_t
58 */
59 tcg_swid_attr_tag_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 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_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_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_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_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_inv_t *this)
128 {
129 bio_writer_t *writer;
130 swid_tag_t *tag;
131 enumerator_t *enumerator;
132
133 if (this->value.ptr)
134 {
135 return;
136 }
137
138 writer = bio_writer_create(TCG_SWID_TAG_INV_MIN_SIZE);
139 writer->write_uint8 (writer, TCG_SWID_TAG_INV_RESERVED);
140 writer->write_uint24(writer, this->inventory->get_count(this->inventory));
141 writer->write_uint32(writer, this->request_id);
142 writer->write_uint32(writer, this->eid_epoch);
143 writer->write_uint32(writer, this->last_eid);
144
145 enumerator = this->inventory->create_enumerator(this->inventory);
146 while (enumerator->enumerate(enumerator, &tag))
147 {
148 writer->write_data16(writer, tag->get_tag_file_path(tag));
149 writer->write_data32(writer, tag->get_encoding(tag));
150 }
151 enumerator->destroy(enumerator);
152
153 this->value = writer->extract_buf(writer);
154 writer->destroy(writer);
155 }
156
157 METHOD(pa_tnc_attr_t, process, status_t,
158 private_tcg_swid_attr_tag_inv_t *this, uint32_t *offset)
159 {
160 bio_reader_t *reader;
161 uint32_t tag_count;
162 uint8_t reserved;
163 chunk_t tag_encoding, tag_file_path;
164 swid_tag_t *tag;
165
166 if (this->value.len < TCG_SWID_TAG_INV_MIN_SIZE)
167 {
168 DBG1(DBG_TNC, "insufficient data for SWID Tag Inventory");
169 *offset = 0;
170 return FAILED;
171 }
172
173 reader = bio_reader_create(this->value);
174 reader->read_uint8 (reader, &reserved);
175 reader->read_uint24(reader, &tag_count);
176 reader->read_uint32(reader, &this->request_id);
177 reader->read_uint32(reader, &this->eid_epoch);
178 reader->read_uint32(reader, &this->last_eid);
179 *offset = TCG_SWID_TAG_INV_MIN_SIZE;
180
181 while (tag_count--)
182 {
183 if (!reader->read_data16(reader, &tag_file_path))
184 {
185 DBG1(DBG_TNC, "insufficient data for Tag File Path");
186 return FAILED;
187 }
188 *offset += 2 + tag_file_path.len;
189
190 if (!reader->read_data32(reader, &tag_encoding))
191 {
192 DBG1(DBG_TNC, "insufficient data for Tag");
193 return FAILED;
194 }
195 *offset += 4 + tag_encoding.len;
196
197 tag = swid_tag_create(tag_encoding, tag_file_path);
198 this->inventory->add(this->inventory, tag);
199 }
200 reader->destroy(reader);
201
202 return SUCCESS;
203 }
204
205 METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
206 private_tcg_swid_attr_tag_inv_t *this)
207 {
208 ref_get(&this->ref);
209 return &this->public.pa_tnc_attribute;
210 }
211
212 METHOD(pa_tnc_attr_t, destroy, void,
213 private_tcg_swid_attr_tag_inv_t *this)
214 {
215 if (ref_put(&this->ref))
216 {
217 this->inventory->destroy(this->inventory);
218 free(this->value.ptr);
219 free(this);
220 }
221 }
222
223 METHOD(tcg_swid_attr_tag_inv_t, add, void,
224 private_tcg_swid_attr_tag_inv_t *this, swid_tag_t *tag)
225 {
226 this->inventory->add(this->inventory, tag);
227 }
228
229 METHOD(tcg_swid_attr_tag_inv_t, get_request_id, uint32_t,
230 private_tcg_swid_attr_tag_inv_t *this)
231 {
232 return this->request_id;
233 }
234
235 METHOD(tcg_swid_attr_tag_inv_t, get_last_eid, uint32_t,
236 private_tcg_swid_attr_tag_inv_t *this, uint32_t *eid_epoch)
237 {
238 if (eid_epoch)
239 {
240 *eid_epoch = this->eid_epoch;
241 }
242 return this->last_eid;
243 }
244
245 METHOD(tcg_swid_attr_tag_inv_t, get_inventory, swid_inventory_t*,
246 private_tcg_swid_attr_tag_inv_t *this)
247 {
248 return this->inventory;
249 }
250
251 /**
252 * Described in header.
253 */
254 pa_tnc_attr_t *tcg_swid_attr_tag_inv_create(uint32_t request_id,
255 uint32_t eid_epoch, uint32_t eid)
256 {
257 private_tcg_swid_attr_tag_inv_t *this;
258
259 INIT(this,
260 .public = {
261 .pa_tnc_attribute = {
262 .get_type = _get_type,
263 .get_value = _get_value,
264 .get_noskip_flag = _get_noskip_flag,
265 .set_noskip_flag = _set_noskip_flag,
266 .build = _build,
267 .process = _process,
268 .get_ref = _get_ref,
269 .destroy = _destroy,
270 },
271 .add = _add,
272 .get_request_id = _get_request_id,
273 .get_last_eid = _get_last_eid,
274 .get_inventory = _get_inventory,
275 },
276 .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY },
277 .request_id = request_id,
278 .eid_epoch = eid_epoch,
279 .last_eid = eid,
280 .inventory = swid_inventory_create(TRUE),
281 .ref = 1,
282 );
283
284 return &this->public.pa_tnc_attribute;
285 }
286
287
288 /**
289 * Described in header.
290 */
291 pa_tnc_attr_t *tcg_swid_attr_tag_inv_create_from_data(chunk_t data)
292 {
293 private_tcg_swid_attr_tag_inv_t *this;
294
295 INIT(this,
296 .public = {
297 .pa_tnc_attribute = {
298 .get_type = _get_type,
299 .get_value = _get_value,
300 .get_noskip_flag = _get_noskip_flag,
301 .set_noskip_flag = _set_noskip_flag,
302 .build = _build,
303 .process = _process,
304 .get_ref = _get_ref,
305 .destroy = _destroy,
306 },
307 .add = _add,
308 .get_request_id = _get_request_id,
309 .get_last_eid = _get_last_eid,
310 .get_inventory = _get_inventory,
311 },
312 .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY },
313 .value = chunk_clone(data),
314 .inventory = swid_inventory_create(TRUE),
315 .ref = 1,
316 );
317
318 return &this->public.pa_tnc_attribute;
319 }