f8d56d92411795eee58a4611fe00d85e1b446de5
[strongswan.git] / src / libimcv / plugins / imc_attestation / imc_attestation_process.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 #define _GNU_SOURCE
17
18 #include <stdio.h>
19 /* for isdigit */
20 #include <ctype.h>
21
22 #include "imc_attestation_process.h"
23
24 #include <ietf/ietf_attr_pa_tnc_error.h>
25 #include <pts/pts.h>
26
27 #include <tcg/tcg_pts_attr_proto_caps.h>
28 #include <tcg/tcg_pts_attr_meas_algo.h>
29 #include <tcg/tcg_pts_attr_dh_nonce_params_req.h>
30 #include <tcg/tcg_pts_attr_dh_nonce_params_resp.h>
31 #include <tcg/tcg_pts_attr_dh_nonce_finish.h>
32 #include <tcg/tcg_pts_attr_get_tpm_version_info.h>
33 #include <tcg/tcg_pts_attr_tpm_version_info.h>
34 #include <tcg/tcg_pts_attr_get_aik.h>
35 #include <tcg/tcg_pts_attr_aik.h>
36 #include <tcg/tcg_pts_attr_req_func_comp_evid.h>
37 #include <tcg/tcg_pts_attr_gen_attest_evid.h>
38 #include <tcg/tcg_pts_attr_simple_comp_evid.h>
39 #include <tcg/tcg_pts_attr_simple_evid_final.h>
40 #include <tcg/tcg_pts_attr_req_file_meas.h>
41 #include <tcg/tcg_pts_attr_file_meas.h>
42 #include <tcg/tcg_pts_attr_req_file_meta.h>
43 #include <tcg/tcg_pts_attr_unix_file_meta.h>
44
45 #include <debug.h>
46 #include <utils/lexparser.h>
47
48 #define DEFAULT_NONCE_LEN 20
49
50 /**
51 * Set parameters of Simple Component Evidence
52 */
53 static bool set_simple_comp_evid_params(pts_t *pts, pts_comp_func_name_t *name,
54 u_int8_t sequence, tcg_pts_attr_simple_comp_evid_params_t *out)
55 {
56 tcg_pts_attr_simple_comp_evid_params_t params;
57 time_t measurement_time_t;
58 struct tm *time_now;
59 char *utc_time;
60
61 params.name = name;
62 params.pcr_info_included = TRUE;
63 params.flags = PTS_SIMPLE_COMP_EVID_FLAG_NO_VALID;
64 params.depth = 0;
65
66 /* The measurements done by tboot and trustedGRUB are SHA1 hashes */
67 params.hash_algorithm = TRUSTED_HASH_ALGO;
68 params.transformation = PTS_PCR_TRANSFORM_NO;
69
70 measurement_time_t = time(NULL);
71 if (!measurement_time_t)
72 {
73 params.measurement_time = chunk_create("0000-00-00T00:00:00Z", 20);
74 params.measurement_time = chunk_clone(params.measurement_time);
75 }
76 else
77 {
78 time_now = localtime(&measurement_time_t);
79 if (asprintf(&utc_time,
80 "%d-%.2d-%.2dT%.2d:%.2d:%.2dZ",
81 time_now->tm_year + 1900,
82 time_now->tm_mon + 1,
83 time_now->tm_mday,
84 time_now->tm_hour,
85 time_now->tm_min,
86 time_now->tm_sec) < 0)
87 {
88 DBG1(DBG_IMC, "could not format local time to UTC");
89 return FALSE;
90 }
91 params.measurement_time = chunk_create(utc_time, 20);
92 params.measurement_time = chunk_clone(params.measurement_time);
93 free(utc_time);
94 }
95
96 params.policy_uri = chunk_empty;
97
98 /* Provisional/temporal implementation for components except tboot */
99 if (params.name->get_name(params.name) == PTS_ITA_COMP_FUNC_NAME_TGRUB)
100 {
101 params.extended_pcr = PCR_DEBUG;
102
103 params.measurement = chunk_alloc(HASH_SIZE_SHA1);
104 memset(params.measurement.ptr, 0, HASH_SIZE_SHA1);
105
106 params.pcr_before = chunk_alloc(PCR_LEN);
107 memset(params.pcr_before.ptr, 0, PCR_LEN);
108
109 if(!pts->read_pcr(pts, params.extended_pcr, &params.pcr_after))
110 {
111 DBG1(DBG_IMC, "error occured while reading PCR: %d",
112 params.extended_pcr);
113 return FALSE;
114 }
115 }
116 /* Set parameters which varies from component to component */
117 else if (params.name->get_name(params.name) == PTS_ITA_COMP_FUNC_NAME_TBOOT)
118 {
119 char *measurement, *pcr_before, *pcr_after;
120
121 if (sequence == 1)
122 {
123 params.extended_pcr = PCR_TBOOT_POLICY;
124 measurement = lib->settings->get_str(lib->settings,
125 "libimcv.plugins.imc-attestation.pcr17_meas", NULL);
126 pcr_before = lib->settings->get_str(lib->settings,
127 "libimcv.plugins.imc-attestation.pcr17_before", NULL);
128 pcr_after = lib->settings->get_str(lib->settings,
129 "libimcv.plugins.imc-attestation.pcr17_after", NULL);
130 }
131 else
132 {
133 params.extended_pcr = PCR_TBOOT_MLE;
134 measurement = lib->settings->get_str(lib->settings,
135 "libimcv.plugins.imc-attestation.pcr18_meas", NULL);
136 pcr_before = lib->settings->get_str(lib->settings,
137 "libimcv.plugins.imc-attestation.pcr18_before", NULL);
138 pcr_after = lib->settings->get_str(lib->settings,
139 "libimcv.plugins.imc-attestation.pcr18_after", NULL);
140 }
141
142 if (!measurement || !pcr_before || !pcr_after)
143 {
144 DBG1(DBG_IMC, "tboot: configure measurement, before and after value"
145 " for PCR%d", params.extended_pcr);
146 return FALSE;
147 }
148
149 params.measurement = chunk_from_hex(
150 chunk_create(measurement, strlen(measurement)), NULL);
151 params.pcr_before = chunk_from_hex(
152 chunk_create(pcr_before, strlen(pcr_before)), NULL);
153 params.pcr_after = chunk_from_hex(
154 chunk_create(pcr_after, strlen(pcr_after)), NULL);
155
156 }
157 else
158 {
159 DBG1(DBG_IMC, "unsupported Functional Component Name: Vendor ID: %d"
160 " Name: %d, Qualifier: %d",
161 params.name->get_vendor_id(params.name),
162 params.name->get_name(params.name),
163 params.name->get_qualifier(params.name));
164 return FALSE;
165 }
166
167 *out = params;
168 return TRUE;
169 }
170
171 bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
172 imc_attestation_state_t *attestation_state,
173 pts_meas_algorithms_t supported_algorithms,
174 pts_dh_group_t supported_dh_groups,
175 linked_list_t *evidences)
176 {
177 chunk_t attr_info;
178 pts_t *pts;
179 pts_error_code_t pts_error;
180 bool valid_path;
181
182 pts = attestation_state->get_pts(attestation_state);
183 switch (attr->get_type(attr))
184 {
185 case TCG_PTS_REQ_PROTO_CAPS:
186 {
187 tcg_pts_attr_proto_caps_t *attr_cast;
188 pts_proto_caps_flag_t imc_caps, imv_caps;
189
190 attr_cast = (tcg_pts_attr_proto_caps_t*)attr;
191 imv_caps = attr_cast->get_flags(attr_cast);
192 imc_caps = pts->get_proto_caps(pts);
193 pts->set_proto_caps(pts, imc_caps & imv_caps);
194
195 /* Send PTS Protocol Capabilities attribute */
196 attr = tcg_pts_attr_proto_caps_create(imc_caps & imv_caps, FALSE);
197 attr_list->insert_last(attr_list, attr);
198 break;
199 }
200 case TCG_PTS_MEAS_ALGO:
201 {
202 tcg_pts_attr_meas_algo_t *attr_cast;
203 pts_meas_algorithms_t offered_algorithms, selected_algorithm;
204
205 attr_cast = (tcg_pts_attr_meas_algo_t*)attr;
206 offered_algorithms = attr_cast->get_algorithms(attr_cast);
207 selected_algorithm = pts_meas_algo_select(supported_algorithms,
208 offered_algorithms);
209 if (selected_algorithm == PTS_MEAS_ALGO_NONE)
210 {
211 attr = pts_hash_alg_error_create(supported_algorithms);
212 attr_list->insert_last(attr_list, attr);
213 break;
214 }
215
216 /* Send Measurement Algorithm Selection attribute */
217 pts->set_meas_algorithm(pts, selected_algorithm);
218 attr = tcg_pts_attr_meas_algo_create(selected_algorithm, TRUE);
219 attr_list->insert_last(attr_list, attr);
220 break;
221 }
222 case TCG_PTS_DH_NONCE_PARAMS_REQ:
223 {
224 tcg_pts_attr_dh_nonce_params_req_t *attr_cast;
225 pts_dh_group_t offered_dh_groups, selected_dh_group;
226 chunk_t responder_value, responder_nonce;
227 int nonce_len, min_nonce_len;
228
229 nonce_len = lib->settings->get_int(lib->settings,
230 "libimcv.plugins.imc-attestation.nonce_len",
231 DEFAULT_NONCE_LEN);
232
233 attr_cast = (tcg_pts_attr_dh_nonce_params_req_t*)attr;
234 min_nonce_len = attr_cast->get_min_nonce_len(attr_cast);
235 if (nonce_len < PTS_MIN_NONCE_LEN ||
236 (min_nonce_len > 0 && nonce_len < min_nonce_len))
237 {
238 attr = pts_dh_nonce_error_create(nonce_len, PTS_MAX_NONCE_LEN);
239 attr_list->insert_last(attr_list, attr);
240 break;
241 }
242
243 offered_dh_groups = attr_cast->get_dh_groups(attr_cast);
244 selected_dh_group = pts_dh_group_select(supported_dh_groups,
245 offered_dh_groups);
246 if (selected_dh_group == PTS_DH_GROUP_NONE)
247 {
248 attr = pts_dh_group_error_create(supported_dh_groups);
249 attr_list->insert_last(attr_list, attr);
250 break;
251 }
252
253 /* Create own DH factor and nonce */
254 if (!pts->create_dh_nonce(pts, selected_dh_group, nonce_len))
255 {
256 return FALSE;
257 }
258 pts->get_my_public_value(pts, &responder_value, &responder_nonce);
259
260 /* Send DH Nonce Parameters Response attribute */
261 attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group,
262 supported_algorithms, responder_nonce, responder_value);
263 attr_list->insert_last(attr_list, attr);
264 break;
265 }
266 case TCG_PTS_DH_NONCE_FINISH:
267 {
268 tcg_pts_attr_dh_nonce_finish_t *attr_cast;
269 pts_meas_algorithms_t selected_algorithm;
270 chunk_t initiator_nonce, initiator_value;
271 int nonce_len;
272
273 attr_cast = (tcg_pts_attr_dh_nonce_finish_t*)attr;
274 selected_algorithm = attr_cast->get_hash_algo(attr_cast);
275 if (!(selected_algorithm & supported_algorithms))
276 {
277 DBG1(DBG_IMC, "PTS-IMV selected unsupported DH hash algorithm");
278 return FALSE;
279 }
280 pts->set_dh_hash_algorithm(pts, selected_algorithm);
281
282 initiator_value = attr_cast->get_initiator_value(attr_cast);
283 initiator_nonce = attr_cast->get_initiator_nonce(attr_cast);
284
285 nonce_len = lib->settings->get_int(lib->settings,
286 "libimcv.plugins.imc-attestation.nonce_len",
287 DEFAULT_NONCE_LEN);
288 if (nonce_len != initiator_nonce.len)
289 {
290 DBG1(DBG_IMC, "initiator and responder DH nonces "
291 "have differing lengths");
292 return FALSE;
293 }
294
295 pts->set_peer_public_value(pts, initiator_value, initiator_nonce);
296 if (!pts->calculate_secret(pts))
297 {
298 return FALSE;
299 }
300 break;
301 }
302 case TCG_PTS_GET_TPM_VERSION_INFO:
303 {
304 chunk_t tpm_version_info, attr_info;
305
306 if (!pts->get_tpm_version_info(pts, &tpm_version_info))
307 {
308 attr_info = attr->get_value(attr);
309 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
310 TCG_PTS_TPM_VERS_NOT_SUPPORTED, attr_info);
311 attr_list->insert_last(attr_list, attr);
312 break;
313 }
314
315 /* Send TPM Version Info attribute */
316 attr = tcg_pts_attr_tpm_version_info_create(tpm_version_info);
317 attr_list->insert_last(attr_list, attr);
318 break;
319 }
320 case TCG_PTS_GET_AIK:
321 {
322 certificate_t *aik;
323
324 aik = pts->get_aik(pts);
325 if (!aik)
326 {
327 DBG1(DBG_IMC, "no AIK certificate or public key available");
328 break;
329 }
330
331 /* Send AIK attribute */
332 attr = tcg_pts_attr_aik_create(aik);
333 attr_list->insert_last(attr_list, attr);
334 break;
335 }
336 case TCG_PTS_REQ_FILE_MEAS:
337 {
338 tcg_pts_attr_req_file_meas_t *attr_cast;
339 char *pathname;
340 u_int16_t request_id;
341 bool is_directory;
342 u_int32_t delimiter;
343 pts_file_meas_t *measurements;
344
345 attr_info = attr->get_value(attr);
346 attr_cast = (tcg_pts_attr_req_file_meas_t*)attr;
347 is_directory = attr_cast->get_directory_flag(attr_cast);
348 request_id = attr_cast->get_request_id(attr_cast);
349 delimiter = attr_cast->get_delimiter(attr_cast);
350 pathname = attr_cast->get_pathname(attr_cast);
351 valid_path = pts->is_path_valid(pts, pathname, &pts_error);
352
353 if (valid_path && pts_error)
354 {
355 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
356 pts_error, attr_info);
357 attr_list->insert_last(attr_list, attr);
358 break;
359 }
360 else if (!valid_path)
361 {
362 break;
363 }
364
365 if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
366 {
367 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
368 TCG_PTS_INVALID_DELIMITER, attr_info);
369 attr_list->insert_last(attr_list, attr);
370 break;
371 }
372
373 /* Do PTS File Measurements and send them to PTS-IMV */
374 DBG2(DBG_IMC, "measurement request %d for %s '%s'",
375 request_id, is_directory ? "directory" : "file",
376 pathname);
377 measurements = pts->do_measurements(pts, request_id,
378 pathname, is_directory);
379 if (!measurements)
380 {
381 /* TODO handle error codes from measurements */
382 return FALSE;
383 }
384 attr = tcg_pts_attr_file_meas_create(measurements);
385 attr->set_noskip_flag(attr, TRUE);
386 attr_list->insert_last(attr_list, attr);
387 break;
388 }
389 case TCG_PTS_REQ_FILE_META:
390 {
391 tcg_pts_attr_req_file_meta_t *attr_cast;
392 char *pathname;
393 bool is_directory;
394 u_int8_t delimiter;
395 pts_file_meta_t *metadata;
396
397 attr_info = attr->get_value(attr);
398 attr_cast = (tcg_pts_attr_req_file_meta_t*)attr;
399 is_directory = attr_cast->get_directory_flag(attr_cast);
400 delimiter = attr_cast->get_delimiter(attr_cast);
401 pathname = attr_cast->get_pathname(attr_cast);
402
403 valid_path = pts->is_path_valid(pts, pathname, &pts_error);
404 if (valid_path && pts_error)
405 {
406 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
407 pts_error, attr_info);
408 attr_list->insert_last(attr_list, attr);
409 break;
410 }
411 else if (!valid_path)
412 {
413 break;
414 }
415 if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
416 {
417 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
418 TCG_PTS_INVALID_DELIMITER, attr_info);
419 attr_list->insert_last(attr_list, attr);
420 break;
421 }
422 /* Get File Metadata and send them to PTS-IMV */
423 DBG2(DBG_IMC, "metadata request for %s '%s'",
424 is_directory ? "directory" : "file",
425 pathname);
426 metadata = pts->get_metadata(pts, pathname, is_directory);
427
428 if (!metadata)
429 {
430 /* TODO handle error codes from measurements */
431 return FALSE;
432 }
433 attr = tcg_pts_attr_unix_file_meta_create(metadata);
434 attr->set_noskip_flag(attr, TRUE);
435 attr_list->insert_last(attr_list, attr);
436
437 break;
438 }
439 case TCG_PTS_REQ_FUNC_COMP_EVID:
440 {
441 tcg_pts_attr_req_func_comp_evid_t *attr_cast;
442 pts_proto_caps_flag_t negotiated_caps;
443 pts_comp_func_name_t *name;
444 u_int32_t depth;
445 u_int8_t flags;
446 enumerator_t *e;
447
448 attr_info = attr->get_value(attr);
449 attr_cast = (tcg_pts_attr_req_func_comp_evid_t*)attr;
450
451 DBG1(DBG_IMC, "evidence requested for %d functional components",
452 attr_cast->get_count(attr_cast));
453
454 e = attr_cast->create_enumerator(attr_cast);
455 while (e->enumerate(e, &flags, &depth, &name))
456 {
457 name->log(name, " ");
458 negotiated_caps = pts->get_proto_caps(pts);
459
460 if (flags & PTS_REQ_FUNC_COMP_FLAG_TTC)
461 {
462 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
463 TCG_PTS_UNABLE_DET_TTC, attr_info);
464 attr_list->insert_last(attr_list, attr);
465 break;
466 }
467 if (flags & PTS_REQ_FUNC_COMP_FLAG_VER &&
468 !(negotiated_caps & PTS_PROTO_CAPS_V))
469 {
470 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
471 TCG_PTS_UNABLE_LOCAL_VAL, attr_info);
472 attr_list->insert_last(attr_list, attr);
473 break;
474 }
475 if (flags & PTS_REQ_FUNC_COMP_FLAG_CURR &&
476 !(negotiated_caps & PTS_PROTO_CAPS_C))
477 {
478 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
479 TCG_PTS_UNABLE_CUR_EVID, attr_info);
480 attr_list->insert_last(attr_list, attr);
481 break;
482 }
483 if (flags & PTS_REQ_FUNC_COMP_FLAG_PCR &&
484 !(negotiated_caps & PTS_PROTO_CAPS_T))
485 {
486 attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
487 TCG_PTS_UNABLE_DET_PCR, attr_info);
488 attr_list->insert_last(attr_list, attr);
489 break;
490 }
491 if (depth != 0)
492 {
493 DBG1(DBG_IMC, "current version of Attestation IMC does not "
494 "support sub component measurement deeper than "
495 "zero. Measuring top level component only.");
496 return FALSE;
497 }
498
499 /* Check if Unknown or Wildcard was set for qualifier */
500 if (name->get_qualifier(name) & PTS_QUALIFIER_WILDCARD)
501 {
502 DBG2(DBG_IMC, "wildcard was set for the qualifier of functional"
503 " component. Identifying the component with "
504 "name binary enumeration");
505 }
506 else if (name->get_qualifier(name) & PTS_QUALIFIER_UNKNOWN)
507 {
508 DBG2(DBG_IMC, "unknown was set for the qualifier of functional"
509 " component. Identifying the component with "
510 "name binary enumeration");
511 }
512 else if ((name->get_qualifier(name) >> PTS_ITA_QUALIFIER_TYPE_SIZE)
513 & PTS_ITA_QUALIFIER_TYPE_TRUSTED)
514 {
515 tcg_pts_attr_simple_comp_evid_params_t params;
516
517 if (name->get_name(name) == PTS_ITA_COMP_FUNC_NAME_TBOOT)
518 {
519 u_int8_t i;
520 for (i = 1; i <= TBOOT_SEQUENCE_COUNT; i++)
521 {
522 /* Set parameters of Simple Component Evidence */
523 if (!set_simple_comp_evid_params(pts, name, i, &params))
524 {
525 DBG1(DBG_IMC, "error occured while setting "
526 " parameters for Simple Component Evidence");
527 return FALSE;
528 }
529 /* Buffer Simple Component Evidence attribute */
530 attr = tcg_pts_attr_simple_comp_evid_create(params);
531 evidences->insert_last(evidences, attr);
532
533 }
534 break;
535 }
536 else
537 {
538 /* Set parameters of Simple Component Evidence */
539 if (!set_simple_comp_evid_params(pts, name, 0, &params))
540 {
541 DBG1(DBG_IMC, "error occured while setting parameters"
542 "for Simple Component Evidence");
543 return FALSE;
544 }
545
546 /* Buffer Simple Component Evidence attribute */
547 attr = tcg_pts_attr_simple_comp_evid_create(params);
548 evidences->insert_last(evidences, attr);
549
550 break;
551 }
552 }
553 else
554 {
555 DBG1(DBG_IMC, "Functional Component with unsupported type: %d"
556 "was requested for evidence",
557 (name->get_qualifier(name) >> PTS_ITA_QUALIFIER_TYPE_SIZE));
558 break;
559 }
560 }
561 e->destroy(e);
562 break;
563 }
564 case TCG_PTS_GEN_ATTEST_EVID:
565 {
566 enumerator_t *e;
567 pts_simple_evid_final_flag_t flags;
568 pts_meas_algorithms_t composite_algorithm = 0;
569 chunk_t pcr_composite, quote_signature;
570 u_int32_t num_of_evidences, i = 0;
571 u_int32_t *pcrs;
572 bool use_quote2;
573
574 /* Send buffered Simple Component Evidences */
575 num_of_evidences = evidences->get_count(evidences);
576 pcrs = (u_int32_t*)malloc(sizeof(u_int32_t)*num_of_evidences);
577
578 e = evidences->create_enumerator(evidences);
579 while (e->enumerate(e, &attr))
580 {
581 tcg_pts_attr_simple_comp_evid_t *attr_cast;
582 u_int32_t extended_pcr;
583
584 attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
585 extended_pcr = attr_cast->get_extended_pcr(attr_cast);
586
587 /* Add extended PCR number to PCR list to quote */
588 /* Duplicated PCR numbers have no influence */
589 pcrs[i] = extended_pcr;
590 i++;
591 /* Send Simple Compoenent Evidence */
592 attr_list->insert_last(attr_list, attr);
593 }
594
595 use_quote2 = (lib->settings->get_int(lib->settings,
596 "libimcv.plugins.imc-attestation.quote_version", 1) == 1) ?
597 FALSE : TRUE;
598
599 /* Quote */
600 if (!pts->quote_tpm(pts, use_quote2, pcrs, num_of_evidences,
601 &pcr_composite, &quote_signature))
602 {
603 DBG1(DBG_IMC, "error occured during TPM quote operation");
604 DESTROY_IF(e);
605 DESTROY_IF(evidences);
606 return FALSE;
607 }
608
609 /* Send Simple Evidence Final attribute */
610 flags = use_quote2 ? PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO2:
611 PTS_SIMPLE_EVID_FINAL_FLAG_TPM_QUOTE_INFO;
612 composite_algorithm |= PTS_MEAS_ALGO_SHA1;
613
614 attr = tcg_pts_attr_simple_evid_final_create(FALSE, flags,
615 composite_algorithm, pcr_composite,
616 quote_signature, chunk_empty);
617 attr_list->insert_last(attr_list, attr);
618
619 DESTROY_IF(e);
620 DESTROY_IF(evidences);
621
622 break;
623 }
624 /* TODO: Not implemented yet */
625 case TCG_PTS_REQ_INTEG_MEAS_LOG:
626 /* Attributes using XML */
627 case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META:
628 case TCG_PTS_UPDATE_TEMPL_REF_MANI:
629 /* On Windows only*/
630 case TCG_PTS_REQ_REGISTRY_VALUE:
631 /* Received on IMV side only*/
632 case TCG_PTS_PROTO_CAPS:
633 case TCG_PTS_DH_NONCE_PARAMS_RESP:
634 case TCG_PTS_MEAS_ALGO_SELECTION:
635 case TCG_PTS_TPM_VERSION_INFO:
636 case TCG_PTS_TEMPL_REF_MANI_SET_META:
637 case TCG_PTS_AIK:
638 case TCG_PTS_SIMPLE_COMP_EVID:
639 case TCG_PTS_SIMPLE_EVID_FINAL:
640 case TCG_PTS_VERIFICATION_RESULT:
641 case TCG_PTS_INTEG_REPORT:
642 case TCG_PTS_UNIX_FILE_META:
643 case TCG_PTS_FILE_MEAS:
644 case TCG_PTS_INTEG_MEAS_LOG:
645 default:
646 DBG1(DBG_IMC, "received unsupported attribute '%N'",
647 tcg_attr_names, attr->get_type(attr));
648 break;
649 }
650 return TRUE;
651 }