diff options
Diffstat (limited to 'src/libimcv/tcg')
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_ @}*/ |