Moved hashing functionalities to pts object
authorSansar Choinyambuu <schoinya@hsr.ch>
Wed, 24 Aug 2011 07:34:55 +0000 (09:34 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 8 Sep 2011 10:08:13 +0000 (12:08 +0200)
src/libimcv/plugins/imc_attestation/imc_attestation.c
src/libimcv/tcg/pts/pts.c
src/libimcv/tcg/pts/pts.h

index b0ec084..64ea559 100644 (file)
@@ -39,8 +39,6 @@
 #include <debug.h>
 #include <utils/linked_list.h>
 #include <crypto/hashers/hasher.h>
-#include <dirent.h>
-#include <errno.h>
 
 /* IMC definitions */
 
@@ -48,7 +46,6 @@ static const char imc_name[] = "Attestation";
 
 #define IMC_VENDOR_ID                          PEN_TCG
 #define IMC_SUBTYPE                                    PA_SUBTYPE_TCG_PTS
-#define IMC_ATTESTATION_BUF_SIZE       32768
 
 static imc_agent_t *imc_attestation;
 
@@ -118,93 +115,6 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
 
 
 /**
- * Get Hash Measurement of a file
- */
-static TNC_Result hash_file(char *path, char *out)
-{
-       char buffer[IMC_ATTESTATION_BUF_SIZE];
-       FILE *file;
-       int bytes_read;
-       pts_meas_algorithms_t selected_algorithm;
-       hasher_t *hasher;
-       hash_algorithm_t hash_alg;
-       
-       /* Create a hasher */
-       selected_algorithm = PTS_MEAS_ALGO_SHA256; /* temporary fix, move to pts */
-       hash_alg = pts_meas_to_hash_algorithm(selected_algorithm);
-       hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
-       if (!hasher)
-       {
-               DBG1(DBG_IMC, "hasher %N not available", hash_algorithm_names, hash_alg);
-               return TNC_RESULT_FATAL;
-       }
-
-       file = fopen(path, "rb");
-       if (!file)
-       {
-               DBG1(DBG_IMC,"file '%s' can not be opened", path);
-               hasher->destroy(hasher);
-               return TNC_RESULT_FATAL;
-       }
-       while (TRUE)
-       {
-               bytes_read = fread(buffer, 1, sizeof(buffer), file);
-               if (bytes_read > 0)
-               {
-                       hasher->get_hash(hasher, chunk_create(buffer, bytes_read), NULL);
-               }
-               else
-               {
-                       hasher->get_hash(hasher, chunk_empty, out);
-                       break;
-               }
-       }
-       fclose(file);
-       hasher->destroy(hasher);
-
-       return TNC_RESULT_SUCCESS;
-}
-
-/**
- * Get hash of all the files in a directory
- */
-static TNC_Result hash_directory(char *path, linked_list_t *file_measurements)
-{
-       DIR *dir;
-       struct dirent *ent;
-       file_meas_entry_t *entry;
-       
-       file_measurements = linked_list_create();
-       entry = malloc_thing(file_meas_entry_t);
-       
-       dir = opendir(path);
-       if (dir == NULL)
-       {
-               DBG1(DBG_IMC, "opening directory '%s' failed: %s", path, strerror(errno));
-               return TNC_RESULT_FATAL;
-       }
-       while ((ent = readdir(dir)))
-       {
-               char *file_hash;
-               
-               if(hash_file(ent->d_name,file_hash) != TNC_RESULT_SUCCESS)
-               {
-                       DBG1(DBG_IMC, "Hashing the given file has failed");
-                       return TNC_RESULT_FATAL;
-               }
-               
-               entry->measurement = chunk_create(file_hash,strlen(file_hash));
-               entry->file_name_len = strlen(ent->d_name);
-               entry->file_name = chunk_create(ent->d_name,strlen(ent->d_name));
-               
-               file_measurements->insert_last(file_measurements,entry);
-       }
-       closedir(dir);
-       
-       return TNC_RESULT_SUCCESS;
-}
-
-/**
  * see section 3.7.3 of TCG TNC IF-IMC Specification 1.2
  */
 TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
@@ -344,7 +254,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        }
                                        else
                                        {
-                                               /* TODO send a TCG_PTS_HASH_ALG_NOT_SUPPORTED error */
+                                               /* TODO send a TCG_PTS_H_ALG_NOT_SUPPORTED error */
                                        }
                                        /* Send Measurement Algorithm Selection attribute */ 
                                        selected_algorithm = pts->get_meas_algorithm(pts);
@@ -424,7 +334,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                        
                                        if(directory_flag)
                                        {
-                                               if(hash_file(path.ptr,file_hash) != TNC_RESULT_SUCCESS)
+                                               if(pts->hash_file(pts,path.ptr,file_hash) != true)
                                                {
                                                        DBG1(DBG_IMC, "Hashing the given file has failed");
                                                        return TNC_RESULT_FATAL;
@@ -438,7 +348,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                enumerator_t *meas_enumerator;
                                                file_meas_entry_t *meas_entry;
                                                u_int64_t num_of_files = 0 ;
-                                               if(hash_directory(path.ptr, file_measurements) != TNC_RESULT_SUCCESS)
+                                               if(pts->hash_directory(pts, path.ptr, file_measurements) != true)
                                                {
                                                        DBG1(DBG_IMC, "Hashing the files in a given directory has failed");
                                                        return TNC_RESULT_FATAL;
index de54fee..1f57ad1 100644 (file)
 #include <trousers/tss.h>
 #include <trousers/trousers.h>
 
+#include <dirent.h>
+#include <errno.h>
+
+#define PTS_BUF_SIZE   32768
+
 typedef struct private_pts_t private_pts_t;
 
 /**
@@ -53,6 +58,7 @@ struct private_pts_t {
         * Contains a TPM_CAP_VERSION_INFO struct
         */
        chunk_t tpm_version_info;
+       
 };
 
 METHOD(pts_t, get_proto_caps, pts_proto_caps_flag_t,
@@ -139,6 +145,96 @@ METHOD(pts_t, set_tpm_version_info, void,
        print_tpm_version_info(this);
 }
 
+
+/**
+ * Get Hash Measurement of a file
+ */
+
+METHOD(pts_t, hash_file, bool,
+       private_pts_t *this, char *path, char *out)
+{
+       char buffer[PTS_BUF_SIZE];
+       FILE *file;
+       int bytes_read;
+       hasher_t *hasher;
+       hash_algorithm_t hash_alg;
+       
+       /* Create a hasher */
+       hash_alg = pts_meas_to_hash_algorithm(this->algorithm);
+       hasher = lib->crypto->create_hasher(lib->crypto, hash_alg);
+       if (!hasher)
+       {
+               DBG1(DBG_IMC, "hasher %N not available", hash_algorithm_names, hash_alg);
+               return false;
+       }
+
+       file = fopen(path, "rb");
+       if (!file)
+       {
+               DBG1(DBG_IMC,"file '%s' can not be opened", path);
+               hasher->destroy(hasher);
+               return false;
+       }
+       while (TRUE)
+       {
+               bytes_read = fread(buffer, 1, sizeof(buffer), file);
+               if (bytes_read > 0)
+               {
+                       hasher->get_hash(hasher, chunk_create(buffer, bytes_read), NULL);
+               }
+               else
+               {
+                       hasher->get_hash(hasher, chunk_empty, out);
+                       break;
+               }
+       }
+       fclose(file);
+       hasher->destroy(hasher);
+
+       return true;
+}
+
+/**
+ * Get hash of all the files in a directory
+ */
+
+METHOD(pts_t, hash_directory, bool,
+       private_pts_t *this, char *path, linked_list_t *file_measurements)
+{
+       DIR *dir;
+       struct dirent *ent;
+       file_meas_entry_t *entry;
+       
+       file_measurements = linked_list_create();
+       entry = malloc_thing(file_meas_entry_t);
+       
+       dir = opendir(path);
+       if (dir == NULL)
+       {
+               DBG1(DBG_IMC, "opening directory '%s' failed: %s", path, strerror(errno));
+               return false;
+       }
+       while ((ent = readdir(dir)))
+       {
+               char *file_hash;
+               
+               if(this->public.hash_file(&this->public,ent->d_name,file_hash) != true)
+               {
+                       DBG1(DBG_IMC, "Hashing the given file has failed");
+                       return false;
+               }
+               
+               entry->measurement = chunk_create(file_hash,strlen(file_hash));
+               entry->file_name_len = strlen(ent->d_name);
+               entry->file_name = chunk_create(ent->d_name,strlen(ent->d_name));
+               
+               file_measurements->insert_last(file_measurements,entry);
+       }
+       closedir(dir);
+       
+       return true;
+}
+
 METHOD(pts_t, destroy, void,
        private_pts_t *this)
 {
@@ -200,6 +296,8 @@ pts_t *pts_create(bool is_imc)
                        .set_meas_algorithm = _set_meas_algorithm,
                        .get_tpm_version_info = _get_tpm_version_info,
                        .set_tpm_version_info = _set_tpm_version_info,
+                       .hash_file = _hash_file,
+                       .hash_directory = _hash_directory,
                        .destroy = _destroy,
                },
                .proto_caps = PTS_PROTO_CAPS_V,
index 13bb813..7c14f41 100644 (file)
@@ -25,9 +25,30 @@ typedef struct pts_t pts_t;
 
 #include "pts_proto_caps.h"
 #include "pts_meas_algo.h"
+#include <utils/linked_list.h>
 
 #include <library.h>
 
+typedef struct measurement_req_entry_t measurement_req_entry_t;
+typedef struct file_meas_entry_t file_meas_entry_t;
+
+/**
+ * Struct to hold file or directory name with the request ID for Request File Measurement attribute
+ */
+struct measurement_req_entry_t {
+       char *path;
+       u_int16_t request_id;
+};
+
+/**
+ * File Measurement entry
+ */
+struct file_meas_entry_t {
+       chunk_t   measurement;
+       u_int16_t file_name_len;
+       chunk_t   file_name;
+};
+
 /**
  * Class implementing the TCG Platform Trust System (PTS)
  *
@@ -76,6 +97,24 @@ struct pts_t {
         * @param info                  chunk containing a TPM_CAP_VERSION_INFO struct 
         */
        void (*set_tpm_version_info)(pts_t *this, chunk_t info);
+       
+       /**
+        * Hash the given file
+        *
+        * @param path                  absolute path to file to be hashed
+        * @param out                   hash output value of a given file
+        * @return                      TRUE if hashing file was successful 
+        */
+       bool (*hash_file)(pts_t *this, char *path, char *out);
+       
+       /**
+        * Hash the given directory
+        *
+        * @param path                  absolute path to directory to be hashed
+        * @param file_measurements     list of hash output values of files in a given folder
+        * @return                      TRUE if hashing directory was successful 
+        */
+       bool (*hash_directory)(pts_t *this, char *path, linked_list_t *file_measurements);
 
        /**
         * Destroys a pts_t object.