summaryrefslogtreecommitdiff
path: root/src/libpts
diff options
context:
space:
mode:
Diffstat (limited to 'src/libpts')
-rw-r--r--src/libpts/Makefile.am1
-rw-r--r--src/libpts/Makefile.in27
-rw-r--r--src/libpts/plugins/imc_attestation/Makefile.in14
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation.c88
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_process.c72
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_state.c103
-rw-r--r--src/libpts/plugins/imc_attestation/imc_attestation_state.h19
-rw-r--r--src/libpts/plugins/imv_attestation/Makefile.am2
-rw-r--r--src/libpts/plugins/imv_attestation/Makefile.in15
-rw-r--r--src/libpts/plugins/imv_attestation/attest.c18
-rw-r--r--src/libpts/plugins/imv_attestation/attest_db.c382
-rw-r--r--src/libpts/plugins/imv_attestation/attest_db.h15
-rw-r--r--src/libpts/plugins/imv_attestation/attest_usage.c23
-rwxr-xr-xsrc/libpts/plugins/imv_attestation/build-database.sh221
-rw-r--r--src/libpts/plugins/imv_attestation/data.sql371
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation.c74
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_build.c24
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_process.c72
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.c162
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.h36
-rw-r--r--src/libpts/plugins/imv_attestation/tables.sql5
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.c807
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.h5
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.c149
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.h5
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.c65
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.h5
-rw-r--r--src/libpts/pts/components/pts_comp_evidence.c22
-rw-r--r--src/libpts/pts/components/pts_comp_evidence.h4
-rw-r--r--src/libpts/pts/components/pts_comp_func_name.c9
-rw-r--r--src/libpts/pts/components/pts_comp_func_name.h9
-rw-r--r--src/libpts/pts/components/pts_component.h24
-rw-r--r--src/libpts/pts/components/pts_component_manager.c6
-rw-r--r--src/libpts/pts/components/pts_component_manager.h3
-rw-r--r--src/libpts/pts/pts.c420
-rw-r--r--src/libpts/pts/pts.h53
-rw-r--r--src/libpts/pts/pts_database.c41
-rw-r--r--src/libpts/pts/pts_database.h13
-rw-r--r--src/libpts/pts/pts_error.c12
-rw-r--r--src/libpts/pts/pts_file_meas.c188
-rw-r--r--src/libpts/pts/pts_file_meas.h26
-rw-r--r--src/libpts/pts/pts_meas_algo.c21
-rw-r--r--src/libpts/pts/pts_meas_algo.h9
-rw-r--r--src/libpts/pts/pts_pcr.c289
-rw-r--r--src/libpts/pts/pts_pcr.h118
-rw-r--r--src/libpts/tcg/tcg_pts_attr_aik.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_file_meas.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_get_aik.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_meas_algo.c33
-rw-r--r--src/libpts/tcg/tcg_pts_attr_proto_caps.c33
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meas.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meta.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c51
-rw-r--r--src/libpts/tcg/tcg_pts_attr_simple_evid_final.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_tpm_version_info.c31
-rw-r--r--src/libpts/tcg/tcg_pts_attr_unix_file_meta.c31
62 files changed, 3250 insertions, 1348 deletions
diff --git a/src/libpts/Makefile.am b/src/libpts/Makefile.am
index 3ff941794..8137493ab 100644
--- a/src/libpts/Makefile.am
+++ b/src/libpts/Makefile.am
@@ -9,6 +9,7 @@ libpts_la_SOURCES = \
libpts.h libpts.c \
pts/pts.h pts/pts.c \
pts/pts_error.h pts/pts_error.c \
+ pts/pts_pcr.h pts/pts_pcr.c \
pts/pts_proto_caps.h \
pts/pts_req_func_comp_evid.h \
pts/pts_simple_evid_final.h \
diff --git a/src/libpts/Makefile.in b/src/libpts/Makefile.in
index d317cfea1..0b6451bcc 100644
--- a/src/libpts/Makefile.in
+++ b/src/libpts/Makefile.in
@@ -51,6 +51,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -77,8 +78,8 @@ am__base_list = \
am__installdirs = "$(DESTDIR)$(ipseclibdir)"
LTLIBRARIES = $(ipseclib_LTLIBRARIES)
libpts_la_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la
-am_libpts_la_OBJECTS = libpts.lo pts.lo pts_error.lo pts_creds.lo \
- pts_database.lo pts_dh_group.lo pts_file_meas.lo \
+am_libpts_la_OBJECTS = libpts.lo pts.lo pts_error.lo pts_pcr.lo \
+ pts_creds.lo pts_database.lo pts_dh_group.lo pts_file_meas.lo \
pts_file_meta.lo pts_file_type.lo pts_meas_algo.lo \
pts_component_manager.lo pts_comp_evidence.lo \
pts_comp_func_name.lo ita_comp_func_name.lo ita_comp_ima.lo \
@@ -96,7 +97,7 @@ am_libpts_la_OBJECTS = libpts.lo pts.lo pts_error.lo pts_creds.lo \
tcg_pts_attr_req_file_meas.lo tcg_pts_attr_file_meas.lo \
tcg_pts_attr_req_file_meta.lo tcg_pts_attr_unix_file_meta.lo
libpts_la_OBJECTS = $(am_libpts_la_OBJECTS)
-DEFAULT_INCLUDES = -I.@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -160,6 +161,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BFDLIB = @BFDLIB@
BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@@ -254,11 +256,14 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
-default_pkcs11 = @default_pkcs11@
+dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -275,11 +280,12 @@ imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
-libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
linux_headers = @linux_headers@
@@ -295,6 +301,7 @@ mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
@@ -304,7 +311,6 @@ pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
-pluto_plugins = @pluto_plugins@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
@@ -339,6 +345,7 @@ libpts_la_SOURCES = \
libpts.h libpts.c \
pts/pts.h pts/pts.c \
pts/pts_error.h pts/pts_error.c \
+ pts/pts_pcr.h pts/pts_pcr.c \
pts/pts_proto_caps.h \
pts/pts_req_func_comp_evid.h \
pts/pts_simple_evid_final.h \
@@ -469,6 +476,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_file_meta.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_file_type.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_meas_algo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pts_pcr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_attr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_comp_func_name.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcg_pts_attr_aik.Plo@am__quote@
@@ -524,6 +532,13 @@ pts_error.lo: pts/pts_error.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pts_error.lo `test -f 'pts/pts_error.c' || echo '$(srcdir)/'`pts/pts_error.c
+pts_pcr.lo: pts/pts_pcr.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_pcr.lo -MD -MP -MF $(DEPDIR)/pts_pcr.Tpo -c -o pts_pcr.lo `test -f 'pts/pts_pcr.c' || echo '$(srcdir)/'`pts/pts_pcr.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_pcr.Tpo $(DEPDIR)/pts_pcr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='pts/pts_pcr.c' object='pts_pcr.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pts_pcr.lo `test -f 'pts/pts_pcr.c' || echo '$(srcdir)/'`pts/pts_pcr.c
+
pts_creds.lo: pts/pts_creds.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pts_creds.lo -MD -MP -MF $(DEPDIR)/pts_creds.Tpo -c -o pts_creds.lo `test -f 'pts/pts_creds.c' || echo '$(srcdir)/'`pts/pts_creds.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pts_creds.Tpo $(DEPDIR)/pts_creds.Plo
diff --git a/src/libpts/plugins/imc_attestation/Makefile.in b/src/libpts/plugins/imc_attestation/Makefile.in
index 583d2dfee..4734379bf 100644
--- a/src/libpts/plugins/imc_attestation/Makefile.in
+++ b/src/libpts/plugins/imc_attestation/Makefile.in
@@ -49,6 +49,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -84,7 +85,7 @@ imc_attestation_la_OBJECTS = $(am_imc_attestation_la_OBJECTS)
imc_attestation_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(imc_attestation_la_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I.@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -110,6 +111,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BFDLIB = @BFDLIB@
BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@@ -204,11 +206,14 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
-default_pkcs11 = @default_pkcs11@
+dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -225,11 +230,12 @@ imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
-libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
linux_headers = @linux_headers@
@@ -245,6 +251,7 @@ mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
@@ -254,7 +261,6 @@ pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
-pluto_plugins = @pluto_plugins@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation.c b/src/libpts/plugins/imc_attestation/imc_attestation.c
index 4f77ba093..7cb2a0671 100644
--- a/src/libpts/plugins/imc_attestation/imc_attestation.c
+++ b/src/libpts/plugins/imc_attestation/imc_attestation.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -21,6 +21,7 @@
#include <ietf/ietf_attr.h>
#include <ietf/ietf_attr_pa_tnc_error.h>
#include <ietf/ietf_attr_product_info.h>
+#include <ietf/ietf_attr_assess_result.h>
#include <libpts.h>
@@ -108,9 +109,17 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
case TNC_CONNECTION_STATE_CREATE:
state = imc_attestation_state_create(connection_id);
return imc_attestation->create_state(imc_attestation, state);
+ case TNC_CONNECTION_STATE_HANDSHAKE:
+ if (imc_attestation->change_state(imc_attestation, connection_id,
+ new_state, &state) != TNC_RESULT_SUCCESS)
+ {
+ return TNC_RESULT_FATAL;
+ }
+ state->set_result(state, imc_id,
+ TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
+ return TNC_RESULT_SUCCESS;
case TNC_CONNECTION_STATE_DELETE:
return imc_attestation->delete_state(imc_attestation, connection_id);
- case TNC_CONNECTION_STATE_HANDSHAKE:
case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
case TNC_CONNECTION_STATE_ACCESS_NONE:
default:
@@ -149,17 +158,15 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
platform_info = pts->get_platform_info(pts);
if (platform_info)
{
- pa_tnc_msg_t *pa_tnc_msg;
+ linked_list_t *attr_list;
pa_tnc_attr_t *attr;
- pa_tnc_msg = pa_tnc_msg_create();
+ attr_list = linked_list_create();
attr = ietf_attr_product_info_create(0, 0, platform_info);
- pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
- pa_tnc_msg->build(pa_tnc_msg);
+ attr_list->insert_last(attr_list, attr);
result = imc_attestation->send_message(imc_attestation, connection_id,
- FALSE, 0, TNC_IMVID_ANY,
- pa_tnc_msg->get_encoding(pa_tnc_msg));
- pa_tnc_msg->destroy(pa_tnc_msg);
+ FALSE, 0, TNC_IMVID_ANY, attr_list);
+ attr_list->destroy(attr_list);
}
return result;
@@ -176,11 +183,13 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
{
pa_tnc_msg_t *pa_tnc_msg;
pa_tnc_attr_t *attr;
+ pen_type_t type;
linked_list_t *attr_list;
imc_state_t *state;
imc_attestation_state_t *attestation_state;
enumerator_t *enumerator;
TNC_Result result;
+ TNC_UInt32 target_imc_id;
if (!imc_attestation)
{
@@ -204,6 +213,7 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
{
return result;
}
+ target_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? imc_id : dst_imc_id;
/* preprocess any IETF standard error attributes */
result = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg) ?
@@ -215,30 +225,40 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
while (enumerator->enumerate(enumerator, &attr))
{
- if (attr->get_vendor_id(attr) == PEN_IETF &&
- attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
- {
- ietf_attr_pa_tnc_error_t *error_attr;
- pen_t error_vendor_id;
- pa_tnc_error_code_t error_code;
- chunk_t msg_info;
+ type = attr->get_type(attr);
- error_attr = (ietf_attr_pa_tnc_error_t*)attr;
- error_vendor_id = error_attr->get_vendor_id(error_attr);
-
- if (error_vendor_id == PEN_TCG)
+ if (type.vendor_id == PEN_IETF)
+ {
+ if (type.type == IETF_ATTR_PA_TNC_ERROR)
{
+ ietf_attr_pa_tnc_error_t *error_attr;
+ pen_type_t error_code;
+ chunk_t msg_info;
+
+ error_attr = (ietf_attr_pa_tnc_error_t*)attr;
error_code = error_attr->get_error_code(error_attr);
- msg_info = error_attr->get_msg_info(error_attr);
- DBG1(DBG_IMC, "received TCG-PTS error '%N'",
- pts_error_code_names, error_code);
- DBG1(DBG_IMC, "error information: %B", &msg_info);
+ if (error_code.vendor_id == PEN_TCG)
+ {
+ msg_info = error_attr->get_msg_info(error_attr);
- result = TNC_RESULT_FATAL;
+ DBG1(DBG_IMC, "received TCG-PTS error '%N'",
+ pts_error_code_names, error_code.type);
+ DBG1(DBG_IMC, "error information: %B", &msg_info);
+
+ result = TNC_RESULT_FATAL;
+ }
+ }
+ else if (type.type == IETF_ATTR_ASSESSMENT_RESULT)
+ {
+ ietf_attr_assess_result_t *ietf_attr;
+
+ ietf_attr = (ietf_attr_assess_result_t*)attr;
+ state->set_result(state, target_imc_id,
+ ietf_attr->get_result(ietf_attr));
}
}
- else if (attr->get_vendor_id(attr) == PEN_TCG)
+ else if (type.vendor_id == PEN_TCG)
{
if (!imc_attestation_process(attr, attr_list, attestation_state,
supported_algorithms, supported_dh_groups))
@@ -253,23 +273,11 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
if (result == TNC_RESULT_SUCCESS && attr_list->get_count(attr_list))
{
- pa_tnc_msg = pa_tnc_msg_create();
-
- enumerator = attr_list->create_enumerator(attr_list);
- while (enumerator->enumerate(enumerator, &attr))
- {
- pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
- }
- enumerator->destroy(enumerator);
-
- pa_tnc_msg->build(pa_tnc_msg);
result = imc_attestation->send_message(imc_attestation, connection_id,
- FALSE, 0, TNC_IMVID_ANY,
- pa_tnc_msg->get_encoding(pa_tnc_msg));
- pa_tnc_msg->destroy(pa_tnc_msg);
+ FALSE, 0, TNC_IMVID_ANY, attr_list);
}
-
attr_list->destroy(attr_list);
+
return result;
}
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_process.c b/src/libpts/plugins/imc_attestation/imc_attestation_process.c
index b70c05370..bd2fa649d 100644
--- a/src/libpts/plugins/imc_attestation/imc_attestation_process.c
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_process.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
#include <ietf/ietf_attr_pa_tnc_error.h>
-#include <libpts.h>
#include <pts/pts.h>
#include <tcg/tcg_pts_attr_proto_caps.h>
@@ -57,10 +56,13 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
chunk_t attr_info;
pts_t *pts;
pts_error_code_t pts_error;
+ pen_type_t attr_type;
bool valid_path;
pts = attestation_state->get_pts(attestation_state);
- switch (attr->get_type(attr))
+ attr_type = attr->get_type(attr);
+
+ switch (attr_type.type)
{
case TCG_PTS_REQ_PROTO_CAPS:
{
@@ -182,12 +184,12 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
case TCG_PTS_GET_TPM_VERSION_INFO:
{
chunk_t tpm_version_info, attr_info;
+ pen_type_t error_code = { PEN_TCG, TCG_PTS_TPM_VERS_NOT_SUPPORTED };
if (!pts->get_tpm_version_info(pts, &tpm_version_info))
{
attr_info = attr->get_value(attr);
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_TPM_VERS_NOT_SUPPORTED, attr_info);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
@@ -221,6 +223,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
bool is_directory;
u_int32_t delimiter;
pts_file_meas_t *measurements;
+ pen_type_t error_code;
attr_info = attr->get_value(attr);
attr_cast = (tcg_pts_attr_req_file_meas_t*)attr;
@@ -232,8 +235,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
if (valid_path && pts_error)
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- pts_error, attr_info);
+ error_code = pen_type_create(PEN_TCG, pts_error);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
@@ -244,8 +247,9 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_INVALID_DELIMITER, attr_info);
+ error_code = pen_type_create(PEN_TCG,
+ TCG_PTS_INVALID_DELIMITER);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
@@ -254,8 +258,9 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
DBG2(DBG_IMC, "measurement request %d for %s '%s'",
request_id, is_directory ? "directory" : "file",
pathname);
- measurements = pts->do_measurements(pts, request_id,
- pathname, is_directory);
+ measurements = pts_file_meas_create_from_path(request_id,
+ pathname, is_directory, TRUE,
+ pts->get_meas_algorithm(pts));
if (!measurements)
{
/* TODO handle error codes from measurements */
@@ -273,6 +278,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
bool is_directory;
u_int8_t delimiter;
pts_file_meta_t *metadata;
+ pen_type_t error_code;
attr_info = attr->get_value(attr);
attr_cast = (tcg_pts_attr_req_file_meta_t*)attr;
@@ -283,8 +289,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
valid_path = pts->is_path_valid(pts, pathname, &pts_error);
if (valid_path && pts_error)
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- pts_error, attr_info);
+ error_code = pen_type_create(PEN_TCG, pts_error);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
@@ -294,8 +300,9 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
}
if (delimiter != SOLIDUS_UTF && delimiter != REVERSE_SOLIDUS_UTF)
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_INVALID_DELIMITER, attr_info);
+ error_code = pen_type_create(PEN_TCG,
+ TCG_PTS_INVALID_DELIMITER);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
@@ -323,6 +330,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
pts_comp_func_name_t *name;
pts_comp_evidence_t *evid;
pts_component_t *comp;
+ pen_type_t error_code;
u_int32_t depth;
u_int8_t flags;
status_t status;
@@ -342,32 +350,36 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
if (flags & PTS_REQ_FUNC_COMP_EVID_TTC)
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_UNABLE_DET_TTC, attr_info);
+ error_code = pen_type_create(PEN_TCG,
+ TCG_PTS_UNABLE_DET_TTC);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
if (flags & PTS_REQ_FUNC_COMP_EVID_VER &&
!(negotiated_caps & PTS_PROTO_CAPS_V))
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_UNABLE_LOCAL_VAL, attr_info);
+ error_code = pen_type_create(PEN_TCG,
+ TCG_PTS_UNABLE_LOCAL_VAL);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
if (flags & PTS_REQ_FUNC_COMP_EVID_CURR &&
!(negotiated_caps & PTS_PROTO_CAPS_C))
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_UNABLE_CUR_EVID, attr_info);
+ error_code = pen_type_create(PEN_TCG,
+ TCG_PTS_UNABLE_CUR_EVID);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
if (flags & PTS_REQ_FUNC_COMP_EVID_PCR &&
!(negotiated_caps & PTS_PROTO_CAPS_T))
{
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG,
- TCG_PTS_UNABLE_DET_PCR, attr_info);
+ error_code = pen_type_create(PEN_TCG,
+ TCG_PTS_UNABLE_DET_PCR);
+ attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
attr_list->insert_last(attr_list, attr);
break;
}
@@ -377,17 +389,19 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
"support sub component measurements");
return FALSE;
}
- comp = pts_components->create(pts_components, name, depth, NULL);
+ comp = attestation_state->create_component(attestation_state,
+ name, depth);
if (!comp)
{
DBG2(DBG_IMC, " not registered: no evidence provided");
continue;
}
- /* do the component evidence measurement[s] */
+ /* do the component evidence measurement[s] and cache them */
do
{
- status = comp->measure(comp, pts, &evid);
+ status = comp->measure(comp, name->get_qualifier(name),
+ pts, &evid);
if (status == FAILED)
{
break;
@@ -395,7 +409,6 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
attestation_state->add_evidence(attestation_state, evid);
}
while (status == NEED_MORE);
- comp->destroy(comp);
}
e->destroy(e);
break;
@@ -408,12 +421,9 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
chunk_t pcr_composite, quote_sig;
bool use_quote2;
- /* Send buffered Simple Component Evidences */
+ /* Send cached Component Evidence entries */
while (attestation_state->next_evidence(attestation_state, &evid))
{
- pts->select_pcr(pts, evid->get_extended_pcr(evid));
-
- /* Send Simple Component Evidence */
attr = tcg_pts_attr_simple_comp_evid_create(evid);
attr_list->insert_last(attr_list, attr);
}
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_state.c b/src/libpts/plugins/imc_attestation/imc_attestation_state.c
index 72a55f60e..8ebabafa2 100644
--- a/src/libpts/plugins/imc_attestation/imc_attestation_state.c
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_state.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,10 +15,15 @@
#include "imc_attestation_state.h"
+#include <libpts.h>
+
+#include <tncif_names.h>
+
#include <utils/linked_list.h>
#include <debug.h>
typedef struct private_imc_attestation_state_t private_imc_attestation_state_t;
+typedef struct func_comp_t func_comp_t;
/**
* Private data of an imc_attestation_state_t object.
@@ -41,6 +46,11 @@ struct private_imc_attestation_state_t {
TNC_ConnectionState state;
/**
+ * Assessment/Evaluation Result
+ */
+ TNC_IMV_Evaluation_Result result;
+
+ /**
* Does the TNCCS connection support long message types?
*/
bool has_long;
@@ -51,12 +61,22 @@ struct private_imc_attestation_state_t {
bool has_excl;
/**
+ * Maximum PA-TNC message size for this TNCCS connection
+ */
+ u_int32_t max_msg_len;
+
+ /**
* PTS object
*/
pts_t *pts;
/**
- * PTS Component Evidence list
+ * List of Functional Components
+ */
+ linked_list_t *components;
+
+ /**
+ * Functional Component Evidence cache list
*/
linked_list_t *list;
@@ -87,18 +107,52 @@ METHOD(imc_state_t, set_flags, void,
this->has_excl = has_excl;
}
+METHOD(imc_state_t, set_max_msg_len, void,
+ private_imc_attestation_state_t *this, u_int32_t max_msg_len)
+{
+ this->max_msg_len = max_msg_len;
+}
+
+METHOD(imc_state_t, get_max_msg_len, u_int32_t,
+ private_imc_attestation_state_t *this)
+{
+ return this->max_msg_len;
+}
+
METHOD(imc_state_t, change_state, void,
private_imc_attestation_state_t *this, TNC_ConnectionState new_state)
{
this->state = new_state;
}
+METHOD(imc_state_t, set_result, void,
+ private_imc_attestation_state_t *this, TNC_IMCID id,
+ TNC_IMV_Evaluation_Result result)
+{
+ DBG1(DBG_IMC, "set assessment result for IMC %u to '%N'",
+ id, TNC_IMV_Evaluation_Result_names, result);
+ this->result = result;
+}
+
+METHOD(imc_state_t, get_result, bool,
+ private_imc_attestation_state_t *this, TNC_IMCID id,
+ TNC_IMV_Evaluation_Result *result)
+{
+ if (result)
+ {
+ *result = this->result;
+ }
+ return this->result != TNC_IMV_EVALUATION_RESULT_DONT_KNOW;
+}
METHOD(imc_state_t, destroy, void,
private_imc_attestation_state_t *this)
{
this->pts->destroy(this->pts);
- this->list->destroy_offset(this->list, offsetof(pts_comp_evidence_t, destroy));
+ this->components->destroy_offset(this->components,
+ offsetof(pts_component_t, destroy));
+ this->list->destroy_offset(this->list,
+ offsetof(pts_comp_evidence_t, destroy));
free(this);
}
@@ -108,10 +162,42 @@ METHOD(imc_attestation_state_t, get_pts, pts_t*,
return this->pts;
}
+METHOD(imc_attestation_state_t, create_component, pts_component_t*,
+ private_imc_attestation_state_t *this, pts_comp_func_name_t *name,
+ u_int32_t depth)
+{
+ enumerator_t *enumerator;
+ pts_component_t *component;
+ bool found = FALSE;
+
+ enumerator = this->components->create_enumerator(this->components);
+ while (enumerator->enumerate(enumerator, &component))
+ {
+ if (name->equals(name, component->get_comp_func_name(component)))
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ component = pts_components->create(pts_components, name, depth, NULL);
+ if (!component)
+ {
+ return NULL;
+ }
+ this->components->insert_last(this->components, component);
+
+ }
+ return component;
+}
+
METHOD(imc_attestation_state_t, add_evidence, void,
- private_imc_attestation_state_t *this, pts_comp_evidence_t *evidence)
+ private_imc_attestation_state_t *this, pts_comp_evidence_t *evid)
{
- this->list->insert_last(this->list, evidence);
+ this->list->insert_last(this->list, evid);
}
METHOD(imc_attestation_state_t, next_evidence, bool,
@@ -135,16 +221,23 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
.has_long = _has_long,
.has_excl = _has_excl,
.set_flags = _set_flags,
+ .set_max_msg_len = _set_max_msg_len,
+ .get_max_msg_len = _get_max_msg_len,
.change_state = _change_state,
+ .set_result = _set_result,
+ .get_result = _get_result,
.destroy = _destroy,
},
.get_pts = _get_pts,
+ .create_component = _create_component,
.add_evidence = _add_evidence,
.next_evidence = _next_evidence,
},
.connection_id = connection_id,
.state = TNC_CONNECTION_STATE_CREATE,
+ .result = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
.pts = pts_create(TRUE),
+ .components = linked_list_create(),
.list = linked_list_create(),
);
diff --git a/src/libpts/plugins/imc_attestation/imc_attestation_state.h b/src/libpts/plugins/imc_attestation/imc_attestation_state.h
index 22b0bba23..e4fca71bb 100644
--- a/src/libpts/plugins/imc_attestation/imc_attestation_state.h
+++ b/src/libpts/plugins/imc_attestation/imc_attestation_state.h
@@ -24,6 +24,7 @@
#include <imc/imc_state.h>
#include <pts/pts.h>
+#include <pts/components/pts_component.h>
#include <pts/components/pts_comp_evidence.h>
#include <library.h>
@@ -47,14 +48,24 @@ struct imc_attestation_state_t {
pts_t* (*get_pts)(imc_attestation_state_t *this);
/**
- * Add an entry to the Component Evidence list
+ * Create and add an entry to the list of Functional Components
*
- * @param entry Component Evidence entry
+ * @param name Component Functional Name
+ * @param depth Sub-component Depth
+ * @return created functional component instance or NULL
*/
- void (*add_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t *entry);
+ pts_component_t* (*create_component)(imc_attestation_state_t *this,
+ pts_comp_func_name_t *name, u_int32_t depth);
/**
- * Removes next Component Evidence entry from list and returns it
+ * Add an entry to the Component Evidence cache list
+ *
+ * @param evid Component Evidence entry
+ */
+ void (*add_evidence)(imc_attestation_state_t *this, pts_comp_evidence_t *evid);
+
+ /**
+ * Removes next entry from the Component Evidence cache list and returns it
*
* @param evid Next Component Evidence entry
* @return TRUE if next entry is available
diff --git a/src/libpts/plugins/imv_attestation/Makefile.am b/src/libpts/plugins/imv_attestation/Makefile.am
index a550a3552..5e7465195 100644
--- a/src/libpts/plugins/imv_attestation/Makefile.am
+++ b/src/libpts/plugins/imv_attestation/Makefile.am
@@ -31,3 +31,5 @@ attest_LDADD = \
$(top_builddir)/src/libpts/libpts.la \
$(top_builddir)/src/libstrongswan/libstrongswan.la
attest.o : $(top_builddir)/config.status
+
+EXTRA_DIST = build-database.sh
diff --git a/src/libpts/plugins/imv_attestation/Makefile.in b/src/libpts/plugins/imv_attestation/Makefile.in
index 989a173b5..afb4abed7 100644
--- a/src/libpts/plugins/imv_attestation/Makefile.in
+++ b/src/libpts/plugins/imv_attestation/Makefile.in
@@ -51,6 +51,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
@@ -94,7 +95,7 @@ attest_OBJECTS = $(am_attest_OBJECTS)
attest_DEPENDENCIES = $(top_builddir)/src/libimcv/libimcv.la \
$(top_builddir)/src/libpts/libpts.la \
$(top_builddir)/src/libstrongswan/libstrongswan.la
-DEFAULT_INCLUDES = -I.@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
@@ -120,6 +121,7 @@ AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
+BFDLIB = @BFDLIB@
BTLIB = @BTLIB@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
@@ -214,11 +216,14 @@ build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
c_plugins = @c_plugins@
+charon_natt_port = @charon_natt_port@
+charon_plugins = @charon_plugins@
+charon_udp_port = @charon_udp_port@
clearsilver_LIBS = @clearsilver_LIBS@
datadir = @datadir@
datarootdir = @datarootdir@
dbusservicedir = @dbusservicedir@
-default_pkcs11 = @default_pkcs11@
+dev_headers = @dev_headers@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
@@ -235,11 +240,12 @@ imcvdir = @imcvdir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
+ipsec_script = @ipsec_script@
+ipsec_script_upper = @ipsec_script_upper@
ipsecdir = @ipsecdir@
ipsecgroup = @ipsecgroup@
ipseclibdir = @ipseclibdir@
ipsecuser = @ipsecuser@
-libcharon_plugins = @libcharon_plugins@
libdir = @libdir@
libexecdir = @libexecdir@
linux_headers = @linux_headers@
@@ -255,6 +261,7 @@ mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
nm_LIBS = @nm_LIBS@
nm_ca_dir = @nm_ca_dir@
+nm_plugins = @nm_plugins@
oldincludedir = @oldincludedir@
openac_plugins = @openac_plugins@
p_plugins = @p_plugins@
@@ -264,7 +271,6 @@ pdfdir = @pdfdir@
piddir = @piddir@
pki_plugins = @pki_plugins@
plugindir = @plugindir@
-pluto_plugins = @pluto_plugins@
pool_plugins = @pool_plugins@
prefix = @prefix@
program_transform_name = @program_transform_name@
@@ -321,6 +327,7 @@ attest_LDADD = \
$(top_builddir)/src/libpts/libpts.la \
$(top_builddir)/src/libstrongswan/libstrongswan.la
+EXTRA_DIST = build-database.sh
all: all-am
.SUFFIXES:
diff --git a/src/libpts/plugins/imv_attestation/attest.c b/src/libpts/plugins/imv_attestation/attest.c
index 9200820e8..a202d128f 100644
--- a/src/libpts/plugins/imv_attestation/attest.c
+++ b/src/libpts/plugins/imv_attestation/attest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
/**
* global debug output variables
*/
-static int debug_level = 2;
+static int debug_level = 1;
static bool stderr_quiet = TRUE;
/**
@@ -131,9 +131,14 @@ static void do_args(int argc, char *argv[])
{ "directory", required_argument, NULL, 'D' },
{ "dir", required_argument, NULL, 'D' },
{ "file", required_argument, NULL, 'F' },
+ { "sha1-ima", no_argument, NULL, 'I' },
{ "key", required_argument, NULL, 'K' },
{ "owner", required_argument, NULL, 'O' },
{ "product", required_argument, NULL, 'P' },
+ { "relative", no_argument, NULL, 'R' },
+ { "rel", no_argument, NULL, 'R' },
+ { "sequence", required_argument, NULL, 'S' },
+ { "seq", required_argument, NULL, 'S' },
{ "sha1", no_argument, NULL, '1' },
{ "sha256", no_argument, NULL, '2' },
{ "sha384", no_argument, NULL, '3' },
@@ -232,6 +237,9 @@ static void do_args(int argc, char *argv[])
exit(EXIT_FAILURE);
}
continue;
+ case 'I':
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA1_IMA);
+ continue;
case 'K':
{
chunk_t aik;
@@ -252,6 +260,12 @@ static void do_args(int argc, char *argv[])
exit(EXIT_FAILURE);
}
continue;
+ case 'R':
+ attest->set_relative(attest);
+ continue;
+ case 'S':
+ attest->set_sequence(attest, atoi(optarg));
+ continue;
case '1':
attest->set_algo(attest, PTS_MEAS_ALGO_SHA1);
continue;
diff --git a/src/libpts/plugins/imv_attestation/attest_db.c b/src/libpts/plugins/imv_attestation/attest_db.c
index 88d19eee1..55afbf701 100644
--- a/src/libpts/plugins/imv_attestation/attest_db.c
+++ b/src/libpts/plugins/imv_attestation/attest_db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -16,8 +16,14 @@
#include "attest_db.h"
#include "libpts.h"
+#include "pts/pts_meas_algo.h"
+#include "pts/pts_file_meas.h"
#include "pts/components/pts_comp_func_name.h"
+#include <libgen.h>
+
+#define IMA_MAX_NAME_LEN 255
+
typedef struct private_attest_db_t private_attest_db_t;
/**
@@ -106,6 +112,16 @@ struct private_attest_db_t {
bool product_set;
/**
+ * TRUE if relative filenames are to be used
+ */
+ bool relative;
+
+ /**
+ * Sequence number for ordering entries
+ */
+ int seq_no;
+
+ /**
* File measurement hash algorithm
*/
pts_meas_algorithms_t algo;
@@ -175,7 +191,7 @@ METHOD(attest_db_t, set_component, bool,
e = this->db->query(this->db,
"SELECT id FROM components "
"WHERE vendor_id = ? AND name = ? AND qualifier = ?",
- DB_INT, vid, DB_INT, name, DB_INT, qualifier, DB_INT);
+ DB_UINT, vid, DB_INT, name, DB_INT, qualifier, DB_INT);
if (e)
{
if (e->enumerate(e, &this->cid))
@@ -231,7 +247,7 @@ METHOD(attest_db_t, set_cid, bool,
e = this->db->query(this->db, "SELECT vendor_id, name, qualifier "
"FROM components WHERE id = ?",
- DB_INT, cid, DB_INT, DB_INT, DB_INT);
+ DB_UINT, cid, DB_INT, DB_INT, DB_INT);
if (e)
{
if (e->enumerate(e, &vid, &name, &qualifier))
@@ -252,6 +268,7 @@ METHOD(attest_db_t, set_directory, bool,
private_attest_db_t *this, char *dir, bool create)
{
enumerator_t *e;
+ size_t len;
if (this->dir_set)
{
@@ -259,6 +276,13 @@ METHOD(attest_db_t, set_directory, bool,
return FALSE;
}
free(this->dir);
+
+ /* remove trailing '/' character */
+ len = strlen(dir);
+ if (len && dir[len-1] == '/')
+ {
+ dir[len-1] = '\0';
+ }
this->dir = strdup(dir);
e = this->db->query(this->db,
@@ -308,7 +332,7 @@ METHOD(attest_db_t, set_did, bool,
this->did = did;
e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
- DB_INT, did, DB_TEXT);
+ DB_UINT, did, DB_TEXT);
if (e)
{
if (e->enumerate(e, &dir))
@@ -330,6 +354,7 @@ METHOD(attest_db_t, set_file, bool,
private_attest_db_t *this, char *file, bool create)
{
enumerator_t *e;
+ char *filename;
if (this->file_set)
{
@@ -337,9 +362,10 @@ METHOD(attest_db_t, set_file, bool,
return FALSE;
}
this->file = strdup(file);
+ filename = this->relative ? basename(file) : file;
e = this->db->query(this->db, "SELECT id FROM files WHERE path = ?",
- DB_TEXT, file, DB_INT);
+ DB_TEXT, filename, DB_INT);
if (e)
{
if (e->enumerate(e, &this->fid))
@@ -362,9 +388,9 @@ METHOD(attest_db_t, set_file, bool,
/* Add a new database entry */
this->file_set = this->db->execute(this->db, &this->fid,
"INSERT INTO files (type, path) VALUES (0, ?)",
- DB_TEXT, file) == 1;
+ DB_TEXT, filename) == 1;
- printf("file '%s' %sinserted into database\n", file,
+ printf("file '%s' %sinserted into database\n", filename,
this->file_set ? "" : "could not be ");
return this->file_set;
@@ -384,7 +410,7 @@ METHOD(attest_db_t, set_fid, bool,
this->fid = fid;
e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
- DB_INT, fid, DB_TEXT);
+ DB_UINT, fid, DB_TEXT);
if (e)
{
if (e->enumerate(e, &file))
@@ -468,7 +494,7 @@ METHOD(attest_db_t, set_kid, bool,
this->kid = kid;
e = this->db->query(this->db, "SELECT keyid, owner FROM keys WHERE id = ?",
- DB_INT, kid, DB_BLOB, DB_TEXT);
+ DB_UINT, kid, DB_BLOB, DB_TEXT);
if (e)
{
if (e->enumerate(e, &key, &owner))
@@ -545,7 +571,7 @@ METHOD(attest_db_t, set_pid, bool,
this->pid = pid;
e = this->db->query(this->db, "SELECT name FROM products WHERE id = ?",
- DB_INT, pid, DB_TEXT);
+ DB_UINT, pid, DB_TEXT);
if (e)
{
if (e->enumerate(e, &product))
@@ -568,6 +594,18 @@ METHOD(attest_db_t, set_algo, void,
this->algo = algo;
}
+METHOD(attest_db_t, set_relative, void,
+ private_attest_db_t *this)
+{
+ this->relative = TRUE;
+}
+
+METHOD(attest_db_t, set_sequence, void,
+ private_attest_db_t *this, int seq_no)
+{
+ this->seq_no = seq_no;
+}
+
METHOD(attest_db_t, set_owner, void,
private_attest_db_t *this, char *owner)
{
@@ -580,16 +618,29 @@ METHOD(attest_db_t, list_components, void,
{
enumerator_t *e;
pts_comp_func_name_t *cfn;
- int cid, vid, name, qualifier, count = 0;
+ int seq_no, cid, vid, name, qualifier, count = 0;
if (this->kid)
{
e = this->db->query(this->db,
- "SELECT c.id, c.vendor_id, c.name, c.qualifier "
+ "SELECT kc.seq_no, c.id, c.vendor_id, c.name, c.qualifier "
"FROM components AS c "
"JOIN key_component AS kc ON c.id = kc.component "
- "WHERE kc.key = ? ORDER BY c.vendor_id, c.name, c.qualifier",
- DB_INT, this->kid, DB_INT, DB_INT, DB_INT, DB_INT);
+ "WHERE kc.key = ? ORDER BY kc.seq_no",
+ DB_UINT, this->kid, DB_INT, DB_INT, DB_INT, DB_INT, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &cid, &seq_no, &vid, &name, &qualifier))
+ {
+ cfn = pts_comp_func_name_create(vid, name, qualifier);
+ printf("%4d: #%-2d %s\n", seq_no, cid, print_cfn(cfn));
+ cfn->destroy(cfn);
+ count++;
+ }
+ e->destroy(e);
+ printf("%d component%s found for key %#B\n", count,
+ (count == 1) ? "" : "s", &this->key);
+ }
}
else
{
@@ -597,24 +648,18 @@ METHOD(attest_db_t, list_components, void,
"SELECT id, vendor_id, name, qualifier FROM components "
"ORDER BY vendor_id, name, qualifier",
DB_INT, DB_INT, DB_INT, DB_INT);
- }
- if (e)
- {
- while (e->enumerate(e, &cid, &vid, &name, &qualifier))
- {
- cfn = pts_comp_func_name_create(vid, name, qualifier);
- printf("%3d: %s\n", cid, print_cfn(cfn));
- cfn->destroy(cfn);
- count++;
- }
- e->destroy(e);
-
- printf("%d component%s found", count, (count == 1) ? "" : "s");
- if (this->key_set)
+ if (e)
{
- printf(" for key %#B", &this->key);
+ while (e->enumerate(e, &cid, &vid, &name, &qualifier))
+ {
+ cfn = pts_comp_func_name_create(vid, name, qualifier);
+ printf("%4d: %s\n", cid, print_cfn(cfn));
+ cfn->destroy(cfn);
+ count++;
+ }
+ e->destroy(e);
+ printf("%d component%s found\n", count, (count == 1) ? "" : "s");
}
- printf("\n");
}
}
@@ -632,12 +677,12 @@ METHOD(attest_db_t, list_keys, void,
"SELECT k.id, k.keyid, k.owner FROM keys AS k "
"JOIN key_component AS kc ON k.id = kc.key "
"WHERE kc.component = ? ORDER BY k.keyid",
- DB_INT, this->cid, DB_INT, DB_BLOB, DB_TEXT);
+ DB_UINT, this->cid, DB_INT, DB_BLOB, DB_TEXT);
if (e)
{
while (e->enumerate(e, &kid, &keyid, &owner))
{
- printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+ printf("%4d: %#B '%s'\n", kid, &keyid, owner);
count++;
}
e->destroy(e);
@@ -652,7 +697,7 @@ METHOD(attest_db_t, list_keys, void,
{
while (e->enumerate(e, &kid, &keyid, &owner))
{
- printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+ printf("%4d: %#B '%s'\n", kid, &keyid, owner);
count++;
}
e->destroy(e);
@@ -681,13 +726,13 @@ METHOD(attest_db_t, list_files, void,
"FROM files AS f "
"JOIN product_file AS pf ON f.id = pf.file "
"WHERE pf.product = ? ORDER BY f.path",
- DB_INT, this->pid, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
+ DB_UINT, this->pid, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
if (e)
{
while (e->enumerate(e, &fid, &type, &file, &meas, &meta))
{
type = (type < 0 || type > 2) ? 0 : type;
- printf("%3d: |%s%s| %s %s\n", fid, meas ? "M":" ", meta ? "T":" ",
+ printf("%4d: |%s%s| %s %s\n", fid, meas ? "M":" ", meta ? "T":" ",
file_type[type], file);
count++;
}
@@ -705,7 +750,7 @@ METHOD(attest_db_t, list_files, void,
while (e->enumerate(e, &fid, &type, &file))
{
type = (type < 0 || type > 2) ? 0 : type;
- printf("%3d: %s %s\n", fid, file_type[type], file);
+ printf("%4d: %s %s\n", fid, file_type[type], file);
count++;
}
e->destroy(e);
@@ -734,12 +779,12 @@ METHOD(attest_db_t, list_products, void,
"FROM products AS p "
"JOIN product_file AS pf ON p.id = pf.product "
"WHERE pf.file = ? ORDER BY p.name",
- DB_INT, this->fid, DB_INT, DB_TEXT, DB_INT, DB_INT);
+ DB_UINT, this->fid, DB_INT, DB_TEXT, DB_INT, DB_INT);
if (e)
{
while (e->enumerate(e, &pid, &product, &meas, &meta))
{
- printf("%3d: |%s%s| %s\n", pid, meas ? "M":" ", meta ? "T":" ",
+ printf("%4d: |%s%s| %s\n", pid, meas ? "M":" ", meta ? "T":" ",
product);
count++;
}
@@ -755,7 +800,7 @@ METHOD(attest_db_t, list_products, void,
{
while (e->enumerate(e, &pid, &product))
{
- printf("%3d: %s\n", pid, product);
+ printf("%4d: %s\n", pid, product);
count++;
}
e->destroy(e);
@@ -785,7 +830,7 @@ static void get_directory(private_attest_db_t *this, int did, char **directory)
{
e = this->db->query(this->db,
"SELECT path from files WHERE id = ?",
- DB_INT, did, DB_TEXT);
+ DB_UINT, did, DB_TEXT);
if (e)
{
if (e->enumerate(e, &dir))
@@ -826,17 +871,17 @@ METHOD(attest_db_t, list_hashes, void,
{
if (this->fid != fid_old)
{
- printf("%3d: %s%s%s\n", this->fid, this->dir,
+ printf("%4d: %s%s%s\n", this->fid, this->dir,
slash(this->dir, this->file) ? "/" : "", this->file);
fid_old = this->fid;
}
- printf(" %#B\n", &hash);
+ printf(" %#B\n", &hash);
count++;
}
e->destroy(e);
printf("%d %N value%s found for product '%s'\n", count,
- hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ pts_meas_algorithm_names, this->algo,
(count == 1) ? "" : "s", this->product);
}
}
@@ -848,7 +893,7 @@ METHOD(attest_db_t, list_hashes, void,
"JOIN files AS f ON f.id = fh.file "
"WHERE fh.algo = ? AND fh.product = ? "
"ORDER BY fh.directory, f.path",
- DB_INT, this->algo, DB_INT, this->pid,
+ DB_INT, this->algo, DB_UINT, this->pid,
DB_INT, DB_TEXT, DB_BLOB, DB_INT);
if (e)
{
@@ -860,18 +905,18 @@ METHOD(attest_db_t, list_hashes, void,
{
get_directory(this, did, &dir);
}
- printf("%3d: %s%s%s\n", fid,
+ printf("%4d: %s%s%s\n", fid,
dir, slash(dir, file) ? "/" : "", file);
fid_old = fid;
did_old = did;
}
- printf(" %#B\n", &hash);
+ printf(" %#B\n", &hash);
count++;
}
e->destroy(e);
printf("%d %N value%s found for product '%s'\n", count,
- hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ pts_meas_algorithm_names, this->algo,
(count == 1) ? "" : "s", this->product);
}
}
@@ -883,7 +928,7 @@ METHOD(attest_db_t, list_hashes, void,
"JOIN products AS p ON p.id = fh.product "
"WHERE fh.algo = ? AND fh.file = ? AND fh.directory = ?"
"ORDER BY p.name",
- DB_INT, this->algo, DB_INT, this->fid, DB_INT, this->did,
+ DB_INT, this->algo, DB_UINT, this->fid, DB_UINT, this->did,
DB_TEXT, DB_BLOB, DB_INT);
if (e)
{
@@ -895,7 +940,7 @@ METHOD(attest_db_t, list_hashes, void,
e->destroy(e);
printf("%d %N value%s found for file '%s%s%s'\n",
- count, hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ count, pts_meas_algorithm_names, this->algo,
(count == 1) ? "" : "s", this->dir,
slash(this->dir, this->file) ? "/" : "", this->file);
}
@@ -922,17 +967,17 @@ METHOD(attest_db_t, list_hashes, void,
get_directory(this, did, &dir);
did_old = did;
}
- printf("%3d: %s%s%s\n", fid,
+ printf("%4d: %s%s%s\n", fid,
dir, slash(dir, file) ? "/" : "", file);
fid_old = fid;
}
- printf(" %#B '%s'\n", &hash, product);
+ printf(" %#B '%s'\n", &hash, product);
count++;
}
e->destroy(e);
- printf("%d %N value%s found\n", count, hash_algorithm_names,
- pts_meas_algo_to_hash(this->algo), (count == 1) ? "" : "s");
+ printf("%d %N value%s found\n", count, pts_meas_algorithm_names,
+ this->algo, (count == 1) ? "" : "s");
}
}
free(dir);
@@ -956,7 +1001,7 @@ METHOD(attest_db_t, list_measurements, void,
"JOIN keys AS k ON k.id = ch.key "
"WHERE ch.algo = ? AND ch.key = ? AND ch.component = ? "
"ORDER BY seq_no",
- DB_INT, this->algo, DB_INT, this->kid, DB_INT, this->cid,
+ DB_INT, this->algo, DB_UINT, this->kid, DB_UINT, this->cid,
DB_INT, DB_INT, DB_BLOB, DB_TEXT);
if (e)
{
@@ -964,16 +1009,16 @@ METHOD(attest_db_t, list_measurements, void,
{
if (this->kid != kid_old)
{
- printf("%3d: %#B '%s'\n", this->kid, &this->key, owner);
+ printf("%4d: %#B '%s'\n", this->kid, &this->key, owner);
kid_old = this->kid;
}
- printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+ printf("%7d %02d %#B\n", seq_no, pcr, &hash);
count++;
}
e->destroy(e);
printf("%d %N value%s found for component '%s'\n", count,
- hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ pts_meas_algorithm_names, this->algo,
(count == 1) ? "" : "s", print_cfn(this->cfn));
}
}
@@ -985,7 +1030,7 @@ METHOD(attest_db_t, list_measurements, void,
"JOIN keys AS k ON k.id = ch.key "
"WHERE ch.algo = ? AND ch.component = ? "
"ORDER BY keyid, seq_no",
- DB_INT, this->algo, DB_INT, this->cid,
+ DB_INT, this->algo, DB_UINT, this->cid,
DB_INT, DB_INT, DB_BLOB, DB_INT, DB_BLOB, DB_TEXT);
if (e)
{
@@ -993,16 +1038,16 @@ METHOD(attest_db_t, list_measurements, void,
{
if (kid != kid_old)
{
- printf("%3d: %#B '%s'\n", kid, &keyid, owner);
+ printf("%4d: %#B '%s'\n", kid, &keyid, owner);
kid_old = kid;
}
- printf("%5d %02d %#B\n", seq_no, pcr, &hash);
+ printf("%7d %02d %#B\n", seq_no, pcr, &hash);
count++;
}
e->destroy(e);
printf("%d %N value%s found for component '%s'\n", count,
- hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ pts_meas_algorithm_names, this->algo,
(count == 1) ? "" : "s", print_cfn(this->cfn));
}
@@ -1016,7 +1061,7 @@ METHOD(attest_db_t, list_measurements, void,
"JOIN components AS c ON c.id = ch.component "
"WHERE ch.algo = ? AND ch.key = ? "
"ORDER BY vendor_id, name, qualifier, seq_no",
- DB_INT, this->algo, DB_INT, this->kid, DB_INT, DB_INT, DB_BLOB,
+ DB_INT, this->algo, DB_UINT, this->kid, DB_INT, DB_INT, DB_BLOB,
DB_INT, DB_INT, DB_INT, DB_INT);
if (e)
{
@@ -1026,7 +1071,7 @@ METHOD(attest_db_t, list_measurements, void,
if (cid != cid_old)
{
cfn = pts_comp_func_name_create(vid, name, qualifier);
- printf("%3d: %s\n", cid, print_cfn(cfn));
+ printf("%4d: %s\n", cid, print_cfn(cfn));
cfn->destroy(cfn);
cid_old = cid;
}
@@ -1036,25 +1081,189 @@ METHOD(attest_db_t, list_measurements, void,
e->destroy(e);
printf("%d %N value%s found for key %#B '%s'\n", count,
- hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ pts_meas_algorithm_names, this->algo,
(count == 1) ? "" : "s", &this->key, this->owner);
}
}
}
+bool insert_file_hash(private_attest_db_t *this, pts_meas_algorithms_t algo,
+ chunk_t measurement, int fid, int did, bool ima,
+ int *hashes_added)
+{
+ enumerator_t *e;
+ chunk_t hash;
+ char *label;
+
+ label = "could not be created";
+
+ e = this->db->query(this->db,
+ "SELECT hash FROM file_hashes WHERE algo = ? "
+ "AND file = ? AND directory = ? AND product = ? and key = 0",
+ DB_INT, algo, DB_UINT, fid, DB_UINT, did, DB_UINT, this->pid, DB_BLOB);
+ if (!e)
+ {
+ printf("file_hashes query failed\n");
+ return FALSE;
+ }
+ if (e->enumerate(e, &hash))
+ {
+ label = chunk_equals(measurement, hash) ?
+ "exists and equals" : "exists and differs";
+ }
+ else
+ {
+ if (this->db->execute(this->db, NULL,
+ "INSERT INTO file_hashes "
+ "(file, directory, product, key, algo, hash) "
+ "VALUES (?, ?, ?, 0, ?, ?)",
+ DB_UINT, fid, DB_UINT, did, DB_UINT, this->pid,
+ DB_INT, algo, DB_BLOB, measurement) == 1)
+ {
+ label = "created";
+ (*hashes_added)++;
+ }
+ }
+ e->destroy(e);
+
+ printf(" %#B - %s%s\n", &measurement, ima ? "ima - " : "", label);
+ return TRUE;
+}
+
METHOD(attest_db_t, add, bool,
private_attest_db_t *this)
{
bool success = FALSE;
+ /* add key/component pair */
if (this->kid && this->cid)
{
success = this->db->execute(this->db, NULL,
- "INSERT INTO key_component (key, component) VALUES (?, ?)",
- DB_UINT, this->kid, DB_UINT, this->cid) == 1;
+ "INSERT INTO key_component (key, component, seq_no) "
+ "VALUES (?, ?, ?)",
+ DB_UINT, this->kid, DB_UINT, this->cid,
+ DB_UINT, this->seq_no) == 1;
- printf("key/component pair (%d/%d) %sinserted into database\n",
- this->kid, this->cid, success ? "" : "could not be ");
+ printf("key/component pair (%d/%d) %sinserted into database at "
+ "position %d\n", this->kid, this->cid,
+ success ? "" : "could not be ", this->seq_no);
+
+ return success;
+ }
+
+ /* add directory or file measurement for a given product */
+ if ((this->did || this->fid) && this->pid)
+ {
+ char *pathname, *filename, *label;
+ char ima_buffer[IMA_MAX_NAME_LEN + 1];
+ chunk_t measurement, ima_template;
+ pts_file_meas_t *measurements;
+ hasher_t *hasher = NULL;
+ bool ima = FALSE;
+ int fid, did;
+ int files_added = 0, hashes_added = 0, ima_hashes_added = 0;
+ enumerator_t *enumerator, *e;
+
+ if (this->algo == PTS_MEAS_ALGO_SHA1_IMA)
+ {
+ ima = TRUE;
+ this->algo = PTS_MEAS_ALGO_SHA1;
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ printf("could not create hasher\n");
+ return FALSE;
+ }
+ }
+
+ pathname = this->did ? this->dir : this->file;
+ measurements = pts_file_meas_create_from_path(0, pathname, this->did,
+ this->relative, this->algo);
+ if (!measurements)
+ {
+ printf("file measurement failed\n");
+ DESTROY_IF(hasher);
+ return FALSE;
+ }
+ if (this->fid && this->relative)
+ {
+ set_directory(this, dirname(pathname), TRUE);
+ }
+ did = this->relative ? this->did : 0;
+
+ enumerator = measurements->create_enumerator(measurements);
+ while (enumerator->enumerate(enumerator, &filename, &measurement))
+ {
+ /* retrieve or create filename */
+ label = "could not be created";
+
+ e = this->db->query(this->db,
+ "SELECT id FROM files WHERE path = ?",
+ DB_TEXT, filename, DB_INT);
+ if (!e)
+ {
+ printf("files query failed\n");
+ break;
+ }
+ if (e->enumerate(e, &fid))
+ {
+ label = "exists";
+ }
+ else
+ {
+ if (this->db->execute(this->db, &fid,
+ "INSERT INTO files (type, path) VALUES (0, ?)",
+ DB_TEXT, filename) == 1)
+ {
+ label = "created";
+ files_added++;
+ }
+ }
+ e->destroy(e);
+
+ printf("%4d: %s - %s\n", fid, filename, label);
+
+ /* compute file measurement hash */
+ if (!insert_file_hash(this, this->algo, measurement,
+ fid, did, FALSE, &hashes_added))
+ {
+ break;
+ }
+
+ if (!ima)
+ {
+ continue;
+ }
+
+ /* compute IMA template hash */
+ strncpy(ima_buffer, filename, IMA_MAX_NAME_LEN);
+ ima_buffer[IMA_MAX_NAME_LEN] = '\0';
+ ima_template = chunk_create(ima_buffer, sizeof(ima_buffer));
+ if (!hasher->get_hash(hasher, measurement, NULL) ||
+ !hasher->get_hash(hasher, ima_template, measurement.ptr))
+ {
+ printf("could not compute IMA template hash\n");
+ break;
+ }
+ if (!insert_file_hash(this, PTS_MEAS_ALGO_SHA1_IMA, measurement,
+ fid, did, TRUE, &ima_hashes_added))
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ printf("%d measurements, added %d new files, %d new file hashes",
+ measurements->get_file_count(measurements),
+ files_added, hashes_added);
+ if (ima)
+ {
+ printf(" , %d new ima hashes", ima_hashes_added);
+ hasher->destroy(hasher);
+ }
+ printf("\n");
+ measurements->destroy(measurements);
+ success = TRUE;
}
return success;
}
@@ -1064,12 +1273,42 @@ METHOD(attest_db_t, delete, bool,
{
bool success;
+ /* delete a file measurement hash for a given product */
+ if (this->algo && this->pid && this->fid)
+ {
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM file_hashes "
+ "WHERE algo = ? AND product = ? "
+ "AND file = ? AND directory = ?",
+ DB_UINT, this->algo, DB_UINT, this->pid,
+ DB_UINT, this->fid, DB_UINT, this->did) > 0;
+
+ printf("%4d: %s%s%s\n", this->fid, this->dir, this->did ? "/":"",
+ this->file);
+ printf("%N value for product '%s' %sdeleted from database\n",
+ pts_meas_algorithm_names, this->algo, this->product,
+ success ? "" : "could not be ");
+
+ return success;
+ }
+
+ /* delete product/file entries */
if (this->pid && (this->fid || this->did))
{
- printf("deletion of product/file entries not supported yet\n");
- return FALSE;
+ success = this->db->execute(this->db, NULL,
+ "DELETE FROM product_file "
+ "WHERE product = ? AND file = ?",
+ DB_UINT, this->pid,
+ DB_UINT, this->fid ? this->fid : this->did) > 0;
+
+ printf("product/file pair (%d/%d) %sdeleted from database\n",
+ this->pid, this->fid ? this->fid : this->did,
+ success ? "" : "could not be ");
+
+ return success;
}
+ /* delete key/component pair */
if (this->kid && this->cid)
{
success = this->db->execute(this->db, NULL,
@@ -1173,6 +1412,8 @@ attest_db_t *attest_db_create(char *uri)
.set_product = _set_product,
.set_pid = _set_pid,
.set_algo = _set_algo,
+ .set_relative = _set_relative,
+ .set_sequence = _set_sequence,
.set_owner = _set_owner,
.list_products = _list_products,
.list_files = _list_files,
@@ -1185,7 +1426,6 @@ attest_db_t *attest_db_create(char *uri)
.destroy = _destroy,
},
.dir = strdup(""),
- .algo = PTS_MEAS_ALGO_SHA256,
.db = lib->db->create(lib->db, uri),
);
diff --git a/src/libpts/plugins/imv_attestation/attest_db.h b/src/libpts/plugins/imv_attestation/attest_db.h
index 9c9a9dcba..e32a368d8 100644
--- a/src/libpts/plugins/imv_attestation/attest_db.h
+++ b/src/libpts/plugins/imv_attestation/attest_db.h
@@ -126,6 +126,21 @@ struct attest_db_t {
void (*set_algo)(attest_db_t *this, pts_meas_algorithms_t algo);
/**
+ * Set that the IMA-specific SHA-1 template hash be computed
+ */
+ void (*set_ima)(attest_db_t *this);
+
+ /**
+ * Set that relative filenames are to be used
+ */
+ void (*set_relative)(attest_db_t *this);
+
+ /**
+ * Set the sequence number
+ */
+ void (*set_sequence)(attest_db_t *this, int seq_no);
+
+ /**
* Set owner [user/host] of an AIK
*
* @param owner user/host name
diff --git a/src/libpts/plugins/imv_attestation/attest_usage.c b/src/libpts/plugins/imv_attestation/attest_usage.c
index e58f821e0..f7040f7ad 100644
--- a/src/libpts/plugins/imv_attestation/attest_usage.c
+++ b/src/libpts/plugins/imv_attestation/attest_usage.c
@@ -40,7 +40,7 @@ Usage:\n\
Show a list of measurement hashes for a given software product or\n\
its primary key as an optional selector.\n\
\n\
- ipsec attest --hashes [--sha1|--sha256|--sha384] [--file <path>|--fid <id>]\n\
+ ipsec attest --hashes [--sha1|--sha1-ima|--sha256|--sha384] [--file <path>|--fid <id>]\n\
Show a list of measurement hashes for a given file or\n\
its primary key as an optional selector.\n\
\n\
@@ -52,11 +52,11 @@ Usage:\n\
Show a list of AIK key digests with a component or\n\
its primary key as an optional selector.\n\
\n\
- ipsec attest --measurements [--sha1|--sha256|--sha384] [--component <cfn>|--cid <id>]\n\
+ ipsec attest --measurements --sha1|--sha256|--sha384 [--component <cfn>|--cid <id>]\n\
Show a list of component measurements for a given component or\n\
its primary key as an optional selector.\n\
\n\
- ipsec attest --measurements [--sha1|--sha256|--sha384] [--key <digest>|--kid <id>|--aik <path>]\n\
+ ipsec attest --measurements --sha1|--sha256|--sha384 [--key <digest>|--kid <id>|--aik <path>]\n\
Show a list of component measurements for a given AIK or\n\
its primary key as an optional selector.\n\
\n\
@@ -67,14 +67,31 @@ Usage:\n\
ipsec attest --add [--owner <name>] --key <digest>|--aik <path>\n\
Add an AIK public key digest entry preceded by an optional owner name\n\
\n\
+ ipsec attest --add --product <name>|--pid <id> --sha1|--sha1-ima|--sha256|--sha384\n\
+ [--relative|--rel] --dir <path>|--file <path>\n\
+ Add hashes of a single file or all files in a directory under absolute or relative filenames\n\
+ \n\
+ ipsec attest --add --key <digest|--kid <id> --component <cfn>|--cid <id> --sequence <no>|--seq <no>\n\
+ Add an ordered key/component entry\n\
+ \n\
ipsec attest --del --file <path>|--fid <id>|--dir <path>|--did <id>\n\
Delete a file or directory entry referenced either by value or primary key\n\
\n\
ipsec attest --del --product <name>|--pid <id>|--component <cfn>|--cid <id>\n\
Delete a product or component entry referenced either by value or primary key\n\
\n\
+ ipsec attest --del --product <name>|--pid <id> --file <path>|--fid <id>|--dir <path>|--did <id>\n\
+ Delete a product/file entry referenced either by value or primary key\n\
+ \n\
ipsec attest --del --key <digest>|--kid <id>|--aik <path>\n\
Delete an AIK entry referenced either by value or primary key\n\
+ \n\
+ ipsec attest --del --key <digest|--kid <id> --component <cfn>|--cid <id>\n\
+ Delete a key/component entry\n\
+ \n\
+ ipsec attest --del --product <name>|--pid <id> --sha1|--sha1-ima|--sha256|--sha384\n\
+ [--dir <path>|--did <id>] --file <path>|--fid <id>\n\
+ Delete a file hash given an absolute or relative filename\n\
\n");
}
diff --git a/src/libpts/plugins/imv_attestation/build-database.sh b/src/libpts/plugins/imv_attestation/build-database.sh
new file mode 100755
index 000000000..a89258e1d
--- /dev/null
+++ b/src/libpts/plugins/imv_attestation/build-database.sh
@@ -0,0 +1,221 @@
+#!/bin/sh
+
+p="Ubuntu 12.04.1 LTS i686"
+
+ipsec attest --add --product "$p" --sha1-ima --dir /sbin
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/sbin
+ipsec attest --add --product "$p" --sha1-ima --dir /bin
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/bin
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/acpi
+ipsec attest --add --product "$p" --sha1-ima --file /etc/init.d/rc
+ipsec attest --add --product "$p" --sha1-ima --file /etc/init.d/rcS
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/network/if-post-down.d
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/network/if-pre-up.d
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/network/if-up.d
+ipsec attest --add --product "$p" --sha1-ima --file /etc/NetworkManager/dispatcher.d/01ifupdown
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/ppp/ip-down.d
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/rc2.d
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/rcS.d
+ipsec attest --add --product "$p" --sha1-ima --file /etc/rc.local
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/resolvconf/update.d
+ipsec attest --add --product "$p" --sha1-ima --file /etc/resolvconf/update-libc.d/avahi-daemon
+ipsec attest --add --product "$p" --sha1-ima --dir /etc/update-motd.d
+ipsec attest --add --product "$p" --sha1-ima --file /lib/crda/setregdomain
+ipsec attest --add --product "$p" --sha1-ima --file /lib/init/apparmor-profile-load
+ipsec attest --add --product "$p" --sha1-ima --file /lib/resolvconf/list-records
+ipsec attest --add --product "$p" --sha1-ima --dir /lib/udev
+ipsec attest --add --product "$p" --sha1-ima --file /lib/ufw/ufw-init
+ipsec attest --add --product "$p" --sha1-ima --file /opt/Adobe/Reader9/Reader/intellinux/bin/acroread
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/accountsservice/accounts-daemon
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/apt/methods
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/at-spi2-core
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/avahi/avahi-daemon-check-dns.sh
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/bamf/bamfdaemon
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/ConsoleKit
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/ConsoleKit/run-seat.d
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/ConsoleKit/run-session.d
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/cups/notifier
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/dconf/dconf-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/dbus-1.0/dbus-daemon-launch-helper
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/deja-dup/deja-dup/deja-dup-monitor
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/evolution/3.2/evolution-alarm-notify
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/firefox/firefox
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/firefox/plugin-container
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gcc/i686-linux-gnu/4.6/cc1
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gcc/i686-linux-gnu/4.6/collect2
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/geoclue/geoclue-master
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/git-core
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gnome-desktop3/check_gl_texture_size
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gnome-disk-utility/gdu-notification-daemon
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gnome-online-accounts/goa-daemon
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/gnome-settings-daemon
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gnome-user-share/gnome-user-share
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gnome-screensaver/gnome-screensaver-dialog
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/gvfs
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/gvfs//gvfs-fuse-daemon
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/i386-linux-gnu/colord/colord
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/i386-linux-gnu/gconf
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-application/indicator-application-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-appmenu/hud-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-datetime/indicator-datetime-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-messages/indicator-messages-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-printers/indicator-printers-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-session/indicator-session-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/indicator-sound/indicator-sound-service
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/lightdm
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/NetworkManager/nm-dhcp-client.action
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/NetworkManager/nm-dispatcher.action
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/notify-osd/notify-osd
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/nux/unity_support_test
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/pm-utils/power.d
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/pm-utils/sleep.d
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/policykit-1/polkitd
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/pulseaudio/pulse/gconf-helper
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/rtkit/rtkit-daemon
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/system-service/system-service-d
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/telepathy/mission-control-5
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/thunderbird/thunderbird
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/ubuntuone-client
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/ubuntu-geoip/ubuntu-geoip-provider
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/ubuntu-sso-client
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/udisks
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/unity/unity-panel-service
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/unity-lens-applications/unity-applications-daemon
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/unity-lens-files/unity-files-daemon
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/unity-lens-music
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/unity-lens-video/unity-lens-video
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/unity-scope-video-remote/unity-scope-video-remote
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/update-manager/release-upgrade-motd
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/lib/update-notifier
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/upower/upowerd
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/libvte-2.90-9/gnome-pty-helper
+ipsec attest --add --product "$p" --sha1-ima --file /usr/lib/zeitgeist/zeitgeist-fts
+ipsec attest --add --product "$p" --sha1-ima --file /usr/share/apport/apport
+ipsec attest --add --product "$p" --sha1-ima --file /usr/share/apport/apport-checkreports
+ipsec attest --add --product "$p" --sha1-ima --file /usr/share/apport/apport-gtk
+ipsec attest --add --product "$p" --sha1-ima --dir /usr/share/language-tools
+ipsec attest --add --product "$p" --sha1-ima --file /usr/share/virtualbox/VBoxCreateUSBNode.sh
+ipsec attest --add --product "$p" --sha1-ima --relative --file /etc/ld.so.cache
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /lib
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /lib/i386-linux-gnu
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /lib/i386-linux-gnu/security
+for file in `find /lib/modules/3.2.21ima/kernel -name *.ko`
+do
+ipsec attest --add --product "$p" --sha1-ima --relative --file $file
+done
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /lib/plymouth
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /lib/plymouth/renderers
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /lib/security
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /opt/Adobe/Reader9/Reader/intellinux/lib
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/apache2/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/compiz
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/compizconfig/backends/
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/enchant
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/evolution/3.2/libemiscwidgets.so.0.0.0
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/evolution/3.2/libeutil.so.0.0.0
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/evolution/3.2/libgnomecanvas.so.0.0.0
+for file in /usr/lib/firefox/*.so
+do
+ipsec attest --add --product "$p" --sha1-ima --relative --file $file
+done
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/firefox/components/libbrowsercomps.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/firefox/components/libdbusservice.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/firefox/components/libmozgnome.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/firefox-addons/extensions/globalmenu@ubuntu.com/components/libglobalmenu.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/firefox-addons/plugins/nppdf.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/flashplugin-installer/libflashplayer.so
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/gedit/plugins
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/gnome-bluetooth
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/gnome-settings-daemon-3.0
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/gtk-2.0/2.10.0/menuproxies
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/gtk-3.0/3.0.0/menuproxies
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/gtk-3.0/3.0.0/theming-engines
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/alsa-lib
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/dri
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gconf/2
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gconv
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gio/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gtk-2.0/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/engines
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gtk-2.0/2.10.0/immodules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gtk-3.0/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gtk-3.0/3.0.0/immodules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/gvfs
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/libcanberra-0.28
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/mesa
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/mit-krb5
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/openssl-1.0.0/engines
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/pango/1.6.0/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/pkcs11
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/polkit-1/extensions
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/nss
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/sane
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/i386-linux-gnu/sse2
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/indicators3/7
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/indicator-messages/status-providers/1
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/libpeas-1.0/loaders
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/man-db/libman-2.6.1.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/man-db/libmandb-2.6.1.so
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/mission-control-plugins.0
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/ModemManager
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/nautilus/extensions-3.0
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/NetworkManager/libnm-settings-plugin-ifupdown.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/perl/5.14.2/auto/File/Glob/Glob.so
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/pulse-1.1/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/python2.7/lib-dynload
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/apt_inst.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/apt_pkg.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/cairo/_cairo.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/dbus/mainloop/qt.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/_dbus_bindings.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/_dbus_glib_bindings.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/duplicity/_librsync.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gi/_gi.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gi/_gobject/_gobject.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gi/_glib/_glib.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/glib/_glib.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gobject/_gobject.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/atk.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/gtk/_gtk.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/gio/_gio.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/gio/unix.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/pango.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/pangocairo.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/gtk-2.0/pynotify/_pynotify.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/OpenSSL/crypto.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/OpenSSL/rand.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/OpenSSL/SSL.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/PyQt4/QtCore.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/simplejson/_speedups.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/sip.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/twisted/internet/_sigchld.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/twisted/python/_initgroups.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/xapian/_xapian.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/python2.7/dist-packages/zope/interface/_zope_interface_coptimizations.so
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/rsyslog
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/sane
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/sse2
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/sudo
+for file in /usr/lib/thunderbird/*.so
+do
+ipsec attest --add --product "$p" --sha1-ima --relative --file $file
+done
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/thunderbird/components/libdbusservice.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/thunderbird/components/libmozgnome.so
+ipsec attest --add --product "$p" --sha1-ima --relative --file /usr/lib/thunderbird-addons/extensions/globalmenu@ubuntu.com/components/libglobalmenu.so
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/xorg/modules
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/xorg/modules/drivers
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/xorg/modules/extensions
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/lib/xorg/modules/input
+ipsec attest --add --product "$p" --sha1-ima --relative --dir /usr/share/fonts/truetype/ubuntu-font-family
+ipsec attest --del --product "$p" --sha1 --file /lib/resolvconf/list-records
+ipsec attest --del --product "$p" --sha1-ima --file /lib/resolvconf/list-records
+ipsec attest --del --product "$p" --sha1 --file /usr/bin/lsb_release
+ipsec attest --del --product "$p" --sha1-ima --file /usr/bin/lsb_release
+ipsec attest --del --product "$p" --sha1 --file /usr/share/language-tools/language-options
+ipsec attest --del --product "$p" --sha1-ima --file /usr/share/language-tools/language-options
+
diff --git a/src/libpts/plugins/imv_attestation/data.sql b/src/libpts/plugins/imv_attestation/data.sql
index e6e03627a..b1646b724 100644
--- a/src/libpts/plugins/imv_attestation/data.sql
+++ b/src/libpts/plugins/imv_attestation/data.sql
@@ -42,6 +42,18 @@ INSERT INTO products (
'Ubuntu 11.10 i686'
);
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 12.04 LTS i686'
+);
+
+INSERT INTO products (
+ name
+) VALUES (
+ 'Ubuntu 12.04.1 LTS i686'
+);
+
/* Files */
INSERT INTO files ( /* 1 */
@@ -83,7 +95,7 @@ INSERT INTO files (
INSERT INTO files (
type, path
) VALUES (
- 1, '/lib/xtables/'
+ 1, '/lib/xtables'
);
INSERT INTO files (
@@ -176,6 +188,19 @@ INSERT INTO files (
0, '/etc/tnc_config'
);
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/lib/libxtables.so.7'
+);
+
+INSERT INTO files (
+ type, path
+) VALUES (
+ 0, '/sbin/xtables-multi'
+);
+
+
/* Product-File */
INSERT INTO product_file (
@@ -388,6 +413,48 @@ INSERT INTO product_file (
7, 22, 1
);
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 8, 1, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 8, 7, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 8, 22, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 8, 23, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 8, 24, 1
+);
+
+INSERT INTO product_file (
+ product, file, measurement
+) VALUES (
+ 9, 1, 1
+);
+
+INSERT INTO product_file (
+ product, file, metadata
+) VALUES (
+ 9, 22, 1
+);
+
/* File Hashes */
INSERT INTO file_hashes (
@@ -429,6 +496,42 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, product, algo, hash
) VALUES (
+ 1, 8, 32768, X'9c3ed3179990c0ffb3a65b75a09b61faa4aca907'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 8, 16384, X'af474dd532c9f2d85c12368334eda3609a7c6287e08940f078547ab0f2871c94'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 8, 8192, X'a23fa7034dabdce2d10f2893d52b21d14fe24c6ae4c8570fb6c7190228046e4c064c4d29d736cd84ca42a3d9abf9bfde'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 9, 32768, X'9c3ed3179990c0ffb3a65b75a09b61faa4aca907'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 9, 16384, X'af474dd532c9f2d85c12368334eda3609a7c6287e08940f078547ab0f2871c94'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 1, 9, 8192, X'a23fa7034dabdce2d10f2893d52b21d14fe24c6ae4c8570fb6c7190228046e4c064c4d29d736cd84ca42a3d9abf9bfde'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
2, 2, 32768, X'2a4047437e6fb346e2d854fc415e16b80e75bf6b'
);
@@ -736,6 +839,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 8, 7, 8, 32768, X'a93f870078b69ba530e6335eaee698908b12078f'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 8, 16384, X'0c31c1f41a57f4b15fafeb541de475e6da88380c911bb606b35413fda8428006'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 8, 7, 8, 8192, X'bb8fc7073691910d315621de176be64316923782df8d836b384414fd9a3d293be5bea51811ee6ef68a497f12384bba42'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
8, 21, 6, 32768, X'010873de0d682a26e1c6795dd4992248cc47cdd1'
);
@@ -808,6 +929,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 9, 7, 8, 32768, X'225836cb243c3502d90c92c3eb54310403303270'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 8, 16384, X'7862ed16eeb35d2f10e6d416a6fcbe8000ba1bbc2daddd15f43b375686308d7d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 9, 7, 8, 8192, X'd4b6b939d0fdcd84bbc66fbf9bd044a61de823b4acb52e0ead7ae7f955d9b2d6399da1f673eadbb4792b819923e5e845'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
9, 21, 6, 32768, X'e1df4f3949b09c25e15b9c9b7088a60d683903a8'
);
@@ -862,6 +1001,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 10, 7, 8, 32768, X'008374e704c81351c333a214f4ee2d89e996f344'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 8, 16384, X'0e28034f99a3e0cdffa64bf126858afb48ee25b5cbfc70bbcd997bab7ef1e056'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 10, 7, 8, 8192, X'b6e01ba0706e48ce37abef3fbc59a45fd50c7abd3bb7950b1d892bc4a0db3f9784f573d74ef51376267183d26513d1d0'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
10, 21, 6, 32768, X'87df2d01b85d8354819b431bae0a0a65bfc5d2db'
);
@@ -916,6 +1073,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 11, 7, 8, 32768, X'105fc70c5ecde30ebe841ac0a229b77b6d5f3d8a'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 8, 16384, X'e4cdc17b835eabe06d719bccada0e59d3ee5eb3759ca75eb9c037166e8dafd30'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 11, 7, 8, 8192, X'a9f6a18ff6f85208583e0b3fdd2fdafc4575baf5d973c7a831ce74d8bb5a24b8ae8e4504ddefa4a2c2b91f31cd68edea'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
12, 7, 1, 32768, X'6c0b2df4fc4c9122b5762ae140d53fdd1cf9e89b'
);
@@ -952,6 +1127,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 12, 7, 8, 32768, X'a9d8ea0203810d269b3ef3d974fed2ac4d486bae'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 8, 16384, X'c071aedaa6f66f8ab45ce037d72bbc42fb1894ac69ab689ad21ce6ff0c1c5d6a'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 12, 7, 8, 8192, X'1612eb51a3be3fcba24808326e29967b6f798c5140aefc8279601c5f5600030148fd01e8fbe737fba9c3972832e67601'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
13, 7, 1, 32768, X'e2f7b92abda769f82796f57a29801870585dcea3'
);
@@ -988,6 +1181,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 13, 7, 8, 32768, X'da655441bf10f7dc32978474c77903f2f9120cc4'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 8, 16384, X'ec6a4bb332af51cf60cc30ce95197a8c89d42e6135d6e0d4e1d9e4bcc88e838c'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 13, 7, 8, 8192, X'135a84e988f219d5bcd7cb4e7ada6f9239c0164a0021262be0c4f9c00d8bece341aa88e0e35011b195c737e438225f4b'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
14, 7, 1, 32768, X'160d2b04d11eb225fb148615b699081869e15b6c'
);
@@ -1024,6 +1235,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 14, 7, 8, 32768, X'7b401b741cc32bcc86c3eac43059c9dd26e99a40'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 8, 16384, X'9a7cf37befecc40b494f9176bb887dd478e72c750fed8d540e5d7bbf4b5f2765'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 14, 7, 8, 8192, X'161c2f502f10a72ef159b6308219c38cb13387e21645e4357e6934d7afc62727cd76fd518dc6f676e2db47125eb9a2f6'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
15, 7, 1, 32768, X'5a0d07ab036603a76759e5f61f7d04f2d3c056cc'
);
@@ -1060,6 +1289,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 15, 7, 8, 32768, X'129f6ecfb596fd751e33209b2ad2a28f2d243fdc'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 8, 16384, X'2fd1e8874b2faf18973881af54bd3e1fd21aaa8ee181313919569715885e69bc'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 15, 7, 8, 8192, X'3862f52ec823474ccfffeb6ead7c6a18b132057018704cb2fa05b08aaee3a1abfaf0eb4c826348f427dfbbb5b3e56647'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
16, 7, 1, 32768, X'd6c8dfbaae7ab28b5cef2626a2af3f99a6ea4365'
);
@@ -1094,6 +1341,24 @@ INSERT INTO file_hashes (
);
INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 8, 32768, X'2b686cd8359dea842cfdcacf39d22f5e0e6d06f2'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 8, 16384, X'e14fb3f87b9539108e023660f2d7b4fc728b0622a85de89bdc1fe20162f200a3'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 16, 7, 8, 8192, X'6f55292ad4061b0575dca0a3e6abe5f86d5288e0b860e6f76715bd5c9df8b5f751bc547d3147e9da12593b56a3f83252'
+);
+
+INSERT INTO file_hashes (
file, product, algo, hash
) VALUES (
17, 1, 32768, X'8a7c41167bc0fcc1dec8329a868ba265c23857f5'
@@ -1186,6 +1451,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 18, 7, 8, 32768, X'9ff04217b3b40cb328440e40b6dc1c283f9f71ec'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 8, 16384, X'76de3b5b8df6d685e522aeea01d79ac457808437c02d40eb2e6ff06098057d41'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 18, 7, 8, 8192, X'ca1c0f6e3516f82a40cbaaea84dd42a8c97cea6b729dc07343f18a5d1b898a94e861b0dfb574c3efad64c363bb07ebf5'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
19, 7, 1, 32768, X'd537d437f058136eb3d7be517dbe7647b623c619'
);
@@ -1222,6 +1505,24 @@ INSERT INTO file_hashes (
INSERT INTO file_hashes (
file, directory, product, algo, hash
) VALUES (
+ 19, 7, 8, 32768, X'b3d6df204cc27f59704c19ab501172892a9c7c5d'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 8, 16384, X'9168ba26a67a3daf0ad3ea956d88358235ebb968b95f91bd110eab34ba75e4f8'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 19, 7, 8, 8192, X'e3a69702f9d07ea6e1f7cb85157f3d76d7e7dc577fd48ca7f6cf8f917ca7e5015e0f7dd463e1229aebf18aabcfd39cc3'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
20, 7, 1, 32768, X'f9e3531abb67a020cf667d46ca823675dd0a0dd4'
);
@@ -1255,6 +1556,60 @@ INSERT INTO file_hashes (
20, 7, 7, 8192, X'84200bd318bb022915150842ddf4002e061ef593604ad0d07021dc662cc40bfa749cce084ddf25d0e5137f6380f613d8'
);
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 8, 32768, X'8696176c12bf8291b6b9989ec5c94c3fdf26b14f'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 8, 16384, X'e7b5896d1dbe17f501f20424e8ed7d2de14d79e984e0c0a032ea70ca2f44e83a'
+);
+
+INSERT INTO file_hashes (
+ file, directory, product, algo, hash
+) VALUES (
+ 20, 7, 8, 8192, X'0d87fb31cf84b57b5b872af0b5e65610df929e48877f5ea199c073da6087c7a0e4b4c186545f654bb5db94284fde6274'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 23, 8, 32768, X'a67433717c2b9e2a9293f15a88456efbf7998a84'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 23, 8, 16384, X'1453d3ceaea4043cecd34f1eb24e0fbbe9fe04978077d06a0f728de849e71365'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 23, 8, 8192, X'abd1134f68a2daf92183aeae372f970cb076164468d4df08b8cb53743cae0867c17231e8f087e3367b6ec6905eb03c16'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 24, 8, 32768, X'bc3f9d1edeb00192c5c040a53823b58642ed8f41'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 24, 8, 16384, X'78f76b5c274705d09cd73cfad04791b8009c56d00849a00613909a659dc9ac63'
+);
+
+INSERT INTO file_hashes (
+ file, product, algo, hash
+) VALUES (
+ 24, 8, 8192, X'52cea5a859d0a1e06ffa8c1fc4f7b8dffde2de99915d660b2d3756315efdd873bee67ba3732f2c1ec692c38a8780cd72'
+);
+
/* AIKs */
INSERT INTO keys (
@@ -1280,7 +1635,13 @@ INSERT INTO components (
INSERT INTO components (
vendor_id, name, qualifier
) VALUES (
- 36906, 3, 33 /* ITA IMA */
+ 36906, 3, 33 /* ITA IMA - Trusted Platform */
+);
+
+INSERT INTO components (
+ vendor_id, name, qualifier
+) VALUES (
+ 36906, 3, 34 /* ITA IMA - Operating System */
);
/* AIK Component */
@@ -1288,18 +1649,18 @@ INSERT INTO components (
INSERT INTO key_component (
key, component, depth, seq_no
) VALUES (
- 2, 2, 0, 1
+ 1, 3, 0, 1
);
INSERT INTO key_component (
key, component, depth, seq_no
) VALUES (
- 1, 3, 0, 1
+ 1, 2, 0, 2
);
INSERT INTO key_component (
key, component, depth, seq_no
) VALUES (
- 1, 2, 0, 2
+ 1, 4, 0, 3
);
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation.c b/src/libpts/plugins/imv_attestation/imv_attestation.c
index 51069b02d..201496e8a 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -168,13 +168,10 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
static TNC_Result send_message(TNC_ConnectionID connection_id)
{
- pa_tnc_msg_t *msg;
- pa_tnc_attr_t *attr;
+ linked_list_t *attr_list;
imv_state_t *state;
imv_attestation_state_t *attestation_state;
TNC_Result result;
- linked_list_t *attr_list;
- enumerator_t *enumerator;
if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
{
@@ -188,21 +185,8 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
{
if (attr_list->get_count(attr_list))
{
- msg = pa_tnc_msg_create();
-
- /* move PA-TNC attributes to PA-TNC message */
- enumerator = attr_list->create_enumerator(attr_list);
- while (enumerator->enumerate(enumerator, &attr))
- {
- msg->add_attribute(msg, attr);
- }
- enumerator->destroy(enumerator);
-
- msg->build(msg);
result = imv_attestation->send_message(imv_attestation,
- connection_id, FALSE, 0, TNC_IMCID_ANY,
- msg->get_encoding(msg));
- msg->destroy(msg);
+ connection_id, FALSE, 0, TNC_IMCID_ANY, attr_list);
}
else
{
@@ -230,6 +214,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
{
pa_tnc_msg_t *pa_tnc_msg;
pa_tnc_attr_t *attr;
+ pen_type_t type;
linked_list_t *attr_list;
imv_state_t *state;
imv_attestation_state_t *attestation_state;
@@ -271,31 +256,31 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
while (enumerator->enumerate(enumerator, &attr))
{
- if (attr->get_vendor_id(attr) == PEN_IETF)
+ type = attr->get_type(attr);
+
+ if (type.vendor_id == PEN_IETF)
{
- if (attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
+ if (type.type == IETF_ATTR_PA_TNC_ERROR)
{
ietf_attr_pa_tnc_error_t *error_attr;
- pen_t error_vendor_id;
- pa_tnc_error_code_t error_code;
+ pen_type_t error_code;
chunk_t msg_info;
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
- error_vendor_id = error_attr->get_vendor_id(error_attr);
+ error_code = error_attr->get_error_code(error_attr);
- if (error_vendor_id == PEN_TCG)
+ if (error_code.vendor_id == PEN_TCG)
{
- error_code = error_attr->get_error_code(error_attr);
msg_info = error_attr->get_msg_info(error_attr);
DBG1(DBG_IMV, "received TCG-PTS error '%N'",
- pts_error_code_names, error_code);
+ pts_error_code_names, error_code.type);
DBG1(DBG_IMV, "error information: %B", &msg_info);
result = TNC_RESULT_FATAL;
}
}
- else if (attr->get_type(attr) == IETF_ATTR_PRODUCT_INFORMATION)
+ else if (type.type == IETF_ATTR_PRODUCT_INFORMATION)
{
ietf_attr_product_info_t *attr_cast;
char *platform_info;
@@ -305,7 +290,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
pts->set_platform_info(pts, platform_info);
}
}
- else if (attr->get_vendor_id(attr) == PEN_TCG)
+ else if (type.vendor_id == PEN_TCG)
{
if (!imv_attestation_process(attr, attr_list, attestation_state,
supported_algorithms,supported_dh_groups, pts_db, pts_credmgr))
@@ -325,29 +310,14 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
TNC_IMV_EVALUATION_RESULT_ERROR);
return imv_attestation->provide_recommendation(imv_attestation,
- connection_id);
+ connection_id, src_imc_id);
}
if (attr_list->get_count(attr_list))
{
- pa_tnc_msg = pa_tnc_msg_create();
-
- /* move PA-TNC attributes to PA-TNC message */
- enumerator = attr_list->create_enumerator(attr_list);
- while (enumerator->enumerate(enumerator, &attr))
- {
- pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
- }
- enumerator->destroy(enumerator);
-
- pa_tnc_msg->build(pa_tnc_msg);
result = imv_attestation->send_message(imv_attestation, connection_id,
- FALSE, 0, TNC_IMCID_ANY,
- pa_tnc_msg->get_encoding(pa_tnc_msg));
-
- pa_tnc_msg->destroy(pa_tnc_msg);
+ FALSE, 0, TNC_IMCID_ANY, attr_list);
attr_list->destroy(attr_list);
-
return result;
}
attr_list->destroy(attr_list);
@@ -360,7 +330,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
TNC_IMV_EVALUATION_RESULT_ERROR);
return imv_attestation->provide_recommendation(imv_attestation,
- connection_id);
+ connection_id, src_imc_id);
}
if (attestation_state->get_handshake_state(attestation_state) ==
@@ -372,12 +342,6 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
attestation_state->get_file_meas_request_count(attestation_state));
attestation_state->set_measurement_error(attestation_state);
}
- if (attestation_state->get_component_count(attestation_state))
- {
- DBG1(DBG_IMV, "failure due to %d components waiting for evidence",
- attestation_state->get_component_count(attestation_state));
- attestation_state->set_measurement_error(attestation_state);
- }
if (attestation_state->get_measurement_error(attestation_state))
{
state->set_recommendation(state,
@@ -391,7 +355,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
TNC_IMV_EVALUATION_RESULT_COMPLIANT);
}
return imv_attestation->provide_recommendation(imv_attestation,
- connection_id);
+ connection_id, src_imc_id);
}
return result;
@@ -446,7 +410,7 @@ TNC_Result TNC_IMV_SolicitRecommendation(TNC_IMVID imv_id,
return TNC_RESULT_NOT_INITIALIZED;
}
return imv_attestation->provide_recommendation(imv_attestation,
- connection_id);
+ connection_id, TNC_IMCID_ANY);
}
/**
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_build.c b/src/libpts/plugins/imv_attestation/imv_attestation_build.c
index 4f2cc1e95..23195d6e3 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_build.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_build.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -16,7 +16,6 @@
#include "imv_attestation_build.h"
#include "imv_attestation_state.h"
-#include <libpts.h>
#include <tcg/tcg_pts_attr_proto_caps.h>
#include <tcg/tcg_pts_attr_meas_algo.h>
#include <tcg/tcg_pts_attr_dh_nonce_params_req.h>
@@ -198,7 +197,13 @@ bool imv_attestation_build(linked_list_t *attr_list,
attr_list->insert_last(attr_list, attr);
}
enumerator->destroy(enumerator);
- break;
+
+ /* do we have any file metadata or measurement requests? */
+ if (attr_list->get_count(attr_list))
+ {
+ break;
+ }
+ /* fall through to next state */
}
case IMV_ATTESTATION_STATE_COMP_EVID:
{
@@ -252,15 +257,15 @@ bool imv_attestation_build(linked_list_t *attr_list,
comp_name = pts_comp_func_name_create(vid, name, qualifier);
comp_name->log(comp_name, " ");
- comp = pts_components->create(pts_components, comp_name,
- depth, pts_db);
+ comp = attestation_state->create_component(attestation_state,
+ comp_name, depth, pts_db);
if (!comp)
{
- DBG2(DBG_IMV, " not registered: removed from request");
+ DBG2(DBG_IMV, " not registered or duplicate"
+ " - removed from request");
comp_name->destroy(comp_name);
continue;
}
- attestation_state->add_component(attestation_state, comp);
if (first_component)
{
attr = tcg_pts_attr_req_func_comp_evid_create();
@@ -290,8 +295,11 @@ bool imv_attestation_build(linked_list_t *attr_list,
break;
}
case IMV_ATTESTATION_STATE_EVID_FINAL:
- attestation_state->set_handshake_state(attestation_state,
+ if (attestation_state->components_finalized(attestation_state))
+ {
+ attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_END);
+ }
break;
case IMV_ATTESTATION_STATE_END:
break;
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
index a742b6697..37e9ac77a 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_process.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -41,11 +41,13 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
pts_database_t *pts_db,
credential_manager_t *pts_credmgr)
{
+ pen_type_t attr_type;
pts_t *pts;
-
+
pts = attestation_state->get_pts(attestation_state);
-
- switch (attr->get_type(attr))
+ attr_type = attr->get_type(attr);
+
+ switch (attr_type.type)
{
case TCG_PTS_PROTO_CAPS:
{
@@ -169,7 +171,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
KEY_ANY, aik->get_issuer(aik), FALSE);
while (e->enumerate(e, &issuer))
{
- if (aik->issued_by(aik, issuer))
+ if (aik->issued_by(aik, issuer, NULL))
{
trusted = TRUE;
break;
@@ -216,22 +218,29 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
DBG1(DBG_IMV, "measurement request %d returned %d file%s:",
request_id, file_count, (file_count == 1) ? "":"s");
- if (!attestation_state->check_off_file_meas_request(attestation_state,
- request_id, &file_id, &is_dir))
+ if (request_id)
{
- DBG1(DBG_IMV, " no entry found for file measurement request %d",
- request_id);
- break;
- }
+ if (!attestation_state->check_off_file_meas_request(
+ attestation_state, request_id, &file_id, &is_dir))
+ {
+ DBG1(DBG_IMV, " no entry found for file measurement "
+ "request %d", request_id);
+ break;
+ }
- /* check hashes from database against measurements */
- e_hash = pts_db->create_file_hash_enumerator(pts_db,
- platform_info, algo, file_id, is_dir);
- if (!measurements->verify(measurements, e_hash, is_dir))
+ /* check hashes from database against measurements */
+ e_hash = pts_db->create_file_hash_enumerator(pts_db,
+ platform_info, algo, file_id, is_dir);
+ if (!measurements->verify(measurements, e_hash, is_dir))
+ {
+ attestation_state->set_measurement_error(attestation_state);
+ }
+ e_hash->destroy(e_hash);
+ }
+ else
{
- attestation_state->set_measurement_error(attestation_state);
+ measurements->check(measurements, pts_db, platform_info, algo);
}
- e_hash->destroy(e_hash);
break;
}
case TCG_PTS_UNIX_FILE_META:
@@ -276,34 +285,22 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
pts_comp_evidence_t *evidence;
pts_component_t *comp;
u_int32_t depth;
- status_t status;
attr_cast = (tcg_pts_attr_simple_comp_evid_t*)attr;
evidence = attr_cast->get_comp_evidence(attr_cast);
name = evidence->get_comp_func_name(evidence, &depth);
- comp = attestation_state->check_off_component(attestation_state, name);
+ comp = attestation_state->get_component(attestation_state, name);
if (!comp)
{
DBG1(DBG_IMV, " no entry found for component evidence request");
break;
}
- status = comp->verify(comp, pts, evidence);
-
- switch (status)
+ if (comp->verify(comp, name->get_qualifier(name), pts,
+ evidence) != SUCCESS)
{
- default:
- case FAILED:
- attestation_state->set_measurement_error(attestation_state);
- comp->destroy(comp);
- break;
- case SUCCESS:
- name->log(name, " successfully measured ");
- comp->destroy(comp);
- break;
- case NEED_MORE:
- /* re-enter component into list */
- attestation_state->add_component(attestation_state, comp);
+ attestation_state->set_measurement_error(attestation_state);
+ name->log(name, " measurement mismatch for ");
}
break;
}
@@ -353,8 +350,11 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
DBG2(DBG_IMV, "TPM Quote Info signature verification successful");
free(quote_info.ptr);
- /* Finalize any pending measurement registrations */
- attestation_state->check_off_registrations(attestation_state);
+ /**
+ * Finalize any pending measurement registrations and check
+ * if all expected component measurements were received
+ */
+ attestation_state->finalize_components(attestation_state);
}
if (attr_cast->get_evid_sig(attr_cast, &evid_sig))
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.c b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
index a58fd3ec3..1dbc88309 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_state.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,21 +15,15 @@
#include "imv_attestation_state.h"
+#include <libpts.h>
+
#include <utils/lexparser.h>
#include <utils/linked_list.h>
#include <debug.h>
typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
typedef struct file_meas_request_t file_meas_request_t;
-
-/**
- * PTS File/Directory Measurement request entry
- */
-struct file_meas_request_t {
- u_int16_t id;
- int file_id;
- bool is_dir;
-};
+typedef struct func_comp_t func_comp_t;
/**
* Private data of an imv_attestation_state_t object.
@@ -62,6 +56,11 @@ struct private_imv_attestation_state_t {
bool has_excl;
/**
+ * Maximum PA-TNC message size for this TNCCS connection
+ */
+ u_int32_t max_msg_len;
+
+ /**
* IMV Attestation handshake state
*/
imv_attestation_handshake_state_t handshake_state;
@@ -103,6 +102,32 @@ struct private_imv_attestation_state_t {
};
+/**
+ * PTS File/Directory Measurement request entry
+ */
+struct file_meas_request_t {
+ u_int16_t id;
+ int file_id;
+ bool is_dir;
+};
+
+/**
+ * PTS Functional Component entry
+ */
+struct func_comp_t {
+ pts_component_t *comp;
+ u_int8_t qualifier;
+};
+
+/**
+ * Frees a func_comp_t object
+ */
+static void free_func_comp(func_comp_t *this)
+{
+ this->comp->destroy(this->comp);
+ free(this);
+}
+
typedef struct entry_t entry_t;
/**
@@ -150,6 +175,18 @@ METHOD(imv_state_t, set_flags, void,
this->has_excl = has_excl;
}
+METHOD(imv_state_t, set_max_msg_len, void,
+ private_imv_attestation_state_t *this, u_int32_t max_msg_len)
+{
+ this->max_msg_len = max_msg_len;
+}
+
+METHOD(imv_state_t, get_max_msg_len, u_int32_t,
+ private_imv_attestation_state_t *this)
+{
+ return this->max_msg_len;
+}
+
METHOD(imv_state_t, change_state, void,
private_imv_attestation_state_t *this, TNC_ConnectionState new_state)
{
@@ -220,8 +257,7 @@ METHOD(imv_state_t, destroy, void,
private_imv_attestation_state_t *this)
{
this->file_meas_requests->destroy_function(this->file_meas_requests, free);
- this->components->destroy_offset(this->components,
- offsetof(pts_component_t, destroy));
+ this->components->destroy_function(this->components, (void *)free_func_comp);
this->pts->destroy(this->pts);
free(this);
}
@@ -290,54 +326,74 @@ METHOD(imv_attestation_state_t, get_file_meas_request_count, int,
return this->file_meas_requests->get_count(this->file_meas_requests);
}
-METHOD(imv_attestation_state_t, add_component, void,
- private_imv_attestation_state_t *this, pts_component_t *entry)
-{
- this->components->insert_last(this->components, entry);
-}
-
-METHOD(imv_attestation_state_t, check_off_component, pts_component_t*,
- private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
+METHOD(imv_attestation_state_t, create_component, pts_component_t*,
+ private_imv_attestation_state_t *this, pts_comp_func_name_t *name,
+ u_int32_t depth, pts_database_t *pts_db)
{
enumerator_t *enumerator;
- pts_component_t *entry, *found = NULL;
+ func_comp_t *entry, *new_entry;
+ pts_component_t *component;
+ bool found = FALSE;
enumerator = this->components->create_enumerator(this->components);
while (enumerator->enumerate(enumerator, &entry))
{
- if (name->equals(name, entry->get_comp_func_name(entry)))
+ if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)))
{
- found = entry;
- this->components->remove_at(this->components, enumerator);
+ found = TRUE;
break;
}
}
enumerator->destroy(enumerator);
- return found;
+
+ if (found)
+ {
+ if (name->get_qualifier(name) == entry->qualifier)
+ {
+ /* duplicate entry */
+ return NULL;
+ }
+ new_entry = malloc_thing(func_comp_t);
+ new_entry->qualifier = name->get_qualifier(name);
+ new_entry->comp = entry->comp->get_ref(entry->comp);
+ this->components->insert_last(this->components, new_entry);
+ return entry->comp;
+ }
+ else
+ {
+ component = pts_components->create(pts_components, name, depth, pts_db);
+ if (!component)
+ {
+ /* unsupported component */
+ return NULL;
+ }
+ new_entry = malloc_thing(func_comp_t);
+ new_entry->qualifier = name->get_qualifier(name);
+ new_entry->comp = component;
+ this->components->insert_last(this->components, new_entry);
+ return component;
+ }
}
-METHOD(imv_attestation_state_t, check_off_registrations, void,
- private_imv_attestation_state_t *this)
+METHOD(imv_attestation_state_t, get_component, pts_component_t*,
+ private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
{
enumerator_t *enumerator;
- pts_component_t *entry;
+ func_comp_t *entry;
+ pts_component_t *found = NULL;
enumerator = this->components->create_enumerator(this->components);
while (enumerator->enumerate(enumerator, &entry))
{
- if (entry->check_off_registrations(entry))
+ if (name->equals(name, entry->comp->get_comp_func_name(entry->comp)) &&
+ name->get_qualifier(name) == entry->qualifier)
{
- this->components->remove_at(this->components, enumerator);
- entry->destroy(entry);
+ found = entry->comp;
+ break;
}
}
enumerator->destroy(enumerator);
-}
-
-METHOD(imv_attestation_state_t, get_component_count, int,
- private_imv_attestation_state_t *this)
-{
- return this->components->get_count(this->components);
+ return found;
}
METHOD(imv_attestation_state_t, get_measurement_error, bool,
@@ -352,6 +408,28 @@ METHOD(imv_attestation_state_t, set_measurement_error, void,
this->measurement_error = TRUE;
}
+METHOD(imv_attestation_state_t, finalize_components, void,
+ private_imv_attestation_state_t *this)
+{
+ func_comp_t *entry;
+
+ while (this->components->remove_last(this->components,
+ (void**)&entry) == SUCCESS)
+ {
+ if (!entry->comp->finalize(entry->comp, entry->qualifier))
+ {
+ _set_measurement_error(this);
+ }
+ free_func_comp(entry);
+ }
+}
+
+METHOD(imv_attestation_state_t, components_finalized, bool,
+ private_imv_attestation_state_t *this)
+{
+ return this->components->get_count(this->components) == 0;
+}
+
/**
* Described in header.
*/
@@ -367,6 +445,8 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
.has_long = _has_long,
.has_excl = _has_excl,
.set_flags = _set_flags,
+ .set_max_msg_len = _set_max_msg_len,
+ .get_max_msg_len = _get_max_msg_len,
.change_state = _change_state,
.get_recommendation = _get_recommendation,
.set_recommendation = _set_recommendation,
@@ -379,10 +459,10 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
.add_file_meas_request = _add_file_meas_request,
.check_off_file_meas_request = _check_off_file_meas_request,
.get_file_meas_request_count = _get_file_meas_request_count,
- .add_component = _add_component,
- .check_off_component = _check_off_component,
- .check_off_registrations = _check_off_registrations,
- .get_component_count = _get_component_count,
+ .create_component = _create_component,
+ .get_component = _get_component,
+ .finalize_components = _finalize_components,
+ .components_finalized = _components_finalized,
.get_measurement_error = _get_measurement_error,
.set_measurement_error = _set_measurement_error,
},
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_state.h b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
index 0e2c04da4..901d4b19d 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_state.h
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
#include <imv/imv_state.h>
#include <pts/pts.h>
+#include <pts/pts_database.h>
#include <pts/components/pts_component.h>
#include <library.h>
@@ -105,32 +106,37 @@ struct imv_attestation_state_t {
u_int16_t id, int *file_id, bool *is_dir);
/**
- * Add an entry to the list of Functional Components waiting for evidence
+ * Create and add an entry to the list of Functional Components
*
- * @param entry Functional Component
+ * @param name Component Functional Name
+ * @param depth Sub-component Depth
+ * @param pts_db PTS measurement database
+ * @return created functional component instance or NULL
*/
- void (*add_component)(imv_attestation_state_t *this, pts_component_t *entry);
+ pts_component_t* (*create_component)(imv_attestation_state_t *this,
+ pts_comp_func_name_t *name,
+ u_int32_t depth,
+ pts_database_t *pts_db);
/**
- * Returns the number of Functional Component waiting for evidence
- *
- * @return Number of waiting Functional Components
- */
- int (*get_component_count)(imv_attestation_state_t *this);
-
- /**
- * Check for presence of Functional Component and remove and return it
+ * Get a Functional Component with a given name
*
* @param name Name of the requested Functional Component
* @return Functional Component if found, NULL otherwise
*/
- pts_component_t* (*check_off_component)(imv_attestation_state_t *this,
- pts_comp_func_name_t *name);
+ pts_component_t* (*get_component)(imv_attestation_state_t *this,
+ pts_comp_func_name_t *name);
/**
* Tell the Functional Components to finalize any measurement registrations
+ * and to check if all expected measurements were received
+ */
+ void (*finalize_components)(imv_attestation_state_t *this);
+
+ /**
+ * Have the Functional Component measurements been finalized?
*/
- void (*check_off_registrations)(imv_attestation_state_t *this);
+ bool (*components_finalized)(imv_attestation_state_t *this);
/**
* Indicates if a file measurement error occurred
diff --git a/src/libpts/plugins/imv_attestation/tables.sql b/src/libpts/plugins/imv_attestation/tables.sql
index 703557a07..42553bef0 100644
--- a/src/libpts/plugins/imv_attestation/tables.sql
+++ b/src/libpts/plugins/imv_attestation/tables.sql
@@ -6,6 +6,10 @@ CREATE TABLE files (
type INTEGER NOT NULL,
path TEXT NOT NULL
);
+DROP INDEX IF EXISTS files_path;
+CREATE INDEX files_path ON files (
+ path
+);
DROP TABLE IF EXISTS products;
CREATE TABLE products (
@@ -31,6 +35,7 @@ CREATE TABLE file_hashes (
file INTEGER NOT NULL,
directory INTEGER DEFAULT 0,
product INTEGER NOT NULL,
+ key INTEGER DEFAULT 0,
algo INTEGER NOT NULL,
hash BLOB NOT NULL,
PRIMARY KEY(file, directory, product, algo)
diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c
index a7da76651..a59732428 100644
--- a/src/libpts/pts/components/ita/ita_comp_ima.c
+++ b/src/libpts/pts/components/ita/ita_comp_ima.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
- *
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,6 +17,7 @@
#include "ita_comp_func_name.h"
#include "libpts.h"
+#include "pts/pts_pcr.h"
#include "pts/components/pts_component.h"
#include <debug.h>
@@ -29,11 +29,25 @@
#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
+#define SECURITY_DIR "/sys/kernel/security/"
+#define IMA_BIOS_MEASUREMENTS SECURITY_DIR "tpm0/binary_bios_measurements"
+#define IMA_RUNTIME_MEASUREMENTS SECURITY_DIR "ima/binary_runtime_measurements"
+#define IMA_PCR 10
+#define IMA_TYPE_LEN 3
+#define IMA_FILENAME_LEN_MAX 255
typedef struct pts_ita_comp_ima_t pts_ita_comp_ima_t;
+typedef struct bios_entry_t bios_entry_t;
+typedef struct ima_entry_t ima_entry_t;
+typedef enum ima_state_t ima_state_t;
+
+enum ima_state_t {
+ IMA_STATE_INIT,
+ IMA_STATE_BIOS,
+ IMA_STATE_BOOT_AGGREGATE,
+ IMA_STATE_RUNTIME,
+ IMA_STATE_END
+};
/**
* Private data of a pts_ita_comp_ima_t object.
@@ -67,52 +81,101 @@ struct pts_ita_comp_ima_t {
pts_database_t *pts_db;
/**
- * Primary key for Component Functional Name database entry
+ * Primary key for AIK database entry
*/
- int cid;
+ int kid;
/**
- * Primary key for AIK database entry
+ * Primary key for IMA BIOS Component Functional Name database entry
*/
- int kid;
+ int bios_cid;
+
+ /**
+ * Primary key for IMA Runtime Component Functional Name database entry
+ */
+ int ima_cid;
/**
- * Component is registering measurements
+ * Component is registering IMA BIOS measurements
*/
- bool is_registering;
+ bool is_bios_registering;
+
+ /**
+ * Component is registering IMA boot aggregate measurement
+ */
+ bool is_ima_registering;
+
+ /**
+ * Measurement sequence number
+ */
+ int seq_no;
/**
- * IMA BIOS measurement time
+ * Expected IMA BIOS measurement count
*/
- time_t bios_measurement_time;
+ int bios_count;
/**
* IMA BIOS measurements
*/
- linked_list_t *list;
+ linked_list_t *bios_list;
/**
- * Expected measurement count
+ * IMA runtime file measurements
+ */
+ linked_list_t *ima_list;
+
+ /**
+ * Whether to send pcr_before and pcr_after info
+ */
+ bool pcr_info;
+
+ /**
+ * IMA measurement time
+ */
+ time_t measurement_time;
+
+ /**
+ * IMA state machine
+ */
+ ima_state_t state;
+
+ /**
+ * Total number of component measurements
*/
int count;
/**
- * Measurement sequence number
+ * Number of successful component measurements
*/
- int seq_no;
+ int count_ok;
/**
- * Shadow PCR registers
+ * Number of unknown component measurements
*/
- chunk_t pcrs[IMA_PCR_MAX];
-};
+ int count_unknown;
-typedef struct entry_t entry_t;
+ /**
+ * Number of differing component measurements
+ */
+ int count_differ;
+
+ /**
+ * Number of failed component measurements
+ */
+ int count_failed;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+
+};
/**
- * Linux IMA measurement entry
+ * Linux IMA BIOS measurement entry
*/
-struct entry_t {
+struct bios_entry_t {
/**
* PCR register
@@ -126,21 +189,48 @@ struct entry_t {
};
/**
- * Free an entry_t object
+ * Linux IMA runtime file measurement entry
+ */
+struct ima_entry_t {
+
+ /**
+ * SHA1 measurement hash
+ */
+ chunk_t measurement;
+
+ /**
+ * absolute path of executable files or basename of dynamic libraries
+ */
+ char *filename;
+};
+
+/**
+ * Free a bios_entry_t object
+ */
+static void free_bios_entry(bios_entry_t *this)
+{
+ free(this->measurement.ptr);
+ free(this);
+}
+
+/**
+ * Free an ima_entry_t object
*/
-static void free_entry(entry_t *this)
+static void free_ima_entry(ima_entry_t *this)
{
free(this->measurement.ptr);
+ free(this->filename);
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)
+static bool load_bios_measurements(char *file, linked_list_t *list,
+ time_t *created)
{
u_int32_t pcr, num, len;
- entry_t *entry;
+ bios_entry_t *entry;
struct stat st;
ssize_t res;
int fd;
@@ -148,13 +238,13 @@ static bool load_measurements(char *file, linked_list_t *list, time_t *created)
fd = open(file, O_RDONLY);
if (fd == -1)
{
- DBG1(DBG_PTS, " opening '%s' failed: %s", file, strerror(errno));
+ 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,
+ DBG1(DBG_PTS, "getting statistics of '%s' failed: %s", file,
strerror(errno));
close(fd);
return FALSE;
@@ -167,12 +257,12 @@ static bool load_measurements(char *file, linked_list_t *list, time_t *created)
if (res == 0)
{
DBG2(DBG_PTS, "loaded bios measurements '%s' (%d entries)",
- file, list->get_count(list));
+ file, list->get_count(list));
close(fd);
return TRUE;
}
- entry = malloc_thing(entry_t);
+ entry = malloc_thing(bios_entry_t);
entry->pcr = pcr;
entry->measurement = chunk_alloc(HASH_SIZE_SHA1);
@@ -199,12 +289,188 @@ static bool load_measurements(char *file, linked_list_t *list, time_t *created)
list->insert_last(list, entry);
}
- DBG1(DBG_PTS, "loading bios measurements '%s' failed: %s",
- file, strerror(errno));
+ DBG1(DBG_PTS, "loading bios measurements '%s' failed: %s", file,
+ strerror(errno));
+ close(fd);
+ return FALSE;
+}
+
+/**
+ * Load an IMA runtime measurement file and determine the creation and
+ * update dates
+ */
+static bool load_runtime_measurements(char *file, linked_list_t *list,
+ time_t *created)
+{
+ u_int32_t pcr, len;
+ ima_entry_t *entry;
+ char type[IMA_TYPE_LEN];
+ 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 TRUE;
+ }
+
+ 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 ima measurements '%s' (%d entries)",
+ file, list->get_count(list));
+ close(fd);
+ return TRUE;
+ }
+
+ entry = malloc_thing(ima_entry_t);
+ entry->measurement = chunk_alloc(HASH_SIZE_SHA1);
+ entry->filename = NULL;
+
+ if (res != 4 || pcr != IMA_PCR)
+ {
+ break;
+ }
+ if (read(fd, entry->measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1)
+ {
+ break;
+ }
+ if (read(fd, &len, 4) != 4 || len != IMA_TYPE_LEN)
+ {
+ break;
+ }
+ if (read(fd, type, IMA_TYPE_LEN) != IMA_TYPE_LEN ||
+ memcmp(type, "ima", IMA_TYPE_LEN))
+ {
+ break;
+ }
+ if (lseek(fd, HASH_SIZE_SHA1, SEEK_CUR) == -1)
+ {
+ break;
+ }
+ if (read(fd, &len, 4) != 4)
+ {
+ break;
+ }
+ entry->filename = malloc(len + 1);
+ if (read(fd, entry->filename, len) != len)
+ {
+ break;
+ }
+ entry->filename[len] = '\0';
+
+ list->insert_last(list, entry);
+ }
+
+ DBG1(DBG_PTS, "loading ima measurements '%s' failed: %s",
+ file, strerror(errno));
close(fd);
return FALSE;
}
+/**
+ * Extend measurement into PCR an create evidence
+ */
+static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this,
+ u_int8_t qualifier, pts_pcr_t *pcrs,
+ u_int32_t pcr, chunk_t measurement)
+{
+ size_t pcr_len;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+ pts_comp_func_name_t *name;
+ pts_comp_evidence_t *evidence;
+ chunk_t pcr_before = chunk_empty, pcr_after = chunk_empty;
+
+ hash_algo = PTS_MEAS_ALGO_SHA1;
+ pcr_len = HASH_SIZE_SHA1;
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+
+ if (this->pcr_info)
+ {
+ pcr_before = chunk_clone(pcrs->get(pcrs, pcr));
+ }
+ pcr_after = pcrs->extend(pcrs, pcr, measurement);
+ if (!pcr_after.ptr)
+ {
+ free(pcr_before.ptr);
+ return NULL;
+ }
+ name = this->name->clone(this->name);
+ name->set_qualifier(name, qualifier);
+ evidence = pts_comp_evidence_create(name, this->depth, pcr, hash_algo,
+ pcr_transform, this->measurement_time, measurement);
+ if (this->pcr_info)
+ {
+ pcr_after =chunk_clone(pcrs->get(pcrs, pcr));
+ evidence->set_pcr_info(evidence, pcr_before, pcr_after);
+ }
+ return evidence;
+}
+
+/**
+ * Compute and check boot aggregate value by hashing PCR0 to PCR7
+ */
+static bool check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
+{
+ u_int32_t i;
+ u_char filename_buffer[IMA_FILENAME_LEN_MAX + 1];
+ u_char pcr_buffer[HASH_SIZE_SHA1];
+ chunk_t file_name, boot_aggregate;
+ hasher_t *hasher;
+ bool success, pcr_ok = TRUE;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ DBG1(DBG_PTS, "%N hasher could not be created",
+ hash_algorithm_short_names, HASH_SHA1);
+ return FALSE;
+ }
+ for (i = 0; i < 8 && pcr_ok; i++)
+ {
+ pcr_ok = hasher->get_hash(hasher, pcrs->get(pcrs, i), NULL);
+ }
+ if (pcr_ok)
+ {
+ boot_aggregate = chunk_create(pcr_buffer, sizeof(pcr_buffer));
+ memset(filename_buffer, 0, sizeof(filename_buffer));
+ strcpy(filename_buffer, "boot_aggregate");
+ file_name = chunk_create (filename_buffer, sizeof(filename_buffer));
+
+ pcr_ok = hasher->get_hash(hasher, chunk_empty, pcr_buffer) &&
+ hasher->get_hash(hasher, boot_aggregate, NULL) &&
+ hasher->get_hash(hasher, file_name, boot_aggregate.ptr);
+ }
+ hasher->destroy(hasher);
+
+ if (pcr_ok)
+ {
+ success = chunk_equals(boot_aggregate, measurement);
+ DBG1(DBG_PTS, "boot aggregate value is %scorrect",
+ success ? "":"in");
+ return success;
+ }
+ else
+ {
+ DBG1(DBG_PTS, "failed to compute boot aggregate value");
+ return FALSE;
+ }
+}
+
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
pts_ita_comp_ima_t *this)
{
@@ -224,193 +490,446 @@ METHOD(pts_component_t, get_depth, u_int32_t,
}
METHOD(pts_component_t, measure, status_t,
- pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+ pts_ita_comp_ima_t *this, u_int8_t qualifier, 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;
+ bios_entry_t *bios_entry;
+ ima_entry_t *ima_entry;
+ pts_pcr_t *pcrs;
+ pts_comp_evidence_t *evid = NULL;
+ status_t status;
- 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);
+ pcrs = pts->get_pcrs(pts);
- if (this->list->get_count(this->list) == 0)
+ if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED))
{
- if (!load_measurements(IMA_BIOS_MEASUREMENT_PATH, this->list,
- &this->bios_measurement_time))
+ switch (this->state)
{
- return FAILED;
+ case IMA_STATE_INIT:
+ if (!load_bios_measurements(IMA_BIOS_MEASUREMENTS,
+ this->bios_list, &this->measurement_time))
+ {
+ return FAILED;
+ }
+ this->bios_count = this->bios_list->get_count(this->bios_list);
+ this->state = IMA_STATE_BIOS;
+ /* fall through to next state */
+ case IMA_STATE_BIOS:
+ status = this->bios_list->remove_first(this->bios_list,
+ (void**)&bios_entry);
+ if (status != SUCCESS)
+ {
+ DBG1(DBG_PTS, "could not retrieve bios measurement entry");
+ return status;
+ }
+ evid = extend_pcr(this, qualifier, pcrs, bios_entry->pcr,
+ bios_entry->measurement);
+ free(bios_entry);
+
+ this->state = this->bios_list->get_count(this->bios_list) ?
+ IMA_STATE_BIOS : IMA_STATE_INIT;
+ break;
+ default:
+ return FAILED;
}
}
-
- if (this->list->remove_first(this->list, (void**)&entry) != SUCCESS)
+ else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_OS))
+ {
+ switch (this->state)
+ {
+ case IMA_STATE_INIT:
+ if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
+ this->ima_list, &this->measurement_time))
+ {
+ return FAILED;
+ }
+ this->state = IMA_STATE_BOOT_AGGREGATE;
+ /* fall through to next state */
+ case IMA_STATE_BOOT_AGGREGATE:
+ case IMA_STATE_RUNTIME:
+ status = this->ima_list->remove_first(this->ima_list,
+ (void**)&ima_entry);
+ if (status != SUCCESS)
+ {
+ DBG1(DBG_PTS, "could not retrieve ima measurement entry");
+ return status;
+ }
+ if (this->state == IMA_STATE_BOOT_AGGREGATE && this->bios_count)
+ {
+ if (!check_boot_aggregate(pcrs, ima_entry->measurement))
+ {
+ return FAILED;
+ }
+ }
+ evid = extend_pcr(this, qualifier, pcrs, IMA_PCR,
+ ima_entry->measurement);
+ if (evid)
+ {
+ evid->set_validation(evid, PTS_COMP_EVID_VALIDATION_PASSED,
+ ima_entry->filename);
+ }
+ free(ima_entry->filename);
+ free(ima_entry);
+
+ this->state = this->ima_list->get_count(this->ima_list) ?
+ IMA_STATE_RUNTIME : IMA_STATE_END;
+ break;
+ default:
+ return FAILED;
+ }
+ }
+ else
{
- DBG1(DBG_PTS, "could not retrieve measurement entry");
+ DBG1(DBG_PTS, "unsupported functional component name qualifier");
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);
+ *evidence = evid;
+ if (!evid)
+ {
+ return FAILED;
+ }
- return (this->list->get_count(this->list)) ? NEED_MORE : SUCCESS;
+ return (this->state == IMA_STATE_INIT || this->state == IMA_STATE_END) ?
+ SUCCESS : NEED_MORE;
}
METHOD(pts_component_t, verify, status_t,
- pts_ita_comp_ima_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+ pts_ita_comp_ima_t *this, u_int8_t qualifier, pts_t *pts,
+ pts_comp_evidence_t *evidence)
{
bool has_pcr_info;
- u_int32_t extended_pcr, vid, name;
+ u_int32_t pcr, vid, name;
enum_name_t *names;
pts_meas_algorithms_t algo;
pts_pcr_transform_t transform;
+ pts_pcr_t *pcrs;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
+ status_t status;
+ char *uri;
- measurement = evidence->get_measurement(evidence, &extended_pcr,
- &algo, &transform, &measurement_time);
-
+ /* some first time initializations */
if (!this->keyid.ptr)
{
if (!pts->get_aik_keyid(pts, &this->keyid))
{
+ DBG1(DBG_PTS, "AIK keyid not available");
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
+ pcrs = pts->get_pcrs(pts);
+ measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
+ &measurement_time);
+
+ if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED))
+ {
+ switch (this->state)
{
- DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
- "measurements", pen_names, vid, names, name);
- this->is_registering = TRUE;
+ case IMA_STATE_INIT:
+ this->name->set_qualifier(this->name, qualifier);
+ status = this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo, &this->bios_cid,
+ &this->kid, &this->bios_count);
+ this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ 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->bios_count)
+ {
+ DBG1(DBG_PTS, "checking %d %N '%N' BIOS evidence measurements",
+ this->bios_count, pen_names, vid, names, name);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "registering %N '%N' BIOS evidence measurements",
+ pen_names, vid, names, name);
+ this->is_bios_registering = TRUE;
+ }
+
+ this->state = IMA_STATE_BIOS;
+ /* fall through to next state */
+ case IMA_STATE_BIOS:
+ if (this->is_bios_registering)
+ {
+ status = this->pts_db->insert_comp_measurement(this->pts_db,
+ measurement, this->bios_cid, this->kid,
+ ++this->seq_no, pcr, algo);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ this->bios_count = this->seq_no + 1;
+ }
+ else
+ {
+ status = this->pts_db->check_comp_measurement(this->pts_db,
+ measurement, this->bios_cid, this->kid,
+ ++this->seq_no, pcr, algo);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ }
+ break;
+ default:
+ return FAILED;
}
}
-
- if (this->is_registering)
+ else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_OS))
{
- if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
- this->cid, this->kid, ++this->seq_no,
- extended_pcr, algo) != SUCCESS)
+ int ima_count;
+
+ switch (this->state)
{
- return FAILED;
+ case IMA_STATE_BIOS:
+ if (!check_boot_aggregate(pcrs, measurement))
+ {
+ this->state = IMA_STATE_RUNTIME;
+ return FAILED;
+ }
+ this->state = IMA_STATE_INIT;
+ /* fall through to next state */
+ case IMA_STATE_INIT:
+ this->name->set_qualifier(this->name, qualifier);
+ status = this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo,
+ &this->ima_cid, &this->kid, &ima_count);
+ this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ 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 (ima_count)
+ {
+ DBG1(DBG_PTS, "checking %N '%N' boot aggregate evidence "
+ "measurement", pen_names, vid, names, name);
+ status = this->pts_db->check_comp_measurement(this->pts_db,
+ measurement, this->ima_cid,
+ this->kid, 1, pcr, algo);
+ }
+ else
+ {
+ DBG1(DBG_PTS, "registering %N '%N' boot aggregate evidence "
+ "measurement", pen_names, vid, names, name);
+ this->is_ima_registering = TRUE;
+ status = this->pts_db->insert_comp_measurement(this->pts_db,
+ measurement, this->ima_cid,
+ this->kid, 1, pcr, algo);
+ }
+ this->state = IMA_STATE_RUNTIME;
+
+ if (status != SUCCESS)
+ {
+ return status;
+ }
+ break;
+ case IMA_STATE_RUNTIME:
+ this->count++;
+ if (evidence->get_validation(evidence, &uri) !=
+ PTS_COMP_EVID_VALIDATION_PASSED)
+ {
+ DBG1(DBG_PTS, "policy URI could no be retrieved");
+ this->count_failed++;
+ return FAILED;
+ }
+ status = this->pts_db->check_file_measurement(this->pts_db,
+ pts->get_platform_info(pts),
+ PTS_MEAS_ALGO_SHA1_IMA,
+ measurement, uri);
+ switch (status)
+ {
+ case SUCCESS:
+ DBG3(DBG_PTS, "%#B for '%s' is ok",
+ &measurement, uri);
+ this->count_ok++;
+ break;
+ case NOT_FOUND:
+ DBG2(DBG_PTS, "%#B for '%s' not found",
+ &measurement, uri);
+ this->count_unknown++;
+ break;
+ case VERIFY_ERROR:
+ DBG1(DBG_PTS, "%#B for '%s' differs",
+ &measurement, uri);
+ this->count_differ++;
+ break;
+ case FAILED:
+ default:
+ DBG1(DBG_PTS, "%#B for '%s' failed",
+ &measurement, uri);
+ this->count_failed++;
+ }
+ break;
+ default:
+ 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;
- }
+ DBG1(DBG_PTS, "unsupported functional component name qualifier");
+ 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))
+ if (!chunk_equals(pcr_before, pcrs->get(pcrs, pcr)))
{
- return FAILED;
+ DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
+ pcr);
+ }
+ if (pcrs->set(pcrs, pcr, pcr_after))
+ {
+ return SUCCESS;
}
}
-
- return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+ else
+ {
+ pcr_after = pcrs->extend(pcrs, pcr, measurement);
+ if (pcr_after.ptr)
+ {
+ return SUCCESS;
+ }
+ }
+ return FAILED;
}
-METHOD(pts_component_t, check_off_registrations, bool,
- pts_ita_comp_ima_t *this)
+METHOD(pts_component_t, finalize, bool,
+ pts_ita_comp_ima_t *this, u_int8_t qualifier)
{
u_int32_t vid, name;
enum_name_t *names;
+ bool success = TRUE;
- if (!this->is_registering)
+ this->name->set_qualifier(this->name, qualifier);
+ 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 (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED))
{
- return FALSE;
+ /* finalize BIOS measurements */
+ if (this->is_bios_registering)
+ {
+ /* close registration */
+ this->is_bios_registering = FALSE;
+
+ DBG1(DBG_PTS, "registered %d %N '%N' BIOS evidence measurements",
+ this->seq_no, pen_names, vid, names, name);
+ }
+ else if (this->seq_no < this->bios_count)
+ {
+ DBG1(DBG_PTS, "%d of %d %N '%N' BIOS evidence measurements missing",
+ this->bios_count - this->seq_no, this->bios_count,
+ pen_names, vid, names, name);
+ success = FALSE;
+ }
}
+ else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_OS))
+ {
+ /* finalize IMA file measurements */
+ if (this->is_ima_registering)
+ {
+ /* close registration */
+ this->is_ima_registering = FALSE;
- /* Finalize registration */
- this->is_registering = FALSE;
+ DBG1(DBG_PTS, "registered %N '%N' boot aggregate evidence "
+ "measurement", pen_names, vid, names, name);
+ }
+ if (this->count)
+ {
+ DBG1(DBG_PTS, "processed %d %N '%N' file evidence measurements: "
+ "%d ok, %d unknown, %d differ, %d failed",
+ this->count, pen_names, vid, names, name,
+ this->count_ok, this->count_unknown,
+ this->count_differ, this->count_failed);
+ success = !this->count_differ && !this->count_failed;
+ }
+ }
+ else
+ {
+ DBG1(DBG_PTS, "unsupported functional component name qualifier");
+ success = FALSE;
+ }
+ this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
- 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;
+ return success;
+}
+
+METHOD(pts_component_t, get_ref, pts_component_t*,
+ pts_ita_comp_ima_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
}
METHOD(pts_component_t, destroy, void,
pts_ita_comp_ima_t *this)
{
- int i, count;
+ int 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)
+ if (ref_put(&this->ref))
{
- 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);
+
+ if (this->is_bios_registering)
+ {
+ count = this->pts_db->delete_comp_measurements(this->pts_db,
+ this->bios_cid, this->kid);
+ DBG1(DBG_PTS, "deleted %d registered %N '%N' BIOS evidence "
+ "measurements", count, pen_names, vid, names, name);
+ }
+ if (this->is_ima_registering)
+ {
+ count = this->pts_db->delete_comp_measurements(this->pts_db,
+ this->ima_cid, this->kid);
+ DBG1(DBG_PTS, "deleted registered %N '%N' boot aggregate evidence "
+ "measurement", pen_names, vid, names, name);
+ }
+ this->bios_list->destroy_function(this->bios_list,
+ (void *)free_bios_entry);
+ this->ima_list->destroy_function(this->ima_list,
+ (void *)free_ima_entry);
+ this->name->destroy(this->name);
+ free(this->keyid.ptr);
+ free(this);
}
- 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_component_t *pts_ita_comp_ima_create(u_int32_t depth,
pts_database_t *pts_db)
{
pts_ita_comp_ima_t *this;
- int i;
INIT(this,
.public = {
@@ -419,21 +938,21 @@ pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
.get_depth = _get_depth,
.measure = _measure,
.verify = _verify,
- .check_off_registrations = _check_off_registrations,
+ .finalize = _finalize,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_IMA,
- qualifier),
+ PTS_QUALIFIER_UNKNOWN),
.depth = depth,
.pts_db = pts_db,
- .list = linked_list_create(),
+ .bios_list = linked_list_create(),
+ .ima_list = linked_list_create(),
+ .pcr_info = lib->settings->get_bool(lib->settings,
+ "libimcv.plugins.imc-attestation.pcr_info", TRUE),
+ .ref = 1,
);
- 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
index 1ca27e6f0..546d0a4b2 100644
--- a/src/libpts/pts/components/ita/ita_comp_ima.h
+++ b/src/libpts/pts/components/ita/ita_comp_ima.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,11 +26,10 @@
/**
* 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_component_t* pts_ita_comp_ima_create(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
index a85de8cd8..9deeb19b5 100644
--- a/src/libpts/pts/components/ita/ita_comp_tboot.c
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
- *
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -86,6 +85,11 @@ struct pts_ita_comp_tboot_t {
*/
int seq_no;
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+
};
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
@@ -107,15 +111,18 @@ METHOD(pts_component_t, get_depth, u_int32_t,
}
METHOD(pts_component_t, measure, status_t,
- pts_ita_comp_tboot_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+ pts_ita_comp_tboot_t *this, u_int8_t qualifier, pts_t *pts,
+ pts_comp_evidence_t **evidence)
+
{
+ size_t pcr_len;
+ pts_pcr_t *pcrs;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
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++)
{
@@ -149,9 +156,8 @@ METHOD(pts_component_t, measure, status_t,
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);
+ hash_algo = PTS_MEAS_ALGO_SHA1;
+ pcr_len = HASH_SIZE_SHA1;
pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
/* get and check the measurement data */
@@ -162,35 +168,40 @@ METHOD(pts_component_t, measure, status_t,
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)
+ measurement.len != pcr_len)
{
- DBG1(DBG_PTS, "TBOOT measurement or pcr data have the wrong 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;
}
+ pcrs = pts->get_pcrs(pts);
+ pcrs->set(pcrs, extended_pcr, pcr_after);
evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
- this->depth, extended_pcr,
- hash_algo, pcr_transform,
- this->measurement_time, measurement);
+ 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)
+ pts_ita_comp_tboot_t *this, u_int8_t qualifier,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;
+ pts_pcr_t *pcrs;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
+ status_t status;
+ pcrs = pts->get_pcrs(pts);
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
@@ -207,11 +218,12 @@ METHOD(pts_component_t, verify, status_t,
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)
+ status = this->pts_db->get_comp_measurement_count(this->pts_db,
+ this->name, this->keyid, algo, &this->cid,
+ &this->kid, &this->count);
+ if (status != SUCCESS)
{
- return FAILED;
+ return status;
}
vid = this->name->get_vendor_id(this->name);
name = this->name->get_name(this->name);
@@ -232,58 +244,79 @@ METHOD(pts_component_t, verify, status_t,
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)
+ status = this->pts_db->insert_comp_measurement(this->pts_db,
+ measurement, this->cid, this->kid,
+ ++this->seq_no, extended_pcr, algo);
+ if (status != SUCCESS)
{
- return FAILED;
+ return status;
}
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)
+ status = this->pts_db->check_comp_measurement(this->pts_db,
+ measurement, this->cid, this->kid,
+ ++this->seq_no, extended_pcr, algo);
+ if (status != SUCCESS)
{
- return FAILED;
+ return status;
}
}
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))
+ if (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr)))
{
- return FAILED;
+ DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
+ extended_pcr);
+ }
+ if (pcrs->set(pcrs, extended_pcr, pcr_after))
+ {
+ return SUCCESS;
}
}
- return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+ return SUCCESS;
}
-METHOD(pts_component_t, check_off_registrations, bool,
- pts_ita_comp_tboot_t *this)
+METHOD(pts_component_t, finalize, bool,
+ pts_ita_comp_tboot_t *this, u_int8_t qualifier)
{
u_int32_t vid, name;
enum_name_t *names;
- if (!this->is_registering)
+ 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->is_registering)
{
+ /* close registration */
+ this->is_registering = FALSE;
+
+ DBG1(DBG_PTS, "registered %d %N '%N' functional component evidence "
+ "measurements", this->seq_no, pen_names, vid, names, name);
+ }
+ else if (this->seq_no < this->count)
+ {
+ DBG1(DBG_PTS, "%d of %d %N '%N' functional component evidence "
+ "measurements missing", this->count - this->seq_no,
+ this->count, pen_names, vid, names, name);
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, get_ref, pts_component_t*,
+ pts_ita_comp_tboot_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
METHOD(pts_component_t, destroy, void,
pts_ita_comp_tboot_t *this)
{
@@ -291,25 +324,28 @@ METHOD(pts_component_t, destroy, void,
u_int32_t vid, name;
enum_name_t *names;
- if (this->is_registering)
+ if (ref_put(&this->ref))
{
- 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);
+ 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);
}
- 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_component_t *pts_ita_comp_tboot_create(u_int32_t depth,
pts_database_t *pts_db)
{
pts_ita_comp_tboot_t *this;
@@ -321,13 +357,16 @@ pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
.get_depth = _get_depth,
.measure = _measure,
.verify = _verify,
- .check_off_registrations = _check_off_registrations,
+ .finalize = _finalize,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TBOOT,
- qualifier),
+ PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED),
.depth = depth,
.pts_db = pts_db,
+ .ref = 1,
);
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
index 39554fbc7..1e1a14831 100644
--- a/src/libpts/pts/components/ita/ita_comp_tboot.h
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,11 +26,10 @@
/**
* 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_component_t* pts_ita_comp_tboot_create(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
index 0dfd5fd41..986f7ace2 100644
--- a/src/libpts/pts/components/ita/ita_comp_tgrub.c
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
- *
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -50,6 +49,12 @@ struct pts_ita_comp_tgrub_t {
*/
pts_database_t *pts_db;
+
+ /**
+ * Reference count
+ */
+ refcount_t ref;
+
};
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
@@ -71,15 +76,16 @@ METHOD(pts_component_t, get_depth, u_int32_t,
}
METHOD(pts_component_t, measure, status_t,
- pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t **evidence)
+ pts_ita_comp_tgrub_t *this, u_int8_t qualifier, pts_t *pts,
+ pts_comp_evidence_t **evidence)
{
+ size_t pcr_len;
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
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;
@@ -91,12 +97,11 @@ METHOD(pts_component_t, measure, status_t,
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);
+ hash_algo = PTS_MEAS_ALGO_SHA1;
+ pcr_len = HASH_SIZE_SHA1;
pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
- measurement = chunk_alloc(hash_size);
+ measurement = chunk_alloc(pcr_len);
memset(measurement.ptr, 0x00, measurement.len);
pcr_before = chunk_alloc(pcr_len);
@@ -112,15 +117,18 @@ METHOD(pts_component_t, measure, status_t,
}
METHOD(pts_component_t, verify, status_t,
- pts_ita_comp_tgrub_t *this, pts_t *pts, pts_comp_evidence_t *evidence)
+ pts_ita_comp_tgrub_t *this, u_int8_t qualifier, 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;
+ pts_pcr_t *pcrs;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
+ pcrs = pts->get_pcrs(pts);
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
if (extended_pcr != PCR_DEBUG)
@@ -133,32 +141,46 @@ METHOD(pts_component_t, verify, status_t,
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))
+ if (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr)))
{
- return FAILED;
+ DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to pcr value");
+ }
+ if (pcrs->set(pcrs, extended_pcr, pcr_after))
+ {
+ return SUCCESS;
}
}
return SUCCESS;
}
-METHOD(pts_component_t, check_off_registrations, bool,
- pts_ita_comp_tgrub_t *this)
+METHOD(pts_component_t, finalize, bool,
+ pts_ita_comp_tgrub_t *this, u_int8_t qualifier)
{
return FALSE;
}
+METHOD(pts_component_t, get_ref, pts_component_t*,
+ pts_ita_comp_tgrub_t *this)
+{
+ ref_get(&this->ref);
+ return &this->public;
+}
+
METHOD(pts_component_t, destroy, void,
pts_ita_comp_tgrub_t *this)
{
- this->name->destroy(this->name);
- free(this);
+ if (ref_put(&this->ref))
+ {
+ 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_component_t *pts_ita_comp_tgrub_create(u_int32_t depth,
pts_database_t *pts_db)
{
pts_ita_comp_tgrub_t *this;
@@ -170,13 +192,16 @@ pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
.get_depth = _get_depth,
.measure = _measure,
.verify = _verify,
- .check_off_registrations = _check_off_registrations,
+ .finalize = _finalize,
+ .get_ref = _get_ref,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TGRUB,
- qualifier),
+ PTS_ITA_QUALIFIER_FLAG_KERNEL |
+ PTS_ITA_QUALIFIER_TYPE_TRUSTED),
.depth = depth,
.pts_db = pts_db,
+ .ref = 1,
);
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
index 52ecc325c..59913c82d 100644
--- a/src/libpts/pts/components/ita/ita_comp_tgrub.h
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -26,11 +26,10 @@
/**
* 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_component_t* pts_ita_comp_tgrub_create(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
index 9eb8dae75..050717472 100644
--- a/src/libpts/pts/components/pts_comp_evidence.c
+++ b/src/libpts/pts/components/pts_comp_evidence.c
@@ -87,7 +87,7 @@ struct private_pts_comp_evidence_t {
/**
* Verification Policy URI
*/
- chunk_t policy_uri;
+ char *policy_uri;
};
@@ -152,12 +152,12 @@ METHOD(pts_comp_evidence_t, set_pcr_info, void,
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);
+ DBG3(DBG_PTS, "PCR %2d before value : %#B", this->extended_pcr, &pcr_before);
+ DBG3(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)
+ private_pts_comp_evidence_t *this, char **uri)
{
if (uri)
{
@@ -168,10 +168,14 @@ METHOD(pts_comp_evidence_t, get_validation, pts_comp_evid_validation_t,
METHOD(pts_comp_evidence_t, set_validation, void,
private_pts_comp_evidence_t *this, pts_comp_evid_validation_t validation,
- chunk_t uri)
+ char *uri)
{
this->validation = validation;
- this->policy_uri = chunk_clone(uri);
+ if (uri)
+ {
+ this->policy_uri = strdup(uri);
+ DBG3(DBG_PTS, "'%s'", uri);
+ }
}
METHOD(pts_comp_evidence_t, destroy, void,
@@ -181,7 +185,7 @@ METHOD(pts_comp_evidence_t, destroy, void,
free(this->measurement.ptr);
free(this->pcr_before.ptr);
free(this->pcr_after.ptr);
- free(this->policy_uri.ptr);
+ free(this->policy_uri);
free(this);
}
@@ -219,8 +223,8 @@ pts_comp_evidence_t *pts_comp_evidence_create(pts_comp_func_name_t *name,
);
name->log(name, "");
- DBG2(DBG_PTS, "measurement time: %T", &measurement_time, FALSE);
- DBG2(DBG_PTS, "PCR %2d extended with: %#B", extended_pcr, &measurement);
+ DBG3(DBG_PTS, "measurement time: %T", &measurement_time, FALSE);
+ DBG3(DBG_PTS, "PCR %2d extended with: %#B", extended_pcr, &measurement);
return &this->public;
}
diff --git a/src/libpts/pts/components/pts_comp_evidence.h b/src/libpts/pts/components/pts_comp_evidence.h
index fe86aa940..55776ce8b 100644
--- a/src/libpts/pts/components/pts_comp_evidence.h
+++ b/src/libpts/pts/components/pts_comp_evidence.h
@@ -120,7 +120,7 @@ struct pts_comp_evidence_t {
* @return validation Validation Result
*/
pts_comp_evid_validation_t (*get_validation)(pts_comp_evidence_t *this,
- chunk_t *uri);
+ char **uri);
/**
* Sets Validation Result if available
@@ -129,7 +129,7 @@ struct pts_comp_evidence_t {
* @param uri Verification Policy URI
*/
void (*set_validation)(pts_comp_evidence_t *this,
- pts_comp_evid_validation_t validation, chunk_t uri);
+ pts_comp_evid_validation_t validation, char* uri);
/**
* Destroys a pts_comp_evidence_t object.
diff --git a/src/libpts/pts/components/pts_comp_func_name.c b/src/libpts/pts/components/pts_comp_func_name.c
index d98850d78..7501be044 100644
--- a/src/libpts/pts/components/pts_comp_func_name.c
+++ b/src/libpts/pts/components/pts_comp_func_name.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
*
* HSR Hochschule fuer Technik Rapperswil
*
@@ -67,6 +67,12 @@ METHOD(pts_comp_func_name_t, get_qualifier, u_int8_t,
return this->qualifier;
}
+METHOD(pts_comp_func_name_t, set_qualifier, void,
+ private_pts_comp_func_name_t *this, u_int8_t qualifier)
+{
+ this->qualifier = qualifier;
+}
+
static bool equals(private_pts_comp_func_name_t *this,
private_pts_comp_func_name_t *other)
{
@@ -137,6 +143,7 @@ pts_comp_func_name_t* pts_comp_func_name_create(u_int32_t vid, u_int32_t name,
.get_vendor_id = _get_vendor_id,
.get_name = _get_name,
.get_qualifier = _get_qualifier,
+ .set_qualifier = _set_qualifier,
.equals = (bool(*)(pts_comp_func_name_t*,pts_comp_func_name_t*))equals,
.clone = _clone_,
.log = _log_,
diff --git a/src/libpts/pts/components/pts_comp_func_name.h b/src/libpts/pts/components/pts_comp_func_name.h
index 2c7a84177..a3ffa1ba9 100644
--- a/src/libpts/pts/components/pts_comp_func_name.h
+++ b/src/libpts/pts/components/pts_comp_func_name.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -55,6 +55,13 @@ struct pts_comp_func_name_t {
u_int8_t (*get_qualifier)(pts_comp_func_name_t *this);
/**
+ * Set the PTS Component Functional Name Qualifier
+ *
+ * @param qualifier PTS Component Functional Name Qualifier to be set
+ */
+ void (*set_qualifier)(pts_comp_func_name_t *this, u_int8_t qualifier);
+
+ /**
* Check to PTS Component Functional Names for equality
*
* @param other Other PTS Component Functional Name
diff --git a/src/libpts/pts/components/pts_component.h b/src/libpts/pts/components/pts_component.h
index 524ff332d..da339a55f 100644
--- a/src/libpts/pts/components/pts_component.h
+++ b/src/libpts/pts/components/pts_component.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@ typedef struct pts_component_t pts_component_t;
#include "pts/pts.h"
#include "pts/pts_database.h"
+#include "pts/pts_file_meas.h"
#include "pts/components/pts_comp_func_name.h"
#include "pts/components/pts_comp_evidence.h"
@@ -59,30 +60,41 @@ struct pts_component_t {
/**
* Do evidence measurements on the PTS Functional Component
*
+ * @param qualifier PTS Component Functional Name Qualifier
* @param pts PTS interface
* @param evidence returns component evidence measureemt
+ * @param measurements additional file measurements (NULL if not present)
* @return status return code
*/
- status_t (*measure)(pts_component_t *this, pts_t *pts,
+ status_t (*measure)(pts_component_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t** evidence);
/**
* Verify the evidence measurements of the PTS Functional Component
*
+ * @param qualifier PTS Component Functional Name Qualifier
* @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,
+ status_t (*verify)(pts_component_t *this, u_int8_t qualifier, pts_t *pts,
pts_comp_evidence_t *evidence);
-
/**
* Tell the PTS Functional Component to finalize pending registrations
+ * and check for missing measurements
+ *
+ * @param qualifier PTS Component Functional Name Qualifier
+ * @return TRUE if finalization successful
+ */
+ bool (*finalize)(pts_component_t *this, u_int8_t qualifier);
+
+ /**
+ * Get a new reference to the PTS Functional Component
*
- * @return TRUE if there are pending registrations
+ * @return this, with an increased refcount
*/
- bool (*check_off_registrations)(pts_component_t *this);
+ pts_component_t* (*get_ref)(pts_component_t *this);
/**
* Destroys a pts_component_t object.
diff --git a/src/libpts/pts/components/pts_component_manager.c b/src/libpts/pts/components/pts_component_manager.c
index 8ac4767bf..e330aeebf 100644
--- a/src/libpts/pts/components/pts_component_manager.c
+++ b/src/libpts/pts/components/pts_component_manager.c
@@ -1,6 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
- *
+ * Copyright (C) 2011-2012 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -270,8 +269,7 @@ METHOD(pts_component_manager_t, create, pts_component_t*,
{
if (entry2->name == name->get_name(name) && entry2->create)
{
- component = entry2->create(name->get_qualifier(name),
- depth, pts_db);
+ component = entry2->create(depth, pts_db);
break;
}
}
diff --git a/src/libpts/pts/components/pts_component_manager.h b/src/libpts/pts/components/pts_component_manager.h
index 0079d0e26..61055ec74 100644
--- a/src/libpts/pts/components/pts_component_manager.h
+++ b/src/libpts/pts/components/pts_component_manager.h
@@ -30,8 +30,7 @@ typedef struct pts_component_manager_t pts_component_manager_t;
#include <library.h>
#include <pen/pen.h>
-typedef pts_component_t* (*pts_component_create_t)(u_int8_t qualifier,
- u_int32_t depth,
+typedef pts_component_t* (*pts_component_create_t)(u_int32_t depth,
pts_database_t *pts_db);
/**
diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c
index 65ae2b2d2..4c6c5bc22 100644
--- a/src/libpts/pts/pts.c
+++ b/src/libpts/pts/pts.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -23,22 +23,13 @@
#include <trousers/tss.h>
#include <trousers/trousers.h>
+#include <sys/types.h>
#include <sys/stat.h>
#include <sys/utsname.h>
+#include <libgen.h>
+#include <unistd.h>
#include <errno.h>
-#define PTS_BUF_SIZE 4096
-
-/**
- * Maximum number of PCR's of TPM, TPM Spec 1.2
- */
-#define PCR_MAX_NUM 24
-
-/**
- * Number of bytes that can be saved in a PCR of TPM, TPM Spec 1.2
- */
-#define PCR_LEN 20
-
typedef struct private_pts_t private_pts_t;
/**
@@ -118,29 +109,9 @@ struct private_pts_t {
certificate_t *aik;
/**
- * Table of extended PCRs with corresponding values
- */
- u_char* pcrs[PCR_MAX_NUM];
-
- /**
- * Length of PCR registers
- */
- size_t pcr_len;
-
- /**
- * Number of extended PCR registers
- */
- u_int32_t pcr_count;
-
- /**
- * Highest extended PCR register
- */
- u_int32_t pcr_max;
-
- /**
- * Bitmap of extended PCR registers
+ * Shadow PCR set
*/
- u_int8_t pcr_select[PCR_MAX_NUM / 8];
+ pts_pcr_t *pcrs;
};
@@ -225,9 +196,13 @@ METHOD(pts_t, create_dh_nonce, bool,
DBG2(DBG_PTS, "nonce length is %d", nonce_len);
nonce = this->is_imc ? &this->responder_nonce : &this->initiator_nonce;
chunk_free(nonce);
- rng->allocate_bytes(rng, nonce_len, nonce);
+ if (!rng->allocate_bytes(rng, nonce_len, nonce))
+ {
+ DBG1(DBG_PTS, "failed to allocate nonce");
+ rng->destroy(rng);
+ return FALSE;
+ }
rng->destroy(rng);
-
return TRUE;
}
@@ -282,10 +257,15 @@ METHOD(pts_t, calculate_secret, bool,
hash_alg = pts_meas_algo_to_hash(this->dh_hash_algorithm);
hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
- hasher->allocate_hash(hasher, chunk_from_chars('1'), NULL);
- hasher->allocate_hash(hasher, this->initiator_nonce, NULL);
- hasher->allocate_hash(hasher, this->responder_nonce, NULL);
- hasher->allocate_hash(hasher, shared_secret, &this->secret);
+ if (!hasher ||
+ !hasher->get_hash(hasher, chunk_from_chars('1'), NULL) ||
+ !hasher->get_hash(hasher, this->initiator_nonce, NULL) ||
+ !hasher->get_hash(hasher, this->responder_nonce, NULL) ||
+ !hasher->allocate_hash(hasher, shared_secret, &this->secret))
+ {
+ DESTROY_IF(hasher);
+ return FALSE;
+ }
hasher->destroy(hasher);
/* The DH secret must be destroyed */
@@ -359,12 +339,6 @@ METHOD(pts_t, set_tpm_version_info, void,
print_tpm_version_info(this);
}
-METHOD(pts_t, get_pcr_len, size_t,
- private_pts_t *this)
-{
- return this->pcr_len;
-}
-
/**
* Load an AIK Blob (TSS_TSPATTRIB_KEYBLOB_BLOB attribute)
*/
@@ -486,54 +460,6 @@ METHOD(pts_t, get_aik_keyid, bool,
return success;
}
-METHOD(pts_t, hash_file, bool,
- private_pts_t *this, hasher_t *hasher, char *pathname, u_char *hash)
-{
- u_char buffer[PTS_BUF_SIZE];
- FILE *file;
- int bytes_read;
-
- file = fopen(pathname, "rb");
- if (!file)
- {
- DBG1(DBG_PTS," file '%s' can not be opened, %s", pathname,
- strerror(errno));
- return FALSE;
- }
- while (TRUE)
- {
- bytes_read = fread(buffer, 1, sizeof(buffer), file);
- if (bytes_read > 0)
- {
- hasher->get_hash(hasher, chunk_create(buffer, bytes_read), NULL);
- }
- else
- {
- hasher->get_hash(hasher, chunk_empty, hash);
- break;
- }
- }
- fclose(file);
-
- return TRUE;
-}
-
-/**
- * Get the relative filename of a fully qualified file pathname
- */
-static char* get_filename(char *pathname)
-{
- char *pos, *filename;
-
- pos = filename = pathname;
- while (pos && *(++pos) != '\0')
- {
- filename = pos;
- pos = strchr(filename, '/');
- }
- return filename;
-}
-
METHOD(pts_t, is_path_valid, bool,
private_pts_t *this, char *path, pts_error_code_t *error_code)
{
@@ -565,82 +491,6 @@ METHOD(pts_t, is_path_valid, bool,
return TRUE;
}
-METHOD(pts_t, do_measurements, pts_file_meas_t*,
- private_pts_t *this, u_int16_t request_id, char *pathname, bool is_directory)
-{
- hasher_t *hasher;
- hash_algorithm_t hash_alg;
- u_char hash[HASH_SIZE_SHA384];
- chunk_t measurement;
- pts_file_meas_t *measurements;
-
- /* Create a hasher */
- hash_alg = pts_meas_algo_to_hash(this->algorithm);
- hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
- if (!hasher)
- {
- DBG1(DBG_PTS, "hasher %N not available", hash_algorithm_names, hash_alg);
- return NULL;
- }
-
- /* Create a measurement object */
- measurements = pts_file_meas_create(request_id);
-
- /* Link the hash to the measurement and set the measurement length */
- measurement = chunk_create(hash, hasher->get_hash_size(hasher));
-
- if (is_directory)
- {
- enumerator_t *enumerator;
- char *rel_name, *abs_name;
- struct stat st;
-
- enumerator = enumerator_create_directory(pathname);
- if (!enumerator)
- {
- DBG1(DBG_PTS," directory '%s' can not be opened, %s", pathname,
- strerror(errno));
- hasher->destroy(hasher);
- measurements->destroy(measurements);
- return NULL;
- }
- while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
- {
- /* measure regular files only */
- if (S_ISREG(st.st_mode) && *rel_name != '.')
- {
- if (!hash_file(this, hasher, abs_name, hash))
- {
- enumerator->destroy(enumerator);
- hasher->destroy(hasher);
- measurements->destroy(measurements);
- return NULL;
- }
- DBG2(DBG_PTS, " %#B for '%s'", &measurement, rel_name);
- measurements->add(measurements, rel_name, measurement);
- }
- }
- enumerator->destroy(enumerator);
- }
- else
- {
- char *filename;
-
- if (!hash_file(this, hasher, pathname, hash))
- {
- hasher->destroy(hasher);
- measurements->destroy(measurements);
- return NULL;
- }
- filename = get_filename(pathname);
- DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename);
- measurements->add(measurements, filename, measurement);
- }
- hasher->destroy(hasher);
-
- return measurements;
-}
-
/**
* Obtain statistical information describing a file
*/
@@ -654,6 +504,7 @@ static bool file_metadata(char *pathname, pts_file_metadata_t **entry)
if (stat(pathname, &st))
{
DBG1(DBG_PTS, "unable to obtain statistics about '%s'", pathname);
+ free(this);
return FALSE;
}
@@ -748,7 +599,7 @@ METHOD(pts_t, get_metadata, pts_file_meta_t*,
metadata->destroy(metadata);
return NULL;
}
- entry->filename = strdup(get_filename(pathname));
+ entry->filename = strdup(basename(pathname));
metadata->add(metadata, entry);
}
@@ -809,7 +660,7 @@ METHOD(pts_t, extend_pcr, bool,
TSS_HTPM hTPM;
TSS_RESULT result;
u_int32_t pcr_length;
- chunk_t pcr_value;
+ chunk_t pcr_value = chunk_empty;
result = Tspi_Context_Create(&hContext);
if (result != TSS_SUCCESS)
@@ -829,8 +680,8 @@ METHOD(pts_t, extend_pcr, bool,
goto err;
}
- pcr_value = chunk_alloc(PCR_LEN);
- result = Tspi_TPM_PcrExtend(hTPM, pcr_num, PCR_LEN, input.ptr,
+ pcr_value = chunk_alloc(PTS_PCR_LEN);
+ result = Tspi_TPM_PcrExtend(hTPM, pcr_num, PTS_PCR_LEN, input.ptr,
NULL, &pcr_length, &pcr_value.ptr);
if (result != TSS_SUCCESS)
{
@@ -842,7 +693,7 @@ METHOD(pts_t, extend_pcr, bool,
DBG3(DBG_PTS, "PCR %d extended with: %B", pcr_num, &input);
DBG3(DBG_PTS, "PCR %d value after extend: %B", pcr_num, output);
-
+
chunk_clear(&pcr_value);
Tspi_Context_FreeMemory(hContext, NULL);
Tspi_Context_Close(hContext);
@@ -851,28 +702,12 @@ METHOD(pts_t, extend_pcr, bool,
err:
DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
-
+
chunk_clear(&pcr_value);
Tspi_Context_FreeMemory(hContext, NULL);
Tspi_Context_Close(hContext);
-
- return FALSE;
-}
-
-
-static void clear_pcrs(private_pts_t *this)
-{
- int i;
- for (i = 0; i <= this->pcr_max; i++)
- {
- free(this->pcrs[i]);
- this->pcrs[i] = NULL;
- }
- this->pcr_count = 0;
- this->pcr_max = 0;
-
- memset(this->pcr_select, 0x00, sizeof(this->pcr_select));
+ return FALSE;
}
METHOD(pts_t, quote_tpm, bool,
@@ -890,7 +725,8 @@ METHOD(pts_t, quote_tpm, bool,
TSS_RESULT result;
chunk_t quote_info;
BYTE* versionInfo;
- u_int32_t versionInfoSize, pcr, i = 0, f = 1;
+ u_int32_t versionInfoSize, pcr;
+ enumerator_t *enumerator;
bool success = FALSE;
result = Tspi_Context_Create(&hContext);
@@ -943,32 +779,30 @@ METHOD(pts_t, quote_tpm, bool,
Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS,
TSS_PCRS_STRUCT_INFO_SHORT, &hPcrComposite) :
Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_PCRS,
- 0, &hPcrComposite);
+ TSS_PCRS_STRUCT_DEFAULT, &hPcrComposite);
if (result != TSS_SUCCESS)
{
goto err2;
}
/* Select PCRs */
- for (pcr = 0; pcr <= this->pcr_max ; pcr++)
- {
- if (f == 256)
+ enumerator = this->pcrs->create_enumerator(this->pcrs);
+ while (enumerator->enumerate(enumerator, &pcr))
+ {
+ result = use_quote2 ?
+ Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
+ TSS_PCRS_DIRECTION_RELEASE) :
+ Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr);
+ if (result != TSS_SUCCESS)
{
- i++;
- f = 1;
- }
- if (this->pcr_select[i] & f)
- {
- result = use_quote2 ?
- Tspi_PcrComposite_SelectPcrIndexEx(hPcrComposite, pcr,
- TSS_PCRS_DIRECTION_RELEASE) :
- Tspi_PcrComposite_SelectPcrIndex(hPcrComposite, pcr);
- if (result != TSS_SUCCESS)
- {
- goto err3;
- }
+ break;
}
- f <<= 1;
+ }
+ enumerator->destroy(enumerator);
+
+ if (result != TSS_SUCCESS)
+ {
+ goto err3;
}
/* Set the Validation Data */
@@ -1028,87 +862,14 @@ err1:
{
DBG1(DBG_PTS, "TPM not available: tss error 0x%x", result);
}
- clear_pcrs(this);
return success;
}
-METHOD(pts_t, select_pcr, bool,
- private_pts_t *this, u_int32_t pcr)
-{
- u_int32_t i, f;
-
- if (pcr >= PCR_MAX_NUM)
- {
- DBG1(DBG_PTS, "PCR %u: number is larger than maximum of %u",
- pcr, PCR_MAX_NUM-1);
- return FALSE;
- }
-
- /* Determine PCR selection flag */
- i = pcr / 8;
- f = 1 << (pcr - 8*i);
-
- /* Has this PCR already been selected? */
- if (!(this->pcr_select[i] & f))
- {
- this->pcr_select[i] |= f;
- this->pcr_max = max(this->pcr_max, pcr);
- this->pcr_count++;
- }
-
- return TRUE;
-}
-
-METHOD(pts_t, add_pcr, bool,
- private_pts_t *this, u_int32_t pcr, chunk_t pcr_before, chunk_t pcr_after)
+METHOD(pts_t, get_pcrs, pts_pcr_t*,
+ private_pts_t *this)
{
- if (pcr >= PCR_MAX_NUM)
- {
- DBG1(DBG_PTS, "PCR %u: number is larger than maximum of %u",
- pcr, PCR_MAX_NUM-1);
- return FALSE;
- }
-
- /* Is the length of the PCR registers already set? */
- if (this->pcr_len)
- {
- if (pcr_after.len != this->pcr_len)
- {
- DBG1(DBG_PTS, "PCR %02u: length is %d bytes but should be %d bytes",
- pcr_after.len, this->pcr_len);
- return FALSE;
- }
- }
- else
- {
- this->pcr_len = pcr_after.len;
- }
-
- /* Has the value of the PCR register already been assigned? */
- if (this->pcrs[pcr])
- {
- if (!memeq(this->pcrs[pcr], pcr_before.ptr, this->pcr_len))
- {
- DBG1(DBG_PTS, "PCR %02u: new pcr_before value does not equal "
- "old pcr_after value");
- }
- /* remove the old PCR value */
- free(this->pcrs[pcr]);
- }
- else
- {
- /* add extended PCR Register */
- this->pcr_select[pcr / 8] |= 1 << (pcr % 8);
- this->pcr_max = max(this->pcr_max, pcr);
- this->pcr_count++;
- }
-
- /* Duplicate and store current PCR value */
- pcr_after = chunk_clone(pcr_after);
- this->pcrs[pcr] = pcr_after.ptr;
-
- return TRUE;
+ return this->pcrs;
}
/**
@@ -1130,13 +891,11 @@ METHOD(pts_t, get_quote_info, bool,
pts_meas_algorithms_t comp_hash_algo,
chunk_t *out_pcr_comp, chunk_t *out_quote_info)
{
- u_int8_t size_of_select;
- int pcr_comp_len, i;
- chunk_t pcr_comp, hash_pcr_comp;
+ chunk_t selection, pcr_comp, hash_pcr_comp;
bio_writer_t *writer;
hasher_t *hasher;
- if (this->pcr_count == 0)
+ if (!this->pcrs->get_count(this->pcrs))
{
DBG1(DBG_PTS, "No extended PCR entries available, "
"unable to construct TPM Quote Info");
@@ -1154,34 +913,9 @@ METHOD(pts_t, get_quote_info, bool,
"unable to construct TPM Quote Info2");
return FALSE;
}
-
- /**
- * A TPM v1.2 has 24 PCR Registers
- * so the bitmask field length used by TrouSerS is at least 3 bytes
- */
- size_of_select = max(PCR_MAX_NUM / 8, 1 + this->pcr_max / 8);
- pcr_comp_len = 2 + size_of_select + 4 + this->pcr_count * this->pcr_len;
-
- writer = bio_writer_create(pcr_comp_len);
-
- writer->write_uint16(writer, size_of_select);
- for (i = 0; i < size_of_select; i++)
- {
- writer->write_uint8(writer, this->pcr_select[i]);
- }
- writer->write_uint32(writer, this->pcr_count * this->pcr_len);
- for (i = 0; i < 8 * size_of_select; i++)
- {
- if (this->pcrs[i])
- {
- writer->write_data(writer, chunk_create(this->pcrs[i], this->pcr_len));
- }
- }
- pcr_comp = chunk_clone(writer->get_buf(writer));
- DBG3(DBG_PTS, "constructed PCR Composite: %B", &pcr_comp);
+ pcr_comp = this->pcrs->get_composite(this->pcrs);
- writer->destroy(writer);
/* Output the TPM_PCR_COMPOSITE expected from IMC */
if (comp_hash_algo)
@@ -1192,7 +926,12 @@ METHOD(pts_t, get_quote_info, bool,
hasher = lib->crypto->create_hasher(lib->crypto, algo);
/* Hash the PCR Composite Structure */
- hasher->allocate_hash(hasher, pcr_comp, out_pcr_comp);
+ if (!hasher || !hasher->allocate_hash(hasher, pcr_comp, out_pcr_comp))
+ {
+ DESTROY_IF(hasher);
+ free(pcr_comp.ptr);
+ return FALSE;
+ }
DBG3(DBG_PTS, "constructed PCR Composite hash: %#B", out_pcr_comp);
hasher->destroy(hasher);
}
@@ -1203,7 +942,13 @@ METHOD(pts_t, get_quote_info, bool,
/* SHA1 hash of PCR Composite to construct TPM_QUOTE_INFO */
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- hasher->allocate_hash(hasher, pcr_comp, &hash_pcr_comp);
+ if (!hasher || !hasher->allocate_hash(hasher, pcr_comp, &hash_pcr_comp))
+ {
+ DESTROY_IF(hasher);
+ chunk_free(out_pcr_comp);
+ free(pcr_comp.ptr);
+ return FALSE;
+ }
hasher->destroy(hasher);
/* Construct TPM_QUOTE_INFO/TPM_QUOTE_INFO2 structure */
@@ -1220,15 +965,11 @@ METHOD(pts_t, get_quote_info, bool,
/* Secret assessment value 20 bytes (nonce) */
writer->write_data(writer, this->secret);
- /* Length of the PCR selection field */
- writer->write_uint16(writer, size_of_select);
-
/* PCR selection */
- for (i = 0; i < size_of_select ; i++)
- {
- writer->write_uint8(writer, this->pcr_select[i]);
- }
-
+ selection.ptr = pcr_comp.ptr;
+ selection.len = 2 + this->pcrs->get_selection_size(this->pcrs);
+ writer->write_data(writer, selection);
+
/* TPM Locality Selection */
writer->write_uint8(writer, TPM_LOC_ZERO);
@@ -1263,7 +1004,6 @@ METHOD(pts_t, get_quote_info, bool,
writer->destroy(writer);
free(pcr_comp.ptr);
free(hash_pcr_comp.ptr);
- clear_pcrs(this);
return TRUE;
}
@@ -1295,7 +1035,7 @@ METHOD(pts_t, verify_quote_signature, bool,
METHOD(pts_t, destroy, void,
private_pts_t *this)
{
- clear_pcrs(this);
+ DESTROY_IF(this->pcrs);
DESTROY_IF(this->aik);
DESTROY_IF(this->dh);
free(this->initiator_nonce.ptr);
@@ -1357,7 +1097,7 @@ static char* extract_platform_info(void)
{
strcpy(buf, str_debian);
pos += strlen(str_debian);
- len -= strlen(str_debian);
+ len -= strlen(str_debian);
}
fseek(file, 0, SEEK_END);
@@ -1477,6 +1217,14 @@ static bool has_tpm(private_pts_t *this)
pts_t *pts_create(bool is_imc)
{
private_pts_t *this;
+ pts_pcr_t *pcrs;
+
+ pcrs = pts_pcr_create();
+ if (!pcrs)
+ {
+ DBG1(DBG_PTS, "shadow PCR set could not be created");
+ return NULL;
+ }
INIT(this,
.public = {
@@ -1494,19 +1242,15 @@ pts_t *pts_create(bool is_imc)
.set_platform_info = _set_platform_info,
.get_tpm_version_info = _get_tpm_version_info,
.set_tpm_version_info = _set_tpm_version_info,
- .get_pcr_len = _get_pcr_len,
.get_aik = _get_aik,
.set_aik = _set_aik,
.get_aik_keyid = _get_aik_keyid,
.is_path_valid = _is_path_valid,
- .hash_file = _hash_file,
- .do_measurements = _do_measurements,
.get_metadata = _get_metadata,
.read_pcr = _read_pcr,
.extend_pcr = _extend_pcr,
.quote_tpm = _quote_tpm,
- .select_pcr = _select_pcr,
- .add_pcr = _add_pcr,
+ .get_pcrs = _get_pcrs,
.get_quote_info = _get_quote_info,
.verify_quote_signature = _verify_quote_signature,
.destroy = _destroy,
@@ -1515,6 +1259,7 @@ pts_t *pts_create(bool is_imc)
.proto_caps = PTS_PROTO_CAPS_V,
.algorithm = PTS_MEAS_ALGO_SHA256,
.dh_hash_algorithm = PTS_MEAS_ALGO_SHA256,
+ .pcrs = pcrs,
);
if (is_imc)
@@ -1524,7 +1269,6 @@ pts_t *pts_create(bool is_imc)
if (has_tpm(this))
{
this->has_tpm = TRUE;
- this->pcr_len = PCR_LEN;
this->proto_caps |= PTS_PROTO_CAPS_T | PTS_PROTO_CAPS_D;
load_aik(this);
load_aik_blob(this);
diff --git a/src/libpts/pts/pts.h b/src/libpts/pts/pts.h
index 212acb02a..5f88cd15c 100644
--- a/src/libpts/pts/pts.h
+++ b/src/libpts/pts/pts.h
@@ -29,6 +29,7 @@ typedef struct pts_t pts_t;
#include "pts_file_meas.h"
#include "pts_file_meta.h"
#include "pts_dh_group.h"
+#include "pts_pcr.h"
#include "pts_req_func_comp_evid.h"
#include "pts_simple_evid_final.h"
#include "components/pts_comp_func_name.h"
@@ -190,13 +191,6 @@ struct pts_t {
void (*set_tpm_version_info)(pts_t *this, chunk_t info);
/**
- * Get the length of the TPM PCR registers
- *
- * @return Length of PCR registers in bytes, 0 if undefined
- */
- size_t (*get_pcr_len)(pts_t *this);
-
- /**
* Get Attestation Identity Certificate or Public Key
*
* @return AIK Certificate or Public Key
@@ -230,34 +224,13 @@ struct pts_t {
bool (*is_path_valid)(pts_t *this, char *path, pts_error_code_t *error_code);
/**
- * Compute a hash over a file
- * @param hasher Hasher to be used
- * @param pathname Absolute path of a file
- * @param hash Buffer to keep hash output
- * @return TRUE if path is valid and hashing succeeded
- */
- bool (*hash_file)(pts_t *this, hasher_t *hasher, char *pathname, u_char *hash);
-
- /**
- * Do PTS File Measurements
- *
- * @param request_id ID of PTS File Measurement Request
- * @param pathname Absolute pathname of file to be measured
- * @param is_directory TRUE if directory contents are measured
- * @return PTS File Measurements of NULL if FAILED
- */
- pts_file_meas_t* (*do_measurements)(pts_t *this, u_int16_t request_id,
- char *pathname, bool is_directory);
-
- /**
* Obtain file metadata
*
* @param pathname Absolute pathname of file/directory
- * @param is_directory TRUE if directory contents are requested
+ * @param is_dir TRUE if directory contents are requested
* @return PTS File Metadata or NULL if FAILED
*/
- pts_file_meta_t* (*get_metadata)(pts_t *this, char *pathname,
- bool is_directory);
+ pts_file_meta_t* (*get_metadata)(pts_t *this, char *pathname, bool is_dir);
/**
* Reads given PCR value and returns it
@@ -294,24 +267,12 @@ struct pts_t {
bool (*quote_tpm)(pts_t *this, bool use_quote2, chunk_t *pcr_comp,
chunk_t *quote_sig);
- /**
- * Mark an extended PCR as selected
- *
- * @param pcr Number of the extended PCR
- * @return TRUE if PCR number is valid
- */
- bool (*select_pcr)(pts_t *this, u_int32_t pcr);
-
- /**
- * Add an extended PCR with its corresponding value
+ /**
+ * Get the shadow PCR set
*
- * @param pcr Number of the extended PCR
- * @param pcr_before PCR value before extension
- * @param pcr_after PCR value after extension
- * @return TRUE if PCR number and register length is valid
+ * @return shadow PCR set
*/
- bool (*add_pcr)(pts_t *this, u_int32_t pcr, chunk_t pcr_before,
- chunk_t pcr_after);
+ pts_pcr_t* (*get_pcrs)(pts_t *this);
/**
* Constructs and returns TPM Quote Info structure expected from IMC
diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c
index 282755c0a..946f37e1e 100644
--- a/src/libpts/pts/pts_database.c
+++ b/src/libpts/pts/pts_database.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -121,6 +121,42 @@ METHOD(pts_database_t, check_aik_keyid, status_t,
return SUCCESS;
}
+METHOD(pts_database_t, check_file_measurement, status_t,
+ private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
+ chunk_t measurement, char *filename)
+{
+ enumerator_t *e;
+ chunk_t hash;
+ status_t status = NOT_FOUND;
+
+ e = this->db->query(this->db,
+ "SELECT fh.hash FROM file_hashes AS fh "
+ "JOIN files AS f ON f.id = fh.file "
+ "JOIN products AS p ON p.id = fh.product "
+ "WHERE p.name = ? AND f.path = ? AND fh.algo = ?",
+ DB_TEXT, product, DB_TEXT, filename, DB_INT, algo, DB_BLOB);
+ if (!e)
+ {
+ return FAILED;
+ }
+ while (e->enumerate(e, &hash))
+ {
+ /* with relative filenames there might be multiple entries */
+ if (chunk_equals(measurement, hash))
+ {
+ status = SUCCESS;
+ break;
+ }
+ else
+ {
+ status = VERIFY_ERROR;
+ }
+ }
+ e->destroy(e);
+
+ return status;
+}
+
METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
private_pts_database_t *this, int kid)
{
@@ -169,7 +205,7 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
"found in database", pcr, seq_no);
DBG1(DBG_PTS, " expected: %#B", &hash);
DBG1(DBG_PTS, " received: %#B", &measurement);
- status = FAILED;
+ status = VERIFY_ERROR;
break;
}
}
@@ -290,6 +326,7 @@ pts_database_t *pts_database_create(char *uri)
.create_comp_evid_enumerator = _create_comp_evid_enumerator,
.create_file_hash_enumerator = _create_file_hash_enumerator,
.check_aik_keyid = _check_aik_keyid,
+ .check_file_measurement = _check_file_measurement,
.check_comp_measurement = _check_comp_measurement,
.insert_comp_measurement = _insert_comp_measurement,
.delete_comp_measurements = _delete_comp_measurements,
diff --git a/src/libpts/pts/pts_database.h b/src/libpts/pts/pts_database.h
index a9a68ac76..649ef0e31 100644
--- a/src/libpts/pts/pts_database.h
+++ b/src/libpts/pts/pts_database.h
@@ -82,6 +82,19 @@ struct pts_database_t {
enumerator_t* (*create_comp_evid_enumerator)(pts_database_t *this, int kid);
/**
+ * Check PTS file measurement against reference stored in database
+ *
+ * @param product Software product (os, vpn client, etc.)
+ * @param algo File measurement hash algorithm used
+ * @param measurement File measurement hash
+ * @param filename Optional name of the file to be checked
+ * @return Status
+ */
+ status_t (*check_file_measurement)(pts_database_t *this, char *product,
+ pts_meas_algorithms_t algo,
+ chunk_t measurement, char *filename);
+
+ /**
* Check a functional component measurement against value stored in database
*
* @param measurement measurement hash
diff --git a/src/libpts/pts/pts_error.c b/src/libpts/pts/pts_error.c
index 6e914b2a9..1e79689f9 100644
--- a/src/libpts/pts/pts_error.c
+++ b/src/libpts/pts/pts_error.c
@@ -46,13 +46,13 @@ pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms)
bio_writer_t *writer;
chunk_t msg_info;
pa_tnc_attr_t *attr;
+ pen_type_t error_code = { PEN_TCG, TCG_PTS_HASH_ALG_NOT_SUPPORTED };
writer = bio_writer_create(4);
writer->write_uint16(writer, 0x0000);
writer->write_uint16(writer, algorithms);
msg_info = writer->get_buf(writer);
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_HASH_ALG_NOT_SUPPORTED,
- msg_info);
+ attr = ietf_attr_pa_tnc_error_create(error_code, msg_info);
writer->destroy(writer);
return attr;
@@ -66,13 +66,13 @@ pa_tnc_attr_t* pts_dh_group_error_create(pts_dh_group_t dh_groups)
bio_writer_t *writer;
chunk_t msg_info;
pa_tnc_attr_t *attr;
+ pen_type_t error_code = { PEN_TCG, TCG_PTS_DH_GRPS_NOT_SUPPORTED };
writer = bio_writer_create(4);
writer->write_uint16(writer, 0x0000);
writer->write_uint16(writer, dh_groups);
msg_info = writer->get_buf(writer);
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_DH_GRPS_NOT_SUPPORTED,
- msg_info);
+ attr = ietf_attr_pa_tnc_error_create(error_code, msg_info);
writer->destroy(writer);
return attr;
@@ -86,13 +86,13 @@ pa_tnc_attr_t* pts_dh_nonce_error_create(int min_nonce_len, int max_nonce_len)
bio_writer_t *writer;
chunk_t msg_info;
pa_tnc_attr_t *attr;
+ pen_type_t error_code = { PEN_TCG, TCG_PTS_BAD_NONCE_LENGTH };
writer = bio_writer_create(4);
writer->write_uint16(writer, min_nonce_len);
writer->write_uint16(writer, max_nonce_len);
msg_info = writer->get_buf(writer);
- attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_BAD_NONCE_LENGTH,
- msg_info);
+ attr = ietf_attr_pa_tnc_error_create(error_code, msg_info);
writer->destroy(writer);
return attr;
diff --git a/src/libpts/pts/pts_file_meas.c b/src/libpts/pts/pts_file_meas.c
index f0e0d4c0a..4fece6b3c 100644
--- a/src/libpts/pts/pts_file_meas.c
+++ b/src/libpts/pts/pts_file_meas.c
@@ -18,6 +18,10 @@
#include <utils/linked_list.h>
#include <debug.h>
+#include <sys/stat.h>
+#include <libgen.h>
+#include <errno.h>
+
typedef struct private_pts_file_meas_t private_pts_file_meas_t;
/**
@@ -107,6 +111,51 @@ METHOD(pts_file_meas_t, create_enumerator, enumerator_t*,
(void*)entry_filter, NULL, NULL);
}
+METHOD(pts_file_meas_t, check, bool,
+ private_pts_file_meas_t *this, pts_database_t *pts_db, char *product,
+ pts_meas_algorithms_t algo)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ int count_ok = 0, count_not_found = 0, count_differ = 0;
+ status_t status;
+
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ status = pts_db->check_file_measurement(pts_db, product, algo,
+ entry->measurement, entry->filename);
+ switch (status)
+ {
+ case SUCCESS:
+ DBG3(DBG_PTS, " %#B for '%s' is ok", &entry->measurement,
+ entry->filename);
+ count_ok++;
+ break;
+ case NOT_FOUND:
+ DBG2(DBG_PTS, " %#B for '%s' not found", &entry->measurement,
+ entry->filename);
+ count_not_found++;
+ break;
+ case VERIFY_ERROR:
+ DBG1(DBG_PTS, " %#B for '%s' differs", &entry->measurement,
+ entry->filename);
+ count_differ++;
+ break;
+ case FAILED:
+ default:
+ DBG1(DBG_PTS, " %#B for '%s' failed", &entry->measurement,
+ entry->filename);
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ DBG1(DBG_PTS, "%d measurements, %d ok, %d not found, %d differ",
+ this->list->get_count(this->list),
+ count_ok, count_not_found, count_differ);
+ return TRUE;
+}
+
METHOD(pts_file_meas_t, verify, bool,
private_pts_file_meas_t *this, enumerator_t *e_hash, bool is_dir)
{
@@ -174,6 +223,7 @@ pts_file_meas_t *pts_file_meas_create(u_int16_t request_id)
.get_file_count = _get_file_count,
.add = _add,
.create_enumerator = _create_enumerator,
+ .check = _check,
.verify = _verify,
.destroy = _destroy,
},
@@ -184,3 +234,141 @@ pts_file_meas_t *pts_file_meas_create(u_int16_t request_id)
return &this->public;
}
+/**
+ * Hash a file with a given absolute pathname
+ */
+static bool hash_file(hasher_t *hasher, char *pathname, u_char *hash)
+{
+ u_char buffer[4096];
+ size_t bytes_read;
+ bool success = TRUE;
+ FILE *file;
+
+ file = fopen(pathname, "rb");
+ if (!file)
+ {
+ DBG1(DBG_PTS," file '%s' can not be opened, %s", pathname,
+ strerror(errno));
+ return FALSE;
+ }
+ while (TRUE)
+ {
+ bytes_read = fread(buffer, 1, sizeof(buffer), file);
+ if (bytes_read > 0)
+ {
+ if (!hasher->get_hash(hasher, chunk_create(buffer, bytes_read), NULL))
+ {
+ DBG1(DBG_PTS, " hasher increment error");
+ success = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ if (!hasher->get_hash(hasher, chunk_empty, hash))
+ {
+ DBG1(DBG_PTS, " hasher finalize error");
+ success = FALSE;
+ }
+ break;
+ }
+ }
+ fclose(file);
+
+ return success;
+}
+
+/**
+ * See header
+ */
+pts_file_meas_t *pts_file_meas_create_from_path(u_int16_t request_id,
+ char *pathname, bool is_dir, bool use_rel_name,
+ pts_meas_algorithms_t alg)
+{
+ private_pts_file_meas_t *this;
+ hash_algorithm_t hash_alg;
+ hasher_t *hasher;
+ u_char hash[HASH_SIZE_SHA384];
+ chunk_t measurement;
+ char* filename;
+ bool success = TRUE;
+
+ /* Create a hasher and a hash measurement buffer */
+ hash_alg = pts_meas_algo_to_hash(alg);
+ hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+ if (!hasher)
+ {
+ DBG1(DBG_PTS, "hasher %N not available", hash_algorithm_names, hash_alg);
+ return NULL;
+ }
+ measurement = chunk_create(hash, hasher->get_hash_size(hasher));
+
+ INIT(this,
+ .public = {
+ .get_request_id = _get_request_id,
+ .get_file_count = _get_file_count,
+ .add = _add,
+ .create_enumerator = _create_enumerator,
+ .check = _check,
+ .verify = _verify,
+ .destroy = _destroy,
+ },
+ .request_id = request_id,
+ .list = linked_list_create(),
+ );
+
+ if (is_dir)
+ {
+ enumerator_t *enumerator;
+ char *rel_name, *abs_name;
+ struct stat st;
+
+ enumerator = enumerator_create_directory(pathname);
+ if (!enumerator)
+ {
+ DBG1(DBG_PTS, " directory '%s' can not be opened, %s", pathname,
+ strerror(errno));
+ success = FALSE;
+ goto end;
+ }
+ while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
+ {
+ /* measure regular files only */
+ if (S_ISREG(st.st_mode) && *rel_name != '.')
+ {
+ if (!hash_file(hasher, abs_name, hash))
+ {
+ success = FALSE;
+ break;
+ }
+ filename = use_rel_name ? rel_name : abs_name;
+ DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename);
+ add(this, filename, measurement);
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ else
+ {
+ if (!hash_file(hasher, pathname, hash))
+ {
+ success = FALSE;
+ goto end;
+ }
+ filename = use_rel_name ? basename(pathname) : pathname;
+ DBG2(DBG_PTS, " %#B for '%s'", &measurement, filename);
+ add(this, filename, measurement);
+ }
+
+end:
+ hasher->destroy(hasher);
+ if (success)
+ {
+ return &this->public;
+ }
+ else
+ {
+ destroy(this);
+ return NULL;
+ }
+}
diff --git a/src/libpts/pts/pts_file_meas.h b/src/libpts/pts/pts_file_meas.h
index 3ebb5c2a0..71efd5026 100644
--- a/src/libpts/pts/pts_file_meas.h
+++ b/src/libpts/pts/pts_file_meas.h
@@ -21,6 +21,8 @@
#ifndef PTS_FILE_MEAS_H_
#define PTS_FILE_MEAS_H_
+#include "pts/pts_database.h"
+
#include <library.h>
typedef struct pts_file_meas_t pts_file_meas_t;
@@ -60,6 +62,17 @@ struct pts_file_meas_t {
enumerator_t* (*create_enumerator)(pts_file_meas_t *this);
/**
+ * Check PTS File Measurements against reference value in the database
+ *
+ * @param db PTS Measurement database
+ * @param product Software product (os, vpn client, etc.)
+ * @param algo PTS Measurement algorithm used
+ * @return TRUE if all measurements agreed
+ */
+ bool (*check)(pts_file_meas_t *this, pts_database_t *db, char* product,
+ pts_meas_algorithms_t algo);
+
+ /**
* Verify stored hashes against PTS File Measurements
*
* @param e_hash Hash enumerator
@@ -82,4 +95,17 @@ struct pts_file_meas_t {
*/
pts_file_meas_t* pts_file_meas_create(u_int16_t request_id);
+/**
+ * Creates a pts_file_meas_t object measuring a file/directory
+ *
+ * @param request_id ID of PTS File Measurement Request
+ * @param pathname Absolute file or directory pathname
+ * @param is_dir TRUE if directory path
+ * @param use_rel_name TRUE if relative filenames are to be used
+ * @param alg PTS hash measurement algorithm to be used
+ */
+pts_file_meas_t* pts_file_meas_create_from_path(u_int16_t request_id,
+ char* pathname, bool is_dir, bool use_rel_name,
+ pts_meas_algorithms_t alg);
+
#endif /** PTS_FILE_MEAS_H_ @}*/
diff --git a/src/libpts/pts/pts_meas_algo.c b/src/libpts/pts/pts_meas_algo.c
index 865857d3c..fbc9c6959 100644
--- a/src/libpts/pts/pts_meas_algo.c
+++ b/src/libpts/pts/pts_meas_algo.c
@@ -17,12 +17,21 @@
#include <debug.h>
-ENUM(pts_meas_algorithm_names, PTS_MEAS_ALGO_NONE, PTS_MEAS_ALGO_SHA384,
- "None",
- "SHA1",
- "SHA256",
- "SHA384"
-);
+ENUM_BEGIN(pts_meas_algorithm_names, PTS_MEAS_ALGO_NONE, PTS_MEAS_ALGO_NONE,
+ "None");
+ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA384, PTS_MEAS_ALGO_SHA384,
+ PTS_MEAS_ALGO_NONE,
+ "SHA384");
+ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA256, PTS_MEAS_ALGO_SHA256,
+ PTS_MEAS_ALGO_SHA384,
+ "SHA256");
+ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1, PTS_MEAS_ALGO_SHA1,
+ PTS_MEAS_ALGO_SHA256,
+ "SHA1");
+ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1_IMA, PTS_MEAS_ALGO_SHA1_IMA,
+ PTS_MEAS_ALGO_SHA1,
+ "SHA1-IMA");
+ENUM_END(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1_IMA);
/**
* Described in header.
diff --git a/src/libpts/pts/pts_meas_algo.h b/src/libpts/pts/pts_meas_algo.h
index 1d96a4946..27cdaea7e 100644
--- a/src/libpts/pts/pts_meas_algo.h
+++ b/src/libpts/pts/pts_meas_algo.h
@@ -30,10 +30,11 @@ typedef enum pts_meas_algorithms_t pts_meas_algorithms_t;
* PTS Measurement Algorithms
*/
enum pts_meas_algorithms_t {
- PTS_MEAS_ALGO_NONE = 0,
- PTS_MEAS_ALGO_SHA1 = (1<<15),
- PTS_MEAS_ALGO_SHA256 = (1<<14),
- PTS_MEAS_ALGO_SHA384 = (1<<13),
+ PTS_MEAS_ALGO_NONE = 0,
+ PTS_MEAS_ALGO_SHA384 = (1<<13),
+ PTS_MEAS_ALGO_SHA256 = (1<<14),
+ PTS_MEAS_ALGO_SHA1 = (1<<15),
+ PTS_MEAS_ALGO_SHA1_IMA = (1<<16), /* internal use only */
};
/**
diff --git a/src/libpts/pts/pts_pcr.c b/src/libpts/pts/pts_pcr.c
new file mode 100644
index 000000000..a7a2f5fae
--- /dev/null
+++ b/src/libpts/pts/pts_pcr.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2012 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_pcr.h"
+
+#include <debug.h>
+
+#include <stdarg.h>
+
+typedef struct private_pts_pcr_t private_pts_pcr_t;
+
+/**
+ * Private data of a pts_pcr_t object.
+ *
+ */
+struct private_pts_pcr_t {
+
+ /**
+ * Public pts_pcr_t interface.
+ */
+ pts_pcr_t public;
+
+ /**
+ * Shadow PCR registers
+ */
+ chunk_t pcrs[PTS_PCR_MAX_NUM];
+
+ /**
+ * Number of extended PCR registers
+ */
+ u_int32_t pcr_count;
+
+ /**
+ * Highest extended PCR register
+ */
+ u_int32_t pcr_max;
+
+ /**
+ * Bitmap of extended PCR registers
+ */
+ u_int8_t pcr_select[PTS_PCR_MAX_NUM / 8];
+
+ /**
+ * Hasher used to extend shadow PCRs
+ */
+ hasher_t *hasher;
+
+};
+
+METHOD(pts_pcr_t, get_count, u_int32_t,
+ private_pts_pcr_t *this)
+{
+ return this->pcr_count;
+}
+
+METHOD(pts_pcr_t, select_pcr, bool,
+ private_pts_pcr_t *this, u_int32_t pcr)
+{
+ u_int32_t i, f;
+
+ if (pcr >= PTS_PCR_MAX_NUM)
+ {
+ DBG1(DBG_PTS, "PCR %2u: number is larger than maximum of %u",
+ pcr, PTS_PCR_MAX_NUM-1);
+ return FALSE;
+ }
+
+ /* Determine PCR selection flag */
+ i = pcr / 8;
+ f = 1 << (pcr - 8*i);
+
+ /* Has this PCR already been selected? */
+ if (!(this->pcr_select[i] & f))
+ {
+ this->pcr_select[i] |= f;
+ this->pcr_max = max(this->pcr_max, pcr);
+ this->pcr_count++;
+ }
+ return TRUE;
+}
+
+METHOD(pts_pcr_t, get_selection_size, size_t,
+ private_pts_pcr_t *this)
+{
+
+ /**
+ * A TPM v1.2 has 24 PCR Registers so the bitmask field length
+ * used by TrouSerS is at least 3 bytes
+ */
+ return PTS_PCR_MAX_NUM / 8;
+}
+
+typedef struct {
+ /** implements enumerator_t */
+ enumerator_t public;
+ /** current PCR */
+ u_int32_t pcr;
+ /** back reference to parent */
+ private_pts_pcr_t *pcrs;
+} pcr_enumerator_t;
+
+/**
+ * Implementation of enumerator.enumerate
+ */
+static bool pcr_enumerator_enumerate(pcr_enumerator_t *this, ...)
+{
+ u_int32_t *pcr, i, f;
+ va_list args;
+
+ va_start(args, this);
+ pcr = va_arg(args, u_int32_t*);
+ va_end(args);
+
+ while (this->pcr <= this->pcrs->pcr_max)
+ {
+ /* Determine PCR selection flag */
+ i = this->pcr / 8;
+ f = 1 << (this->pcr - 8*i);
+
+ /* Assign current PCR to output argument and increase */
+ *pcr = this->pcr++;
+
+ /* return if PCR is selected */
+ if (this->pcrs->pcr_select[i] & f)
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+METHOD(pts_pcr_t, create_enumerator, enumerator_t*,
+ private_pts_pcr_t *this)
+{
+ pcr_enumerator_t *enumerator;
+
+ INIT(enumerator,
+ .public = {
+ .enumerate = (void*)pcr_enumerator_enumerate,
+ .destroy = (void*)free,
+ },
+ .pcrs = this,
+ );
+
+ return (enumerator_t*)enumerator;
+}
+
+METHOD(pts_pcr_t, get, chunk_t,
+ private_pts_pcr_t *this, u_int32_t pcr)
+{
+ return (pcr < PTS_PCR_MAX_NUM) ? this->pcrs[pcr] : chunk_empty;
+}
+
+METHOD(pts_pcr_t, set, bool,
+ private_pts_pcr_t *this, u_int32_t pcr, chunk_t value)
+{
+ if (value.len != PTS_PCR_LEN)
+ {
+ DBG1(DBG_PTS, "PCR %2u: value does not fit", pcr);
+ return FALSE;
+ }
+ if (select_pcr(this, pcr))
+ {
+ memcpy(this->pcrs[pcr].ptr, value.ptr, PTS_PCR_LEN);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+METHOD(pts_pcr_t, extend, chunk_t,
+ private_pts_pcr_t *this, u_int32_t pcr, chunk_t measurement)
+{
+ if (measurement.len != PTS_PCR_LEN)
+ {
+ DBG1(DBG_PTS, "PCR %2u: measurement does not fit", pcr);
+ return chunk_empty;
+ }
+ if (!select_pcr(this, pcr))
+ {
+ return chunk_empty;
+ }
+ if (!this->hasher->get_hash(this->hasher, this->pcrs[pcr] , NULL) ||
+ !this->hasher->get_hash(this->hasher, measurement, this->pcrs[pcr].ptr))
+ {
+ DBG1(DBG_PTS, "PCR %2u: not extended due to hasher problem", pcr);
+ return chunk_empty;
+ }
+ return this->pcrs[pcr];
+}
+
+METHOD(pts_pcr_t, get_composite, chunk_t,
+ private_pts_pcr_t *this)
+{
+ chunk_t composite;
+ enumerator_t *enumerator;
+ u_int16_t selection_size;
+ u_int32_t pcr_field_size, pcr;
+ u_char *pos;
+
+ selection_size = get_selection_size(this);
+ pcr_field_size = this->pcr_count * PTS_PCR_LEN;
+
+ composite = chunk_alloc(2 + selection_size + 4 + pcr_field_size);
+ pos = composite.ptr;
+ htoun16(pos, selection_size);
+ pos += 2;
+ memcpy(pos, this->pcr_select, selection_size);
+ pos += selection_size;
+ htoun32(pos, pcr_field_size);
+ pos += 4;
+
+ enumerator = create_enumerator(this);
+ while (enumerator->enumerate(enumerator, &pcr))
+ {
+ memcpy(pos, this->pcrs[pcr].ptr, PTS_PCR_LEN);
+ pos += PTS_PCR_LEN;
+ }
+ enumerator->destroy(enumerator);
+
+ DBG3(DBG_PTS, "constructed PCR Composite: %B", &composite);
+ return composite;
+}
+
+METHOD(pts_pcr_t, destroy, void,
+ private_pts_pcr_t *this)
+{
+ u_int32_t i;
+
+ for (i = 0; i < PTS_PCR_MAX_NUM; i++)
+ {
+ free(this->pcrs[i].ptr);
+ }
+ this->hasher->destroy(this->hasher);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_pcr_t *pts_pcr_create(void)
+{
+ private_pts_pcr_t *this;
+ hasher_t *hasher;
+ u_int32_t i;
+
+ hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
+ if (!hasher)
+ {
+ DBG1(DBG_PTS, "%N hasher could not be created",
+ hash_algorithm_short_names, HASH_SHA1);
+ return NULL;
+ }
+
+ INIT(this,
+ .public = {
+ .get_count = _get_count,
+ .select_pcr = _select_pcr,
+ .get_selection_size = _get_selection_size,
+ .create_enumerator = _create_enumerator,
+ .get = _get,
+ .set = _set,
+ .extend = _extend,
+ .get_composite = _get_composite,
+ .destroy = _destroy,
+ },
+ .hasher = hasher,
+ );
+
+ for (i = 0; i < PTS_PCR_MAX_NUM; i++)
+ {
+ this->pcrs[i] = chunk_alloc(PTS_PCR_LEN);
+ memset(this->pcrs[i].ptr, 0x00, PTS_PCR_LEN);
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/pts_pcr.h b/src/libpts/pts/pts_pcr.h
new file mode 100644
index 000000000..f638b5ee4
--- /dev/null
+++ b/src/libpts/pts/pts_pcr.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 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_pcr pts_pcr
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_PCR_H_
+#define PTS_PCR_H_
+
+typedef struct pts_pcr_t pts_pcr_t;
+
+#include <library.h>
+
+/**
+ * Maximum number of PCR's of TPM, TPM Spec 1.2
+ */
+#define PTS_PCR_MAX_NUM 24
+
+/**
+ * Number of bytes that can be saved in a PCR of TPM, TPM Spec 1.2
+ */
+#define PTS_PCR_LEN 20
+
+/**
+ * Class implementing a shadow PCR register set
+ */
+struct pts_pcr_t {
+
+ /**
+ * Get the number of selected PCRs
+ *
+ * @return number of selected PCRs
+ */
+ u_int32_t (*get_count)(pts_pcr_t *this);
+
+ /**
+ * Mark a PCR as selected
+ *
+ * @param pcr index of PCR
+ * @return TRUE if PCR index exists
+ */
+ bool (*select_pcr)(pts_pcr_t *this, u_int32_t pcr);
+
+ /**
+ * Get the size of the selection field in bytes
+ *
+ * @return number of bytes written
+ */
+ size_t (*get_selection_size)(pts_pcr_t *this);
+
+ /**
+ * Create an enumerator over all selected PCR indexes
+ *
+ * @return enumerator
+ */
+ enumerator_t* (*create_enumerator)(pts_pcr_t *this);
+
+ /**
+ * Get the current content of a PCR
+ *
+ * @param pcr index of PCR
+ * @return content of PCR
+ */
+ chunk_t (*get)(pts_pcr_t *this, u_int32_t pcr);
+
+ /**
+ * Set the content of a PCR
+ *
+ * @param pcr index of PCR
+ * @param value new value of PCR
+ * @return TRUE if value could be set
+ */
+ bool (*set)(pts_pcr_t *this, u_int32_t pcr, chunk_t value);
+
+ /**
+ * Extend the content of a PCR
+ *
+ * @param pcr index of PCR
+ * @param measurement measurment value to be extended into PCR
+ * @return new content of PCR
+ */
+ chunk_t (*extend)(pts_pcr_t *this, u_int32_t pcr, chunk_t measurement);
+
+ /**
+ * Create a PCR Composite object over all selected PCRs
+ *
+ * @return PCR Composite object (must be freed)
+ */
+ chunk_t (*get_composite)(pts_pcr_t *this);
+
+ /**
+
+ * Destroys a pts_pcr_t object.
+ */
+ void (*destroy)(pts_pcr_t *this);
+
+};
+
+/**
+ * Creates an pts_pcr_t object
+ */
+pts_pcr_t* pts_pcr_create(void);
+
+#endif /** PTS_PCR_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_aik.c b/src/libpts/tcg/tcg_pts_attr_aik.c
index 9be3794b6..75f3f179c 100644
--- a/src/libpts/tcg/tcg_pts_attr_aik.c
+++ b/src/libpts/tcg/tcg_pts_attr_aik.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -49,14 +49,9 @@ struct private_tcg_pts_attr_aik_t {
tcg_pts_attr_aik_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -79,13 +74,7 @@ struct private_tcg_pts_attr_aik_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_aik_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_aik_t *this)
{
return this->type;
@@ -117,6 +106,10 @@ METHOD(pa_tnc_attr_t, build, void,
cred_encoding_type_t encoding_type = CERT_ASN1_DER;
chunk_t aik_blob;
+ if (this->value.ptr)
+ {
+ return;
+ }
if (this->aik->get_type(this->aik) == CERT_TRUSTED_PUBKEY)
{
flags |= PTS_AIK_FLAGS_NAKED_KEY;
@@ -202,7 +195,6 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -214,8 +206,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create(certificate_t *aik)
},
.get_aik = _get_aik,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_AIK,
+ .type = { PEN_TCG, TCG_PTS_AIK },
.aik = aik->get_ref(aik),
.ref = 1,
);
@@ -234,7 +225,6 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -246,8 +236,7 @@ pa_tnc_attr_t *tcg_pts_attr_aik_create_from_data(chunk_t data)
},
.get_aik = _get_aik,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_AIK,
+ .type = { PEN_TCG, TCG_PTS_AIK },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c
index dce98e87d..3ca255cba 100644
--- a/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_finish.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -53,14 +53,9 @@ struct private_tcg_pts_attr_dh_nonce_finish_t {
tcg_pts_attr_dh_nonce_finish_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -93,13 +88,7 @@ struct private_tcg_pts_attr_dh_nonce_finish_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_dh_nonce_finish_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_dh_nonce_finish_t *this)
{
return this->type;
@@ -128,6 +117,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_DH_NONCE_FINISH_SIZE);
writer->write_uint8 (writer, PTS_DH_NONCE_FINISH_RESERVED);
writer->write_uint8 (writer, this->initiator_nonce.len);
@@ -217,7 +210,6 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create(
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -231,8 +223,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create(
.get_initiator_nonce = _get_initiator_nonce,
.get_initiator_value = _get_initiator_value,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_DH_NONCE_FINISH,
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_FINISH },
.hash_algo = hash_algo,
.initiator_value = initiator_value,
.initiator_nonce = chunk_clone(initiator_nonce),
@@ -252,7 +243,6 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -266,8 +256,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_finish_create_from_data(chunk_t value)
.get_initiator_nonce = _get_initiator_nonce,
.get_initiator_value = _get_initiator_value,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_DH_NONCE_FINISH,
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_FINISH },
.value = chunk_clone(value),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c
index 36266fe12..828c09605 100644
--- a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_req.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -49,14 +49,9 @@ struct private_tcg_pts_attr_dh_nonce_params_req_t {
tcg_pts_attr_dh_nonce_params_req_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -84,13 +79,7 @@ struct private_tcg_pts_attr_dh_nonce_params_req_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_dh_nonce_params_req_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_dh_nonce_params_req_t *this)
{
return this->type;
@@ -119,6 +108,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_DH_NONCE_PARAMS_REQ_SIZE);
writer->write_uint8 (writer, PTS_DH_NONCE_PARAMS_REQ_RESERVED);
writer->write_uint8 (writer, this->min_nonce_len);
@@ -191,7 +184,6 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -204,8 +196,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create(u_int8_t min_nonce_len,
.get_min_nonce_len = _get_min_nonce_len,
.get_dh_groups = _get_dh_groups,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_DH_NONCE_PARAMS_REQ,
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_REQ },
.min_nonce_len = min_nonce_len,
.dh_groups = dh_groups,
.ref = 1,
@@ -224,7 +215,6 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -237,8 +227,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_req_create_from_data(chunk_t value)
.get_min_nonce_len = _get_min_nonce_len,
.get_dh_groups = _get_dh_groups,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_DH_NONCE_PARAMS_REQ,
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_REQ },
.value = chunk_clone(value),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c
index 09bfa3aac..66ac185b3 100644
--- a/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c
+++ b/src/libpts/tcg/tcg_pts_attr_dh_nonce_params_resp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -55,14 +55,9 @@ struct private_tcg_pts_attr_dh_nonce_params_resp_t {
tcg_pts_attr_dh_nonce_params_resp_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -100,13 +95,7 @@ struct private_tcg_pts_attr_dh_nonce_params_resp_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_dh_nonce_params_resp_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_dh_nonce_params_resp_t *this)
{
return this->type;
@@ -135,6 +124,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_DH_NONCE_PARAMS_RESP_SIZE);
writer->write_uint24(writer, PTS_DH_NONCE_PARAMS_RESP_RESERVED);
writer->write_uint8 (writer, this->responder_nonce.len);
@@ -233,7 +226,6 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -248,8 +240,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create(pts_dh_group_t dh_group,
.get_responder_nonce = _get_responder_nonce,
.get_responder_value = _get_responder_value,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_DH_NONCE_PARAMS_RESP,
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_RESP },
.dh_group = dh_group,
.hash_algo_set = hash_algo_set,
.responder_nonce = chunk_clone(responder_nonce),
@@ -270,7 +261,6 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -285,8 +275,7 @@ pa_tnc_attr_t *tcg_pts_attr_dh_nonce_params_resp_create_from_data(chunk_t value)
.get_responder_nonce = _get_responder_nonce,
.get_responder_value = _get_responder_value,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_DH_NONCE_PARAMS_RESP,
+ .type = { PEN_TCG, TCG_PTS_DH_NONCE_PARAMS_RESP },
.value = chunk_clone(value),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_file_meas.c b/src/libpts/tcg/tcg_pts_attr_file_meas.c
index 737da65c1..01c4361e1 100644
--- a/src/libpts/tcg/tcg_pts_attr_file_meas.c
+++ b/src/libpts/tcg/tcg_pts_attr_file_meas.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -64,14 +64,9 @@ struct private_tcg_pts_attr_file_meas_t {
tcg_pts_attr_file_meas_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -94,13 +89,7 @@ struct private_tcg_pts_attr_file_meas_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_file_meas_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_file_meas_t *this)
{
return this->type;
@@ -135,6 +124,10 @@ METHOD(pa_tnc_attr_t, build, void,
chunk_t measurement;
bool first = TRUE;
+ if (this->value.ptr)
+ {
+ return;
+ }
number_of_files = this->measurements->get_file_count(this->measurements);
request_id = this->measurements->get_request_id(this->measurements);
@@ -254,7 +247,6 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -266,8 +258,7 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create(pts_file_meas_t *measurements)
},
.get_measurements = _get_measurements,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_FILE_MEAS,
+ .type = { PEN_TCG, TCG_PTS_FILE_MEAS },
.measurements = measurements,
.ref = 1,
);
@@ -286,7 +277,6 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -298,8 +288,7 @@ pa_tnc_attr_t *tcg_pts_attr_file_meas_create_from_data(chunk_t data)
},
.get_measurements = _get_measurements,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_FILE_MEAS,
+ .type = { PEN_TCG, TCG_PTS_FILE_MEAS },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c
index 054285c4e..5eac5ecae 100644
--- a/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c
+++ b/src/libpts/tcg/tcg_pts_attr_gen_attest_evid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -50,14 +50,9 @@ struct private_tcg_pts_attr_gen_attest_evid_t {
tcg_pts_attr_gen_attest_evid_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -75,13 +70,7 @@ struct private_tcg_pts_attr_gen_attest_evid_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_gen_attest_evid_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_gen_attest_evid_t *this)
{
return this->type;
@@ -110,6 +99,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_GEN_ATTEST_EVID_SIZE);
writer->write_uint32 (writer, PTS_GEN_ATTEST_EVID_RESERVED);
@@ -163,7 +156,6 @@ pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create()
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -174,8 +166,7 @@ pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create()
.destroy = _destroy,
},
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_GEN_ATTEST_EVID,
+ .type = { PEN_TCG, TCG_PTS_GEN_ATTEST_EVID },
.ref = 1,
);
@@ -193,7 +184,6 @@ pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -204,8 +194,7 @@ pa_tnc_attr_t *tcg_pts_attr_gen_attest_evid_create_from_data(chunk_t data)
.destroy = _destroy,
},
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_GEN_ATTEST_EVID,
+ .type = { PEN_TCG, TCG_PTS_GEN_ATTEST_EVID },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_get_aik.c b/src/libpts/tcg/tcg_pts_attr_get_aik.c
index 1875375a4..4b5eae7a7 100644
--- a/src/libpts/tcg/tcg_pts_attr_get_aik.c
+++ b/src/libpts/tcg/tcg_pts_attr_get_aik.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -47,14 +47,9 @@ struct private_tcg_pts_attr_get_aik_t {
tcg_pts_attr_get_aik_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -72,13 +67,7 @@ struct private_tcg_pts_attr_get_aik_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_get_aik_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_get_aik_t *this)
{
return this->type;
@@ -107,6 +96,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_GET_AIK_SIZE);
writer->write_uint32 (writer, PTS_GET_AIK_RESERVED);
@@ -160,7 +153,6 @@ pa_tnc_attr_t *tcg_pts_attr_get_aik_create()
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -171,8 +163,7 @@ pa_tnc_attr_t *tcg_pts_attr_get_aik_create()
.destroy = _destroy,
},
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_GET_AIK,
+ .type = { PEN_TCG, TCG_PTS_GET_AIK },
.ref = 1,
);
@@ -190,7 +181,6 @@ pa_tnc_attr_t *tcg_pts_attr_get_aik_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -201,8 +191,7 @@ pa_tnc_attr_t *tcg_pts_attr_get_aik_create_from_data(chunk_t data)
.destroy = _destroy,
},
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_GET_AIK,
+ .type = { PEN_TCG, TCG_PTS_GET_AIK },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c
index cb6834ca5..0cfc7efa9 100644
--- a/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c
+++ b/src/libpts/tcg/tcg_pts_attr_get_tpm_version_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -50,14 +50,9 @@ struct private_tcg_pts_attr_get_tpm_version_info_t {
tcg_pts_attr_get_tpm_version_info_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -75,13 +70,7 @@ struct private_tcg_pts_attr_get_tpm_version_info_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_get_tpm_version_info_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_get_tpm_version_info_t *this)
{
return this->type;
@@ -110,6 +99,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_GET_TPM_VER_INFO_SIZE);
writer->write_uint32 (writer, PTS_GET_TPM_VER_INFO_RESERVED);
@@ -163,7 +156,6 @@ pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create()
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -174,8 +166,7 @@ pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create()
.destroy = _destroy,
},
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_GET_TPM_VERSION_INFO,
+ .type = { PEN_TCG, TCG_PTS_GET_TPM_VERSION_INFO },
.ref = 1,
);
@@ -193,7 +184,6 @@ pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -204,8 +194,7 @@ pa_tnc_attr_t *tcg_pts_attr_get_tpm_version_info_create_from_data(chunk_t data)
.destroy = _destroy,
},
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_GET_TPM_VERSION_INFO,
+ .type = { PEN_TCG, TCG_PTS_GET_TPM_VERSION_INFO },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_meas_algo.c b/src/libpts/tcg/tcg_pts_attr_meas_algo.c
index ed520e3cd..bb95adc9e 100644
--- a/src/libpts/tcg/tcg_pts_attr_meas_algo.c
+++ b/src/libpts/tcg/tcg_pts_attr_meas_algo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -48,14 +48,9 @@ struct private_tcg_pts_attr_meas_algo_t {
tcg_pts_attr_meas_algo_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -78,13 +73,7 @@ struct private_tcg_pts_attr_meas_algo_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_meas_algo_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_meas_algo_t *this)
{
return this->type;
@@ -113,6 +102,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_MEAS_ALGO_SIZE);
writer->write_uint16(writer, PTS_MEAS_ALGO_RESERVED);
writer->write_uint16(writer, this->algorithms);
@@ -175,7 +168,6 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -187,8 +179,8 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create(pts_meas_algorithms_t algorithms,
},
.get_algorithms = _get_algorithms,
},
- .vendor_id = PEN_TCG,
- .type = selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO,
+ .type = { PEN_TCG,
+ selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO },
.algorithms = algorithms,
.ref = 1,
);
@@ -208,7 +200,6 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(chunk_t data,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -220,8 +211,8 @@ pa_tnc_attr_t *tcg_pts_attr_meas_algo_create_from_data(chunk_t data,
},
.get_algorithms = _get_algorithms,
},
- .vendor_id = PEN_TCG,
- .type = selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO,
+ .type = { PEN_TCG,
+ selection ? TCG_PTS_MEAS_ALGO_SELECTION : TCG_PTS_MEAS_ALGO },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_proto_caps.c b/src/libpts/tcg/tcg_pts_attr_proto_caps.c
index 055c750ff..83665ff69 100644
--- a/src/libpts/tcg/tcg_pts_attr_proto_caps.c
+++ b/src/libpts/tcg/tcg_pts_attr_proto_caps.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -48,14 +48,9 @@ struct private_tcg_pts_attr_proto_caps_t {
tcg_pts_attr_proto_caps_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -78,13 +73,7 @@ struct private_tcg_pts_attr_proto_caps_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_proto_caps_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_proto_caps_t *this)
{
return this->type;
@@ -113,6 +102,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_PROTO_CAPS_SIZE);
writer->write_uint16(writer, PTS_PROTO_CAPS_RESERVED);
writer->write_uint16(writer, this->flags);
@@ -176,7 +169,6 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -188,8 +180,8 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create(pts_proto_caps_flag_t flags,
},
.get_flags = _get_flags,
},
- .vendor_id = PEN_TCG,
- .type = request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS,
+ .type = { PEN_TCG,
+ request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS },
.flags = flags,
.ref = 1,
);
@@ -208,7 +200,6 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(chunk_t data,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -220,8 +211,8 @@ pa_tnc_attr_t *tcg_pts_attr_proto_caps_create_from_data(chunk_t data,
},
.get_flags = _get_flags,
},
- .vendor_id = PEN_TCG,
- .type = request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS,
+ .type = { PEN_TCG,
+ request ? TCG_PTS_REQ_PROTO_CAPS : TCG_PTS_PROTO_CAPS },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meas.c b/src/libpts/tcg/tcg_pts_attr_req_file_meas.c
index 17781f745..65bdff579 100644
--- a/src/libpts/tcg/tcg_pts_attr_req_file_meas.c
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meas.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -54,14 +54,9 @@ struct private_tcg_pts_attr_req_file_meas_t {
tcg_pts_attr_req_file_meas_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -99,13 +94,7 @@ struct private_tcg_pts_attr_req_file_meas_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_req_file_meas_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_req_file_meas_t *this)
{
return this->type;
@@ -136,6 +125,10 @@ METHOD(pa_tnc_attr_t, build, void,
chunk_t pathname;
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
if (this->directory_flag)
{
flags |= DIRECTORY_CONTENTS_FLAG;
@@ -240,7 +233,6 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -255,8 +247,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag,
.get_delimiter = _get_delimiter,
.get_pathname = _get_pathname,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_REQ_FILE_MEAS,
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_MEAS },
.directory_flag = directory_flag,
.request_id = request_id,
.delimiter = delimiter,
@@ -278,7 +269,6 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -293,8 +283,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data)
.get_delimiter = _get_delimiter,
.get_pathname = _get_pathname,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_REQ_FILE_MEAS,
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_MEAS },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meta.c b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
index bef6b5db6..eb5114172 100644
--- a/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -52,14 +52,9 @@ struct private_tcg_pts_attr_req_file_meta_t {
tcg_pts_attr_req_file_meta_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -92,13 +87,7 @@ struct private_tcg_pts_attr_req_file_meta_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_req_file_meta_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_req_file_meta_t *this)
{
return this->type;
@@ -129,6 +118,10 @@ METHOD(pa_tnc_attr_t, build, void,
chunk_t pathname;
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
if (this->directory_flag)
{
flags |= DIRECTORY_CONTENTS_FLAG;
@@ -226,7 +219,6 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -240,8 +232,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create(bool directory_flag,
.get_delimiter = _get_delimiter,
.get_pathname = _get_pathname,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_REQ_FILE_META,
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_META },
.directory_flag = directory_flag,
.delimiter = delimiter,
.pathname = strdup(pathname),
@@ -262,7 +253,6 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -276,8 +266,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_file_meta_create_from_data(chunk_t data)
.get_delimiter = _get_delimiter,
.get_pathname = _get_pathname,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_REQ_FILE_META,
+ .type = { PEN_TCG, TCG_PTS_REQ_FILE_META },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c
index bfd108b9f..a631e9891 100644
--- a/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c
+++ b/src/libpts/tcg/tcg_pts_attr_req_func_comp_evid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -73,14 +73,9 @@ struct private_tcg_pts_attr_req_func_comp_evid_t {
tcg_pts_attr_req_func_comp_evid_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -140,13 +135,7 @@ static void free_entry(entry_t *this)
}
}
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_req_func_comp_evid_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_req_func_comp_evid_t *this)
{
return this->type;
@@ -177,6 +166,10 @@ METHOD(pa_tnc_attr_t, build, void,
enumerator_t *enumerator;
entry_t *entry;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_REQ_FUNC_COMP_EVID_SIZE);
enumerator = this->list->create_enumerator(this->list);
@@ -320,7 +313,6 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -334,8 +326,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create(void)
.get_count = _get_count,
.create_enumerator = _create_enumerator,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_REQ_FUNC_COMP_EVID,
+ .type = { PEN_TCG, TCG_PTS_REQ_FUNC_COMP_EVID },
.list = linked_list_create(),
.ref = 1,
);
@@ -353,7 +344,6 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -367,8 +357,7 @@ pa_tnc_attr_t *tcg_pts_attr_req_func_comp_evid_create_from_data(chunk_t data)
.get_count = _get_count,
.create_enumerator = _create_enumerator,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_REQ_FUNC_COMP_EVID,
+ .type = { PEN_TCG, TCG_PTS_REQ_FUNC_COMP_EVID },
.list = linked_list_create(),
.value = chunk_clone(data),
.ref = 1,
diff --git a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c
index d2c197ac4..387f4a115 100644
--- a/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c
+++ b/src/libpts/tcg/tcg_pts_attr_simple_comp_evid.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -100,14 +100,9 @@ struct private_tcg_pts_attr_simple_comp_evid_t {
tcg_pts_attr_simple_comp_evid_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -130,13 +125,7 @@ struct private_tcg_pts_attr_simple_comp_evid_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_simple_comp_evid_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_simple_comp_evid_t *this)
{
return this->type;
@@ -185,16 +174,22 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
bool has_pcr_info;
- char utc_time_buf[25];
+ char utc_time_buf[25], *policy_uri;
u_int8_t flags;
+ u_int16_t len;
u_int32_t depth, extended_pcr;
pts_comp_func_name_t *name;
pts_meas_algorithms_t hash_algorithm;
pts_pcr_transform_t transform;
pts_comp_evid_validation_t validation;
time_t measurement_time;
- chunk_t measurement, utc_time, pcr_before, pcr_after, policy_uri;
+ chunk_t measurement, utc_time, pcr_before, pcr_after;
+ if (this->value.ptr)
+ {
+ return;
+ }
+
/* Extract parameters from comp_evidence_t object */
name = this->evidence->get_comp_func_name(this->evidence,
&depth);
@@ -234,8 +229,9 @@ METHOD(pa_tnc_attr_t, build, void,
if (validation == PTS_COMP_EVID_VALIDATION_FAILED ||
validation == PTS_COMP_EVID_VALIDATION_PASSED)
{
- writer->write_uint16(writer, policy_uri.len);
- writer->write_data (writer, policy_uri);
+ len = strlen(policy_uri);
+ writer->write_uint16(writer, len);
+ writer->write_data (writer, chunk_create(policy_uri, len));
}
if (has_pcr_info)
{
@@ -409,8 +405,13 @@ METHOD(pa_tnc_attr_t, process, status_t,
/* Add options */
if (has_validation)
{
- policy_uri = chunk_clone(policy_uri);
- this->evidence->set_validation(this->evidence, validation, policy_uri);
+ char buf[BUF_LEN];
+ size_t len;
+
+ len = min(policy_uri.len, BUF_LEN-1);
+ memcpy(buf, policy_uri.ptr, len);
+ buf[len] = '\0';
+ this->evidence->set_validation(this->evidence, validation, buf);
}
if (has_pcr_info)
{
@@ -460,7 +461,6 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -472,8 +472,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create(pts_comp_evidence_t *evid)
},
.get_comp_evidence = _get_comp_evidence,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_SIMPLE_COMP_EVID,
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_COMP_EVID },
.evidence = evid,
.ref = 1,
);
@@ -492,7 +491,6 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -504,8 +502,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_comp_evid_create_from_data(chunk_t data)
},
.get_comp_evidence = _get_comp_evidence,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_SIMPLE_COMP_EVID,
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_COMP_EVID },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c
index 27720d509..8d2d4f82d 100644
--- a/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c
+++ b/src/libpts/tcg/tcg_pts_attr_simple_evid_final.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -58,14 +58,9 @@ struct private_tcg_pts_attr_simple_evid_final_t {
tcg_pts_attr_simple_evid_final_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -113,13 +108,7 @@ struct private_tcg_pts_attr_simple_evid_final_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_simple_evid_final_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_simple_evid_final_t *this)
{
return this->type;
@@ -169,6 +158,10 @@ METHOD(pa_tnc_attr_t, build, void,
bio_writer_t *writer;
u_int8_t flags;
+ if (this->value.ptr)
+ {
+ return;
+ }
flags = this->flags & PTS_SIMPLE_EVID_FINAL_FLAG_MASK;
if (this->has_evid_sig)
@@ -333,7 +326,6 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags,
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -347,8 +339,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create(u_int8_t flags,
.get_evid_sig = _get_evid_sig,
.set_evid_sig = _set_evid_sig,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_SIMPLE_EVID_FINAL,
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL },
.flags = flags,
.comp_hash_algorithm = comp_hash_algorithm,
.pcr_comp = pcr_comp,
@@ -370,7 +361,6 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -384,8 +374,7 @@ pa_tnc_attr_t *tcg_pts_attr_simple_evid_final_create_from_data(chunk_t data)
.get_evid_sig = _get_evid_sig,
.set_evid_sig = _set_evid_sig,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_SIMPLE_EVID_FINAL,
+ .type = { PEN_TCG, TCG_PTS_SIMPLE_EVID_FINAL },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c
index 944a12cc9..8d1e78f18 100644
--- a/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c
+++ b/src/libpts/tcg/tcg_pts_attr_tpm_version_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -49,14 +49,9 @@ struct private_tcg_pts_attr_tpm_version_info_t {
tcg_pts_attr_tpm_version_info_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -79,13 +74,7 @@ struct private_tcg_pts_attr_tpm_version_info_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_tpm_version_info_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_tpm_version_info_t *this)
{
return this->type;
@@ -114,6 +103,10 @@ METHOD(pa_tnc_attr_t, build, void,
{
bio_writer_t *writer;
+ if (this->value.ptr)
+ {
+ return;
+ }
writer = bio_writer_create(PTS_TPM_VER_INFO_SIZE);
writer->write_data(writer, this->tpm_version_info);
@@ -181,7 +174,6 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -194,8 +186,7 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create(chunk_t tpm_version_info)
.get_tpm_version_info = _get_tpm_version_info,
.set_tpm_version_info = _set_tpm_version_info,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_TPM_VERSION_INFO,
+ .type = { PEN_TCG, TCG_PTS_TPM_VERSION_INFO },
.tpm_version_info = chunk_clone(tpm_version_info),
.ref = 1,
);
@@ -214,7 +205,6 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -227,8 +217,7 @@ pa_tnc_attr_t *tcg_pts_attr_tpm_version_info_create_from_data(chunk_t data)
.get_tpm_version_info = _get_tpm_version_info,
.set_tpm_version_info = _set_tpm_version_info,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_TPM_VERSION_INFO,
+ .type = { PEN_TCG, TCG_PTS_TPM_VERSION_INFO },
.value = chunk_clone(data),
.ref = 1,
);
diff --git a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
index a9f4a115d..4f93ee885 100644
--- a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
+++ b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Sansar Choinyambuu
+ * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -80,14 +80,9 @@ struct private_tcg_pts_attr_file_meta_t {
tcg_pts_attr_file_meta_t public;
/**
- * Attribute vendor ID
+ * Vendor-specific attribute type
*/
- pen_t vendor_id;
-
- /**
- * Attribute type
- */
- u_int32_t type;
+ pen_type_t type;
/**
* Attribute value
@@ -110,13 +105,7 @@ struct private_tcg_pts_attr_file_meta_t {
refcount_t ref;
};
-METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
- private_tcg_pts_attr_file_meta_t *this)
-{
- return this->vendor_id;
-}
-
-METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+METHOD(pa_tnc_attr_t, get_type, pen_type_t,
private_tcg_pts_attr_file_meta_t *this)
{
return this->type;
@@ -148,6 +137,10 @@ METHOD(pa_tnc_attr_t, build, void,
pts_file_metadata_t *entry;
u_int64_t number_of_files;
+ if (this->value.ptr)
+ {
+ return;
+ }
number_of_files = this->metadata->get_file_count(this->metadata);
writer = bio_writer_create(PTS_FILE_META_SIZE);
@@ -306,7 +299,6 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -318,8 +310,7 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata)
},
.get_metadata = _get_metadata,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_UNIX_FILE_META,
+ .type = { PEN_TCG, TCG_PTS_UNIX_FILE_META },
.metadata = metadata,
.ref = 1,
);
@@ -338,7 +329,6 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data)
INIT(this,
.public = {
.pa_tnc_attribute = {
- .get_vendor_id = _get_vendor_id,
.get_type = _get_type,
.get_value = _get_value,
.get_noskip_flag = _get_noskip_flag,
@@ -350,8 +340,7 @@ pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data)
},
.get_metadata = _get_metadata,
},
- .vendor_id = PEN_TCG,
- .type = TCG_PTS_UNIX_FILE_META,
+ .type = { PEN_TCG, TCG_PTS_UNIX_FILE_META },
.value = chunk_clone(data),
.ref = 1,
);