attest now maintains multiple versions of a file hash
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2013 Andreas Steffen
|
* Copyright (C) 2011-2014 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -144,9 +144,9 @@ static void do_args(int argc, char *argv[])
|
|||||||
{ "directory", required_argument, NULL, 'D' },
|
{ "directory", required_argument, NULL, 'D' },
|
||||||
{ "dir", required_argument, NULL, 'D' },
|
{ "dir", required_argument, NULL, 'D' },
|
||||||
{ "file", required_argument, NULL, 'F' },
|
{ "file", required_argument, NULL, 'F' },
|
||||||
{ "sha1-ima", no_argument, NULL, 'I' },
|
|
||||||
{ "package", required_argument, NULL, 'G' },
|
{ "package", required_argument, NULL, 'G' },
|
||||||
{ "key", required_argument, NULL, 'K' },
|
{ "key", required_argument, NULL, 'K' },
|
||||||
|
{ "measdir", required_argument, NULL, 'M' },
|
||||||
{ "owner", required_argument, NULL, 'O' },
|
{ "owner", required_argument, NULL, 'O' },
|
||||||
{ "product", required_argument, NULL, 'P' },
|
{ "product", required_argument, NULL, 'P' },
|
||||||
{ "relative", no_argument, NULL, 'R' },
|
{ "relative", no_argument, NULL, 'R' },
|
||||||
@@ -294,9 +294,6 @@ static void do_args(int argc, char *argv[])
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case 'I':
|
|
||||||
attest->set_algo(attest, PTS_MEAS_ALGO_SHA1_IMA);
|
|
||||||
continue;
|
|
||||||
case 'K':
|
case 'K':
|
||||||
{
|
{
|
||||||
chunk_t aik;
|
chunk_t aik;
|
||||||
@@ -308,6 +305,12 @@ static void do_args(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
case 'M':
|
||||||
|
if (!attest->set_meas_directory(attest, optarg))
|
||||||
|
{
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
case 'O':
|
case 'O':
|
||||||
attest->set_owner(attest, optarg);
|
attest->set_owner(attest, optarg);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -78,6 +78,11 @@ struct private_attest_db_t {
|
|||||||
*/
|
*/
|
||||||
int fid;
|
int fid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directory where file measurement are to be taken
|
||||||
|
*/
|
||||||
|
char *meas_dir;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AIK to be queried
|
* AIK to be queried
|
||||||
*/
|
*/
|
||||||
@@ -470,6 +475,22 @@ METHOD(attest_db_t, set_fid, bool,
|
|||||||
return this->fid > 0;
|
return this->fid > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(attest_db_t, set_meas_directory, bool,
|
||||||
|
private_attest_db_t *this, char *dir)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* remove trailing '/' character if not root directory */
|
||||||
|
len = strlen(dir);
|
||||||
|
if (len > 1 && dir[len-1] == '/')
|
||||||
|
{
|
||||||
|
dir[len-1] = '\0';
|
||||||
|
}
|
||||||
|
this->meas_dir = strdup(dir);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(attest_db_t, set_key, bool,
|
METHOD(attest_db_t, set_key, bool,
|
||||||
private_attest_db_t *this, chunk_t key, bool create)
|
private_attest_db_t *this, chunk_t key, bool create)
|
||||||
{
|
{
|
||||||
@@ -1568,12 +1589,13 @@ METHOD(attest_db_t, list_sessions, void,
|
|||||||
*/
|
*/
|
||||||
static bool insert_file_hash(private_attest_db_t *this,
|
static bool insert_file_hash(private_attest_db_t *this,
|
||||||
pts_meas_algorithms_t algo,
|
pts_meas_algorithms_t algo,
|
||||||
chunk_t measurement, int fid, bool ima,
|
chunk_t measurement, int fid,
|
||||||
int *hashes_added, int *hashes_updated)
|
int *hashes_added, int *hashes_updated)
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
chunk_t hash;
|
chunk_t hash;
|
||||||
char *label;
|
char *label;
|
||||||
|
bool insert = TRUE, update = FALSE;
|
||||||
|
|
||||||
label = "could not be created";
|
label = "could not be created";
|
||||||
|
|
||||||
@@ -1581,46 +1603,50 @@ static bool insert_file_hash(private_attest_db_t *this,
|
|||||||
"SELECT hash FROM file_hashes WHERE algo = ? "
|
"SELECT hash FROM file_hashes WHERE algo = ? "
|
||||||
"AND file = ? AND product = ? AND device = 0",
|
"AND file = ? AND product = ? AND device = 0",
|
||||||
DB_INT, algo, DB_UINT, fid, DB_UINT, this->pid, DB_BLOB);
|
DB_INT, algo, DB_UINT, fid, DB_UINT, this->pid, DB_BLOB);
|
||||||
|
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
printf("file_hashes query failed\n");
|
printf("file_hashes query failed\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (e->enumerate(e, &hash))
|
|
||||||
|
while (e->enumerate(e, &hash))
|
||||||
{
|
{
|
||||||
|
update = TRUE;
|
||||||
|
|
||||||
if (chunk_equals(measurement, hash))
|
if (chunk_equals(measurement, hash))
|
||||||
{
|
{
|
||||||
label = "exists and equals";
|
label = "exists and equals";
|
||||||
}
|
insert = FALSE;
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
if (this->db->execute(this->db, NULL,
|
|
||||||
"UPDATE file_hashes SET hash = ? WHERE algo = ? "
|
|
||||||
"AND file = ? AND product = ? and device = 0",
|
|
||||||
DB_BLOB, measurement, DB_INT, algo, DB_UINT, fid,
|
|
||||||
DB_UINT, this->pid) == 1)
|
|
||||||
{
|
|
||||||
label = "updated";
|
|
||||||
(*hashes_updated)++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
e->destroy(e);
|
||||||
|
|
||||||
|
if (insert)
|
||||||
{
|
{
|
||||||
if (this->db->execute(this->db, NULL,
|
if (this->db->execute(this->db, NULL,
|
||||||
"INSERT INTO file_hashes "
|
"INSERT INTO file_hashes "
|
||||||
"(file, product, device, algo, hash) "
|
"(file, product, device, algo, hash) "
|
||||||
"VALUES (?, ?, 0, ?, ?)",
|
"VALUES (?, ?, 0, ?, ?)",
|
||||||
DB_UINT, fid, DB_UINT, this->pid,
|
DB_UINT, fid, DB_UINT, this->pid,
|
||||||
DB_INT, algo, DB_BLOB, measurement) == 1)
|
DB_INT, algo, DB_BLOB, measurement) != 1)
|
||||||
|
{
|
||||||
|
printf("file_hash insertion failed\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (update)
|
||||||
|
{
|
||||||
|
label = "updated";
|
||||||
|
(*hashes_updated)++;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
label = "created";
|
label = "created";
|
||||||
(*hashes_added)++;
|
(*hashes_added)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
e->destroy(e);
|
printf(" %#B - %s\n", &measurement, label);
|
||||||
|
|
||||||
printf(" %#B - %s%s\n", &measurement, ima ? "ima - " : "", label);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1629,33 +1655,23 @@ static bool insert_file_hash(private_attest_db_t *this,
|
|||||||
*/
|
*/
|
||||||
static bool add_hash(private_attest_db_t *this)
|
static bool add_hash(private_attest_db_t *this)
|
||||||
{
|
{
|
||||||
char *pathname, *filename, *sep, *label, *pos;
|
char *pathname, *filename, *sep, *label;
|
||||||
char ima_buffer[IMA_MAX_NAME_LEN + 1];
|
|
||||||
chunk_t measurement, ima_template;
|
|
||||||
pts_file_meas_t *measurements;
|
pts_file_meas_t *measurements;
|
||||||
|
chunk_t measurement;
|
||||||
hasher_t *hasher = NULL;
|
hasher_t *hasher = NULL;
|
||||||
bool ima = FALSE;
|
|
||||||
int fid, files_added = 0, hashes_added = 0, hashes_updated = 0;
|
int fid, files_added = 0, hashes_added = 0, hashes_updated = 0;
|
||||||
int len, ima_hashes_added = 0, ima_hashes_updated = 0;
|
|
||||||
enumerator_t *enumerator, *e;
|
enumerator_t *enumerator, *e;
|
||||||
|
|
||||||
if (this->algo == PTS_MEAS_ALGO_SHA1_IMA)
|
if (!this->meas_dir)
|
||||||
{
|
{
|
||||||
ima = TRUE;
|
this->meas_dir = strdup(this->dir);
|
||||||
this->algo = PTS_MEAS_ALGO_SHA1;
|
|
||||||
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
|
|
||||||
if (!hasher)
|
|
||||||
{
|
|
||||||
printf("could not create hasher\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
sep = streq(this->dir, "/") ? "" : "/";
|
sep = streq(this->meas_dir, "/") ? "" : "/";
|
||||||
|
|
||||||
if (this->fid)
|
if (this->fid)
|
||||||
{
|
{
|
||||||
/* build pathname from directory path and relative filename */
|
/* build pathname from directory path and relative filename */
|
||||||
if (asprintf(&pathname, "%s%s%s", this->dir, sep, this->file) == -1)
|
if (asprintf(&pathname, "%s%s%s", this->meas_dir, sep, this->file) == -1)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1665,7 +1681,7 @@ static bool add_hash(private_attest_db_t *this)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
measurements = pts_file_meas_create_from_path(0, this->dir, TRUE,
|
measurements = pts_file_meas_create_from_path(0, this->meas_dir, TRUE,
|
||||||
TRUE, this->algo);
|
TRUE, this->algo);
|
||||||
}
|
}
|
||||||
if (!measurements)
|
if (!measurements)
|
||||||
@@ -1717,59 +1733,18 @@ static bool add_hash(private_attest_db_t *this)
|
|||||||
printf("%4d: %s - %s\n", fid, filename, label);
|
printf("%4d: %s - %s\n", fid, filename, label);
|
||||||
|
|
||||||
/* compute file measurement hash */
|
/* compute file measurement hash */
|
||||||
if (!insert_file_hash(this, this->algo, measurement, fid, FALSE,
|
if (!insert_file_hash(this, this->algo, measurement, fid,
|
||||||
&hashes_added, &hashes_updated))
|
&hashes_added, &hashes_updated))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!ima)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute IMA template hash */
|
|
||||||
pos = ima_buffer;
|
|
||||||
len = IMA_MAX_NAME_LEN;
|
|
||||||
if (!this->relative)
|
|
||||||
{
|
|
||||||
strncpy(pos, this->dir, len);
|
|
||||||
len = max(0, len - strlen(this->dir));
|
|
||||||
pos = ima_buffer + IMA_MAX_NAME_LEN - len;
|
|
||||||
strncpy(pos, sep, len);
|
|
||||||
len = max(0, len - strlen(sep));
|
|
||||||
pos = ima_buffer + IMA_MAX_NAME_LEN - len;
|
|
||||||
}
|
|
||||||
strncpy(pos, filename, len);
|
|
||||||
ima_buffer[IMA_MAX_NAME_LEN] = '\0';
|
|
||||||
ima_template = chunk_create(ima_buffer, sizeof(ima_buffer));
|
|
||||||
if (!hasher->get_hash(hasher, measurement, NULL) ||
|
|
||||||
!hasher->get_hash(hasher, ima_template, measurement.ptr))
|
|
||||||
{
|
|
||||||
printf("could not compute IMA template hash\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!insert_file_hash(this, PTS_MEAS_ALGO_SHA1_IMA, measurement, fid,
|
|
||||||
TRUE, &ima_hashes_added, &ima_hashes_updated))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
printf("%d measurements, added %d new files, %d file hashes",
|
printf("%d measurements, added %d new files, %d file hashes, "
|
||||||
measurements->get_file_count(measurements), files_added,
|
"updated %d file hashes\n",
|
||||||
hashes_added);
|
measurements->get_file_count(measurements),
|
||||||
if (ima)
|
files_added, hashes_added, hashes_updated);
|
||||||
{
|
|
||||||
printf(", %d ima hashes", ima_hashes_added);
|
|
||||||
hasher->destroy(hasher);
|
|
||||||
}
|
|
||||||
printf(", updated %d file hashes", hashes_updated);
|
|
||||||
if (ima)
|
|
||||||
{
|
|
||||||
printf(", %d ima hashes", ima_hashes_updated);
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
measurements->destroy(measurements);
|
measurements->destroy(measurements);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -1941,6 +1916,7 @@ METHOD(attest_db_t, destroy, void,
|
|||||||
free(this->version);
|
free(this->version);
|
||||||
free(this->file);
|
free(this->file);
|
||||||
free(this->dir);
|
free(this->dir);
|
||||||
|
free(this->meas_dir);
|
||||||
free(this->owner);
|
free(this->owner);
|
||||||
free(this->key.ptr);
|
free(this->key.ptr);
|
||||||
free(this);
|
free(this);
|
||||||
@@ -1961,6 +1937,7 @@ attest_db_t *attest_db_create(char *uri)
|
|||||||
.set_did = _set_did,
|
.set_did = _set_did,
|
||||||
.set_file = _set_file,
|
.set_file = _set_file,
|
||||||
.set_fid = _set_fid,
|
.set_fid = _set_fid,
|
||||||
|
.set_meas_directory = _set_meas_directory,
|
||||||
.set_key = _set_key,
|
.set_key = _set_key,
|
||||||
.set_kid = _set_kid,
|
.set_kid = _set_kid,
|
||||||
.set_package = _set_package,
|
.set_package = _set_package,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Andreas Steffen
|
* Copyright (C) 2011-2014 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -83,6 +83,14 @@ struct attest_db_t {
|
|||||||
*/
|
*/
|
||||||
bool (*set_fid)(attest_db_t *this, int fid);
|
bool (*set_fid)(attest_db_t *this, int fid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set path to directory where file[s] are to be measured
|
||||||
|
*
|
||||||
|
* @param meas_dir measurement directory
|
||||||
|
* @return TRUE if successful
|
||||||
|
*/
|
||||||
|
bool (*set_meas_directory)(attest_db_t *this, char *dir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set functional component to be queried
|
* Set functional component to be queried
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ do
|
|||||||
ipsec attest --add --product "$p" --$hash --dir /usr/lib/$a/samba
|
ipsec attest --add --product "$p" --$hash --dir /usr/lib/$a/samba
|
||||||
ipsec attest --add --product "$p" --$hash --dir /usr/lib/$a/sasl2
|
ipsec attest --add --product "$p" --$hash --dir /usr/lib/$a/sasl2
|
||||||
|
|
||||||
|
ipsec attest --add --product "$p" --$hash --file /init \
|
||||||
|
--measdir /usr/share/initramfs-tools
|
||||||
|
|
||||||
|
ipsec attest --add --product "$p" --$hash --file /scripts/functions \
|
||||||
|
--measdir /usr/share/initramfs-tools/scripts
|
||||||
|
|
||||||
for file in `find /usr/lib/evolution-data-server -name *.so`
|
for file in `find /usr/lib/evolution-data-server -name *.so`
|
||||||
do
|
do
|
||||||
ipsec attest --add --product "$p" --$hash --file $file
|
ipsec attest --add --product "$p" --$hash --file $file
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Andreas Steffen
|
* Copyright (C) 2011-2014 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -28,10 +28,7 @@ ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA256, PTS_MEAS_ALGO_SHA256,
|
|||||||
ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1, PTS_MEAS_ALGO_SHA1,
|
ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1, PTS_MEAS_ALGO_SHA1,
|
||||||
PTS_MEAS_ALGO_SHA256,
|
PTS_MEAS_ALGO_SHA256,
|
||||||
"SHA1");
|
"SHA1");
|
||||||
ENUM_NEXT(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1_IMA, PTS_MEAS_ALGO_SHA1_IMA,
|
ENUM_END(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1);
|
||||||
PTS_MEAS_ALGO_SHA1,
|
|
||||||
"SHA1-IMA");
|
|
||||||
ENUM_END(pts_meas_algorithm_names, PTS_MEAS_ALGO_SHA1_IMA);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011 Sansar Choinyambuu
|
* Copyright (C) 2011 Sansar Choinyambuu
|
||||||
|
* Copyright (C) 2011-2014 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -33,8 +34,7 @@ enum pts_meas_algorithms_t {
|
|||||||
PTS_MEAS_ALGO_NONE = 0,
|
PTS_MEAS_ALGO_NONE = 0,
|
||||||
PTS_MEAS_ALGO_SHA384 = (1<<13),
|
PTS_MEAS_ALGO_SHA384 = (1<<13),
|
||||||
PTS_MEAS_ALGO_SHA256 = (1<<14),
|
PTS_MEAS_ALGO_SHA256 = (1<<14),
|
||||||
PTS_MEAS_ALGO_SHA1 = (1<<15),
|
PTS_MEAS_ALGO_SHA1 = (1<<15)
|
||||||
PTS_MEAS_ALGO_SHA1_IMA = (1<<16), /* internal use only */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user