diff --git a/src/libimcv/plugins/imc_attestation/imc_attestation.c b/src/libimcv/plugins/imc_attestation/imc_attestation.c index b0ec084e2..64ea5596e 100644 --- a/src/libimcv/plugins/imc_attestation/imc_attestation.c +++ b/src/libimcv/plugins/imc_attestation/imc_attestation.c @@ -39,8 +39,6 @@ #include #include #include -#include -#include /* 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; @@ -117,93 +114,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 */ @@ -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; diff --git a/src/libimcv/tcg/pts/pts.c b/src/libimcv/tcg/pts/pts.c index de54fee3d..1f57ad1fa 100644 --- a/src/libimcv/tcg/pts/pts.c +++ b/src/libimcv/tcg/pts/pts.c @@ -21,6 +21,11 @@ #include #include +#include +#include + +#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, diff --git a/src/libimcv/tcg/pts/pts.h b/src/libimcv/tcg/pts/pts.h index 13bb81361..7c14f4193 100644 --- a/src/libimcv/tcg/pts/pts.h +++ b/src/libimcv/tcg/pts/pts.h @@ -25,9 +25,30 @@ typedef struct pts_t pts_t; #include "pts_proto_caps.h" #include "pts_meas_algo.h" +#include #include +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.