From: Andreas Steffen Date: Tue, 17 Jul 2012 09:16:11 +0000 (+0200) Subject: check IMA file measurements against database reference X-Git-Tag: 5.0.1~292 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=964de0abde0a92233488c16ca7d5434847eb3880;p=thirdparty%2Fstrongswan.git check IMA file measurements against database reference --- diff --git a/src/libpts/plugins/imv_attestation/imv_attestation_process.c b/src/libpts/plugins/imv_attestation/imv_attestation_process.c index 842144f646..5efcf7f708 100644 --- a/src/libpts/plugins/imv_attestation/imv_attestation_process.c +++ b/src/libpts/plugins/imv_attestation/imv_attestation_process.c @@ -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; } diff --git a/src/libpts/pts/pts_database.c b/src/libpts/pts/pts_database.c index 17ebe56d30..97de8190bb 100644 --- a/src/libpts/pts/pts_database.c +++ b/src/libpts/pts/pts_database.c @@ -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) { diff --git a/src/libpts/pts/pts_database.h b/src/libpts/pts/pts_database.h index a9a68ac76b..94acd3339b 100644 --- a/src/libpts/pts/pts_database.h +++ b/src/libpts/pts/pts_database.h @@ -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 * diff --git a/src/libpts/pts/pts_file_meas.c b/src/libpts/pts/pts_file_meas.c index c8793e3013..4eb359ce17 100644 --- a/src/libpts/pts/pts_file_meas.c +++ b/src/libpts/pts/pts_file_meas.c @@ -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, }, diff --git a/src/libpts/pts/pts_file_meas.h b/src/libpts/pts/pts_file_meas.h index 817cb547a3..71efd5026c 100644 --- a/src/libpts/pts/pts_file_meas.h +++ b/src/libpts/pts/pts_file_meas.h @@ -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