aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2012-07-05 13:34:34 +0200
committerAndreas Steffen <andreas.steffen@strongswan.org>2012-07-11 17:09:04 +0200
commitddafcda4d80d2e6e76e4c660cd637a6ca503ac92 (patch)
treed2c6a377c57ea3db6addb720e65ae3be32f13ce3 /src
parentb188f23199293951138f05f0604a123c3437b6f1 (diff)
downloadstrongswan-ddafcda4d80d2e6e76e4c660cd637a6ca503ac92.tar.bz2
strongswan-ddafcda4d80d2e6e76e4c660cd637a6ca503ac92.tar.xz
refactored PTS functional component measurements
Diffstat (limited to 'src')
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation.c6
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_process.c28
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.c46
-rw-r--r--src/libpts/plugins/imv_attestation/imv_attestation_state.h16
-rw-r--r--src/libpts/pts/components/ita/ita_comp_ima.c406
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tboot.c59
-rw-r--r--src/libpts/pts/components/ita/ita_comp_tgrub.c4
-rw-r--r--src/libpts/pts/components/pts_component.h5
-rw-r--r--src/libpts/pts/pts_database.c2
9 files changed, 385 insertions, 187 deletions
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation.c b/src/libpts/plugins/imv_attestation/imv_attestation.c
index 51069b02d..6aaf6a643 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation.c
@@ -372,12 +372,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,
diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
index 21277a18c..96f663245 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_process.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c
@@ -276,34 +276,21 @@ 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, 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 +340,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..7041bc514 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_state.c
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.c
@@ -296,7 +296,7 @@ METHOD(imv_attestation_state_t, add_component, void,
this->components->insert_last(this->components, entry);
}
-METHOD(imv_attestation_state_t, check_off_component, pts_component_t*,
+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;
@@ -308,7 +308,6 @@ METHOD(imv_attestation_state_t, check_off_component, pts_component_t*,
if (name->equals(name, entry->get_comp_func_name(entry)))
{
found = entry;
- this->components->remove_at(this->components, enumerator);
break;
}
}
@@ -316,40 +315,32 @@ METHOD(imv_attestation_state_t, check_off_component, pts_component_t*,
return found;
}
-METHOD(imv_attestation_state_t, check_off_registrations, void,
+METHOD(imv_attestation_state_t, get_measurement_error, bool,
private_imv_attestation_state_t *this)
{
- enumerator_t *enumerator;
- pts_component_t *entry;
-
- enumerator = this->components->create_enumerator(this->components);
- while (enumerator->enumerate(enumerator, &entry))
- {
- if (entry->check_off_registrations(entry))
- {
- this->components->remove_at(this->components, enumerator);
- entry->destroy(entry);
- }
- }
- enumerator->destroy(enumerator);
+ return this->measurement_error;
}
-METHOD(imv_attestation_state_t, get_component_count, int,
+METHOD(imv_attestation_state_t, set_measurement_error, void,
private_imv_attestation_state_t *this)
{
- return this->components->get_count(this->components);
+ this->measurement_error = TRUE;
}
-METHOD(imv_attestation_state_t, get_measurement_error, bool,
+METHOD(imv_attestation_state_t, finalize_components, void,
private_imv_attestation_state_t *this)
{
- return this->measurement_error;
-}
+ pts_component_t *entry;
-METHOD(imv_attestation_state_t, set_measurement_error, void,
- private_imv_attestation_state_t *this)
-{
- this->measurement_error = TRUE;
+ while (this->components->remove_last(this->components,
+ (void**)&entry) == SUCCESS)
+ {
+ if (!entry->finalize(entry))
+ {
+ _set_measurement_error(this);
+ }
+ entry->destroy(entry);
+ }
}
/**
@@ -380,9 +371,8 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
.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,
+ .get_component = _get_component,
+ .finalize_components = _finalize_components,
.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..3e08f46a3 100644
--- a/src/libpts/plugins/imv_attestation/imv_attestation_state.h
+++ b/src/libpts/plugins/imv_attestation/imv_attestation_state.h
@@ -112,25 +112,19 @@ struct imv_attestation_state_t {
void (*add_component)(imv_attestation_state_t *this, pts_component_t *entry);
/**
- * 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 (*check_off_registrations)(imv_attestation_state_t *this);
+ void (*finalize_components)(imv_attestation_state_t *this);
/**
* Indicates if a file measurement error occurred
diff --git a/src/libpts/pts/components/ita/ita_comp_ima.c b/src/libpts/pts/components/ita/ita_comp_ima.c
index a7da76651..e9c6b9dd0 100644
--- a/src/libpts/pts/components/ita/ita_comp_ima.c
+++ b/src/libpts/pts/components/ita/ita_comp_ima.c
@@ -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 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_PCR_MAX 16
+#define IMA_TYPE_LEN 3
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_BIOS_AGGREGATE,
+ IMA_STATE_RUNTIME,
+ IMA_STATE_END
+};
/**
* Private data of a pts_ita_comp_ima_t object.
@@ -82,37 +96,51 @@ struct pts_ita_comp_ima_t {
bool is_registering;
/**
- * IMA BIOS measurement time
+ * Measurement sequence number
*/
- time_t bios_measurement_time;
+ int seq_no;
/**
- * IMA BIOS measurements
+ * Expected IMA BIOS measurement count
*/
- linked_list_t *list;
+ int count;
/**
- * Expected measurement count
+ * IMA BIOS measurements
*/
- int count;
+ linked_list_t *bios_list;
/**
- * Measurement sequence number
+ * IMA runtime file measurements
*/
- int seq_no;
+ linked_list_t *ima_list;
/**
* Shadow PCR registers
*/
chunk_t pcrs[IMA_PCR_MAX];
-};
-typedef struct entry_t entry_t;
+ /**
+ * IMA measurement time
+ */
+ time_t measurement_time;
+
+ /**
+ * IMA state machine
+ */
+ ima_state_t state;
+
+ /**
+ * Hasher used to extend emulated PCRs
+ */
+ hasher_t *hasher;
+
+};
/**
- * Linux IMA measurement entry
+ * Linux IMA BIOS measurement entry
*/
-struct entry_t {
+struct bios_entry_t {
/**
* PCR register
@@ -126,21 +154,54 @@ struct entry_t {
};
/**
- * Free an entry_t object
+ * Linux IMA runtime file measurement entry
+ */
+struct ima_entry_t {
+
+ /**
+ * SHA1 measurement hash
+ */
+ chunk_t measurement;
+
+ /**
+ * SHA1 file measurement thash
+ */
+ chunk_t file_measurement;
+
+ /**
+ * absolute path of executable files or basename of dynamic libraries
+ */
+ chunk_t filename;
+};
+
+/**
+ * Free a bios_entry_t object
*/
-static void free_entry(entry_t *this)
+static void free_bios_entry(bios_entry_t *this)
{
free(this->measurement.ptr);
free(this);
}
/**
+ * Free an ima_entry_t object
+ */
+static void free_ima_entry(ima_entry_t *this)
+{
+ free(this->measurement.ptr);
+ free(this->file_measurement.ptr);
+ free(this->filename.ptr);
+ free(this);
+}
+
+/**
* Load a PCR measurement file and determine the creation date
*/
-static bool load_measurements(char *file, linked_list_t *list, time_t *created)
+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 +209,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 +228,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 +260,123 @@ 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->file_measurement = chunk_alloc(HASH_SIZE_SHA1);
+ entry->filename = chunk_empty;
+
+ 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 (read(fd, entry->file_measurement.ptr, HASH_SIZE_SHA1) != HASH_SIZE_SHA1)
+ {
+ break;
+ }
+ if (read(fd, &len, 4) != 4)
+ {
+ break;
+ }
+ entry->filename = chunk_alloc(len);
+ if (read(fd, entry->filename.ptr, len) != len)
+ {
+ break;
+ }
+ 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
+ */
+pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, u_int32_t pcr,
+ size_t pcr_len, chunk_t measurement)
+{
+ pts_pcr_transform_t pcr_transform;
+ pts_meas_algorithms_t hash_algo;
+ pts_comp_evidence_t *evidence;
+ chunk_t pcr_before, pcr_after;
+
+ hash_algo = PTS_MEAS_ALGO_SHA1;
+ pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+ pcr_before = chunk_clone(this->pcrs[pcr]);
+ this->hasher->get_hash(this->hasher, pcr_before, NULL);
+ this->hasher->get_hash(this->hasher, measurement, this->pcrs[pcr].ptr);
+ pcr_after = chunk_clone(this->pcrs[pcr]);
+
+ evidence = pts_comp_evidence_create(this->name->clone(this->name),
+ this->depth, pcr, hash_algo, pcr_transform,
+ this->measurement_time, measurement);
+ evidence->set_pcr_info(evidence, pcr_before, pcr_after);
+
+ return evidence;
+}
+
METHOD(pts_component_t, get_comp_func_name, pts_comp_func_name_t*,
pts_ita_comp_ima_t *this)
{
@@ -226,50 +398,78 @@ 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_comp_evidence_t *evid;
- chunk_t pcr_before, pcr_after;
- pts_pcr_transform_t pcr_transform;
- pts_meas_algorithms_t hash_algo;
- size_t pcr_len;
- entry_t *entry;
- hasher_t *hasher;
-
- hash_algo = PTS_MEAS_ALGO_SHA1;
- pcr_len = pts->get_pcr_len(pts);
- pcr_transform = pts_meas_algo_to_pcr_transform(hash_algo, pcr_len);
+ bios_entry_t *bios_entry;
+ ima_entry_t *ima_entry;
+ status_t status;
- if (this->list->get_count(this->list) == 0)
+ switch (this->state)
{
- if (!load_measurements(IMA_BIOS_MEASUREMENT_PATH, this->list,
- &this->bios_measurement_time))
- {
- return FAILED;
- }
- }
+ case IMA_STATE_INIT:
+ if (!load_bios_measurements(IMA_BIOS_MEASUREMENTS, this->bios_list,
+ &this->measurement_time))
+ {
+ return FAILED;
+ }
+ 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;
+ }
+ *evidence = extend_pcr(this, bios_entry->pcr, pts->get_pcr_len(pts),
+ bios_entry->measurement);
+ free(bios_entry);
- if (this->list->remove_first(this->list, (void**)&entry) != SUCCESS)
- {
- DBG1(DBG_PTS, "could not retrieve measurement entry");
- return FAILED;
+ /* break if still some BIOS measurements are left */
+ if (this->bios_list->get_count(this->bios_list))
+ {
+ break;
+ }
+
+ /* check if IMA runtime measurements are enabled */
+ if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
+ this->ima_list, &this->measurement_time))
+ {
+ return FAILED;
+ }
+
+ this->state = this->ima_list->get_count(this->ima_list) ?
+ IMA_STATE_BIOS_AGGREGATE : IMA_STATE_END;
+ break;
+ case IMA_STATE_BIOS_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;
+ }
+ *evidence = extend_pcr(this, IMA_PCR, pts->get_pcr_len(pts),
+ ima_entry->measurement);
+
+ /* TODO optionally send file measurements */
+ chunk_free(&ima_entry->file_measurement);
+ chunk_free(&ima_entry->filename);
+ free(ima_entry);
+
+ if (this->state == IMA_STATE_BIOS_AGGREGATE)
+ {
+ /* TODO check BIOS aggregate value */
+ }
+ this->state = this->ima_list->get_count(this->ima_list) ?
+ IMA_STATE_RUNTIME : IMA_STATE_END;
+ break;
+ case IMA_STATE_END:
+ /* shouldn't happen */
+ return FAILED;
}
- pcr_before = chunk_clone(this->pcrs[entry->pcr]);
-
- hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- hasher->get_hash(hasher, pcr_before, NULL);
- hasher->get_hash(hasher, entry->measurement, this->pcrs[entry->pcr].ptr);
- hasher->destroy(hasher);
-
- pcr_after = chunk_clone(this->pcrs[entry->pcr]);
-
- evid = *evidence = pts_comp_evidence_create(this->name->clone(this->name),
- this->depth, entry->pcr, hash_algo, pcr_transform,
- this->bios_measurement_time, entry->measurement);
- evid->set_pcr_info(evid, pcr_before, pcr_after);
-
- free(entry);
-
- return (this->list->get_count(this->list)) ? NEED_MORE : SUCCESS;
+ return (this->state == IMA_STATE_END) ? SUCCESS : NEED_MORE;
}
METHOD(pts_component_t, verify, status_t,
@@ -282,6 +482,7 @@ METHOD(pts_component_t, verify, status_t,
pts_pcr_transform_t transform;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
+ status_t status;
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
@@ -299,11 +500,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);
@@ -322,23 +524,28 @@ METHOD(pts_component_t, verify, status_t,
}
}
- if (this->is_registering)
+ if (extended_pcr != IMA_PCR)
{
- if (this->pts_db->insert_comp_measurement(this->pts_db, measurement,
- this->cid, this->kid, ++this->seq_no,
- extended_pcr, algo) != SUCCESS)
+ if (this->is_registering)
{
- return FAILED;
+ 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 status;
+ }
+ this->count = this->seq_no + 1;
}
- 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)
+ else
{
- return FAILED;
+ 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 status;
+ }
}
}
@@ -351,28 +558,35 @@ METHOD(pts_component_t, verify, status_t,
}
}
- return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+ return SUCCESS;
}
-METHOD(pts_component_t, check_off_registrations, bool,
+METHOD(pts_component_t, finalize, bool,
pts_ita_comp_ima_t *this)
{
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;
}
@@ -397,8 +611,10 @@ METHOD(pts_component_t, destroy, void,
DBG1(DBG_PTS, "deleted %d registered %N '%N' functional component "
"evidence measurements", count, pen_names, vid, names, name);
}
- this->list->destroy_function(this->list, (void *)free_entry);
+ this->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);
+ this->hasher->destroy(this->hasher);
free(this->keyid.ptr);
free(this);
}
@@ -419,14 +635,16 @@ 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,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_IMA,
qualifier),
.depth = depth,
.pts_db = pts_db,
- .list = linked_list_create(),
+ .bios_list = linked_list_create(),
+ .ima_list = linked_list_create(),
+ .hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1),
);
for (i = 0; i < IMA_PCR_MAX; i++)
diff --git a/src/libpts/pts/components/ita/ita_comp_tboot.c b/src/libpts/pts/components/ita/ita_comp_tboot.c
index a85de8cd8..dd26fdb96 100644
--- a/src/libpts/pts/components/ita/ita_comp_tboot.c
+++ b/src/libpts/pts/components/ita/ita_comp_tboot.c
@@ -190,6 +190,7 @@ METHOD(pts_component_t, verify, status_t,
pts_pcr_transform_t transform;
time_t measurement_time;
chunk_t measurement, pcr_before, pcr_after;
+ status_t status;
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
@@ -207,11 +208,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,21 +234,23 @@ 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;
}
}
@@ -259,28 +263,35 @@ METHOD(pts_component_t, verify, status_t,
}
}
- return (this->seq_no < this->count) ? NEED_MORE : SUCCESS;
+ return SUCCESS;
}
-METHOD(pts_component_t, check_off_registrations, bool,
+METHOD(pts_component_t, finalize, bool,
pts_ita_comp_tboot_t *this)
{
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;
}
@@ -321,7 +332,7 @@ 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,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TBOOT,
diff --git a/src/libpts/pts/components/ita/ita_comp_tgrub.c b/src/libpts/pts/components/ita/ita_comp_tgrub.c
index 0dfd5fd41..00b9ef3c5 100644
--- a/src/libpts/pts/components/ita/ita_comp_tgrub.c
+++ b/src/libpts/pts/components/ita/ita_comp_tgrub.c
@@ -142,7 +142,7 @@ METHOD(pts_component_t, verify, status_t,
return SUCCESS;
}
-METHOD(pts_component_t, check_off_registrations, bool,
+METHOD(pts_component_t, finalize, bool,
pts_ita_comp_tgrub_t *this)
{
return FALSE;
@@ -170,7 +170,7 @@ 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,
.destroy = _destroy,
},
.name = pts_comp_func_name_create(PEN_ITA, PTS_ITA_COMP_FUNC_NAME_TGRUB,
diff --git a/src/libpts/pts/components/pts_component.h b/src/libpts/pts/components/pts_component.h
index 524ff332d..160fd0518 100644
--- a/src/libpts/pts/components/pts_component.h
+++ b/src/libpts/pts/components/pts_component.h
@@ -79,10 +79,11 @@ struct pts_component_t {
/**
* Tell the PTS Functional Component to finalize pending registrations
+ * and check for missing measurements
*
- * @return TRUE if there are pending registrations
+ * @return TRUE if finalization successful
*/
- bool (*check_off_registrations)(pts_component_t *this);
+ bool (*finalize)(pts_component_t *this);
/**
* Destroys a pts_component_t object.
diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c
index 282755c0a..bbada6183 100644
--- a/src/libpts/pts/pts_database.c
+++ b/src/libpts/pts/pts_database.c
@@ -169,7 +169,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;
}
}