fixed two memory leaks
[strongswan.git] / src / libpts / tcg / tcg_pts_attr_req_func_comp_evid.c
1 /*
2 * Copyright (C) 2011 Sansar Choinyambuu
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_pts_attr_req_func_comp_evid.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/linked_list.h>
22 #include <debug.h>
23
24 typedef struct private_tcg_pts_attr_req_func_comp_evid_t private_tcg_pts_attr_req_func_comp_evid_t;
25
26 /**
27 * Request Functional Component Evidence
28 * see section 3.14.1 of PTS Protocol: Binding to TNC IF-M Specification
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 * | Flags | Sub-component Depth (for Component #1) |
34 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
35 * | Component Functional Name #1 |
36 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37 * | Component Functional Name #1 |
38 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 * | ........ |
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | Flags | Sub-component Depth (for Component #N) |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | Component Functional Name #N |
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | Component Functional Name #N |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 */
48
49 /**
50 * Component Functional Name Structure
51 * (see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification)
52 *
53 * 1 2 3
54 * 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
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * | Component Functional Name Vendor ID |Fam| Qualifier |
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * | Component Functional Name |
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 */
61
62 #define PTS_REQ_FUNC_COMP_EVID_SIZE 12
63 #define PTS_REQ_FUNC_COMP_FAMILY_MASK 0xC0
64
65 /**
66 * Private data of an tcg_pts_attr_req_func_comp_evid_t object.
67 */
68 struct private_tcg_pts_attr_req_func_comp_evid_t {
69
70 /**
71 * Public members of tcg_pts_attr_req_func_comp_evid_t
72 */
73 tcg_pts_attr_req_func_comp_evid_t public;
74
75 /**
76 * Attribute vendor ID
77 */
78 pen_t vendor_id;
79
80 /**
81 * Attribute type
82 */
83 u_int32_t type;
84
85 /**
86 * Attribute value
87 */
88 chunk_t value;
89
90 /**
91 * Noskip flag
92 */
93 bool noskip_flag;
94
95 /**
96 * List of Functional Components
97 */
98 linked_list_t *list;
99 };
100
101 typedef struct entry_t entry_t;
102
103 /**
104 * Functional component entry
105 */
106 struct entry_t {
107 u_int8_t flags;
108 u_int32_t depth;
109 pts_comp_func_name_t *name;
110 };
111
112 /**
113 * Enumerate functional component entries
114 */
115 static bool entry_filter(void *null, entry_t **entry, u_int8_t *flags,
116 void *i2, u_int32_t *depth, void *i3,
117 pts_comp_func_name_t **name)
118 {
119 *flags = (*entry)->flags;
120 *depth = (*entry)->depth;
121 *name = (*entry)->name;
122
123 return TRUE;
124 }
125
126 /**
127 * Free an entry_t object
128 */
129 static void free_entry(entry_t *this)
130 {
131 if (this)
132 {
133 this->name->destroy(this->name);
134 free(this);
135 }
136 }
137
138 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
139 private_tcg_pts_attr_req_func_comp_evid_t *this)
140 {
141 return this->vendor_id;
142 }
143
144 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
145 private_tcg_pts_attr_req_func_comp_evid_t *this)
146 {
147 return this->type;
148 }
149
150 METHOD(pa_tnc_attr_t, get_value, chunk_t,
151 private_tcg_pts_attr_req_func_comp_evid_t *this)
152 {
153 return this->value;
154 }
155
156 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
157 private_tcg_pts_attr_req_func_comp_evid_t *this)
158 {
159 return this->noskip_flag;
160 }
161
162 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
163 private_tcg_pts_attr_req_func_comp_evid_t *this, bool noskip)
164 {
165 this->noskip_flag = noskip;
166 }
167
168 METHOD(pa_tnc_attr_t, build, void,
169 private_tcg_pts_attr_req_func_comp_evid_t *this)
170 {
171 bio_writer_t *writer;
172 enumerator_t *enumerator;
173 entry_t *entry;
174
175 writer = bio_writer_create(PTS_REQ_FUNC_COMP_EVID_SIZE);
176
177 enumerator = this->list->create_enumerator(this->list);
178 while (enumerator->enumerate(enumerator, &entry))
179 {
180 writer->write_uint8 (writer, entry->flags);
181 writer->write_uint24(writer, entry->depth);
182 writer->write_uint24(writer, entry->name->get_vendor_id(entry->name));
183 writer->write_uint8 (writer, entry->name->get_qualifier(entry->name));
184 writer->write_uint32(writer, entry->name->get_name(entry->name));
185 }
186 enumerator->destroy(enumerator);
187
188 this->value = chunk_clone(writer->get_buf(writer));
189 writer->destroy(writer);
190 }
191
192 METHOD(pa_tnc_attr_t, process, status_t,
193 private_tcg_pts_attr_req_func_comp_evid_t *this, u_int32_t *offset)
194 {
195 bio_reader_t *reader;
196 u_int32_t depth, vendor_id, name;
197 u_int8_t flags, fam_and_qualifier, qualifier;
198 status_t status = FAILED;
199 entry_t *entry = NULL;
200
201 if (this->value.len < PTS_REQ_FUNC_COMP_EVID_SIZE)
202 {
203 DBG1(DBG_TNC, "insufficient data for Request Functional "
204 "Component Evidence");
205 *offset = 0;
206 return FAILED;
207 }
208 reader = bio_reader_create(this->value);
209
210 while (reader->remaining(reader))
211 {
212 if (!reader->read_uint8(reader, &flags))
213 {
214 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
215 "Component Evidence Flags");
216 goto end;
217 }
218 if (!reader->read_uint24(reader, &depth))
219 {
220 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
221 "Component Evidence Sub Component Depth");
222 goto end;
223 }
224 if (!reader->read_uint24(reader, &vendor_id))
225 {
226 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
227 "Component Evidence Component Name Vendor ID");
228 goto end;
229 }
230 if (!reader->read_uint8(reader, &fam_and_qualifier))
231 {
232 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
233 "Component Evidence Family and Qualifier");
234 goto end;
235 }
236 if (fam_and_qualifier & PTS_REQ_FUNC_COMP_FAMILY_MASK)
237 {
238 DBG1(DBG_TNC, "the Functional Name Encoding Family "
239 "is not Binary Enumeration");
240 goto end;
241 }
242 if (!reader->read_uint32(reader, &name))
243 {
244 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
245 "Component Evidence Component Functional Name");
246 goto end;
247 }
248 qualifier = fam_and_qualifier & ~PTS_REQ_FUNC_COMP_FAMILY_MASK;
249
250 entry = malloc_thing(entry_t);
251 entry->flags = flags;
252 entry->depth = depth;
253 entry->name = pts_comp_func_name_create(vendor_id, name, qualifier);
254
255 this->list->insert_last(this->list, entry);
256 }
257 status = SUCCESS;
258
259 end:
260 reader->destroy(reader);
261 return status;
262 }
263
264 METHOD(pa_tnc_attr_t, destroy, void,
265 private_tcg_pts_attr_req_func_comp_evid_t *this)
266 {
267 this->list->destroy_function(this->list, (void *)free_entry);
268 free(this->value.ptr);
269 free(this);
270 }
271
272 METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void,
273 private_tcg_pts_attr_req_func_comp_evid_t *this, u_int8_t flags,
274 u_int32_t depth, pts_comp_func_name_t *name)
275 {
276 entry_t *entry;
277
278 entry = malloc_thing(entry_t);
279 entry->flags = flags;
280 entry->depth = depth;
281 entry->name = name;
282 this->list->insert_last(this->list, entry);
283 }
284
285 METHOD(tcg_pts_attr_req_func_comp_evid_t, get_count, int,
286 private_tcg_pts_attr_req_func_comp_evid_t *this)
287 {
288 return this->list->get_count(this->list);
289 }
290
291 METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*,
292 private_tcg_pts_attr_req_func_comp_evid_t *this)
293 {
294 return enumerator_create_filter(this->list->create_enumerator(this->list),
295 (void*)entry_filter, NULL, NULL);
296 }
297
298 /**
299 * Described in header.
300 */
301 pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void)
302 {
303 private_tcg_pts_attr_req_func_comp_evid_t *this;
304
305 INIT(this,
306 .public = {
307 .pa_tnc_attribute = {
308 .get_vendor_id = _get_vendor_id,
309 .get_type = _get_type,
310 .get_value = _get_value,
311 .get_noskip_flag = _get_noskip_flag,
312 .set_noskip_flag = _set_noskip_flag,
313 .build = _build,
314 .process = _process,
315 .destroy = _destroy,
316 },
317 .add_component = _add_component,
318 .get_count = _get_count,
319 .create_enumerator = _create_enumerator,
320 },
321 .vendor_id = PEN_TCG,
322 .type = TCG_PTS_REQ_FUNC_COMP_EVID,
323 .list = linked_list_create(),
324 );
325
326 return &this->public.pa_tnc_attribute;
327 }
328
329 /**
330 * Described in header.
331 */
332 pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data)
333 {
334 private_tcg_pts_attr_req_func_comp_evid_t *this;
335
336 INIT(this,
337 .public = {
338 .pa_tnc_attribute = {
339 .get_vendor_id = _get_vendor_id,
340 .get_type = _get_type,
341 .get_value = _get_value,
342 .get_noskip_flag = _get_noskip_flag,
343 .set_noskip_flag = _set_noskip_flag,
344 .build = _build,
345 .process = _process,
346 .destroy = _destroy,
347 },
348 .add_component = _add_component,
349 .get_count = _get_count,
350 .create_enumerator = _create_enumerator,
351 },
352 .vendor_id = PEN_TCG,
353 .type = TCG_PTS_REQ_FUNC_COMP_EVID,
354 .list = linked_list_create(),
355 .value = chunk_clone(data),
356 );
357
358 return &this->public.pa_tnc_attribute;
359 }