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