check IMA file measurements against database reference
This commit is contained in:
@@ -237,7 +237,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
|
||||
}
|
||||
else
|
||||
{
|
||||
measurements->insert(measurements, pts_db, platform_info);
|
||||
measurements->check(measurements, pts_db, platform_info, algo);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,38 @@ struct private_pts_database_t {
|
||||
|
||||
};
|
||||
|
||||
METHOD(pts_database_t, check_file_measurement, status_t,
|
||||
private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
|
||||
chunk_t measurement, char *filename)
|
||||
{
|
||||
enumerator_t *e;
|
||||
chunk_t hash;
|
||||
status_t status;
|
||||
|
||||
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.product = ? AND f.file = ? AND fh.algo = ?",
|
||||
DB_TEXT, product, DB_TEXT, filename, DB_INT, algo, DB_BLOB);
|
||||
if (!e)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
if (e->enumerate(e, &hash))
|
||||
{
|
||||
status = chunk_equals(measurement, hash) ?
|
||||
SUCCESS : VERIFY_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = NOT_FOUND;
|
||||
}
|
||||
e->destroy(e);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
|
||||
private_pts_database_t *this, char *product)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,19 @@ typedef struct pts_database_t pts_database_t;
|
||||
*/
|
||||
struct pts_database_t {
|
||||
|
||||
/**
|
||||
* Get files/directories to be measured by PTS
|
||||
*
|
||||
* @param product Software product (os, vpn client, etc.)
|
||||
* @param algo File measurement hash algorithm used
|
||||
* @param measurement File measurement hash
|
||||
* @param filename Optional name of the file to be checked
|
||||
* @return Status
|
||||
*/
|
||||
status_t (*check_file_measurement)(pts_database_t *this, char *product,
|
||||
pts_meas_algorithms_t algo,
|
||||
chunk_t measurement, char *filename);
|
||||
|
||||
/**
|
||||
* Get files/directories to be measured by PTS
|
||||
*
|
||||
|
||||
@@ -111,19 +111,47 @@ METHOD(pts_file_meas_t, create_enumerator, enumerator_t*,
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, insert, bool,
|
||||
private_pts_file_meas_t *this, pts_database_t *pts_db, char *product)
|
||||
METHOD(pts_file_meas_t, check, bool,
|
||||
private_pts_file_meas_t *this, pts_database_t *pts_db, char *product,
|
||||
pts_meas_algorithms_t algo)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
char *status_msg;
|
||||
int count_ok = 0, count_not_found = 0, count_differ = 0;
|
||||
status_t status;
|
||||
|
||||
enumerator = this->list->create_enumerator(this->list);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
DBG2(DBG_PTS, " %#B for '%s'", &entry->measurement, entry->filename);
|
||||
status = pts_db->check_file_measurement(pts_db, product, algo,
|
||||
entry->measurement, entry->filename);
|
||||
switch (status)
|
||||
{
|
||||
case SUCCESS:
|
||||
status_msg = "ok";
|
||||
count_ok++;
|
||||
break;
|
||||
case NOT_FOUND:
|
||||
status_msg = "not found";
|
||||
count_not_found++;
|
||||
break;
|
||||
case VERIFY_ERROR:
|
||||
status_msg = "differs";
|
||||
count_differ++;
|
||||
break;
|
||||
case FAILED:
|
||||
default:
|
||||
status_msg = "failed";
|
||||
}
|
||||
DBG2(DBG_PTS, " %#B for '%s' - %s", &entry->measurement,
|
||||
entry->filename, status_msg);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
DBG1(DBG_PTS, "%d measurements, %d ok, %d not found, %d differ",
|
||||
this->list->get_count(this->list),
|
||||
count_ok, count_not_found, count_differ);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -194,7 +222,7 @@ pts_file_meas_t *pts_file_meas_create(u_int16_t request_id)
|
||||
.get_file_count = _get_file_count,
|
||||
.add = _add,
|
||||
.create_enumerator = _create_enumerator,
|
||||
.insert = _insert,
|
||||
.check = _check,
|
||||
.verify = _verify,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
@@ -280,7 +308,7 @@ pts_file_meas_t *pts_file_meas_create_from_path(u_int16_t request_id,
|
||||
.get_file_count = _get_file_count,
|
||||
.add = _add,
|
||||
.create_enumerator = _create_enumerator,
|
||||
.insert = _insert,
|
||||
.check = _check,
|
||||
.verify = _verify,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
|
||||
@@ -62,13 +62,15 @@ struct pts_file_meas_t {
|
||||
enumerator_t* (*create_enumerator)(pts_file_meas_t *this);
|
||||
|
||||
/**
|
||||
* Insert PTS File Measurements into the database
|
||||
* Check PTS File Measurements against reference value in the database
|
||||
*
|
||||
* @param db PTS Measurement database
|
||||
* @param product Software product (os, vpn client, etc.)
|
||||
* @return TRUE if all measurements could be inserted
|
||||
* @param algo PTS Measurement algorithm used
|
||||
* @return TRUE if all measurements agreed
|
||||
*/
|
||||
bool (*insert)(pts_file_meas_t *this, pts_database_t *db, char* product);
|
||||
bool (*check)(pts_file_meas_t *this, pts_database_t *db, char* product,
|
||||
pts_meas_algorithms_t algo);
|
||||
|
||||
/**
|
||||
* Verify stored hashes against PTS File Measurements
|
||||
|
||||
Reference in New Issue
Block a user