Finalized the implementation of TCG PTS Request Functional Component Evidence Attribute
[strongswan.git] / src / libimcv / 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 * Qualifier for Functional Component (see section 5.2 of PTS Protocol: Binding to TNC IF-M Specification)
27 *
28 *
29 * 0 1 2 3 4 5
30 * +-+-+-+-+-+-+
31 * |K|S| Type |
32 * +-+-+-+-+-+-+
33 */
34
35 /**
36 * Request Functional Component Evidence (see section 3.14.1 of PTS Protocol: Binding to TNC IF-M Specification)
37 *
38 * 1 2 3
39 * 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
40 *
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | Flags | Sub-component Depth |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | Component Functional Name |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 *
47 */
48
49 /**
50 * Component Functional Name Structure (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 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * | Component Functional Name Vendor ID |Fam| Qualifier |
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * | Component Functional Name |
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 *
61 */
62
63 #define PTS_REQ_FUNCT_COMP_EVID_SIZE 12
64 #define PTS_REQ_FUNCT_COMP_FAM_BIN_ENUM 0x00
65
66 /**
67 * Private data of an tcg_pts_attr_req_funct_comp_evid_t object.
68 */
69 struct private_tcg_pts_attr_req_funct_comp_evid_t {
70
71 /**
72 * Public members of tcg_pts_attr_req_funct_comp_evid_t
73 */
74 tcg_pts_attr_req_funct_comp_evid_t public;
75
76 /**
77 * Attribute vendor ID
78 */
79 pen_t vendor_id;
80
81 /**
82 * Attribute type
83 */
84 u_int32_t type;
85
86 /**
87 * Attribute value
88 */
89 chunk_t value;
90
91 /**
92 * Noskip flag
93 */
94 bool noskip_flag;
95
96 /**
97 * Set of flags for Request Functional Component
98 */
99 pts_attr_req_funct_comp_evid_flag_t flags;
100
101 /**
102 * Sub-component Depth
103 */
104 u_int32_t depth;
105
106 /**
107 * Component Functional Name Vendor ID
108 */
109 u_int32_t comp_vendor_id;
110
111 /**
112 * Functional Name Encoding Family
113 */
114 u_int8_t family;
115
116 /**
117 * Functional Name Category Qualifier
118 */
119 tcg_pts_qualifier_t qualifier;
120
121 /**
122 * Component Functional Name
123 */
124 u_int32_t name;
125 };
126
127 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
128 private_tcg_pts_attr_req_funct_comp_evid_t *this)
129 {
130 return this->vendor_id;
131 }
132
133 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
134 private_tcg_pts_attr_req_funct_comp_evid_t *this)
135 {
136 return this->type;
137 }
138
139 METHOD(pa_tnc_attr_t, get_value, chunk_t,
140 private_tcg_pts_attr_req_funct_comp_evid_t *this)
141 {
142 return this->value;
143 }
144
145 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
146 private_tcg_pts_attr_req_funct_comp_evid_t *this)
147 {
148 return this->noskip_flag;
149 }
150
151 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
152 private_tcg_pts_attr_req_funct_comp_evid_t *this, bool noskip)
153 {
154 this->noskip_flag = noskip;
155 }
156
157 METHOD(pa_tnc_attr_t, build, void,
158 private_tcg_pts_attr_req_funct_comp_evid_t *this)
159 {
160 bio_writer_t *writer;
161 u_int8_t flags = 0;
162 u_int8_t qualifier = 0;
163
164 writer = bio_writer_create(PTS_REQ_FUNCT_COMP_EVID_SIZE);
165
166 /* Determine the flags to set*/
167 if(this->flags & PTS_REQ_FUNC_COMP_FLAG_TTC) flags += 1;
168 if(this->flags & PTS_REQ_FUNC_COMP_FLAG_VER) flags += 2;
169 if(this->flags & PTS_REQ_FUNC_COMP_FLAG_CURR) flags += 4;
170 if(this->flags & PTS_REQ_FUNC_COMP_FLAG_PCR) flags += 8;
171 writer->write_uint8(writer, flags);
172
173 writer->write_uint24 (writer, this->depth);
174 writer->write_uint24 (writer, this->comp_vendor_id);
175
176 if(this->family != PTS_REQ_FUNCT_COMP_FAM_BIN_ENUM)
177 {
178 DBG1(DBG_TNC, "Functional Name Encoding Family is not set to 00");
179 }
180
181 qualifier += this->qualifier.type;
182 if(this->qualifier.kernel) qualifier += 16;
183 if(this->qualifier.sub_component) qualifier += 32;
184
185 writer->write_uint8 (writer, qualifier);
186 writer->write_uint32 (writer, this->name);
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_funct_comp_evid_t *this, u_int32_t *offset)
194 {
195 bio_reader_t *reader;
196 u_int8_t flags;
197 u_int8_t fam_and_qualifier;
198
199 if (this->value.len < PTS_REQ_FUNCT_COMP_EVID_SIZE)
200 {
201 DBG1(DBG_TNC, "insufficient data for Request Functional Component Evidence");
202 *offset = 0;
203 return FAILED;
204 }
205 reader = bio_reader_create(this->value);
206
207 reader->read_uint8(reader, &flags);
208 if((flags >> 0) & 1) this->flags |= PTS_REQ_FUNC_COMP_FLAG_TTC;
209 if((flags >> 1) & 1) this->flags |= PTS_REQ_FUNC_COMP_FLAG_VER;
210 if((flags >> 2) & 1) this->flags |= PTS_REQ_FUNC_COMP_FLAG_CURR;
211 if((flags >> 3) & 1) this->flags |= PTS_REQ_FUNC_COMP_FLAG_PCR;
212
213 reader->read_uint24(reader, &this->depth);
214 reader->read_uint24(reader, &this->comp_vendor_id);
215 reader->read_uint8(reader, &fam_and_qualifier);
216
217 if(((fam_and_qualifier >> 6) & 1) ) this->family += 64;
218 if(((fam_and_qualifier >> 7) & 1) ) this->family += 128;
219
220 /* TODO: Generate an IF-M error attribute indicating */
221 /* TCG_PTS_INVALID_NAME_FAM */
222 //if(&this->comp_vendor_id==PEN_TCG && this->family != PTS_REQ_FUNCT_COMP_FAM_BIN_ENUM)
223 //{
224 // DBG1(DBG_TNC, "Functional Name Encoding Family is not set to 00");
225 //}
226
227 if(((fam_and_qualifier >> 5) & 1) ) this->qualifier.kernel = true;
228 if(((fam_and_qualifier >> 4) & 1) ) this->qualifier.sub_component = true;
229 this->qualifier.type = ( fam_and_qualifier & 0xF );
230
231 /* TODO: Check the type is defined in pts_attr_req_funct_comp_type_t */
232
233 reader->destroy(reader);
234 return SUCCESS;
235 }
236
237 METHOD(pa_tnc_attr_t, destroy, void,
238 private_tcg_pts_attr_req_funct_comp_evid_t *this)
239 {
240 free(this->value.ptr);
241 free(this);
242 }
243
244 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_flags, pts_attr_req_funct_comp_evid_flag_t,
245 private_tcg_pts_attr_req_funct_comp_evid_t *this)
246 {
247 return this->flags;
248 }
249
250 METHOD(tcg_pts_attr_req_funct_comp_evid_t, set_flags, void,
251 private_tcg_pts_attr_req_funct_comp_evid_t *this, pts_attr_req_funct_comp_evid_flag_t flags)
252 {
253 this->flags = flags;
254 }
255
256 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_sub_component_depth, u_int32_t,
257 private_tcg_pts_attr_req_funct_comp_evid_t *this)
258 {
259 return this->depth;
260 }
261
262 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_comp_funct_name_vendor_id, u_int32_t,
263 private_tcg_pts_attr_req_funct_comp_evid_t *this)
264 {
265 return this->comp_vendor_id;
266 }
267
268 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_family, u_int8_t,
269 private_tcg_pts_attr_req_funct_comp_evid_t *this)
270 {
271 return this->family;
272 }
273
274 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_qualifier, tcg_pts_qualifier_t,
275 private_tcg_pts_attr_req_funct_comp_evid_t *this)
276 {
277 return this->qualifier;
278 }
279
280 METHOD(tcg_pts_attr_req_funct_comp_evid_t, set_qualifier, void,
281 private_tcg_pts_attr_req_funct_comp_evid_t *this,
282 tcg_pts_qualifier_t qualifier)
283 {
284 this->qualifier = qualifier;
285 }
286
287 METHOD(tcg_pts_attr_req_funct_comp_evid_t, get_comp_funct_name, u_int32_t,
288 private_tcg_pts_attr_req_funct_comp_evid_t *this)
289 {
290 return this->name;
291 }
292
293 METHOD(tcg_pts_attr_req_funct_comp_evid_t, set_comp_funct_name, void,
294 private_tcg_pts_attr_req_funct_comp_evid_t *this, u_int32_t name)
295 {
296 this->name = name;
297 }
298
299 /**
300 * Described in header.
301 */
302 pa_tnc_attr_t *tcg_pts_attr_req_funct_comp_evid_create(
303 pts_attr_req_funct_comp_evid_flag_t flags,
304 u_int32_t depth,
305 u_int32_t vendor_id,
306 tcg_pts_qualifier_t qualifier,
307 u_int32_t name)
308 {
309 private_tcg_pts_attr_req_funct_comp_evid_t *this;
310
311 INIT(this,
312 .public = {
313 .pa_tnc_attribute = {
314 .get_vendor_id = _get_vendor_id,
315 .get_type = _get_type,
316 .get_value = _get_value,
317 .get_noskip_flag = _get_noskip_flag,
318 .set_noskip_flag = _set_noskip_flag,
319 .build = _build,
320 .process = _process,
321 .destroy = _destroy,
322 },
323 .get_flags= _get_flags,
324 .set_flags= _set_flags,
325 .get_sub_component_depth = _get_sub_component_depth,
326 .get_comp_funct_name_vendor_id = _get_comp_funct_name_vendor_id,
327 .get_family = _get_family,
328 .get_qualifier = _get_qualifier,
329 .set_qualifier = _set_qualifier,
330 .get_comp_funct_name = _get_comp_funct_name,
331 .set_comp_funct_name = _set_comp_funct_name,
332 },
333 .vendor_id = PEN_TCG,
334 .type = TCG_PTS_REQ_FUNCT_COMP_EVID,
335 .flags = flags,
336 .depth = depth,
337 .comp_vendor_id = vendor_id,
338 .family = PTS_REQ_FUNCT_COMP_FAM_BIN_ENUM,
339 .qualifier = qualifier,
340 .name = name,
341 );
342
343 return &this->public.pa_tnc_attribute;
344 }
345
346
347 /**
348 * Described in header.
349 */
350 pa_tnc_attr_t *tcg_pts_attr_req_funct_comp_evid_create_from_data(chunk_t data)
351 {
352 private_tcg_pts_attr_req_funct_comp_evid_t *this;
353
354 INIT(this,
355 .public = {
356 .pa_tnc_attribute = {
357 .get_vendor_id = _get_vendor_id,
358 .get_type = _get_type,
359 .get_value = _get_value,
360 .get_noskip_flag = _get_noskip_flag,
361 .set_noskip_flag = _set_noskip_flag,
362 .build = _build,
363 .process = _process,
364 .destroy = _destroy,
365 },
366 .get_flags= _get_flags,
367 .set_flags= _set_flags,
368 .get_sub_component_depth = _get_sub_component_depth,
369 .get_comp_funct_name_vendor_id = _get_comp_funct_name_vendor_id,
370 .get_family = _get_family,
371 .get_qualifier = _get_qualifier,
372 .set_qualifier = _set_qualifier,
373 .get_comp_funct_name = _get_comp_funct_name,
374 .set_comp_funct_name = _set_comp_funct_name,
375 },
376 .vendor_id = PEN_TCG,
377 .type = TCG_PTS_REQ_FUNCT_COMP_EVID,
378 .value = chunk_clone(data),
379 );
380
381 return &this->public.pa_tnc_attribute;
382 }