429919edd7e06bf693553e5599ec7581c9599153
[strongswan.git] / src / libpts / tcg / swid / tcg_swid_attr_tag_id_inv.c
1 /*
2 * Copyright (C) 2013 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 * | Unique Sequence ID Length |Unique Sequence ID (var length)|
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 */
48
49 #define SWID_TAG_ID_INV_SIZE 16
50 #define SWID_TAG_ID_INV_RESERVED 0x00
51
52 /**
53 * Private data of an tcg_swid_attr_tag_id_inv_t object.
54 */
55 struct private_tcg_swid_attr_tag_id_inv_t {
56
57 /**
58 * Public members of tcg_swid_attr_tag_id_inv_t
59 */
60 tcg_swid_attr_tag_id_inv_t public;
61
62 /**
63 * Vendor-specific attribute type
64 */
65 pen_type_t type;
66
67 /**
68 * Attribute value
69 */
70 chunk_t value;
71
72 /**
73 * Noskip flag
74 */
75 bool noskip_flag;
76
77 /**
78 * Request ID
79 */
80 u_int32_t request_id;
81
82 /**
83 * Event ID Epoch
84 */
85 u_int32_t eid_epoch;
86
87 /**
88 * Last Event ID
89 */
90 u_int32_t last_eid;
91
92 /**
93 * SWID Tag ID Inventory
94 */
95 swid_inventory_t *inventory;
96
97 /**
98 * Reference count
99 */
100 refcount_t ref;
101 };
102
103 METHOD(pa_tnc_attr_t, get_type, pen_type_t,
104 private_tcg_swid_attr_tag_id_inv_t *this)
105 {
106 return this->type;
107 }
108
109 METHOD(pa_tnc_attr_t, get_value, chunk_t,
110 private_tcg_swid_attr_tag_id_inv_t *this)
111 {
112 return this->value;
113 }
114
115 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
116 private_tcg_swid_attr_tag_id_inv_t *this)
117 {
118 return this->noskip_flag;
119 }
120
121 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
122 private_tcg_swid_attr_tag_id_inv_t *this, bool noskip)
123 {
124 this->noskip_flag = noskip;
125 }
126
127 METHOD(pa_tnc_attr_t, build, void,
128 private_tcg_swid_attr_tag_id_inv_t *this)
129 {
130 bio_writer_t *writer;
131 swid_tag_id_t *tag_id;
132 chunk_t tag_creator, unique_sw_id, unique_seq_id;
133 enumerator_t *enumerator;
134
135 if (this->value.ptr)
136 {
137 return;
138 }
139
140 writer = bio_writer_create(SWID_TAG_ID_INV_SIZE);
141 writer->write_uint8 (writer, SWID_TAG_ID_INV_RESERVED);
142 writer->write_uint24(writer, this->inventory->get_count(this->inventory));
143 writer->write_uint32(writer, this->request_id);
144 writer->write_uint32(writer, this->eid_epoch);
145 writer->write_uint32(writer, this->last_eid);
146
147 enumerator = this->inventory->create_enumerator(this->inventory);
148 while (enumerator->enumerate(enumerator, &tag_id))
149 {
150 tag_creator = tag_id->get_tag_creator(tag_id);
151 unique_sw_id = tag_id->get_unique_sw_id(tag_id, &unique_seq_id);
152 writer->write_data16(writer, tag_creator);
153 writer->write_data16(writer, unique_sw_id);
154 writer->write_data16(writer, unique_seq_id);
155 }
156 enumerator->destroy(enumerator);
157
158 this->value = writer->extract_buf(writer);
159 writer->destroy(writer);
160 }
161
162 METHOD(pa_tnc_attr_t, process, status_t,
163 private_tcg_swid_attr_tag_id_inv_t *this, u_int32_t *offset)
164 {
165 bio_reader_t *reader;
166 u_int32_t tag_id_count;
167 u_int8_t reserved;
168 chunk_t tag_creator, unique_sw_id, unique_seq_id;
169 swid_tag_id_t *tag_id;
170
171 if (this->value.len < SWID_TAG_ID_INV_SIZE)
172 {
173 DBG1(DBG_TNC, "insufficient data for SWID Tag Identifier Inventory");
174 *offset = 0;
175 return FAILED;
176 }
177
178 reader = bio_reader_create(this->value);
179 reader->read_uint8 (reader, &reserved);
180 reader->read_uint24(reader, &tag_id_count);
181 reader->read_uint32(reader, &this->request_id);
182 reader->read_uint32(reader, &this->eid_epoch);
183 reader->read_uint32(reader, &this->last_eid);
184 *offset = SWID_TAG_ID_INV_SIZE;
185
186 while (tag_id_count--)
187 {
188 if (!reader->read_data16(reader, &tag_creator))
189 {
190 DBG1(DBG_TNC, "insufficient data for Tag Creator field");
191 return FAILED;
192 }
193 *offset += 2 + tag_creator.len;
194
195 if (!reader->read_data16(reader, &unique_sw_id))
196 {
197 DBG1(DBG_TNC, "insufficient data for Unique Software ID");
198 return FAILED;
199 }
200 *offset += 2 + unique_sw_id.len;
201
202 if (!reader->read_data16(reader, &unique_seq_id))
203 {
204 DBG1(DBG_TNC, "insufficient data for Unique Sequence ID");
205 return FAILED;
206 }
207 *offset += 2 + unique_seq_id.len;
208
209 tag_id = swid_tag_id_create(tag_creator, unique_sw_id, unique_seq_id);
210 this->inventory->add(this->inventory, tag_id);
211 }
212 reader->destroy(reader);
213
214 return SUCCESS;
215 }
216
217 METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
218 private_tcg_swid_attr_tag_id_inv_t *this)
219 {
220 ref_get(&this->ref);
221 return &this->public.pa_tnc_attribute;
222 }
223
224 METHOD(pa_tnc_attr_t, destroy, void,
225 private_tcg_swid_attr_tag_id_inv_t *this)
226 {
227 if (ref_put(&this->ref))
228 {
229 this->inventory->destroy(this->inventory);
230 free(this->value.ptr);
231 free(this);
232 }
233 }
234
235 METHOD(tcg_swid_attr_tag_id_inv_t, get_request_id, u_int32_t,
236 private_tcg_swid_attr_tag_id_inv_t *this)
237 {
238 return this->request_id;
239 }
240
241 METHOD(tcg_swid_attr_tag_id_inv_t, get_last_eid, u_int32_t,
242 private_tcg_swid_attr_tag_id_inv_t *this, u_int32_t *eid_epoch)
243 {
244 if (eid_epoch)
245 {
246 *eid_epoch = this->eid_epoch;
247 }
248 return this->last_eid;
249 }
250
251 METHOD(tcg_swid_attr_tag_id_inv_t, get_inventory, swid_inventory_t*,
252 private_tcg_swid_attr_tag_id_inv_t *this)
253 {
254 return this->inventory;
255 }
256
257 /**
258 * Described in header.
259 */
260 pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(u_int32_t request_id,
261 u_int32_t eid_epoch,
262 u_int32_t eid,
263 swid_inventory_t *inventory)
264 {
265 private_tcg_swid_attr_tag_id_inv_t *this;
266
267 INIT(this,
268 .public = {
269 .pa_tnc_attribute = {
270 .get_type = _get_type,
271 .get_value = _get_value,
272 .get_noskip_flag = _get_noskip_flag,
273 .set_noskip_flag = _set_noskip_flag,
274 .build = _build,
275 .process = _process,
276 .get_ref = _get_ref,
277 .destroy = _destroy,
278 },
279 .get_request_id = _get_request_id,
280 .get_last_eid = _get_last_eid,
281 .get_inventory = _get_inventory,
282 },
283 .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY },
284 .request_id = request_id,
285 .eid_epoch = eid_epoch,
286 .last_eid = eid,
287 .inventory = inventory,
288 .ref = 1,
289 );
290
291 return &this->public.pa_tnc_attribute;
292 }
293
294
295 /**
296 * Described in header.
297 */
298 pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(chunk_t data)
299 {
300 private_tcg_swid_attr_tag_id_inv_t *this;
301
302 INIT(this,
303 .public = {
304 .pa_tnc_attribute = {
305 .get_type = _get_type,
306 .get_value = _get_value,
307 .get_noskip_flag = _get_noskip_flag,
308 .set_noskip_flag = _set_noskip_flag,
309 .build = _build,
310 .process = _process,
311 .get_ref = _get_ref,
312 .destroy = _destroy,
313 },
314 .get_request_id = _get_request_id,
315 .get_last_eid = _get_last_eid,
316 .get_inventory = _get_inventory,
317 },
318 .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY },
319 .value = chunk_clone(data),
320 .inventory = swid_inventory_create(FALSE),
321 .ref = 1,
322 );
323
324 return &this->public.pa_tnc_attribute;
325 }