Moved hashing functionalities to pts object

This commit is contained in:
Sansar Choinyambuu 2011-08-24 09:34:55 +02:00 committed by Andreas Steffen
parent a1ff28f582
commit 921b1022a5
3 changed files with 140 additions and 93 deletions

View 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;
@ -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;

View File

@ -21,6 +21,11 @@
#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,

View 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.