Added create_meas_enumerator function to pts_database object
authorSansar Choinyambuu <schoinya@hsr.ch>
Fri, 26 Aug 2011 08:08:16 +0000 (10:08 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 8 Sep 2011 10:08:14 +0000 (12:08 +0200)
Implemented handling part of File Measurement attributes reception
Ending the exchange and allowing access if all measurements match with database isolate if not

src/libimcv/plugins/imv_attestation/imv_attestation.c
src/libimcv/tcg/pts/pts_database.c
src/libimcv/tcg/pts/pts_database.h

index 851efb9..7e0b13a 100644 (file)
@@ -422,17 +422,66 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
                                        u_int64_t num_of_files;
                                        u_int16_t request_id;
                                        u_int16_t meas_len;
+                                       enumerator_t *meas_enumerator;
+                                       file_meas_entry_t *meas_entry;
+                                       bool comparisons_succeeded = true;
                                        
                                        attr_cast = (tcg_pts_attr_file_meas_t*)attr;
                                        num_of_files = attr_cast->get_number_of_files(attr_cast);
                                        request_id = attr_cast->get_request_id(attr_cast);
                                        meas_len = attr_cast->get_meas_len(attr_cast);
                                        
-                                       /* TODO: Start working here */
+                                       meas_enumerator = attr_cast->create_file_meas_enumerator(attr_cast);
+                                       while (meas_enumerator->enumerate(meas_enumerator, &meas_entry))
+                                       {
+                                               enumerator_t *hash_enumerator;
+                                               pts_meas_algorithms_t selected_algorithm;
+                                               char *product = "Ubuntu 10.10 x86_64";
+                                               chunk_t db_measurement;
+                                               
+                                               DBG3(DBG_IMV, "Received measurement: %B", &meas_entry->measurement);
+                                               
+                                               if (!pts_db)
+                                               {
+                                                       break;
+                                               }
+                                               selected_algorithm = pts->get_meas_algorithm(pts);
+                                               
+                                               hash_enumerator = pts_db->create_meas_enumerator(pts_db, product, request_id, selected_algorithm);
+                                               if (!hash_enumerator)
+                                               {
+                                                       break;
+                                               }
+                                               while (hash_enumerator->enumerate(hash_enumerator, &db_measurement))
+                                               {
+                                                       DBG3(DBG_IMV, "Expected measurement: %B", &db_measurement);
+                                                       
+                                                       /* Compare the received hash measurement with one saved in db */
+                                                       if(chunk_compare(db_measurement, meas_entry->measurement) == 0)
+                                                       {
+                                                               DBG1(DBG_IMV, "Measurement comparison succeeded for: %s", meas_entry->file_name.ptr);
+                                                       }
+                                                       else
+                                                       {
+                                                               DBG1(DBG_IMV, "Measurement comparison failed for: %s", meas_entry->file_name.ptr);
+                                                               comparisons_succeeded = false;
+                                                       }                                                       
+                                               }
+                                               hash_enumerator->destroy(hash_enumerator);
+                                               
+                                       }
                                        
                                        attestation_state->set_handshake_state(attestation_state,
                                                                                        IMV_ATTESTATION_STATE_END);
-                                       break;
+                                       
+                                       (comparisons_succeeded) ? state->set_recommendation(state,
+                                                                 TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
+                                                                 TNC_IMV_EVALUATION_RESULT_COMPLIANT) :
+                                               state->set_recommendation(state,
+                                                                 TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
+                                                                 TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
+                 
+                                       return imv_attestation->provide_recommendation(imv_attestation, connection_id);
                                }
                                
                                /* TODO: Not implemented yet */
index bcfa8c8..00ec977 100644 (file)
@@ -54,6 +54,35 @@ METHOD(pts_database_t, create_file_enumerator, enumerator_t*,
        return e;
 }
 
+METHOD(pts_database_t, create_meas_enumerator, enumerator_t*,
+       private_pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm)
+{
+       enumerator_t *e;
+       int algo = 0;
+       
+       switch(algorithm)
+       {
+               case PTS_MEAS_ALGO_SHA1:
+                       algo = 32768;
+                       break;
+               case PTS_MEAS_ALGO_SHA256:
+                       algo = 16384;
+                       break;
+               case PTS_MEAS_ALGO_SHA384:
+                       algo = 8192;
+                       break;
+       }
+       
+       /* look for all entries belonging to a product and file in file_hashes table */
+       e = this->db->query(this->db,
+                               "SELECT fh.hash FROM file_hashes AS fh "
+                               "JOIN files AS f ON fh.file = f.id "
+                               "JOIN products AS p ON fh.product = p.id "
+                               "WHERE p.name = ? AND f.id = ? AND fh.algo = ?",
+                               DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_BLOB);
+       return e;
+}
+
 METHOD(pts_database_t, destroy, void,
        private_pts_database_t *this)
 {
@@ -71,6 +100,7 @@ pts_database_t *pts_database_create(char *uri)
        INIT(this,
                .public = {
                        .create_file_enumerator = _create_file_enumerator,
+                       .create_meas_enumerator = _create_meas_enumerator,
                        .destroy = _destroy,
                },
                .db = lib->db->create(lib->db, uri),
index 9675d60..778ea8a 100644 (file)
@@ -23,6 +23,7 @@
 
 typedef struct pts_database_t pts_database_t;
 
+#include "pts_meas_algo.h"
 #include <library.h>
 
 /**
@@ -38,6 +39,16 @@ struct pts_database_t {
         * @return                              enumerator over all files matching a given release 
         */
        enumerator_t* (*create_file_enumerator)(pts_database_t *this, char *product);
+       
+       /**
+        * Get Hash measurement of a file with given id and hashing algorithm type
+        *
+        * @product                             software product (os, vpn client, etc.)
+        * @id                                  primary key in files table
+        * @algorithm                           measurement algorithm type
+        * @return                              enumerator over all measurements matching a given release 
+        */
+       enumerator_t* (*create_meas_enumerator)(pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm);
 
        /**
         * Destroys a pts_database_t object.