Skip to content

Commit

Permalink
Raise an error when using unsupported hash types
Browse files Browse the repository at this point in the history
The OVAL content can have a hash algorithm in `hash_type` element that
is allowed by the OVAL specification but isn't currently supported in
OpenSCAP. At this moment, this can happen if OpenSCAP is compiled
without SHA-1 or MD5 support by setting OPENSCAP_ENABLE_SHA1 or
OPENSCAP_ENABLE_MD5 to OFF. In this situation we should warn the user,
for example show a warning and add a message element to the OVAL
results.

To do that, we need to be able to iterate over all hash types specified
in the OVAL specification, not only over the supported ones, because we
need to distinguish between a no match, a match of supported algorithm
and a match of an unsupported algorithm. Therefore we need to list them
explicitly.

The CRAPI_INVALID value has been replaced by 0 because it used to be a
-1 but a negative value can't be compared with an enum. That would cause
a compiler warning.
  • Loading branch information
jan-cerny committed Jul 21, 2021
1 parent df30597 commit 741bffe
Showing 1 changed file with 69 additions and 40 deletions.
109 changes: 69 additions & 40 deletions src/OVAL/probes/independent/filehash58_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,22 @@
#include "util.h"
#include "probe/entcmp.h"
#include "filehash58_probe.h"
#include "oscap_helpers.h"

#define FILE_SEPARATOR '/'

#define CRAPI_INVALID -1
/* List of hash types listed in OVAL specification */
static const char *OVAL_FILEHASH58_HASH_TYPES[] = {
"MD5",
"SHA-1",
"SHA-224",
"SHA-256",
"SHA-384",
"SHA-512",
NULL
};

/* List of hash types supported by OpenSCAP */
static const struct oscap_string_map CRAPI_ALG_MAP[] = {
#ifdef OPENSCAP_ENABLE_MD5
{CRAPI_DIGEST_MD5, "MD5"},
Expand All @@ -71,7 +82,7 @@ static const struct oscap_string_map CRAPI_ALG_MAP[] = {
{CRAPI_DIGEST_SHA384, "SHA-384"},
{CRAPI_DIGEST_SHA512, "SHA-512"},
/* {CRAPI_DIGEST_RMD160, "RMD-160"}, OVAL doesn't support this */
{CRAPI_INVALID, NULL}
{0, NULL}
};

static const struct oscap_string_map CRAPI_ALG_MAP_SIZE[] = {
Expand Down Expand Up @@ -165,45 +176,64 @@ static int filehash58_cb(const char *prefix, const char *p, const char *f, const
probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
"Can't open \"%s\": errno=%d, %s.", pbuf, errno, strerror (errno));
probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
} else {
uint8_t hash_dst[1025];
size_t hash_dstlen = sizeof hash_dst;
char hash_str[2051];

crapi_alg_t hash_type;
probe_item_collect(ctx, itm);
return 0;
}

hash_type = oscap_string_to_enum(CRAPI_ALG_MAP, h);
hash_dstlen = oscap_string_to_enum(CRAPI_ALG_MAP_SIZE, h);
uint8_t hash_dst[1025];
size_t hash_dstlen = sizeof(hash_dst);
char hash_str[2051];
crapi_alg_t hash_type;

/*
* Compute hash value
*/
if (crapi_mdigest_fd (fd, 1, hash_type, hash_dst, &hash_dstlen) != 0) {
close (fd);
return (-1);
}
hash_type = oscap_string_to_enum(CRAPI_ALG_MAP, h);
if (hash_type == 0) {
char *msg = oscap_sprintf("This version of OpenSCAP doesn't support the '%s' hash algorithm.", h);
dW(msg);
itm = probe_item_create (OVAL_INDEPENDENT_FILE_HASH58, NULL,
"filepath", OVAL_DATATYPE_STRING, pbuf,
"path", OVAL_DATATYPE_STRING, p,
"filename", OVAL_DATATYPE_STRING, f,
"hash_type", OVAL_DATATYPE_STRING, h,
NULL);
probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR, msg);
free(msg);
probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
probe_item_collect(ctx, itm);
close(fd);
return 0;
}

hash_dstlen = oscap_string_to_enum(CRAPI_ALG_MAP_SIZE, h);

/*
* Compute hash value
*/
if (crapi_mdigest_fd(fd, 1, hash_type, hash_dst, &hash_dstlen) != 0) {
close (fd);
return (-1);
}

hash_str[0] = '\0';
mem2hex (hash_dst, hash_dstlen, hash_str, sizeof hash_str);
close (fd);

/*
* Create and add the item
*/
itm = probe_item_create(OVAL_INDEPENDENT_FILE_HASH58, NULL,
"filepath", OVAL_DATATYPE_STRING, pbuf,
"path", OVAL_DATATYPE_STRING, p,
"filename", OVAL_DATATYPE_STRING, f,
"hash_type",OVAL_DATATYPE_STRING, h,
"hash", OVAL_DATATYPE_STRING, hash_str,
NULL);
hash_str[0] = '\0';
mem2hex(hash_dst, hash_dstlen, hash_str, sizeof(hash_str));

if (hash_dstlen == 0) {
probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
"Unable to compute %s hash value of \"%s\".", h, pbuf);
probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
}
/*
* Create and add the item
*/
itm = probe_item_create(OVAL_INDEPENDENT_FILE_HASH58, NULL,
"filepath", OVAL_DATATYPE_STRING, pbuf,
"path", OVAL_DATATYPE_STRING, p,
"filename", OVAL_DATATYPE_STRING, f,
"hash_type",OVAL_DATATYPE_STRING, h,
"hash", OVAL_DATATYPE_STRING, hash_str,
NULL);

if (hash_dstlen == 0) {
probe_item_add_msg(itm, OVAL_MESSAGE_LEVEL_ERROR,
"Unable to compute %s hash value of \"%s\".", h, pbuf);
probe_item_setstatus(itm, SYSCHAR_STATUS_ERROR);
}

probe_item_collect(ctx, itm);
Expand Down Expand Up @@ -300,15 +330,14 @@ int filehash58_probe_main(probe_ctx *ctx, void *arg)
if ((ofts = oval_fts_open_prefixed(prefix, path, filename, filepath, behaviors, probe_ctx_getresult(ctx))) != NULL) {
while ((ofts_ent = oval_fts_read(ofts)) != NULL) {
/* find hash types to compare with entity, think "not satisfy" */
const struct oscap_string_map *p = CRAPI_ALG_MAP;
while (p->value != CRAPI_INVALID) {
SEXP_t *crapi_hash_type_sexp = SEXP_string_new(p->string, strlen(p->string));
if (probe_entobj_cmp(hash_type, crapi_hash_type_sexp) == OVAL_RESULT_TRUE) {
filehash58_cb(prefix, ofts_ent->path, ofts_ent->file, p->string, ctx);
for (int i = 0; OVAL_FILEHASH58_HASH_TYPES[i] != NULL; i++) {
const char *oval_filehash58_hash_type = OVAL_FILEHASH58_HASH_TYPES[i];
SEXP_t *oval_filehash58_hash_type_sexp = SEXP_string_new(oval_filehash58_hash_type, strlen(oval_filehash58_hash_type));
if (probe_entobj_cmp(hash_type, oval_filehash58_hash_type_sexp) == OVAL_RESULT_TRUE) {
filehash58_cb(prefix, ofts_ent->path, ofts_ent->file, oval_filehash58_hash_type, ctx);
}

SEXP_free(crapi_hash_type_sexp);
p++;
SEXP_free(oval_filehash58_hash_type_sexp);
}
oval_ftsent_free(ofts_ent);
}
Expand Down

0 comments on commit 741bffe

Please sign in to comment.