check IMA file measurements against database reference
authorAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 17 Jul 2012 09:16:11 +0000 (11:16 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 17 Jul 2012 09:16:19 +0000 (11:16 +0200)
src/libpts/plugins/imv_attestation/imv_attestation_process.c
src/libpts/pts/pts_database.c
src/libpts/pts/pts_database.h
src/libpts/pts/pts_file_meas.c
src/libpts/pts/pts_file_meas.h

index 842144f..5efcf7f 100644 (file)
@@ -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;
                }
index 17ebe56..97de819 100644 (file)
@@ -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)
 {
index a9a68ac..94acd33 100644 (file)
@@ -37,6 +37,19 @@ 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
+       *
+       * @param product                Software product (os, vpn client, etc.)
        * @return                               Enumerator over all matching files/directories
        */
        enumerator_t* (*create_file_meas_enumerator)(pts_database_t *this,
index c8793e3..4eb359c 100644 (file)
@@ -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,
                },
index 817cb54..71efd50 100644 (file)
@@ -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