created libpts
This commit is contained in:
@@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pts.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
#include <trousers/tss.h>
|
||||
#include <trousers/trousers.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define PTS_BUF_SIZE 4096
|
||||
|
||||
typedef struct private_pts_t private_pts_t;
|
||||
|
||||
/**
|
||||
* Private data of a pts_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pts_t {
|
||||
|
||||
/**
|
||||
* Public pts_t interface.
|
||||
*/
|
||||
pts_t public;
|
||||
|
||||
/**
|
||||
* PTS Protocol Capabilities
|
||||
*/
|
||||
pts_proto_caps_flag_t proto_caps;
|
||||
|
||||
/**
|
||||
* PTS Measurement Algorithm
|
||||
*/
|
||||
pts_meas_algorithms_t algorithm;
|
||||
|
||||
/**
|
||||
* Platform and OS Info
|
||||
*/
|
||||
char *platform_info;
|
||||
|
||||
/**
|
||||
* Do we have an activated TPM
|
||||
*/
|
||||
bool has_tpm;
|
||||
|
||||
/**
|
||||
* Contains a TPM_CAP_VERSION_INFO struct
|
||||
*/
|
||||
chunk_t tpm_version_info;
|
||||
|
||||
/**
|
||||
* Contains a Attestation Identity Key or Certificate
|
||||
*/
|
||||
certificate_t *aik;
|
||||
|
||||
};
|
||||
|
||||
METHOD(pts_t, get_proto_caps, pts_proto_caps_flag_t,
|
||||
private_pts_t *this)
|
||||
{
|
||||
return this->proto_caps;
|
||||
}
|
||||
|
||||
METHOD(pts_t, set_proto_caps, void,
|
||||
private_pts_t *this, pts_proto_caps_flag_t flags)
|
||||
{
|
||||
this->proto_caps = flags;
|
||||
DBG2(DBG_IMC, "supported PTS protocol capabilities: %s%s%s%s%s",
|
||||
flags & PTS_PROTO_CAPS_C ? "C" : ".",
|
||||
flags & PTS_PROTO_CAPS_V ? "V" : ".",
|
||||
flags & PTS_PROTO_CAPS_D ? "D" : ".",
|
||||
flags & PTS_PROTO_CAPS_T ? "T" : ".",
|
||||
flags & PTS_PROTO_CAPS_X ? "X" : ".");
|
||||
}
|
||||
|
||||
METHOD(pts_t, get_meas_algorithm, pts_meas_algorithms_t,
|
||||
private_pts_t *this)
|
||||
{
|
||||
return this->algorithm;
|
||||
}
|
||||
|
||||
METHOD(pts_t, set_meas_algorithm, void,
|
||||
private_pts_t *this, pts_meas_algorithms_t algorithm)
|
||||
{
|
||||
hash_algorithm_t hash_alg;
|
||||
|
||||
hash_alg = pts_meas_to_hash_algorithm(algorithm);
|
||||
DBG2(DBG_IMC, "selected PTS measurement algorithm is %N",
|
||||
hash_algorithm_names, hash_alg);
|
||||
if (hash_alg != HASH_UNKNOWN)
|
||||
{
|
||||
this->algorithm = algorithm;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print TPM 1.2 Version Info
|
||||
*/
|
||||
static void print_tpm_version_info(private_pts_t *this)
|
||||
{
|
||||
TPM_CAP_VERSION_INFO versionInfo;
|
||||
UINT64 offset = 0;
|
||||
TSS_RESULT result;
|
||||
|
||||
result = Trspi_UnloadBlob_CAP_VERSION_INFO(&offset,
|
||||
this->tpm_version_info.ptr, &versionInfo);
|
||||
if (result != TSS_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "could not parse tpm version info: tss error 0x%x",
|
||||
result);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "TPM 1.2 Version Info: Chip Version: %hhu.%hhu.%hhu.%hhu,"
|
||||
" Spec Level: %hu, Errata Rev: %hhu, Vendor ID: %.4s",
|
||||
versionInfo.version.major, versionInfo.version.minor,
|
||||
versionInfo.version.revMajor, versionInfo.version.revMinor,
|
||||
versionInfo.specLevel, versionInfo.errataRev,
|
||||
versionInfo.tpmVendorID);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(pts_t, get_platform_info, char*,
|
||||
private_pts_t *this)
|
||||
{
|
||||
return this->platform_info;
|
||||
}
|
||||
|
||||
METHOD(pts_t, set_platform_info, void,
|
||||
private_pts_t *this, char *info)
|
||||
{
|
||||
free(this->platform_info);
|
||||
this->platform_info = strdup(info);
|
||||
}
|
||||
|
||||
METHOD(pts_t, get_tpm_version_info, bool,
|
||||
private_pts_t *this, chunk_t *info)
|
||||
{
|
||||
if (!this->has_tpm)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*info = this->tpm_version_info;
|
||||
print_tpm_version_info(this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(pts_t, set_tpm_version_info, void,
|
||||
private_pts_t *this, chunk_t info)
|
||||
{
|
||||
this->tpm_version_info = chunk_clone(info);
|
||||
print_tpm_version_info(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an AIK certificate or public key,
|
||||
* the certificate having precedence over the public key if both are present
|
||||
*/
|
||||
static void load_aik(private_pts_t *this)
|
||||
{
|
||||
char *cert_path, *key_path;
|
||||
|
||||
cert_path = lib->settings->get_str(lib->settings,
|
||||
"libimcv.plugins.imc-attestation.aik_cert", NULL);
|
||||
key_path = lib->settings->get_str(lib->settings,
|
||||
"libimcv.plugins.imc-attestation.aik_key", NULL);
|
||||
|
||||
if (cert_path)
|
||||
{
|
||||
this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
||||
CERT_X509, BUILD_FROM_FILE,
|
||||
cert_path, BUILD_END);
|
||||
if (this->aik)
|
||||
{
|
||||
DBG2(DBG_IMC, "loaded AIK certificate from '%s'", cert_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (key_path)
|
||||
{
|
||||
this->aik = lib->creds->create(lib->creds, CRED_CERTIFICATE,
|
||||
CERT_TRUSTED_PUBKEY, BUILD_FROM_FILE,
|
||||
key_path, BUILD_END);
|
||||
if (this->aik)
|
||||
{
|
||||
DBG2(DBG_IMC, "loaded AIK public key from '%s'", key_path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
DBG1(DBG_IMC, "neither AIK certificate nor public key is available");
|
||||
}
|
||||
|
||||
METHOD(pts_t, get_aik, certificate_t*,
|
||||
private_pts_t *this)
|
||||
{
|
||||
return this->aik;
|
||||
}
|
||||
|
||||
METHOD(pts_t, set_aik, void,
|
||||
private_pts_t *this, certificate_t *aik)
|
||||
{
|
||||
DESTROY_IF(this->aik);
|
||||
this->aik = aik->get_ref(aik);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a hash over a file
|
||||
*/
|
||||
static bool hash_file(hasher_t *hasher, char *pathname, u_char *hash)
|
||||
{
|
||||
u_char buffer[PTS_BUF_SIZE];
|
||||
FILE *file;
|
||||
int bytes_read;
|
||||
|
||||
file = fopen(pathname, "rb");
|
||||
if (!file)
|
||||
{
|
||||
DBG1(DBG_IMC," file '%s' can not be opened, %s", pathname,
|
||||
strerror(errno));
|
||||
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, hash);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the relative filename of a fully qualified file pathname
|
||||
*/
|
||||
static char* get_filename(char *pathname)
|
||||
{
|
||||
char *pos, *filename;
|
||||
|
||||
pos = filename = pathname;
|
||||
while (pos && *(++pos) != '\0')
|
||||
{
|
||||
filename = pos;
|
||||
pos = strchr(filename, '/');
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
METHOD(pts_t, do_measurements, pts_file_meas_t*,
|
||||
private_pts_t *this, u_int16_t request_id, char *pathname, bool is_directory)
|
||||
{
|
||||
hasher_t *hasher;
|
||||
hash_algorithm_t hash_alg;
|
||||
u_char hash[HASH_SIZE_SHA384];
|
||||
chunk_t measurement;
|
||||
pts_file_meas_t *measurements;
|
||||
|
||||
/* 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 NULL;
|
||||
}
|
||||
|
||||
/* Create a measurement object */
|
||||
measurements = pts_file_meas_create(request_id);
|
||||
|
||||
/* Link the hash to the measurement and set the measurement length */
|
||||
measurement = chunk_create(hash, hasher->get_hash_size(hasher));
|
||||
|
||||
if (is_directory)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
char *rel_name, *abs_name;
|
||||
struct stat st;
|
||||
|
||||
enumerator = enumerator_create_directory(pathname);
|
||||
if (!enumerator)
|
||||
{
|
||||
DBG1(DBG_IMC," directory '%s' can not be opened, %s", pathname,
|
||||
strerror(errno));
|
||||
hasher->destroy(hasher);
|
||||
measurements->destroy(measurements);
|
||||
return NULL;
|
||||
}
|
||||
while (enumerator->enumerate(enumerator, &rel_name, &abs_name, &st))
|
||||
{
|
||||
/* measure regular files only */
|
||||
if (S_ISREG(st.st_mode) && *rel_name != '.')
|
||||
{
|
||||
if (!hash_file(hasher, abs_name, hash))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
hasher->destroy(hasher);
|
||||
measurements->destroy(measurements);
|
||||
return NULL;
|
||||
}
|
||||
DBG2(DBG_IMC, " %#B for '%s'", &measurement, rel_name);
|
||||
measurements->add(measurements, rel_name, measurement);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *filename;
|
||||
|
||||
if (!hash_file(hasher, pathname, hash))
|
||||
{
|
||||
hasher->destroy(hasher);
|
||||
measurements->destroy(measurements);
|
||||
return NULL;
|
||||
}
|
||||
filename = get_filename(pathname);
|
||||
DBG2(DBG_IMC, " %#B for '%s'", &measurement, filename);
|
||||
measurements->add(measurements, filename, measurement);
|
||||
}
|
||||
hasher->destroy(hasher);
|
||||
|
||||
return measurements;
|
||||
}
|
||||
|
||||
METHOD(pts_t, destroy, void,
|
||||
private_pts_t *this)
|
||||
{
|
||||
DESTROY_IF(this->aik);
|
||||
free(this->platform_info);
|
||||
free(this->tpm_version_info.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine Linux distribution and hardware platform
|
||||
*/
|
||||
static char* extract_platform_info(void)
|
||||
{
|
||||
FILE *file;
|
||||
const char description[] = "Description:";
|
||||
char buf[BUF_LEN], *pos, *value;
|
||||
int value_len;
|
||||
|
||||
/* open a pipe stream for reading the output of the lsb_release commmand */
|
||||
file = popen("/usr/bin/lsb_release -d" , "r");
|
||||
if (!file)
|
||||
{
|
||||
DBG2(DBG_IMC, "failed to run lsb_release command");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read the output the lsb_release command */
|
||||
if (!fgets(buf, BUF_LEN-1, file))
|
||||
{
|
||||
DBG2(DBG_IMC, "failed to read output of lsb_release command");
|
||||
pclose(file);
|
||||
return NULL;
|
||||
}
|
||||
pclose(file);
|
||||
|
||||
pos = strstr(buf, description);
|
||||
if (!pos)
|
||||
{
|
||||
DBG2(DBG_IMC, "failed to find lsb_release description field");
|
||||
return NULL;
|
||||
}
|
||||
value = pos + strlen(description);
|
||||
|
||||
/* eat whitespace */
|
||||
while (*value == ' ' || *value == '\t')
|
||||
{
|
||||
value++;
|
||||
}
|
||||
|
||||
/* remove newline at the end and move value to the front of the buffer */
|
||||
value_len = strlen(value) - 1;
|
||||
memcpy(buf, value, value_len);
|
||||
buf[value_len] = ' ';
|
||||
|
||||
/* open a pipe stream for reading the output of the arch commmand */
|
||||
file = popen("/usr/bin/arch" , "r");
|
||||
if (!file)
|
||||
{
|
||||
DBG2(DBG_IMC, "failed to run arch command");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read the output the arch command */
|
||||
if (!fgets(buf + value_len + 1, BUF_LEN - value_len - 2, file))
|
||||
{
|
||||
DBG2(DBG_IMC, "failed to read output of arch command");
|
||||
pclose(file);
|
||||
return NULL;
|
||||
}
|
||||
pclose(file);
|
||||
|
||||
/* remove newline at the end */
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
|
||||
DBG1(DBG_IMV, "platform is '%s'", buf);
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a TPM by querying for TPM Version Info
|
||||
*/
|
||||
static bool has_tpm(private_pts_t *this)
|
||||
{
|
||||
TSS_HCONTEXT hContext;
|
||||
TSS_HTPM hTPM;
|
||||
TSS_RESULT result;
|
||||
|
||||
result = Tspi_Context_Create(&hContext);
|
||||
if (result != TSS_SUCCESS)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
result = Tspi_Context_Connect(hContext, NULL);
|
||||
if (result != TSS_SUCCESS)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
result = Tspi_Context_GetTpmObject (hContext, &hTPM);
|
||||
if (result != TSS_SUCCESS)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
result = Tspi_TPM_GetCapability(hTPM, TSS_TPMCAP_VERSION_VAL, 0, NULL,
|
||||
&this->tpm_version_info.len,
|
||||
&this->tpm_version_info.ptr);
|
||||
if (result != TSS_SUCCESS)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
this->tpm_version_info = chunk_clone(this->tpm_version_info);
|
||||
return TRUE;
|
||||
|
||||
err:
|
||||
DBG1(DBG_IMC, "TPM not available: tss error 0x%x", result);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pts_t *pts_create(bool is_imc)
|
||||
{
|
||||
private_pts_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_proto_caps = _get_proto_caps,
|
||||
.set_proto_caps = _set_proto_caps,
|
||||
.get_meas_algorithm = _get_meas_algorithm,
|
||||
.set_meas_algorithm = _set_meas_algorithm,
|
||||
.get_platform_info = _get_platform_info,
|
||||
.set_platform_info = _set_platform_info,
|
||||
.get_tpm_version_info = _get_tpm_version_info,
|
||||
.set_tpm_version_info = _set_tpm_version_info,
|
||||
.get_aik = _get_aik,
|
||||
.set_aik = _set_aik,
|
||||
.do_measurements = _do_measurements,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.proto_caps = PTS_PROTO_CAPS_V,
|
||||
.algorithm = PTS_MEAS_ALGO_SHA256,
|
||||
);
|
||||
|
||||
if (is_imc)
|
||||
{
|
||||
this->platform_info = extract_platform_info();
|
||||
|
||||
if (has_tpm(this))
|
||||
{
|
||||
this->has_tpm = TRUE;
|
||||
this->proto_caps |= PTS_PROTO_CAPS_T;
|
||||
load_aik(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->proto_caps |= PTS_PROTO_CAPS_T | PTS_PROTO_CAPS_C;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts pts
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_H_
|
||||
#define PTS_H_
|
||||
|
||||
typedef struct pts_t pts_t;
|
||||
|
||||
#include "pts_proto_caps.h"
|
||||
#include "pts_meas_algo.h"
|
||||
#include "pts_file_meas.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Class implementing the TCG Platform Trust System (PTS)
|
||||
*
|
||||
*/
|
||||
struct pts_t {
|
||||
|
||||
/**
|
||||
* Get PTS Protocol Capabilities
|
||||
*
|
||||
* @return protocol capabilities flags
|
||||
*/
|
||||
pts_proto_caps_flag_t (*get_proto_caps)(pts_t *this);
|
||||
|
||||
/**
|
||||
* Set PTS Protocol Capabilities
|
||||
*
|
||||
* @param flags protocol capabilities flags
|
||||
*/
|
||||
void (*set_proto_caps)(pts_t *this, pts_proto_caps_flag_t flags);
|
||||
|
||||
/**
|
||||
* Get PTS Measurement Algorithm
|
||||
*
|
||||
* @return measurement algorithm
|
||||
*/
|
||||
pts_meas_algorithms_t (*get_meas_algorithm)(pts_t *this);
|
||||
|
||||
/**
|
||||
* Set PTS Measurement Algorithm
|
||||
*
|
||||
* @param algorithm measurement algorithm
|
||||
*/
|
||||
void (*set_meas_algorithm)(pts_t *this, pts_meas_algorithms_t algorithm);
|
||||
|
||||
/**
|
||||
* Get Platform and OS Info
|
||||
*
|
||||
* @return platform and OS info
|
||||
*/
|
||||
char* (*get_platform_info)(pts_t *this);
|
||||
|
||||
/**
|
||||
* Set Platform and OS Info
|
||||
*
|
||||
* @param info platform and OS info
|
||||
*/
|
||||
void (*set_platform_info)(pts_t *this, char *info);
|
||||
|
||||
/**
|
||||
* Get TPM 1.2 Version Info
|
||||
*
|
||||
* @param info chunk containing a TPM_CAP_VERSION_INFO struct
|
||||
* @return TRUE if TPM Version Info available
|
||||
*/
|
||||
bool (*get_tpm_version_info)(pts_t *this, chunk_t *info);
|
||||
|
||||
/**
|
||||
* Set TPM 1.2 Version Info
|
||||
*
|
||||
* @param info chunk containing a TPM_CAP_VERSION_INFO struct
|
||||
*/
|
||||
void (*set_tpm_version_info)(pts_t *this, chunk_t info);
|
||||
|
||||
/**
|
||||
* Get Attestation Identity Certificate or Public Key
|
||||
*
|
||||
* @return AIK Certificate or Public Key
|
||||
*/
|
||||
certificate_t* (*get_aik)(pts_t *this);
|
||||
|
||||
/**
|
||||
* Set Attestation Identity Certificate or Public Key
|
||||
*
|
||||
* @param aik AIK Certificate or Public Key
|
||||
*/
|
||||
void (*set_aik)(pts_t *this, certificate_t *aik);
|
||||
|
||||
/**
|
||||
* Do PTS File Measurements
|
||||
*
|
||||
* @param request_id ID of PTS File Measurement Request
|
||||
* @param pathname Absolute pathname of file to be measured
|
||||
* @param is_directory if TRUE directory contents are measured
|
||||
* @return PTS File Measurements of NULL if FAILED
|
||||
*/
|
||||
pts_file_meas_t* (*do_measurements)(pts_t *this, u_int16_t request_id,
|
||||
char *pathname, bool is_directory);
|
||||
|
||||
/**
|
||||
* Destroys a pts_t object.
|
||||
*/
|
||||
void (*destroy)(pts_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an pts_t object
|
||||
*
|
||||
* @param is_imc TRUE if running on an IMC
|
||||
*/
|
||||
pts_t* pts_create(bool is_imc);
|
||||
|
||||
#endif /** PTS_H_ @}*/
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pts_creds.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <credentials/certificates/x509.h>
|
||||
#include <credentials/sets/mem_cred.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef struct private_pts_creds_t private_pts_creds_t;
|
||||
|
||||
/**
|
||||
* Private data of a pts_creds_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pts_creds_t {
|
||||
|
||||
/**
|
||||
* Public pts_creds_t interface.
|
||||
*/
|
||||
pts_creds_t public;
|
||||
|
||||
/**
|
||||
* Credential set
|
||||
*/
|
||||
mem_cred_t *creds;
|
||||
|
||||
};
|
||||
|
||||
METHOD(pts_creds_t, get_set, credential_set_t*,
|
||||
private_pts_creds_t *this)
|
||||
{
|
||||
return &this->creds->set;
|
||||
}
|
||||
|
||||
|
||||
METHOD(pts_creds_t, destroy, void,
|
||||
private_pts_creds_t *this)
|
||||
{
|
||||
this->creds->destroy(this->creds);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load trusted PTS CA certificates from a directory
|
||||
*/
|
||||
static void load_cacerts(private_pts_creds_t *this, char *path)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
struct stat st;
|
||||
char *file;
|
||||
|
||||
DBG1(DBG_TNC, "loading PTS ca certificates from '%s'", path);
|
||||
|
||||
enumerator = enumerator_create_directory(path);
|
||||
if (!enumerator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (enumerator->enumerate(enumerator, NULL, &file, &st))
|
||||
{
|
||||
certificate_t *cert;
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
{
|
||||
/* skip special file */
|
||||
continue;
|
||||
}
|
||||
cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
|
||||
BUILD_FROM_FILE, file, BUILD_END);
|
||||
if (cert)
|
||||
{
|
||||
x509_t *x509 = (x509_t*)cert;
|
||||
|
||||
if (!(x509->get_flags(x509) & X509_CA))
|
||||
{
|
||||
DBG1(DBG_TNC, " ca certificate \"%Y\" lacks ca basic constraint"
|
||||
", discarded", cert->get_subject(cert));
|
||||
cert->destroy(cert);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, " loaded ca certificate \"%Y\" from '%s'",
|
||||
cert->get_subject(cert), file);
|
||||
this->creds->add_cert(this->creds, TRUE, cert);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, " loading ca certificate from '%s' failed", file);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pts_creds_t *pts_creds_create(char *path)
|
||||
{
|
||||
private_pts_creds_t *this;
|
||||
|
||||
if (!path)
|
||||
{
|
||||
DBG1(DBG_TNC, "no PTS cacerts directory defined");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_set = _get_set,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.creds = mem_cred_create(),
|
||||
);
|
||||
|
||||
load_cacerts(this, path);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_creds pts_creds
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_CREDS_H_
|
||||
#define PTS_CREDS_H_
|
||||
|
||||
typedef struct pts_creds_t pts_creds_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <credentials/credential_set.h>
|
||||
|
||||
/**
|
||||
* Class implementing a PTS credentials set
|
||||
*/
|
||||
struct pts_creds_t {
|
||||
|
||||
/**
|
||||
* Get the credential set
|
||||
*
|
||||
* @return credential set
|
||||
*/
|
||||
credential_set_t* (*get_set)(pts_creds_t *this);
|
||||
|
||||
/**
|
||||
* Destroys a pts_creds_t object.
|
||||
*/
|
||||
void (*destroy)(pts_creds_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an pts_creds_t object
|
||||
*
|
||||
* @param path path to the PTS cacerts directory
|
||||
*/
|
||||
pts_creds_t* pts_creds_create(char *path);
|
||||
|
||||
#endif /** PTS_CREDS_H_ @}*/
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pts_database.h"
|
||||
|
||||
#include <debug.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
|
||||
typedef struct private_pts_database_t private_pts_database_t;
|
||||
|
||||
/**
|
||||
* Private data of a pts_database_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pts_database_t {
|
||||
|
||||
/**
|
||||
* Public pts_database_t interface.
|
||||
*/
|
||||
pts_database_t public;
|
||||
|
||||
/**
|
||||
* database instance
|
||||
*/
|
||||
database_t *db;
|
||||
|
||||
};
|
||||
|
||||
METHOD(pts_database_t, create_file_enumerator, enumerator_t*,
|
||||
private_pts_database_t *this, char *product)
|
||||
{
|
||||
enumerator_t *e;
|
||||
|
||||
/* look for all entries belonging to a product in the files table */
|
||||
e = this->db->query(this->db,
|
||||
"SELECT f.id, f.type, f.path FROM files AS f "
|
||||
"JOIN product_file AS pf ON f.id = pf.file "
|
||||
"JOIN products AS p ON p.id = pf.product "
|
||||
"WHERE p.name = ?",
|
||||
DB_TEXT, product, DB_INT, DB_INT, DB_TEXT);
|
||||
return e;
|
||||
}
|
||||
|
||||
METHOD(pts_database_t, create_hash_enumerator, enumerator_t*,
|
||||
private_pts_database_t *this, char *product, pts_meas_algorithms_t algo,
|
||||
int id, bool is_dir)
|
||||
{
|
||||
enumerator_t *e;
|
||||
|
||||
if (is_dir)
|
||||
{
|
||||
e = this->db->query(this->db,
|
||||
"SELECT f.path, 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 fh.directory = ? AND fh.algo = ? "
|
||||
"ORDER BY f.path",
|
||||
DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_TEXT, DB_BLOB);
|
||||
}
|
||||
else
|
||||
{
|
||||
e = this->db->query(this->db,
|
||||
"SELECT f.path, 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 fh.file = ? AND fh.algo = ?",
|
||||
DB_TEXT, product, DB_INT, id, DB_INT, algo, DB_TEXT, DB_BLOB);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
METHOD(pts_database_t, destroy, void,
|
||||
private_pts_database_t *this)
|
||||
{
|
||||
this->db->destroy(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pts_database_t *pts_database_create(char *uri)
|
||||
{
|
||||
private_pts_database_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.create_file_enumerator = _create_file_enumerator,
|
||||
.create_hash_enumerator = _create_hash_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.db = lib->db->create(lib->db, uri),
|
||||
);
|
||||
|
||||
if (!this->db)
|
||||
{
|
||||
DBG1(DBG_TNC, "failed to connect to PTS file measurement database '%s'",
|
||||
uri);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_database pts_database
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_DATABASE_H_
|
||||
#define PTS_DATABASE_H_
|
||||
|
||||
typedef struct pts_database_t pts_database_t;
|
||||
|
||||
#include "pts_meas_algo.h"
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Class implementing the PTS File Measurement database
|
||||
*
|
||||
*/
|
||||
struct pts_database_t {
|
||||
|
||||
/**
|
||||
* Get files to be measured by PTS
|
||||
*
|
||||
* @param product software product (os, vpn client, etc.)
|
||||
* @return enumerator over all matching files
|
||||
*/
|
||||
enumerator_t* (*create_file_enumerator)(pts_database_t *this, char *product);
|
||||
|
||||
/**
|
||||
* Get stored measurement hash for single file or directory entries
|
||||
*
|
||||
* @param product software product (os, vpn client, etc.)
|
||||
* @param algo hash algorithm used for measurement
|
||||
* @param id primary key of measured file/directory
|
||||
* @param is_dir TRUE if directory was measured
|
||||
* @return enumerator over all matching measurement hashes
|
||||
*/
|
||||
enumerator_t* (*create_hash_enumerator)(pts_database_t *this, char *product,
|
||||
pts_meas_algorithms_t algo,
|
||||
int id, bool is_dir);
|
||||
|
||||
/**
|
||||
* Destroys a pts_database_t object.
|
||||
*/
|
||||
void (*destroy)(pts_database_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an pts_database_t object
|
||||
*
|
||||
* @param uri database uri
|
||||
*/
|
||||
pts_database_t* pts_database_create(char *uri);
|
||||
|
||||
#endif /** PTS_DATABASE_H_ @}*/
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pts_error.h"
|
||||
|
||||
#include <bio/bio_writer.h>
|
||||
#include <ietf/ietf_attr_pa_tnc_error.h>
|
||||
|
||||
ENUM(pts_error_code_names, TCG_PTS_RESERVED_ERROR, TCG_PTS_UNABLE_DET_PCR,
|
||||
"Reserved Error",
|
||||
"Hash Algorithm Not Supported",
|
||||
"Invalid Path",
|
||||
"File Not Found",
|
||||
"Registry Not Supported",
|
||||
"Registry Key Not Found",
|
||||
"D-H Group Not Supported",
|
||||
"DH-PN Nonce Not Acceptable",
|
||||
"Invalid Functional Name Family",
|
||||
"TPM Version Information Unavailable",
|
||||
"Invalid File Pathname Delimiter",
|
||||
"PTS Operation Not Supported",
|
||||
"Unable To Update Reference Manifest",
|
||||
"Unable To Perform Local Validation",
|
||||
"Unable To Collect Current Evidence",
|
||||
"Unable To Determine Transitive Trust Chain",
|
||||
"Unable To Determine PCR"
|
||||
);
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
chunk_t msg_info;
|
||||
pa_tnc_attr_t *attr;
|
||||
|
||||
writer = bio_writer_create(4);
|
||||
writer->write_uint16(writer, 0x0000);
|
||||
writer->write_uint16(writer, algorithms);
|
||||
msg_info = writer->get_buf(writer);
|
||||
attr = ietf_attr_pa_tnc_error_create(PEN_TCG, TCG_PTS_HASH_ALG_NOT_SUPPORTED,
|
||||
msg_info);
|
||||
writer->destroy(writer);
|
||||
|
||||
return attr;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_error pts_error
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_ERROR_H_
|
||||
#define PTS_ERROR_H_
|
||||
|
||||
typedef enum pts_error_code_t pts_error_code_t;
|
||||
|
||||
#include "pts_meas_algo.h"
|
||||
#include "pa_tnc/pa_tnc_attr.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* PTS Attestation Error Codes
|
||||
* see section 3.14.2 of PTS Protocol: Binding to TNC IF-M Specification
|
||||
*/
|
||||
enum pts_error_code_t {
|
||||
TCG_PTS_RESERVED_ERROR = 0,
|
||||
TCG_PTS_HASH_ALG_NOT_SUPPORTED = 1,
|
||||
TCG_PTS_INVALID_PATH = 2,
|
||||
TCG_PTS_FILE_NOT_FOUND = 3,
|
||||
TCG_PTS_REG_NOT_SUPPORTED = 4,
|
||||
TCG_PTS_REG_KEY_NOT_FOUND = 5,
|
||||
TCG_PTS_DH_GRPS_NOT_SUPPORTED = 6,
|
||||
TCG_PTS_BAD_NONCE_LENGTH = 7,
|
||||
TCG_PTS_INVALID_NAME_FAM = 8,
|
||||
TCG_PTS_TPM_VERS_NOT_SUPPORTED = 9,
|
||||
TCG_PTS_INVALID_DELIMITER = 10,
|
||||
TCG_PTS_OPERATION_NOT_SUPPORTED = 11,
|
||||
TCG_PTS_RM_ERROR = 12,
|
||||
TCG_PTS_UNABLE_LOCAL_VAL = 13,
|
||||
TCG_PTS_UNABLE_CUR_EVID = 14,
|
||||
TCG_PTS_UNABLE_DET_TTC = 15,
|
||||
TCG_PTS_UNABLE_DET_PCR = 16,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for pts_error_code_t.
|
||||
*/
|
||||
extern enum_name_t *pts_error_code_names;
|
||||
|
||||
/**
|
||||
* Creates a PTS Hash Algorithm Not Supported Error Attribute
|
||||
* see section 4.2.2 of PTS Protocol: Binding to TNC IF-M Specification
|
||||
*
|
||||
* @param algorithms supported measurement hash algorithms
|
||||
*/
|
||||
pa_tnc_attr_t* pts_hash_alg_error_create(pts_meas_algorithms_t algorithms);
|
||||
|
||||
#endif /** PTS_ERROR_H_ @}*/
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pts_file_meas.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct private_pts_file_meas_t private_pts_file_meas_t;
|
||||
|
||||
/**
|
||||
* Private data of a pts_file_meas_t object.
|
||||
*
|
||||
*/
|
||||
struct private_pts_file_meas_t {
|
||||
|
||||
/**
|
||||
* Public pts_file_meas_t interface.
|
||||
*/
|
||||
pts_file_meas_t public;
|
||||
|
||||
/**
|
||||
* ID of PTS File Measurement Request
|
||||
*/
|
||||
u_int16_t request_id;
|
||||
|
||||
/**
|
||||
* List of File Measurements
|
||||
*/
|
||||
linked_list_t *list;
|
||||
};
|
||||
|
||||
typedef struct entry_t entry_t;
|
||||
|
||||
/**
|
||||
* PTS File Measurement entry
|
||||
*/
|
||||
struct entry_t {
|
||||
char *filename;
|
||||
chunk_t measurement;
|
||||
};
|
||||
|
||||
/**
|
||||
* Free an entry_t object
|
||||
*/
|
||||
static void free_entry(entry_t *entry)
|
||||
{
|
||||
if (entry)
|
||||
{
|
||||
free(entry->filename);
|
||||
free(entry->measurement.ptr);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, get_request_id, u_int16_t,
|
||||
private_pts_file_meas_t *this)
|
||||
{
|
||||
return this->request_id;
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, get_file_count, int,
|
||||
private_pts_file_meas_t *this)
|
||||
{
|
||||
return this->list->get_count(this->list);
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, add, void,
|
||||
private_pts_file_meas_t *this, char *filename, chunk_t measurement)
|
||||
{
|
||||
entry_t *entry;
|
||||
|
||||
entry = malloc_thing(entry_t);
|
||||
entry->filename = strdup(filename);
|
||||
entry->measurement = chunk_clone(measurement);
|
||||
|
||||
this->list->insert_last(this->list, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerate file measurement entries
|
||||
*/
|
||||
static bool entry_filter(void *null, entry_t **entry, char **filename,
|
||||
void *i2, chunk_t *measurement)
|
||||
{
|
||||
*filename = (*entry)->filename;
|
||||
*measurement = (*entry)->measurement;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, create_enumerator, enumerator_t*,
|
||||
private_pts_file_meas_t *this)
|
||||
{
|
||||
return enumerator_create_filter(this->list->create_enumerator(this->list),
|
||||
(void*)entry_filter, NULL, NULL);
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, verify, bool,
|
||||
private_pts_file_meas_t *this, enumerator_t *e_hash, bool is_dir)
|
||||
{
|
||||
char *filename;
|
||||
chunk_t measurement;
|
||||
entry_t *entry;
|
||||
enumerator_t *enumerator;
|
||||
bool found, success = TRUE;
|
||||
|
||||
while (e_hash->enumerate(e_hash, &filename, &measurement))
|
||||
{
|
||||
found = FALSE;
|
||||
|
||||
enumerator = this->list->create_enumerator(this->list);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (!is_dir || streq(filename, entry->filename))
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
DBG1(DBG_TNC, " no measurement found for '%s'", filename);
|
||||
success = FALSE;
|
||||
continue;
|
||||
}
|
||||
if (chunk_equals(measurement, entry->measurement))
|
||||
{
|
||||
DBG2(DBG_TNC, " %#B for '%s' is ok", &measurement, filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_TNC, " %#B for '%s' is incorrect", &measurement, filename);
|
||||
success = FALSE;
|
||||
}
|
||||
if (!is_dir)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
METHOD(pts_file_meas_t, destroy, void,
|
||||
private_pts_file_meas_t *this)
|
||||
{
|
||||
this->list->destroy_function(this->list, (void *)free_entry);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
pts_file_meas_t *pts_file_meas_create(u_int16_t request_id)
|
||||
{
|
||||
private_pts_file_meas_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.get_request_id = _get_request_id,
|
||||
.get_file_count = _get_file_count,
|
||||
.add = _add,
|
||||
.create_enumerator = _create_enumerator,
|
||||
.verify = _verify,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.request_id = request_id,
|
||||
.list = linked_list_create(),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_file_meas pts_file_meas
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_FILE_MEAS_H_
|
||||
#define PTS_FILE_MEAS_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct pts_file_meas_t pts_file_meas_t;
|
||||
|
||||
/**
|
||||
* Class storing PTS File Measurements
|
||||
*/
|
||||
struct pts_file_meas_t {
|
||||
|
||||
/**
|
||||
* Get the ID of the PTS File Measurement Request
|
||||
*
|
||||
* @return ID of PTS File Measurement Request
|
||||
*/
|
||||
u_int16_t (*get_request_id)(pts_file_meas_t *this);
|
||||
|
||||
/**
|
||||
* Get the number of measured files
|
||||
*
|
||||
* @return Number of measured files
|
||||
*/
|
||||
int (*get_file_count)(pts_file_meas_t *this);
|
||||
|
||||
/**
|
||||
* Add a PTS File Measurement
|
||||
*
|
||||
* @param filename Name of measured file or directory
|
||||
* @param measurement PTS Measurement hash
|
||||
*/
|
||||
void (*add)(pts_file_meas_t *this, char *filename, chunk_t measurement);
|
||||
|
||||
/**
|
||||
* Create a PTS File Measurement enumerator
|
||||
*
|
||||
* @return Enumerator returning filename and measurement
|
||||
*/
|
||||
enumerator_t* (*create_enumerator)(pts_file_meas_t *this);
|
||||
|
||||
/**
|
||||
* Verify stored hashes against PTS File Measurements
|
||||
*
|
||||
* @param e_hash Hash enumerator
|
||||
* @paraem is_dir TRUE for directory contents hashes
|
||||
* @return TRUE if all hashes match a measurement
|
||||
*/
|
||||
bool (*verify)(pts_file_meas_t *this, enumerator_t *e_hash, bool is_dir);
|
||||
|
||||
/**
|
||||
* Destroys a pts_file_meas_t object.
|
||||
*/
|
||||
void (*destroy)(pts_file_meas_t *this);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a pts_file_meas_t object
|
||||
*
|
||||
* @param request_id ID of PTS File Measurement Request
|
||||
*/
|
||||
pts_file_meas_t* pts_file_meas_create(u_int16_t request_id);
|
||||
|
||||
#endif /** PTS_FILE_MEAS_H_ @}*/
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_funct_comp_name pts_funct_comp_name
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_FUNCT_COMP_NAME_H_
|
||||
#define PTS_FUNCT_COMP_NAME_H_
|
||||
|
||||
typedef enum pts_funct_comp_type_t pts_funct_comp_type_t;
|
||||
typedef enum pts_funct_comp_name_t pts_funct_comp_name_t;
|
||||
typedef struct pts_qualifier_t pts_qualifier_t;
|
||||
|
||||
/**
|
||||
* PTS Component Functional Type for Qualifier field
|
||||
*/
|
||||
enum pts_funct_comp_type_t {
|
||||
/** Unknown */
|
||||
PTS_FUNC_COMP_TYPE_UNKNOWN = 0x0,
|
||||
/** Trusted Platform */
|
||||
PTS_FUNC_COMP_TYPE_TRUSTED = 0x1,
|
||||
/** Operating System */
|
||||
PTS_FUNC_COMP_TYPE_OS = 0x2,
|
||||
/** Graphical User Interface */
|
||||
PTS_FUNC_COMP_TYPE_GUI = 0x3,
|
||||
/** Application */
|
||||
PTS_FUNC_COMP_TYPE_APP = 0x4,
|
||||
/** Networking */
|
||||
PTS_FUNC_COMP_TYPE_NET = 0x5,
|
||||
/** Library */
|
||||
PTS_FUNC_COMP_TYPE_LIB = 0x6,
|
||||
/** TNC Defined Component */
|
||||
PTS_FUNC_COMP_TYPE_TNC = 0x7,
|
||||
/** All matching Components */
|
||||
PTS_FUNC_COMP_TYPE_ALL = 0xF,
|
||||
};
|
||||
|
||||
/**
|
||||
* PTS Component Functional Name Binary Enumeration
|
||||
*/
|
||||
enum pts_funct_comp_name_t {
|
||||
/** Ignore */
|
||||
PTS_FUNC_COMP_NAME_IGNORE = 0x0000,
|
||||
/** CRTM */
|
||||
PTS_FUNC_COMP_NAME_CRTM = 0x0001,
|
||||
/** BIOS */
|
||||
PTS_FUNC_COMP_NAME_BIOS = 0x0002,
|
||||
/** Platform Extensions */
|
||||
PTS_FUNC_COMP_NAME_PLATFORM_EXT = 0x0003,
|
||||
/** Motherboard firmware */
|
||||
PTS_FUNC_COMP_NAME_BOARD = 0x0004,
|
||||
/** Initial Program Loader */
|
||||
PTS_FUNC_COMP_NAME_INIT_LOADER = 0x0005,
|
||||
/** Option ROMs */
|
||||
PTS_FUNC_COMP_NAME_OPT_ROMS = 0x0006,
|
||||
};
|
||||
|
||||
/**
|
||||
* Qualifier for Functional Component
|
||||
*/
|
||||
struct pts_qualifier_t {
|
||||
bool kernel;
|
||||
bool sub_component;
|
||||
pts_funct_comp_type_t type;
|
||||
};
|
||||
|
||||
#endif /** PTS_FUNCT_COMP_NAME_H_ @}*/
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "pts_meas_algo.h"
|
||||
|
||||
#include <debug.h>
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
bool pts_meas_probe_algorithms(pts_meas_algorithms_t *algorithms)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
hash_algorithm_t hash_alg;
|
||||
const char *plugin_name;
|
||||
char format1[] = " %s PTS measurement algorithm %N[%s] available";
|
||||
char format2[] = " %s PTS measurement algorithm %N not available";
|
||||
|
||||
*algorithms = 0;
|
||||
|
||||
enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
|
||||
while (enumerator->enumerate(enumerator, &hash_alg, &plugin_name))
|
||||
{
|
||||
if (hash_alg == HASH_SHA1)
|
||||
{
|
||||
*algorithms |= PTS_MEAS_ALGO_SHA1;
|
||||
DBG2(DBG_TNC, format1, "mandatory", hash_algorithm_names, hash_alg,
|
||||
plugin_name);
|
||||
}
|
||||
else if (hash_alg == HASH_SHA256)
|
||||
{
|
||||
*algorithms |= PTS_MEAS_ALGO_SHA256;
|
||||
DBG2(DBG_TNC, format1, "mandatory", hash_algorithm_names, hash_alg,
|
||||
plugin_name);
|
||||
}
|
||||
else if (hash_alg == HASH_SHA384)
|
||||
{
|
||||
*algorithms |= PTS_MEAS_ALGO_SHA384;
|
||||
DBG2(DBG_TNC, format1, "optional ", hash_algorithm_names, hash_alg,
|
||||
plugin_name);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!(*algorithms & PTS_MEAS_ALGO_SHA384))
|
||||
{
|
||||
DBG1(DBG_TNC, format2, "optional ", hash_algorithm_names, HASH_SHA384);
|
||||
}
|
||||
if ((*algorithms & PTS_MEAS_ALGO_SHA1) &&
|
||||
(*algorithms & PTS_MEAS_ALGO_SHA256))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (!(*algorithms & PTS_MEAS_ALGO_SHA1))
|
||||
{
|
||||
DBG1(DBG_TNC, format2, "mandatory", hash_algorithm_names, HASH_SHA1);
|
||||
}
|
||||
if (!(*algorithms & PTS_MEAS_ALGO_SHA256))
|
||||
{
|
||||
DBG1(DBG_TNC, format2, "mandatory", hash_algorithm_names, HASH_SHA256);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
hash_algorithm_t pts_meas_to_hash_algorithm(pts_meas_algorithms_t algorithm)
|
||||
{
|
||||
switch (algorithm)
|
||||
{
|
||||
case PTS_MEAS_ALGO_SHA1:
|
||||
return HASH_SHA1;
|
||||
case PTS_MEAS_ALGO_SHA256:
|
||||
return HASH_SHA256;
|
||||
case PTS_MEAS_ALGO_SHA384:
|
||||
return HASH_SHA384;
|
||||
default:
|
||||
return HASH_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_meas_algo pts_meas_algo
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_MEAS_ALGO_H_
|
||||
#define PTS_MEAS_ALGO_H_
|
||||
|
||||
#include <library.h>
|
||||
#include <crypto/hashers/hasher.h>
|
||||
|
||||
typedef enum pts_meas_algorithms_t pts_meas_algorithms_t;
|
||||
|
||||
/**
|
||||
* PTS Measurement Algorithms
|
||||
*/
|
||||
enum pts_meas_algorithms_t {
|
||||
PTS_MEAS_ALGO_SHA1 = (1<<15),
|
||||
PTS_MEAS_ALGO_SHA256 = (1<<14),
|
||||
PTS_MEAS_ALGO_SHA384 = (1<<13),
|
||||
};
|
||||
|
||||
/**
|
||||
* Diffie-Hellman Hash Algorithm Values
|
||||
* see section 3.8.5 of PTS Protocol: Binding to TNC IF-M Specification
|
||||
*
|
||||
* 1
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* |1|2|3|R|R|R|R|R|R|R|R|R|R|R|R|R|
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Probe available PTS measurement algorithms
|
||||
*
|
||||
* @param algorithms set of available algorithms
|
||||
* @return TRUE if mandatory algorithms are available
|
||||
*/
|
||||
bool pts_meas_probe_algorithms(pts_meas_algorithms_t *algorithms);
|
||||
|
||||
/**
|
||||
* Convert pts_meas_algorithms_t to hash_algorithm_t
|
||||
*
|
||||
* @param algorithm PTS measurement algorithm type
|
||||
* @return libstrongswan hash algorithm type
|
||||
*/
|
||||
hash_algorithm_t pts_meas_to_hash_algorithm(pts_meas_algorithms_t algorithm);
|
||||
|
||||
#endif /** PTS_MEAS_ALGO_H_ @}*/
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Sansar Choinyambuu
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup pts_proto_caps pts_proto_caps
|
||||
* @{ @ingroup pts
|
||||
*/
|
||||
|
||||
#ifndef PTS_PROTO_CAPS_H_
|
||||
#define PTS_PROTO_CAPS_H_
|
||||
|
||||
typedef enum pts_proto_caps_flag_t pts_proto_caps_flag_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* PTS Protocol Capabilities Flags
|
||||
*/
|
||||
enum pts_proto_caps_flag_t {
|
||||
/** XML based Evidence Support flag */
|
||||
PTS_PROTO_CAPS_X = (1<<0),
|
||||
/** Trusted Platform Evidence flag */
|
||||
PTS_PROTO_CAPS_T = (1<<1),
|
||||
/** DH Nonce Negotiation Support flag */
|
||||
PTS_PROTO_CAPS_D = (1<<2),
|
||||
/** Verification Support flag */
|
||||
PTS_PROTO_CAPS_V = (1<<3),
|
||||
/** Current (In-Memory) Evidence Support flag */
|
||||
PTS_PROTO_CAPS_C = (1<<4),
|
||||
};
|
||||
|
||||
#endif /** PTS_PROTO_CAPS_H_ @}*/
|
||||
Reference in New Issue
Block a user