summaryrefslogtreecommitdiff
path: root/src/libpts/pts/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpts/pts/components')
-rw-r--r--src/libpts/pts/components/ita/ita_comp_func_name.c45
-rw-r--r--src/libpts/pts/components/ita/ita_comp_func_name.h85
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.c439
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.h36
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.c335
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.h36
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.c184
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.h36
-rw-r--r--src/libpts/pts/components/pts_comp_evidence.c251
-rw-r--r--src/libpts/pts/components/pts_comp_evidence.h170
-rw-r--r--src/libpts/pts/components/pts_comp_func_name.c152
-rw-r--r--src/libpts/pts/components/pts_comp_func_name.h96
-rw-r--r--src/libpts/pts/components/pts_component.h94
-rw-r--r--src/libpts/pts/components/pts_component_manager.c317
-rw-r--r--src/libpts/pts/components/pts_component_manager.h125
-rw-r--r--src/libpts/pts/components/tcg/tcg_comp_func_name.c48
-rw-r--r--src/libpts/pts/components/tcg/tcg_comp_func_name.h98
17 files changed, 2547 insertions, 0 deletions
diff --git a/src/libpts/pts/components/ita/ita_comp_func_name.c b/src/libpts/pts/components/ita/ita_comp_func_name.c
new file mode 100644
index 000000000..a593281ba
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_func_name.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 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_comp_func_name.h"
+
+char pts_ita_qualifier_flag_names[] = { 'K', 'S' };
+
+ENUM_BEGIN(pts_ita_qualifier_type_names, PTS_ITA_QUALIFIER_TYPE_UNKNOWN,
+ PTS_ITA_QUALIFIER_TYPE_TNC,
+ "Unknown",
+ "Trusted Platform",
+ "Operating System",
+ "Graphical User Interface",
+ "Application",
+ "Networking",
+ "Library",
+ "TNC Defined Component"
+);
+ENUM_NEXT(pts_ita_qualifier_type_names, PTS_ITA_QUALIFIER_TYPE_ALL,
+ PTS_ITA_QUALIFIER_TYPE_ALL,
+ PTS_ITA_QUALIFIER_TYPE_TNC,
+ "All Matching Components"
+);
+ENUM_END(pts_ita_qualifier_type_names, PTS_ITA_QUALIFIER_TYPE_ALL);
+
+ENUM(pts_ita_comp_func_names, PTS_ITA_COMP_FUNC_NAME_IGNORE,
+ PTS_ITA_COMP_FUNC_NAME_IMA,
+ "Ignore",
+ "Trusted GRUB Boot Loader",
+ "Trusted Boot",
+ "Linux IMA"
+);
+
diff --git a/src/libpts/pts/components/ita/ita_comp_func_name.h b/src/libpts/pts/components/ita/ita_comp_func_name.h
new file mode 100644
index 000000000..eb2f363f3
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_func_name.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_FUNC_NAME_H_
+#define PTS_ITA_COMP_FUNC_NAME_H_
+
+typedef enum pts_ita_qualifier_type_t pts_ita_qualifier_type_t;
+typedef enum pts_ita_comp_func_name_t pts_ita_comp_func_name_t;
+
+#include <library.h>
+
+/**
+ * PTS Component Functional Name Qualifier Flags for the ITA namespace
+ */
+#define PTS_ITA_QUALIFIER_FLAG_KERNEL (1<<5)
+#define PTS_ITA_QUALIFIER_FLAG_SUB (1<<4)
+
+extern char pts_ita_qualifier_flag_names[];
+
+/**
+ * Size of the PTS Component Functional Name Qualifier Type field
+ */
+#define PTS_ITA_QUALIFIER_TYPE_SIZE 4
+
+/**
+ * PTS Component Functional Name Qualifier Types for the ITA namespace
+ * equal to section 5.2 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_ita_qualifier_type_t {
+ /** Unknown */
+ PTS_ITA_QUALIFIER_TYPE_UNKNOWN = 0x0,
+ /** Trusted Platform */
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED = 0x1,
+ /** Operating System */
+ PTS_ITA_QUALIFIER_TYPE_OS = 0x2,
+ /** Graphical User Interface */
+ PTS_ITA_QUALIFIER_TYPE_GUI = 0x3,
+ /** Application */
+ PTS_ITA_QUALIFIER_TYPE_APP = 0x4,
+ /** Networking */
+ PTS_ITA_QUALIFIER_TYPE_NET = 0x5,
+ /** Library */
+ PTS_ITA_QUALIFIER_TYPE_LIB = 0x6,
+ /** TNC Defined Component */
+ PTS_ITA_QUALIFIER_TYPE_TNC = 0x7,
+ /** All Matching Components */
+ PTS_ITA_QUALIFIER_TYPE_ALL = 0xF,
+};
+
+extern enum_name_t *pts_ita_qualifier_type_names;
+
+/**
+ * PTS Component Functional Name Binary Enumeration for the ITA namespace
+ */
+enum pts_ita_comp_func_name_t {
+ /** Ignore */
+ PTS_ITA_COMP_FUNC_NAME_IGNORE = 0x0000,
+ /** Trusted GRUB Boot Loader */
+ PTS_ITA_COMP_FUNC_NAME_TGRUB = 0x0001,
+ /** Trusted Boot */
+ PTS_ITA_COMP_FUNC_NAME_TBOOT = 0x0002,
+ /** Linux Integrity Measurement Architecture */
+ PTS_ITA_COMP_FUNC_NAME_IMA = 0x0003,
+};
+
+extern enum_name_t *pts_ita_comp_func_names;
+
+#endif /** PTS_ITA_COMP_FUNC_NAME_H_ @}*/
diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c
new file mode 100644
index 000000000..a7da76651
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_ima.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2011 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_comp_ima.h"
+#include "ita_comp_func_name.h"
+
+#include "libpts.h"
+#include "pts/components/pts_component.h"
+
+#include <debug.h>
+#include <pen/pen.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define IMA_SECURITY_DIR "/sys/kernel/security/tpm0/"
+#define IMA_BIOS_MEASUREMENT_PATH IMA_SECURITY_DIR "binary_bios_measurements"
+#define IMA_PCR_MAX 16
+
+typedef struct pts_ita_comp_ima_t pts_ita_comp_ima_t;
+
+/**
+ * Private data of a pts_ita_comp_ima_t object.
+ *
+ */
+struct pts_ita_comp_ima_t {
+
+ /**
+ * Public pts_component_t interface.
+ */
+ pts_component_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * AIK keyid
+ */
+ chunk_t keyid;
+
+ /**
+ * Sub-component depth
+ */
+ u_int32_t depth;
+
+ /**
+ * PTS measurement database
+ */
+ pts_database_t *pts_db;
+
+ /**
+ * Primary key for Component Functional Name database entry
+ */
+ int cid;
+
+ /**
+ * Primary key for AIK database entry
+ */
+ int kid;
+
+ /**
+ * Component is registering measurements
+ */
+ bool is_registering;
+
+ /**
+ * IMA BIOS measurement time
+ */
+ time_t bios_measurement_time;
+
+ /**
+ * IMA BIOS measurements
+ */
+ linked_list_t *list;
+
+ /**
+ * Expected measurement count
+ */
+ int count;
+
+ /**
+ * Measurement sequence number
+ */
+ int seq_no;
+
+ /**
+ * Shadow PCR registers
+ */
+ chunk_t pcrs[IMA_PCR_MAX];
+};
+
+typedef struct entry_t entry_t;
+
+/**
+ * Linux IMA measurement entry
+ */
+struct entry_t {
+
+ /**
+ * PCR register
+ */
+ u_int32_t pcr;
+
+ /**
+ * SHA1 measurement hash
+ */
+ chunk_t measurement;
+};
+
+/**
+ * Free an entry_t object
+ */
+static void free_entry(entry_t *this)
+{
+ free(this->measurement.ptr);
+ free(this);
+}
+
+/**
+ * Load a PCR measurement file and determine the creation date
+ */
+static bool load_measurements(char *file, linked_list_t *list, time_t *created)
+{
+ u_int32_t pcr, num, len;
+ entry_t *entry;
+ struct stat st;
+ ssize_t res;
+ int fd;
+
+ fd = open(file, O_RDONLY);
+ if (fd == -1)
+ {
+ DBG1(DBG_PTS, " opening '%s' failed: %s", file, strerror(errno));
+ return FALSE;
+ }
+
+ if (fstat(fd, &st) == -1)
+ {
+ DBG1(DBG_PTS, " getting statistics of '%s' failed: %s", file,
+ strerror(errno));
+ close(fd);
+ return FALSE;
+ }
+ *created = st.st_ctime;
+
+ while (TRUE)
+ {
+ res = read(fd, &pcr, 4);
+ if (res == 0)
+ {
+ DBG2(DBG_PTS, "loaded bios measurements '%s' (%d entries)",
+ file, list->get_count(list));
+ close(fd);
+ return TRUE;
+ }
+
+ entry = malloc_thing(entry_t);
+ entry->pcr = pcr;
+ entry->measurement = chunk_alloc(HASH_SIZE_SHA1);
+
+ if (res != 4)
+ {
+ break;
+ }
+ if (read(fd, &num, 4) != 4)
+ {
+ break;
+ }
+ if (read(fd, entry->measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1)
+ {
+ break;
+ }
+ if (read(fd, &len, 4) != 4)
+ {
+ break;
+ }
+ if (lseek(fd, len, SEEK_CUR) == -1)
+ {
+ break;
+ }
+ list->insert_last(list, entry);
+ }
+
+ DBG1(DBG_PTS, "loading bios measurements '%s' failed: %s",
+ file, strerror(errno));
+ close(fd);
+ return FALSE;
+}
+
+METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
+ pts_ita_comp_ima_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_component_t, get_evidence_flags, u_int8_t,
+ pts_ita_comp_ima_t *this)
+{
+ return PTS_REQ_FUNC_COMP_EVID_PCR;
+}
+
+METHOD(pts_component_t, get_depth, u_int32_t,
+ pts_ita_comp_ima_t *this)
+{
+ return this->depth;
+}
+
+METHOD(pts_component_t, measure, status_t,
+ pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+{
+ pts_comp_evidence_t *evid;
+ chunk_t pcr_before, pcr_after;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+ size_t pcr_len;
+ entry_t *entry;
+ hasher_t *hasher;
+
+ hash_algo = PTS_MEAS_ALGO_SHA1;
+ pcr_len = pts->get_pcr_len(pts);
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ if (this->list->get_count(this->list) == 0)
+ {
+ if (!load_measurements(IMA_BIOS_MEASUREMENT_PATH, this->list,
+ &this->bios_measurement_time))
+ {
+ return FAILED;
+ }
+ }
+
+ if (this->list->remove_first(this->list, (void**)&entry) != SUCCESS)
+ {
+ DBG1(DBG_PTS, "could not retrieve measurement entry");
+ return FAILED;
+ }
+
+ pcr_before = chunk_clone(this->pcrs[entry->pcr]);
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ hasher->get_hash(hasher, pcr_before, NULL);
+ hasher->get_hash(hasher, entry->measurement, this->pcrs[entry->pcr].ptr);
+ hasher->destroy(hasher);
+
+ pcr_after = chunk_clone(this->pcrs[entry->pcr]);
+
+ evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, entry->pcr, hash_algo, pcr_transform,
+ this->bios_measurement_time, entry->measurement);
+ evid->set_pcr_info(evid, pcr_before, pcr_after);
+
+ free(entry);
+
+ return (this->list->get_count(this->list)) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, verify, status_t,
+ pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+{
+ bool has_pcr_info;
+ u_int32_t extended_pcr, vid, name;
+ enum_name_t *names;
+ pts_meas_algorithms_t algo;
+ pts_pcr_transform_t transform;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+
+ measurement = evidence->get_measurement(evidence, &extended_pcr,
+ &algo, &transform, &measurement_time);
+
+ if (!this->keyid.ptr)
+ {
+ if (!pts->get_aik_keyid(pts, &this->keyid))
+ {
+ return FAILED;
+ }
+ this->keyid = chunk_clone(this->keyid);
+
+ if (!this->pts_db)
+ {
+ DBG1(DBG_PTS, "pts database not available");
+ return FAILED;
+ }
+ if (this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo,
+ &this->cid, &this->kid, &this->count) != SUCCESS)
+ {
+ return FAILED;
+ }
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+
+ if (this->count)
+ {
+ DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence "
+ "measurements", this->count, pen_names, vid, names, name);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
+ "measurements", pen_names, vid, names, name);
+ this->is_registering = TRUE;
+ }
+ }
+
+ if (this->is_registering)
+ {
+ if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ this->count = this->seq_no + 1;
+ }
+ else
+ {
+ if (this->pts_db->check_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ }
+
+ has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
+ if (has_pcr_info)
+ {
+ if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+ {
+ return FAILED;
+ }
+ }
+
+ return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, check_off_registrations, bool,
+ pts_ita_comp_ima_t *this)
+{
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ if (!this->is_registering)
+ {
+ return FALSE;
+ }
+
+ /* Finalize registration */
+ this->is_registering = FALSE;
+
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "registered %d %N '%N' functional component evidence "
+ "measurements", this->seq_no, pen_names, vid, names, name);
+ return TRUE;
+}
+
+METHOD(pts_component_t, destroy, void,
+ pts_ita_comp_ima_t *this)
+{
+ int i, count;
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ for (i = 0; i < IMA_PCR_MAX; i++)
+ {
+ free(this->pcrs[i].ptr);
+ }
+ if (this->is_registering)
+ {
+ count = this->pts_db->delete_comp_measurements(this->pts_db,
+ this->cid, this->kid);
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
+ "evidence measurements", count, pen_names, vid, names, name);
+ }
+ this->list->destroy_function(this->list, (void *)free_entry);
+ this->name->destroy(this->name);
+ free(this->keyid.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db)
+{
+ pts_ita_comp_ima_t *this;
+ int i;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_evidence_flags = _get_evidence_flags,
+ .get_depth = _get_depth,
+ .measure = _measure,
+ .verify = _verify,
+ .check_off_registrations = _check_off_registrations,
+ .destroy = _destroy,
+ },
+ .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_IMA,
+ qualifier),
+ .depth = depth,
+ .pts_db = pts_db,
+ .list = linked_list_create(),
+ );
+
+ for (i = 0; i < IMA_PCR_MAX; i++)
+ {
+ this->pcrs[i] = chunk_alloc(HASH_SIZE_SHA1);
+ memset(this->pcrs[i].ptr, 0x00, HASH_SIZE_SHA1);
+ }
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/ita/ita_comp_ima.h b/src/libpts/pts/components/ita/ita_comp_ima.h
new file mode 100644
index 000000000..1ca27e6f0
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_ima.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_IMA_H_
+#define PTS_ITA_COMP_IMA_H_
+
+#include "pts/components/pts_component.h"
+
+/**
+ * Create a PTS ITS Functional Component object
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @param depth Sub-component depth
+ * @param pts_db PTS measurement database
+ */
+pts_component_t* pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db);
+
+#endif /** PTS_ITA_COMP_IMA_H_ @}*/
diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c
new file mode 100644
index 000000000..a85de8cd8
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2011 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_comp_tboot.h"
+#include "ita_comp_func_name.h"
+
+#include "libpts.h"
+#include "pts/components/pts_component.h"
+
+#include <debug.h>
+#include <pen/pen.h>
+
+typedef struct pts_ita_comp_tboot_t pts_ita_comp_tboot_t;
+
+/**
+ * Private data of a pts_ita_comp_tboot_t object.
+ *
+ */
+struct pts_ita_comp_tboot_t {
+
+ /**
+ * Public pts_component_t interface.
+ */
+ pts_component_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * AIK keyid
+ */
+ chunk_t keyid;
+
+ /**
+ * Sub-component depth
+ */
+ u_int32_t depth;
+
+ /**
+ * PTS measurement database
+ */
+ pts_database_t *pts_db;
+
+ /**
+ * Primary key for Component Functional Name database entry
+ */
+ int cid;
+
+ /**
+ * Primary key for AIK database entry
+ */
+ int kid;
+
+ /**
+ * Component is registering measurements
+ */
+ bool is_registering;
+
+ /**
+ * Time of TBOOT measurement
+ */
+ time_t measurement_time;
+
+ /**
+ * Expected measurement count
+ */
+ int count;
+
+ /**
+ * Measurement sequence number
+ */
+ int seq_no;
+
+};
+
+METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
+ pts_ita_comp_tboot_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_component_t, get_evidence_flags, u_int8_t,
+ pts_ita_comp_tboot_t *this)
+{
+ return PTS_REQ_FUNC_COMP_EVID_PCR;
+}
+
+METHOD(pts_component_t, get_depth, u_int32_t,
+ pts_ita_comp_tboot_t *this)
+{
+ return this->depth;
+}
+
+METHOD(pts_component_t, measure, status_t,
+ pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+{
+ pts_comp_evidence_t *evid;
+ char *meas_hex, *pcr_before_hex, *pcr_after_hex;
+ chunk_t measurement, pcr_before, pcr_after;
+ size_t hash_size, pcr_len;
+ u_int32_t extended_pcr;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+
+ switch (this->seq_no++)
+ {
+ case 0:
+ /* dummy data since currently the TBOOT log is not retrieved */
+ time(&this->measurement_time);
+ meas_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr17_meas", NULL);
+ pcr_before_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr17_before", NULL);
+ pcr_after_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr17_after", NULL);
+ extended_pcr = PCR_TBOOT_POLICY;
+ break;
+ case 1:
+ /* dummy data since currently the TBOOT log is not retrieved */
+ meas_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr18_meas", NULL);
+ pcr_before_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr18_before", NULL);
+ pcr_after_hex = lib->settings->get_str(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr18_after", NULL);
+ extended_pcr = PCR_TBOOT_MLE;
+ break;
+ default:
+ return FAILED;
+ }
+
+ if (meas_hex == NULL || pcr_before_hex == NULL || pcr_after_hex == NULL)
+ {
+ return FAILED;
+ }
+
+ hash_algo = pts->get_meas_algorithm(pts);
+ hash_size = pts_meas_algo_hash_size(hash_algo);
+ pcr_len = pts->get_pcr_len(pts);
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ /* get and check the measurement data */
+ measurement = chunk_from_hex(
+ chunk_create(meas_hex, strlen(meas_hex)), NULL);
+ pcr_before = chunk_from_hex(
+ chunk_create(pcr_before_hex, strlen(pcr_before_hex)), NULL);
+ pcr_after = chunk_from_hex(
+ chunk_create(pcr_after_hex, strlen(pcr_after_hex)), NULL);
+ if (pcr_before.len != pcr_len || pcr_after.len != pcr_len ||
+ measurement.len != hash_size)
+ {
+ DBG1(DBG_PTS, "TBOOT measurement or pcr data have the wrong size");
+ free(measurement.ptr);
+ free(pcr_before.ptr);
+ free(pcr_after.ptr);
+ return FAILED;
+ }
+
+ evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, extended_pcr,
+ hash_algo, pcr_transform,
+ this->measurement_time, measurement);
+ evid->set_pcr_info(evid, pcr_before, pcr_after);
+
+ return (this->seq_no < 2) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, verify, status_t,
+ pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+{
+ bool has_pcr_info;
+ u_int32_t extended_pcr, vid, name;
+ enum_name_t *names;
+ pts_meas_algorithms_t algo;
+ pts_pcr_transform_t transform;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+
+ measurement = evidence->get_measurement(evidence, &extended_pcr,
+ &algo, &transform, &measurement_time);
+
+ if (!this->keyid.ptr)
+ {
+ if (!pts->get_aik_keyid(pts, &this->keyid))
+ {
+ return FAILED;
+ }
+ this->keyid = chunk_clone(this->keyid);
+
+ if (!this->pts_db)
+ {
+ DBG1(DBG_PTS, "pts database not available");
+ return FAILED;
+ }
+ if (this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo,
+ &this->cid, &this->kid, &this->count) != SUCCESS)
+ {
+ return FAILED;
+ }
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+
+ if (this->count)
+ {
+ DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence "
+ "measurements", this->count, pen_names, vid, names, name);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
+ "measurements", pen_names, vid, names, name);
+ this->is_registering = TRUE;
+ }
+ }
+
+ if (this->is_registering)
+ {
+ if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ this->count = this->seq_no + 1;
+ }
+ else
+ {
+ if (this->pts_db->check_comp_measurement(this->pts_db, measurement,
+ this->cid, this->kid, ++this->seq_no,
+ extended_pcr, algo) != SUCCESS)
+ {
+ return FAILED;
+ }
+ }
+
+ has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
+ if (has_pcr_info)
+ {
+ if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+ {
+ return FAILED;
+ }
+ }
+
+ return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+}
+
+METHOD(pts_component_t, check_off_registrations, bool,
+ pts_ita_comp_tboot_t *this)
+{
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ if (!this->is_registering)
+ {
+ return FALSE;
+ }
+
+ /* Finalize registration */
+ this->is_registering = FALSE;
+
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "registered %d %N '%N' functional component evidence "
+ "measurements", this->seq_no, pen_names, vid, names, name);
+ return TRUE;
+}
+
+METHOD(pts_component_t, destroy, void,
+ pts_ita_comp_tboot_t *this)
+{
+ int count;
+ u_int32_t vid, name;
+ enum_name_t *names;
+
+ if (this->is_registering)
+ {
+ count = this->pts_db->delete_comp_measurements(this->pts_db,
+ this->cid, this->kid);
+ vid = this->name->get_vendor_id(this->name);
+ name = this->name->get_name(this->name);
+ names = pts_components->get_comp_func_names(pts_components, vid);
+ DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
+ "evidence measurements", count, pen_names, vid, names, name);
+ }
+ this->name->destroy(this->name);
+ free(this->keyid.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db)
+{
+ pts_ita_comp_tboot_t *this;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_evidence_flags = _get_evidence_flags,
+ .get_depth = _get_depth,
+ .measure = _measure,
+ .verify = _verify,
+ .check_off_registrations = _check_off_registrations,
+ .destroy = _destroy,
+ },
+ .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TBOOT,
+ qualifier),
+ .depth = depth,
+ .pts_db = pts_db,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.h b/src/libpts/pts/components/ita/ita_comp_tboot.h
new file mode 100644
index 000000000..39554fbc7
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_TBOOT_H_
+#define PTS_ITA_COMP_TBOOT_H_
+
+#include "pts/components/pts_component.h"
+
+/**
+ * Create a PTS ITS Functional Component object
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @param depth Sub-component depth
+ * @param pts_db PTS measurement database
+ */
+pts_component_t* pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db);
+
+#endif /** PTS_ITA_COMP_TBOOT_H_ @}*/
diff --git a/src/libpts/pts/components/ita/ita_comp_tgrub.c b/src/libpts/pts/components/ita/ita_comp_tgrub.c
new file mode 100644
index 000000000..0dfd5fd41
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2011 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_comp_tgrub.h"
+#include "ita_comp_func_name.h"
+
+#include "pts/components/pts_component.h"
+
+#include <debug.h>
+#include <pen/pen.h>
+
+typedef struct pts_ita_comp_tgrub_t pts_ita_comp_tgrub_t;
+
+/**
+ * Private data of a pts_ita_comp_tgrub_t object.
+ *
+ */
+struct pts_ita_comp_tgrub_t {
+
+ /**
+ * Public pts_component_t interface.
+ */
+ pts_component_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * Sub-component depth
+ */
+ u_int32_t depth;
+
+ /**
+ * PTS measurement database
+ */
+ pts_database_t *pts_db;
+
+};
+
+METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
+ pts_ita_comp_tgrub_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_component_t, get_evidence_flags, u_int8_t,
+ pts_ita_comp_tgrub_t *this)
+{
+ return PTS_REQ_FUNC_COMP_EVID_PCR;
+}
+
+METHOD(pts_component_t, get_depth, u_int32_t,
+ pts_ita_comp_tgrub_t *this)
+{
+ return this->depth;
+}
+
+METHOD(pts_component_t, measure, status_t,
+ pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+{
+ pts_comp_evidence_t *evid;
+ u_int32_t extended_pcr;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+ size_t hash_size, pcr_len;
+
+ /* Provisional implementation for TGRUB */
+ extended_pcr = PCR_DEBUG;
+ time(&measurement_time);
+
+ if (!pts->read_pcr(pts, extended_pcr, &pcr_after))
+ {
+ DBG1(DBG_PTS, "error occurred while reading PCR: %d", extended_pcr);
+ return FAILED;
+ }
+
+ hash_algo = pts->get_meas_algorithm(pts);
+ hash_size = pts_meas_algo_hash_size(hash_algo);
+ pcr_len = pts->get_pcr_len(pts);
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ measurement = chunk_alloc(hash_size);
+ memset(measurement.ptr, 0x00, measurement.len);
+
+ pcr_before = chunk_alloc(pcr_len);
+ memset(pcr_before.ptr, 0x00, pcr_before.len);
+
+ evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, extended_pcr,
+ hash_algo, pcr_transform,
+ measurement_time, measurement);
+ evid->set_pcr_info(evid, pcr_before, pcr_after);
+
+ return SUCCESS;
+}
+
+METHOD(pts_component_t, verify, status_t,
+ pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+{
+ bool has_pcr_info;
+ u_int32_t extended_pcr;
+ pts_meas_algorithms_t algo;
+ pts_pcr_transform_t transform;
+ time_t measurement_time;
+ chunk_t measurement, pcr_before, pcr_after;
+
+ measurement = evidence->get_measurement(evidence, &extended_pcr,
+ &algo, &transform, &measurement_time);
+ if (extended_pcr != PCR_DEBUG)
+ {
+ return FAILED;
+ }
+
+ /* TODO check measurement in database */
+
+ has_pcr_info = evidence->get_pcr_info(evidence, &pcr_before, &pcr_after);
+ if (has_pcr_info)
+ {
+ if (!pts->add_pcr(pts, extended_pcr, pcr_before, pcr_after))
+ {
+ return FAILED;
+ }
+ }
+
+ return SUCCESS;
+}
+
+METHOD(pts_component_t, check_off_registrations, bool,
+ pts_ita_comp_tgrub_t *this)
+{
+ return FALSE;
+}
+
+METHOD(pts_component_t, destroy, void,
+ pts_ita_comp_tgrub_t *this)
+{
+ this->name->destroy(this->name);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db)
+{
+ pts_ita_comp_tgrub_t *this;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_evidence_flags = _get_evidence_flags,
+ .get_depth = _get_depth,
+ .measure = _measure,
+ .verify = _verify,
+ .check_off_registrations = _check_off_registrations,
+ .destroy = _destroy,
+ },
+ .name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TGRUB,
+ qualifier),
+ .depth = depth,
+ .pts_db = pts_db,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/ita/ita_comp_tgrub.h b/src/libpts/pts/components/ita/ita_comp_tgrub.h
new file mode 100644
index 000000000..52ecc325c
--- /dev/null
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_ita_comp_func_name pts_ita_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_ITA_COMP_TGRUB_H_
+#define PTS_ITA_COMP_TGRUB_H_
+
+#include "pts/components/pts_component.h"
+
+/**
+ * Create a PTS ITS Functional Component object
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @param depth Sub-component depth
+ * @param pts_db PTS measurement database
+ */
+pts_component_t* pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
+ pts_database_t *pts_db);
+
+#endif /** PTS_ITA_COMP_TGRUB_H_ @}*/
diff --git a/src/libpts/pts/components/pts_comp_evidence.c b/src/libpts/pts/components/pts_comp_evidence.c
new file mode 100644
index 000000000..9eb8dae75
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_evidence.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu, 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/components/pts_comp_evidence.h"
+
+#include <debug.h>
+
+typedef struct private_pts_comp_evidence_t private_pts_comp_evidence_t;
+
+/**
+ * Private data of a pts_comp_evidence_t object.
+ */
+struct private_pts_comp_evidence_t {
+
+ /**
+ * Public pts_comp_evidence_t interface.
+ */
+ pts_comp_evidence_t public;
+
+ /**
+ * Component Functional Name
+ */
+ pts_comp_func_name_t *name;
+
+ /**
+ * Sub-Component Depth
+ */
+ u_int32_t depth;
+
+ /**
+ * Measurement Time
+ */
+ time_t measurement_time;
+
+ /**
+ * Measurement Time
+ */
+ chunk_t measurement;
+
+ /**
+ * Measurement Hash Algorithm
+ */
+ pts_meas_algorithms_t hash_algorithm;
+
+ /**
+ * Is PCR Information included?
+ */
+ bool has_pcr_info;
+
+ /**
+ * PCR the measurement was extended into
+ */
+ u_int32_t extended_pcr;
+
+ /**
+ * PCR value before extension
+ */
+ chunk_t pcr_before;
+
+ /**
+ * PCR value after extension
+ */
+ chunk_t pcr_after;
+
+ /**
+ * Transformation used for extending measurement into PCR
+ */
+ pts_pcr_transform_t transform;
+
+ /**
+ * Component Validation Result
+ */
+ pts_comp_evid_validation_t validation;
+
+ /**
+ * Verification Policy URI
+ */
+ chunk_t policy_uri;
+
+};
+
+METHOD(pts_comp_evidence_t, get_comp_func_name, pts_comp_func_name_t*,
+ private_pts_comp_evidence_t *this, u_int32_t *depth)
+{
+ if (depth)
+ {
+ *depth = this->depth;
+ }
+ return this->name;
+}
+
+METHOD(pts_comp_evidence_t, get_extended_pcr, u_int32_t,
+ private_pts_comp_evidence_t *this)
+{
+ return this->extended_pcr;
+}
+
+METHOD(pts_comp_evidence_t, get_measurement, chunk_t,
+ private_pts_comp_evidence_t *this, u_int32_t *extended_pcr,
+ pts_meas_algorithms_t *algo, pts_pcr_transform_t *transform,
+ time_t *measurement_time)
+{
+ if (extended_pcr)
+ {
+ *extended_pcr = this->extended_pcr;
+ }
+ if (algo)
+ {
+ *algo = this->hash_algorithm;
+ }
+ if (transform)
+ {
+ *transform = this->transform;
+ }
+ if (measurement_time)
+ {
+ *measurement_time = this->measurement_time;
+ }
+ return this->measurement;
+}
+
+METHOD(pts_comp_evidence_t, get_pcr_info, bool,
+ private_pts_comp_evidence_t *this, chunk_t *pcr_before, chunk_t *pcr_after)
+{
+ if (pcr_before)
+ {
+ *pcr_before = this->pcr_before;
+ }
+ if (pcr_after)
+ {
+ *pcr_after = this->pcr_after;
+ }
+ return this->has_pcr_info;
+}
+
+METHOD(pts_comp_evidence_t, set_pcr_info, void,
+ private_pts_comp_evidence_t *this, chunk_t pcr_before, chunk_t pcr_after)
+{
+ this->has_pcr_info = TRUE;
+ this->pcr_before = pcr_before;
+ this->pcr_after = pcr_after;
+
+ DBG2(DBG_PTS, "PCR %2d before value : %#B", this->extended_pcr, &pcr_before);
+ DBG2(DBG_PTS, "PCR %2d after value : %#B", this->extended_pcr, &pcr_after);
+}
+
+METHOD(pts_comp_evidence_t, get_validation, pts_comp_evid_validation_t,
+ private_pts_comp_evidence_t *this, chunk_t *uri)
+{
+ if (uri)
+ {
+ *uri = this->policy_uri;
+ }
+ return this->validation;
+}
+
+METHOD(pts_comp_evidence_t, set_validation, void,
+ private_pts_comp_evidence_t *this, pts_comp_evid_validation_t validation,
+ chunk_t uri)
+{
+ this->validation = validation;
+ this->policy_uri = chunk_clone(uri);
+}
+
+METHOD(pts_comp_evidence_t, destroy, void,
+ private_pts_comp_evidence_t *this)
+{
+ this->name->destroy(this->name);
+ free(this->measurement.ptr);
+ free(this->pcr_before.ptr);
+ free(this->pcr_after.ptr);
+ free(this->policy_uri.ptr);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_comp_evidence_t *pts_comp_evidence_create(pts_comp_func_name_t *name,
+ u_int32_t depth,
+ u_int32_t extended_pcr,
+ pts_meas_algorithms_t algo,
+ pts_pcr_transform_t transform,
+ time_t measurement_time,
+ chunk_t measurement)
+{
+ private_pts_comp_evidence_t *this;
+
+ INIT(this,
+ .public = {
+ .get_comp_func_name = _get_comp_func_name,
+ .get_extended_pcr = _get_extended_pcr,
+ .get_measurement = _get_measurement,
+ .get_pcr_info = _get_pcr_info,
+ .set_pcr_info = _set_pcr_info,
+ .get_validation = _get_validation,
+ .set_validation = _set_validation,
+ .destroy = _destroy,
+ },
+ .name = name,
+ .depth = depth,
+ .extended_pcr = extended_pcr,
+ .hash_algorithm = algo,
+ .transform = transform,
+ .measurement_time = measurement_time,
+ .measurement = measurement,
+ );
+
+ name->log(name, "");
+ DBG2(DBG_PTS, "measurement time: %T", &measurement_time, FALSE);
+ DBG2(DBG_PTS, "PCR %2d extended with: %#B", extended_pcr, &measurement);
+
+ return &this->public;
+}
+
+/**
+ * See header
+ */
+pts_pcr_transform_t pts_meas_algo_to_pcr_transform(pts_meas_algorithms_t algo,
+ size_t pcr_len)
+{
+ size_t hash_size;
+
+ hash_size = pts_meas_algo_hash_size(algo);
+ if (hash_size == 0)
+ {
+ return PTS_PCR_TRANSFORM_NO;
+ }
+ if (hash_size == pcr_len)
+ {
+ return PTS_PCR_TRANSFORM_MATCH;
+ }
+ if (hash_size > pcr_len)
+ {
+ return PTS_PCR_TRANSFORM_LONG;
+ }
+ return PTS_PCR_TRANSFORM_SHORT;
+}
+
diff --git a/src/libpts/pts/components/pts_comp_evidence.h b/src/libpts/pts/components/pts_comp_evidence.h
new file mode 100644
index 000000000..fe86aa940
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_evidence.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu, 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_comp_evidence pts_comp_evidence
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_COMP_EVIDENCE_H_
+#define PTS_COMP_EVIDENCE_H_
+
+typedef struct pts_comp_evidence_t pts_comp_evidence_t;
+typedef enum pts_pcr_transform_t pts_pcr_transform_t;
+typedef enum pts_comp_evid_validation_t pts_comp_evid_validation_t;
+
+#include "pts/pts_meas_algo.h"
+#include "pts/components/pts_comp_func_name.h"
+
+#include <library.h>
+
+/**
+ * PTS PCR Transformations
+ */
+enum pts_pcr_transform_t {
+ /** No Transformation */
+ PTS_PCR_TRANSFORM_NO = 0,
+ /** Hash Value matched PCR size */
+ PTS_PCR_TRANSFORM_MATCH = 1,
+ /** Hash value shorter than PCR size */
+ PTS_PCR_TRANSFORM_SHORT = 2,
+ /** Hash value longer than PCR size */
+ PTS_PCR_TRANSFORM_LONG = 3,
+};
+
+/**
+ * PTS Component Evidence Validation Result Flags
+ */
+enum pts_comp_evid_validation_t {
+ /** No Validation was attempted */
+ PTS_COMP_EVID_VALIDATION_NONE = 0x00,
+ /** Attempted validation, unable to verify */
+ PTS_COMP_EVID_VALIDATION_UNABLE = 0x20,
+ /** Attempted validation, verification failed */
+ PTS_COMP_EVID_VALIDATION_FAILED = 0x40,
+ /** Attempted validation, verification passed */
+ PTS_COMP_EVID_VALIDATION_PASSED = 0x60,
+};
+
+/**
+ * PTS Functional Component Interface
+ */
+struct pts_comp_evidence_t {
+
+ /**
+ * Gets the Component Functional Name and Sub-Component Depth
+ *
+ * @param depth Sub-Component Depth
+ * @result Component Functional Name
+ */
+ pts_comp_func_name_t* (*get_comp_func_name)(pts_comp_evidence_t *this,
+ u_int32_t *depth);
+
+ /**
+ * Gets the PCR the measurement was extended into
+ *
+ * @result PCR the measurement was extended into
+ */
+ u_int32_t (*get_extended_pcr)(pts_comp_evidence_t *this);
+
+ /**
+ * Gets the measurement and the algorithms used
+ *
+ * @param extended_pcr PCR the measurement was extended into
+ * @param algo Measurement hash algorithm
+ * @param transform Transformation used for PCR extension
+ * @param measurement_time Time the measurement was taken
+ * @result Measurement hash value
+ */
+ chunk_t (*get_measurement)(pts_comp_evidence_t *this,
+ u_int32_t *extended_pcr,
+ pts_meas_algorithms_t *algo,
+ pts_pcr_transform_t *transform,
+ time_t *measurement_time);
+
+ /**
+ * Gets the PCR information if available
+ *
+ * @param pcr_before PCR value before extension
+ * @param pcr_after PCR value after extension
+ * @result TRUE if PCR information is available
+ */
+ bool (*get_pcr_info)(pts_comp_evidence_t *this, chunk_t *pcr_before,
+ chunk_t *pcr_after);
+
+ /**
+ * Sets PCR information if available
+ *
+ * @param pcr_before PCR value before extension
+ * @param pcr_after PCR value after extension
+ */
+ void (*set_pcr_info)(pts_comp_evidence_t *this, chunk_t pcr_before,
+ chunk_t pcr_after);
+
+ /**
+ * Gets Validation Result if available
+ *
+ * @param uri Verification Policy URI
+ * @return validation Validation Result
+ */
+ pts_comp_evid_validation_t (*get_validation)(pts_comp_evidence_t *this,
+ chunk_t *uri);
+
+ /**
+ * Sets Validation Result if available
+ *
+ * @param validation Validation Result
+ * @param uri Verification Policy URI
+ */
+ void (*set_validation)(pts_comp_evidence_t *this,
+ pts_comp_evid_validation_t validation, chunk_t uri);
+
+ /**
+ * Destroys a pts_comp_evidence_t object.
+ */
+ void (*destroy)(pts_comp_evidence_t *this);
+
+};
+
+/**
+ * Creates a pts_comp_evidence_t object
+ *
+ * @param name Component Functional Name
+ * @param depth Sub-component depth
+ * @param extended_pcr PCR the measurement was extended into
+ * @param algo Measurement hash algorithm
+ * @param transform Transformation used for PCR extension
+ * @param measurement_time Time the measurement was taken, 0 if unknown
+ * @param measurement Measurement hash value
+ */
+pts_comp_evidence_t* pts_comp_evidence_create(pts_comp_func_name_t *name,
+ u_int32_t depth,
+ u_int32_t extended_pcr,
+ pts_meas_algorithms_t algo,
+ pts_pcr_transform_t transform,
+ time_t measurement_time,
+ chunk_t measurement);
+
+/**
+ * Determine transform to fit measurement hash into PCR register
+ *
+ * @param algo Measurement hash algorithm
+ * @param pcr_len Length of the PCR registers in bytes
+ * @return PCR transform type
+ */
+pts_pcr_transform_t pts_meas_algo_to_pcr_transform(pts_meas_algorithms_t algo,
+ size_t pcr_len);
+
+#endif /** PTS_COMP_EVIDENCE_H_ @}*/
diff --git a/src/libpts/pts/components/pts_comp_func_name.c b/src/libpts/pts/components/pts_comp_func_name.c
new file mode 100644
index 000000000..d98850d78
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_func_name.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011 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 "libpts.h"
+#include "pts/components/pts_comp_func_name.h"
+
+#include <debug.h>
+
+typedef struct private_pts_comp_func_name_t private_pts_comp_func_name_t;
+
+/**
+ * Private data of a pts_comp_func_name_t object.
+ *
+ */
+struct private_pts_comp_func_name_t {
+
+ /**
+ * Public pts_comp_func_name_t interface.
+ */
+ pts_comp_func_name_t public;
+
+ /**
+ * PTS Component Functional Name Vendor ID
+ */
+ u_int32_t vid;
+
+ /**
+ * PTS Component Functional Name
+ */
+ u_int32_t name;
+
+ /**
+ * PTS Component Functional Name Qualifier
+ */
+ u_int8_t qualifier;
+
+};
+
+METHOD(pts_comp_func_name_t, get_vendor_id, u_int32_t,
+ private_pts_comp_func_name_t *this)
+{
+ return this->vid;
+}
+
+METHOD(pts_comp_func_name_t, get_name, u_int32_t,
+ private_pts_comp_func_name_t *this)
+{
+ return this->name;
+}
+
+METHOD(pts_comp_func_name_t, get_qualifier, u_int8_t,
+ private_pts_comp_func_name_t *this)
+{
+ return this->qualifier;
+}
+
+static bool equals(private_pts_comp_func_name_t *this,
+ private_pts_comp_func_name_t *other)
+{
+ if (this->vid != other->vid || this->name != other->name)
+ {
+ return FALSE;
+ }
+ if (this->qualifier == PTS_QUALIFIER_UNKNOWN ||
+ other->qualifier == PTS_QUALIFIER_UNKNOWN)
+ {
+ return TRUE;
+ }
+ /* TODO handle qualifier wildcards */
+
+ return this->qualifier == other->qualifier;
+}
+
+METHOD(pts_comp_func_name_t, clone_, pts_comp_func_name_t*,
+ private_pts_comp_func_name_t *this)
+{
+ private_pts_comp_func_name_t *clone;
+
+ clone = malloc_thing(private_pts_comp_func_name_t);
+ memcpy(clone, this, sizeof(private_pts_comp_func_name_t));
+
+ return &clone->public;
+}
+
+METHOD(pts_comp_func_name_t, log_, void,
+ private_pts_comp_func_name_t *this, char *label)
+{
+ enum_name_t *names, *types;
+ char flags[8];
+ int type;
+
+ names = pts_components->get_comp_func_names(pts_components, this->vid);
+ types = pts_components->get_qualifier_type_names(pts_components, this->vid);
+ type = pts_components->get_qualifier(pts_components, &this->public, flags);
+
+ if (names && types)
+ {
+ DBG2(DBG_PTS, "%s%N functional component '%N' [%s] '%N'",
+ label, pen_names, this->vid, names, this->name, flags, types, type);
+ }
+ else
+ {
+ DBG2(DBG_PTS, "%s0x%06x functional component 0x%08x 0x%02x",
+ label, this->vid, this->name, this->qualifier);
+ }
+}
+
+METHOD(pts_comp_func_name_t, destroy, void,
+ private_pts_comp_func_name_t *this)
+{
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
+ u_int8_t qualifier)
+{
+ private_pts_comp_func_name_t *this;
+
+ INIT(this,
+ .public = {
+ .get_vendor_id = _get_vendor_id,
+ .get_name = _get_name,
+ .get_qualifier = _get_qualifier,
+ .equals = (bool(*)(pts_comp_func_name_t*,pts_comp_func_name_t*))equals,
+ .clone = _clone_,
+ .log = _log_,
+ .destroy = _destroy,
+ },
+ .vid = vid,
+ .name = name,
+ .qualifier = qualifier,
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/pts_comp_func_name.h b/src/libpts/pts/components/pts_comp_func_name.h
new file mode 100644
index 000000000..2c7a84177
--- /dev/null
+++ b/src/libpts/pts/components/pts_comp_func_name.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_comp_func_name pts_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FUNC_COMP_NAME_H_
+#define PTS_FUNC_COMP_NAME_H_
+
+typedef struct pts_comp_func_name_t pts_comp_func_name_t;
+
+#include <library.h>
+
+#define PTS_QUALIFIER_UNKNOWN 0x00
+#define PTS_QUALIFIER_WILDCARD 0x3F
+
+/**
+ * PTS Component Functional Name object
+ */
+struct pts_comp_func_name_t {
+
+ /**
+ * Get the PTS Component Functional Name Vendor ID
+ *
+ * @return PTS Component Functional Name Vendor ID
+ */
+ u_int32_t (*get_vendor_id)(pts_comp_func_name_t *this);
+
+ /**
+ * Get the PTS Component Functional Name
+ *
+ * @return PTS Component Functional Name
+ */
+ u_int32_t (*get_name)(pts_comp_func_name_t *this);
+
+ /**
+ * Get the PTS Component Functional Name Qualifier
+ *
+ * @return PTS Component Functional Name Qualifier
+ */
+ u_int8_t (*get_qualifier)(pts_comp_func_name_t *this);
+
+ /**
+ * Check to PTS Component Functional Names for equality
+ *
+ * @param other Other PTS Component Functional Name
+ * @return TRUE if equal
+ */
+ bool (*equals)(pts_comp_func_name_t *this, pts_comp_func_name_t *other);
+
+ /**
+ * Clone a PTS Component Functional Name
+ *
+ * @return Cloned PTS Component Functional Name
+ */
+ pts_comp_func_name_t* (*clone)(pts_comp_func_name_t *this);
+
+ /**
+ * Write PTS Component Functional Name information to the standard logfile
+ *
+ * @param label Label added to log output
+ */
+ void (*log)(pts_comp_func_name_t *this, char *label);
+
+ /**
+ * Destroys a pts_component_t object.
+ */
+ void (*destroy)(pts_comp_func_name_t *this);
+
+};
+
+/**
+ * Create a PTS Component Functional Name object
+ *
+ * @param vid PTS Component Functional Name Vendor ID
+ * @param name PTS Component Functional Name
+ * @param PTS Component Functional Name Qualifier
+ */
+pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
+ u_int8_t qualifier);
+
+#endif /** PTS_FUNC_COMP_NAME_H_ @}*/
diff --git a/src/libpts/pts/components/pts_component.h b/src/libpts/pts/components/pts_component.h
new file mode 100644
index 000000000..524ff332d
--- /dev/null
+++ b/src/libpts/pts/components/pts_component.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 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_component pts_component
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_COMPONENT_H_
+#define PTS_COMPONENT_H_
+
+typedef struct pts_component_t pts_component_t;
+
+#include "pts/pts.h"
+#include "pts/pts_database.h"
+#include "pts/components/pts_comp_func_name.h"
+#include "pts/components/pts_comp_evidence.h"
+
+#include <library.h>
+
+/**
+ * PTS Functional Component Interface
+ */
+struct pts_component_t {
+
+ /**
+ * Get the PTS Component Functional Name
+ *
+ * @return PTS Component Functional Name
+ */
+ pts_comp_func_name_t* (*get_comp_func_name)(pts_component_t *this);
+
+ /**
+ * Get the PTS Component Evidence Flags
+ *
+ * @return PTS Component Functional Name
+ */
+ u_int8_t (*get_evidence_flags)(pts_component_t *this);
+
+ /**
+ * Get the PTS Sub-component Depth
+ *
+ * @return PTS Sub-component Depth
+ */
+ u_int32_t (*get_depth)(pts_component_t *this);
+
+ /**
+ * Do evidence measurements on the PTS Functional Component
+ *
+ * @param pts PTS interface
+ * @param evidence returns component evidence measureemt
+ * @return status return code
+ */
+ status_t (*measure)(pts_component_t *this, pts_t *pts,
+ pts_comp_evidence_t** evidence);
+
+ /**
+ * Verify the evidence measurements of the PTS Functional Component
+ *
+ * @param pts PTS interface
+ * @param evidence component evidence measurement to be verified
+ * @return status return code
+ */
+ status_t (*verify)(pts_component_t *this, pts_t *pts,
+ pts_comp_evidence_t *evidence);
+
+
+ /**
+ * Tell the PTS Functional Component to finalize pending registrations
+ *
+ * @return TRUE if there are pending registrations
+ */
+ bool (*check_off_registrations)(pts_component_t *this);
+
+ /**
+ * Destroys a pts_component_t object.
+ */
+ void (*destroy)(pts_component_t *this);
+
+};
+
+#endif /** PTS_COMPONENT_H_ @}*/
diff --git a/src/libpts/pts/components/pts_component_manager.c b/src/libpts/pts/components/pts_component_manager.c
new file mode 100644
index 000000000..8ac4767bf
--- /dev/null
+++ b/src/libpts/pts/components/pts_component_manager.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2011 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/components/pts_component_manager.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_pts_component_manager_t private_pts_component_manager_t;
+typedef struct vendor_entry_t vendor_entry_t;
+typedef struct component_entry_t component_entry_t;
+
+#define PTS_QUALIFIER_SIZE 6
+
+/**
+ * Vendor-specific namespace information and list of registered components
+ */
+struct vendor_entry_t {
+
+ /**
+ * Vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Vendor-specific Component Functional names
+ */
+ enum_name_t *comp_func_names;
+
+ /**
+ * Vendor-specific Qualifier Type names
+ */
+ enum_name_t *qualifier_type_names;
+
+ /**
+ * Vendor-specific Qualifier Flag names
+ */
+ char *qualifier_flag_names;
+
+ /**
+ * Vendor-specific size of Qualfiier Type field
+ */
+ int qualifier_type_size;
+
+ /**
+ * List of vendor-specific registered Functional Components
+ */
+ linked_list_t *components;
+};
+
+/**
+ * Destroy a vendor_entry_t object
+ */
+static void vendor_entry_destroy(vendor_entry_t *entry)
+{
+ entry->components->destroy_function(entry->components, free);
+ free(entry);
+}
+
+/**
+ * Creation method for a vendor-specific Functional Component
+ */
+struct component_entry_t {
+
+ /**
+ * Vendor-Specific Component Functional Name
+ */
+ u_int32_t name;
+
+ /**
+ * Functional Component creation method
+ */
+ pts_component_create_t create;
+};
+
+/**
+ * Private data of a pts_component_manager_t object.
+ *
+ */
+struct private_pts_component_manager_t {
+
+ /**
+ * Public pts_component_manager_t interface.
+ */
+ pts_component_manager_t public;
+
+ /**
+ * List of vendor-specific namespaces and registered components
+ */
+ linked_list_t *list;
+};
+
+METHOD(pts_component_manager_t, add_vendor, void,
+ private_pts_component_manager_t *this, pen_t vendor_id,
+ enum_name_t *comp_func_names, int qualifier_type_size,
+ char *qualifier_flag_names, enum_name_t *qualifier_type_names)
+{
+ vendor_entry_t *entry;
+
+ entry = malloc_thing(vendor_entry_t);
+ entry->vendor_id = vendor_id;
+ entry->comp_func_names = comp_func_names;
+ entry->qualifier_type_size = qualifier_type_size;
+ entry->qualifier_flag_names = qualifier_flag_names;
+ entry->qualifier_type_names = qualifier_type_names;
+ entry->components = linked_list_create();
+
+ this->list->insert_last(this->list, entry);
+ DBG2(DBG_PTS, "added %N functional component namespace",
+ pen_names, vendor_id);
+}
+
+METHOD(pts_component_manager_t, get_comp_func_names, enum_name_t*,
+ private_pts_component_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ enum_name_t *names = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ names = entry->comp_func_names;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return names;
+}
+
+METHOD(pts_component_manager_t, get_qualifier_type_names, enum_name_t*,
+ private_pts_component_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ enum_name_t *names = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ names = entry->qualifier_type_names;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return names;
+}
+
+METHOD(pts_component_manager_t, add_component, void,
+ private_pts_component_manager_t *this, pen_t vendor_id, u_int32_t name,
+ pts_component_create_t create)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ component_entry_t *component;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ component = malloc_thing(component_entry_t);
+ component->name = name;
+ component->create = create;
+
+ entry->components->insert_last(entry->components, component);
+ DBG2(DBG_PTS, "added %N functional component '%N'",
+ pen_names, vendor_id,
+ get_comp_func_names(this, vendor_id), name);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(pts_component_manager_t, remove_vendor, void,
+ private_pts_component_manager_t *this, pen_t vendor_id)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ this->list->remove_at(this->list, enumerator);
+ vendor_entry_destroy(entry);
+ DBG2(DBG_PTS, "removed %N functional component namespace",
+ pen_names, vendor_id);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
+METHOD(pts_component_manager_t, get_qualifier, u_int8_t,
+ private_pts_component_manager_t *this, pts_comp_func_name_t *name,
+ char *flags)
+{
+ enumerator_t *enumerator;
+ vendor_entry_t *entry;
+ u_int8_t qualifier, size, flag, type = 0;
+ int i;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == name->get_vendor_id(name))
+ {
+ qualifier = name->get_qualifier(name);
+ size = entry->qualifier_type_size;
+
+ /* mask qualifier type field */
+ type = qualifier & ((1 << size) - 1);
+
+ /* determine flags */
+ size = PTS_QUALIFIER_SIZE - size;
+ flag = (1 << (PTS_QUALIFIER_SIZE - 1));
+ if (flags)
+ {
+ for (i = 0 ; i < size; i++)
+ {
+ flags[i] = (qualifier & flag) ?
+ entry->qualifier_flag_names[i] : '.';
+ flag >>= 1;
+ }
+ flags[size] = '\0';
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return type;
+}
+
+METHOD(pts_component_manager_t, create, pts_component_t*,
+ private_pts_component_manager_t *this,
+ pts_comp_func_name_t *name, u_int32_t depth, pts_database_t *pts_db)
+{
+ enumerator_t *enumerator, *e2;
+ vendor_entry_t *entry;
+ component_entry_t *entry2;
+ pts_component_t *component = NULL;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == name->get_vendor_id(name))
+ {
+ e2 = entry->components->create_enumerator(entry->components);
+ while (e2->enumerate(e2, &entry2))
+ {
+ if (entry2->name == name->get_name(name) && entry2->create)
+ {
+ component = entry2->create(name->get_qualifier(name),
+ depth, pts_db);
+ break;
+ }
+ }
+ e2->destroy(e2);
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return component;
+}
+
+METHOD(pts_component_manager_t, destroy, void,
+ private_pts_component_manager_t *this)
+{
+ this->list->destroy_function(this->list, (void *)vendor_entry_destroy);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_component_manager_t *pts_component_manager_create(void)
+{
+ private_pts_component_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_vendor = _add_vendor,
+ .add_component = _add_component,
+ .remove_vendor = _remove_vendor,
+ .get_comp_func_names = _get_comp_func_names,
+ .get_qualifier_type_names = _get_qualifier_type_names,
+ .get_qualifier = _get_qualifier,
+ .create = _create,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/components/pts_component_manager.h b/src/libpts/pts/components/pts_component_manager.h
new file mode 100644
index 000000000..0079d0e26
--- /dev/null
+++ b/src/libpts/pts/components/pts_component_manager.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 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_component_manager pts_component_manager
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_COMPONENT_MANAGER_H_
+#define PTS_COMPONENT_MANAGER_H_
+
+typedef struct pts_component_manager_t pts_component_manager_t;
+
+#include "pts/pts_database.h"
+#include "pts/components/pts_component.h"
+#include "pts/components/pts_comp_func_name.h"
+
+#include <library.h>
+#include <pen/pen.h>
+
+typedef pts_component_t* (*pts_component_create_t)(u_int8_t qualifier,
+ u_int32_t depth,
+ pts_database_t *pts_db);
+
+/**
+ * Manages PTS Functional Components
+ */
+struct pts_component_manager_t {
+
+ /**
+ * Add vendor-specific functional component names
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @param comp_func_names Vendor-specific Component Functional names
+ * @param qualifier_type_size Vendor-specific Qualifier Type size
+ * @param qualifier_flag_names Vendor-specific Qualifier Flag names
+ * @param qualifier_type_names Vendor-specific Qualifier Type names
+ */
+ void (*add_vendor)(pts_component_manager_t *this, pen_t vendor_id,
+ enum_name_t *comp_func_names,
+ int qualifier_type_size,
+ char *qualifier_flag_names,
+ enum_name_t *qualifier_type_names);
+
+ /**
+ * Add vendor-specific functional component
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @param names Component Functional Name
+ * @param create Functional Component creation method
+ */
+ void (*add_component)(pts_component_manager_t *this, pen_t vendor_id,
+ u_int32_t name, pts_component_create_t create);
+
+ /**
+ * Remove vendor-specific components and associated namespace
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ */
+ void (*remove_vendor)(pts_component_manager_t *this, pen_t vendor_id);
+
+ /**
+ * Return the Functional Component names for a given vendor ID
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @return Comp. Func. names if found, NULL else
+ */
+ enum_name_t* (*get_comp_func_names)(pts_component_manager_t *this,
+ pen_t vendor_id);
+
+ /**
+ * Return the Functional Component Qualifier Type names for a given vendor ID
+ *
+ * @param vendor_id Private Enterprise Number (PEN)
+ * @return Qualifier Type names if found, NULL else
+ */
+ enum_name_t* (*get_qualifier_type_names)(pts_component_manager_t *this,
+ pen_t vendor_id);
+
+ /**
+ * Return the Qualifier Type and Flags
+ *
+ * @param name Component Functional Name
+ * @param flags Qualifier Flags as a string in a char buffer
+ * @return Qualifier Type
+ */
+ u_int8_t (*get_qualifier)(pts_component_manager_t *this,
+ pts_comp_func_name_t *name, char *flags);
+
+ /**
+ * Create a PTS Component object from a Functional Component Name object
+ *
+ * @param name Component Functional Name
+ * @param depth Sub-component Depth
+ * @param pts_db PTS measurement database
+ * @return Component object if supported, NULL else
+ */
+ pts_component_t* (*create)(pts_component_manager_t *this,
+ pts_comp_func_name_t *name, u_int32_t depth,
+ pts_database_t *pts_db);
+
+ /**
+ * Destroys a pts_component_manager_t object.
+ */
+ void (*destroy)(pts_component_manager_t *this);
+};
+
+/**
+ * Create a PA-TNC attribute manager
+ */
+pts_component_manager_t* pts_component_manager_create(void);
+
+#endif /** PTS_COMPONENT_MANAGER_H_ @}*/
diff --git a/src/libpts/pts/components/tcg/tcg_comp_func_name.c b/src/libpts/pts/components/tcg/tcg_comp_func_name.c
new file mode 100644
index 000000000..a70c84e48
--- /dev/null
+++ b/src/libpts/pts/components/tcg/tcg_comp_func_name.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011 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_comp_func_name.h"
+
+char pts_tcg_qualifier_flag_names[] = { 'K', 'S' };
+
+ENUM_BEGIN(pts_tcg_qualifier_type_names, PTS_TCG_QUALIFIER_TYPE_UNKNOWN,
+ PTS_TCG_QUALIFIER_TYPE_TNC,
+ "Unknown",
+ "Trusted Platform",
+ "Operating System",
+ "Graphical User Interface",
+ "Application",
+ "Networking",
+ "Library",
+ "TNC Defined Component"
+);
+ENUM_NEXT(pts_tcg_qualifier_type_names, PTS_TCG_QUALIFIER_TYPE_ALL,
+ PTS_TCG_QUALIFIER_TYPE_ALL,
+ PTS_TCG_QUALIFIER_TYPE_TNC,
+ "All Matching Components"
+);
+ENUM_END(pts_tcg_qualifier_type_names, PTS_TCG_QUALIFIER_TYPE_ALL);
+
+ENUM(pts_tcg_comp_func_names, PTS_TCG_COMP_FUNC_NAME_IGNORE,
+ PTS_TCG_COMP_FUNC_NAME_OPT_ROMS,
+ "Ignore",
+ "CRTM",
+ "BIOS",
+ "Platform Extensions",
+ "Motherboard Firmware",
+ "Initial Program Loader",
+ "Option ROMs"
+);
+
diff --git a/src/libpts/pts/components/tcg/tcg_comp_func_name.h b/src/libpts/pts/components/tcg/tcg_comp_func_name.h
new file mode 100644
index 000000000..9708ad09d
--- /dev/null
+++ b/src/libpts/pts/components/tcg/tcg_comp_func_name.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_tcg_comp_func_name pts_tcg_comp_func_name
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_TCG_COMP_FUNC_NAME_H_
+#define PTS_TCG_COMP_FUNC_NAME_H_
+
+typedef enum pts_tcg_qualifier_type_t pts_tcg_qualifier_type_t;
+typedef enum pts_tcg_comp_func_name_t pts_tcp_comp_func_name_t;
+
+#include <library.h>
+
+/**
+ * PTS Component Functional Name Qualifier Flags for the TCG namespace
+ * see section 5.2 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 0 1 2 3 4 5
+ * +-+-+-+-+-+-+
+ * |K|S| Type |
+ * +-+-+-+-+-+-+
+ */
+#define PTS_TCG_QUALIFIER_FLAG_KERNEL (1<<5)
+#define PTS_TCG_QUALIFIER_FLAG_SUB (1<<4)
+
+extern char pts_tcg_qualifier_flag_names[];
+
+/**
+ * Size of the PTS Component Functional Name Qualifier Type field
+ */
+#define PTS_TCG_QUALIFIER_TYPE_SIZE 4
+
+/**
+ * PTS Component Functional Name Qualifier Types for the TCG namespace
+ * see section 5.2 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_tcg_qualifier_type_t {
+ /** Unknown */
+ PTS_TCG_QUALIFIER_TYPE_UNKNOWN = 0x0,
+ /** Trusted Platform */
+ PTS_TCG_QUALIFIER_TYPE_TRUSTED = 0x1,
+ /** Operating System */
+ PTS_TCG_QUALIFIER_TYPE_OS = 0x2,
+ /** Graphical User Interface */
+ PTS_TCG_QUALIFIER_TYPE_GUI = 0x3,
+ /** Application */
+ PTS_TCG_QUALIFIER_TYPE_APP = 0x4,
+ /** Networking */
+ PTS_TCG_QUALIFIER_TYPE_NET = 0x5,
+ /** Library */
+ PTS_TCG_QUALIFIER_TYPE_LIB = 0x6,
+ /** TNC Defined Component */
+ PTS_TCG_QUALIFIER_TYPE_TNC = 0x7,
+ /** All matching Components */
+ PTS_TCG_QUALIFIER_TYPE_ALL = 0xF,
+};
+
+extern enum_name_t *pts_tcg_qualifier_type_names;
+
+/**
+ * PTS Component Functional Name Binary Enumeration for the TCG namespace
+ * see section 5.3 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_tcg_comp_func_name_t {
+ /** Ignore */
+ PTS_TCG_COMP_FUNC_NAME_IGNORE = 0x0000,
+ /** CRTM */
+ PTS_TCG_COMP_FUNC_NAME_CRTM = 0x0001,
+ /** BIOS */
+ PTS_TCG_COMP_FUNC_NAME_BIOS = 0x0002,
+ /** Platform Extensions */
+ PTS_TCG_COMP_FUNC_NAME_PLATFORM_EXT = 0x0003,
+ /** Motherboard Firmware */
+ PTS_TCG_COMP_FUNC_NAME_BOARD = 0x0004,
+ /** Initial Program Loader */
+ PTS_TCG_COMP_FUNC_NAME_INIT_LOADER = 0x0005,
+ /** Option ROMs */
+ PTS_TCG_COMP_FUNC_NAME_OPT_ROMS = 0x0006,
+};
+
+extern enum_name_t *pts_tcg_comp_func_names;
+
+#endif /** PTS_TCG_COMP_FUNC_NAME_H_ @}*/