ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
ita/ita_attr_settings.h ita/ita_attr_settings.c \
ita/ita_attr_angel.h ita/ita_attr_angel.c \
+ ita/ita_attr_symlinks.h ita/ita_attr_symlinks.c \
os_info/os_info.h os_info/os_info.c \
pa_tnc/pa_tnc_attr.h \
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
pts/pts_ima_bios_list.h pts/pts_ima_bios_list.c \
pts/pts_ima_event_list.h pts/pts_ima_event_list.c \
pts/pts_meas_algo.h pts/pts_meas_algo.c \
+ pts/pts_symlinks.h pts/pts_symlinks.c \
pts/components/pts_component.h \
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
ita/ita_attr_settings.h ita/ita_attr_settings.c \
ita/ita_attr_angel.h ita/ita_attr_angel.c \
+ ita/ita_attr_symlinks.h ita/ita_attr_symlinks.c \
os_info/os_info.h os_info/os_info.c \
pa_tnc/pa_tnc_attr.h \
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
pts/pts_ima_bios_list.h pts/pts_ima_bios_list.c \
pts/pts_ima_event_list.h pts/pts_ima_event_list.c \
pts/pts_meas_algo.h pts/pts_meas_algo.c \
+ pts/pts_symlinks.h pts/pts_symlinks.c \
pts/components/pts_component.h \
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
/*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include "ita/ita_attr_get_settings.h"
#include "ita/ita_attr_settings.h"
#include "ita/ita_attr_angel.h"
+#include "ita/ita_attr_symlinks.h"
#include "generic/generic_attr_string.h"
-ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_DEVICE_ID,
+ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_SYMLINKS,
"Command",
"Dummy",
"Get Settings",
"Start Angel",
"Stop Angel",
"Echo",
- "Device ID"
+ "Device ID",
+ "Get Symlinks",
+ "Symlinks"
);
/**
case ITA_ATTR_DEVICE_ID:
return generic_attr_string_create_from_data(length, value,
pen_type_create(PEN_ITA, type));
+ case ITA_ATTR_GET_SYMLINKS:
+ return generic_attr_string_create_from_data(length, value,
+ pen_type_create(PEN_ITA, type));
+ case ITA_ATTR_SYMLINKS:
+ return ita_attr_symlinks_create_from_data(length, value);
default:
return NULL;
}
/*
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
ITA_ATTR_START_ANGEL = 5,
ITA_ATTR_STOP_ANGEL = 6,
ITA_ATTR_ECHO = 7,
- ITA_ATTR_DEVICE_ID = 8
+ ITA_ATTR_DEVICE_ID = 8,
+ ITA_ATTR_GET_SYMLINKS = 9,
+ ITA_ATTR_SYMLINKS = 10
};
/**
--- /dev/null
+/*
+ * Copyright (C) 2020 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 "ita_attr_symlinks.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_ita_attr_symlinks_t private_ita_attr_symlinks_t;
+
+/**
+ * List of Symbolic Links pointing to Directories
+ *
+ * 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 Symlinks |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Symlink #1 Length | Symlink #1 Path (Var Len) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Symlink #1 Path (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Directory #1 Length | Directory #1 Path (Var Len) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Directory #1 Path (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Symlink #2 Length | Symlink #2 Path (Var Len) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Symlink #2 Path (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Directory #2 Length | Directory #2 Path (Var Len) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Directory #2 Path (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ...........................
+ */
+
+#define ITA_ATTR_SYMLINKS_SIZE 4
+
+/**
+ * Private data of an ita_attr_symlinks_t object.
+ */
+struct private_ita_attr_symlinks_t {
+
+ /**
+ * Public members of ita_attr_symlinks_t
+ */
+ ita_attr_symlinks_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;
+
+ /**
+ * Number of symbolic link entries
+ */
+ uint32_t count;
+
+ /**
+ * List of symbolic links
+ */
+ pts_symlinks_t *symlinks;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+};
+
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
+ private_ita_attr_symlinks_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_ita_attr_symlinks_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_ita_attr_symlinks_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_ita_attr_symlinks_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_ita_attr_symlinks_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ chunk_t symlink, dir;
+
+ if (this->value.ptr)
+ {
+ return;
+ }
+ this->count = this->symlinks->get_count(this->symlinks);
+
+ writer = bio_writer_create(ITA_ATTR_SYMLINKS_SIZE);
+ writer->write_uint32(writer, this->count);
+
+ enumerator = this->symlinks->create_enumerator(this->symlinks);
+ while (enumerator->enumerate(enumerator, &symlink, &dir))
+ {
+ writer->write_data16(writer, symlink);
+ writer->write_data16(writer, dir);
+ }
+ 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_ita_attr_symlinks_t *this, uint32_t *offset)
+{
+ bio_reader_t *reader;
+ chunk_t symlink, dir;
+ status_t status = NEED_MORE;
+
+ if (this->offset == 0)
+ {
+ if (this->length < ITA_ATTR_SYMLINKS_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_ITA,
+ ita_attr_names, this->type.type);
+ *offset = this->offset;
+ return FAILED;
+ }
+ if (this->value.len < ITA_ATTR_SYMLINKS_SIZE)
+ {
+ return NEED_MORE;
+ }
+ reader = bio_reader_create(this->value);
+ reader->read_uint32(reader, &this->count);
+ this->offset = ITA_ATTR_SYMLINKS_SIZE;
+ this->value = reader->peek(reader);
+ reader->destroy(reader);
+ }
+
+ this->symlinks = pts_symlinks_create();
+ reader = bio_reader_create(this->value);
+
+ while (this->count)
+ {
+ if (!reader->read_data16(reader, &symlink) ||
+ !reader->read_data16(reader, &dir))
+ {
+ goto end;
+ }
+ this->offset += this->value.len - reader->remaining(reader);
+ this->value = reader->peek(reader);
+ this->symlinks->add(this->symlinks, symlink, dir);
+ this->count--;
+ }
+
+ status = SUCCESS;
+
+ if (this->length != this->offset)
+ {
+ DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_ITA,
+ ita_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_ita_attr_symlinks_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_ita_attr_symlinks_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public.pa_tnc_attribute;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_ita_attr_symlinks_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ DESTROY_IF(this->symlinks);
+ free(this->segment.ptr);
+ free(this);
+ }
+}
+
+METHOD(ita_attr_symlinks_t, get_symlinks, pts_symlinks_t*,
+ private_ita_attr_symlinks_t *this)
+{
+ return this->symlinks;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ita_attr_symlinks_create(pts_symlinks_t *symlinks)
+{
+ private_ita_attr_symlinks_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_symlinks = _get_symlinks,
+ },
+ .type = { PEN_ITA, ITA_ATTR_SYMLINKS },
+ .symlinks = symlinks->get_ref(symlinks),
+ .ref = 1,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *ita_attr_symlinks_create_from_data(size_t length, chunk_t data)
+{
+ private_ita_attr_symlinks_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_symlinks = _get_symlinks,
+ },
+ .type = { PEN_ITA, ITA_ATTR_SYMLINKS },
+ .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;
+}
--- /dev/null
+/*
+ * Copyright (C) 2020 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 ita_attr_sysmlinks ita_attr_sysmlinks
+ * @{ @ingroup ita_attr
+ */
+
+#ifndef ITA_ATTR_SYMLINKS_H_
+#define ITA_ATTR_SYMLINKS_H_
+
+typedef struct ita_attr_symlinks_t ita_attr_symlinks_t;
+
+#include "ita/ita_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts_symlinks.h"
+
+/**
+ * Class implementing the ITA Symlinks attribute
+ *
+ */
+struct ita_attr_symlinks_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get list of symbolic links
+ *
+ * @return List of symbolic links pointing to directories
+ */
+ pts_symlinks_t* (*get_symlinks)(ita_attr_symlinks_t *this);
+
+};
+
+/**
+ * Creates an ita_attr_sysmlinks_t object
+ */
+pa_tnc_attr_t* ita_attr_symlinks_create(pts_symlinks_t *symlinks);
+
+/**
+ * Creates an ita_attr_sysmlinks_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* ita_attr_symlinks_create_from_data(size_t length, chunk_t value);
+
+#endif /** ITA_ATTR_SYMLINKS_H_ @}*/
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <ietf/ietf_attr_product_info.h>
#include <ietf/ietf_attr_string_version.h>
#include <ietf/ietf_attr_assess_result.h>
+#include <ita/ita_attr_symlinks.h>
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
#include <os_info/os_info.h>
break;
}
}
+ else if (type.vendor_id == PEN_ITA)
+ {
+ if (type.type == ITA_ATTR_GET_SYMLINKS)
+ {
+ pts_symlinks_t *symlinks;
+ chunk_t dir;
+ pts_t *pts;
+
+ dir = attr->get_value(attr);
+ attestation_state = (imc_attestation_state_t*)state;
+ pts = attestation_state->get_pts(attestation_state);
+ symlinks = pts->extract_symlinks(pts, dir);
+ if (symlinks)
+ {
+ attr = ita_attr_symlinks_create(symlinks);
+ out_msg->add_attribute(out_msg, attr);
+ }
+ }
+ }
}
enumerator->destroy(enumerator);
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2011-2015 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <ietf/ietf_attr_product_info.h>
#include <ietf/ietf_attr_string_version.h>
#include <ita/ita_attr.h>
+#include <ita/ita_attr_symlinks.h>
#include <tcg/tcg_attr.h>
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
#include <pts/pts.h>
#include <pts/pts_database.h>
#include <pts/pts_creds.h>
+#include <pts/pts_symlinks.h>
#include <pts/components/ita/ita_comp_func_name.h>
#include <tncif_pa_subtypes.h>
session->set_device_id(session, value);
break;
}
+ case ITA_ATTR_SYMLINKS:
+ {
+ imv_attestation_state_t *attestation_state;
+ ita_attr_symlinks_t *attr_cast;
+ pts_symlinks_t *symlinks;
+ pts_t *pts;
+
+ attr_cast = (ita_attr_symlinks_t*)attr;
+ symlinks = attr_cast->get_symlinks(attr_cast);
+ attestation_state = (imv_attestation_state_t*)state;
+ pts = attestation_state->get_pts(attestation_state);
+ pts->set_symlinks(pts, symlinks);
+ break;
+ }
default:
break;
}
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2011-2014 Andreas Steffen
+ * Copyright (C) 2011-2020 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
#include <tcg/pts/tcg_pts_attr_get_aik.h>
#include <tcg/pts/tcg_pts_attr_req_func_comp_evid.h>
#include <tcg/pts/tcg_pts_attr_gen_attest_evid.h>
+#include <generic/generic_attr_string.h>
+#include <ita/ita_attr.h>
#include <utils/debug.h>
if (attr)
{
+ /* Send Get Symlinks attribute */
+ out_msg->add_attribute(out_msg, generic_attr_string_create(
+ chunk_from_str("/"),
+ pen_type_create(PEN_ITA, ITA_ATTR_GET_SYMLINKS)));
+
/* Send Request Functional Component Evidence attribute */
out_msg->add_attribute(out_msg, attr);
* for more details.
*/
+#define _GNU_SOURCE
+#include <stdio.h>
+
#include "ita_comp_ima.h"
#include "ita_comp_func_name.h"
return hash_algo;
}
+/**
+ * Look up all hashes for a given file and OS in the database and check
+ * if one of them matches the IMA measurement
+ */
+static status_t verify_ima_measuremnt(pts_t *pts, pts_database_t *pts_db,
+ pts_meas_algorithms_t hash_algo,
+ pts_meas_algorithms_t algo,
+ bool pcr_padding, chunk_t measurement,
+ char* ima_algo, char* ima_name,
+ char *filename)
+{
+ status_t status = NOT_FOUND;
+ pts_meas_algorithms_t meas_algo;
+ uint8_t *hex_digest_buf;
+ uint8_t digest_buf[HASH_SIZE_SHA512];
+ uint8_t hash_buf[HASH_SIZE_SHA512];
+ size_t hash_size;
+ chunk_t hash, digest, hex_digest;
+ enumerator_t *e;
+
+ hash_size = pts_meas_algo_hash_size(algo);
+ hash = chunk_create(hash_buf, hash_size);
+
+ if (pcr_padding)
+ {
+ memset(hash_buf, 0x00, hash_size);
+ meas_algo = PTS_MEAS_ALGO_SHA1;
+ }
+ else
+ {
+ meas_algo = algo;
+ }
+
+ e = pts_db->create_file_meas_enumerator(pts_db, pts->get_platform_id(pts),
+ hash_algo, filename);
+ if (!e)
+ {
+ return FAILED;
+ }
+
+ while (e->enumerate(e, &hex_digest_buf))
+ {
+ hex_digest = chunk_from_str(hex_digest_buf);
+ digest = chunk_from_hex(hex_digest, digest_buf);
+
+ if (!pts_ima_event_hash(digest, ima_algo, ima_name, meas_algo, hash_buf))
+ {
+ status = FAILED;
+ break;
+ }
+ if (chunk_equals_const(measurement, hash))
+ {
+ status = SUCCESS;
+ break;
+ }
+ else
+ {
+ status = VERIFY_ERROR;
+ }
+ }
+ e->destroy(e);
+
+ return status;
+}
+
+/**
+ * Generate an alternative pathname based on symbolic link info
+ */
+static char* alternative_pathname(pts_t * pts, char *path)
+{
+ pts_symlinks_t *symlinks;
+ enumerator_t *enumerator;
+ chunk_t prefix1, prefix2;
+ char *alt_path = NULL;
+ size_t path_len = strlen(path);
+ int ret;
+
+ symlinks = pts->get_symlinks(pts);
+ if (!symlinks || symlinks->get_count(symlinks) == 0)
+ {
+ return NULL;
+ }
+
+ enumerator = symlinks->create_enumerator(symlinks);
+ while (enumerator->enumerate(enumerator, &prefix1, &prefix2))
+ {
+ /* replace prefix2 by prefix1*/
+ if (path_len > prefix2.len && path[prefix2.len] == '/' &&
+ memeq(path, prefix2.ptr, prefix2.len))
+ {
+ ret = asprintf(&alt_path, "%.*s%s", (int)prefix1.len, prefix1.ptr,
+ path + prefix2.len);
+ if (ret <= 0)
+ {
+ alt_path = NULL;
+ }
+ break;
+ }
+
+ /* replace prefix1 by prefix2 */
+ if (path_len > prefix1.len && path[prefix1.len] == '/' &&
+ memeq(path, prefix1.ptr, prefix1.len))
+ {
+ ret = asprintf(&alt_path, "%.*s%s", (int)prefix2.len, prefix2.ptr,
+ path + prefix1.len);
+ if (ret <= 0)
+ {
+ alt_path = NULL;
+ }
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return alt_path;
+}
+
METHOD(pts_component_t, verify, status_t,
pts_ita_comp_ima_t *this, uint8_t qualifier, pts_t *pts,
pts_comp_evidence_t *evidence)
break;
case IMA_STATE_RUNTIME:
{
- chunk_t hex_digest, digest, hash;
- uint8_t digest_buf[HASH_SIZE_SHA512], *hex_digest_buf;
- uint8_t hash_buf[HASH_SIZE_SHA512];
- size_t hash_size;
- pts_meas_algorithms_t meas_algo;
- enumerator_t *e;
-
this->count++;
+
if (evidence->get_validation(evidence, NULL) !=
PTS_COMP_EVID_VALIDATION_PASSED)
{
this->count_failed++;
return FAILED;
}
- hash_size = pts_meas_algo_hash_size(algo);
- hash = chunk_create(hash_buf, hash_size);
- if (this->pcr_padding)
- {
- memset(hash_buf, 0x00, hash_size);
- meas_algo = PTS_MEAS_ALGO_SHA1;
- }
- else
- {
- meas_algo = algo;
- }
+ status = verify_ima_measuremnt(pts, this->pts_db,
+ hash_algo, algo,
+ this->pcr_padding, measurement,
+ ima_algo, ima_name, ima_name);
- e = this->pts_db->create_file_meas_enumerator(this->pts_db,
- pts->get_platform_id(pts),
- hash_algo, ima_name);
- if (e)
+ if (status == NOT_FOUND || status == VERIFY_ERROR)
{
- while (e->enumerate(e, &hex_digest_buf))
- {
- hex_digest = chunk_from_str(hex_digest_buf);
- digest = chunk_from_hex(hex_digest, digest_buf);
+ status_t alt_status;
+ char *alt_path;
- if (!pts_ima_event_hash(digest, ima_algo, ima_name,
- meas_algo, hash_buf))
- {
- status = FAILED;
- break;
- }
- if (chunk_equals_const(measurement, hash))
- {
- status = SUCCESS;
- break;
- }
- else
+ alt_path = alternative_pathname(pts, ima_name);
+ if (alt_path)
+ {
+ alt_status = verify_ima_measuremnt(pts, this->pts_db,
+ hash_algo, algo,
+ this->pcr_padding, measurement,
+ ima_algo, ima_name, alt_path);
+ if (alt_status != NOT_FOUND)
{
- status = VERIFY_ERROR;
+ status = alt_status;
}
+ free(alt_path);
}
- e->destroy(e);
- }
- else
- {
- status = FAILED;
}
switch (status)
#include <sys/stat.h>
#include <libgen.h>
#include <unistd.h>
+#include <dirent.h>
#include <errno.h>
+
#ifndef TPM_TAG_QUOTE_INFO2
#define TPM_TAG_QUOTE_INFO2 0x0036
#endif
*/
int platform_id;
+ /**
+ * List of directory symlinks received from IMC
+ */
+ pts_symlinks_t *symlinks;
+
/**
* TRUE if IMC-PTS, FALSE if IMV-PTS
*/
this->platform_id = pid;
}
+METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
+ private_pts_t *this, chunk_t pathname)
+{
+#ifndef WIN32
+ char path[BUF_LEN], real_path[BUF_LEN];
+ size_t path_len, real_path_len;
+ struct dirent *entry;
+ struct stat st;
+ DIR *dir;
+
+ /* open directory and prepare pathnames */
+ snprintf(path, BUF_LEN-1, "%.*s", (int)pathname.len, pathname.ptr);
+ dir = opendir(path);
+ if (!dir)
+ {
+ DBG1(DBG_PTS, "opening directory '%s' failed: %s", path,
+ strerror(errno));
+ return NULL;
+ }
+ if (pathname.len == 1 && path[0] == '/')
+ {
+ path_len = 1;
+ }
+ else
+ {
+ path[pathname.len] = '/';
+ path_len = pathname.len + 1;
+ }
+ real_path[0] = '/';
+
+ /* symlinks object is owned by pts object */
+ DESTROY_IF(this->symlinks);
+ this->symlinks = pts_symlinks_create();
+
+ while (TRUE)
+ {
+
+ entry = readdir(dir);
+ if (!entry)
+ {
+ /* no more entries -> exit */
+ break;
+ }
+ if (streq(entry->d_name, ".") || streq(entry->d_name, ".."))
+ {
+ continue;
+ }
+
+ /* assemble absolute path */
+ snprintf(path + path_len, BUF_LEN - path_len, "%s", entry->d_name);
+
+ /* only evaluate symlinks pointing to directories */
+ if (lstat(path, &st) == -1 || !S_ISLNK(st.st_mode) ||
+ stat(path, &st) == -1 || !S_ISDIR(st.st_mode))
+ {
+ continue;
+ }
+
+ real_path_len = readlink(path, real_path + 1, BUF_LEN - 1);
+ if (real_path_len <= 0)
+ {
+ continue;
+ }
+ this->symlinks->add(this->symlinks, chunk_from_str(path),
+ chunk_create(real_path, 1 + real_path_len));
+ }
+ closedir(dir);
+#endif
+
+ return this->symlinks;
+}
+
+
+METHOD(pts_t, get_symlinks, pts_symlinks_t*,
+ private_pts_t *this)
+{
+ return this->symlinks;
+}
+
+METHOD(pts_t, set_symlinks, void,
+ private_pts_t *this, pts_symlinks_t *symlinks)
+{
+ enumerator_t *enumerator;
+ chunk_t symlink, dir;
+
+ DESTROY_IF(this->symlinks);
+ this->symlinks = symlinks->get_ref(symlinks);
+
+ DBG2(DBG_PTS, "adding directory symlinks:");
+ enumerator = symlinks->create_enumerator(symlinks);
+ while (enumerator->enumerate(enumerator, &symlink, &dir))
+ {
+ DBG2(DBG_PTS, " %.*s -> %.*s", (int)symlink.len, symlink.ptr,
+ (int)dir.len, dir.ptr);
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(pts_t, get_tpm, tpm_tss_t*,
private_pts_t *this)
{
{
DBG2(DBG_PTS, "%s 1.2 rev. %u.%u.%u.%u %.*s", TPM_VERSION_INFO_LABEL,
(uint32_t)major, (uint32_t)minor, (uint32_t)rev_major,
- (uint32_t)rev_minor, vendor.len, vendor.ptr);
+ (uint32_t)rev_minor, (int)vendor.len, vendor.ptr);
}
else
{
{
DBG2(DBG_PTS, "%s 2.0 rev. %4.2f %u %.*s - startup locality: %u",
TPM_VERSION_INFO_LABEL, revision/100.0, year,
- vendor.len, vendor.ptr, (uint32_t)locality);
+ (int)vendor.len, vendor.ptr, (uint32_t)locality);
}
else
{
DESTROY_IF(this->pcrs);
DESTROY_IF(this->aik_cert);
DESTROY_IF(this->dh);
+ DESTROY_IF(this->symlinks);
free(this->initiator_nonce.ptr);
free(this->responder_nonce.ptr);
free(this->secret.ptr);
.calculate_secret = _calculate_secret,
.get_platform_id = _get_platform_id,
.set_platform_id = _set_platform_id,
+ .extract_symlinks = _extract_symlinks,
+ .get_symlinks = _get_symlinks,
+ .set_symlinks = _set_symlinks,
.get_tpm = _get_tpm,
.get_tpm_version_info = _get_tpm_version_info,
.set_tpm_version_info = _set_tpm_version_info,
#include "pts_dh_group.h"
#include "pts_pcr.h"
#include "pts_req_func_comp_evid.h"
+#include "pts_symlinks.h"
#include "components/pts_comp_func_name.h"
#include <tpm_tss_quote_info.h>
*/
void (*set_platform_id)(pts_t *this, int pid);
+ /**
+ * Extract all directory symlinks contained in a directory
+ *
+ * @param pathname Absolute pathname of directory
+ * @return List of directory symlinks
+ */
+ pts_symlinks_t* (*extract_symlinks)(pts_t *this, chunk_t pathname);
+
+ /**
+ * Get list of directory symlinks received from IMC
+ *
+ * @return List of symbolic links
+ */
+ pts_symlinks_t* (*get_symlinks)(pts_t *this);
+
+ /**
+ * Set list of directory symlinks received from IMC
+ *
+ * @param symlinks List of symbolic links
+ */
+ void (*set_symlinks)(pts_t *this, pts_symlinks_t *symlinks);
+
+
/**
* Get TPM object handle
*
--- /dev/null
+/*
+ * Copyright (C) 2020 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 "pts_symlinks.h"
+
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_pts_symlinks_t private_pts_symlinks_t;
+typedef struct entry_t entry_t;
+
+/**
+ * Private data of a pts_symlinks_t object.
+ *
+ */
+struct private_pts_symlinks_t {
+
+ /**
+ * Public pts_symlinks_t interface.
+ */
+ pts_symlinks_t public;
+
+ /**
+ * List of symbolic links pointing to directories
+ */
+ linked_list_t *list;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+
+};
+
+/**
+ * Symlink entry
+ */
+struct entry_t {
+ chunk_t symlink;
+ chunk_t dir;
+};
+
+/**
+ * Free an entry_t object
+ */
+static void free_entry(entry_t *entry)
+{
+ if (entry)
+ {
+ free(entry->symlink.ptr);
+ free(entry->dir.ptr);
+ free(entry);
+ }
+}
+
+METHOD(pts_symlinks_t, get_count, int,
+ private_pts_symlinks_t *this)
+{
+ return this->list->get_count(this->list);
+}
+
+METHOD(pts_symlinks_t, add, void,
+ private_pts_symlinks_t *this, chunk_t symlink, chunk_t dir)
+{
+ entry_t *entry;
+
+ entry = malloc_thing(entry_t);
+ entry->symlink = chunk_clone(symlink);
+ entry->dir = chunk_clone(dir);
+
+ this->list->insert_last(this->list, entry);
+}
+
+CALLBACK(symlink_filter, bool,
+ void *null, enumerator_t *orig, va_list args)
+{
+ entry_t *entry;
+ chunk_t *symlink;
+ chunk_t *dir;
+
+ VA_ARGS_VGET(args, symlink, dir);
+
+ if (orig->enumerate(orig, &entry))
+ {
+ *symlink = entry->symlink;
+ *dir = entry->dir;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(pts_symlinks_t, create_enumerator, enumerator_t*,
+ private_pts_symlinks_t *this)
+{
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ symlink_filter, NULL, NULL);
+}
+
+METHOD(pts_symlinks_t, get_ref, pts_symlinks_t*,
+ private_pts_symlinks_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
+METHOD(pts_symlinks_t, destroy, void,
+ private_pts_symlinks_t *this)
+{
+ if (ref_put(&this->ref))
+ {
+ this->list->destroy_function(this->list, (void *)free_entry);
+ free(this);
+ }
+}
+
+/**
+ * See header
+ */
+pts_symlinks_t *pts_symlinks_create()
+{
+ private_pts_symlinks_t *this;
+
+ INIT(this,
+ .public = {
+ .get_count = _get_count,
+ .add = _add,
+ .create_enumerator = _create_enumerator,
+ .get_ref = _get_ref,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ .ref = 1,
+ );
+
+ return &this->public;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2020 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 pts_symlinks pts_symlinks
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_SYMLINKS_H_
+#define PTS_SYMLINKS_H_
+
+#include <library.h>
+
+typedef struct pts_symlinks_t pts_symlinks_t;
+
+
+/**
+ * Class storing a list of symbolic links pointing to directories
+ */
+struct pts_symlinks_t {
+
+ /**
+ * Get the number of symbolic link entries
+ *
+ * @return Number of symbolic links
+ */
+ int (*get_count)(pts_symlinks_t *this);
+
+ /**
+ * Add a symbolic link pointing to a directory
+ *
+ * @param symlink Pathname of symbolic link
+ * @param dir Pathname of directory the symlink points to
+ */
+ void (*add)(pts_symlinks_t *this, chunk_t symlink, chunk_t dir);
+
+ /**
+ * Create a symlink enumerator
+ *
+ * @return Enumerator returning (chunk_t symlink, chunk_t dir)
+ */
+ enumerator_t* (*create_enumerator)(pts_symlinks_t *this);
+
+ /**
+ * Get a new reference to the list of symbolic links
+ *
+ * @return this, with an increased refcount
+ */
+ pts_symlinks_t* (*get_ref)(pts_symlinks_t *this);
+
+
+ /**
+ * Destroys a pts_symlinks_t object.
+ */
+ void (*destroy)(pts_symlinks_t *this);
+
+};
+
+/**
+ * Creates a pts_symlinks_t object
+ */
+pts_symlinks_t* pts_symlinks_create();
+
+#endif /** PTS_SYMLINKS_H_ @}*/