object oriented approach to pts functional components
[strongswan.git] / src / libpts / tcg / tcg_pts_attr_simple_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_simple_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_simple_comp_evid_t private_tcg_pts_attr_simple_comp_evid_t;
24
25 /**
26 * Simple Component Evidence
27 * see section 3.15.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 |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Specific Functional Component |
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | Specific Functional Component |
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | Measure. Type | Extended into PCR |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * | Hash Algorithm | PCR Transform | Reserved |
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | Measurement Date/Time |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | Measurement Date/Time |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 * | Measurement Date/Time |
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * | Measurement Date/Time |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * | Measurement Date/Time |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * | Optional Policy URI Length | Opt. Verification Policy URI ~
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 * ~ Optional Verification Policy URI ~
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
56 * | Optional PCR Length | Optional PCR Before Value ~
57 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
58 * ~ Optional PCR Before Value (Variable Length) ~
59 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
60 * ~ Optional PCR After Value (Variable Length) ~
61 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
62 * ~ Component Measurement (Variable Length) ~
63 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
64 */
65
66 /**
67 * Specific Functional Component -> Component Functional Name Structure
68 * see section 5.1 of PTS Protocol: Binding to TNC IF-M Specification
69 *
70 * 1 2 3
71 * 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
72 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73 * | Component Functional Name Vendor ID |Fam| Qualifier |
74 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75 * | Component Functional Name |
76 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 *
78 */
79
80 #define PTS_SIMPLE_COMP_EVID_SIZE 40
81 #define PTS_SIMPLE_COMP_EVID_MEASUREMENT_TIME_SIZE 20
82 #define PTS_SIMPLE_COMP_EVID_RESERVED 0x00
83 #define PTS_SIMPLE_COMP_EVID_FAMILY_MASK 0xC0
84
85 /**
86 * Private data of an tcg_pts_attr_simple_comp_evid_t object.
87 */
88 struct private_tcg_pts_attr_simple_comp_evid_t {
89
90 /**
91 * Public members of tcg_pts_attr_simple_comp_evid_t
92 */
93 tcg_pts_attr_simple_comp_evid_t public;
94
95 /**
96 * Attribute vendor ID
97 */
98 pen_t vendor_id;
99
100 /**
101 * Attribute type
102 */
103 u_int32_t type;
104
105 /**
106 * Attribute value
107 */
108 chunk_t value;
109
110 /**
111 * Noskip flag
112 */
113 bool noskip_flag;
114
115 /**
116 * Set of flags for Simple Component Evidence
117 */
118 pts_attr_simple_comp_evid_flag_t flags;
119
120 /**
121 * PCR Information included
122 */
123 bool pcr_info_included;
124
125 /**
126 * Sub-component Depth
127 */
128 u_int32_t depth;
129
130 /**
131 * Component Functional Name
132 */
133 pts_comp_func_name_t *name;
134
135 /**
136 * Measurement type
137 */
138 u_int8_t measurement_type;
139
140 /**
141 * Which PCR the functional component is extended into
142 */
143 u_int32_t extended_pcr;
144
145 /**
146 * Hash Algorithm
147 */
148 pts_meas_algorithms_t hash_algorithm;
149
150 /**
151 * Transformation type for PCR
152 */
153 pts_pcr_transform_t transformation;
154
155 /**
156 * Measurement time
157 */
158 chunk_t measurement_time;
159
160 /**
161 * Optional Policy URI
162 */
163 chunk_t policy_uri;
164
165 /**
166 * Optional PCR before value
167 */
168 chunk_t pcr_before;
169
170 /**
171 * Optional PCR after value
172 */
173 chunk_t pcr_after;
174
175 /**
176 * Component Measurement
177 */
178 chunk_t measurement;
179
180 };
181
182 METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
183 private_tcg_pts_attr_simple_comp_evid_t *this)
184 {
185 return this->vendor_id;
186 }
187
188 METHOD(pa_tnc_attr_t, get_type, u_int32_t,
189 private_tcg_pts_attr_simple_comp_evid_t *this)
190 {
191 return this->type;
192 }
193
194 METHOD(pa_tnc_attr_t, get_value, chunk_t,
195 private_tcg_pts_attr_simple_comp_evid_t *this)
196 {
197 return this->value;
198 }
199
200 METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
201 private_tcg_pts_attr_simple_comp_evid_t *this)
202 {
203 return this->noskip_flag;
204 }
205
206 METHOD(pa_tnc_attr_t, set_noskip_flag,void,
207 private_tcg_pts_attr_simple_comp_evid_t *this, bool noskip)
208 {
209 this->noskip_flag = noskip;
210 }
211
212 METHOD(pa_tnc_attr_t, build, void,
213 private_tcg_pts_attr_simple_comp_evid_t *this)
214 {
215 bio_writer_t *writer;
216 u_int8_t flags = 0;
217
218 writer = bio_writer_create(PTS_SIMPLE_COMP_EVID_SIZE);
219 /* Determine the flags to set*/
220 if (this->pcr_info_included)
221 {
222 flags += 128;
223 }
224 if (this->flags == PTS_SIMPLE_COMP_EVID_FLAG_NO_VER)
225 {
226 flags += 32;
227 }
228 else if (this->flags == PTS_SIMPLE_COMP_EVID_FLAG_VER_FAIL)
229 {
230 flags += 64;
231 }
232 else if (this->flags == PTS_SIMPLE_COMP_EVID_FLAG_VER_PASS)
233 {
234 flags += 96;
235 }
236
237 writer->write_uint8 (writer, flags);
238 writer->write_uint24(writer, this->depth);
239 writer->write_uint24(writer, this->name->get_vendor_id(this->name));
240 writer->write_uint8 (writer, this->name->get_qualifier(this->name));
241 writer->write_uint32(writer, this->name->get_name(this->name));
242 writer->write_uint8 (writer, (this->measurement_type << 7));
243 writer->write_uint24(writer, this->extended_pcr);
244 writer->write_uint16(writer, this->hash_algorithm);
245 writer->write_uint8 (writer, this->transformation);
246 writer->write_data (writer, this->measurement_time);
247
248 /* Optional fields */
249 if (this->policy_uri.ptr && this->policy_uri.len > 0)
250 {
251 writer->write_uint16(writer, this->policy_uri.len);
252 writer->write_data (writer, this->policy_uri);
253 }
254 if (this->pcr_before.ptr && this->pcr_after.ptr &&
255 this->pcr_before.len == this->pcr_after.len &&
256 this->pcr_before.len > 0 && this->pcr_after.len > 0)
257 {
258 writer->write_uint16(writer, this->pcr_before.len);
259 writer->write_data (writer, this->pcr_before);
260 writer->write_data (writer, this->pcr_after);
261 }
262
263 if (this->measurement.ptr && this->measurement.len > 0)
264 {
265 writer->write_data (writer, this->measurement);
266 }
267
268 this->value = chunk_clone(writer->get_buf(writer));
269 writer->destroy(writer);
270 }
271
272 METHOD(pa_tnc_attr_t, process, status_t,
273 private_tcg_pts_attr_simple_comp_evid_t *this, u_int32_t *offset)
274 {
275 bio_reader_t *reader;
276 u_int8_t flags, fam_and_qualifier, qualifier;
277 u_int8_t measurement_type, transformation;
278 u_int16_t algorithm;
279 u_int32_t vendor_id, name, measurement_len;
280
281 if (this->value.len < PTS_SIMPLE_COMP_EVID_SIZE)
282 {
283 DBG1(DBG_TNC, "insufficient data for Simple Component Evidence");
284 *offset = 0;
285 return FAILED;
286 }
287 reader = bio_reader_create(this->value);
288
289 reader->read_uint8(reader, &flags);
290 /* Determine the flags to set*/
291 if ((flags >> 7) & 1)
292 {
293 this->pcr_info_included = TRUE;
294 }
295 if (!((flags >> 6) & 1) && !((flags >> 5) & 1))
296 {
297 this->flags = PTS_SIMPLE_COMP_EVID_FLAG_NO_VALID;
298 }
299 else if (!((flags >> 6) & 1) && ((flags >> 5) & 1))
300 {
301 this->flags = PTS_SIMPLE_COMP_EVID_FLAG_NO_VER;
302 }
303 else if (((flags >> 6) & 1) && !((flags >> 5) & 1))
304 {
305 this->flags = PTS_SIMPLE_COMP_EVID_FLAG_VER_FAIL;
306 }
307 else if (((flags >> 6) & 1) && ((flags >> 5) & 1))
308 {
309 this->flags = PTS_SIMPLE_COMP_EVID_FLAG_VER_PASS;
310 }
311
312 reader->read_uint24(reader, &this->depth);
313 reader->read_uint24(reader, &vendor_id);
314 reader->read_uint8 (reader, &fam_and_qualifier);
315 reader->read_uint32(reader, &name);
316 reader->read_uint8 (reader, &measurement_type);
317 reader->read_uint24(reader, &this->extended_pcr);
318 reader->read_uint16(reader, &algorithm);
319 reader->read_uint8 (reader, &transformation);
320 reader->read_data (reader, PTS_SIMPLE_COMP_EVID_MEASUREMENT_TIME_SIZE,
321 &this->measurement_time);
322
323 qualifier = fam_and_qualifier & (!PTS_SIMPLE_COMP_EVID_FAMILY_MASK);
324
325 this->name = pts_comp_func_name_create(vendor_id, name, qualifier);
326 this->measurement_type = (measurement_type >> 7 ) & 1;
327 this->hash_algorithm = algorithm;
328 this->transformation = transformation;
329 this->measurement_time = chunk_clone(this->measurement_time);
330
331 /* Optional Policy URI field is included */
332 if ((this->flags == PTS_SIMPLE_COMP_EVID_FLAG_VER_FAIL) ||
333 (this->flags == PTS_SIMPLE_COMP_EVID_FLAG_VER_PASS))
334 {
335 u_int16_t policy_uri_len;
336 reader->read_uint16(reader, &policy_uri_len);
337 reader->read_data(reader, policy_uri_len, &this->policy_uri);
338 this->policy_uri = chunk_clone(this->policy_uri);
339 }
340
341 /* Optional PCR value fields are included */
342 if (this->pcr_info_included)
343 {
344 u_int16_t pcr_value_len;
345 reader->read_uint16(reader, &pcr_value_len);
346 reader->read_data(reader, pcr_value_len, &this->pcr_before);
347 this->pcr_before = chunk_clone(this->pcr_before);
348 reader->read_data(reader, pcr_value_len, &this->pcr_after);
349 this->pcr_after = chunk_clone(this->pcr_after);
350 }
351 measurement_len = reader->remaining(reader);
352 reader->read_data(reader, measurement_len, &this->measurement);
353 this->measurement = chunk_clone(this->measurement);
354
355 reader->destroy(reader);
356 return SUCCESS;
357 }
358
359 METHOD(pa_tnc_attr_t, destroy, void,
360 private_tcg_pts_attr_simple_comp_evid_t *this)
361 {
362 free(this->value.ptr);
363 free(this->measurement_time.ptr);
364 free(this->policy_uri.ptr);
365 free(this->pcr_before.ptr);
366 free(this->pcr_after.ptr);
367 free(this->measurement.ptr);
368 free(this);
369 }
370
371 METHOD(tcg_pts_attr_simple_comp_evid_t, is_pcr_info_included, bool,
372 private_tcg_pts_attr_simple_comp_evid_t *this)
373 {
374 return this->pcr_info_included;
375 }
376
377 METHOD(tcg_pts_attr_simple_comp_evid_t, get_flags, pts_attr_simple_comp_evid_flag_t,
378 private_tcg_pts_attr_simple_comp_evid_t *this)
379 {
380 return this->flags;
381 }
382
383 METHOD(tcg_pts_attr_simple_comp_evid_t, get_sub_component_depth, u_int32_t,
384 private_tcg_pts_attr_simple_comp_evid_t *this)
385 {
386 return this->depth;
387 }
388
389 METHOD(tcg_pts_attr_simple_comp_evid_t, get_comp_func_name, pts_comp_func_name_t*,
390 private_tcg_pts_attr_simple_comp_evid_t *this)
391 {
392 return this->name;
393 }
394
395 METHOD(tcg_pts_attr_simple_comp_evid_t, get_measurement_type, u_int8_t,
396 private_tcg_pts_attr_simple_comp_evid_t *this)
397 {
398 return this->measurement_type;
399 }
400
401 METHOD(tcg_pts_attr_simple_comp_evid_t, get_extended_pcr, u_int32_t,
402 private_tcg_pts_attr_simple_comp_evid_t *this)
403 {
404 return this->extended_pcr;
405 }
406
407 METHOD(tcg_pts_attr_simple_comp_evid_t, get_hash_algorithm, pts_meas_algorithms_t,
408 private_tcg_pts_attr_simple_comp_evid_t *this)
409 {
410 return this->hash_algorithm;
411 }
412
413 METHOD(tcg_pts_attr_simple_comp_evid_t, get_pcr_trans, pts_pcr_transform_t,
414 private_tcg_pts_attr_simple_comp_evid_t *this)
415 {
416 return this->transformation;
417 }
418
419 METHOD(tcg_pts_attr_simple_comp_evid_t, get_measurement_time, chunk_t,
420 private_tcg_pts_attr_simple_comp_evid_t *this)
421 {
422 return this->measurement_time;
423 }
424
425 METHOD(tcg_pts_attr_simple_comp_evid_t, get_policy_uri, chunk_t,
426 private_tcg_pts_attr_simple_comp_evid_t *this)
427 {
428 return this->policy_uri;
429 }
430
431 METHOD(tcg_pts_attr_simple_comp_evid_t, get_pcr_before_value, chunk_t,
432 private_tcg_pts_attr_simple_comp_evid_t *this)
433 {
434 return this->pcr_before;
435 }
436
437 METHOD(tcg_pts_attr_simple_comp_evid_t, get_pcr_after_value, chunk_t,
438 private_tcg_pts_attr_simple_comp_evid_t *this)
439 {
440 return this->pcr_after;
441 }
442
443 METHOD(tcg_pts_attr_simple_comp_evid_t, get_pcr_len, u_int16_t,
444 private_tcg_pts_attr_simple_comp_evid_t *this)
445 {
446 if (this->pcr_before.ptr && this->pcr_after.ptr &&
447 this->pcr_before.len == this->pcr_after.len &&
448 this->pcr_before.len > 0 && this->pcr_after.len > 0)
449 {
450 return this->pcr_before.len;
451 }
452 return 0;
453 }
454
455 METHOD(tcg_pts_attr_simple_comp_evid_t, get_comp_measurement, chunk_t,
456 private_tcg_pts_attr_simple_comp_evid_t *this)
457 {
458 return this->measurement;
459 }
460
461 /**
462 * Described in header.
463 */
464 pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(tcg_pts_attr_simple_comp_evid_params_t params)
465 {
466 private_tcg_pts_attr_simple_comp_evid_t *this;
467
468 INIT(this,
469 .public = {
470 .pa_tnc_attribute = {
471 .get_vendor_id = _get_vendor_id,
472 .get_type = _get_type,
473 .get_value = _get_value,
474 .get_noskip_flag = _get_noskip_flag,
475 .set_noskip_flag = _set_noskip_flag,
476 .build = _build,
477 .process = _process,
478 .destroy = _destroy,
479 },
480 .is_pcr_info_included = _is_pcr_info_included,
481 .get_flags= _get_flags,
482 .get_sub_component_depth = _get_sub_component_depth,
483 .get_comp_func_name = _get_comp_func_name,
484 .get_measurement_type = _get_measurement_type,
485 .get_extended_pcr = _get_extended_pcr,
486 .get_hash_algorithm = _get_hash_algorithm,
487 .get_pcr_trans = _get_pcr_trans,
488 .get_measurement_time = _get_measurement_time,
489 .get_policy_uri = _get_policy_uri,
490 .get_pcr_before_value = _get_pcr_before_value,
491 .get_pcr_after_value = _get_pcr_after_value,
492 .get_pcr_len = _get_pcr_len,
493 .get_comp_measurement = _get_comp_measurement,
494 },
495 .vendor_id = PEN_TCG,
496 .type = TCG_PTS_SIMPLE_COMP_EVID,
497 .pcr_info_included = params.pcr_info_included,
498 .flags = params.flags,
499 .depth = params.depth,
500 .name = params.name,
501 .extended_pcr = params.extended_pcr,
502 .hash_algorithm = params.hash_algorithm,
503 .transformation = params.transformation,
504 .measurement_time = params.measurement_time,
505 .policy_uri = chunk_clone(params.policy_uri),
506 .pcr_before = params.pcr_before,
507 .pcr_after = params.pcr_after,
508 .measurement = params.measurement,
509 );
510
511 return &this->public.pa_tnc_attribute;
512 }
513
514
515 /**
516 * Described in header.
517 */
518 pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data)
519 {
520 private_tcg_pts_attr_simple_comp_evid_t *this;
521
522 INIT(this,
523 .public = {
524 .pa_tnc_attribute = {
525 .get_vendor_id = _get_vendor_id,
526 .get_type = _get_type,
527 .get_value = _get_value,
528 .get_noskip_flag = _get_noskip_flag,
529 .set_noskip_flag = _set_noskip_flag,
530 .build = _build,
531 .process = _process,
532 .destroy = _destroy,
533 },
534 .is_pcr_info_included = _is_pcr_info_included,
535 .get_flags= _get_flags,
536 .get_sub_component_depth = _get_sub_component_depth,
537 .get_comp_func_name = _get_comp_func_name,
538 .get_measurement_type = _get_measurement_type,
539 .get_extended_pcr = _get_extended_pcr,
540 .get_hash_algorithm = _get_hash_algorithm,
541 .get_pcr_trans = _get_pcr_trans,
542 .get_measurement_time = _get_measurement_time,
543 .get_policy_uri = _get_policy_uri,
544 .get_pcr_before_value = _get_pcr_before_value,
545 .get_pcr_after_value = _get_pcr_after_value,
546 .get_pcr_len = _get_pcr_len,
547 .get_comp_measurement = _get_comp_measurement,
548 },
549 .vendor_id = PEN_TCG,
550 .type = TCG_PTS_SIMPLE_COMP_EVID,
551 .value = chunk_clone(data),
552 );
553
554 return &this->public.pa_tnc_attribute;
555 }