implemented support if functional sub-components
This commit is contained in:
@@ -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>
|
||||
@@ -378,7 +377,8 @@ 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");
|
||||
@@ -388,7 +388,8 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
||||
/* 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;
|
||||
@@ -396,7 +397,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;
|
||||
|
||||
@@ -15,10 +15,13 @@
|
||||
|
||||
#include "imc_attestation_state.h"
|
||||
|
||||
#include <libpts.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.
|
||||
@@ -61,7 +64,12 @@ struct private_imc_attestation_state_t {
|
||||
pts_t *pts;
|
||||
|
||||
/**
|
||||
* PA-TNC attribute cache list
|
||||
* List of Functional Components
|
||||
*/
|
||||
linked_list_t *components;
|
||||
|
||||
/**
|
||||
* Functional Component Evidence cache list
|
||||
*/
|
||||
linked_list_t *list;
|
||||
|
||||
@@ -110,12 +118,14 @@ METHOD(imc_state_t, change_state, void,
|
||||
this->state = new_state;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -125,6 +135,38 @@ 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 *evid)
|
||||
{
|
||||
@@ -158,12 +200,14 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
|
||||
.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,
|
||||
.pts = pts_create(TRUE),
|
||||
.components = linked_list_create(),
|
||||
.list = linked_list_create(),
|
||||
);
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -46,6 +47,16 @@ struct imc_attestation_state_t {
|
||||
*/
|
||||
pts_t* (*get_pts)(imc_attestation_state_t *this);
|
||||
|
||||
/**
|
||||
* Create and add an entry to the list of Functional Components
|
||||
*
|
||||
* @param name Component Functional Name
|
||||
* @param depth Sub-component Depth
|
||||
* @return created functional component instance or NULL
|
||||
*/
|
||||
pts_component_t* (*create_component)(imc_attestation_state_t *this,
|
||||
pts_comp_func_name_t *name, u_int32_t depth);
|
||||
|
||||
/**
|
||||
* Add an entry to the Component Evidence cache list
|
||||
*
|
||||
|
||||
@@ -1599,17 +1599,17 @@ 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 */
|
||||
|
||||
INSERT INTO key_component (
|
||||
key, component, depth, seq_no
|
||||
) VALUES (
|
||||
2, 2, 0, 1
|
||||
);
|
||||
|
||||
INSERT INTO key_component (
|
||||
key, component, depth, seq_no
|
||||
) VALUES (
|
||||
@@ -1622,3 +1622,9 @@ INSERT INTO key_component (
|
||||
1, 2, 0, 2
|
||||
);
|
||||
|
||||
INSERT INTO key_component (
|
||||
key, component, depth, seq_no
|
||||
) VALUES (
|
||||
1, 4, 0, 3
|
||||
);
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -252,15 +251,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();
|
||||
|
||||
@@ -294,7 +294,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
||||
DBG1(DBG_IMV, " no entry found for component evidence request");
|
||||
break;
|
||||
}
|
||||
if (comp->verify(comp, pts, evidence) != SUCCESS)
|
||||
if (comp->verify(comp, name->get_qualifier(name), pts,
|
||||
evidence) != SUCCESS)
|
||||
{
|
||||
attestation_state->set_measurement_error(attestation_state);
|
||||
name->log(name, " measurement mismatch for ");
|
||||
|
||||
@@ -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.
|
||||
@@ -108,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;
|
||||
|
||||
/**
|
||||
@@ -237,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);
|
||||
}
|
||||
@@ -307,24 +326,69 @@ 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)
|
||||
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)
|
||||
{
|
||||
this->components->insert_last(this->components, entry);
|
||||
enumerator_t *enumerator;
|
||||
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->comp->get_comp_func_name(entry->comp)))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
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, get_component, pts_component_t*,
|
||||
private_imv_attestation_state_t *this, pts_comp_func_name_t *name)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
pts_component_t *entry, *found = NULL;
|
||||
func_comp_t *entry;
|
||||
pts_component_t *found = NULL;
|
||||
|
||||
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)) &&
|
||||
name->get_qualifier(name) == entry->qualifier)
|
||||
{
|
||||
found = entry;
|
||||
found = entry->comp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -347,16 +411,16 @@ METHOD(imv_attestation_state_t, set_measurement_error, void,
|
||||
METHOD(imv_attestation_state_t, finalize_components, void,
|
||||
private_imv_attestation_state_t *this)
|
||||
{
|
||||
pts_component_t *entry;
|
||||
func_comp_t *entry;
|
||||
|
||||
while (this->components->remove_last(this->components,
|
||||
(void**)&entry) == SUCCESS)
|
||||
{
|
||||
if (!entry->finalize(entry))
|
||||
if (!entry->comp->finalize(entry->comp, entry->qualifier))
|
||||
{
|
||||
_set_measurement_error(this);
|
||||
}
|
||||
entry->destroy(entry);
|
||||
free_func_comp(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +459,7 @@ 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,
|
||||
.create_component = _create_component,
|
||||
.get_component = _get_component,
|
||||
.finalize_components = _finalize_components,
|
||||
.components_finalized = _components_finalized,
|
||||
|
||||
@@ -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,11 +106,17 @@ 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);
|
||||
|
||||
/**
|
||||
* Get a Functional Component with a given name
|
||||
|
||||
@@ -80,20 +80,30 @@ struct pts_ita_comp_ima_t {
|
||||
*/
|
||||
pts_database_t *pts_db;
|
||||
|
||||
/**
|
||||
* Primary key for Component Functional Name database entry
|
||||
*/
|
||||
int cid;
|
||||
|
||||
/**
|
||||
* Primary key for AIK database entry
|
||||
*/
|
||||
int kid;
|
||||
|
||||
/**
|
||||
* Component is registering measurements
|
||||
* Primary key for IMA BIOS Component Functional Name database entry
|
||||
*/
|
||||
bool is_registering;
|
||||
int bios_cid;
|
||||
|
||||
/**
|
||||
* Primary key for IMA Runtime Component Functional Name database entry
|
||||
*/
|
||||
int ima_cid;
|
||||
|
||||
/**
|
||||
* Component is registering IMA BIOS measurements
|
||||
*/
|
||||
bool is_bios_registering;
|
||||
|
||||
/**
|
||||
* Component is registering IMA boot aggregate measurement
|
||||
*/
|
||||
bool is_ima_registering;
|
||||
|
||||
/**
|
||||
* Measurement sequence number
|
||||
@@ -155,6 +165,11 @@ struct pts_ita_comp_ima_t {
|
||||
*/
|
||||
int count_failed;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
*/
|
||||
refcount_t ref;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -369,12 +384,14 @@ static bool load_runtime_measurements(char *file, linked_list_t *list,
|
||||
/**
|
||||
* Extend measurement into PCR an create evidence
|
||||
*/
|
||||
static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs,
|
||||
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;
|
||||
|
||||
@@ -392,9 +409,10 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs
|
||||
free(pcr_before.ptr);
|
||||
return NULL;
|
||||
}
|
||||
evidence = pts_comp_evidence_create(this->name->clone(this->name),
|
||||
this->depth, pcr, hash_algo, pcr_transform,
|
||||
this->measurement_time, measurement);
|
||||
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));
|
||||
@@ -406,20 +424,21 @@ static pts_comp_evidence_t* extend_pcr(pts_ita_comp_ima_t* this, pts_pcr_t *pcrs
|
||||
/**
|
||||
* Compute and check boot aggregate value by hashing PCR0 to PCR7
|
||||
*/
|
||||
static void check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
|
||||
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 pcr_ok = TRUE;
|
||||
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++)
|
||||
{
|
||||
@@ -440,12 +459,15 @@ static void check_boot_aggregate(pts_pcr_t *pcrs, chunk_t measurement)
|
||||
|
||||
if (pcr_ok)
|
||||
{
|
||||
success = chunk_equals(boot_aggregate, measurement);
|
||||
DBG1(DBG_PTS, "boot aggregate value is %scorrect",
|
||||
chunk_equals(boot_aggregate, measurement) ? "":"in");
|
||||
success ? "":"in");
|
||||
return success;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_PTS, "failed to compute boot aggregate value");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,7 +490,8 @@ 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)
|
||||
{
|
||||
bios_entry_t *bios_entry;
|
||||
ima_entry_t *ima_entry;
|
||||
@@ -478,84 +501,107 @@ METHOD(pts_component_t, measure, status_t,
|
||||
|
||||
pcrs = pts->get_pcrs(pts);
|
||||
|
||||
switch (this->state)
|
||||
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
|
||||
{
|
||||
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;
|
||||
}
|
||||
evid = extend_pcr(this, pcrs, bios_entry->pcr,
|
||||
bios_entry->measurement);
|
||||
free(bios_entry);
|
||||
switch (this->state)
|
||||
{
|
||||
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);
|
||||
|
||||
/* break if still some BIOS measurements are left */
|
||||
if (this->bios_list->get_count(this->bios_list))
|
||||
{
|
||||
this->state = this->bios_list->get_count(this->bios_list) ?
|
||||
IMA_STATE_BIOS : IMA_STATE_INIT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if IMA runtime measurements are enabled */
|
||||
if (!load_runtime_measurements(IMA_RUNTIME_MEASUREMENTS,
|
||||
this->ima_list, &this->measurement_time))
|
||||
{
|
||||
default:
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
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_BOOT_AGGREGATE : IMA_STATE_END;
|
||||
break;
|
||||
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)
|
||||
{
|
||||
check_boot_aggregate(pcrs, ima_entry->measurement);
|
||||
}
|
||||
|
||||
evid = extend_pcr(this, 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) ?
|
||||
this->state = this->ima_list->get_count(this->ima_list) ?
|
||||
IMA_STATE_RUNTIME : IMA_STATE_END;
|
||||
break;
|
||||
case IMA_STATE_END:
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_PTS, "unsupported functional component name qualifier");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
*evidence = evid;
|
||||
return evid ? ((this->state == IMA_STATE_END) ? SUCCESS : NEED_MORE) :
|
||||
FAILED;
|
||||
if (!evid)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -565,56 +611,65 @@ METHOD(pts_component_t, verify, status_t,
|
||||
status_t status;
|
||||
char *uri;
|
||||
|
||||
pcrs = pts->get_pcrs(pts);
|
||||
measurement = evidence->get_measurement(evidence, &extended_pcr,
|
||||
&algo, &transform, &measurement_time);
|
||||
|
||||
switch (this->state)
|
||||
/* some first time initializations */
|
||||
if (!this->keyid.ptr)
|
||||
{
|
||||
case IMA_STATE_INIT:
|
||||
if (!pts->get_aik_keyid(pts, &this->keyid))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
this->keyid = chunk_clone(this->keyid);
|
||||
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)
|
||||
{
|
||||
DBG1(DBG_PTS, "pts database not available");
|
||||
return FAILED;
|
||||
}
|
||||
status = this->pts_db->get_comp_measurement_count(this->pts_db,
|
||||
this->name, this->keyid, algo,
|
||||
&this->cid, &this->kid, &this->bios_count);
|
||||
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);
|
||||
pcrs = pts->get_pcrs(pts);
|
||||
measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
|
||||
&measurement_time);
|
||||
|
||||
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_registering = TRUE;
|
||||
}
|
||||
this->state = IMA_STATE_BIOS;
|
||||
/* fall through to next state */
|
||||
case IMA_STATE_BIOS:
|
||||
if (extended_pcr != IMA_PCR)
|
||||
{
|
||||
if (this->is_registering)
|
||||
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
|
||||
{
|
||||
switch (this->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->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->cid, this->kid,
|
||||
++this->seq_no, extended_pcr, algo);
|
||||
measurement, this->bios_cid, this->kid,
|
||||
++this->seq_no, pcr, algo);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
return status;
|
||||
@@ -624,75 +679,129 @@ METHOD(pts_component_t, verify, status_t,
|
||||
else
|
||||
{
|
||||
status = this->pts_db->check_comp_measurement(this->pts_db,
|
||||
measurement, this->cid, this->kid,
|
||||
++this->seq_no, extended_pcr, algo);
|
||||
measurement, this->bios_cid, this->kid,
|
||||
++this->seq_no, pcr, algo);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
this->state = IMA_STATE_BOOT_AGGREGATE;
|
||||
/* fall through to next state */
|
||||
case IMA_STATE_BOOT_AGGREGATE:
|
||||
check_boot_aggregate(pcrs, measurement);
|
||||
this->state = IMA_STATE_RUNTIME;
|
||||
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++;
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_OS))
|
||||
{
|
||||
int ima_count;
|
||||
|
||||
break;
|
||||
case IMA_STATE_END:
|
||||
break;
|
||||
switch (this->state)
|
||||
{
|
||||
case IMA_STATE_BIOS:
|
||||
if (!check_boot_aggregate(pcrs, measurement))
|
||||
{
|
||||
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);
|
||||
}
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
this->state = IMA_STATE_RUNTIME;
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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 (!chunk_equals(pcr_before, pcrs->get(pcrs, extended_pcr)))
|
||||
if (!chunk_equals(pcr_before, pcrs->get(pcrs, pcr)))
|
||||
{
|
||||
DBG1(DBG_PTS, "PCR %2u: pcr_before is not equal to register value",
|
||||
extended_pcr);
|
||||
pcr);
|
||||
}
|
||||
if (pcrs->set(pcrs, extended_pcr, pcr_after))
|
||||
if (pcrs->set(pcrs, pcr, pcr_after))
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pcr_after = pcrs->extend(pcrs, extended_pcr, measurement);
|
||||
pcr_after = pcrs->extend(pcrs, pcr, measurement);
|
||||
if (pcr_after.ptr)
|
||||
{
|
||||
return SUCCESS;
|
||||
@@ -702,44 +811,74 @@ METHOD(pts_component_t, verify, status_t,
|
||||
}
|
||||
|
||||
METHOD(pts_component_t, finalize, bool,
|
||||
pts_ita_comp_ima_t *this)
|
||||
pts_ita_comp_ima_t *this, u_int8_t qualifier)
|
||||
{
|
||||
u_int32_t vid, name;
|
||||
enum_name_t *names;
|
||||
bool success = TRUE;
|
||||
|
||||
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 (this->is_registering)
|
||||
if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_TRUSTED))
|
||||
{
|
||||
/* close registration */
|
||||
this->is_registering = 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);
|
||||
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 (this->seq_no < this->bios_count)
|
||||
else if (qualifier == (PTS_ITA_QUALIFIER_FLAG_KERNEL |
|
||||
PTS_ITA_QUALIFIER_TYPE_OS))
|
||||
{
|
||||
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);
|
||||
return FALSE;
|
||||
}
|
||||
/* finalize IMA file measurements */
|
||||
if (this->is_ima_registering)
|
||||
{
|
||||
/* close registration */
|
||||
this->is_ima_registering = FALSE;
|
||||
|
||||
/* finalize IMA file measurements */
|
||||
if (this->count)
|
||||
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, "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);
|
||||
|
||||
return !this->count_differ && !this->count_failed;
|
||||
DBG1(DBG_PTS, "unsupported functional component name qualifier");
|
||||
success = FALSE;
|
||||
}
|
||||
this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
|
||||
|
||||
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,
|
||||
@@ -749,27 +888,40 @@ 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_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->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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@@ -782,16 +934,18 @@ pts_component_t *pts_ita_comp_ima_create(u_int8_t qualifier, u_int32_t depth,
|
||||
.measure = _measure,
|
||||
.verify = _verify,
|
||||
.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,
|
||||
.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,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
|
||||
@@ -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_ @}*/
|
||||
|
||||
@@ -85,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*,
|
||||
@@ -106,7 +111,8 @@ 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;
|
||||
@@ -182,7 +188,8 @@ METHOD(pts_component_t, measure, status_t,
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -275,7 +282,7 @@ METHOD(pts_component_t, verify, status_t,
|
||||
}
|
||||
|
||||
METHOD(pts_component_t, finalize, bool,
|
||||
pts_ita_comp_tboot_t *this)
|
||||
pts_ita_comp_tboot_t *this, u_int8_t qualifier)
|
||||
{
|
||||
u_int32_t vid, name;
|
||||
enum_name_t *names;
|
||||
@@ -303,6 +310,13 @@ METHOD(pts_component_t, finalize, bool,
|
||||
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)
|
||||
{
|
||||
@@ -310,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;
|
||||
@@ -341,12 +358,15 @@ pts_component_t *pts_ita_comp_tboot_create(u_int8_t qualifier, u_int32_t depth,
|
||||
.measure = _measure,
|
||||
.verify = _verify,
|
||||
.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;
|
||||
|
||||
@@ -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_ @}*/
|
||||
|
||||
@@ -49,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*,
|
||||
@@ -70,7 +76,8 @@ 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;
|
||||
@@ -110,7 +117,8 @@ 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;
|
||||
@@ -147,22 +155,32 @@ METHOD(pts_component_t, verify, status_t,
|
||||
}
|
||||
|
||||
METHOD(pts_component_t, finalize, bool,
|
||||
pts_ita_comp_tgrub_t *this)
|
||||
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;
|
||||
@@ -175,12 +193,15 @@ pts_component_t *pts_ita_comp_tgrub_create(u_int8_t qualifier, u_int32_t depth,
|
||||
.measure = _measure,
|
||||
.verify = _verify,
|
||||
.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;
|
||||
|
||||
@@ -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_ @}*/
|
||||
|
||||
@@ -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_,
|
||||
|
||||
@@ -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,6 +54,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
|
||||
*
|
||||
|
||||
@@ -60,31 +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);
|
||||
bool (*finalize)(pts_component_t *this, u_int8_t qualifier);
|
||||
|
||||
/**
|
||||
* Get a new reference to the PTS Functional Component
|
||||
*
|
||||
* @return this, with an increased refcount
|
||||
*/
|
||||
pts_component_t* (*get_ref)(pts_component_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a pts_component_t object.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user