Optimized PTS measurements

This commit is contained in:
Andreas Steffen 2014-04-06 07:18:28 +02:00
parent 40e8c67392
commit b138bbee4e
12 changed files with 132 additions and 294 deletions

View File

@ -1780,22 +1780,6 @@ METHOD(attest_db_t, add, bool,
{
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, 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 at "
"position %d\n", this->kid, this->cid,
success ? "" : "could not be ", this->seq_no);
return success;
}
/* add directory or file hash measurement for a given product */
if (this->did && this->pid)
{
@ -1869,19 +1853,6 @@ METHOD(attest_db_t, delete, bool,
return success;
}
/* delete key/component pair */
if (this->kid && this->cid)
{
success = this->db->execute(this->db, NULL,
"DELETE FROM key_component "
"WHERE key = ? AND component = ?",
DB_UINT, this->kid, DB_UINT, this->cid) > 0;
printf("key/component pair (%d/%d) %sdeleted from database\n",
this->kid, this->cid, success ? "" : "could not be ");
return success;
}
if (this->cid)
{
success = this->db->execute(this->db, NULL,

View File

@ -391,7 +391,6 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
imv_msg_t *out_msg;
imv_state_t *state;
imv_session_t *session;
imv_os_info_t *os_info;
imv_attestation_state_t *attestation_state;
imv_attestation_handshake_state_t handshake_state;
imv_workitem_t *workitem;
@ -400,6 +399,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
TNC_IMVID imv_id;
TNC_Result result = TNC_RESULT_SUCCESS;
pts_t *pts;
int pid;
uint32_t actions;
enumerator_t *enumerator;
@ -500,8 +500,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
return TNC_RESULT_SUCCESS;
}
os_info = session->get_os_info(session);
pts->set_platform_info(pts, os_info->get_info(os_info));
session->get_session_id(session, &pid, NULL);
pts->set_platform_id(pts, pid);
/* create an empty out message - we might need it */
out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,

View File

@ -89,7 +89,6 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
tcg_pts_attr_req_func_comp_evid_t *attr_cast;
enumerator_t *enumerator;
pts_comp_func_name_t *name;
chunk_t keyid;
uint8_t flags;
uint32_t depth;
bool first_component = TRUE;
@ -97,7 +96,7 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
attestation_state->set_handshake_state(attestation_state,
IMV_ATTESTATION_STATE_END);
if (!pts->get_aik_keyid(pts, &keyid))
if (!pts->get_aik_id(pts))
{
attestation_state->set_measurement_error(attestation_state,
IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);

View File

@ -160,6 +160,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
certificate_t *aik, *issuer;
public_key_t *public;
chunk_t keyid, keyid_hex, device_id;
int aik_id;
enumerator_t *e;
bool trusted = FALSE, trusted_chain = FALSE;
@ -214,7 +215,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
break;
}
}
pts->set_aik(pts, aik);
session->get_session_id(session, NULL, &aik_id);
pts->set_aik(pts, aik, aik_id);
break;
}
case TCG_PTS_FILE_MEAS:
@ -228,13 +230,12 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
pts_file_meas_t *measurements;
imv_workitem_t *workitem, *found = NULL;
imv_workitem_type_t type;
char result_str[BUF_LEN], *platform_info;
char result_str[BUF_LEN];
bool is_dir, correct;
enumerator_t *enumerator;
eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
algo = pts->get_meas_algorithm(pts);
platform_info = pts->get_platform_info(pts);
attr_cast = (tcg_pts_attr_file_meas_t*)attr;
measurements = attr_cast->get_measurements(attr_cast);
request_id = measurements->get_request_id(measurements);
@ -287,7 +288,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
/* check hashes from database against measurements */
e = pts_db->create_file_hash_enumerator(pts_db,
platform_info, algo, is_dir, arg_int);
pts->get_platform_id(pts),
algo, is_dir, arg_int);
if (!e)
{
eval = TNC_IMV_EVALUATION_RESULT_ERROR;
@ -319,8 +321,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
while (e->enumerate(e, &filename, &measurement))
{
if (pts_db->add_file_measurement(pts_db,
platform_info, algo, measurement, filename,
is_dir, arg_int) != SUCCESS)
pts->get_platform_id(pts), algo, measurement,
filename, is_dir, arg_int) != SUCCESS)
{
eval = TNC_IMV_EVALUATION_RESULT_ERROR;
}
@ -343,7 +345,8 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
}
else
{
measurements->check(measurements, pts_db, platform_info, algo);
measurements->check(measurements, pts_db,
pts->get_platform_id(pts), algo);
}
break;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2012 Andreas Steffen
* Copyright (C) 2011-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@ -65,11 +65,6 @@ struct pts_ita_comp_ima_t {
*/
pts_comp_func_name_t *name;
/**
* AIK keyid
*/
chunk_t keyid;
/**
* Sub-component depth
*/
@ -83,7 +78,7 @@ struct pts_ita_comp_ima_t {
/**
* Primary key for AIK database entry
*/
int kid;
int aik_id;
/**
* Primary key for IMA BIOS Component Functional Name database entry
@ -613,22 +608,7 @@ METHOD(pts_component_t, verify, status_t,
status_t status;
char *uri;
/* 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;
}
}
this->aik_id = pts->get_aik_id(pts);
pcrs = pts->get_pcrs(pts);
measurement = evidence->get_measurement(evidence, &pcr, &algo, &transform,
&measurement_time);
@ -641,8 +621,8 @@ METHOD(pts_component_t, verify, status_t,
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, this->aik_id, algo,
&this->bios_cid, &this->bios_count);
this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
if (status != SUCCESS)
{
@ -670,8 +650,8 @@ METHOD(pts_component_t, verify, status_t,
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);
measurement, this->bios_cid, this->aik_id,
++this->seq_no, pcr, algo);
if (status != SUCCESS)
{
return status;
@ -681,8 +661,8 @@ METHOD(pts_component_t, verify, status_t,
else
{
status = this->pts_db->check_comp_measurement(this->pts_db,
measurement, this->bios_cid, this->kid,
++this->seq_no, pcr, algo);
measurement, this->bios_cid, this->aik_id,
++this->seq_no, pcr, algo);
if (status == FAILED)
{
return status;
@ -711,8 +691,8 @@ METHOD(pts_component_t, verify, status_t,
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, this->aik_id, algo,
&this->ima_cid, &ima_count);
this->name->set_qualifier(this->name, PTS_QUALIFIER_UNKNOWN);
if (status != SUCCESS)
{
@ -728,7 +708,7 @@ METHOD(pts_component_t, verify, status_t,
"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);
this->aik_id, 1, pcr, algo);
}
else
{
@ -737,7 +717,7 @@ METHOD(pts_component_t, verify, status_t,
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->aik_id, 1, pcr, algo);
}
this->state = IMA_STATE_RUNTIME;
@ -756,7 +736,7 @@ METHOD(pts_component_t, verify, status_t,
return FAILED;
}
status = this->pts_db->check_file_measurement(this->pts_db,
pts->get_platform_info(pts),
pts->get_platform_id(pts),
PTS_MEAS_ALGO_SHA1_IMA,
measurement, uri);
switch (status)
@ -904,14 +884,14 @@ METHOD(pts_component_t, destroy, void,
if (this->is_bios_registering)
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->bios_cid, this->kid);
this->bios_cid, this->aik_id);
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);
this->ima_cid, this->aik_id);
DBG1(DBG_PTS, "deleted registered %N '%N' boot aggregate evidence "
"measurement", pen_names, vid, names, name);
}
@ -920,7 +900,6 @@ METHOD(pts_component_t, destroy, void,
this->ima_list->destroy_function(this->ima_list,
(void *)free_ima_entry);
this->name->destroy(this->name);
free(this->keyid.ptr);
free(this);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2012 Andreas Steffen
* Copyright (C) 2011-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@ -40,11 +40,6 @@ struct pts_ita_comp_tboot_t {
*/
pts_comp_func_name_t *name;
/**
* AIK keyid
*/
chunk_t keyid;
/**
* Sub-component depth
*/
@ -55,6 +50,11 @@ struct pts_ita_comp_tboot_t {
*/
pts_database_t *pts_db;
/**
* Primary key for AIK database entry
*/
int aik_id;
/**
* Primary key for Component Functional Name database entry
*/
@ -201,51 +201,38 @@ METHOD(pts_component_t, verify, status_t,
chunk_t measurement, pcr_before, pcr_after;
status_t status;
this->aik_id = pts->get_aik_id(pts);
pcrs = pts->get_pcrs(pts);
measurement = evidence->get_measurement(evidence, &extended_pcr,
&algo, &transform, &measurement_time);
if (!this->keyid.ptr)
status = this->pts_db->get_comp_measurement_count(this->pts_db,
this->name, this->aik_id, algo,
&this->cid, &this->count);
if (status != SUCCESS)
{
if (!pts->get_aik_keyid(pts, &this->keyid))
{
return FAILED;
}
this->keyid = chunk_clone(this->keyid);
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->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->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);
if (this->count)
{
DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence "
"measurements", this->count, pen_names, vid, names, name);
}
else
{
DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
"measurements", pen_names, vid, names, name);
this->is_registering = TRUE;
}
if (this->count)
{
DBG1(DBG_PTS, "checking %d %N '%N' functional component evidence "
"measurements", this->count, pen_names, vid, names, name);
}
else
{
DBG1(DBG_PTS, "registering %N '%N' functional component evidence "
"measurements", pen_names, vid, names, name);
this->is_registering = TRUE;
}
if (this->is_registering)
{
status = this->pts_db->insert_comp_measurement(this->pts_db,
measurement, this->cid, this->kid,
measurement, this->cid, this->aik_id,
++this->seq_no, extended_pcr, algo);
if (status != SUCCESS)
{
@ -329,7 +316,7 @@ METHOD(pts_component_t, destroy, void,
if (this->is_registering)
{
count = this->pts_db->delete_comp_measurements(this->pts_db,
this->cid, this->kid);
this->cid, this->aik_id);
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);
@ -337,7 +324,6 @@ METHOD(pts_component_t, destroy, void,
"evidence measurements", count, pen_names, vid, names, name);
}
this->name->destroy(this->name);
free(this->keyid.ptr);
free(this);
}
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
* Copyright (C) 2011-2012 Sansar Choinyambuu
* Copyright (C) 2012-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@ -88,9 +89,9 @@ struct private_pts_t {
chunk_t secret;
/**
* Platform and OS Info
* Primary key of platform entry in database
*/
char *platform_info;
int platform_id;
/**
* TRUE if IMC-PTS, FALSE if IMV-PTS
@ -117,6 +118,11 @@ struct private_pts_t {
*/
certificate_t *aik;
/**
* Primary key referening AIK in database
*/
int aik_id;
/**
* Shadow PCR set
*/
@ -330,17 +336,16 @@ static void print_tpm_version_info(private_pts_t *this)
#endif /* TSS_TROUSERS */
METHOD(pts_t, get_platform_info, char*,
METHOD(pts_t, get_platform_id, int,
private_pts_t *this)
{
return this->platform_info;
return this->platform_id;
}
METHOD(pts_t, set_platform_info, void,
private_pts_t *this, char *info)
METHOD(pts_t, set_platform_id, void,
private_pts_t *this, int pid)
{
free(this->platform_info);
this->platform_info = strdup(info);
this->platform_id = pid;
}
METHOD(pts_t, get_tpm_version_info, bool,
@ -451,37 +456,17 @@ METHOD(pts_t, get_aik, certificate_t*,
}
METHOD(pts_t, set_aik, void,
private_pts_t *this, certificate_t *aik)
private_pts_t *this, certificate_t *aik, int aik_id)
{
DESTROY_IF(this->aik);
this->aik = aik->get_ref(aik);
this->aik_id = aik_id;
}
METHOD(pts_t, get_aik_keyid, bool,
private_pts_t *this, chunk_t *keyid)
METHOD(pts_t, get_aik_id, int,
private_pts_t *this)
{
public_key_t *public;
bool success;
if (!this->aik)
{
DBG1(DBG_PTS, "no AIK certificate available");
return FALSE;
}
public = this->aik->get_public_key(this->aik);
if (!public)
{
DBG1(DBG_PTS, "no AIK public key available");
return FALSE;
}
success = public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, keyid);
if (!success)
{
DBG1(DBG_PTS, "no SHA-1 AIK public key info ID available");
}
public->destroy(public);
return success;
return this->aik_id;
}
METHOD(pts_t, is_path_valid, bool,
@ -1088,7 +1073,6 @@ METHOD(pts_t, destroy, void,
free(this->initiator_nonce.ptr);
free(this->responder_nonce.ptr);
free(this->secret.ptr);
free(this->platform_info);
free(this->aik_blob.ptr);
free(this->tpm_version_info.ptr);
free(this);
@ -1182,13 +1166,13 @@ pts_t *pts_create(bool is_imc)
.get_my_public_value = _get_my_public_value,
.set_peer_public_value = _set_peer_public_value,
.calculate_secret = _calculate_secret,
.get_platform_info = _get_platform_info,
.set_platform_info = _set_platform_info,
.get_platform_id = _get_platform_id,
.set_platform_id = _set_platform_id,
.get_tpm_version_info = _get_tpm_version_info,
.set_tpm_version_info = _set_tpm_version_info,
.get_aik = _get_aik,
.set_aik = _set_aik,
.get_aik_keyid = _get_aik_keyid,
.get_aik_id = _get_aik_id,
.is_path_valid = _is_path_valid,
.get_metadata = _get_metadata,
.read_pcr = _read_pcr,

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Sansar Choinyambuu
* Copyright (C) 2012-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@ -162,19 +163,18 @@ struct pts_t {
bool (*calculate_secret) (pts_t *this);
/**
* Get Platform and OS Info
* Get primary key of platform entry in database
*
* @return Platform and OS info
*/
char* (*get_platform_info)(pts_t *this);
int (*get_platform_id)(pts_t *this);
/**
* Set Platform and OS Info
* Set primary key of platform entry in database
*
* @param name OS name
* @param version OS version
* @param pid Primary key of platform entry in database
*/
void (*set_platform_info)(pts_t *this, char *info);
void (*set_platform_id)(pts_t *this, int pid);
/**
* Get TPM 1.2 Version Info
@ -202,16 +202,16 @@ struct pts_t {
* Set Attestation Identity Certificate or Public Key
*
* @param aik AIK Certificate or Public Key
* @param aik_id Primary key referencing AIK in database
*/
void (*set_aik)(pts_t *this, certificate_t *aik);
void (*set_aik)(pts_t *this, certificate_t *aik, int aik_id);
/**
* Get SHA-1 Attestation Identity Public Key Info ID
* Get primary key referencing AIK in database
*
* @param keyid AIK ID
* @return TRUE if AIK ID exists
* @return Primary key referencing AIK in database
*/
bool (*get_aik_keyid)(pts_t *this, chunk_t *keyid);
int (*get_aik_id)(pts_t *this);
/**
* Check whether path is valid file/directory on filesystem

View File

@ -83,7 +83,7 @@ METHOD(pts_database_t, get_pathname, char*,
}
METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
private_pts_database_t *this, int pid, pts_meas_algorithms_t algo,
bool is_dir, int id)
{
enumerator_t *e;
@ -93,76 +93,32 @@ METHOD(pts_database_t, create_file_hash_enumerator, enumerator_t*,
e = this->db->query(this->db,
"SELECT f.name, 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 "
"JOIN directories as d ON d.id = f.dir "
"WHERE p.name = ? AND fh.algo = ? AND d.id = ? "
"WHERE fh.product = ? AND fh.algo = ? AND d.id = ? "
"ORDER BY f.name",
DB_TEXT, product, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB);
DB_INT, pid, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB);
}
else
{
e = this->db->query(this->db,
"SELECT f.name, 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 fh.algo = ? AND fh.file = ?",
DB_TEXT, product, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB);
"WHERE fh.product = ? AND fh.algo = ? AND fh.file = ?",
DB_INT, pid, DB_INT, algo, DB_INT, id, DB_TEXT, DB_BLOB);
}
return e;
}
METHOD(pts_database_t, check_aik_keyid, status_t,
private_pts_database_t *this, chunk_t keyid, int *kid)
{
enumerator_t *e;
chunk_t keyid_hex;
/* Convert keyid into a hex-encoded string */
keyid_hex = chunk_to_hex(keyid, NULL, FALSE);
/* If the AIK is registered get the primary key */
e = this->db->query(this->db,
"SELECT id FROM devices WHERE name = ?",
DB_TEXT, keyid_hex.ptr, DB_INT);
if (!e)
{
DBG1(DBG_PTS, "no database query enumerator returned");
return FAILED;
}
if (!e->enumerate(e, kid))
{
DBG1(DBG_PTS, "AIK %#B is not registered in database", &keyid);
e->destroy(e);
return FAILED;
}
e->destroy(e);
return SUCCESS;
}
METHOD(pts_database_t, add_file_measurement, status_t,
private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
private_pts_database_t *this, int pid, pts_meas_algorithms_t algo,
chunk_t measurement, char *filename, bool is_dir, int id)
{
enumerator_t *e;
char *name;
chunk_t hash_value;
int hash_id, fid, pid = 0;
int hash_id, fid;
status_t status = SUCCESS;
/* get primary key of product string */
e = this->db->query(this->db,
"SELECT id FROM products WHERE name = ?", DB_TEXT, product, DB_INT);
if (e)
{
e->enumerate(e, &pid);
e->destroy(e);
}
if (pid == 0)
{
return FAILED;
}
if (is_dir)
{
/* does filename entry already exist? */
@ -249,7 +205,7 @@ METHOD(pts_database_t, add_file_measurement, status_t,
}
METHOD(pts_database_t, check_file_measurement, status_t,
private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
private_pts_database_t *this, int pid, pts_meas_algorithms_t algo,
chunk_t measurement, char *filename)
{
enumerator_t *e;
@ -271,9 +227,8 @@ METHOD(pts_database_t, check_file_measurement, status_t,
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.name = ? AND fh.algo = ?",
DB_TEXT, product, DB_TEXT, file, DB_INT, algo, DB_BLOB);
"WHERE fh.product = ? AND f.name = ? AND fh.algo = ?",
DB_INT, pid, DB_TEXT, file, DB_INT, algo, DB_BLOB);
}
else
{ /* absolute pathname */
@ -300,9 +255,8 @@ METHOD(pts_database_t, check_file_measurement, status_t,
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.dir = ? AND f.name = ? AND fh.algo = ?",
DB_TEXT, product, DB_INT, did, DB_TEXT, file, DB_INT, algo,
"WHERE fh.product = ? AND f.dir = ? AND f.name = ? AND fh.algo = ?",
DB_INT, pid, DB_INT, did, DB_TEXT, file, DB_INT, algo,
DB_BLOB);
}
if (!e)
@ -332,23 +286,8 @@ err:
return status;
}
METHOD(pts_database_t, create_comp_evid_enumerator, enumerator_t*,
private_pts_database_t *this, int kid)
{
enumerator_t *e;
/* look for all entries belonging to an AIK in the components table */
e = this->db->query(this->db,
"SELECT c.vendor_id, c.name, c.qualifier, kc.depth "
"FROM components AS c "
"JOIN key_component AS kc ON c.id = kc.component "
"WHERE kc.key = ? ORDER BY kc.seq_no",
DB_INT, kid, DB_INT, DB_INT, DB_INT, DB_INT);
return e;
}
METHOD(pts_database_t, check_comp_measurement, status_t,
private_pts_database_t *this, chunk_t measurement, int cid, int kid,
private_pts_database_t *this, chunk_t measurement, int cid, int aik_id,
int seq_no, int pcr, pts_meas_algorithms_t algo)
{
enumerator_t *e;
@ -359,7 +298,7 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
"SELECT hash FROM component_hashes "
"WHERE component = ? AND key = ? "
"AND seq_no = ? AND pcr = ? AND algo = ? ",
DB_INT, cid, DB_INT, kid, DB_INT, seq_no,
DB_INT, cid, DB_INT, aik_id, DB_INT, seq_no,
DB_INT, pcr, DB_INT, algo, DB_BLOB);
if (!e)
{
@ -396,7 +335,7 @@ METHOD(pts_database_t, check_comp_measurement, status_t,
}
METHOD(pts_database_t, insert_comp_measurement, status_t,
private_pts_database_t *this, chunk_t measurement, int cid, int kid,
private_pts_database_t *this, chunk_t measurement, int cid, int aik_id,
int seq_no, int pcr, pts_meas_algorithms_t algo)
{
int id;
@ -405,7 +344,7 @@ METHOD(pts_database_t, insert_comp_measurement, status_t,
"INSERT INTO component_hashes "
"(component, key, seq_no, pcr, algo, hash) "
"VALUES (?, ?, ?, ?, ?, ?)",
DB_INT, cid, DB_INT, kid, DB_INT, seq_no, DB_INT, pcr,
DB_INT, cid, DB_INT, aik_id, DB_INT, seq_no, DB_INT, pcr,
DB_INT, algo, DB_BLOB, measurement) == 1)
{
return SUCCESS;
@ -416,17 +355,17 @@ METHOD(pts_database_t, insert_comp_measurement, status_t,
}
METHOD(pts_database_t, delete_comp_measurements, int,
private_pts_database_t *this, int cid, int kid)
private_pts_database_t *this, int cid, int aik_id)
{
return this->db->execute(this->db, NULL,
"DELETE FROM component_hashes "
"WHERE component = ? AND key = ?",
DB_INT, cid, DB_INT, kid);
DB_INT, cid, DB_INT, aik_id);
}
METHOD(pts_database_t, get_comp_measurement_count, status_t,
private_pts_database_t *this, pts_comp_func_name_t *comp_name,
chunk_t keyid, pts_meas_algorithms_t algo, int *cid, int *kid, int *count)
int aik_id, pts_meas_algorithms_t algo, int *cid, int *count)
{
enumerator_t *e;
status_t status = SUCCESS;
@ -434,11 +373,6 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t,
/* Initialize count */
*count = 0;
if (_check_aik_keyid(this, keyid, kid) != SUCCESS)
{
return FAILED;
}
/* Get the primary key of the Component Functional Name */
e = this->db->query(this->db,
"SELECT id FROM components "
@ -464,7 +398,7 @@ METHOD(pts_database_t, get_comp_measurement_count, status_t,
e = this->db->query(this->db,
"SELECT COUNT(*) FROM component_hashes AS ch "
"WHERE component = ? AND key = ? AND algo = ?",
DB_INT, *cid, DB_INT, *kid, DB_INT, algo, DB_INT);
DB_INT, *cid, DB_INT, aik_id, DB_INT, algo, DB_INT);
if (!e)
{
DBG1(DBG_PTS, "no database query enumerator returned");
@ -501,7 +435,6 @@ pts_database_t *pts_database_create(imv_database_t *imv_db)
INIT(this,
.public = {
.get_pathname = _get_pathname,
.create_comp_evid_enumerator = _create_comp_evid_enumerator,
.create_file_hash_enumerator = _create_file_hash_enumerator,
.add_file_measurement = _add_file_measurement,
.check_file_measurement = _check_file_measurement,

View File

@ -47,37 +47,20 @@ struct pts_database_t {
/**
* Get stored measurement hash for single file or directory entries
*
* @param product Software product (os, vpn client, etc.)
* @param pid Primary key of software product in database
* @param algo Hash algorithm used for measurement
* @param is_dir TRUE if directory was measured
* @param id Primary key of measured file/directory
* @return Enumerator over all matching measurement hashes
*/
enumerator_t* (*create_file_hash_enumerator)(pts_database_t *this,
char *product, pts_meas_algorithms_t algo,
int pid, pts_meas_algorithms_t algo,
bool is_dir, int id);
/**
* Check if an AIK given by its keyid is registered in the database
*
* @param keyid AIK keyid (SHA-1 hash of the AIK public key info)
* @param kid Primary key of AIK entry in devices table
* @return SUCCESS if AIK is present, FAILED otherwise
*/
status_t (*check_aik_keyid)(pts_database_t *this, chunk_t keyid, int *kid);
/**
* Get functional components to request evidence of
*
* @param kid Primary key of AIK entry in keys table
* @return Enumerator over all matching components
*/
enumerator_t* (*create_comp_evid_enumerator)(pts_database_t *this, int kid);
/**
* Add PTS file measurement reference value
*
* @param product Software product (os, vpn client, etc.)
* @param pid Primary key of software product in database
* @param algo File measurement hash algorithm used
* @param measurement File measurement hash
* @param filename Optional name of the file to be checked
@ -85,7 +68,7 @@ struct pts_database_t {
* @param id Primary key into direcories/files table
* @return Status
*/
status_t (*add_file_measurement)(pts_database_t *this, char *product,
status_t (*add_file_measurement)(pts_database_t *this, int pid,
pts_meas_algorithms_t algo,
chunk_t measurement, char *filename,
bool is_dir, int id);
@ -93,13 +76,13 @@ struct pts_database_t {
/**
* Check PTS file measurement against reference stored in database
*
* @param product Software product (os, vpn client, etc.)
* @param pid Primary key of software product in database
* @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,
status_t (*check_file_measurement)(pts_database_t *this, int pid,
pts_meas_algorithms_t algo,
chunk_t measurement, char *filename);
@ -108,14 +91,14 @@ struct pts_database_t {
*
* @param measurement measurement hash
* @param cid Primary key of Component Functional Name entry
* @param kid Primary key of AIK entry in keys table
* @param aik_id Primary key of AIK entry in database
* @param seq_no Measurement sequence number
* @param prc Number of the PCR the measurement was extended into
* @param algo Hash algorithm used for measurement
* @return SUCCESS if check was successful
*/
status_t (*check_comp_measurement)(pts_database_t *this, chunk_t measurement,
int cid, int kid, int seq_no, int pcr,
int cid, int aik_id, int seq_no, int pcr,
pts_meas_algorithms_t algo);
/**
@ -123,40 +106,38 @@ struct pts_database_t {
*
* @param measurement Measurement hash
* @param cid Primary key of Component Functional Name entry
* @param kid Primary key of AIK entry in keys table
* @param aik_id Primary key of AIK entry in database
* @param seq_no Measurement sequence number
* @param prc Number of the PCR the measurement was extended into
* @param algo Hash algorithm used for measurement
* @return SUCCESS if INSERT was successful
*/
status_t (*insert_comp_measurement)(pts_database_t *this, chunk_t measurement,
int cid, int kid, int seq_no, int pcr,
int cid, int aik_id, int seq_no, int pcr,
pts_meas_algorithms_t algo);
/**
* Delete functional component measurements from the database
*
* @param cid Primary key of Component Functional Name entry
* @param kid Primary key of AIK entry in keys table
* @param aik_id Primary key of AIK entry in database
* @return number of deleted measurement entries
*/
int (*delete_comp_measurements)(pts_database_t *this, int cid, int kid);
int (*delete_comp_measurements)(pts_database_t *this, int cid, int aik_id);
/**
* Get the number of measurements for a functional component and AIK
*
* @param comp_name Component Functional Name
* @param keyid SHA-1 hash of AIK public key info
* @param aik_id Primary key of AIK entry in database
* @param algo Hash algorithm used for measurement
* @param cid Primary key of Component Functional Name entry
* @param kid Primary key of AIK entry in keys table
* @param count measurement count
* @return SUCCESS if COUNT was successful
*/
status_t (*get_comp_measurement_count)(pts_database_t *this,
pts_comp_func_name_t *comp_name, chunk_t keyid,
pts_meas_algorithms_t algo, int *cid, int *kid,
int *count);
pts_comp_func_name_t *comp_name, int aik_id,
pts_meas_algorithms_t algo, int *cid, int *count);
/**
* Destroys a pts_database_t object.

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Sansar Choinyambuu
* Copyright (C) 2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@ -112,7 +113,7 @@ METHOD(pts_file_meas_t, create_enumerator, enumerator_t*,
}
METHOD(pts_file_meas_t, check, bool,
private_pts_file_meas_t *this, pts_database_t *pts_db, char *product,
private_pts_file_meas_t *this, pts_database_t *pts_db, int pid,
pts_meas_algorithms_t algo)
{
enumerator_t *enumerator;
@ -123,7 +124,7 @@ METHOD(pts_file_meas_t, check, bool,
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
status = pts_db->check_file_measurement(pts_db, product, algo,
status = pts_db->check_file_measurement(pts_db, pid, algo,
entry->measurement, entry->filename);
switch (status)
{

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2011 Sansar Choinyambuu
* Copyright (C) 2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@ -65,11 +66,11 @@ struct pts_file_meas_t {
* Check PTS File Measurements against reference value in the database
*
* @param db PTS Measurement database
* @param product Software product (os, vpn client, etc.)
* @param pid Primary key of software product in database
* @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,
bool (*check)(pts_file_meas_t *this, pts_database_t *db, int pid,
pts_meas_algorithms_t algo);
/**