From: Andreas Steffen Date: Sat, 8 Oct 2011 22:58:33 +0000 (+0200) Subject: moved attribute processing to imv_attestation_process X-Git-Tag: 4.6.2~332 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=350f855ca4c8869cce7dfd934b22c31fc99fc4f5;p=thirdparty%2Fstrongswan.git moved attribute processing to imv_attestation_process --- diff --git a/src/libimcv/plugins/imv_attestation/Makefile.am b/src/libimcv/plugins/imv_attestation/Makefile.am index bfff6e8777..e52a4f325d 100644 --- a/src/libimcv/plugins/imv_attestation/Makefile.am +++ b/src/libimcv/plugins/imv_attestation/Makefile.am @@ -11,7 +11,8 @@ imv_attestation_la_LIBADD = $(top_builddir)/src/libimcv/libimcv.la \ $(top_builddir)/src/libpts/libpts.la imv_attestation_la_SOURCES = imv_attestation.c \ - imv_attestation_state.h imv_attestation_state.c + imv_attestation_state.h imv_attestation_state.c \ + imv_attestation_process.h imv_attestation_process.c imv_attestation_la_LDFLAGS = -module -avoid-version diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c index dadd77b088..e496b79f8d 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -14,6 +14,7 @@ */ #include "imv_attestation_state.h" +#include "imv_attestation_process.h" #include #include @@ -23,28 +24,21 @@ #include +#include #include #include -#include #include #include +#include #include -#include #include -#include #include -#include #include -#include #include #include -#include -#include #include -#include #include -#include #include @@ -60,8 +54,6 @@ static const char imv_name[] = "Attestation"; #define IMV_VENDOR_ID PEN_TCG #define IMV_SUBTYPE PA_SUBTYPE_TCG_PTS -#define NONCE_LEN_LIMIT 16 - static imv_agent_t *imv_attestation; /** @@ -431,9 +423,7 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, enumerator_t *enumerator; TNC_Result result; bool fatal_error = FALSE; - bool measurement_error = FALSE; linked_list_t *attr_list; - chunk_t attr_info; if (!imv_attestation) { @@ -523,363 +513,16 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, } else if (attr->get_vendor_id(attr) == PEN_TCG) { - switch (attr->get_type(attr)) + if (!imv_attestation_process(attr, attr_list, attestation_state, + supported_algorithms, supported_dh_groups, pts_db, pts_credmgr)) { - case TCG_PTS_PROTO_CAPS: - { - tcg_pts_attr_proto_caps_t *attr_cast; - pts_proto_caps_flag_t flags; - - attr_cast = (tcg_pts_attr_proto_caps_t*)attr; - flags = attr_cast->get_flags(attr_cast); - pts->set_proto_caps(pts, flags); - break; - } - case TCG_PTS_MEAS_ALGO_SELECTION: - { - tcg_pts_attr_meas_algo_t *attr_cast; - pts_meas_algorithms_t selected_algorithm; - - attr_cast = (tcg_pts_attr_meas_algo_t*)attr; - selected_algorithm = attr_cast->get_algorithms(attr_cast); - if (!(selected_algorithm & supported_algorithms)) - { - DBG1(DBG_IMV, "PTS-IMC selected unsupported " - "measurement algorithm"); - return TNC_RESULT_FATAL; - } - pts->set_meas_algorithm(pts, selected_algorithm); - break; - } - case TCG_PTS_DH_NONCE_PARAMS_RESP: - { - tcg_pts_attr_dh_nonce_params_resp_t *attr_cast; - int nonce_len, min_nonce_len; - pts_dh_group_t dh_group; - pts_meas_algorithms_t offered_algorithms, selected_algorithm; - chunk_t responder_value, responder_nonce; - - attr_cast = (tcg_pts_attr_dh_nonce_params_resp_t*)attr; - responder_nonce = attr_cast->get_responder_nonce(attr_cast); - - /* check compliance of responder nonce length */ - min_nonce_len = lib->settings->get_int(lib->settings, - "libimcv.plugins.imv-attestation.min_nonce_len", 0); - nonce_len = responder_nonce.len; - if (nonce_len <= NONCE_LEN_LIMIT || - (min_nonce_len > 0 && nonce_len < min_nonce_len)) - { - attr_info = attr->get_value(attr); - attr = ietf_attr_pa_tnc_error_create(PEN_TCG, - TCG_PTS_BAD_NONCE_LENGTH, attr_info); - attr_list->insert_last(attr_list, attr); - break; - } - - dh_group = attr_cast->get_dh_group(attr_cast); - if (!(dh_group & supported_dh_groups)) - { - DBG1(DBG_IMV, "PTS-IMC selected unsupported DH group"); - return TNC_RESULT_FATAL; - } - - offered_algorithms = attr_cast->get_hash_algo_set(attr_cast); - selected_algorithm = pts_meas_algo_select(supported_algorithms, - offered_algorithms); - if (selected_algorithm == PTS_MEAS_ALGO_NONE) - { - attr = pts_hash_alg_error_create(supported_algorithms); - attr_list->insert_last(attr_list, attr); - break; - } - pts->set_dh_hash_algorithm(pts, selected_algorithm); - - if (!pts->create_dh_nonce(pts, dh_group, nonce_len)) - { - return TNC_RESULT_FATAL; - } - - responder_value = attr_cast->get_responder_value(attr_cast); - pts->set_peer_public_value(pts, responder_value, - responder_nonce); - - /* Calculate secret assessment value */ - if (!pts->calculate_secret(pts)) - { - return TNC_RESULT_FATAL; - } - break; - } - case TCG_PTS_TPM_VERSION_INFO: - { - tcg_pts_attr_tpm_version_info_t *attr_cast; - chunk_t tpm_version_info; - - attr_cast = (tcg_pts_attr_tpm_version_info_t*)attr; - tpm_version_info = attr_cast->get_tpm_version_info(attr_cast); - pts->set_tpm_version_info(pts, tpm_version_info); - break; - } - case TCG_PTS_AIK: - { - tcg_pts_attr_aik_t *attr_cast; - certificate_t *aik, *issuer; - enumerator_t *e; - bool trusted = FALSE; - - attr_cast = (tcg_pts_attr_aik_t*)attr; - aik = attr_cast->get_aik(attr_cast); - if (!aik) - { - /* TODO generate error attribute */ - break; - } - if (aik->get_type(aik) == CERT_X509) - { - DBG1(DBG_IMV, "verifying AIK certificate"); - e = pts_credmgr->create_trusted_enumerator(pts_credmgr, - KEY_ANY, aik->get_issuer(aik), FALSE); - while (e->enumerate(e, &issuer)) - { - if (aik->issued_by(aik, issuer)) - { - trusted = TRUE; - break; - } - } - e->destroy(e); - DBG1(DBG_IMV, "AIK certificate is %strusted", - trusted ? "" : "not "); - } - pts->set_aik(pts, aik); - break; - } - - /* PTS-based Attestation Evidence */ - case TCG_PTS_SIMPLE_COMP_EVID: - { - tcg_pts_attr_simple_comp_evid_t *attr_cast; - pts_attr_simple_comp_evid_flag_t flags; - u_int32_t depth, comp_vendor_id, extended_pcr; - u_int8_t family, measurement_type; - pts_qualifier_t qualifier; - pts_funct_comp_name_t name; - pts_meas_algorithms_t hash_algorithm; - pts_pcr_transform_t transformation; - chunk_t measurement_time, policy_uri, pcr_before, pcr_after, measurement; - - attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr; - attr_info = attr->get_value(attr); - - flags = attr_cast->get_flags(attr_cast); - depth = attr_cast->get_sub_component_depth(attr_cast); - /* TODO: Implement checking of components with its sub-components */ - if (depth != 0) - { - DBG1(DBG_IMV, "Current version of Attestation IMV does not support" - "sub component measurement deeper than zero"); - } - comp_vendor_id = attr_cast->get_spec_comp_funct_name_vendor_id(attr_cast); - if (comp_vendor_id != PEN_TCG) - { - DBG1(DBG_IMV, "Current version of Attestation IMV supports" - "only functional component namings by TCG "); - break; - } - family = attr_cast->get_family(attr_cast); - if (family) - { - attr = ietf_attr_pa_tnc_error_create(PEN_TCG, - TCG_PTS_INVALID_NAME_FAM, attr_info); - attr_list->insert_last(attr_list, attr); - break; - } - qualifier = attr_cast->get_qualifier(attr_cast); - /* Check if Unknown or Wildcard was set for qualifier */ - if (qualifier.kernel && qualifier.sub_component && - (qualifier.type & PTS_FUNC_COMP_TYPE_ALL)) - { - DBG1(DBG_IMV, "Wildcard was set for the qualifier" - "of functional component"); - return TNC_RESULT_FATAL; - } - else if (!qualifier.kernel && !qualifier.sub_component && - (qualifier.type & PTS_FUNC_COMP_TYPE_UNKNOWN)) - { - DBG1(DBG_IMV, "Unknown feature was set for the qualifier" - "of functional component"); - return TNC_RESULT_FATAL; - } - else - { - /* TODO: Implement what todo with received qualifier */ - } - - name = attr_cast->get_comp_funct_name(attr_cast); - measurement_type = attr_cast->get_measurement_type(attr_cast); - hash_algorithm = attr_cast->get_hash_algorithm(attr_cast); - transformation = attr_cast->get_pcr_trans(attr_cast); - measurement_time = attr_cast->get_measurement_time(attr_cast); - - /* Call getters of optional fields when corresponding flag is set */ - if (flags & PTS_SIMPLE_COMP_EVID_FLAG_PCR) - { - extended_pcr = attr_cast->get_extended_pcr(attr_cast); - pcr_before = attr_cast->get_pcr_before_value(attr_cast); - pcr_after = attr_cast->get_pcr_after_value(attr_cast); - measurement = attr_cast->get_comp_measurement(attr_cast); - } - if (!(flags & PTS_SIMPLE_COMP_EVID_FLAG_NO_VALID)) - { - policy_uri = attr_cast->get_policy_uri(attr_cast); - } - - /** TODO: Implement saving the PCR number, Hash Algo = communicated one, - * PCR transform (truncate SHA256, SHA384), PCR before and after values - */ - break; - } - - case TCG_PTS_SIMPLE_EVID_FINAL: - { - tcg_pts_attr_simple_evid_final_t *attr_cast; - pts_simple_evid_final_flag_t flags; - chunk_t pcr_comp = chunk_empty; - chunk_t tpm_quote_sign = chunk_empty; - chunk_t evid_sign = chunk_empty; - - /** TODO: Ignoring Composite Hash Algorithm field - * No flag defined which indicates the precense of it - */ - attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr; - flags = attr_cast->get_flags(attr_cast); - - if ((flags >> 6) & PTS_SIMPLE_EVID_FINAL_FLAG_NO) - { - pcr_comp = attr_cast->get_pcr_comp(attr_cast); - tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast); - - /** TODO: Construct PCR Composite */ - } - if (flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID) - { - /** TODO: What to do with Evidence Signature */ - evid_sign = attr_cast->get_evid_sign(attr_cast); - } - - break; - } - - case TCG_PTS_FILE_MEAS: - { - tcg_pts_attr_file_meas_t *attr_cast; - u_int16_t request_id; - int file_count, file_id; - pts_meas_algorithms_t algo; - pts_file_meas_t *measurements; - char *platform_info; - enumerator_t *e_hash; - bool is_dir; - - platform_info = pts->get_platform_info(pts); - if (!pts_db || !platform_info) - { - break; - } - - attr_cast = (tcg_pts_attr_file_meas_t*)attr; - measurements = attr_cast->get_measurements(attr_cast); - algo = pts->get_meas_algorithm(pts); - request_id = measurements->get_request_id(measurements); - file_count = measurements->get_file_count(measurements); - - DBG1(DBG_IMV, "measurement request %d returned %d file%s:", - request_id, file_count, (file_count == 1) ? "":"s"); - - if (!attestation_state->check_off_request(attestation_state, - request_id, &file_id, &is_dir)) - { - DBG1(DBG_IMV, " no entry found for this request"); - break; - } - - /* check hashes from database against measurements */ - e_hash = pts_db->create_hash_enumerator(pts_db, - platform_info, algo, file_id, is_dir); - if (!measurements->verify(measurements, e_hash, is_dir)) - { - measurement_error = TRUE; - } - e_hash->destroy(e_hash); - break; - } - case TCG_PTS_UNIX_FILE_META: - { - tcg_pts_attr_file_meta_t *attr_cast; - int file_count; - pts_file_meta_t *metadata; - enumerator_t *e; - pts_file_metadata_t *entry; - - attr_cast = (tcg_pts_attr_file_meta_t*)attr; - metadata = attr_cast->get_metadata(attr_cast); - file_count = metadata->get_file_count(metadata); - - DBG1(DBG_IMV, "metadata request returned %d file%s:", - file_count, (file_count == 1) ? "":"s"); - - e = metadata->create_enumerator(metadata); - while(e->enumerate(e, &entry)) - { - DBG1(DBG_IMV, "File name: %s", entry->filename); - DBG1(DBG_IMV, " type: %d", entry->type); - DBG1(DBG_IMV, " size: %d", entry->filesize); - DBG1(DBG_IMV, " create time: %s", ctime(&entry->create_time)); - DBG1(DBG_IMV, " last modified: %s", ctime(&entry->last_modify_time)); - DBG1(DBG_IMV, " last accessed: %s", ctime(&entry->last_access_time)); - DBG1(DBG_IMV, " owner id: %d", entry->owner_id); - DBG1(DBG_IMV, " group id: %d", entry->group_id); - } - - e->destroy(e); - - break; - } - - /* TODO: Not implemented yet */ - case TCG_PTS_INTEG_MEAS_LOG: - /* Attributes using XML */ - case TCG_PTS_TEMPL_REF_MANI_SET_META: - case TCG_PTS_VERIFICATION_RESULT: - case TCG_PTS_INTEG_REPORT: - /* On Windows only*/ - case TCG_PTS_WIN_FILE_META: - case TCG_PTS_REGISTRY_VALUE: - /* Received on IMC side only*/ - case TCG_PTS_REQ_PROTO_CAPS: - case TCG_PTS_DH_NONCE_PARAMS_REQ: - case TCG_PTS_DH_NONCE_FINISH: - case TCG_PTS_MEAS_ALGO: - case TCG_PTS_GET_TPM_VERSION_INFO: - case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META: - case TCG_PTS_UPDATE_TEMPL_REF_MANI: - case TCG_PTS_GET_AIK: - case TCG_PTS_REQ_FUNCT_COMP_EVID: - case TCG_PTS_GEN_ATTEST_EVID: - case TCG_PTS_REQ_FILE_META: - case TCG_PTS_REQ_FILE_MEAS: - case TCG_PTS_REQ_INTEG_MEAS_LOG: - default: - DBG1(DBG_IMV, "received unsupported attribute '%N'", - tcg_attr_names, attr->get_type(attr)); - break; + return TNC_RESULT_FATAL; } } } enumerator->destroy(enumerator); pa_tnc_msg->destroy(pa_tnc_msg); - if (fatal_error) { state->set_recommendation(state, @@ -918,9 +561,9 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, { DBG1(DBG_IMV, "failure due to %d pending file measurements", attestation_state->get_request_count(attestation_state)); - measurement_error = TRUE; + attestation_state->set_measurement_error(attestation_state); } - if (measurement_error) + if (attestation_state->get_measurement_error(attestation_state)) { state->set_recommendation(state, TNC_IMV_ACTION_RECOMMENDATION_ISOLATE, diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_process.c b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c new file mode 100644 index 0000000000..efb4966c70 --- /dev/null +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_process.c @@ -0,0 +1,397 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "imv_attestation_process.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NONCE_LEN_LIMIT 16 + +bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list, + imv_attestation_state_t *attestation_state, + pts_meas_algorithms_t supported_algorithms, + pts_dh_group_t supported_dh_groups, + pts_database_t *pts_db, + credential_manager_t *pts_credmgr) +{ + chunk_t attr_info; + pts_t *pts; + + pts = attestation_state->get_pts(attestation_state); + + switch (attr->get_type(attr)) + { + case TCG_PTS_PROTO_CAPS: + { + tcg_pts_attr_proto_caps_t *attr_cast; + pts_proto_caps_flag_t flags; + + attr_cast = (tcg_pts_attr_proto_caps_t*)attr; + flags = attr_cast->get_flags(attr_cast); + pts->set_proto_caps(pts, flags); + break; + } + case TCG_PTS_MEAS_ALGO_SELECTION: + { + tcg_pts_attr_meas_algo_t *attr_cast; + pts_meas_algorithms_t selected_algorithm; + + attr_cast = (tcg_pts_attr_meas_algo_t*)attr; + selected_algorithm = attr_cast->get_algorithms(attr_cast); + if (!(selected_algorithm & supported_algorithms)) + { + DBG1(DBG_IMV, "PTS-IMC selected unsupported measurement algorithm"); + return FALSE; + } + pts->set_meas_algorithm(pts, selected_algorithm); + break; + } + case TCG_PTS_DH_NONCE_PARAMS_RESP: + { + tcg_pts_attr_dh_nonce_params_resp_t *attr_cast; + int nonce_len, min_nonce_len; + pts_dh_group_t dh_group; + pts_meas_algorithms_t offered_algorithms, selected_algorithm; + chunk_t responder_value, responder_nonce; + + attr_cast = (tcg_pts_attr_dh_nonce_params_resp_t*)attr; + responder_nonce = attr_cast->get_responder_nonce(attr_cast); + + /* check compliance of responder nonce length */ + min_nonce_len = lib->settings->get_int(lib->settings, + "libimcv.plugins.imv-attestation.min_nonce_len", 0); + nonce_len = responder_nonce.len; + if (nonce_len <= NONCE_LEN_LIMIT || + (min_nonce_len > 0 && nonce_len < min_nonce_len)) + { + attr_info = attr->get_value(attr); + attr = ietf_attr_pa_tnc_error_create(PEN_TCG, + TCG_PTS_BAD_NONCE_LENGTH, attr_info); + attr_list->insert_last(attr_list, attr); + break; + } + + dh_group = attr_cast->get_dh_group(attr_cast); + if (!(dh_group & supported_dh_groups)) + { + DBG1(DBG_IMV, "PTS-IMC selected unsupported DH group"); + return FALSE; + } + + offered_algorithms = attr_cast->get_hash_algo_set(attr_cast); + selected_algorithm = pts_meas_algo_select(supported_algorithms, + offered_algorithms); + if (selected_algorithm == PTS_MEAS_ALGO_NONE) + { + attr = pts_hash_alg_error_create(supported_algorithms); + attr_list->insert_last(attr_list, attr); + break; + } + pts->set_dh_hash_algorithm(pts, selected_algorithm); + + if (!pts->create_dh_nonce(pts, dh_group, nonce_len)) + { + return FALSE; + } + + responder_value = attr_cast->get_responder_value(attr_cast); + pts->set_peer_public_value(pts, responder_value, + responder_nonce); + + /* Calculate secret assessment value */ + if (!pts->calculate_secret(pts)) + { + return FALSE; + } + break; + } + case TCG_PTS_TPM_VERSION_INFO: + { + tcg_pts_attr_tpm_version_info_t *attr_cast; + chunk_t tpm_version_info; + + attr_cast = (tcg_pts_attr_tpm_version_info_t*)attr; + tpm_version_info = attr_cast->get_tpm_version_info(attr_cast); + pts->set_tpm_version_info(pts, tpm_version_info); + break; + } + case TCG_PTS_AIK: + { + tcg_pts_attr_aik_t *attr_cast; + certificate_t *aik, *issuer; + enumerator_t *e; + bool trusted = FALSE; + + attr_cast = (tcg_pts_attr_aik_t*)attr; + aik = attr_cast->get_aik(attr_cast); + if (!aik) + { + /* TODO generate error attribute */ + break; + } + if (aik->get_type(aik) == CERT_X509) + { + DBG1(DBG_IMV, "verifying AIK certificate"); + e = pts_credmgr->create_trusted_enumerator(pts_credmgr, + KEY_ANY, aik->get_issuer(aik), FALSE); + while (e->enumerate(e, &issuer)) + { + if (aik->issued_by(aik, issuer)) + { + trusted = TRUE; + break; + } + } + e->destroy(e); + DBG1(DBG_IMV, "AIK certificate is %strusted", + trusted ? "" : "not "); + } + pts->set_aik(pts, aik); + break; + } + case TCG_PTS_SIMPLE_COMP_EVID: + { + tcg_pts_attr_simple_comp_evid_t *attr_cast; + pts_attr_simple_comp_evid_flag_t flags; + u_int32_t depth, comp_vendor_id, extended_pcr; + u_int8_t family, measurement_type; + pts_qualifier_t qualifier; + pts_funct_comp_name_t name; + pts_meas_algorithms_t hash_algorithm; + pts_pcr_transform_t transformation; + chunk_t measurement_time, policy_uri; + chunk_t pcr_before, pcr_after, measurement; + + attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr; + attr_info = attr->get_value(attr); + + flags = attr_cast->get_flags(attr_cast); + depth = attr_cast->get_sub_component_depth(attr_cast); + /* TODO: Implement checking of components with its sub-components */ + if (depth != 0) + { + DBG1(DBG_IMV, "Current version of Attestation IMV does not support" + "sub component measurement deeper than zero"); + } + comp_vendor_id = attr_cast->get_spec_comp_funct_name_vendor_id(attr_cast); + if (comp_vendor_id != PEN_TCG) + { + DBG1(DBG_IMV, "Current version of Attestation IMV supports" + "only functional component namings by TCG "); + break; + } + family = attr_cast->get_family(attr_cast); + if (family) + { + attr = ietf_attr_pa_tnc_error_create(PEN_TCG, + TCG_PTS_INVALID_NAME_FAM, attr_info); + attr_list->insert_last(attr_list, attr); + break; + } + qualifier = attr_cast->get_qualifier(attr_cast); + + /* Check if Unknown or Wildcard was set for qualifier */ + if (qualifier.kernel && qualifier.sub_component && + (qualifier.type & PTS_FUNC_COMP_TYPE_ALL)) + { + DBG1(DBG_IMV, "Wildcard was set for the qualifier " + "of functional component"); + return FALSE; + } + else if (!qualifier.kernel && !qualifier.sub_component && + (qualifier.type & PTS_FUNC_COMP_TYPE_UNKNOWN)) + { + DBG1(DBG_IMV, "Unknown feature was set for the qualifier " + "of functional component"); + return FALSE; + } + else + { + /* TODO: Implement what todo with received qualifier */ + } + + name = attr_cast->get_comp_funct_name(attr_cast); + measurement_type = attr_cast->get_measurement_type(attr_cast); + hash_algorithm = attr_cast->get_hash_algorithm(attr_cast); + transformation = attr_cast->get_pcr_trans(attr_cast); + measurement_time = attr_cast->get_measurement_time(attr_cast); + + /* Call getters of optional fields when corresponding flag is set */ + if (flags & PTS_SIMPLE_COMP_EVID_FLAG_PCR) + { + extended_pcr = attr_cast->get_extended_pcr(attr_cast); + pcr_before = attr_cast->get_pcr_before_value(attr_cast); + pcr_after = attr_cast->get_pcr_after_value(attr_cast); + measurement = attr_cast->get_comp_measurement(attr_cast); + } + if (!(flags & PTS_SIMPLE_COMP_EVID_FLAG_NO_VALID)) + { + policy_uri = attr_cast->get_policy_uri(attr_cast); + } + + /** TODO: Implement saving the PCR number, Hash Algo = communicated one, + * PCR transform (truncate SHA256, SHA384), PCR before and after values + */ + break; + } + case TCG_PTS_SIMPLE_EVID_FINAL: + { + tcg_pts_attr_simple_evid_final_t *attr_cast; + pts_simple_evid_final_flag_t flags; + chunk_t pcr_comp = chunk_empty; + chunk_t tpm_quote_sign = chunk_empty; + chunk_t evid_sign = chunk_empty; + + /** TODO: Ignoring Composite Hash Algorithm field + * No flag defined which indicates the precense of it + */ + attr_cast = (tcg_pts_attr_simple_evid_final_t*)attr; + flags = attr_cast->get_flags(attr_cast); + + if ((flags >> 6) & PTS_SIMPLE_EVID_FINAL_FLAG_NO) + { + pcr_comp = attr_cast->get_pcr_comp(attr_cast); + tpm_quote_sign = attr_cast->get_tpm_quote_sign(attr_cast); + + /** TODO: Construct PCR Composite */ + } + if (flags & PTS_SIMPLE_EVID_FINAL_FLAG_EVID) + { + /** TODO: What to do with Evidence Signature */ + evid_sign = attr_cast->get_evid_sign(attr_cast); + } + + break; + } + case TCG_PTS_FILE_MEAS: + { + tcg_pts_attr_file_meas_t *attr_cast; + u_int16_t request_id; + int file_count, file_id; + pts_meas_algorithms_t algo; + pts_file_meas_t *measurements; + char *platform_info; + enumerator_t *e_hash; + bool is_dir; + + platform_info = pts->get_platform_info(pts); + if (!pts_db || !platform_info) + { + break; + } + + attr_cast = (tcg_pts_attr_file_meas_t*)attr; + measurements = attr_cast->get_measurements(attr_cast); + algo = pts->get_meas_algorithm(pts); + request_id = measurements->get_request_id(measurements); + file_count = measurements->get_file_count(measurements); + + DBG1(DBG_IMV, "measurement request %d returned %d file%s:", + request_id, file_count, (file_count == 1) ? "":"s"); + + if (!attestation_state->check_off_request(attestation_state, + request_id, &file_id, &is_dir)) + { + DBG1(DBG_IMV, " no entry found for this request"); + break; + } + + /* check hashes from database against measurements */ + e_hash = pts_db->create_hash_enumerator(pts_db, + platform_info, algo, file_id, is_dir); + if (!measurements->verify(measurements, e_hash, is_dir)) + { + attestation_state->set_measurement_error(attestation_state); + } + e_hash->destroy(e_hash); + break; + } + case TCG_PTS_UNIX_FILE_META: + { + tcg_pts_attr_file_meta_t *attr_cast; + int file_count; + pts_file_meta_t *metadata; + enumerator_t *e; + pts_file_metadata_t *entry; + + attr_cast = (tcg_pts_attr_file_meta_t*)attr; + metadata = attr_cast->get_metadata(attr_cast); + file_count = metadata->get_file_count(metadata); + + DBG1(DBG_IMV, "metadata request returned %d file%s:", + file_count, (file_count == 1) ? "":"s"); + + e = metadata->create_enumerator(metadata); + while(e->enumerate(e, &entry)) + { + DBG1(DBG_IMV, "File name: %s", entry->filename); + DBG1(DBG_IMV, " type: %d", entry->type); + DBG1(DBG_IMV, " size: %d", entry->filesize); + DBG1(DBG_IMV, " create time: %s", ctime(&entry->create_time)); + DBG1(DBG_IMV, " last modified: %s", ctime(&entry->last_modify_time)); + DBG1(DBG_IMV, " last accessed: %s", ctime(&entry->last_access_time)); + DBG1(DBG_IMV, " owner id: %d", entry->owner_id); + DBG1(DBG_IMV, " group id: %d", entry->group_id); + } + e->destroy(e); + + break; + } + + /* TODO: Not implemented yet */ + case TCG_PTS_INTEG_MEAS_LOG: + /* Attributes using XML */ + case TCG_PTS_TEMPL_REF_MANI_SET_META: + case TCG_PTS_VERIFICATION_RESULT: + case TCG_PTS_INTEG_REPORT: + /* On Windows only*/ + case TCG_PTS_WIN_FILE_META: + case TCG_PTS_REGISTRY_VALUE: + /* Received on IMC side only*/ + case TCG_PTS_REQ_PROTO_CAPS: + case TCG_PTS_DH_NONCE_PARAMS_REQ: + case TCG_PTS_DH_NONCE_FINISH: + case TCG_PTS_MEAS_ALGO: + case TCG_PTS_GET_TPM_VERSION_INFO: + case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META: + case TCG_PTS_UPDATE_TEMPL_REF_MANI: + case TCG_PTS_GET_AIK: + case TCG_PTS_REQ_FUNCT_COMP_EVID: + case TCG_PTS_GEN_ATTEST_EVID: + case TCG_PTS_REQ_FILE_META: + case TCG_PTS_REQ_FILE_MEAS: + case TCG_PTS_REQ_INTEG_MEAS_LOG: + default: + DBG1(DBG_IMV, "received unsupported attribute '%N'", + tcg_attr_names, attr->get_type(attr)); + break; + } + return TRUE; +} + diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_process.h b/src/libimcv/plugins/imv_attestation/imv_attestation_process.h new file mode 100644 index 0000000000..506ecfd031 --- /dev/null +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_process.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2011 Sansar Choinyambuu + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * + * @defgroup imv_attestation_process_t imv_attestation_process + * @{ @ingroup imv_attestation_process + */ + +#ifndef IMV_ATTESTATION_PROCESS_H_ +#define IMV_ATTESTATION_PROCESS_H_ + +#include "imv_attestation_state.h" + +#include +#include +#include + +#include + +#include +#include +#include + +/** + * Process a TCG PTS attribute + * + * @param attr PA-TNC attribute to be processed + * @param attr_list list with PA-TNC error attributes + * @return TRUE if successful + */ +bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list, + imv_attestation_state_t *attestation_state, + pts_meas_algorithms_t supported_algorithms, + pts_dh_group_t supported_dh_groups, + pts_database_t *pts_db, + credential_manager_t *pts_credmgr); + +#endif /** IMV_ATTESTATION_PROCESS_H_ @}*/ diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c index 6305dac2f7..498dcbf40e 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c @@ -81,6 +81,11 @@ struct private_imv_attestation_state_t { */ pts_t *pts; + /** + * File Measurement error + */ + bool measurement_error; + }; typedef struct entry_t entry_t; @@ -245,6 +250,18 @@ METHOD(imv_attestation_state_t, get_request_count, int, return this->requests->get_count(this->requests); } +METHOD(imv_attestation_state_t, get_measurement_error, bool, + private_imv_attestation_state_t *this) +{ + return this->measurement_error; +} + +METHOD(imv_attestation_state_t, set_measurement_error, void, + private_imv_attestation_state_t *this) +{ + this->measurement_error = TRUE; +} + /** * Described in header. */ @@ -269,6 +286,8 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id) .add_request = _add_request, .check_off_request = _check_off_request, .get_request_count = _get_request_count, + .get_measurement_error = _get_measurement_error, + .set_measurement_error = _set_measurement_error, }, .connection_id = connection_id, .state = TNC_CONNECTION_STATE_CREATE, diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_state.h b/src/libimcv/plugins/imv_attestation/imv_attestation_state.h index 45d382b0a1..acc46cb0cf 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation_state.h +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_state.h @@ -100,6 +100,18 @@ struct imv_attestation_state_t { bool (*check_off_request)(imv_attestation_state_t *this, u_int16_t id, int *file_id, bool *is_dir); + /** + * Indicates if a file measurement error occurred + * + * @return TRUE in case of measurement error + */ + bool (*get_measurement_error)(imv_attestation_state_t *this); + + /** + * Call if a file measurement error is encountered + */ + void (*set_measurement_error)(imv_attestation_state_t *this); + }; /**