2 * Copyright (C) 2011 Sansar Choinyambuu
3 * HSR Hochschule fuer Technik Rapperswil
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>.
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
16 #include "imc_attestation_state.h"
18 #include <imc/imc_agent.h>
19 #include <pa_tnc/pa_tnc_msg.h>
20 #include <ietf/ietf_attr.h>
21 #include <ietf/ietf_attr_pa_tnc_error.h>
22 #include <ietf/ietf_attr_product_info.h>
26 #include <pts/pts_error.h>
28 #include <tcg/tcg_pts_attr_proto_caps.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_meas_algo.h>
33 #include <tcg/tcg_pts_attr_get_tpm_version_info.h>
34 #include <tcg/tcg_pts_attr_tpm_version_info.h>
35 #include <tcg/tcg_pts_attr_get_aik.h>
36 #include <tcg/tcg_pts_attr_aik.h>
37 #include <tcg/tcg_pts_attr_req_funct_comp_evid.h>
38 #include <tcg/tcg_pts_attr_gen_attest_evid.h>
39 #include <tcg/tcg_pts_attr_simple_comp_evid.h>
40 #include <tcg/tcg_pts_attr_simple_evid_final.h>
41 #include <tcg/tcg_pts_attr_req_file_meas.h>
42 #include <tcg/tcg_pts_attr_file_meas.h>
43 #include <tcg/tcg_pts_attr_req_file_meta.h>
44 #include <tcg/tcg_pts_attr_unix_file_meta.h>
46 #include <tncif_pa_subtypes.h>
50 #include <utils/linked_list.h>
54 static const char imc_name
[] = "Attestation";
56 #define IMC_VENDOR_ID PEN_TCG
57 #define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS
59 static imc_agent_t
*imc_attestation
;
62 * Supported PTS measurement algorithms
64 static pts_meas_algorithms_t supported_algorithms
= 0;
67 * Supported PTS Diffie Hellman Groups
69 static pts_dh_group_t supported_dh_groups
= 0;
72 * see section 3.7.1 of TCG TNC IF-IMC Specification 1.2
74 TNC_Result
TNC_IMC_Initialize(TNC_IMCID imc_id
,
75 TNC_Version min_version
,
76 TNC_Version max_version
,
77 TNC_Version
*actual_version
)
81 DBG1(DBG_IMC
, "IMC \"%s\" has already been initialized", imc_name
);
82 return TNC_RESULT_ALREADY_INITIALIZED
;
84 if (!pts_meas_probe_algorithms(&supported_algorithms
))
86 return TNC_RESULT_FATAL
;
88 if (!pts_probe_dh_groups(&supported_dh_groups
))
90 return TNC_RESULT_FATAL
;
92 imc_attestation
= imc_agent_create(imc_name
, IMC_VENDOR_ID
, IMC_SUBTYPE
,
93 imc_id
, actual_version
);
96 return TNC_RESULT_FATAL
;
101 if (min_version
> TNC_IFIMC_VERSION_1
|| max_version
< TNC_IFIMC_VERSION_1
)
103 DBG1(DBG_IMC
, "no common IF-IMC version");
104 return TNC_RESULT_NO_COMMON_VERSION
;
106 return TNC_RESULT_SUCCESS
;
110 * see section 3.7.2 of TCG TNC IF-IMC Specification 1.2
112 TNC_Result
TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id
,
113 TNC_ConnectionID connection_id
,
114 TNC_ConnectionState new_state
)
117 /* TODO: Not used so far */
118 //imc_attestation_state_t *attestation_state;
120 if (!imc_attestation
)
122 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
123 return TNC_RESULT_NOT_INITIALIZED
;
127 case TNC_CONNECTION_STATE_CREATE
:
128 state
= imc_attestation_state_create(connection_id
);
129 return imc_attestation
->create_state(imc_attestation
, state
);
130 case TNC_CONNECTION_STATE_DELETE
:
131 return imc_attestation
->delete_state(imc_attestation
, connection_id
);
132 case TNC_CONNECTION_STATE_HANDSHAKE
:
133 case TNC_CONNECTION_STATE_ACCESS_ISOLATED
:
134 case TNC_CONNECTION_STATE_ACCESS_NONE
:
136 return imc_attestation
->change_state(imc_attestation
, connection_id
,
143 * see section 3.7.3 of TCG TNC IF-IMC Specification 1.2
145 TNC_Result
TNC_IMC_BeginHandshake(TNC_IMCID imc_id
,
146 TNC_ConnectionID connection_id
)
149 imc_attestation_state_t
*attestation_state
;
152 TNC_Result result
= TNC_RESULT_SUCCESS
;
154 if (!imc_attestation
)
156 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
157 return TNC_RESULT_NOT_INITIALIZED
;
160 /* get current IMC state */
161 if (!imc_attestation
->get_state(imc_attestation
, connection_id
, &state
))
163 return TNC_RESULT_FATAL
;
165 attestation_state
= (imc_attestation_state_t
*)state
;
166 pts
= attestation_state
->get_pts(attestation_state
);
168 platform_info
= pts
->get_platform_info(pts
);
171 pa_tnc_msg_t
*pa_tnc_msg
;
174 pa_tnc_msg
= pa_tnc_msg_create();
175 attr
= ietf_attr_product_info_create(0, 0, platform_info
);
176 pa_tnc_msg
->add_attribute(pa_tnc_msg
, attr
);
177 pa_tnc_msg
->build(pa_tnc_msg
);
178 result
= imc_attestation
->send_message(imc_attestation
, connection_id
,
179 pa_tnc_msg
->get_encoding(pa_tnc_msg
));
180 pa_tnc_msg
->destroy(pa_tnc_msg
);
187 * see section 3.7.4 of TCG TNC IF-IMC Specification 1.2
189 TNC_Result
TNC_IMC_ReceiveMessage(TNC_IMCID imc_id
,
190 TNC_ConnectionID connection_id
,
191 TNC_BufferReference msg
,
193 TNC_MessageType msg_type
)
195 pa_tnc_msg_t
*pa_tnc_msg
;
197 linked_list_t
*attr_list
;
199 imc_attestation_state_t
*attestation_state
;
200 enumerator_t
*enumerator
;
203 bool fatal_error
= FALSE
;
205 pts_error_code_t pts_error
;
208 if (!imc_attestation
)
210 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
211 return TNC_RESULT_NOT_INITIALIZED
;
214 /* get current IMC state */
215 if (!imc_attestation
->get_state(imc_attestation
, connection_id
, &state
))
217 return TNC_RESULT_FATAL
;
219 attestation_state
= (imc_attestation_state_t
*)state
;
220 pts
= attestation_state
->get_pts(attestation_state
);
222 /* parse received PA-TNC message and automatically handle any errors */
223 result
= imc_attestation
->receive_message(imc_attestation
, connection_id
,
224 chunk_create(msg
, msg_len
), msg_type
,
227 /* no parsed PA-TNC attributes available if an error occurred */
233 attr_list
= linked_list_create();
235 /* analyze PA-TNC attributes */
236 enumerator
= pa_tnc_msg
->create_attribute_enumerator(pa_tnc_msg
);
237 while (enumerator
->enumerate(enumerator
, &attr
))
239 if (attr
->get_vendor_id(attr
) == PEN_IETF
&&
240 attr
->get_type(attr
) == IETF_ATTR_PA_TNC_ERROR
)
242 ietf_attr_pa_tnc_error_t
*error_attr
;
243 pa_tnc_error_code_t error_code
;
244 chunk_t msg_info
, attr_info
;
247 error_attr
= (ietf_attr_pa_tnc_error_t
*)attr
;
248 error_code
= error_attr
->get_error_code(error_attr
);
249 msg_info
= error_attr
->get_msg_info(error_attr
);
251 DBG1(DBG_IMC
, "received PA-TNC error '%N' concerning message %#B",
252 pa_tnc_error_code_names
, error_code
, &msg_info
);
255 case PA_ERROR_INVALID_PARAMETER
:
256 offset
= error_attr
->get_offset(error_attr
);
257 DBG1(DBG_IMC
, " occurred at offset of %u bytes", offset
);
259 case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED
:
260 attr_info
= error_attr
->get_attr_info(error_attr
);
261 DBG1(DBG_IMC
, " unsupported attribute %#B", &attr_info
);
268 else if (attr
->get_vendor_id(attr
) == PEN_TCG
)
270 switch (attr
->get_type(attr
))
272 case TCG_PTS_REQ_PROTO_CAPS
:
274 tcg_pts_attr_proto_caps_t
*attr_cast
;
275 pts_proto_caps_flag_t imc_caps
, imv_caps
;
277 attr_cast
= (tcg_pts_attr_proto_caps_t
*)attr
;
278 imv_caps
= attr_cast
->get_flags(attr_cast
);
279 imc_caps
= pts
->get_proto_caps(pts
);
280 pts
->set_proto_caps(pts
, imc_caps
& imv_caps
);
282 /* Send PTS Protocol Capabilities attribute */
283 attr
= tcg_pts_attr_proto_caps_create(imc_caps
& imv_caps
,
285 attr_list
->insert_last(attr_list
, attr
);
288 case TCG_PTS_DH_NONCE_PARAMS_REQ
:
290 tcg_pts_attr_dh_nonce_params_req_t
*attr_cast
;
291 u_int8_t min_nonce_len
;
292 pts_dh_group_t offered_dh_groups
, selected_dh_group
;
294 attr_cast
= (tcg_pts_attr_dh_nonce_params_req_t
*)attr
;
295 min_nonce_len
= attr_cast
->get_min_nonce_len(attr_cast
);
296 offered_dh_groups
= attr_cast
->get_dh_groups(attr_cast
);
298 if ((supported_dh_groups
& PTS_DH_GROUP_IKE20
) &&
299 (offered_dh_groups
& PTS_DH_GROUP_IKE20
))
301 pts
->set_dh_group(pts
, PTS_DH_GROUP_IKE20
);
303 else if ((supported_dh_groups
& PTS_DH_GROUP_IKE19
) &&
304 (offered_dh_groups
& PTS_DH_GROUP_IKE19
))
306 pts
->set_dh_group(pts
, PTS_DH_GROUP_IKE19
);
308 else if ((supported_dh_groups
& PTS_DH_GROUP_IKE14
) &&
309 (offered_dh_groups
& PTS_DH_GROUP_IKE14
))
311 pts
->set_dh_group(pts
, PTS_DH_GROUP_IKE14
);
313 else if ((supported_dh_groups
& PTS_DH_GROUP_IKE5
) &&
314 (offered_dh_groups
& PTS_DH_GROUP_IKE5
))
316 pts
->set_dh_group(pts
, PTS_DH_GROUP_IKE5
);
318 else if ((supported_dh_groups
& PTS_DH_GROUP_IKE2
) &&
319 (offered_dh_groups
& PTS_DH_GROUP_IKE2
))
321 pts
->set_dh_group(pts
, PTS_DH_GROUP_IKE2
);
325 attr_info
= attr
->get_value(attr
);
326 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
327 TCG_PTS_DH_GRPS_NOT_SUPPORTED
, attr_info
);
328 attr_list
->insert_last(attr_list
, attr
);
332 /* Send DH Nonce Parameters Response attribute */
333 selected_dh_group
= pts
->get_dh_group(pts
);
334 /* TODO: Implement */
338 case TCG_PTS_DH_NONCE_FINISH
:
340 /* TODO: Implement */
343 case TCG_PTS_MEAS_ALGO
:
345 tcg_pts_attr_meas_algo_t
*attr_cast
;
346 pts_meas_algorithms_t offered_algorithms
, selected_algorithm
;
348 attr_cast
= (tcg_pts_attr_meas_algo_t
*)attr
;
349 offered_algorithms
= attr_cast
->get_algorithms(attr_cast
);
351 if ((supported_algorithms
& PTS_MEAS_ALGO_SHA384
) &&
352 (offered_algorithms
& PTS_MEAS_ALGO_SHA384
))
354 pts
->set_meas_algorithm(pts
, PTS_MEAS_ALGO_SHA384
);
356 else if ((supported_algorithms
& PTS_MEAS_ALGO_SHA256
) &&
357 (offered_algorithms
& PTS_MEAS_ALGO_SHA256
))
359 pts
->set_meas_algorithm(pts
, PTS_MEAS_ALGO_SHA256
);
362 else if ((supported_algorithms
& PTS_MEAS_ALGO_SHA1
) &&
363 (offered_algorithms
& PTS_MEAS_ALGO_SHA1
))
365 pts
->set_meas_algorithm(pts
, PTS_MEAS_ALGO_SHA1
);
369 attr
= pts_hash_alg_error_create(supported_algorithms
);
370 attr_list
->insert_last(attr_list
, attr
);
374 /* Send Measurement Algorithm Selection attribute */
375 selected_algorithm
= pts
->get_meas_algorithm(pts
);
376 attr
= tcg_pts_attr_meas_algo_create(selected_algorithm
,
378 attr_list
->insert_last(attr_list
, attr
);
382 case TCG_PTS_GET_TPM_VERSION_INFO
:
384 chunk_t tpm_version_info
, attr_info
;
386 if (!pts
->get_tpm_version_info(pts
, &tpm_version_info
))
388 attr_info
= attr
->get_value(attr
);
389 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
390 TCG_PTS_TPM_VERS_NOT_SUPPORTED
, attr_info
);
391 attr_list
->insert_last(attr_list
, attr
);
395 /* Send TPM Version Info attribute */
396 attr
= tcg_pts_attr_tpm_version_info_create(tpm_version_info
);
397 attr_list
->insert_last(attr_list
, attr
);
401 case TCG_PTS_GET_AIK
:
405 aik
= pts
->get_aik(pts
);
408 DBG1(DBG_IMC
, "no AIK certificate or public key available");
412 /* Send AIK attribute */
413 attr
= tcg_pts_attr_aik_create(aik
);
414 attr_list
->insert_last(attr_list
, attr
);
418 /* PTS-based Attestation Evidence */
419 case TCG_PTS_REQ_FUNCT_COMP_EVID
:
421 tcg_pts_attr_req_funct_comp_evid_t
*attr_cast
;
422 pts_proto_caps_flag_t negotiated_caps
;
423 pts_attr_req_funct_comp_evid_flag_t flags
;
424 u_int32_t sub_comp_depth
;
425 u_int32_t comp_name_vendor_id
;
427 pts_qualifier_t qualifier
;
428 pts_funct_comp_name_t name
;
430 attr_info
= attr
->get_value(attr
);
431 attr_cast
= (tcg_pts_attr_req_funct_comp_evid_t
*)attr
;
432 negotiated_caps
= pts
->get_proto_caps(pts
);
433 flags
= attr_cast
->get_flags(attr_cast
);
435 if (flags
& PTS_REQ_FUNC_COMP_FLAG_TTC
)
437 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
438 TCG_PTS_UNABLE_DET_TTC
, attr_info
);
439 attr_list
->insert_last(attr_list
, attr
);
442 if (flags
& PTS_REQ_FUNC_COMP_FLAG_VER
&&
443 !(negotiated_caps
& PTS_PROTO_CAPS_V
))
445 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
446 TCG_PTS_UNABLE_LOCAL_VAL
, attr_info
);
447 attr_list
->insert_last(attr_list
, attr
);
450 if (flags
& PTS_REQ_FUNC_COMP_FLAG_CURR
&&
451 !(negotiated_caps
& PTS_PROTO_CAPS_C
))
453 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
454 TCG_PTS_UNABLE_CUR_EVID
, attr_info
);
455 attr_list
->insert_last(attr_list
, attr
);
458 if (flags
& PTS_REQ_FUNC_COMP_FLAG_PCR
&&
459 !(negotiated_caps
& PTS_PROTO_CAPS_T
))
461 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
462 TCG_PTS_UNABLE_DET_PCR
, attr_info
);
463 attr_list
->insert_last(attr_list
, attr
);
467 sub_comp_depth
= attr_cast
->get_sub_component_depth(attr_cast
);
468 /* TODO: Implement checking of components with its sub-components */
469 if (sub_comp_depth
!= 1)
471 DBG1(DBG_IMC
, "Current version of Attestation IMC does not support"
472 "sub component measurement deeper than 1. "
473 "Measuring top level component only.");
476 comp_name_vendor_id
= attr_cast
->get_comp_funct_name_vendor_id(attr_cast
);
477 if (comp_name_vendor_id
!= PEN_TCG
)
479 DBG1(DBG_IMC
, "Current version of Attestation IMC supports"
480 "only functional component namings by TCG ");
484 family
= attr_cast
->get_family(attr_cast
);
487 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
488 TCG_PTS_INVALID_NAME_FAM
, attr_info
);
489 attr_list
->insert_last(attr_list
, attr
);
493 qualifier
= attr_cast
->get_qualifier(attr_cast
);
494 /* Check if Unknown or Wildcard was set for qualifier */
495 if (qualifier
.kernel
&& qualifier
.sub_component
&&
496 (qualifier
.type
& PTS_FUNC_COMP_TYPE_ALL
))
498 DBG2(DBG_IMC
, "Wildcard was set for the qualifier of functional"
499 " component. Identifying the component with name binary enumeration");
501 else if (!qualifier
.kernel
&& !qualifier
.sub_component
&&
502 (qualifier
.type
& PTS_FUNC_COMP_TYPE_UNKNOWN
))
504 DBG2(DBG_IMC
, "Unknown was set for the qualifier of functional"
505 " component. Identifying the component with name binary enumeration");
509 /* TODO: Implement what todo with received qualifier */
512 name
= attr_cast
->get_comp_funct_name(attr_cast
);
515 case PTS_FUNC_COMP_NAME_BIOS
:
517 /* TODO: Implement BIOS measurement */
518 DBG1(DBG_IMC
, "TODO: Implement BIOS measurement");
521 case PTS_FUNC_COMP_NAME_IGNORE
:
522 case PTS_FUNC_COMP_NAME_CRTM
:
523 case PTS_FUNC_COMP_NAME_PLATFORM_EXT
:
524 case PTS_FUNC_COMP_NAME_BOARD
:
525 case PTS_FUNC_COMP_NAME_INIT_LOADER
:
526 case PTS_FUNC_COMP_NAME_OPT_ROMS
:
529 DBG1(DBG_IMC
, "Unsupported Functional Component Name");
536 case TCG_PTS_GEN_ATTEST_EVID
:
538 pts_simple_evid_final_flag_t flags
;
539 /* TODO: TPM quote operation over included PCR's */
541 /* Send Simple Evidence Final attribute */
542 flags
= PTS_SIMPLE_EVID_FINAL_FLAG_NO
;
543 attr
= tcg_pts_attr_simple_evid_final_create(flags
, 0,
544 chunk_empty
, chunk_empty
, chunk_empty
);
545 attr_list
->insert_last(attr_list
, attr
);
548 case TCG_PTS_REQ_FILE_META
:
550 tcg_pts_attr_req_file_meta_t
*attr_cast
;
554 pts_file_meta_t
*metadata
;
556 attr_info
= attr
->get_value(attr
);
557 attr_cast
= (tcg_pts_attr_req_file_meta_t
*)attr
;
558 is_directory
= attr_cast
->get_directory_flag(attr_cast
);
559 delimiter
= attr_cast
->get_delimiter(attr_cast
);
560 pathname
= attr_cast
->get_pathname(attr_cast
);
562 valid_path
= pts
->is_path_valid(pts
, pathname
, &pts_error
);
563 if (valid_path
&& pts_error
)
565 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
566 pts_error
, attr_info
);
567 attr_list
->insert_last(attr_list
, attr
);
570 else if (!valid_path
)
574 if (delimiter
!= SOLIDUS_UTF
&& delimiter
!= REVERSE_SOLIDUS_UTF
)
576 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
577 TCG_PTS_INVALID_DELIMITER
, attr_info
);
578 attr_list
->insert_last(attr_list
, attr
);
581 /* Get File Metadata and send them to PTS-IMV */
582 DBG2(DBG_IMC
, "metadata request for %s '%s'",
583 is_directory ?
"directory" : "file",
585 metadata
= pts
->get_metadata(pts
, pathname
, is_directory
);
589 /* TODO handle error codes from measurements */
590 return TNC_RESULT_FATAL
;
592 attr
= tcg_pts_attr_unix_file_meta_create(metadata
);
593 attr
->set_noskip_flag(attr
, TRUE
);
594 attr_list
->insert_last(attr_list
, attr
);
598 case TCG_PTS_REQ_FILE_MEAS
:
600 tcg_pts_attr_req_file_meas_t
*attr_cast
;
602 u_int16_t request_id
;
605 pts_file_meas_t
*measurements
;
607 attr_info
= attr
->get_value(attr
);
608 attr_cast
= (tcg_pts_attr_req_file_meas_t
*)attr
;
609 is_directory
= attr_cast
->get_directory_flag(attr_cast
);
610 request_id
= attr_cast
->get_request_id(attr_cast
);
611 delimiter
= attr_cast
->get_delimiter(attr_cast
);
612 pathname
= attr_cast
->get_pathname(attr_cast
);
613 valid_path
= pts
->is_path_valid(pts
, pathname
, &pts_error
);
615 if (valid_path
&& pts_error
)
617 attr_info
= attr
->get_value(attr
);
618 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
619 pts_error
, attr_info
);
620 attr_list
->insert_last(attr_list
, attr
);
623 else if (!valid_path
)
628 if (delimiter
!= SOLIDUS_UTF
&& delimiter
!= REVERSE_SOLIDUS_UTF
)
630 attr_info
= attr
->get_value(attr
);
631 attr
= ietf_attr_pa_tnc_error_create(PEN_TCG
,
632 TCG_PTS_INVALID_DELIMITER
, attr_info
);
633 attr_list
->insert_last(attr_list
, attr
);
637 /* Do PTS File Measurements and send them to PTS-IMV */
638 DBG2(DBG_IMC
, "measurement request %d for %s '%s'",
639 request_id
, is_directory ?
"directory" : "file",
641 measurements
= pts
->do_measurements(pts
, request_id
,
642 pathname
, is_directory
);
645 /* TODO handle error codes from measurements */
646 return TNC_RESULT_FATAL
;
648 attr
= tcg_pts_attr_file_meas_create(measurements
);
649 attr
->set_noskip_flag(attr
, TRUE
);
650 attr_list
->insert_last(attr_list
, attr
);
653 /* TODO: Not implemented yet */
654 case TCG_PTS_REQ_INTEG_MEAS_LOG
:
655 /* Attributes using XML */
656 case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META
:
657 case TCG_PTS_UPDATE_TEMPL_REF_MANI
:
659 case TCG_PTS_REQ_REGISTRY_VALUE
:
660 /* Received on IMV side only*/
661 case TCG_PTS_PROTO_CAPS
:
662 case TCG_PTS_DH_NONCE_PARAMS_RESP
:
663 case TCG_PTS_MEAS_ALGO_SELECTION
:
664 case TCG_PTS_TPM_VERSION_INFO
:
665 case TCG_PTS_TEMPL_REF_MANI_SET_META
:
667 case TCG_PTS_SIMPLE_COMP_EVID
:
668 case TCG_PTS_SIMPLE_EVID_FINAL
:
669 case TCG_PTS_VERIFICATION_RESULT
:
670 case TCG_PTS_INTEG_REPORT
:
671 case TCG_PTS_UNIX_FILE_META
:
672 case TCG_PTS_FILE_MEAS
:
673 case TCG_PTS_INTEG_MEAS_LOG
:
675 DBG1(DBG_IMC
, "received unsupported attribute '%N'",
676 tcg_attr_names
, attr
->get_type(attr
));
681 enumerator
->destroy(enumerator
);
682 pa_tnc_msg
->destroy(pa_tnc_msg
);
684 result
= TNC_RESULT_SUCCESS
;
686 if (attr_list
->get_count(attr_list
))
688 pa_tnc_msg
= pa_tnc_msg_create();
690 enumerator
= attr_list
->create_enumerator(attr_list
);
691 while (enumerator
->enumerate(enumerator
, &attr
))
693 pa_tnc_msg
->add_attribute(pa_tnc_msg
, attr
);
695 enumerator
->destroy(enumerator
);
697 pa_tnc_msg
->build(pa_tnc_msg
);
698 result
= imc_attestation
->send_message(imc_attestation
, connection_id
,
699 pa_tnc_msg
->get_encoding(pa_tnc_msg
));
700 pa_tnc_msg
->destroy(pa_tnc_msg
);
702 attr_list
->destroy(attr_list
);
708 * see section 3.7.5 of TCG TNC IF-IMC Specification 1.2
710 TNC_Result
TNC_IMC_BatchEnding(TNC_IMCID imc_id
,
711 TNC_ConnectionID connection_id
)
713 if (!imc_attestation
)
715 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
716 return TNC_RESULT_NOT_INITIALIZED
;
718 return TNC_RESULT_SUCCESS
;
722 * see section 3.7.6 of TCG TNC IF-IMC Specification 1.2
724 TNC_Result
TNC_IMC_Terminate(TNC_IMCID imc_id
)
726 if (!imc_attestation
)
728 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
729 return TNC_RESULT_NOT_INITIALIZED
;
734 imc_attestation
->destroy(imc_attestation
);
735 imc_attestation
= NULL
;
737 return TNC_RESULT_SUCCESS
;
741 * see section 4.2.8.1 of TCG TNC IF-IMC Specification 1.2
743 TNC_Result
TNC_IMC_ProvideBindFunction(TNC_IMCID imc_id
,
744 TNC_TNCC_BindFunctionPointer bind_function
)
746 if (!imc_attestation
)
748 DBG1(DBG_IMC
, "IMC \"%s\" has not been initialized", imc_name
);
749 return TNC_RESULT_NOT_INITIALIZED
;
751 return imc_attestation
->bind_functions(imc_attestation
, bind_function
);