implemented first TCG-PTS error attribute
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 1 Sep 2011 19:00:20 +0000 (21:00 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 8 Sep 2011 10:08:15 +0000 (12:08 +0200)
src/libimcv/ietf/ietf_attr_pa_tnc_error.c
src/libimcv/plugins/imc_attestation/imc_attestation.c
src/libimcv/plugins/imv_attestation/imv_attestation.c
src/libimcv/tcg/pts/pts_error.c
src/libimcv/tcg/pts/pts_error.h

index cccb3ec..6daee1a 100644 (file)
@@ -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 = {
index cc91bcf..11a9a94 100644 (file)
@@ -20,6 +20,8 @@
 #include <ietf/ietf_attr.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
 
+#include <tcg/pts/pts_error.h>
+
 #include <tcg/tcg_pts_attr_proto_caps.h>
 #include <tcg/tcg_pts_attr_meas_algo.h>
 #include <tcg/tcg_pts_attr_get_tpm_version_info.h>
@@ -38,7 +40,6 @@
 #include <pen/pen.h>
 #include <debug.h>
 #include <utils/linked_list.h>
-#include <crypto/hashers/hasher.h>
 
 /* 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);
index 13f3d40..3488667 100644 (file)
@@ -21,6 +21,7 @@
 #include <ietf/ietf_attr_pa_tnc_error.h>
 
 #include <tcg/pts/pts_database.h>
+#include <tcg/pts/pts_error.h>
 
 #include <tcg/tcg_attr.h>
 #include <tcg/tcg_pts_attr_proto_caps.h>
@@ -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;
                }
index ca33fb4..843a38a 100644 (file)
@@ -15,6 +15,9 @@
 
 #include "pts_error.h"
 
+#include <bio/bio_writer.h>
+#include <ietf/ietf_attr_pa_tnc_error.h>
+
 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;
+}
index fa25080..202e4d2 100644 (file)
@@ -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 <library.h>
 
 /**
@@ -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_ @}*/