From 3d0699595bbd4113f3b19a1f6c2d5e2ee8d008f3 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Thu, 1 Sep 2011 21:00:20 +0200 Subject: [PATCH] implemented first TCG-PTS error attribute --- src/libimcv/ietf/ietf_attr_pa_tnc_error.c | 118 +++++++++++------- .../plugins/imc_attestation/imc_attestation.c | 15 +-- .../plugins/imv_attestation/imv_attestation.c | 39 ++++-- src/libimcv/tcg/pts/pts_error.c | 23 ++++ src/libimcv/tcg/pts/pts_error.h | 11 ++ 5 files changed, 138 insertions(+), 68 deletions(-) diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c index cccb3ecc4..6daee1a77 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c @@ -34,7 +34,6 @@ typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t * * 1 2 3 * 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 - * * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Reserved | PA-TNC Error Code Vendor ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -48,7 +47,7 @@ typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t #define PA_ERROR_RESERVED 0x00 /** - * All Error Types return the first 8 bytes of the erroneous PA-TNC message + * All IETF Error Types return the first 8 bytes of the erroneous PA-TNC message * * 1 2 3 * 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 @@ -60,6 +59,7 @@ typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t */ #define PA_ERROR_MSG_INFO_SIZE 8 +#define PA_ERROR_MSG_INFO_MAX_SIZE 1024 /** * "Invalid Parameter" Error Code @@ -198,23 +198,25 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_uint32(writer, this->error_code); writer->write_data (writer, this->msg_info); - switch (this->error_code) + if (this->error_vendor_id == PEN_IETF) { - case PA_ERROR_INVALID_PARAMETER: - writer->write_uint32(writer, this->error_offset); - break; - case PA_ERROR_VERSION_NOT_SUPPORTED: - writer->write_uint8 (writer, PA_TNC_VERSION); - writer->write_uint8 (writer, PA_TNC_VERSION); - writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED); - break; - case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: - writer->write_data(writer, this->attr_info); - break; - default: - break; + switch (this->error_code) + { + case PA_ERROR_INVALID_PARAMETER: + writer->write_uint32(writer, this->error_offset); + break; + case PA_ERROR_VERSION_NOT_SUPPORTED: + writer->write_uint8 (writer, PA_TNC_VERSION); + writer->write_uint8 (writer, PA_TNC_VERSION); + writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED); + break; + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + writer->write_data(writer, this->attr_info); + break; + default: + break; + } } - this->value = chunk_clone(writer->get_buf(writer)); writer->destroy(writer); } @@ -225,10 +227,9 @@ METHOD(pa_tnc_attr_t, process, status_t, bio_reader_t *reader; u_int8_t reserved; - if (this->value.len < PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE) + if (this->value.len < PA_ERROR_HEADER_SIZE) { - DBG1(DBG_TNC, "insufficient data for PA-TNC error header and " - "error information"); + DBG1(DBG_TNC, "insufficient data for PA-TNC error header"); *offset = 0; return FAILED; } @@ -236,34 +237,49 @@ METHOD(pa_tnc_attr_t, process, status_t, reader->read_uint8 (reader, &reserved); reader->read_uint24(reader, &this->error_vendor_id); reader->read_uint32(reader, &this->error_code); - reader->read_data (reader, PA_ERROR_MSG_INFO_SIZE, &this->msg_info); - this->msg_info = chunk_clone(this->msg_info); - switch (this->error_code) + if (this->error_vendor_id == PEN_IETF) { - case PA_ERROR_INVALID_PARAMETER: - if (!reader->read_uint32(reader, &this->error_offset)) - { - reader->destroy(reader); - DBG1(DBG_TNC, "insufficient data for error offset field"); - *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; - return FAILED; - } - break; - case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: - if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE, - &this->attr_info)) - { - reader->destroy(reader); - DBG1(DBG_TNC, "insufficient data for unsupported attribute " - "information"); - *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; - return FAILED; - } - this->attr_info = chunk_clone(this->attr_info); - break; - default: - break; + if (!reader->read_data(reader, PA_ERROR_MSG_INFO_SIZE, &this->msg_info)) + { + reader->destroy(reader); + DBG1(DBG_TNC, "insufficient data for IETF error information"); + *offset = PA_ERROR_HEADER_SIZE; + return FAILED; + } + this->msg_info = chunk_clone(this->msg_info); + + switch (this->error_code) + { + case PA_ERROR_INVALID_PARAMETER: + if (!reader->read_uint32(reader, &this->error_offset)) + { + reader->destroy(reader); + DBG1(DBG_TNC, "insufficient data for error offset field"); + *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; + return FAILED; + } + break; + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE, + &this->attr_info)) + { + reader->destroy(reader); + DBG1(DBG_TNC, "insufficient data for unsupported attribute " + "information"); + *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; + return FAILED; + } + this->attr_info = chunk_clone(this->attr_info); + break; + default: + break; + } + } + else + { + reader->read_data(reader, reader->remaining(reader), &this->msg_info); + this->msg_info = chunk_clone(this->msg_info); } reader->destroy(reader); @@ -334,8 +350,14 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_t vendor_id, { private_ietf_attr_pa_tnc_error_t *this; - /* the first 8 bytes of the erroneous PA-TNC message are sent back */ - msg_info.len = PA_ERROR_MSG_INFO_SIZE; + if (vendor_id == PEN_IETF) + { + msg_info.len = PA_ERROR_MSG_INFO_SIZE; + } + else if (msg_info.len > PA_ERROR_MSG_INFO_MAX_SIZE) + { + msg_info.len = PA_ERROR_MSG_INFO_MAX_SIZE; + } INIT(this, .public = { diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation.c b/src/libimcv/plugins/imc_attestation/imc_attestation.c index cc91bcf4f..11a9a94a7 100644 --- a/src/libimcv/plugins/imc_attestation/imc_attestation.c +++ b/src/libimcv/plugins/imc_attestation/imc_attestation.c @@ -20,6 +20,8 @@ #include #include +#include + #include #include #include @@ -38,7 +40,6 @@ #include #include #include -#include /* IMC definitions */ @@ -241,19 +242,21 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, pts->set_meas_algorithm(pts, PTS_MEAS_ALGO_SHA384); } else if ((supported_algorithms & PTS_MEAS_ALGO_SHA256) && - (selected_algorithm & PTS_MEAS_ALGO_SHA256)) + (selected_algorithm & PTS_MEAS_ALGO_SHA256)) { pts->set_meas_algorithm(pts, PTS_MEAS_ALGO_SHA256); } else if ((supported_algorithms & PTS_MEAS_ALGO_SHA1) && - (selected_algorithm & PTS_MEAS_ALGO_SHA1)) + (selected_algorithm & PTS_MEAS_ALGO_SHA1)) { pts->set_meas_algorithm(pts, PTS_MEAS_ALGO_SHA1); } else { - /* TODO send a TCG_PTS_H_ALG_NOT_SUPPORTED error */ + attr = pts_hash_alg_error_create(supported_algorithms); + attr_list->insert_last(attr_list, attr); + break; } /* Send Measurement Algorithm Selection attribute */ @@ -287,7 +290,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, if (!pts->get_aik(pts, &aik, &is_naked_key)) { - DBG1(DBG_IMC,"Obtaining AIK Certificate failed"); + DBG1(DBG_IMC, "Obtaining AIK Certificate failed"); break; } @@ -360,8 +363,6 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id, tcg_attr_names, attr->get_type(attr)); break; } - - } } enumerator->destroy(enumerator); diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c index 13f3d4012..348866768 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -331,28 +332,40 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id, attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR) { ietf_attr_pa_tnc_error_t *error_attr; + pen_t error_vendor_id; pa_tnc_error_code_t error_code; chunk_t msg_info, attr_info; u_int32_t offset; error_attr = (ietf_attr_pa_tnc_error_t*)attr; + error_vendor_id = error_attr->get_vendor_id(error_attr); error_code = error_attr->get_error_code(error_attr); msg_info = error_attr->get_msg_info(error_attr); - DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B", - pa_tnc_error_code_names, error_code, &msg_info); - switch (error_code) + if (error_vendor_id == PEN_IETF) { - case PA_ERROR_INVALID_PARAMETER: - offset = error_attr->get_offset(error_attr); - DBG1(DBG_IMV, " occurred at offset of %u bytes", offset); - break; - case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: - attr_info = error_attr->get_attr_info(error_attr); - DBG1(DBG_IMV, " unsupported attribute %#B", &attr_info); - break; - default: - break; + DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B", + pa_tnc_error_code_names, error_code, &msg_info); + + switch (error_code) + { + case PA_ERROR_INVALID_PARAMETER: + offset = error_attr->get_offset(error_attr); + DBG1(DBG_IMV, " occurred at offset of %u bytes", offset); + break; + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + attr_info = error_attr->get_attr_info(error_attr); + DBG1(DBG_IMV, " unsupported attribute %#B", &attr_info); + break; + default: + break; + } + } + else if (error_vendor_id == PEN_TCG) + { + DBG1(DBG_IMV, "received TCG-PTS error '%N'", + pts_error_code_names, error_code); + DBG1(DBG_IMV, "error information: %B", &msg_info); } fatal_error = TRUE; } diff --git a/src/libimcv/tcg/pts/pts_error.c b/src/libimcv/tcg/pts/pts_error.c index ca33fb474..843a38ac3 100644 --- a/src/libimcv/tcg/pts/pts_error.c +++ b/src/libimcv/tcg/pts/pts_error.c @@ -15,6 +15,9 @@ #include "pts_error.h" +#include +#include + ENUM(pts_error_code_names, TCG_PTS_RESERVED_ERROR, TCG_PTS_UNABLE_DET_PCR, "Reserved Error", "Hash Algorithm Not Supported", @@ -34,3 +37,23 @@ ENUM(pts_error_code_names, TCG_PTS_RESERVED_ERROR, TCG_PTS_UNABLE_DET_PCR, "Unable To Determine Transitive Trust Chain", "Unable To Determine PCR" ); + +/** + * Described in header. + */ +pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms) +{ + bio_writer_t *writer; + chunk_t msg_info; + pa_tnc_attr_t *attr; + + writer = bio_writer_create(4); + writer->write_uint16(writer, 0x0000); + writer->write_uint16(writer, algorithms); + msg_info = writer->get_buf(writer); + attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_HASH_ALG_NOT_SUPPORTED, + msg_info); + writer->destroy(writer); + + return attr; +} diff --git a/src/libimcv/tcg/pts/pts_error.h b/src/libimcv/tcg/pts/pts_error.h index fa250801c..202e4d2ea 100644 --- a/src/libimcv/tcg/pts/pts_error.h +++ b/src/libimcv/tcg/pts/pts_error.h @@ -23,6 +23,9 @@ typedef enum pts_error_code_t pts_error_code_t; +#include "pts_meas_algo.h" +#include "pa_tnc/pa_tnc_attr.h" + #include /** @@ -54,4 +57,12 @@ enum pts_error_code_t { */ extern enum_name_t *pts_error_code_names; +/** + * Creates a PTS Hash Algorithm Not Supported Error Attribute + * see section 4.2.2 of PTS Protocol: Binding to TNC IF-M Specification + * + * @param algorithms supported measurement hash algorithms + */ +pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms); + #endif /** PTS_ERROR_H_ @}*/