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