summaryrefslogtreecommitdiff
path: root/src/libimcv/tcg
diff options
context:
space:
mode:
authorRomain Francoise <rfrancoise@debian.org>2014-10-21 19:28:38 +0200
committerRomain Francoise <rfrancoise@debian.org>2014-10-21 19:41:50 +0200
commitb23b0e5609ed4b3d29396a1727aab035fa4a395f (patch)
tree091d0b144dd92a0c124b7fbe9eae68f79cb975dc /src/libimcv/tcg
parent4a01a7e2574040cf246fd00ebff173b873c17349 (diff)
downloadvyos-strongswan-b23b0e5609ed4b3d29396a1727aab035fa4a395f.tar.gz
vyos-strongswan-b23b0e5609ed4b3d29396a1727aab035fa4a395f.zip
Import upstream release 5.2.1
Diffstat (limited to 'src/libimcv/tcg')
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_aik.c266
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_aik.h67
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.c287
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.h92
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c258
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h75
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c306
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h96
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c356
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_file_meas.h68
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.c225
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.h56
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_get_aik.c222
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_get_aik.h56
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.c225
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.h57
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.c243
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.h71
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.c244
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.h70
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.c314
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.h93
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.c296
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.h84
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c389
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.h83
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c532
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.h67
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.c405
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.h96
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.c248
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.h73
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.c372
-rw-r--r--src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.h68
-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
-rw-r--r--src/libimcv/tcg/swid/tcg_swid_attr_req.c349
-rw-r--r--src/libimcv/tcg/swid/tcg_swid_attr_req.h106
-rw-r--r--src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c396
-rw-r--r--src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h109
-rw-r--r--src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c389
-rw-r--r--src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h108
-rw-r--r--src/libimcv/tcg/tcg_attr.c270
-rw-r--r--src/libimcv/tcg/tcg_attr.h105
48 files changed, 9283 insertions, 0 deletions
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_aik.c b/src/libimcv/tcg/pts/tcg_pts_attr_aik.c
new file mode 100644
index 000000000..194cf1b68
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_aik.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_aik.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_pts_attr_aik_t private_tcg_pts_attr_aik_t;
+
+/**
+ * Attestation Identity Key
+ * see section 3.13 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Attestation Identity Key (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Attestation Identity Key (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_AIK_SIZE 4
+#define PTS_AIK_FLAGS_NONE 0
+#define PTS_AIK_FLAGS_NAKED_KEY (1<<7)
+/**
+ * Private data of an tcg_pts_attr_aik_t object.
+ */
+struct private_tcg_pts_attr_aik_t {
+
+ /**
+ * Public members of tcg_pts_attr_aik_t
+ */
+ tcg_pts_attr_aik_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;
+
+ /**
+ * AIK Certificate or Public Key
+ */
+ certificate_t *aik;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_aik_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_aik_t *this)
+{
+ bio_writer_t *writer;
+ u_int8_t flags = PTS_AIK_FLAGS_NONE;
+ cred_encoding_type_t encoding_type = CERT_ASN1_DER;
+ chunk_t aik_blob;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY)
+ {
+ flags |= PTS_AIK_FLAGS_NAKED_KEY;
+ encoding_type = PUBKEY_SPKI_ASN1_DER;
+ }
+ if (!this->aik->get_encoding(this->aik, encoding_type, &aik_blob))
+ {
+ DBG1(DBG_TNC, "encoding of Attestation Identity Key failed");
+ aik_blob = chunk_empty;
+ }
+ writer = bio_writer_create(PTS_AIK_SIZE);
+ writer->write_uint8(writer, flags);
+ writer->write_data (writer, aik_blob);
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+ free(aik_blob.ptr);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_aik_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ certificate_type_t type;
+ chunk_t aik_blob;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_AIK_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Attestation Identity Key");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8(reader, &flags);
+ reader->read_data (reader, reader->remaining(reader), &aik_blob);
+
+ type = (flags & PTS_AIK_FLAGS_NAKED_KEY) ? CERT_TRUSTED_PUBKEY : CERT_X509;
+
+ this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+ BUILD_BLOB_PEM, aik_blob, BUILD_END);
+ reader->destroy(reader);
+
+ if (!this->aik)
+ {
+ DBG1(DBG_TNC, "parsing of Attestation Identity Key failed");
+ *offset = 0;
+ return FAILED;
+ }
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_aik_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_pts_attr_aik_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_aik_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->aik);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_aik_t, get_aik, certificate_t*,
+ private_tcg_pts_attr_aik_t *this)
+{
+ return this->aik;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik)
+{
+ private_tcg_pts_attr_aik_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_aik = _get_aik,
+ },
+ .type = { PEN_TCG, TCG_PTS_AIK },
+ .aik = aik->get_ref(aik),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(size_t length, chunk_t data)
+{
+ private_tcg_pts_attr_aik_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_aik = _get_aik,
+ },
+ .type = { PEN_TCG, TCG_PTS_AIK },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_aik.h b/src/libimcv/tcg/pts/tcg_pts_attr_aik.h
new file mode 100644
index 000000000..b524ff321
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_aik.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_aik tcg_pts_attr_aik
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_AIK_H_
+#define TCG_PTS_ATTR_AIK_H_
+
+typedef struct tcg_pts_attr_aik_t tcg_pts_attr_aik_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+#include <credentials/certificates/certificate.h>
+
+/**
+ * Class implementing the TCG PTS Attestation Identity Key attribute
+ *
+ */
+struct tcg_pts_attr_aik_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get AIK
+ *
+ * @return AIK Certificate or Public Key
+ */
+ certificate_t* (*get_aik)(tcg_pts_attr_aik_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_aik_t object
+ *
+ * @param aik Attestation Identity Key
+ */
+pa_tnc_attr_t* tcg_pts_attr_aik_create(certificate_t *aik);
+
+/**
+ * Creates an tcg_pts_attr_aik_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_pts_attr_aik_create_from_data(size_t length, chunk_t value);
+
+#endif /** TCG_PTS_ATTR_AIK_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.c b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.c
new file mode 100644
index 000000000..2a1506898
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_dh_nonce_finish.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_pts_attr_dh_nonce_finish_t
+ private_tcg_pts_attr_dh_nonce_finish_t;
+
+/**
+ * PTS DH Nonce Finish
+ * see section 3.8.3 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Nonce Len | Selected Hash Algorithm |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Initiator Public Value ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Initiator Nonce ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_DH_NONCE_FINISH_SIZE 12
+#define PTS_DH_NONCE_FINISH_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_dh_nonce_finish_t object.
+ */
+struct private_tcg_pts_attr_dh_nonce_finish_t {
+
+ /**
+ * Public members of tcg_pts_attr_dh_nonce_finish_t
+ */
+ tcg_pts_attr_dh_nonce_finish_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;
+
+ /**
+ * Selected Hashing Algorithm
+ */
+ pts_meas_algorithms_t hash_algo;
+
+ /**
+ * DH Initiator Public Value
+ */
+ chunk_t initiator_value;
+
+ /**
+ * DH Initiator Nonce
+ */
+ chunk_t initiator_nonce;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_dh_nonce_finish_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_DH_NONCE_FINISH_SIZE);
+ writer->write_uint8 (writer, PTS_DH_NONCE_FINISH_RESERVED);
+ writer->write_uint8 (writer, this->initiator_nonce.len);
+ writer->write_uint16(writer, this->hash_algo);
+ writer->write_data (writer, this->initiator_value);
+ writer->write_data (writer, this->initiator_nonce);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t reserved, nonce_len;
+ u_int16_t hash_algo;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_DH_NONCE_FINISH_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Finish");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint8 (reader, &nonce_len);
+ reader->read_uint16(reader, &hash_algo);
+ reader->read_data(reader, reader->remaining(reader) - nonce_len,
+ &this->initiator_value);
+ reader->read_data(reader, nonce_len, &this->initiator_nonce);
+ this->hash_algo = hash_algo;
+ this->initiator_value = chunk_clone(this->initiator_value);
+ this->initiator_nonce = chunk_clone(this->initiator_nonce);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_dh_nonce_finish_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_pts_attr_dh_nonce_finish_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->initiator_value.ptr);
+ free(this->initiator_nonce.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_dh_nonce_finish_t, get_hash_algo, pts_meas_algorithms_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->hash_algo;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_finish_t, get_initiator_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->initiator_value;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_finish_t, get_initiator_nonce, chunk_t,
+ private_tcg_pts_attr_dh_nonce_finish_t *this)
+{
+ return this->initiator_nonce;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create(
+ pts_meas_algorithms_t hash_algo,
+ chunk_t initiator_value,
+ chunk_t initiator_nonce)
+{
+ private_tcg_pts_attr_dh_nonce_finish_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_hash_algo = _get_hash_algo,
+ .get_initiator_nonce = _get_initiator_nonce,
+ .get_initiator_value = _get_initiator_value,
+ },
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_FINISH },
+ .hash_algo = hash_algo,
+ .initiator_value = initiator_value,
+ .initiator_nonce = chunk_clone(initiator_nonce),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(size_t length,
+ chunk_t value)
+{
+ private_tcg_pts_attr_dh_nonce_finish_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_hash_algo = _get_hash_algo,
+ .get_initiator_nonce = _get_initiator_nonce,
+ .get_initiator_value = _get_initiator_value,
+ },
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_FINISH },
+ .length = length,
+ .value = chunk_clone(value),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.h b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.h
new file mode 100644
index 000000000..78b5025bc
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_finish.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_dh_nonce_finish tcg_pts_attr_dh_nonce_finish
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_DH_NONCE_FINISH_H_
+#define TCG_PTS_ATTR_DH_NONCE_FINISH_H_
+
+typedef struct tcg_pts_attr_dh_nonce_finish_t tcg_pts_attr_dh_nonce_finish_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_meas_algo.h"
+
+/**
+ * Class implementing the TCG PTS DH Nonce Finish Attribute
+ */
+struct tcg_pts_attr_dh_nonce_finish_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get nonce length
+ *
+ * @return Length of nonce
+ */
+ u_int8_t (*get_nonce_len)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+ /**
+ * Get selected hash algorithm
+ *
+ * @return Selected hash algorithm
+ */
+ pts_meas_algorithms_t (*get_hash_algo)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+ /**
+ * Get DH Initiator Public Value
+ *
+ * @return DH Initiator Public Value
+ */
+ chunk_t (*get_initiator_value)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+ /**
+ * Get DH Initiator Nonce
+ *
+ * @return DH Initiator Nonce
+ */
+ chunk_t (*get_initiator_nonce)(tcg_pts_attr_dh_nonce_finish_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_finish_t object
+ *
+ * @param hash_algo Selected hash algorithm
+ * @param initiator_value DH Initiator Public Value
+ * @param initiator_nonce DH Initiator Nonce
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_finish_create(
+ pts_meas_algorithms_t hash_algo,
+ chunk_t initiator_value,
+ chunk_t initiator_nonce);
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_finish_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_pts_attr_dh_nonce_finish_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_DH_NONCE_FINISH_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c
new file mode 100644
index 000000000..0349ce53e
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_dh_nonce_params_req.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_pts_attr_dh_nonce_params_req_t
+ private_tcg_pts_attr_dh_nonce_params_req_t;
+
+/**
+ * PTS DH Nonce Parameters Request
+ * see section 3.8.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Min. Nonce Len | D-H Group Set |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_DH_NONCE_PARAMS_REQ_SIZE 4
+#define PTS_DH_NONCE_PARAMS_REQ_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_dh_nonce_params_req_t object.
+ */
+struct private_tcg_pts_attr_dh_nonce_params_req_t {
+
+ /**
+ * Public members of tcg_pts_attr_dh_nonce_params_req_t
+ */
+ tcg_pts_attr_dh_nonce_params_req_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;
+
+ /**
+ * Minimum acceptable length of nonce
+ */
+ u_int8_t min_nonce_len;
+
+ /**
+ * Diffie Hellman group set
+ */
+ pts_dh_group_t dh_groups;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_DH_NONCE_PARAMS_REQ_SIZE);
+ writer->write_uint8 (writer, PTS_DH_NONCE_PARAMS_REQ_RESERVED);
+ writer->write_uint8 (writer, this->min_nonce_len);
+ writer->write_uint16(writer, this->dh_groups);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t reserved;
+ u_int16_t dh_groups;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_DH_NONCE_PARAMS_REQ_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Parameters Request");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8(reader, &reserved);
+ reader->read_uint8(reader, &this->min_nonce_len);
+ reader->read_uint16(reader, &dh_groups);
+ this->dh_groups = dh_groups;
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_dh_nonce_params_req_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_pts_attr_dh_nonce_params_req_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_min_nonce_len, u_int8_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->min_nonce_len;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_req_t, get_dh_groups, pts_dh_group_t,
+ private_tcg_pts_attr_dh_nonce_params_req_t *this)
+{
+ return this->dh_groups;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len,
+ pts_dh_group_t dh_groups)
+{
+ private_tcg_pts_attr_dh_nonce_params_req_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_min_nonce_len = _get_min_nonce_len,
+ .get_dh_groups = _get_dh_groups,
+ },
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_REQ },
+ .min_nonce_len = min_nonce_len,
+ .dh_groups = dh_groups,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(size_t length,
+ chunk_t value)
+{
+ private_tcg_pts_attr_dh_nonce_params_req_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_min_nonce_len = _get_min_nonce_len,
+ .get_dh_groups = _get_dh_groups,
+ },
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_REQ },
+ .length = length,
+ .value = chunk_clone(value),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h
new file mode 100644
index 000000000..4396bf687
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_req.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_dh_nonce_params_req tcg_pts_attr_dh_nonce_params_req
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_
+#define TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_
+
+typedef struct tcg_pts_attr_dh_nonce_params_req_t
+ tcg_pts_attr_dh_nonce_params_req_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_dh_group.h"
+
+/**
+ * Class implementing the TCG PTS DH Nonce Parameters Request Attribute
+ */
+struct tcg_pts_attr_dh_nonce_params_req_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Minimum nonce length
+ *
+ * @return Minimum acceptable length of nonce
+ */
+ u_int8_t (*get_min_nonce_len)(tcg_pts_attr_dh_nonce_params_req_t *this);
+
+ /**
+ * Get supported Diffie Hellman Groups
+ *
+ * @return Supported Diffie Hellman Groups
+ */
+ pts_dh_group_t (*get_dh_groups)(tcg_pts_attr_dh_nonce_params_req_t *this);
+};
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_req_t object
+ *
+ * @param min_nonce_len Minimum acceptable length of nonce
+ * @param dh_groups Initiator's supported DH groups
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len,
+ pts_dh_group_t dh_groups);
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_req_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_pts_attr_dh_nonce_params_req_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_DH_NONCE_PARAMS_REQ_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c
new file mode 100644
index 000000000..fa1dbdd3a
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_dh_nonce_params_resp.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_pts_attr_dh_nonce_params_resp_t
+ private_tcg_pts_attr_dh_nonce_params_resp_t;
+
+/**
+ * PTS DH Nonce Parameters Response
+ * see section 3.8.2 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Nonce Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Selected D-H Group | Hash Algorithm Set |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Responder Nonce ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | D-H Responder Public Value ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_DH_NONCE_PARAMS_RESP_SIZE 16
+#define PTS_DH_NONCE_PARAMS_RESP_RESERVED 0x0000
+
+/**
+ * Private data of an tcg_pts_attr_dh_nonce_params_resp_t object.
+ */
+struct private_tcg_pts_attr_dh_nonce_params_resp_t {
+
+ /**
+ * Public members of tcg_pts_attr_dh_nonce_params_resp_t
+ */
+ tcg_pts_attr_dh_nonce_params_resp_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;
+
+ /**
+ * Selected Diffie Hellman group
+ */
+ pts_dh_group_t dh_group;
+
+ /**
+ * Supported Hashing Algorithms
+ */
+ pts_meas_algorithms_t hash_algo_set;
+
+ /**
+ * DH Responder Nonce
+ */
+ chunk_t responder_nonce;
+
+ /**
+ * DH Responder Public Value
+ */
+ chunk_t responder_value;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_DH_NONCE_PARAMS_RESP_SIZE);
+ writer->write_uint24(writer, PTS_DH_NONCE_PARAMS_RESP_RESERVED);
+ writer->write_uint8 (writer, this->responder_nonce.len);
+ writer->write_uint16(writer, this->dh_group);
+ writer->write_uint16(writer, this->hash_algo_set);
+ writer->write_data (writer, this->responder_nonce);
+ writer->write_data (writer, this->responder_value);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+ u_int8_t nonce_len;
+ u_int16_t dh_group, hash_algo_set;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_DH_NONCE_PARAMS_RESP_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS DH Nonce Parameters Response");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint24(reader, &reserved);
+ reader->read_uint8 (reader, &nonce_len);
+ reader->read_uint16(reader, &dh_group);
+ reader->read_uint16(reader, &hash_algo_set);
+ reader->read_data(reader, nonce_len, &this->responder_nonce);
+ reader->read_data(reader, reader->remaining(reader), &this->responder_value);
+ this->dh_group = dh_group;
+ this->hash_algo_set = hash_algo_set;
+ this->responder_nonce = chunk_clone(this->responder_nonce);
+ this->responder_value = chunk_clone(this->responder_value);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_dh_nonce_params_resp_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_pts_attr_dh_nonce_params_resp_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->responder_nonce.ptr);
+ free(this->responder_value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_dh_group, pts_dh_group_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->dh_group;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_hash_algo_set,
+ pts_meas_algorithms_t, private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->hash_algo_set;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_responder_nonce, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->responder_nonce;
+}
+
+METHOD(tcg_pts_attr_dh_nonce_params_resp_t, get_responder_value, chunk_t,
+ private_tcg_pts_attr_dh_nonce_params_resp_t *this)
+{
+ return this->responder_value;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group,
+ pts_meas_algorithms_t hash_algo_set,
+ chunk_t responder_nonce,
+ chunk_t responder_value)
+{
+ private_tcg_pts_attr_dh_nonce_params_resp_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_dh_group = _get_dh_group,
+ .get_hash_algo_set = _get_hash_algo_set,
+ .get_responder_nonce = _get_responder_nonce,
+ .get_responder_value = _get_responder_value,
+ },
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_RESP },
+ .dh_group = dh_group,
+ .hash_algo_set = hash_algo_set,
+ .responder_nonce = chunk_clone(responder_nonce),
+ .responder_value = responder_value,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(size_t length,
+ chunk_t value)
+{
+ private_tcg_pts_attr_dh_nonce_params_resp_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_dh_group = _get_dh_group,
+ .get_hash_algo_set = _get_hash_algo_set,
+ .get_responder_nonce = _get_responder_nonce,
+ .get_responder_value = _get_responder_value,
+ },
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_RESP },
+ .length = length,
+ .value = chunk_clone(value),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h
new file mode 100644
index 000000000..b548a81f0
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_dh_nonce_params_resp tcg_pts_attr_dh_nonce_params_resp
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_
+#define TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_
+
+typedef struct tcg_pts_attr_dh_nonce_params_resp_t
+ tcg_pts_attr_dh_nonce_params_resp_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_dh_group.h"
+#include "pts/pts_meas_algo.h"
+
+/**
+ * Class implementing the TCG PTS DH Nonce Parameters Response Attribute
+ */
+struct tcg_pts_attr_dh_nonce_params_resp_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get selected Diffie Hellman Group
+ *
+ * @return Selected Diffie Hellman Group
+ */
+ pts_dh_group_t (*get_dh_group)(tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+ /**
+ * Get supported hash algorithms
+ *
+ * @return Hash algorithm set
+ */
+ pts_meas_algorithms_t (*get_hash_algo_set)(
+ tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+ /**
+ * Get DH Responder Nonce
+ *
+ * @return DH Responder Nonce
+ */
+ chunk_t (*get_responder_nonce)(tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+ /**
+ * Get DH Responder Public Value
+ *
+ * @return DH Responder Public Value
+ */
+ chunk_t (*get_responder_value)(tcg_pts_attr_dh_nonce_params_resp_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_resp_t object
+ *
+ * @param dh_group Selected DH group
+ * @param hash_algo_set Set of supported hash algorithms
+ * @param responder_nonce DH Responder Nonce
+ * @param responder_value DH Responder Public value
+ */
+pa_tnc_attr_t* tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group,
+ pts_meas_algorithms_t hash_algo_set,
+ chunk_t responder_nonce,
+ chunk_t responder_value);
+
+/**
+ * Creates an tcg_pts_attr_dh_nonce_params_resp_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_pts_attr_dh_nonce_params_resp_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_DH_NONCE_PARAMS_RESP_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
new file mode 100644
index 000000000..5b4cc273b
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_file_meas.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t;
+
+/**
+ * File Measurement
+ * see section 3.19.2 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Request ID | Measurement Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement #1 (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Filename Length | Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement #2 (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Filename Length | Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ...........................
+ */
+
+#define PTS_FILE_MEAS_SIZE 12
+
+/**
+ * Private data of an tcg_pts_attr_file_meas_t object.
+ */
+struct private_tcg_pts_attr_file_meas_t {
+
+ /**
+ * Public members of tcg_pts_attr_file_meas_t
+ */
+ tcg_pts_attr_file_meas_t public;
+
+ /**
+ * Vendor-specific attribute type
+ */
+ pen_type_t type;
+
+ /**
+ * Length of attribute value
+ */
+ size_t length;
+
+ /**
+ * Offset up to which attribute value has been processed
+ */
+ size_t offset;
+
+ /**
+ * Current position of attribute value pointer
+ */
+ chunk_t value;
+
+ /**
+ * Contains complete attribute or current segment
+ */
+ chunk_t segment;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Request ID
+ */
+ uint16_t request_id;
+
+ /**
+ * Measurement Length
+ */
+ uint16_t meas_len;
+
+ /**
+ * Number of Files in attribute
+ */
+ uint64_t count;
+
+ /**
+ * PTS File Measurements
+ */
+ pts_file_meas_t *measurements;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_file_meas_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ u_int64_t count;
+ u_int16_t request_id;
+ char *filename;
+ chunk_t measurement;
+ bool first = TRUE;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ count = this->measurements->get_file_count(this->measurements);
+ request_id = this->measurements->get_request_id(this->measurements);
+
+ writer = bio_writer_create(PTS_FILE_MEAS_SIZE);
+ writer->write_uint64(writer, count);
+ writer->write_uint16(writer, request_id);
+
+ enumerator = this->measurements->create_enumerator(this->measurements);
+ while (enumerator->enumerate(enumerator, &filename, &measurement))
+ {
+ if (first)
+ {
+ writer->write_uint16(writer, measurement.len);
+ first = FALSE;
+ }
+ writer->write_data (writer, measurement);
+ writer->write_data16(writer, chunk_create(filename, strlen(filename)));
+ }
+ enumerator->destroy(enumerator);
+
+ if (first)
+ {
+ /* no attached measurements */
+ writer->write_uint16(writer, 0);
+ }
+
+ this->value = writer->extract_buf(writer);
+ this->segment = this->value;
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_file_meas_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ chunk_t measurement, filename;
+ status_t status = NEED_MORE;
+ char buf[BUF_LEN];
+ size_t len;
+
+ if (this->offset == 0)
+ {
+ if (this->length < PTS_FILE_MEAS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ return FAILED;
+ }
+ if (this->value.len < PTS_FILE_MEAS_SIZE)
+ {
+ return NEED_MORE;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint64(reader, &this->count);
+ reader->read_uint16(reader, &this->request_id);
+ reader->read_uint16(reader, &this->meas_len);
+ this->offset = PTS_FILE_MEAS_SIZE;
+ this->value = reader->peek(reader);
+ reader->destroy(reader);
+ }
+
+ this->measurements = pts_file_meas_create(this->request_id);
+ reader = bio_reader_create(this->value);
+
+ while (this->count)
+ {
+ if (!reader->read_data(reader, this->meas_len, &measurement) ||
+ !reader->read_data16(reader, &filename))
+ {
+ goto end;
+ }
+ this->offset += this->value.len - reader->remaining(reader);
+ this->value = reader->peek(reader);
+
+ len = min(filename.len, BUF_LEN-1);
+ memcpy(buf, filename.ptr, len);
+ buf[len] = '\0';
+ this->measurements->add(this->measurements, buf, measurement);
+ this->count--;
+ }
+
+ if (this->length != this->offset)
+ {
+ DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ status = FAILED;
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_file_meas_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("cc", this->value, segment);
+ chunk_free(&this->segment);
+ this->segment = this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->measurements);
+ free(this->segment.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_file_meas_t, get_measurements, pts_file_meas_t*,
+ private_tcg_pts_attr_file_meas_t *this)
+{
+ return this->measurements;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements)
+{
+ private_tcg_pts_attr_file_meas_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_measurements = _get_measurements,
+ },
+ .type = { PEN_TCG, TCG_PTS_FILE_MEAS },
+ .request_id = measurements->get_request_id(measurements),
+ .count = measurements->get_file_count(measurements),
+ .measurements = measurements,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_file_meas_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_measurements = _get_measurements,
+ },
+ .type = { PEN_TCG, TCG_PTS_FILE_MEAS },
+ .length = length,
+ .segment = chunk_clone(data),
+ .ref = 1,
+ );
+
+ /* received either complete attribute value or first segment */
+ this->value = this->segment;
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.h b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.h
new file mode 100644
index 000000000..d399fecbb
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_file_meas.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_file_meas tcg_pts_attr_file_meas
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_FILE_MEAS_H_
+#define TCG_PTS_ATTR_FILE_MEAS_H_
+
+typedef struct tcg_pts_attr_file_meas_t tcg_pts_attr_file_meas_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts.h"
+#include "pts/pts_file_meas.h"
+
+/**
+ * Class implementing the TCG PTS File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_file_meas_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS File Measurements
+ *
+ * @return PTS File Measurements
+ */
+ pts_file_meas_t* (*get_measurements)(tcg_pts_attr_file_meas_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_file_meas_t object
+ *
+ * @param measurements PTS File Measurements
+ */
+pa_tnc_attr_t* tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements);
+
+/**
+ * Creates an tcg_pts_attr_file_meas_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_pts_attr_file_meas_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_FILE_MEAS_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.c b/src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.c
new file mode 100644
index 000000000..b7b4d7e3f
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_gen_attest_evid.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_pts_attr_gen_attest_evid_t
+ private_tcg_pts_attr_gen_attest_evid_t;
+
+/**
+ * Generate Attestation Evidence
+ * see section 3.14.2 of PTS Protocol: Binding to TNC IF-M 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
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_GEN_ATTEST_EVID_SIZE 4
+#define PTS_GEN_ATTEST_EVID_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_gen_attest_evid_t object.
+ */
+struct private_tcg_pts_attr_gen_attest_evid_t {
+
+ /**
+ * Public members of tcg_pts_attr_gen_attest_evid_t
+ */
+ tcg_pts_attr_gen_attest_evid_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;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_gen_attest_evid_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_GEN_ATTEST_EVID_SIZE);
+ writer->write_uint32 (writer, PTS_GEN_ATTEST_EVID_RESERVED);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_gen_attest_evid_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_GEN_ATTEST_EVID_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Generate Attestation Evidence");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32 (reader, &reserved);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_gen_attest_evid_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_pts_attr_gen_attest_evid_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_gen_attest_evid_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create()
+{
+ private_tcg_pts_attr_gen_attest_evid_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,
+ },
+ },
+ .type = { PEN_TCG, TCG_PTS_GEN_ATTEST_EVID },
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_gen_attest_evid_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,
+ },
+ },
+ .type = { PEN_TCG, TCG_PTS_GEN_ATTEST_EVID },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.h b/src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.h
new file mode 100644
index 000000000..971abd2a3
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_gen_attest_evid.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_gen_attest_evid tcg_pts_attr_gen_attest_evid
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_GEN_ATTEST_EVID_H_
+#define TCG_PTS_ATTR_GEN_ATTEST_EVID_H_
+
+typedef struct tcg_pts_attr_gen_attest_evid_t tcg_pts_attr_gen_attest_evid_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Generate Attestation Evidence Attribute
+ *
+ */
+struct tcg_pts_attr_gen_attest_evid_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+};
+
+/**
+ * Creates an tcg_pts_attr_gen_attest_evid_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_gen_attest_evid_create();
+
+/**
+ * Creates an tcg_pts_attr_gen_attest_evid_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_pts_attr_gen_attest_evid_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_GEN_ATTEST_EVID_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_get_aik.c b/src/libimcv/tcg/pts/tcg_pts_attr_get_aik.c
new file mode 100644
index 000000000..8fda2b1f5
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_get_aik.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_get_aik.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_pts_attr_get_aik_t private_tcg_pts_attr_get_aik_t;
+
+/**
+ * Get Attestation Identity Key
+ * see section 3.12 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_GET_AIK_SIZE 4
+#define PTS_GET_AIK_RESERVED 0x00000000
+
+/**
+ * Private data of an tcg_pts_attr_get_aik_t object.
+ */
+struct private_tcg_pts_attr_get_aik_t {
+
+ /**
+ * Public members of tcg_pts_attr_get_aik_t
+ */
+ tcg_pts_attr_get_aik_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;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_get_aik_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_GET_AIK_SIZE);
+ writer->write_uint32 (writer, PTS_GET_AIK_RESERVED);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_get_aik_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("mc", this->value, segment);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_get_aik_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_GET_AIK_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Get AIK");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32 (reader, &reserved);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_get_aik_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_aik_create()
+{
+ private_tcg_pts_attr_get_aik_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,
+ },
+ },
+ .type = { PEN_TCG, TCG_PTS_GET_AIK },
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_aik_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_get_aik_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,
+ },
+ },
+ .type = { PEN_TCG, TCG_PTS_GET_AIK },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_get_aik.h b/src/libimcv/tcg/pts/tcg_pts_attr_get_aik.h
new file mode 100644
index 000000000..923fd039f
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_get_aik.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_get_aik tcg_pts_attr_get_aik
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_GET_AIK_H_
+#define TCG_PTS_ATTR_GET_AIK_H_
+
+typedef struct tcg_pts_attr_get_aik_t tcg_pts_attr_get_aik_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Get Attestation Identity Key Attribute
+ *
+ */
+struct tcg_pts_attr_get_aik_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+};
+
+/**
+ * Creates an tcg_pts_attr_get_aik_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_get_aik_create();
+
+/**
+ * Creates an tcg_pts_attr_get_aik_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_pts_attr_get_aik_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_GET_AIK_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.c b/src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.c
new file mode 100644
index 000000000..a4c9dba87
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_get_tpm_version_info.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_pts_attr_get_tpm_version_info_t
+ private_tcg_pts_attr_get_tpm_version_info_t;
+
+/**
+ * Get TPM Version Information
+ * see section 3.10 of PTS Protocol: Binding to TNC IF-M 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
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_GET_TPM_VER_INFO_SIZE 4
+#define PTS_GET_TPM_VER_INFO_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_get_tpm_version_info_t object.
+ */
+struct private_tcg_pts_attr_get_tpm_version_info_t {
+
+ /**
+ * Public members of tcg_pts_attr_get_tpm_version_info_t
+ */
+ tcg_pts_attr_get_tpm_version_info_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;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_get_tpm_version_info_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_GET_TPM_VER_INFO_SIZE);
+ writer->write_uint32 (writer, PTS_GET_TPM_VER_INFO_RESERVED);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_get_tpm_version_info_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t reserved;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_GET_TPM_VER_INFO_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Get TPM Version Information");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32 (reader, &reserved);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_get_tpm_version_info_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_pts_attr_get_tpm_version_info_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_get_tpm_version_info_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create()
+{
+ private_tcg_pts_attr_get_tpm_version_info_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,
+ },
+ },
+ .type = { PEN_TCG, TCG_PTS_GET_TPM_VERSION_INFO },
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_get_tpm_version_info_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,
+ },
+ },
+ .type = { PEN_TCG, TCG_PTS_GET_TPM_VERSION_INFO },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.h b/src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.h
new file mode 100644
index 000000000..19fb5a4e8
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_get_tpm_version_info.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_get_tpm_version_info tcg_pts_attr_get_tpm_version_info
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_
+#define TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_
+
+typedef struct tcg_pts_attr_get_tpm_version_info_t
+ tcg_pts_attr_get_tpm_version_info_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Get TPM Version Info Attribute
+ *
+ */
+struct tcg_pts_attr_get_tpm_version_info_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+};
+
+/**
+ * Creates an tcg_pts_attr_get_tpm_version_info_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_get_tpm_version_info_create();
+
+/**
+ * Creates an tcg_pts_attr_get_tpm_version_info_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_pts_attr_get_tpm_version_info_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_GET_TPM_VERSION_INFO_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.c b/src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.c
new file mode 100644
index 000000000..8b0502a91
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_meas_algo.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_pts_attr_meas_algo_t private_tcg_pts_attr_meas_algo_t;
+
+/**
+ * PTS Measurement Algorithm
+ * see section 3.9.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Hash Algorithm Set |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_MEAS_ALGO_SIZE 4
+#define PTS_MEAS_ALGO_RESERVED 0x0000
+
+/**
+ * Private data of an tcg_pts_attr_meas_algo_t object.
+ */
+struct private_tcg_pts_attr_meas_algo_t {
+
+ /**
+ * Public members of tcg_pts_attr_meas_algo_t
+ */
+ tcg_pts_attr_meas_algo_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;
+
+ /**
+ * Set of algorithms
+ */
+ pts_meas_algorithms_t algorithms;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_meas_algo_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_MEAS_ALGO_SIZE);
+ writer->write_uint16(writer, PTS_MEAS_ALGO_RESERVED);
+ writer->write_uint16(writer, this->algorithms);
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_meas_algo_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int16_t reserved, algorithms;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_MEAS_ALGO_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Measurement Algorithm");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint16(reader, &reserved);
+ reader->read_uint16(reader, &algorithms);
+ this->algorithms = algorithms;
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_meas_algo_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_pts_attr_meas_algo_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_meas_algo_t, get_algorithms, pts_meas_algorithms_t,
+ private_tcg_pts_attr_meas_algo_t *this)
+{
+ return this->algorithms;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms,
+ bool selection)
+{
+ private_tcg_pts_attr_meas_algo_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_algorithms = _get_algorithms,
+ },
+ .type = { PEN_TCG,
+ selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO },
+ .algorithms = algorithms,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(size_t length,
+ chunk_t data,
+ bool selection)
+{
+ private_tcg_pts_attr_meas_algo_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_algorithms = _get_algorithms,
+ },
+ .type = { PEN_TCG,
+ selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.h b/src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.h
new file mode 100644
index 000000000..bc15a9bb4
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_meas_algo.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_meas_algo tcg_pts_attr_meas_algo
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_MEAS_ALGO_H_
+#define TCG_PTS_ATTR_MEAS_ALGO_H_
+
+typedef struct tcg_pts_attr_meas_algo_t tcg_pts_attr_meas_algo_t;
+
+#include "tcg/tcg_attr.h"
+#include "pts/pts_meas_algo.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG Measurement Algorithm Attribute
+ *
+ */
+struct tcg_pts_attr_meas_algo_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS Measurement Algorithm Set
+ *
+ * @return set of algorithms
+ */
+ pts_meas_algorithms_t (*get_algorithms)(tcg_pts_attr_meas_algo_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_meas_algo_t object
+ *
+ * @param algorithms set of algorithms
+ * @param selection TRUE if a selection
+ */
+pa_tnc_attr_t* tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms,
+ bool selection);
+
+/**
+ * Creates an tcg_pts_attr_meas_algo_t object from received data
+ *
+ * @param length Total length of attribute value
+ * @param value Unparsed attribute value (might be a segment)
+ * @param selection TRUE if a selection
+ */
+pa_tnc_attr_t* tcg_pts_attr_meas_algo_create_from_data(size_t length,
+ chunk_t value,
+ bool selection);
+
+#endif /** TCG_PTS_ATTR_MEAS_ALGO_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.c b/src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.c
new file mode 100644
index 000000000..0a562c0bc
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_proto_caps.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_pts_attr_proto_caps_t private_tcg_pts_attr_proto_caps_t;
+
+/**
+ * PTS Protocol Capabilities
+ * see section 3.7 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved |C|V|D|T|X|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_PROTO_CAPS_SIZE 4
+#define PTS_PROTO_CAPS_RESERVED 0x0000
+
+/**
+ * Private data of an tcg_pts_attr_proto_caps_t object.
+ */
+struct private_tcg_pts_attr_proto_caps_t {
+
+ /**
+ * Public members of tcg_pts_attr_proto_caps_t
+ */
+ tcg_pts_attr_proto_caps_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;
+
+ /**
+ * Set of flags
+ */
+ pts_proto_caps_flag_t flags;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_proto_caps_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_PROTO_CAPS_SIZE);
+ writer->write_uint16(writer, PTS_PROTO_CAPS_RESERVED);
+ writer->write_uint16(writer, this->flags);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_proto_caps_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int16_t reserved, flags;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_PROTO_CAPS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Protocol Capabilities");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint16(reader, &reserved);
+ reader->read_uint16(reader, &flags);
+ this->flags = flags;
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_proto_caps_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_pts_attr_proto_caps_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_proto_caps_t, get_flags, pts_proto_caps_flag_t,
+ private_tcg_pts_attr_proto_caps_t *this)
+{
+ return this->flags;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags,
+ bool request)
+{
+ private_tcg_pts_attr_proto_caps_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_flags = _get_flags,
+ },
+ .type = { PEN_TCG,
+ request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS },
+ .flags = flags,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(size_t length,
+ chunk_t data,
+ bool request)
+{
+ private_tcg_pts_attr_proto_caps_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_flags = _get_flags,
+ },
+ .type = { PEN_TCG,
+ request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.h b/src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.h
new file mode 100644
index 000000000..11ed22810
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_proto_caps.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_proto_caps tcg_pts_attr_proto_caps
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_PROTO_CAPS_H_
+#define TCG_PTS_ATTR_PROTO_CAPS_H_
+
+typedef struct tcg_pts_attr_proto_caps_t tcg_pts_attr_proto_caps_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_proto_caps.h"
+
+/**
+ * Class implementing the TCG PTS Protocol Capabilities Attribute
+ */
+struct tcg_pts_attr_proto_caps_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS procol capabilities flags
+ *
+ * @return set of flags
+ */
+ pts_proto_caps_flag_t (*get_flags)(tcg_pts_attr_proto_caps_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_proto_caps_t object
+ *
+ * @param flags set of flags
+ * @param request TRUE for a PTS protocol capabilities request
+ */
+pa_tnc_attr_t* tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags,
+ bool request);
+
+/**
+ * Creates an tcg_pts_attr_proto_caps_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 PTS protocol capabilities request
+ */
+pa_tnc_attr_t* tcg_pts_attr_proto_caps_create_from_data(size_t length,
+ chunk_t value,
+ bool request);
+
+#endif /** TCG_PTS_ATTR_PROTO_CAPS_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.c b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.c
new file mode 100644
index 000000000..a3c3ce56e
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.c
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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.
+ */
+
+#define _GNU_SOURCE /* for stdndup() */
+#include <string.h>
+
+#include "tcg_pts_attr_req_file_meas.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_pts_attr_req_file_meas_t private_tcg_pts_attr_req_file_meas_t;
+
+/**
+ * Request File Measurement
+ * see section 3.19.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Reserved | Request ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Delimiter |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Fully Qualified File Pathname (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FILE_MEAS_SIZE 8
+#define PTS_REQ_FILE_MEAS_RESERVED 0x00
+#define PTS_REQ_FILE_MEAS_NO_FLAGS 0x00
+
+#define DIRECTORY_CONTENTS_FLAG (1<<7)
+
+/**
+ * Private data of an tcg_pts_attr_req_file_meas_t object.
+ */
+struct private_tcg_pts_attr_req_file_meas_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_file_meas_t
+ */
+ tcg_pts_attr_req_file_meas_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;
+
+ /**
+ * Directory Contents flag
+ */
+ bool directory_flag;
+
+ /**
+ * Request ID
+ */
+ u_int16_t request_id;
+
+ /**
+ * UTF8 Encoding of Delimiter Character
+ */
+ u_int32_t delimiter;
+
+ /**
+ * Fully Qualified File Pathname
+ */
+ char *pathname;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_file_meas_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ u_int8_t flags = PTS_REQ_FILE_MEAS_NO_FLAGS;
+ chunk_t pathname;
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ if (this->directory_flag)
+ {
+ flags |= DIRECTORY_CONTENTS_FLAG;
+ }
+ pathname = chunk_create(this->pathname, strlen(this->pathname));
+
+ writer = bio_writer_create(PTS_REQ_FILE_MEAS_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, PTS_REQ_FILE_MEAS_RESERVED);
+ writer->write_uint16(writer, this->request_id);
+ writer->write_uint32(writer, this->delimiter);
+ writer->write_data (writer, pathname);
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_file_meas_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ u_int8_t reserved;
+ chunk_t pathname;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_REQ_FILE_MEAS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request File Measurement");
+ return FAILED;
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint16(reader, &this->request_id);
+ reader->read_uint32(reader, &this->delimiter);
+ reader->read_data (reader, reader->remaining(reader), &pathname);
+
+ this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) !=
+ PTS_REQ_FILE_MEAS_NO_FLAGS;
+ this->pathname = strndup(pathname.ptr, pathname.len);
+
+ reader->destroy(reader);
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_req_file_meas_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_pts_attr_req_file_meas_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->pathname);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_directory_flag, bool,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->directory_flag;
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_request_id, u_int16_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->request_id;
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_delimiter, u_int32_t,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->delimiter;
+}
+
+METHOD(tcg_pts_attr_req_file_meas_t, get_pathname, char*,
+ private_tcg_pts_attr_req_file_meas_t *this)
+{
+ return this->pathname;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag,
+ u_int16_t request_id,
+ u_int32_t delimiter,
+ char *pathname)
+{
+ private_tcg_pts_attr_req_file_meas_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_directory_flag = _get_directory_flag,
+ .get_request_id = _get_request_id,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_MEAS },
+ .directory_flag = directory_flag,
+ .request_id = request_id,
+ .delimiter = delimiter,
+ .pathname = strdup(pathname),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_req_file_meas_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_directory_flag = _get_directory_flag,
+ .get_request_id = _get_request_id,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_MEAS },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.h b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.h
new file mode 100644
index 000000000..20a54dfaf
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meas.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_req_file_meas tcg_pts_attr_req_file_meas
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FILE_MEAS_H_
+#define TCG_PTS_ATTR_REQ_FILE_MEAS_H_
+
+typedef struct tcg_pts_attr_req_file_meas_t tcg_pts_attr_req_file_meas_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_req_file_meas_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get flag for PTS Request File Measurement
+ *
+ * @return Directory Contents flag
+ */
+ bool (*get_directory_flag)(tcg_pts_attr_req_file_meas_t *this);
+
+ /**
+ * Get Request ID
+ *
+ * @return Request ID
+ */
+ u_int16_t (*get_request_id)(tcg_pts_attr_req_file_meas_t *this);
+
+ /**
+ * Get Delimiter
+ *
+ * @return UTF-8 encoding of a Delimiter Character
+ */
+ u_int32_t (*get_delimiter)(tcg_pts_attr_req_file_meas_t *this);
+
+ /**
+ * Get Fully Qualified File Pathname
+ *
+ * @return Pathname
+ */
+ char* (*get_pathname)(tcg_pts_attr_req_file_meas_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_req_file_meas_t object
+ *
+ * @param directory_flag Directory Contents Flag
+ * @param request_id Request ID
+ * @param delimiter Delimiter Character
+ * @param pathname File Pathname
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meas_create(bool directory_flag,
+ u_int16_t request_id,
+ u_int32_t delimiter,
+ char *pathname);
+
+/**
+ * Creates an tcg_pts_attr_req_file_meas_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_pts_attr_req_file_meas_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FILE_MEAS_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.c b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.c
new file mode 100644
index 000000000..f6befa8b9
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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.
+ */
+
+#define _GNU_SOURCE /* for stdndup() */
+#include <string.h>
+
+#include "tcg_pts_attr_req_file_meta.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_pts_attr_req_file_meta_t private_tcg_pts_attr_req_file_meta_t;
+
+/**
+ * Request File Metadata
+ * see section 3.17.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Delimiter | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Fully Qualified File Pathname (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FILE_META_SIZE 4
+#define PTS_REQ_FILE_META_RESERVED 0x00
+#define PTS_REQ_FILE_META_NO_FLAGS 0x00
+
+#define DIRECTORY_CONTENTS_FLAG (1<<7)
+
+/**
+ * Private data of an tcg_pts_attr_req_file_meta_t object.
+ */
+struct private_tcg_pts_attr_req_file_meta_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_file_meta_t
+ */
+ tcg_pts_attr_req_file_meta_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;
+
+ /**
+ * Directory Contents flag
+ */
+ bool directory_flag;
+
+ /**
+ * UTF8 Encoding of Delimiter Character
+ */
+ u_int8_t delimiter;
+
+ /**
+ * Fully Qualified File Pathname
+ */
+ char *pathname;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_file_meta_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ u_int8_t flags = PTS_REQ_FILE_META_NO_FLAGS;
+ chunk_t pathname;
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ if (this->directory_flag)
+ {
+ flags |= DIRECTORY_CONTENTS_FLAG;
+ }
+ pathname = chunk_create(this->pathname, strlen(this->pathname));
+
+ writer = bio_writer_create(PTS_REQ_FILE_META_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, this->delimiter);
+ writer->write_uint16(writer, PTS_REQ_FILE_META_RESERVED);
+
+ writer->write_data (writer, pathname);
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_file_meta_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ u_int16_t reserved;
+ chunk_t pathname;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_REQ_FILE_META_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request File Metadata");
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint8 (reader, &this->delimiter);
+ reader->read_uint16(reader, &reserved);
+
+ reader->read_data (reader, reader->remaining(reader), &pathname);
+
+ this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) !=
+ PTS_REQ_FILE_META_NO_FLAGS;
+ this->pathname = strndup(pathname.ptr, pathname.len);
+
+ reader->destroy(reader);
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_req_file_meta_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_pts_attr_req_file_meta_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->pathname);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_directory_flag, bool,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->directory_flag;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_delimiter, u_int8_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->delimiter;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_pathname, char*,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->pathname;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag,
+ u_int8_t delimiter,
+ char *pathname)
+{
+ private_tcg_pts_attr_req_file_meta_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_directory_flag = _get_directory_flag,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_META },
+ .directory_flag = directory_flag,
+ .delimiter = delimiter,
+ .pathname = strdup(pathname),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_req_file_meta_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_directory_flag = _get_directory_flag,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_META },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.h b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.h
new file mode 100644
index 000000000..c2f1cca74
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_file_meta.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_req_file_meta tcg_pts_attr_req_file_meta
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FILE_META_H_
+#define TCG_PTS_ATTR_REQ_FILE_META_H_
+
+typedef struct tcg_pts_attr_req_file_meta_t tcg_pts_attr_req_file_meta_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request File Metadata attribute
+ *
+ */
+struct tcg_pts_attr_req_file_meta_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get directory flag for PTS Request File Metadata
+ *
+ * @return Directory Contents flag
+ */
+ bool (*get_directory_flag)(tcg_pts_attr_req_file_meta_t *this);
+
+ /**
+ * Get Delimiter
+ *
+ * @return UTF-8 encoding of a Delimiter Character
+ */
+ u_int8_t (*get_delimiter)(tcg_pts_attr_req_file_meta_t *this);
+
+ /**
+ * Get Fully Qualified File Pathname
+ *
+ * @return Pathname
+ */
+ char* (*get_pathname)(tcg_pts_attr_req_file_meta_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_req_file_meta_t object
+ *
+ * @param directory_flag Directory Contents Flag
+ * @param delimiter Delimiter Character
+ * @param pathname File Pathname
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create(bool directory_flag,
+ u_int8_t delimiter,
+ char *pathname);
+
+/**
+ * Creates an tcg_pts_attr_req_file_meta_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_pts_attr_req_file_meta_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FILE_META_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c
new file mode 100644
index 000000000..03891104c
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_req_func_comp_evid.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_tcg_pts_attr_req_func_comp_evid_t private_tcg_pts_attr_req_func_comp_evid_t;
+
+/**
+ * Request Functional Component Evidence
+ * see section 3.14.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Sub-component Depth (for Component #1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ........ |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Sub-component Depth (for Component #N) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #N |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name #N |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Component Functional Name Structure
+ * (see section 5.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name Vendor ID |Fam| Qualifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FUNC_COMP_EVID_SIZE 12
+#define PTS_REQ_FUNC_COMP_FAMILY_MASK 0xC0
+
+/**
+ * Private data of an tcg_pts_attr_req_func_comp_evid_t object.
+ */
+struct private_tcg_pts_attr_req_func_comp_evid_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_func_comp_evid_t
+ */
+ tcg_pts_attr_req_func_comp_evid_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;
+
+ /**
+ * List of Functional Components
+ */
+ linked_list_t *list;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Functional component entry
+ */
+struct entry_t {
+ u_int8_t flags;
+ u_int32_t depth;
+ pts_comp_func_name_t *name;
+};
+
+/**
+ * Enumerate functional component entries
+ */
+static bool entry_filter(void *null, entry_t **entry, u_int8_t *flags,
+ void *i2, u_int32_t *depth, void *i3,
+ pts_comp_func_name_t **name)
+{
+ *flags = (*entry)->flags;
+ *depth = (*entry)->depth;
+ *name = (*entry)->name;
+
+ return TRUE;
+}
+
+/**
+ * Free an entry_t object
+ */
+static void free_entry(entry_t *this)
+{
+ if (this)
+ {
+ this->name->destroy(this->name);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_REQ_FUNC_COMP_EVID_SIZE);
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ writer->write_uint8 (writer, entry->flags);
+ writer->write_uint24(writer, entry->depth);
+ writer->write_uint24(writer, entry->name->get_vendor_id(entry->name));
+ writer->write_uint8 (writer, entry->name->get_qualifier(entry->name));
+ writer->write_uint32(writer, entry->name->get_name(entry->name));
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_func_comp_evid_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t depth, vendor_id, name;
+ u_int8_t flags, fam_and_qualifier, qualifier;
+ status_t status = FAILED;
+ entry_t *entry = NULL;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_REQ_FUNC_COMP_EVID_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request Functional "
+ "Component Evidence");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ while (reader->remaining(reader))
+ {
+ if (!reader->read_uint8(reader, &flags))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Flags");
+ goto end;
+ }
+ if (!reader->read_uint24(reader, &depth))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Sub Component Depth");
+ goto end;
+ }
+ if (!reader->read_uint24(reader, &vendor_id))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Component Name Vendor ID");
+ goto end;
+ }
+ if (!reader->read_uint8(reader, &fam_and_qualifier))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Family and Qualifier");
+ goto end;
+ }
+ if (fam_and_qualifier & PTS_REQ_FUNC_COMP_FAMILY_MASK)
+ {
+ DBG1(DBG_TNC, "the Functional Name Encoding Family "
+ "is not Binary Enumeration");
+ goto end;
+ }
+ if (!reader->read_uint32(reader, &name))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Request Functional "
+ "Component Evidence Component Functional Name");
+ goto end;
+ }
+ qualifier = fam_and_qualifier & ~PTS_REQ_FUNC_COMP_FAMILY_MASK;
+
+ entry = malloc_thing(entry_t);
+ entry->flags = flags;
+ entry->depth = depth;
+ entry->name = pts_comp_func_name_create(vendor_id, name, qualifier);
+
+ this->list->insert_last(this->list, entry);
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_req_func_comp_evid_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_pts_attr_req_func_comp_evid_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->list->destroy_function(this->list, (void *)free_entry);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_req_func_comp_evid_t, add_component, void,
+ private_tcg_pts_attr_req_func_comp_evid_t *this, u_int8_t flags,
+ u_int32_t depth, pts_comp_func_name_t *name)
+{
+ entry_t *entry;
+
+ entry = malloc_thing(entry_t);
+ entry->flags = flags;
+ entry->depth = depth;
+ entry->name = name->clone(name);
+ this->list->insert_last(this->list, entry);
+}
+
+METHOD(tcg_pts_attr_req_func_comp_evid_t, get_count, int,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return this->list->get_count(this->list);
+}
+
+METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*,
+ private_tcg_pts_attr_req_func_comp_evid_t *this)
+{
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)entry_filter, NULL, NULL);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void)
+{
+ private_tcg_pts_attr_req_func_comp_evid_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,
+ },
+ .add_component = _add_component,
+ .get_count = _get_count,
+ .create_enumerator = _create_enumerator,
+ },
+ .type = { PEN_TCG, TCG_PTS_REQ_FUNC_COMP_EVID },
+ .list = linked_list_create(),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_req_func_comp_evid_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,
+ },
+ .add_component = _add_component,
+ .get_count = _get_count,
+ .create_enumerator = _create_enumerator,
+ },
+ .type = { PEN_TCG, TCG_PTS_REQ_FUNC_COMP_EVID },
+ .length = length,
+ .list = linked_list_create(),
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.h b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.h
new file mode 100644
index 000000000..2f8657ed2
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_req_func_comp_evid tcg_pts_attr_req_func_comp_evid
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_
+#define TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_
+
+typedef struct tcg_pts_attr_req_func_comp_evid_t tcg_pts_attr_req_func_comp_evid_t;
+
+#include "tcg/tcg_attr.h"
+#include "pts/components/pts_comp_func_name.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request Functional Component Evidence attribute
+ *
+ */
+struct tcg_pts_attr_req_func_comp_evid_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Add a component to the Functional Component Evidence Request
+ *
+ * @param flags Component Evidence Request Flags
+ * @param depth Sub-component Depth
+ * @param name Functional Component Name
+ */
+ void (*add_component)(tcg_pts_attr_req_func_comp_evid_t *this,
+ u_int8_t flags, u_int32_t depth,
+ pts_comp_func_name_t *name);
+
+ /**
+ * Returns the number of Functional Component entries
+ *
+ * @return Number of entries
+ */
+ int (*get_count)(tcg_pts_attr_req_func_comp_evid_t *this);
+
+ /**
+ * Enumerator over Functional Component entries
+ *
+ * @return Entry enumerator
+ */
+ enumerator_t* (*create_enumerator)(tcg_pts_attr_req_func_comp_evid_t *this);
+
+};
+
+/**
+ * Creates a tcg_pts_attr_req_func_comp_evid_t object
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_func_comp_evid_create(void);
+
+/**
+ * Creates a tcg_pts_attr_req_func_comp_evid_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_pts_attr_req_func_comp_evid_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FUNC_COMP_EVID_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c b/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c
new file mode 100644
index 000000000..d94ee89a5
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c
@@ -0,0 +1,532 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_simple_comp_evid.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+
+#include <time.h>
+
+typedef struct private_tcg_pts_attr_simple_comp_evid_t private_tcg_pts_attr_simple_comp_evid_t;
+
+/**
+ * Simple Component Evidence
+ * see section 3.15.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Sub-Component Depth |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Specific Functional Component |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Specific Functional Component |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measure. Type | Extended into PCR |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Hash Algorithm | PCR Transform | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Measurement Date/Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional Policy URI Length | Opt. Verification Policy URI ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional Verification Policy URI ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional PCR Length | Optional PCR Before Value ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional PCR Before Value (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional PCR After Value (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Component Measurement (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/**
+ * Specific Functional Component -> Component Functional Name Structure
+ * see section 5.1 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name Vendor ID |Fam| Qualifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Component Functional Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define PTS_SIMPLE_COMP_EVID_SIZE 40
+#define PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE 20
+#define PTS_SIMPLE_COMP_EVID_RESERVED 0x00
+#define PTS_SIMPLE_COMP_EVID_FAMILY_MASK 0xC0
+#define PTS_SIMPLE_COMP_EVID_VALIDATION_MASK 0x60
+#define PTS_SIMPLE_COMP_EVID_MEAS_TYPE (1<<7)
+#define PTS_SIMPLE_COMP_EVID_FLAG_PCR (1<<7)
+
+static char *utc_undefined_time_str = "0000-00-00T00:00:00Z";
+
+/**
+ * Private data of an tcg_pts_attr_simple_comp_evid_t object.
+ */
+struct private_tcg_pts_attr_simple_comp_evid_t {
+
+ /**
+ * Public members of tcg_pts_attr_simple_comp_evid_t
+ */
+ tcg_pts_attr_simple_comp_evid_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;
+
+ /**
+ * PTS Component Evidence
+ */
+ pts_comp_evidence_t *evidence;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_simple_comp_evid_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+/**
+ * Convert time_t to Simple Component Evidence UTS string format
+ */
+void measurement_time_to_utc(time_t measurement_time, chunk_t *utc_time)
+{
+ struct tm t;
+
+ if (measurement_time == UNDEFINED_TIME)
+ {
+ utc_time->ptr = utc_undefined_time_str;
+ }
+ else
+ {
+ gmtime_r(&measurement_time, &t);
+ sprintf(utc_time->ptr, "%04d-%02d-%02dT%02d:%02d:%02dZ",
+ t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
+ t.tm_hour, t.tm_min, t.tm_sec);
+ }
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ bio_writer_t *writer;
+ bool has_pcr_info;
+ char utc_time_buf[25], *policy_uri;
+ u_int8_t flags;
+ u_int16_t len;
+ u_int32_t depth, extended_pcr;
+ pts_comp_func_name_t *name;
+ pts_meas_algorithms_t hash_algorithm;
+ pts_pcr_transform_t transform;
+ pts_comp_evid_validation_t validation;
+ time_t measurement_time;
+ chunk_t measurement, utc_time, pcr_before, pcr_after;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+
+ /* Extract parameters from comp_evidence_t object */
+ name = this->evidence->get_comp_func_name(this->evidence,
+ &depth);
+ measurement = this->evidence->get_measurement(this->evidence,
+ &extended_pcr, &hash_algorithm, &transform,
+ &measurement_time);
+ has_pcr_info = this->evidence->get_pcr_info(this->evidence,
+ &pcr_before, &pcr_after);
+ validation = this->evidence->get_validation(this->evidence,
+ &policy_uri);
+
+ /* Determine the flags to set*/
+ flags = validation;
+ if (has_pcr_info)
+ {
+ flags |= PTS_SIMPLE_COMP_EVID_FLAG_PCR;
+ }
+
+ utc_time = chunk_create(utc_time_buf, PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE);
+ measurement_time_to_utc(measurement_time, &utc_time);
+
+ writer = bio_writer_create(PTS_SIMPLE_COMP_EVID_SIZE);
+
+ writer->write_uint8 (writer, flags);
+ writer->write_uint24(writer, depth);
+ writer->write_uint24(writer, name->get_vendor_id(name));
+ writer->write_uint8 (writer, name->get_qualifier(name));
+ writer->write_uint32(writer, name->get_name(name));
+ writer->write_uint8 (writer, PTS_SIMPLE_COMP_EVID_MEAS_TYPE);
+ writer->write_uint24(writer, extended_pcr);
+ writer->write_uint16(writer, hash_algorithm);
+ writer->write_uint8 (writer, transform);
+ writer->write_uint8 (writer, PTS_SIMPLE_COMP_EVID_RESERVED);
+ writer->write_data (writer, utc_time);
+
+ /* Optional fields */
+ if (validation == PTS_COMP_EVID_VALIDATION_FAILED ||
+ validation == PTS_COMP_EVID_VALIDATION_PASSED)
+ {
+ len = strlen(policy_uri);
+ writer->write_uint16(writer, len);
+ writer->write_data (writer, chunk_create(policy_uri, len));
+ }
+ if (has_pcr_info)
+ {
+ writer->write_uint16(writer, pcr_before.len);
+ writer->write_data (writer, pcr_before);
+ writer->write_data (writer, pcr_after);
+ }
+
+ writer->write_data(writer, measurement);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+static const int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+static const int tm_leap_1970 = 477;
+
+/**
+ * Convert Simple Component Evidence UTS string format to time_t
+ */
+bool measurement_time_from_utc(time_t *measurement_time, chunk_t utc_time)
+{
+ int tm_year, tm_mon, tm_day, tm_days, tm_hour, tm_min, tm_sec, tm_secs;
+ int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap;
+
+ if (memeq(utc_undefined_time_str, utc_time.ptr, utc_time.len))
+ {
+ *measurement_time = 0;
+ return TRUE;
+ }
+ if (sscanf(utc_time.ptr, "%4d-%2d-%2dT%2d:%2d:%2dZ",
+ &tm_year, &tm_mon, &tm_day, &tm_hour, &tm_min, &tm_sec) != 6)
+ {
+ return FALSE;
+ }
+
+ /* representation of months as 0..11 */
+ tm_mon--;
+
+ /* representation of days as 0..30 */
+ tm_day--;
+
+ /* number of leap years between last year and 1970? */
+ tm_leap_4 = (tm_year - 1) / 4;
+ tm_leap_100 = tm_leap_4 / 25;
+ tm_leap_400 = tm_leap_100 / 4;
+ tm_leap = tm_leap_4 - tm_leap_100 + tm_leap_400 - tm_leap_1970;
+
+ /* if date later then February, is the current year a leap year? */
+ if (tm_mon > 1 && (tm_year % 4 == 0) &&
+ (tm_year % 100 != 0 || tm_year % 400 == 0))
+ {
+ tm_leap++;
+ }
+ tm_days = 365 * (tm_year - 1970) + days[tm_mon] + tm_day + tm_leap;
+ tm_secs = 60 * (60 * (24 * tm_days + tm_hour) + tm_min) + tm_sec;
+
+ *measurement_time = tm_secs;
+ return TRUE;
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_simple_comp_evid_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ pts_comp_func_name_t *name;
+ u_int8_t flags, fam_and_qualifier, qualifier, reserved;
+ u_int8_t measurement_type, transform, validation;
+ u_int16_t hash_algorithm, len;
+ u_int32_t depth, vendor_id, comp_name, extended_pcr;
+ chunk_t measurement, utc_time, policy_uri, pcr_before, pcr_after;
+ time_t measurement_time;
+ bool has_pcr_info = FALSE, has_validation = FALSE;
+ status_t status = FAILED;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_SIMPLE_COMP_EVID_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Simple Component Evidence");
+ }
+ reader = bio_reader_create(this->value);
+
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &depth);
+ reader->read_uint24(reader, &vendor_id);
+ reader->read_uint8 (reader, &fam_and_qualifier);
+ reader->read_uint32(reader, &comp_name);
+ reader->read_uint8 (reader, &measurement_type);
+ reader->read_uint24(reader, &extended_pcr);
+ reader->read_uint16(reader, &hash_algorithm);
+ reader->read_uint8 (reader, &transform);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_data (reader, PTS_SIMPLE_COMP_EVID_MEAS_TIME_SIZE, &utc_time);
+
+ if (measurement_type != PTS_SIMPLE_COMP_EVID_MEAS_TYPE)
+ {
+ DBG1(DBG_TNC, "unsupported Measurement Type in "
+ "Simple Component Evidence");
+ *offset = 12;
+ reader->destroy(reader);
+ return FAILED;
+ }
+ if (!measurement_time_from_utc(&measurement_time, utc_time))
+ {
+ DBG1(DBG_TNC, "invalid Measurement Time field in "
+ "Simple Component Evidence");
+ *offset = 20;
+ reader->destroy(reader);
+ return FAILED;
+ }
+ validation = flags & PTS_SIMPLE_COMP_EVID_VALIDATION_MASK;
+ qualifier = fam_and_qualifier & ~PTS_SIMPLE_COMP_EVID_FAMILY_MASK;
+
+ /* Is optional Policy URI field included? */
+ if (validation == PTS_COMP_EVID_VALIDATION_FAILED ||
+ validation == PTS_COMP_EVID_VALIDATION_PASSED)
+ {
+ if (!reader->read_uint16(reader, &len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "Verification Policy URI Length");
+ goto end;
+ }
+ if (!reader->read_data(reader, len, &policy_uri))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "Verification Policy URI");
+ goto end;
+ }
+ has_validation = TRUE;
+ }
+
+ /* Are optional PCR value fields included? */
+ if (flags & PTS_SIMPLE_COMP_EVID_FLAG_PCR)
+ {
+ if (!reader->read_uint16(reader, &len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "PCR Value length");
+ goto end;
+ }
+ if (!reader->read_data(reader, len, &pcr_before))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "PCR Before Value");
+ goto end;
+ }
+ if (!reader->read_data(reader, len, &pcr_after))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Component Evidence "
+ "PCR After Value");
+ goto end;
+ }
+ has_pcr_info = TRUE;
+ }
+
+ /* Measurement field comes at the very end */
+ reader->read_data(reader,reader->remaining(reader), &measurement);
+ reader->destroy(reader);
+
+ /* Create Component Functional Name object */
+ name = pts_comp_func_name_create(vendor_id, comp_name, qualifier);
+
+ /* Create Component Evidence object */
+ measurement = chunk_clone(measurement);
+ this->evidence = pts_comp_evidence_create(name, depth, extended_pcr,
+ hash_algorithm, transform,
+ measurement_time, measurement);
+
+ /* Add options */
+ if (has_validation)
+ {
+ char buf[BUF_LEN];
+ size_t len;
+
+ len = min(policy_uri.len, BUF_LEN-1);
+ memcpy(buf, policy_uri.ptr, len);
+ buf[len] = '\0';
+ this->evidence->set_validation(this->evidence, validation, buf);
+ }
+ if (has_pcr_info)
+ {
+ pcr_before = chunk_clone(pcr_before);
+ pcr_after = chunk_clone(pcr_after);
+ this->evidence->set_pcr_info(this->evidence, pcr_before, pcr_after);
+ }
+
+ return SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_simple_comp_evid_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_pts_attr_simple_comp_evid_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->evidence);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_simple_comp_evid_t, get_comp_evidence, pts_comp_evidence_t*,
+ private_tcg_pts_attr_simple_comp_evid_t *this)
+{
+ return this->evidence;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid)
+{
+ private_tcg_pts_attr_simple_comp_evid_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_comp_evidence = _get_comp_evidence,
+ },
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_COMP_EVID },
+ .evidence = evid,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_simple_comp_evid_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_comp_evidence = _get_comp_evidence,
+ },
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_COMP_EVID },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.h b/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.h
new file mode 100644
index 000000000..c08adb8c9
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_simple_comp_evid tcg_pts_attr_simple_comp_evid
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_
+#define TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_
+
+typedef struct tcg_pts_attr_simple_comp_evid_t tcg_pts_attr_simple_comp_evid_t;
+
+#include "tcg/tcg_attr.h"
+#include "pts/components/pts_comp_evidence.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Simple Component Evidence attribute
+ *
+ */
+struct tcg_pts_attr_simple_comp_evid_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Component Evidence
+ *
+ * @return Component Evidence
+ */
+ pts_comp_evidence_t* (*get_comp_evidence)(tcg_pts_attr_simple_comp_evid_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_simple_comp_evid_t object
+ *
+ * @param evid Component Evidence
+ */
+pa_tnc_attr_t* tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid);
+
+/**
+ * Creates an tcg_pts_attr_simple_comp_evid_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_pts_attr_simple_comp_evid_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_SIMPLE_COMP_EVID_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.c b/src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.c
new file mode 100644
index 000000000..cfeaec6e9
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_simple_evid_final.h"
+#include "pts/pts_simple_evid_final.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_pts_attr_simple_evid_final_t private_tcg_pts_attr_simple_evid_final_t;
+
+/**
+ * Simple Evidence Final
+ * see section 3.15.2 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Reserved | Optional Composite Hash Alg |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional TPM PCR Composite Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional TPM PCR Composite (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Optional TPM Quote Signature Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional TPM Quote Signature (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Optional Evidence Signature (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_SIMPLE_EVID_FINAL_SIZE 2
+#define PTS_SIMPLE_EVID_FINAL_RESERVED 0x00
+#define PTS_SIMPLE_EVID_FINAL_FLAG_MASK 0xC0
+/**
+ * Private data of an tcg_pts_attr_simple_evid_final_t object.
+ */
+struct private_tcg_pts_attr_simple_evid_final_t {
+
+ /**
+ * Public members of tcg_pts_attr_simple_evid_final_t
+ */
+ tcg_pts_attr_simple_evid_final_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;
+
+ /**
+ * Set of flags for Simple Evidence Final
+ */
+ u_int8_t flags;
+
+ /**
+ * Optional Composite Hash Algorithm
+ */
+ pts_meas_algorithms_t comp_hash_algorithm;
+
+ /**
+ * Optional TPM PCR Composite
+ */
+ chunk_t pcr_comp;
+
+ /**
+ * Optional TPM Quote Signature
+ */
+ chunk_t tpm_quote_sig;
+
+ /**
+ * Is Evidence Signature included?
+ */
+ bool has_evid_sig;
+
+ /**
+ * Optional Evidence Signature
+ */
+ chunk_t evid_sig;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_simple_evid_final_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("mc", this->value, segment);
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_simple_evid_final_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->pcr_comp.ptr);
+ free(this->tpm_quote_sig.ptr);
+ free(this->evid_sig.ptr);
+ free(this);
+ }
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_simple_evid_final_t *this)
+{
+ bio_writer_t *writer;
+ u_int8_t flags;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ flags = this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
+
+ if (this->has_evid_sig)
+ {
+ flags |= PTS_SIMPLE_EVID_FINAL_EVID_SIG;
+ }
+
+ writer = bio_writer_create(PTS_SIMPLE_EVID_FINAL_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, PTS_SIMPLE_EVID_FINAL_RESERVED);
+
+ /** Optional Composite Hash Algorithm field is always present
+ * Field has value of all zeroes if not used.
+ * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
+ */
+ writer->write_uint16(writer, this->comp_hash_algorithm);
+
+ /* Optional fields */
+ if (this->flags != PTS_SIMPLE_EVID_FINAL_NO)
+ {
+ writer->write_uint32 (writer, this->pcr_comp.len);
+ writer->write_data (writer, this->pcr_comp);
+
+ writer->write_uint32 (writer, this->tpm_quote_sig.len);
+ writer->write_data (writer, this->tpm_quote_sig);
+ }
+
+ if (this->has_evid_sig)
+ {
+ writer->write_data (writer, this->evid_sig);
+ }
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_simple_evid_final_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags, reserved;
+ u_int16_t algorithm;
+ u_int32_t pcr_comp_len, tpm_quote_sig_len, evid_sig_len;
+ status_t status = FAILED;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_SIMPLE_EVID_FINAL_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Simple Evidence Final");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ reader->read_uint8(reader, &flags);
+ reader->read_uint8(reader, &reserved);
+
+ this->flags = flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
+
+ this->has_evid_sig = (flags & PTS_SIMPLE_EVID_FINAL_EVID_SIG) != 0;
+
+ /** Optional Composite Hash Algorithm field is always present
+ * Field has value of all zeroes if not used.
+ * Implemented adhering the suggestion of Paul Sangster 28.Oct.2011
+ */
+
+ reader->read_uint16(reader, &algorithm);
+ this->comp_hash_algorithm = algorithm;
+
+ /* Optional Composite Hash Algorithm and TPM PCR Composite fields */
+ if (this->flags != PTS_SIMPLE_EVID_FINAL_NO)
+ {
+ if (!reader->read_uint32(reader, &pcr_comp_len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "PCR Composite Length");
+ goto end;
+ }
+ if (!reader->read_data(reader, pcr_comp_len, &this->pcr_comp))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "PCR Composite");
+ goto end;
+ }
+ this->pcr_comp = chunk_clone(this->pcr_comp);
+
+ if (!reader->read_uint32(reader, &tpm_quote_sig_len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "TPM Quote Singature Length");
+ goto end;
+ }
+ if (!reader->read_data(reader, tpm_quote_sig_len, &this->tpm_quote_sig))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Simple Evidence Final "
+ "TPM Quote Singature");
+ goto end;
+ }
+ this->tpm_quote_sig = chunk_clone(this->tpm_quote_sig);
+ }
+
+ /* Optional Evidence Signature field */
+ if (this->has_evid_sig)
+ {
+ evid_sig_len = reader->remaining(reader);
+ reader->read_data(reader, evid_sig_len, &this->evid_sig);
+ this->evid_sig = chunk_clone(this->evid_sig);
+ }
+
+ reader->destroy(reader);
+ return SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(tcg_pts_attr_simple_evid_final_t, get_quote_info, u_int8_t,
+ private_tcg_pts_attr_simple_evid_final_t *this,
+ pts_meas_algorithms_t *comp_hash_algo, chunk_t *pcr_comp, chunk_t *tpm_quote_sig)
+{
+ if (comp_hash_algo)
+ {
+ *comp_hash_algo = this->comp_hash_algorithm;
+ }
+ if (pcr_comp)
+ {
+ *pcr_comp = this->pcr_comp;
+ }
+ if (tpm_quote_sig)
+ {
+ *tpm_quote_sig = this->tpm_quote_sig;
+ }
+ return this->flags;
+}
+
+METHOD(tcg_pts_attr_simple_evid_final_t, get_evid_sig, bool,
+ private_tcg_pts_attr_simple_evid_final_t *this, chunk_t *evid_sig)
+{
+ if (evid_sig)
+ {
+ *evid_sig = this->evid_sig;
+ }
+ return this->has_evid_sig;
+}
+
+METHOD(tcg_pts_attr_simple_evid_final_t, set_evid_sig, void,
+ private_tcg_pts_attr_simple_evid_final_t *this, chunk_t evid_sig)
+{
+ this->evid_sig = evid_sig;
+ this->has_evid_sig = TRUE;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags,
+ pts_meas_algorithms_t comp_hash_algorithm,
+ chunk_t pcr_comp, chunk_t tpm_quote_sig)
+{
+ private_tcg_pts_attr_simple_evid_final_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_quote_info = _get_quote_info,
+ .get_evid_sig = _get_evid_sig,
+ .set_evid_sig = _set_evid_sig,
+ },
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL },
+ .flags = flags,
+ .comp_hash_algorithm = comp_hash_algorithm,
+ .pcr_comp = pcr_comp,
+ .tpm_quote_sig = tpm_quote_sig,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_simple_evid_final_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_quote_info = _get_quote_info,
+ .get_evid_sig = _get_evid_sig,
+ .set_evid_sig = _set_evid_sig,
+ },
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.h b/src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.h
new file mode 100644
index 000000000..8343b5b30
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_simple_evid_final.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_simple_evid_final tcg_pts_attr_simple_evid_final
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_
+#define TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_
+
+typedef struct tcg_pts_attr_simple_evid_final_t tcg_pts_attr_simple_evid_final_t;
+
+#include "tcg/tcg_attr.h"
+#include "tcg_pts_attr_meas_algo.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Simple Evidence Final attribute
+ *
+ */
+struct tcg_pts_attr_simple_evid_final_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get Optional PCR Composite and TPM Quote Signature
+ *
+ * @param comp_hash_algo Optional Composite Hash Algorithm
+ * @param pcr_comp Optional PCR Composite
+ * @param tpm_quote sig Optional TPM Quote Signature
+ * @return PTS_SIMPLE_EVID_FINAL flags
+ */
+ u_int8_t (*get_quote_info)(tcg_pts_attr_simple_evid_final_t *this,
+ pts_meas_algorithms_t *comp_hash_algo,
+ chunk_t *pcr_comp, chunk_t *tpm_quote_sig);
+
+ /**
+ * Get Optional Evidence Signature
+ *
+ * @param evid_sig Optional Evidence Signature
+ * @return TRUE if Evidence Signature is available
+ */
+ bool (*get_evid_sig)(tcg_pts_attr_simple_evid_final_t *this,
+ chunk_t *evid_sig);
+
+ /**
+ * Set Optional Evidence Signature
+ *
+ * @param vid_sig Optional Evidence Signature
+ */
+ void (*set_evid_sig)(tcg_pts_attr_simple_evid_final_t *this,
+ chunk_t evid_sig);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_simple_evid_final_t object
+ *
+ * @param flags Set of flags
+ * @param comp_hash_algorithm Composite Hash Algorithm
+ * @param pcr_comp Optional TPM PCR Composite
+ * @param tpm_quote_sign Optional TPM Quote Signature
+ */
+pa_tnc_attr_t* tcg_pts_attr_simple_evid_final_create(
+ u_int8_t flags,
+ pts_meas_algorithms_t comp_hash_algorithm,
+ chunk_t pcr_comp,
+ chunk_t tpm_quote_sign);
+
+/**
+ * Creates an tcg_pts_attr_simple_evid_final_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_pts_attr_simple_evid_final_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_SIMPLE_EVID_FINAL_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.c b/src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.c
new file mode 100644
index 000000000..db877e9c5
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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_pts_attr_tpm_version_info.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_pts_attr_tpm_version_info_t private_tcg_pts_attr_tpm_version_info_t;
+
+/**
+ * TPM Version Information
+ * see section 3.11 of PTS Protocol: Binding to TNC IF-M 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
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TPM Version Information (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * see TPM Structure Specification Part 2, section 21.6: TPM_CAP_VERSION_INFO
+ */
+
+#define PTS_TPM_VER_INFO_SIZE 4
+
+/**
+ * Private data of an tcg_pts_attr_tpm_version_info_t object.
+ */
+struct private_tcg_pts_attr_tpm_version_info_t {
+
+ /**
+ * Public members of tcg_pts_attr_tpm_version_info_t
+ */
+ tcg_pts_attr_tpm_version_info_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;
+
+ /**
+ * TPM Version Information
+ */
+ chunk_t tpm_version_info;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_tpm_version_info_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ bio_writer_t *writer;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ writer = bio_writer_create(PTS_TPM_VER_INFO_SIZE);
+ writer->write_data(writer, this->tpm_version_info);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_tpm_version_info_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 < PTS_TPM_VER_INFO_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for TPM Version Information");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_data (reader, this->value.len, &this->tpm_version_info);
+ this->tpm_version_info = chunk_clone(this->tpm_version_info);
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_tpm_version_info_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_pts_attr_tpm_version_info_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ free(this->value.ptr);
+ free(this->tpm_version_info.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_tpm_version_info_t, get_tpm_version_info, chunk_t,
+ private_tcg_pts_attr_tpm_version_info_t *this)
+{
+ return this->tpm_version_info;
+}
+
+METHOD(tcg_pts_attr_tpm_version_info_t, set_tpm_version_info, void,
+ private_tcg_pts_attr_tpm_version_info_t *this,
+ chunk_t tpm_version_info)
+{
+ this->tpm_version_info = tpm_version_info;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info)
+{
+ private_tcg_pts_attr_tpm_version_info_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_tpm_version_info = _get_tpm_version_info,
+ .set_tpm_version_info = _set_tpm_version_info,
+ },
+ .type = { PEN_TCG, TCG_PTS_TPM_VERSION_INFO },
+ .tpm_version_info = chunk_clone(tpm_version_info),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_tpm_version_info_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_tpm_version_info = _get_tpm_version_info,
+ .set_tpm_version_info = _set_tpm_version_info,
+ },
+ .type = { PEN_TCG, TCG_PTS_TPM_VERSION_INFO },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.h b/src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.h
new file mode 100644
index 000000000..d87d72b22
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_tpm_version_info.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_tpm_version_info tcg_pts_attr_tpm_version_info
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_TPM_VERSION_INFO_H_
+#define TCG_PTS_ATTR_TPM_VERSION_INFO_H_
+
+typedef struct tcg_pts_attr_tpm_version_info_t tcg_pts_attr_tpm_version_info_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS TPM Version Info Attribute
+ *
+ */
+struct tcg_pts_attr_tpm_version_info_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get TPM Version Info
+ *
+ * @return TPM version info
+ */
+ chunk_t (*get_tpm_version_info)(tcg_pts_attr_tpm_version_info_t *this);
+
+ /**
+ * Set TPM Version Info
+ *
+ * @param tpm_version_info TPM version info
+ */
+ void (*set_tpm_version_info)(tcg_pts_attr_tpm_version_info_t *this,
+ chunk_t tpm_version_info);
+};
+
+/**
+ * Creates an tcg_pts_attr_tpm_version_info_t object
+ *
+ * @param tpm_version_info TPM version info
+ */
+pa_tnc_attr_t* tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info);
+
+/**
+ * Creates an tcg_pts_attr_tpm_version_info_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_pts_attr_tpm_version_info_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_TPM_VERSION_INFO_H_ @}*/
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.c b/src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.c
new file mode 100644
index 000000000..7c176fdf6
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2011-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.
+ */
+
+#define _GNU_SOURCE /* for stdndup() */
+#include <string.h>
+
+#include "tcg_pts_attr_unix_file_meta.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_tcg_pts_attr_file_meta_t private_tcg_pts_attr_file_meta_t;
+
+/**
+ * Unix-Style File Metadata
+ * see section 3.17.3 of PTS Protocol: Binding to TNC IF-M 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File metadata Length | Type | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Create Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Create Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Modify Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Modify Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Access Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Access Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Owner ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Owner ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Group ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Group ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ...........................
+ */
+
+#define PTS_FILE_META_SIZE 8
+#define PTS_FILE_MEAS_RESERVED 0x00
+#define PTS_FILE_METADATA_SIZE 52
+
+/**
+ * Private data of an tcg_pts_attr_file_meta_t object.
+ */
+struct private_tcg_pts_attr_file_meta_t {
+
+ /**
+ * Public members of tcg_pts_attr_file_meta_t
+ */
+ tcg_pts_attr_file_meta_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;
+
+ /**
+ * PTS File Metadata
+ */
+ pts_file_meta_t *metadata;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_file_meta_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ pts_file_metadata_t *entry;
+ u_int64_t number_of_files;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ number_of_files = this->metadata->get_file_count(this->metadata);
+ writer = bio_writer_create(PTS_FILE_META_SIZE);
+
+ writer->write_uint64(writer, number_of_files);
+
+ enumerator = this->metadata->create_enumerator(this->metadata);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ writer->write_uint16(writer, PTS_FILE_METADATA_SIZE +
+ strlen(entry->filename));
+ writer->write_uint8 (writer, entry->type);
+ writer->write_uint8 (writer, PTS_FILE_MEAS_RESERVED);
+ writer->write_uint64(writer, entry->filesize);
+ writer->write_uint64(writer, entry->created);
+ writer->write_uint64(writer, entry->modified);
+ writer->write_uint64(writer, entry->accessed);
+ writer->write_uint64(writer, entry->owner);
+ writer->write_uint64(writer, entry->group);
+ writer->write_data (writer, chunk_create(entry->filename,
+ strlen(entry->filename)));
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_file_meta_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ pts_file_metadata_t *entry;
+ u_int8_t type, reserved;
+ u_int16_t len;
+ u_int64_t number_of_files, filesize, created, modified, accessed;
+ u_int64_t owner, group;
+ chunk_t filename;
+ status_t status = FAILED;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < PTS_FILE_META_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Unix-Style file metadata header");
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint64(reader, &number_of_files);
+
+ this->metadata = pts_file_meta_create();
+
+ while (number_of_files--)
+ {
+ if (!reader->read_uint16(reader, &len))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS file metadata length");
+ goto end;
+ }
+ if (!reader->read_uint8(reader, &type))
+ {
+ DBG1(DBG_TNC, "insufficient data for file type");
+ goto end;
+ }
+ if (!reader->read_uint8(reader, &reserved))
+ {
+ DBG1(DBG_TNC, "insufficient data for reserved field");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &filesize))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &created))
+ {
+ DBG1(DBG_TNC, "insufficient data for file create time");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &modified))
+ {
+ DBG1(DBG_TNC, "insufficient data for last modify time");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &accessed))
+ {
+ DBG1(DBG_TNC, "insufficient data for last access time");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &owner))
+ {
+ DBG1(DBG_TNC, "insufficient data for owner id");
+ goto end;
+ }
+ if (!reader->read_uint64(reader, &group))
+ {
+ DBG1(DBG_TNC, "insufficient data for group id");
+ goto end;
+ }
+ if (!reader->read_data(reader, len - PTS_FILE_METADATA_SIZE, &filename))
+ {
+ DBG1(DBG_TNC, "insufficient data for filename");
+ goto end;
+ }
+
+ entry = malloc_thing(pts_file_metadata_t);
+ entry->type = type;
+ entry->filesize = filesize;
+ entry->created = created;
+ entry->modified = modified;
+ entry->accessed = accessed;
+ entry->owner = owner;
+ entry->group = group;
+ entry->filename = strndup(filename.ptr, filename.len);
+
+ this->metadata->add(this->metadata, entry);
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_pts_attr_file_meta_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_pts_attr_file_meta_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->metadata);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_pts_attr_file_meta_t, get_metadata, pts_file_meta_t*,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->metadata;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata)
+{
+ private_tcg_pts_attr_file_meta_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_metadata = _get_metadata,
+ },
+ .type = { PEN_TCG, TCG_PTS_UNIX_FILE_META },
+ .metadata = metadata,
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_pts_attr_file_meta_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_metadata = _get_metadata,
+ },
+ .type = { PEN_TCG, TCG_PTS_UNIX_FILE_META },
+ .length = length,
+ .value = chunk_clone(data),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.h b/src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.h
new file mode 100644
index 000000000..d08261cc9
--- /dev/null
+++ b/src/libimcv/tcg/pts/tcg_pts_attr_unix_file_meta.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_pts_attr_unix_file_meta tcg_pts_attr_unix_file_meta
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_PTS_ATTR_UNIX_FILE_META_H_
+#define TCG_PTS_ATTR_UNIX_FILE_META_H_
+
+typedef struct tcg_pts_attr_file_meta_t tcg_pts_attr_file_meta_t;
+
+#include "tcg/tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts.h"
+#include "pts/pts_file_meta.h"
+
+/**
+ * Class implementing the TCG PTS File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_file_meta_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS File Metadata
+ *
+ * @return PTS File Metadata
+ */
+ pts_file_meta_t* (*get_metadata)(tcg_pts_attr_file_meta_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_file_meta_t object
+ *
+ * @param metadata PTS File Metadata
+ */
+pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata);
+
+/**
+ * Creates an tcg_pts_attr_file_meta_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_pts_attr_unix_file_meta_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_PTS_ATTR_UNIX_FILE_META_H_ @}*/
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_ @}*/
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_req.c b/src/libimcv/tcg/swid/tcg_swid_attr_req.c
new file mode 100644
index 000000000..561242758
--- /dev/null
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_req.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2013-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_swid_attr_req.h"
+
+#include "swid/swid_tag_id.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/debug.h>
+#include <collections/linked_list.h>
+
+typedef struct private_tcg_swid_attr_req_t private_tcg_swid_attr_req_t;
+
+/**
+ * SWID Request
+ * see section 4.7 of TCG TNC SWID Message and Attributes for IF-M
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|S|C| Reserved| Tag ID Count |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Request ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Earliest EID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Tag Creator Length | Tag Creator (variable length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Unique Software ID Length |Unique Software ID (var length)|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define SWID_REQ_RESERVED_MASK 0xE0
+
+/**
+ * Private data of an tcg_swid_attr_req_t object.
+ */
+struct private_tcg_swid_attr_req_t {
+
+ /**
+ * Public members of tcg_swid_attr_req_t
+ */
+ tcg_swid_attr_req_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;
+
+ /**
+ * SWID request flags
+ */
+ u_int8_t flags;
+
+ /**
+ * Request ID
+ */
+ u_int32_t request_id;
+
+ /**
+ * Earliest EID
+ */
+ u_int32_t earliest_eid;
+
+ /**
+ * List of Target Tag Identifiers
+ */
+ swid_inventory_t *targets;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_swid_attr_req_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_swid_attr_req_t *this)
+{
+ bio_writer_t *writer;
+ chunk_t tag_creator, unique_sw_id;
+ swid_tag_id_t *tag_id;
+ enumerator_t *enumerator;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+
+ writer = bio_writer_create(TCG_SWID_REQ_MIN_SIZE);
+ writer->write_uint8 (writer, this->flags);
+ writer->write_uint24(writer, this->targets->get_count(this->targets));
+ writer->write_uint32(writer, this->request_id);
+ writer->write_uint32(writer, this->earliest_eid);
+
+ enumerator = this->targets->create_enumerator(this->targets);
+ while (enumerator->enumerate(enumerator, &tag_id))
+ {
+ tag_creator = tag_id->get_tag_creator(tag_id);
+ unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL);
+ writer->write_data16(writer, tag_creator);
+ writer->write_data16(writer, unique_sw_id);
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = writer->extract_buf(writer);
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_swid_attr_req_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int32_t tag_id_count;
+ chunk_t tag_creator, unique_sw_id;
+ swid_tag_id_t *tag_id;
+
+ *offset = 0;
+
+ if (this->value.len < this->length)
+ {
+ return NEED_MORE;
+ }
+ if (this->value.len < TCG_SWID_REQ_MIN_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for SWID Request");
+ return FAILED;
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &this->flags);
+ reader->read_uint24(reader, &tag_id_count);
+ reader->read_uint32(reader, &this->request_id);
+ reader->read_uint32(reader, &this->earliest_eid);
+
+ if (this->request_id == 0)
+ {
+ *offset = 4;
+ return FAILED;
+ }
+ *offset = TCG_SWID_REQ_MIN_SIZE;
+
+ this->flags &= SWID_REQ_RESERVED_MASK;
+
+ while (tag_id_count--)
+ {
+ if (!reader->read_data16(reader, &tag_creator))
+ {
+ DBG1(DBG_TNC, "insufficient data for Tag Creator field");
+ return FAILED;
+ }
+ *offset += 2 + tag_creator.len;
+
+ if (!reader->read_data16(reader, &unique_sw_id))
+ {
+ DBG1(DBG_TNC, "insufficient data for Unique Software ID");
+ return FAILED;
+ }
+ *offset += 2 + unique_sw_id.len;
+
+ tag_id = swid_tag_id_create(tag_creator, unique_sw_id, chunk_empty);
+ this->targets->add(this->targets, tag_id);
+ }
+ reader->destroy(reader);
+
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_swid_attr_req_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_swid_attr_req_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_swid_attr_req_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->targets->destroy(this->targets);
+ free(this->value.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_swid_attr_req_t, get_flags, u_int8_t,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->flags;
+}
+
+METHOD(tcg_swid_attr_req_t, get_request_id, u_int32_t,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->request_id;
+}
+
+METHOD(tcg_swid_attr_req_t, get_earliest_eid, u_int32_t,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->earliest_eid;
+}
+
+METHOD(tcg_swid_attr_req_t, add_target, void,
+ private_tcg_swid_attr_req_t *this, swid_tag_id_t *tag_id)
+{
+ this->targets->add(this->targets, tag_id);
+}
+
+METHOD(tcg_swid_attr_req_t, get_targets, swid_inventory_t*,
+ private_tcg_swid_attr_req_t *this)
+{
+ return this->targets;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_swid_attr_req_create(u_int8_t flags, u_int32_t request_id,
+ u_int32_t eid)
+{
+ private_tcg_swid_attr_req_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_flags = _get_flags,
+ .get_request_id = _get_request_id,
+ .get_earliest_eid = _get_earliest_eid,
+ .add_target = _add_target,
+ .get_targets = _get_targets,
+ },
+ .type = { PEN_TCG, TCG_SWID_REQUEST },
+ .flags = flags & SWID_REQ_RESERVED_MASK,
+ .request_id = request_id,
+ .earliest_eid = eid,
+ .targets = swid_inventory_create(FALSE),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_swid_attr_req_create_from_data(size_t length, chunk_t data)
+{
+ private_tcg_swid_attr_req_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_flags = _get_flags,
+ .get_request_id = _get_request_id,
+ .get_earliest_eid = _get_earliest_eid,
+ .add_target = _add_target,
+ .get_targets = _get_targets,
+ },
+ .type = { PEN_TCG, TCG_SWID_REQUEST },
+ .length = length,
+ .value = chunk_clone(data),
+ .targets = swid_inventory_create(FALSE),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_req.h b/src/libimcv/tcg/swid/tcg_swid_attr_req.h
new file mode 100644
index 000000000..fd2ccdc4f
--- /dev/null
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_req.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2013-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_swid_attr_req tcg_swid_attr_req
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_SWID_ATTR_REQ_H_
+#define TCG_SWID_ATTR_REQ_H_
+
+#define TCG_SWID_REQ_MIN_SIZE 12
+
+typedef struct tcg_swid_attr_req_t tcg_swid_attr_req_t;
+typedef enum tcg_swid_attr_req_flag_t tcg_swid_attr_req_flag_t;
+
+enum tcg_swid_attr_req_flag_t {
+ TCG_SWID_ATTR_REQ_FLAG_NONE = 0,
+ TCG_SWID_ATTR_REQ_FLAG_R = (1 << 7),
+ TCG_SWID_ATTR_REQ_FLAG_S = (1 << 6),
+ TCG_SWID_ATTR_REQ_FLAG_C = (1 << 5)
+};
+
+#include "tcg/tcg_attr.h"
+#include "swid/swid_tag_id.h"
+#include "swid/swid_inventory.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG SWID Request attribute
+ */
+struct tcg_swid_attr_req_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get SWID request flags
+ *
+ * @return Flags
+ */
+ u_int8_t (*get_flags)(tcg_swid_attr_req_t *this);
+
+ /**
+ * Get Request ID
+ *
+ * @return Request ID
+ */
+ u_int32_t (*get_request_id)(tcg_swid_attr_req_t *this);
+
+ /**
+ * Get Earliest EID
+ *
+ * @return Event ID
+ */
+ u_int32_t (*get_earliest_eid)(tcg_swid_attr_req_t *this);
+
+ /**
+ * Add Tag ID
+ *
+ * @param tag_id SWID Tag ID (is not cloned by constructor!)
+ */
+ void (*add_target)(tcg_swid_attr_req_t *this, swid_tag_id_t *tag_id);
+
+ /**
+ * Create Tag ID enumerator
+ *
+ * @return Get a list of target tag IDs
+ */
+ swid_inventory_t* (*get_targets)(tcg_swid_attr_req_t *this);
+
+};
+
+/**
+ * Creates an tcg_swid_attr_req_t object
+ *
+ * @param flags Sets the C|S|R flags
+ * @param request_id Request ID
+ * @param eid Earliest Event ID
+ */
+pa_tnc_attr_t* tcg_swid_attr_req_create(u_int8_t flags, u_int32_t request_id,
+ u_int32_t eid);
+
+/**
+ * Creates an tcg_swid_attr_req_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_swid_attr_req_create_from_data(size_t length, chunk_t value);
+
+#endif /** TCG_SWID_ATTR_REQ_H_ @}*/
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c
new file mode 100644
index 000000000..560d5878f
--- /dev/null
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (C) 2013-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_swid_attr_tag_id_inv.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_swid_attr_tag_id_inv_t private_tcg_swid_attr_tag_id_inv_t;
+
+/**
+ * SWID Tag Identifier Inventory
+ * see section 4.8 of TCG TNC SWID Message and Attributes for IF-M
+ *
+ * 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 | Tag ID Count |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Request ID Copy |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | EID Epoch |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last EID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Tag Creator Length | Tag Creator (variable length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Unique Software ID Length |Unique Software ID (var length)|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Instance ID Length | Instance ID (variable length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define TCG_SWID_TAG_ID_INV_RESERVED 0x00
+
+/**
+ * Private data of an tcg_swid_attr_tag_id_inv_t object.
+ */
+struct private_tcg_swid_attr_tag_id_inv_t {
+
+ /**
+ * Public members of tcg_swid_attr_tag_id_inv_t
+ */
+ tcg_swid_attr_tag_id_inv_t public;
+
+ /**
+ * Vendor-specific attribute type
+ */
+ pen_type_t type;
+
+ /**
+ * Length of attribute value
+ */
+ size_t length;
+
+ /**
+ * Offset up to which attribute value has been processed
+ */
+ size_t offset;
+
+ /**
+ * Current position of attribute value pointer
+ */
+ chunk_t value;
+
+ /**
+ * Contains complete attribute or current segment
+ */
+ chunk_t segment;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Request ID
+ */
+ uint32_t request_id;
+
+ /**
+ * Event ID Epoch
+ */
+ uint32_t eid_epoch;
+
+ /**
+ * Last Event ID
+ */
+ uint32_t last_eid;
+
+ /**
+ * Number of SWID Tag IDs in attribute
+ */
+ uint32_t tag_id_count;
+
+ /**
+ * SWID Tag ID Inventory
+ */
+ swid_inventory_t *inventory;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_swid_attr_tag_id_inv_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ bio_writer_t *writer;
+ swid_tag_id_t *tag_id;
+ chunk_t tag_creator, unique_sw_id, instance_id;
+ enumerator_t *enumerator;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+
+ writer = bio_writer_create(TCG_SWID_TAG_ID_INV_MIN_SIZE);
+ writer->write_uint8 (writer, TCG_SWID_TAG_ID_INV_RESERVED);
+ writer->write_uint24(writer, this->inventory->get_count(this->inventory));
+ writer->write_uint32(writer, this->request_id);
+ writer->write_uint32(writer, this->eid_epoch);
+ writer->write_uint32(writer, this->last_eid);
+
+ enumerator = this->inventory->create_enumerator(this->inventory);
+ while (enumerator->enumerate(enumerator, &tag_id))
+ {
+ tag_creator = tag_id->get_tag_creator(tag_id);
+ unique_sw_id = tag_id->get_unique_sw_id(tag_id, &instance_id);
+ writer->write_data16(writer, tag_creator);
+ writer->write_data16(writer, unique_sw_id);
+ writer->write_data16(writer, instance_id);
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = writer->extract_buf(writer);
+ this->segment = this->value;
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_swid_attr_tag_id_inv_t *this, uint32_t *offset)
+{
+ bio_reader_t *reader;
+ uint8_t reserved;
+ chunk_t tag_creator, unique_sw_id, instance_id;
+ swid_tag_id_t *tag_id;
+ status_t status = NEED_MORE;
+
+ if (this->offset == 0)
+ {
+ if (this->length < TCG_SWID_TAG_ID_INV_MIN_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ return FAILED;
+ }
+ if (this->value.len < TCG_SWID_TAG_ID_INV_MIN_SIZE)
+ {
+ return NEED_MORE;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint24(reader, &this->tag_id_count);
+ reader->read_uint32(reader, &this->request_id);
+ reader->read_uint32(reader, &this->eid_epoch);
+ reader->read_uint32(reader, &this->last_eid);
+ this->offset = TCG_SWID_TAG_ID_INV_MIN_SIZE;
+ this->value = reader->peek(reader);
+ reader->destroy(reader);
+ }
+
+ reader = bio_reader_create(this->value);
+
+ while (this->tag_id_count)
+ {
+ if (!reader->read_data16(reader, &tag_creator) ||
+ !reader->read_data16(reader, &unique_sw_id) ||
+ !reader->read_data16(reader, &instance_id))
+ {
+ goto end;
+ }
+ tag_id = swid_tag_id_create(tag_creator, unique_sw_id, instance_id);
+ this->inventory->add(this->inventory, tag_id);
+ this->offset += this->value.len - reader->remaining(reader);
+ this->value = reader->peek(reader);
+
+ /* at least one tag ID was processed */
+ status = SUCCESS;
+ this->tag_id_count--;
+ }
+
+ if (this->length != this->offset)
+ {
+ DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ status = FAILED;
+ }
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_swid_attr_tag_id_inv_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("cc", this->value, segment);
+ chunk_free(&this->segment);
+ this->segment = this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->inventory->destroy(this->inventory);
+ free(this->segment.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_swid_attr_tag_id_inv_t, add, void,
+ private_tcg_swid_attr_tag_id_inv_t *this, swid_tag_id_t *tag_id)
+{
+ this->inventory->add(this->inventory, tag_id);
+}
+
+METHOD(tcg_swid_attr_tag_id_inv_t, get_request_id, uint32_t,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ return this->request_id;
+}
+
+METHOD(tcg_swid_attr_tag_id_inv_t, get_last_eid, uint32_t,
+ private_tcg_swid_attr_tag_id_inv_t *this, uint32_t *eid_epoch)
+{
+ if (eid_epoch)
+ {
+ *eid_epoch = this->eid_epoch;
+ }
+ return this->last_eid;
+}
+
+METHOD(tcg_swid_attr_tag_id_inv_t, get_tag_id_count, uint32_t,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ return this->tag_id_count;
+}
+
+METHOD(tcg_swid_attr_tag_id_inv_t, get_inventory, swid_inventory_t*,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ return this->inventory;
+}
+
+METHOD(tcg_swid_attr_tag_id_inv_t, clear_inventory, void,
+ private_tcg_swid_attr_tag_id_inv_t *this)
+{
+ this->inventory->destroy(this->inventory);
+ this->inventory = swid_inventory_create(FALSE);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create(uint32_t request_id,
+ uint32_t eid_epoch,
+ uint32_t eid)
+{
+ private_tcg_swid_attr_tag_id_inv_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,
+ },
+ .add = _add,
+ .get_request_id = _get_request_id,
+ .get_last_eid = _get_last_eid,
+ .get_tag_id_count = _get_tag_id_count,
+ .get_inventory = _get_inventory,
+ .clear_inventory = _clear_inventory,
+ },
+ .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY },
+ .request_id = request_id,
+ .eid_epoch = eid_epoch,
+ .last_eid = eid,
+ .inventory = swid_inventory_create(FALSE),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_swid_attr_tag_id_inv_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_swid_attr_tag_id_inv_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,
+ },
+ .add = _add,
+ .get_request_id = _get_request_id,
+ .get_last_eid = _get_last_eid,
+ .get_tag_id_count = _get_tag_id_count,
+ .get_inventory = _get_inventory,
+ .clear_inventory = _clear_inventory,
+ },
+ .type = { PEN_TCG, TCG_SWID_TAG_ID_INVENTORY },
+ .length = length,
+ .segment = chunk_clone(data),
+ .inventory = swid_inventory_create(FALSE),
+ .ref = 1,
+ );
+
+ /* received either complete attribute value or first segment */
+ this->value = this->segment;
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h
new file mode 100644
index 000000000..e9db9b3c6
--- /dev/null
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_id_inv.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2013-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_swid_attr_tag_id_inv tcg_swid_attr_tag_id_inv
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_SWID_ATTR_TAG_ID_INV_H_
+#define TCG_SWID_ATTR_TAG_ID_INV_H_
+
+typedef struct tcg_swid_attr_tag_id_inv_t tcg_swid_attr_tag_id_inv_t;
+
+#include "tcg/tcg_attr.h"
+#include "swid/swid_tag_id.h"
+#include "swid/swid_inventory.h"
+
+#include <pa_tnc/pa_tnc_attr.h>
+
+#define TCG_SWID_TAG_ID_INV_MIN_SIZE 16
+
+/**
+ * Class implementing the TCG SWID Tag Identifier Inventory attribute
+ *
+ */
+struct tcg_swid_attr_tag_id_inv_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Add a Tag ID to the attribute
+ *
+ * @param tag_id SWID Tag ID to be added
+ */
+ void (*add)(tcg_swid_attr_tag_id_inv_t *this, swid_tag_id_t *tag_id);
+
+ /**
+ * Get Request ID
+ *
+ * @return Request ID
+ */
+ uint32_t (*get_request_id)(tcg_swid_attr_tag_id_inv_t *this);
+
+ /**
+ * Get Last Event ID
+ *
+ * @param eid_epoch Event ID Epoch
+ * @return Last Event ID
+ */
+ uint32_t (*get_last_eid)(tcg_swid_attr_tag_id_inv_t *this,
+ uint32_t *eid_epoch);
+
+ /**
+ * Get count of remaining SWID tag IDs
+ *
+ * @return SWID Tag ID count
+ */
+ uint32_t (*get_tag_id_count)(tcg_swid_attr_tag_id_inv_t *this);
+
+ /**
+ * Get Inventory of SWID tag IDs
+ *
+ * @result SWID Tag ID Inventory
+ */
+ swid_inventory_t* (*get_inventory)(tcg_swid_attr_tag_id_inv_t *this);
+
+ /**
+ * Remove all SWID Tag IDs from the Inventory
+ */
+ void (*clear_inventory)(tcg_swid_attr_tag_id_inv_t *this);
+
+};
+
+/**
+ * Creates an tcg_swid_attr_tag_id_inv_t object
+ *
+ * @param request_id Copy of the Request ID
+ * @param eid_epoch Event ID Epoch
+ * @param eid Last Event ID
+ */
+pa_tnc_attr_t* tcg_swid_attr_tag_id_inv_create(uint32_t request_id,
+ uint32_t eid_epoch,
+ uint32_t eid);
+
+/**
+ * Creates an tcg_swid_attr_tag_id_inv_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_swid_attr_tag_id_inv_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_SWID_ATTR_TAG_ID_INV_H_ @}*/
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c
new file mode 100644
index 000000000..013482441
--- /dev/null
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2013-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_swid_attr_tag_inv.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_swid_attr_tag_inv_t private_tcg_swid_attr_tag_inv_t;
+
+/**
+ * SWID Tag Inventory
+ * see section 4.10 of TCG TNC SWID Message and Attributes for IF-M
+ *
+ * 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 | Tag ID Count |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Request ID Copy |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | EID Epoch |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last EID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Instance ID Length | Instance ID (var. length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Tag Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Tag (Variable) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define TCG_SWID_TAG_INV_RESERVED 0x00
+
+/**
+ * Private data of an tcg_swid_attr_tag_inv_t object.
+ */
+struct private_tcg_swid_attr_tag_inv_t {
+
+ /**
+ * Public members of tcg_swid_attr_tag_inv_t
+ */
+ tcg_swid_attr_tag_inv_t public;
+
+ /**
+ * Vendor-specific attribute type
+ */
+ pen_type_t type;
+
+ /**
+ * Length of attribute value
+ */
+ size_t length;
+
+ /**
+ * Offset up to which attribute value has been processed
+ */
+ size_t offset;
+
+ /**
+ * Current position of attribute value pointer
+ */
+ chunk_t value;
+
+ /**
+ * Contains complete attribute or current segment
+ */
+ chunk_t segment;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Request ID
+ */
+ uint32_t request_id;
+
+ /**
+ * Event ID Epoch
+ */
+ uint32_t eid_epoch;
+
+ /**
+ * Last Event ID
+ */
+ uint32_t last_eid;
+
+ /**
+ * Number of SWID Tags in attribute
+ */
+ uint32_t tag_count;
+
+ /**
+ * SWID Tag Inventory
+ */
+ swid_inventory_t *inventory;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_swid_attr_tag_inv_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ bio_writer_t *writer;
+ swid_tag_t *tag;
+ enumerator_t *enumerator;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+
+ writer = bio_writer_create(TCG_SWID_TAG_INV_MIN_SIZE);
+ writer->write_uint8 (writer, TCG_SWID_TAG_INV_RESERVED);
+ writer->write_uint24(writer, this->inventory->get_count(this->inventory));
+ writer->write_uint32(writer, this->request_id);
+ writer->write_uint32(writer, this->eid_epoch);
+ writer->write_uint32(writer, this->last_eid);
+
+ enumerator = this->inventory->create_enumerator(this->inventory);
+ while (enumerator->enumerate(enumerator, &tag))
+ {
+ writer->write_data16(writer, tag->get_instance_id(tag));
+ writer->write_data32(writer, tag->get_encoding(tag));
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = writer->extract_buf(writer);
+ this->segment = this->value;
+ this->length = this->value.len;
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_swid_attr_tag_inv_t *this, uint32_t *offset)
+{
+ bio_reader_t *reader;
+ uint8_t reserved;
+ chunk_t tag_encoding, instance_id;
+ swid_tag_t *tag;
+ status_t status = NEED_MORE;
+
+ if (this->offset == 0)
+ {
+ if (this->length < TCG_SWID_TAG_INV_MIN_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ return FAILED;
+ }
+ if (this->value.len < TCG_SWID_TAG_INV_MIN_SIZE)
+ {
+ return NEED_MORE;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &reserved);
+ reader->read_uint24(reader, &this->tag_count);
+ reader->read_uint32(reader, &this->request_id);
+ reader->read_uint32(reader, &this->eid_epoch);
+ reader->read_uint32(reader, &this->last_eid);
+ this->offset = TCG_SWID_TAG_INV_MIN_SIZE;
+ this->value = reader->peek(reader);
+ reader->destroy(reader);
+ }
+
+ reader = bio_reader_create(this->value);
+
+ while (this->tag_count)
+ {
+ if (!reader->read_data16(reader, &instance_id) ||
+ !reader->read_data32(reader, &tag_encoding))
+ {
+ goto end;
+ }
+ tag = swid_tag_create(tag_encoding, instance_id);
+ this->inventory->add(this->inventory, tag);
+ this->offset += this->value.len - reader->remaining(reader);
+ this->value = reader->peek(reader);
+
+ /* at least one tag was processed */
+ status = SUCCESS;
+ this->tag_count--;
+ }
+
+ if (this->length != this->offset)
+ {
+ DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_TCG,
+ tcg_attr_names, this->type.type);
+ *offset = this->offset;
+ status = FAILED;
+ }
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, add_segment, void,
+ private_tcg_swid_attr_tag_inv_t *this, chunk_t segment)
+{
+ this->value = chunk_cat("cc", this->value, segment);
+ chunk_free(&this->segment);
+ this->segment = this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->inventory->destroy(this->inventory);
+ free(this->segment.ptr);
+ free(this);
+ }
+}
+
+METHOD(tcg_swid_attr_tag_inv_t, add, void,
+ private_tcg_swid_attr_tag_inv_t *this, swid_tag_t *tag)
+{
+ this->inventory->add(this->inventory, tag);
+}
+
+METHOD(tcg_swid_attr_tag_inv_t, get_request_id, uint32_t,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ return this->request_id;
+}
+
+METHOD(tcg_swid_attr_tag_inv_t, get_last_eid, uint32_t,
+ private_tcg_swid_attr_tag_inv_t *this, uint32_t *eid_epoch)
+{
+ if (eid_epoch)
+ {
+ *eid_epoch = this->eid_epoch;
+ }
+ return this->last_eid;
+}
+
+METHOD(tcg_swid_attr_tag_inv_t, get_tag_count, uint32_t,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ return this->tag_count;
+}
+
+METHOD(tcg_swid_attr_tag_inv_t, get_inventory, swid_inventory_t*,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ return this->inventory;
+}
+
+METHOD(tcg_swid_attr_tag_inv_t, clear_inventory, void,
+ private_tcg_swid_attr_tag_inv_t *this)
+{
+ this->inventory->destroy(this->inventory);
+ this->inventory = swid_inventory_create(TRUE);
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_swid_attr_tag_inv_create(uint32_t request_id,
+ uint32_t eid_epoch, uint32_t eid)
+{
+ private_tcg_swid_attr_tag_inv_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,
+ },
+ .add = _add,
+ .get_request_id = _get_request_id,
+ .get_last_eid = _get_last_eid,
+ .get_tag_count = _get_tag_count,
+ .get_inventory = _get_inventory,
+ .clear_inventory = _clear_inventory,
+ },
+ .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY },
+ .request_id = request_id,
+ .eid_epoch = eid_epoch,
+ .last_eid = eid,
+ .inventory = swid_inventory_create(TRUE),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_swid_attr_tag_inv_create_from_data(size_t length,
+ chunk_t data)
+{
+ private_tcg_swid_attr_tag_inv_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,
+ },
+ .add = _add,
+ .get_request_id = _get_request_id,
+ .get_last_eid = _get_last_eid,
+ .get_tag_count = _get_tag_count,
+ .get_inventory = _get_inventory,
+ .clear_inventory = _clear_inventory,
+ },
+ .type = { PEN_TCG, TCG_SWID_TAG_INVENTORY },
+ .length = length,
+ .segment = chunk_clone(data),
+ .inventory = swid_inventory_create(TRUE),
+ .ref = 1,
+ );
+
+ /* received either complete attribute value or first segment */
+ this->value = this->segment;
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h
new file mode 100644
index 000000000..43ebd9e2a
--- /dev/null
+++ b/src/libimcv/tcg/swid/tcg_swid_attr_tag_inv.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2013-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_swid_attr_tag_inv tcg_swid_attr_tag_inv
+ * @{ @ingroup tcg_attr
+ */
+
+#ifndef TCG_SWID_ATTR_TAG_INV_H_
+#define TCG_SWID_ATTR_TAG_INV_H_
+
+typedef struct tcg_swid_attr_tag_inv_t tcg_swid_attr_tag_inv_t;
+
+#include "tcg/tcg_attr.h"
+#include "swid/swid_tag.h"
+#include "swid/swid_inventory.h"
+
+#include <pa_tnc/pa_tnc_attr.h>
+
+#define TCG_SWID_TAG_INV_MIN_SIZE 16
+
+/**
+ * Class implementing the TCG SWID Tag Inventory attribute
+ *
+ */
+struct tcg_swid_attr_tag_inv_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Add a Tag ID to the attribute
+ *
+ * @param tag SWID Tag to be added
+ */
+ void (*add)(tcg_swid_attr_tag_inv_t *this, swid_tag_t *tag);
+ /**
+ * Get Request ID
+ *
+ * @return Request ID
+ */
+ uint32_t (*get_request_id)(tcg_swid_attr_tag_inv_t *this);
+
+ /**
+ * Get Last Event ID
+ *
+ * @param eid_epoch Event ID Epoch
+ * @return Last Event ID
+ */
+ uint32_t (*get_last_eid)(tcg_swid_attr_tag_inv_t *this,
+ uint32_t *eid_epoch);
+
+ /**
+ * Get count of remaining SWID tags
+ *
+ * @return SWID Tag count
+ */
+ uint32_t (*get_tag_count)(tcg_swid_attr_tag_inv_t *this);
+
+ /**
+ * Get Inventory of SWID tags
+ *
+ * @result SWID Tag Inventory
+ */
+ swid_inventory_t* (*get_inventory)(tcg_swid_attr_tag_inv_t *this);
+
+ /**
+ * Remove all SWID Tags from the Inventory
+ */
+ void (*clear_inventory)(tcg_swid_attr_tag_inv_t *this);
+
+};
+
+/**
+ * Creates an tcg_swid_attr_tag_inv_t object
+ *
+ * @param request_id Copy of the Request ID
+ * @param eid_epoch Event ID Epoch
+ * @param eid Last Event ID
+ */
+pa_tnc_attr_t* tcg_swid_attr_tag_inv_create(uint32_t request_id,
+ uint32_t eid_epoch,
+ uint32_t eid);
+
+/**
+ * Creates an tcg_swid_attr_tag_inv_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_swid_attr_tag_inv_create_from_data(size_t length,
+ chunk_t value);
+
+#endif /** TCG_SWID_ATTR_TAG_INV_H_ @}*/
diff --git a/src/libimcv/tcg/tcg_attr.c b/src/libimcv/tcg/tcg_attr.c
new file mode 100644
index 000000000..79492913b
--- /dev/null
+++ b/src/libimcv/tcg/tcg_attr.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2011-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_attr.h"
+#include "tcg/pts/tcg_pts_attr_proto_caps.h"
+#include "tcg/pts/tcg_pts_attr_dh_nonce_params_req.h"
+#include "tcg/pts/tcg_pts_attr_dh_nonce_params_resp.h"
+#include "tcg/pts/tcg_pts_attr_dh_nonce_finish.h"
+#include "tcg/pts/tcg_pts_attr_meas_algo.h"
+#include "tcg/pts/tcg_pts_attr_get_tpm_version_info.h"
+#include "tcg/pts/tcg_pts_attr_tpm_version_info.h"
+#include "tcg/pts/tcg_pts_attr_get_aik.h"
+#include "tcg/pts/tcg_pts_attr_aik.h"
+#include "tcg/pts/tcg_pts_attr_req_func_comp_evid.h"
+#include "tcg/pts/tcg_pts_attr_gen_attest_evid.h"
+#include "tcg/pts/tcg_pts_attr_simple_comp_evid.h"
+#include "tcg/pts/tcg_pts_attr_simple_evid_final.h"
+#include "tcg/pts/tcg_pts_attr_req_file_meas.h"
+#include "tcg/pts/tcg_pts_attr_file_meas.h"
+#include "tcg/pts/tcg_pts_attr_req_file_meta.h"
+#include "tcg/pts/tcg_pts_attr_unix_file_meta.h"
+#include "tcg/swid/tcg_swid_attr_req.h"
+#include "tcg/swid/tcg_swid_attr_tag_id_inv.h"
+#include "tcg/swid/tcg_swid_attr_tag_inv.h"
+#include "tcg/seg/tcg_seg_attr_max_size.h"
+#include "tcg/seg/tcg_seg_attr_seg_env.h"
+#include "tcg/seg/tcg_seg_attr_next_seg.h"
+
+ENUM_BEGIN(tcg_attr_names, TCG_SCAP_REFERENCES,
+ TCG_SCAP_SUMMARY_RESULTS,
+ "SCAP References",
+ "SCAP Capabilities and Inventory",
+ "SCAP Content",
+ "SCAP Assessment",
+ "SCAP Results",
+ "SCAP Summary Results");
+ENUM_NEXT(tcg_attr_names, TCG_SWID_REQUEST,
+ TCG_SWID_TAG_EVENTS,
+ TCG_SCAP_SUMMARY_RESULTS,
+ "SWID Request",
+ "SWID Tag Identifier Inventory",
+ "SWID Tag Identifier Events",
+ "SWID Tag Inventory",
+ "SWID Tag Events");
+ENUM_NEXT(tcg_attr_names, TCG_SEG_MAX_ATTR_SIZE_REQ,
+ TCG_SEG_CANCEL_SEG_EXCH,
+ TCG_SWID_TAG_EVENTS,
+ "Max Attribute Size Request",
+ "Max Attribute Size Response",
+ "Attribute Segment Envelope",
+ "Next Segment Request",
+ "Cancel Segment Exchange");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FUNC_COMP_EVID,
+ TCG_PTS_REQ_FUNC_COMP_EVID,
+ TCG_SEG_CANCEL_SEG_EXCH,
+ "Request Functional Component Evidence");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_GEN_ATTEST_EVID,
+ TCG_PTS_GEN_ATTEST_EVID,
+ TCG_PTS_REQ_FUNC_COMP_EVID,
+ "Generate Attestation Evidence");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_SIMPLE_COMP_EVID,
+ TCG_PTS_SIMPLE_COMP_EVID,
+ TCG_PTS_GEN_ATTEST_EVID,
+ "Simple Component Evidence");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_SIMPLE_EVID_FINAL,
+ TCG_PTS_SIMPLE_EVID_FINAL,
+ TCG_PTS_SIMPLE_COMP_EVID,
+ "Simple Evidence Final");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_VERIFICATION_RESULT,
+ TCG_PTS_VERIFICATION_RESULT,
+ TCG_PTS_SIMPLE_EVID_FINAL,
+ "Verification Result");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_INTEG_REPORT,
+ TCG_PTS_INTEG_REPORT,
+ TCG_PTS_VERIFICATION_RESULT,
+ "Integrity Report");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FILE_META,
+ TCG_PTS_REQ_FILE_META,
+ TCG_PTS_INTEG_REPORT,
+ "Request File Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_WIN_FILE_META,
+ TCG_PTS_WIN_FILE_META,
+ TCG_PTS_REQ_FILE_META,
+ "Windows-Style File Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_UNIX_FILE_META,
+ TCG_PTS_UNIX_FILE_META,
+ TCG_PTS_WIN_FILE_META,
+ "Unix-Style File Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_REGISTRY_VALUE,
+ TCG_PTS_REQ_REGISTRY_VALUE,
+ TCG_PTS_UNIX_FILE_META,
+ "Request Registry Value");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REGISTRY_VALUE,
+ TCG_PTS_REGISTRY_VALUE,
+ TCG_PTS_REQ_REGISTRY_VALUE,
+ "Registry Value");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_FILE_MEAS,
+ TCG_PTS_REQ_FILE_MEAS,
+ TCG_PTS_REGISTRY_VALUE,
+ "Request File Measurement");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_FILE_MEAS,
+ TCG_PTS_FILE_MEAS,
+ TCG_PTS_REQ_FILE_MEAS,
+ "File Measurement");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_INTEG_MEAS_LOG,
+ TCG_PTS_REQ_INTEG_MEAS_LOG,
+ TCG_PTS_FILE_MEAS,
+ "Request Integrity Measurement Log");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_INTEG_MEAS_LOG,
+ TCG_PTS_INTEG_MEAS_LOG,
+ TCG_PTS_REQ_INTEG_MEAS_LOG,
+ "Integrity Measurement Log");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_PROTO_CAPS,
+ TCG_PTS_REQ_PROTO_CAPS,
+ TCG_PTS_INTEG_MEAS_LOG,
+ "Request PTS Protocol Capabilities");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_PROTO_CAPS,
+ TCG_PTS_PROTO_CAPS,
+ TCG_PTS_REQ_PROTO_CAPS,
+ "PTS Protocol Capabilities");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_PARAMS_REQ,
+ TCG_PTS_DH_NONCE_PARAMS_REQ,
+ TCG_PTS_PROTO_CAPS,
+ "DH Nonce Parameters Request");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_PARAMS_RESP,
+ TCG_PTS_DH_NONCE_PARAMS_RESP,
+ TCG_PTS_DH_NONCE_PARAMS_REQ,
+ "DH Nonce Parameters Response");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_DH_NONCE_FINISH,
+ TCG_PTS_DH_NONCE_FINISH,
+ TCG_PTS_DH_NONCE_PARAMS_RESP,
+ "DH Nonce Finish");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_MEAS_ALGO,
+ TCG_PTS_MEAS_ALGO,
+ TCG_PTS_DH_NONCE_FINISH,
+ "PTS Measurement Algorithm Request");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_MEAS_ALGO_SELECTION,
+ TCG_PTS_MEAS_ALGO_SELECTION,
+ TCG_PTS_MEAS_ALGO,
+ "PTS Measurement Algorithm");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_GET_TPM_VERSION_INFO,
+ TCG_PTS_GET_TPM_VERSION_INFO,
+ TCG_PTS_MEAS_ALGO_SELECTION,
+ "Get TPM Version Information");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_TPM_VERSION_INFO,
+ TCG_PTS_TPM_VERSION_INFO,
+ TCG_PTS_GET_TPM_VERSION_INFO,
+ "TPM Version Information");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_REQ_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_REQ_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_TPM_VERSION_INFO,
+ "Request Template Reference Manifest Set Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_TEMPL_REF_MANI_SET_META,
+ TCG_PTS_REQ_TEMPL_REF_MANI_SET_META,
+ "Template Reference Manifest Set Metadata");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_UPDATE_TEMPL_REF_MANI,
+ TCG_PTS_UPDATE_TEMPL_REF_MANI,
+ TCG_PTS_TEMPL_REF_MANI_SET_META,
+ "Update Template Reference Manifest");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_GET_AIK,
+ TCG_PTS_GET_AIK,
+ TCG_PTS_UPDATE_TEMPL_REF_MANI,
+ "Get Attestation Identity Key");
+ENUM_NEXT(tcg_attr_names, TCG_PTS_AIK,
+ TCG_PTS_AIK,
+ TCG_PTS_GET_AIK,
+ "Attestation Identity Key");
+ENUM_END(tcg_attr_names, TCG_PTS_AIK);
+
+/**
+ * See header
+ */
+pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, size_t length, chunk_t value)
+{
+ switch (type)
+ {
+ case TCG_SWID_REQUEST:
+ return tcg_swid_attr_req_create_from_data(length, value);
+ case TCG_SWID_TAG_ID_INVENTORY:
+ return tcg_swid_attr_tag_id_inv_create_from_data(length, value);
+ case TCG_SWID_TAG_INVENTORY:
+ return tcg_swid_attr_tag_inv_create_from_data(length, value);
+ case TCG_SEG_MAX_ATTR_SIZE_REQ:
+ return tcg_seg_attr_max_size_create_from_data(length, value, TRUE);
+ case TCG_SEG_MAX_ATTR_SIZE_RESP:
+ return tcg_seg_attr_max_size_create_from_data(length, value, FALSE);
+ case TCG_SEG_ATTR_SEG_ENV:
+ return tcg_seg_attr_seg_env_create_from_data(length, value);
+ case TCG_SEG_NEXT_SEG_REQ:
+ return tcg_seg_attr_next_seg_create_from_data(length, value);
+ case TCG_PTS_REQ_PROTO_CAPS:
+ return tcg_pts_attr_proto_caps_create_from_data(length, value,
+ TRUE);
+ case TCG_PTS_PROTO_CAPS:
+ return tcg_pts_attr_proto_caps_create_from_data(length, value,
+ FALSE);
+ case TCG_PTS_DH_NONCE_PARAMS_REQ:
+ return tcg_pts_attr_dh_nonce_params_req_create_from_data(length,
+ value);
+ case TCG_PTS_DH_NONCE_PARAMS_RESP:
+ return tcg_pts_attr_dh_nonce_params_resp_create_from_data(length,
+ value);
+ case TCG_PTS_DH_NONCE_FINISH:
+ return tcg_pts_attr_dh_nonce_finish_create_from_data(length, value);
+ case TCG_PTS_MEAS_ALGO:
+ return tcg_pts_attr_meas_algo_create_from_data(length, value,
+ FALSE);
+ case TCG_PTS_MEAS_ALGO_SELECTION:
+ return tcg_pts_attr_meas_algo_create_from_data(length, value,
+ TRUE);
+ case TCG_PTS_GET_TPM_VERSION_INFO:
+ return tcg_pts_attr_get_tpm_version_info_create_from_data(length,
+ value);
+ case TCG_PTS_TPM_VERSION_INFO:
+ return tcg_pts_attr_tpm_version_info_create_from_data(length,
+ value);
+ case TCG_PTS_GET_AIK:
+ return tcg_pts_attr_get_aik_create_from_data(length, value);
+ case TCG_PTS_AIK:
+ return tcg_pts_attr_aik_create_from_data(length, value);
+ case TCG_PTS_REQ_FUNC_COMP_EVID:
+ return tcg_pts_attr_req_func_comp_evid_create_from_data(length,
+ value);
+ case TCG_PTS_GEN_ATTEST_EVID:
+ return tcg_pts_attr_gen_attest_evid_create_from_data(length, value);
+ case TCG_PTS_SIMPLE_COMP_EVID:
+ return tcg_pts_attr_simple_comp_evid_create_from_data(length,
+ value);
+ case TCG_PTS_SIMPLE_EVID_FINAL:
+ return tcg_pts_attr_simple_evid_final_create_from_data(length,
+ value);
+ case TCG_PTS_REQ_FILE_MEAS:
+ return tcg_pts_attr_req_file_meas_create_from_data(length, value);
+ case TCG_PTS_FILE_MEAS:
+ return tcg_pts_attr_file_meas_create_from_data(length, value);
+ case TCG_PTS_REQ_FILE_META:
+ return tcg_pts_attr_req_file_meta_create_from_data(length, value);
+ case TCG_PTS_UNIX_FILE_META:
+ return tcg_pts_attr_unix_file_meta_create_from_data(length, value);
+ /* unsupported TCG/SWID attributes */
+ case TCG_SWID_TAG_ID_EVENTS:
+ case TCG_SWID_TAG_EVENTS:
+ /* unsupported TCG/PTS attributes */
+ case TCG_PTS_REQ_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_TEMPL_REF_MANI_SET_META:
+ case TCG_PTS_UPDATE_TEMPL_REF_MANI:
+ case TCG_PTS_VERIFICATION_RESULT:
+ case TCG_PTS_INTEG_REPORT:
+ case TCG_PTS_WIN_FILE_META:
+ case TCG_PTS_REQ_REGISTRY_VALUE:
+ case TCG_PTS_REGISTRY_VALUE:
+ case TCG_PTS_REQ_INTEG_MEAS_LOG:
+ case TCG_PTS_INTEG_MEAS_LOG:
+ default:
+ return NULL;
+ }
+}
diff --git a/src/libimcv/tcg/tcg_attr.h b/src/libimcv/tcg/tcg_attr.h
new file mode 100644
index 000000000..9523f8e18
--- /dev/null
+++ b/src/libimcv/tcg/tcg_attr.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011-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_attr tcg_attr
+ * @{ @ingroup libimcv
+ */
+
+#ifndef TCG_ATTR_H_
+#define TCG_ATTR_H_
+
+#include <pa_tnc/pa_tnc_attr.h>
+#include <library.h>
+
+typedef enum tcg_attr_t tcg_attr_t;
+
+/**
+ * TCG PTS IF-M Attributes (section 4 of PTS PROTO: Binding to TNC IF-M)
+ */
+enum tcg_attr_t {
+
+ /* SCAP Attributes */
+ TCG_SCAP_REFERENCES = 0x00000001,
+ TCG_SCAP_CAPS_AND_INVENTORY = 0x00000002,
+ TCG_SCAP_CONTENT = 0x00000003,
+ TCG_SCAP_ASSESSMENT = 0x00000004,
+ TCG_SCAP_RESULTS = 0x00000005,
+ TCG_SCAP_SUMMARY_RESULTS = 0x00000006,
+
+ /* SWID Attributes */
+ TCG_SWID_REQUEST = 0x00000011,
+ TCG_SWID_TAG_ID_INVENTORY = 0x00000012,
+ TCG_SWID_TAG_ID_EVENTS = 0x00000013,
+ TCG_SWID_TAG_INVENTORY = 0x00000014,
+ TCG_SWID_TAG_EVENTS = 0x00000015,
+
+ /* IF-M Attribute Segmentation */
+ TCG_SEG_MAX_ATTR_SIZE_REQ = 0x00000021,
+ TCG_SEG_MAX_ATTR_SIZE_RESP = 0x00000022,
+ TCG_SEG_ATTR_SEG_ENV = 0x00000023,
+ TCG_SEG_NEXT_SEG_REQ = 0x00000024,
+ TCG_SEG_CANCEL_SEG_EXCH = 0x00000025,
+
+ /* PTS Protocol Negotiations */
+ TCG_PTS_REQ_PROTO_CAPS = 0x01000000,
+ TCG_PTS_PROTO_CAPS = 0x02000000,
+ TCG_PTS_DH_NONCE_PARAMS_REQ = 0x03000000,
+ TCG_PTS_DH_NONCE_PARAMS_RESP = 0x04000000,
+ TCG_PTS_DH_NONCE_FINISH = 0x05000000,
+ TCG_PTS_MEAS_ALGO = 0x06000000,
+ TCG_PTS_MEAS_ALGO_SELECTION = 0x07000000,
+ TCG_PTS_GET_TPM_VERSION_INFO = 0x08000000,
+ TCG_PTS_TPM_VERSION_INFO = 0x09000000,
+ TCG_PTS_REQ_TEMPL_REF_MANI_SET_META = 0x0A000000,
+ TCG_PTS_TEMPL_REF_MANI_SET_META = 0x0B000000,
+ TCG_PTS_UPDATE_TEMPL_REF_MANI = 0x0C000000,
+ TCG_PTS_GET_AIK = 0x0D000000,
+ TCG_PTS_AIK = 0x0E000000,
+
+ /* PTS-based Attestation Evidence */
+ TCG_PTS_REQ_FUNC_COMP_EVID = 0x00100000,
+ TCG_PTS_GEN_ATTEST_EVID = 0x00200000,
+ TCG_PTS_SIMPLE_COMP_EVID = 0x00300000,
+ TCG_PTS_SIMPLE_EVID_FINAL = 0x00400000,
+ TCG_PTS_VERIFICATION_RESULT = 0x00500000,
+ TCG_PTS_INTEG_REPORT = 0x00600000,
+ TCG_PTS_REQ_FILE_META = 0x00700000,
+ TCG_PTS_WIN_FILE_META = 0x00800000,
+ TCG_PTS_UNIX_FILE_META = 0x00900000,
+ TCG_PTS_REQ_REGISTRY_VALUE = 0x00A00000,
+ TCG_PTS_REGISTRY_VALUE = 0x00B00000,
+ TCG_PTS_REQ_FILE_MEAS = 0x00C00000,
+ TCG_PTS_FILE_MEAS = 0x00D00000,
+ TCG_PTS_REQ_INTEG_MEAS_LOG = 0x00E00000,
+ TCG_PTS_INTEG_MEAS_LOG = 0x00F00000,
+};
+
+/**
+ * enum name for tcg_attr_t.
+ */
+extern enum_name_t *tcg_attr_names;
+
+/**
+ * Create a TCG PA-TNC attribute from data
+ *
+ * @param type attribute type
+ * @param length attribute length
+ * @param value attribute value or segment
+ */
+pa_tnc_attr_t* tcg_attr_create_from_data(u_int32_t type, size_t length,
+ chunk_t value);
+
+#endif /** TCG_ATTR_H_ @}*/