diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c index 829cb8806..2dffa211c 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -77,11 +77,6 @@ static pts_creds_t *pts_creds; */ static credential_manager_t *pts_credmgr; -/** - * TRUE if DH Nonce Parameters Request attribute is sent - */ -static bool dh_nonce_req_sent = FALSE; - /** * see section 3.7.1 of TCG TNC IF-IMV Specification 1.2 */ @@ -227,16 +222,175 @@ static TNC_Result send_message(TNC_ConnectionID connection_id) attestation_state = (imv_attestation_state_t*)state; msg = pa_tnc_msg_create(); +<<<<<<< HEAD if (imv_attestation_build(msg, attestation_state, supported_algorithms, supported_dh_groups, pts_db)) { msg->build(msg); result = imv_attestation->send_message(imv_attestation, connection_id, msg->get_encoding(msg)); +======= + if (handshake_state == IMV_ATTESTATION_STATE_NONCE_REQ && + !(pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T)) + { + DBG1(DBG_IMV, "PTS-IMC has no TPM capability - " + "advancing to PTS measurement phase"); + handshake_state = IMV_ATTESTATION_STATE_MEAS; +>>>>>>> added the IMV_ATTESTATION_STATE_NONCE_REQ state } else { +<<<<<<< HEAD result = TNC_RESULT_FATAL; +======= + case IMV_ATTESTATION_STATE_INIT: + { + pts_proto_caps_flag_t flags; + + /* Send Request Protocol Capabilities attribute */ + flags = pts->get_proto_caps(pts); + attr = tcg_pts_attr_proto_caps_create(flags, TRUE); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + /* Send Measurement Algorithms attribute */ + attr = tcg_pts_attr_meas_algo_create(supported_algorithms, FALSE); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_NONCE_REQ); + break; + } + case IMV_ATTESTATION_STATE_NONCE_REQ: + { + int min_nonce_len; + + /* Send DH nonce parameters request attribute */ + min_nonce_len = lib->settings->get_int(lib->settings, + "libimcv.plugins.imv-attestation.min_nonce_len", 0); + attr = tcg_pts_attr_dh_nonce_params_req_create(min_nonce_len, + supported_dh_groups); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_TPM_INIT); + break; + } + case IMV_ATTESTATION_STATE_TPM_INIT: + { + pts_meas_algorithms_t selected_algorithm; + chunk_t initiator_value, initiator_nonce; + + /* Send DH nonce finish attribute */ + selected_algorithm = pts->get_meas_algorithm(pts); + pts->get_my_public_value(pts, &initiator_value, &initiator_nonce); + attr = tcg_pts_attr_dh_nonce_finish_create(selected_algorithm, + initiator_value, initiator_nonce); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + /* Send Get TPM Version attribute */ + attr = tcg_pts_attr_get_tpm_version_info_create(); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + /* Send Get AIK attribute */ + attr = tcg_pts_attr_get_aik_create(); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_MEAS); + break; + } + case IMV_ATTESTATION_STATE_MEAS: + { + + enumerator_t *enumerator; + u_int32_t delimiter = SOLIDUS_UTF; + char *platform_info, *pathname; + u_int16_t request_id; + int id, type; + bool is_dir; + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_COMP_EVID); + + /* Get Platform and OS of the PTS-IMC */ + platform_info = pts->get_platform_info(pts); + + if (!pts_db || !platform_info) + { + DBG1(DBG_IMV, "%s%s%s not available", + (pts_db) ? "" : "pts database", + (!pts_db && !platform_info) ? "and" : "", + (platform_info) ? "" : "platform info"); + break; + } + DBG1(DBG_IMV, "platform is '%s'", platform_info); + + /* Send Request File Metadata attribute */ + attr = tcg_pts_attr_req_file_meta_create(FALSE, SOLIDUS_UTF, "/etc/tnc_config"); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + /* Send Request File Measurement attribute */ + enumerator = pts_db->create_file_enumerator(pts_db, platform_info); + if (!enumerator) + { + break; + } + while (enumerator->enumerate(enumerator, &id, &type, &pathname)) + { + is_dir = (type != 0); + request_id = attestation_state->add_request(attestation_state, + id, is_dir); + DBG2(DBG_IMV, "measurement request %d for %s '%s'", + request_id, is_dir ? "directory" : "file", pathname); + attr = tcg_pts_attr_req_file_meas_create(is_dir, request_id, + delimiter, pathname); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + } + enumerator->destroy(enumerator); + break; + } + case IMV_ATTESTATION_STATE_COMP_EVID: + { + pts_attr_req_funct_comp_evid_flag_t flags; + u_int32_t sub_comp_depth; + pts_qualifier_t qualifier; + pts_funct_comp_name_t name; + + attestation_state->set_handshake_state(attestation_state, + IMV_ATTESTATION_STATE_END); + + flags = PTS_REQ_FUNC_COMP_FLAG_PCR; + sub_comp_depth = 0; + qualifier.kernel = FALSE; + qualifier.sub_component = FALSE; + qualifier.type = PTS_FUNC_COMP_TYPE_ALL; + name = PTS_FUNC_COMP_NAME_BIOS; + + /* Send Request Functional Component Evidence attribute */ + attr = tcg_pts_attr_req_funct_comp_evid_create(flags, sub_comp_depth, + PEN_TCG, qualifier, name); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + /* Send Generate Attestation Evidence attribute */ + attr = tcg_pts_attr_gen_attest_evid_create(); + attr->set_noskip_flag(attr, TRUE); + msg->add_attribute(msg, attr); + + break; + } + default: + DBG1(DBG_IMV, "Attestation IMV is in unknown state: \"%s\"", + handshake_state); + return TNC_RESULT_FATAL; +>>>>>>> added the IMV_ATTESTATION_STATE_NONCE_REQ state } msg->destroy(msg);