Factored IMC/V Attestation build/process of Component Functional Name
[strongswan.git] / src / libpts / tcg / tcg_pts_attr_req_funct_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_funct_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 <debug.h>
22
23 typedef struct private_tcg_pts_attr_req_funct_comp_evid_t private_tcg_pts_attr_req_funct_comp_evid_t;
24
25 /**
26 * Request Functional Component Evidence
27 * see section 3.14.1 of PTS Protocol: Binding to TNC IF-M Specification
28 *
29 * 1 2 3
30 * 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
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Flags | Sub-component Depth (for Component #1) |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Component Functional Name #1 |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | Component Functional Name #1 |
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | ........ |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * | Flags | Sub-component Depth (for Component #N) |
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | Component Functional Name #N |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | Component Functional Name #N |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 */
47
48 /**
49 * Component Functional Name Structure
50 * (see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification)
51 *
52 * 1 2 3
53 * 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
54 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55 * | Component Functional Name Vendor ID |Fam| Qualifier |
56 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57 * | Component Functional Name |
58 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59 */
60
61 #define PTS_REQ_FUNCT_COMP_EVID_SIZE 12
62
63 /**
64 * Private data of an tcg_pts_attr_req_funct_comp_evid_t object.
65 */
66 struct private_tcg_pts_attr_req_funct_comp_evid_t {
67
68 /**
69 * Public members of tcg_pts_attr_req_funct_comp_evid_t
70 */
71 tcg_pts_attr_req_funct_comp_evid_t public;
72
73 /**
74 * Attribute vendor ID
75 */
76 pen_t vendor_id;
77
78 /**
79 * Attribute type
80 */
81 u_int32_t type;
82
83 /**
84 * Attribute value
85 */
86 chunk_t value;
87
88 /**
89 * Noskip flag
90 */
91 bool noskip_flag;
92
93 /**
94 * PTS Functional Component Evidence Requests
95 */
96 pts_funct_comp_evid_req_t *requests;
97 };
98
99 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
100 private_tcg_pts_attr_req_funct_comp_evid_t *this)
101 {
102 return this->vendor_id;
103 }
104
105 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
106 private_tcg_pts_attr_req_funct_comp_evid_t *this)
107 {
108 return this->type;
109 }
110
111 METHOD(pa_tnc_attr_t, get_value, chunk_t,
112 private_tcg_pts_attr_req_funct_comp_evid_t *this)
113 {
114 return this->value;
115 }
116
117 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
118 private_tcg_pts_attr_req_funct_comp_evid_t *this)
119 {
120 return this->noskip_flag;
121 }
122
123 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
124 private_tcg_pts_attr_req_funct_comp_evid_t *this, bool noskip)
125 {
126 this->noskip_flag = noskip;
127 }
128
129 METHOD(pa_tnc_attr_t, build, void,
130 private_tcg_pts_attr_req_funct_comp_evid_t *this)
131 {
132 bio_writer_t *writer;
133 enumerator_t *enumerator;
134 funct_comp_evid_req_entry_t *entry;
135
136 writer = bio_writer_create(PTS_REQ_FUNCT_COMP_EVID_SIZE);
137
138 enumerator = this->requests->create_enumerator(this->requests);
139 while (enumerator->enumerate(enumerator, &entry))
140 {
141 writer->write_uint8 (writer, entry->flags);
142 writer->write_uint24(writer, entry->sub_comp_depth);
143 writer->write_uint24(writer, entry->name->get_vendor_id(entry->name));
144 writer->write_uint8 (writer, entry->name->get_qualifier(entry->name));
145 writer->write_uint32(writer, entry->name->get_name(entry->name));
146 }
147 enumerator->destroy(enumerator);
148
149 this->value = chunk_clone(writer->get_buf(writer));
150 writer->destroy(writer);
151 }
152
153 METHOD(pa_tnc_attr_t, process, status_t,
154 private_tcg_pts_attr_req_funct_comp_evid_t *this, u_int32_t *offset)
155 {
156 bio_reader_t *reader;
157 status_t status = FAILED;
158 funct_comp_evid_req_entry_t *entry = NULL;
159 u_int32_t sub_comp_depth, vendor_id, name;
160 u_int8_t flags, fam_and_qualifier, qualifier;
161
162 if (this->value.len < PTS_REQ_FUNCT_COMP_EVID_SIZE)
163 {
164 DBG1(DBG_TNC, "insufficient data for Request Functional "
165 "Component Evidence");
166 *offset = 0;
167 return FAILED;
168 }
169
170 reader = bio_reader_create(this->value);
171 this->requests = pts_funct_comp_evid_req_create();
172
173 while (reader->remaining(reader))
174 {
175 if (!reader->read_uint8(reader, &flags))
176 {
177 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
178 "Component Evidence Flags");
179 goto end;
180 }
181 if (!reader->read_uint24(reader, &sub_comp_depth))
182 {
183 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
184 "Component Evidence Sub Component Depth");
185 goto end;
186 }
187 if (!reader->read_uint24(reader, &vendor_id))
188 {
189 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
190 "Component Evidence Component Name Vendor ID");
191 goto end;
192 }
193 if (!reader->read_uint8(reader, &fam_and_qualifier))
194 {
195 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
196 "Component Evidence Family and Qualifier");
197 goto end;
198 }
199 if (fam_and_qualifier & PTS_REQ_FUNCT_COMP_FAMILY_MASK)
200 {
201 DBG1(DBG_TNC, "the Functional Name Encoding Family "
202 "is not Binary Enumeration");
203 goto end;
204 }
205 if (!reader->read_uint32(reader, &name))
206 {
207 DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
208 "Component Evidence Component Functional Name");
209 goto end;
210 }
211 qualifier = fam_and_qualifier & !PTS_REQ_FUNCT_COMP_FAMILY_MASK;
212
213 entry = malloc_thing(funct_comp_evid_req_entry_t);
214 entry->flags = flags;
215 entry->sub_comp_depth = sub_comp_depth;
216 entry->name = pts_comp_func_name_create(vendor_id, name, qualifier);
217
218 this->requests->add(this->requests, entry);
219 }
220 status = SUCCESS;
221
222 end:
223 if (entry)
224 {
225 free(entry);
226 }
227 reader->destroy(reader);
228 return status;
229 }
230
231 METHOD(pa_tnc_attr_t, destroy, void,
232 private_tcg_pts_attr_req_funct_comp_evid_t *this)
233 {
234 this->requests->destroy(this->requests);
235 free(this->value.ptr);
236 free(this);
237 }
238
239 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_requests,
240 pts_funct_comp_evid_req_t*,
241 private_tcg_pts_attr_req_funct_comp_evid_t *this)
242 {
243 return this->requests;
244 }
245
246 /**
247 * Described in header.
248 */
249 pa_tnc_attr_t *tcg_pts_attr_req_funct_comp_evid_create(
250 pts_funct_comp_evid_req_t *requests)
251 {
252 private_tcg_pts_attr_req_funct_comp_evid_t *this;
253
254 INIT(this,
255 .public = {
256 .pa_tnc_attribute = {
257 .get_vendor_id = _get_vendor_id,
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 .destroy = _destroy,
265 },
266 .get_requests = _get_requests,
267 },
268 .vendor_id = PEN_TCG,
269 .type = TCG_PTS_REQ_FUNCT_COMP_EVID,
270 .requests = requests,
271 );
272
273 return &this->public.pa_tnc_attribute;
274 }
275
276
277 /**
278 * Described in header.
279 */
280 pa_tnc_attr_t *tcg_pts_attr_req_funct_comp_evid_create_from_data(chunk_t data)
281 {
282 private_tcg_pts_attr_req_funct_comp_evid_t *this;
283
284 INIT(this,
285 .public = {
286 .pa_tnc_attribute = {
287 .get_vendor_id = _get_vendor_id,
288 .get_type = _get_type,
289 .get_value = _get_value,
290 .get_noskip_flag = _get_noskip_flag,
291 .set_noskip_flag = _set_noskip_flag,
292 .build = _build,
293 .process = _process,
294 .destroy = _destroy,
295 },
296 .get_requests = _get_requests,
297 },
298 .vendor_id = PEN_TCG,
299 .type = TCG_PTS_REQ_FUNCT_COMP_EVID,
300 .value = chunk_clone(data),
301 );
302
303 return &this->public.pa_tnc_attribute;
304 }