summaryrefslogtreecommitdiff
path: root/src/libimcv/tcg/seg
diff options
context:
space:
mode:
Diffstat (limited to 'src/libimcv/tcg/seg')
-rw-r--r--src/libimcv/tcg/seg/tcg_seg_attr_max_size.c254
-rw-r--r--src/libimcv/tcg/seg/tcg_seg_attr_max_size.h73
-rw-r--r--src/libimcv/tcg/seg/tcg_seg_attr_next_seg.c258
-rw-r--r--src/libimcv/tcg/seg/tcg_seg_attr_next_seg.h73
-rw-r--r--src/libimcv/tcg/seg/tcg_seg_attr_seg_env.c257
-rw-r--r--src/libimcv/tcg/seg/tcg_seg_attr_seg_env.h76
6 files changed, 991 insertions, 0 deletions
diff --git a/src/libimcv/tcg/seg/tcg_seg_attr_max_size.c b/src/libimcv/tcg/seg/tcg_seg_attr_max_size.c
new file mode 100644
index 000000000..010eaf83d
--- /dev/null
+++ b/src/libimcv/tcg/seg/tcg_seg_attr_max_size.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 "tcg_seg_attr_max_size.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+typedef struct private_tcg_seg_attr_max_size_t private_tcg_seg_attr_max_size_t;
+
+/**
+ * Maximum Attribute Size Request/Response
+ * see TCG IF-M Segmentation Specification
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Max Attribute Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Max Segment Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of an tcg_seg_attr_max_size_t object.
+ */
+struct private_tcg_seg_attr_max_size_t {
+
+ /**
+ * Public members of tcg_seg_attr_max_size_t
+ */
+ tcg_seg_attr_max_size_t public;
+
+ /**
+ * Vendor-specific attribute type
+ */
+ pen_type_t type;
+
+ /**
+ * Length of attribute value
+ */
+ size_t length;
+
+ /**
+ * Attribute value or segment
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Maximum IF-M attribute size in octets
+ */
+ uint32_t max_attr_size;
+
+ /**
+ * Maximum IF-M attribute segment size in octets
+ */
+ uint32_t max_seg_size;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_seg_attr_max_size_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_seg_attr_max_size_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_seg_attr_max_size_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_seg_attr_max_size_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_seg_attr_max_size_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(TCG_SEG_ATTR_MAX_SIZE_SIZE);
+ writer->write_uint32(writer, this->max_attr_size);
+ writer->write_uint32(writer, this->max_seg_size);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_seg_attr_max_size_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < TCG_SEG_ATTR_MAX_SIZE_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N", tcg_attr_names,
+ this->type.type);
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32(reader, &this->max_attr_size);
+ reader->read_uint32(reader, &this->max_seg_size);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_seg_attr_max_size_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("mc", this->value, segment);
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_seg_attr_max_size_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_seg_attr_max_size_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_seg_attr_max_size_t, get_attr_size, void,
+ private_tcg_seg_attr_max_size_t *this, uint32_t *max_attr_size,
+ uint32_t *max_seg_size)
+{
+ if (max_attr_size)
+ {
+ *max_attr_size = this->max_attr_size;
+ }
+ if (max_seg_size)
+ {
+ *max_seg_size = this->max_seg_size;
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* tcg_seg_attr_max_size_create(uint32_t max_attr_size,
+ uint32_t max_seg_size,
+ bool request)
+{
+ private_tcg_seg_attr_max_size_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .add_segment = _add_segment,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_attr_size = _get_attr_size,
+ },
+ .type = { PEN_TCG, request ? TCG_SEG_MAX_ATTR_SIZE_REQ :
+ TCG_SEG_MAX_ATTR_SIZE_RESP },
+ .max_attr_size = max_attr_size,
+ .max_seg_size = max_seg_size,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_seg_attr_max_size_create_from_data(size_t length,
+ chunk_t data,
+ bool request)
+{
+ private_tcg_seg_attr_max_size_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .add_segment = _add_segment,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_attr_size = _get_attr_size,
+ },
+ .type = { PEN_TCG, request ? TCG_SEG_MAX_ATTR_SIZE_REQ :
+ TCG_SEG_MAX_ATTR_SIZE_RESP },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/seg/tcg_seg_attr_max_size.h b/src/libimcv/tcg/seg/tcg_seg_attr_max_size.h
new file mode 100644
index 000000000..72660acd5
--- /dev/null
+++ b/src/libimcv/tcg/seg/tcg_seg_attr_max_size.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 tcg_seg_attr_max_size tcg_seg_attr_max_size
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_SEG_ATTR_MAX_SIZE_H_
+#define TCG_SEG_ATTR_MAX_SIZE_H_
+
+typedef struct tcg_seg_attr_max_size_t tcg_seg_attr_max_size_t;
+
+#include "tcg/tcg_attr.h"
+
+#define TCG_SEG_ATTR_MAX_SIZE_SIZE 8
+
+/**
+ * Class implementing the TCG Segmentation Maximum Attribute Size Attribute
+ */
+struct tcg_seg_attr_max_size_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get maximum IF-M attribute and segment size in octets
+ *
+ * @param max_attr_size Maximum IF-M attribute size in octets
+ * @param max_seg_size Maximum IF-M attribute segment size in octets
+ */
+ void (*get_attr_size)(tcg_seg_attr_max_size_t *this,
+ uint32_t *max_attr_size, uint32_t *max_seg_size);
+
+};
+
+/**
+ * Creates an tcg_seg_attr_max_size_t object
+ *
+ * @param max_attr_size Maximum IF-M attribute size in octets
+ * @param max_seg_size Maximum IF-M attribute segment size in octets
+ * @param request TRUE for a request, FALSE for a response
+ */
+pa_tnc_attr_t* tcg_seg_attr_max_size_create(uint32_t max_attr_size,
+ uint32_t max_seg_size,
+ bool request);
+
+/**
+ * Creates an tcg_seg_attr_max_size_t object from received data
+ *
+ * @param length Total length of attribute value
+ * @param value Unparsed attribute value (might be a segment)
+ * @param request TRUE for a request, FALSE for a response
+ */
+pa_tnc_attr_t* tcg_seg_attr_max_size_create_from_data(size_t length,
+ chunk_t value,
+ bool request);
+
+#endif /** TCG_SEG_ATTR_MAX_SIZE_H_ @}*/
diff --git a/src/libimcv/tcg/seg/tcg_seg_attr_next_seg.c b/src/libimcv/tcg/seg/tcg_seg_attr_next_seg.c
new file mode 100644
index 000000000..995f64cad
--- /dev/null
+++ b/src/libimcv/tcg/seg/tcg_seg_attr_next_seg.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 "tcg_seg_attr_next_seg.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+typedef struct private_tcg_seg_attr_next_seg_t private_tcg_seg_attr_next_seg_t;
+
+typedef enum {
+ NEXT_SEG_FLAG_NONE = 0,
+ NEXT_SEG_FLAG_CANCEL = 1
+} next_seg_flags_t;
+
+/**
+ * Next Segment
+ * see TCG IF-M Segmentation Specification
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |C| Reserved | Base Attribute ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of an tcg_seg_attr_next_seg_t object.
+ */
+struct private_tcg_seg_attr_next_seg_t {
+
+ /**
+ * Public members of tcg_seg_attr_next_seg_t
+ */
+ tcg_seg_attr_next_seg_t public;
+
+ /**
+ * Vendor-specific attribute type
+ */
+ pen_type_t type;
+
+ /**
+ * Length of attribute value
+ */
+ size_t length;
+
+ /**
+ * Attribute value or segment
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Cancel flag
+ */
+ bool cancel_flag;
+
+ /**
+ * Base Attribute ID
+ */
+ uint32_t base_attr_id;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_seg_attr_next_seg_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(TCG_SEG_ATTR_NEXT_SEG_SIZE);
+ writer->write_uint8 (writer, this->cancel_flag ? NEXT_SEG_FLAG_CANCEL :
+ NEXT_SEG_FLAG_NONE);
+ writer->write_uint24(writer, this->base_attr_id);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_seg_attr_next_seg_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ uint8_t flags;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ DBG1(DBG_TNC, "segmentation not allowed for %N", tcg_attr_names,
+ this->type.type);
+ return FAILED;
+ }
+ if (this->value.len < TCG_SEG_ATTR_NEXT_SEG_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N", tcg_attr_names,
+ this->type.type);
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &this->base_attr_id);
+ reader->destroy(reader);
+
+ this->cancel_flag = (flags & NEXT_SEG_FLAG_CANCEL);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_seg_attr_next_seg_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("mc", this->value, segment);
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_seg_attr_next_seg_t, get_base_attr_id, uint32_t,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ return this->base_attr_id;
+}
+
+METHOD(tcg_seg_attr_next_seg_t, get_cancel_flag, bool,
+ private_tcg_seg_attr_next_seg_t *this)
+{
+ return this->cancel_flag;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* tcg_seg_attr_next_seg_create(uint32_t base_attr_id, bool cancel)
+{
+ private_tcg_seg_attr_next_seg_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .add_segment = _add_segment,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_base_attr_id = _get_base_attr_id,
+ .get_cancel_flag = _get_cancel_flag,
+ },
+ .type = { PEN_TCG, TCG_SEG_NEXT_SEG_REQ },
+ .base_attr_id = base_attr_id,
+ .cancel_flag = cancel,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_seg_attr_next_seg_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_seg_attr_next_seg_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .add_segment = _add_segment,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_base_attr_id = _get_base_attr_id,
+ .get_cancel_flag = _get_cancel_flag,
+ },
+ .type = { PEN_TCG, TCG_SEG_NEXT_SEG_REQ },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/seg/tcg_seg_attr_next_seg.h b/src/libimcv/tcg/seg/tcg_seg_attr_next_seg.h
new file mode 100644
index 000000000..49a4d3666
--- /dev/null
+++ b/src/libimcv/tcg/seg/tcg_seg_attr_next_seg.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 tcg_seg_attr_next_seg tcg_seg_attr_next_seg
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_SEG_ATTR_NEXT_SEG_H_
+#define TCG_SEG_ATTR_NEXT_SEG_H_
+
+typedef struct tcg_seg_attr_next_seg_t tcg_seg_attr_next_seg_t;
+
+#include "tcg/tcg_attr.h"
+
+#define TCG_SEG_ATTR_NEXT_SEG_SIZE 4
+
+/**
+ * Class implementing the TCG Segmentation Next Segment Attribute
+ */
+struct tcg_seg_attr_next_seg_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Base Attribute ID
+ *
+ * @return Base Attribute ID
+ */
+ uint32_t (*get_base_attr_id)(tcg_seg_attr_next_seg_t *this);
+
+ /**
+ * Get the Cancel flag
+ *
+ * @return Cancel flag
+ */
+ bool (*get_cancel_flag)(tcg_seg_attr_next_seg_t *this);
+
+};
+
+/**
+ * Creates an tcg_seg_attr_next_seg_t object
+ *
+ * @param base_attr_id Base Attribute ID
+ * @param cancel If TRUE set Cancel flag
+ */
+pa_tnc_attr_t* tcg_seg_attr_next_seg_create(uint32_t base_attr_id, bool cancel);
+
+/**
+ * Creates an tcg_seg_attr_next_seg_t object from received data
+ *
+ * @param length Total length of attribute value
+ * @param value Unparsed attribute value (might be a segment)
+ */
+pa_tnc_attr_t* tcg_seg_attr_next_seg_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_SEG_ATTR_NEXT_SEG_H_ @}*/
diff --git a/src/libimcv/tcg/seg/tcg_seg_attr_seg_env.c b/src/libimcv/tcg/seg/tcg_seg_attr_seg_env.c
new file mode 100644
index 000000000..4f767539c
--- /dev/null
+++ b/src/libimcv/tcg/seg/tcg_seg_attr_seg_env.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 "tcg_seg_attr_seg_env.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+typedef struct private_tcg_seg_attr_seg_env_t private_tcg_seg_attr_seg_env_t;
+
+/**
+ * Attribute Segment Envelope
+ * see TCG IF-M Segmentation Specification
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |M|S| Reserved | Base Attribute ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Segment Value (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Private data of an tcg_seg_attr_seg_env_t object.
+ */
+struct private_tcg_seg_attr_seg_env_t {
+
+ /**
+ * Public members of tcg_seg_attr_seg_env_t
+ */
+ tcg_seg_attr_seg_env_t public;
+
+ /**
+ * Vendor-specific attribute type
+ */
+ pen_type_t type;
+
+ /**
+ * Length of attribute value
+ */
+ size_t length;
+
+ /**
+ * Attribute value or segment
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * PA-TNC segmentation flags
+ */
+ uint8_t flags;
+
+ /**
+ * Base Attribute ID
+ */
+ uint32_t base_attr_id;
+
+ /**
+ * Attribute value
+ */
+ chunk_t segment;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_seg_attr_seg_env_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ /* constructor already allocated and built value */
+ this->length = this->value.len;
+ return;
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_seg_attr_seg_env_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ DBG1(DBG_TNC, "segmentation not allowed for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ return FAILED;
+ }
+ if (this->value.len < TCG_SEG_ATTR_SEG_ENV_HEADER)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &this->flags);
+ reader->read_uint24(reader, &this->base_attr_id);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_seg_attr_seg_env_t *this, chunk_t segment)
+{
+ /* no segments are expected */
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_seg_attr_seg_env_t, get_segment, chunk_t,
+ private_tcg_seg_attr_seg_env_t *this, uint8_t *flags)
+{
+ if (flags)
+ {
+ *flags = this->flags;
+ }
+ return chunk_skip(this->value, TCG_SEG_ATTR_SEG_ENV_HEADER);
+}
+
+METHOD(tcg_seg_attr_seg_env_t, get_base_attr_id, uint32_t,
+ private_tcg_seg_attr_seg_env_t *this)
+{
+ return this->base_attr_id;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t* tcg_seg_attr_seg_env_create(chunk_t segment, uint8_t flags,
+ uint32_t base_attr_id)
+{
+ private_tcg_seg_attr_seg_env_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .add_segment = _add_segment,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_base_attr_id = _get_base_attr_id,
+ .get_segment = _get_segment,
+ },
+ .type = { PEN_TCG, TCG_SEG_ATTR_SEG_ENV },
+ .flags = flags,
+ .base_attr_id = base_attr_id,
+ .value = chunk_alloc(TCG_SEG_ATTR_SEG_ENV_HEADER + segment.len),
+ .ref = 1,
+ );
+
+ htoun32(this->value.ptr, base_attr_id);
+ *this->value.ptr = flags;
+ memcpy(this->value.ptr + TCG_SEG_ATTR_SEG_ENV_HEADER,
+ segment.ptr, segment.len);
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_seg_attr_seg_env_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_seg_attr_seg_env_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .add_segment = _add_segment,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .get_base_attr_id = _get_base_attr_id,
+ .get_segment = _get_segment,
+ },
+ .type = { PEN_TCG, TCG_SEG_ATTR_SEG_ENV },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/seg/tcg_seg_attr_seg_env.h b/src/libimcv/tcg/seg/tcg_seg_attr_seg_env.h
new file mode 100644
index 000000000..a8b3d7c34
--- /dev/null
+++ b/src/libimcv/tcg/seg/tcg_seg_attr_seg_env.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2014 Andreas Steffen
+ * 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 <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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 tcg_seg_attr_seg_env tcg_seg_attr_seg_env
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_SEG_ATTR_SEG_ENV_H_
+#define TCG_SEG_ATTR_SEG_ENV_H_
+
+typedef struct tcg_seg_attr_seg_env_t tcg_seg_attr_seg_env_t;
+
+#include "tcg/tcg_attr.h"
+
+#define TCG_SEG_ATTR_SEG_ENV_HEADER 4
+
+/**
+ * Class implementing the TCG Segmentation Envelope Attribute
+ */
+struct tcg_seg_attr_seg_env_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get enveloped attribute segment
+ *
+ * @param flags Segmentation flags
+ * @return Segment
+ */
+ chunk_t (*get_segment)(tcg_seg_attr_seg_env_t *this, uint8_t *flags);
+
+ /**
+ * Get Base Attribute ID
+ *
+ * @return Base Attribute ID
+ */
+ uint32_t (*get_base_attr_id)(tcg_seg_attr_seg_env_t *this);
+
+};
+
+/**
+ * Creates an tcg_seg_attr_seg_env_t object
+ *
+ * @param segment Attribute segment
+ * @param flags Segmentation flags
+ * @param base_attr_id Base Attribute ID
+ */
+pa_tnc_attr_t* tcg_seg_attr_seg_env_create(chunk_t segment, uint8_t flags,
+ uint32_t base_attr_id);
+
+/**
+ * Creates an tcg_seg_attr_seg_env_t object from received data
+ *
+ * @param length Total length of attribute value
+ * @param value Unparsed attribute value (might be a segment)
+ */
+pa_tnc_attr_t* tcg_seg_attr_seg_env_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_SEG_ATTR_SEG_ENV_H_ @}*/