Moved hashing functionalities to pts object
This commit is contained in:
committed by
Andreas Steffen
parent
a1ff28f582
commit
921b1022a5
@@ -39,8 +39,6 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
#include <crypto/hashers/hasher.h>
|
#include <crypto/hashers/hasher.h>
|
||||||
#include <dirent.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
/* IMC definitions */
|
/* IMC definitions */
|
||||||
|
|
||||||
@@ -48,7 +46,6 @@ static const char imc_name[] = "Attestation";
|
|||||||
|
|
||||||
#define IMC_VENDOR_ID PEN_TCG
|
#define IMC_VENDOR_ID PEN_TCG
|
||||||
#define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS
|
#define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS
|
||||||
#define IMC_ATTESTATION_BUF_SIZE 32768
|
|
||||||
|
|
||||||
static imc_agent_t *imc_attestation;
|
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
|
* 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
|
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 */
|
/* Send Measurement Algorithm Selection attribute */
|
||||||
selected_algorithm = pts->get_meas_algorithm(pts);
|
selected_algorithm = pts->get_meas_algorithm(pts);
|
||||||
@@ -424,7 +334,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
|
|||||||
|
|
||||||
if(directory_flag)
|
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");
|
DBG1(DBG_IMC, "Hashing the given file has failed");
|
||||||
return TNC_RESULT_FATAL;
|
return TNC_RESULT_FATAL;
|
||||||
@@ -438,7 +348,7 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
|
|||||||
enumerator_t *meas_enumerator;
|
enumerator_t *meas_enumerator;
|
||||||
file_meas_entry_t *meas_entry;
|
file_meas_entry_t *meas_entry;
|
||||||
u_int64_t num_of_files = 0 ;
|
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");
|
DBG1(DBG_IMC, "Hashing the files in a given directory has failed");
|
||||||
return TNC_RESULT_FATAL;
|
return TNC_RESULT_FATAL;
|
||||||
|
|||||||
@@ -21,6 +21,11 @@
|
|||||||
#include <trousers/tss.h>
|
#include <trousers/tss.h>
|
||||||
#include <trousers/trousers.h>
|
#include <trousers/trousers.h>
|
||||||
|
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define PTS_BUF_SIZE 32768
|
||||||
|
|
||||||
typedef struct private_pts_t private_pts_t;
|
typedef struct private_pts_t private_pts_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,6 +58,7 @@ struct private_pts_t {
|
|||||||
* Contains a TPM_CAP_VERSION_INFO struct
|
* Contains a TPM_CAP_VERSION_INFO struct
|
||||||
*/
|
*/
|
||||||
chunk_t tpm_version_info;
|
chunk_t tpm_version_info;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(pts_t, get_proto_caps, pts_proto_caps_flag_t,
|
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);
|
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,
|
METHOD(pts_t, destroy, void,
|
||||||
private_pts_t *this)
|
private_pts_t *this)
|
||||||
{
|
{
|
||||||
@@ -200,6 +296,8 @@ pts_t *pts_create(bool is_imc)
|
|||||||
.set_meas_algorithm = _set_meas_algorithm,
|
.set_meas_algorithm = _set_meas_algorithm,
|
||||||
.get_tpm_version_info = _get_tpm_version_info,
|
.get_tpm_version_info = _get_tpm_version_info,
|
||||||
.set_tpm_version_info = _set_tpm_version_info,
|
.set_tpm_version_info = _set_tpm_version_info,
|
||||||
|
.hash_file = _hash_file,
|
||||||
|
.hash_directory = _hash_directory,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.proto_caps = PTS_PROTO_CAPS_V,
|
.proto_caps = PTS_PROTO_CAPS_V,
|
||||||
|
|||||||
@@ -25,9 +25,30 @@ typedef struct pts_t pts_t;
|
|||||||
|
|
||||||
#include "pts_proto_caps.h"
|
#include "pts_proto_caps.h"
|
||||||
#include "pts_meas_algo.h"
|
#include "pts_meas_algo.h"
|
||||||
|
#include <utils/linked_list.h>
|
||||||
|
|
||||||
#include <library.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)
|
* Class implementing the TCG Platform Trust System (PTS)
|
||||||
*
|
*
|
||||||
@@ -77,6 +98,24 @@ struct pts_t {
|
|||||||
*/
|
*/
|
||||||
void (*set_tpm_version_info)(pts_t *this, chunk_t info);
|
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.
|
* Destroys a pts_t object.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user