From 0ad2c3da34827b68c4f524c0c50f223746af91a5 Mon Sep 17 00:00:00 2001 From: pcarana Date: Tue, 24 Mar 2020 18:39:01 -0600 Subject: [PATCH] Add new incidences regarding manifest validation. -Related to #28. -'incid-file-at_mft-not-found': when a file listed in a manifest isn't found at the manifest publication point. -'incid-file-at-mft-hash-not-match': the file hash doesn't match the hash listed at the manifest. -Both incidences will be an error by default. --- src/crypto/hash.c | 32 +++++++++++++++++++++++++++----- src/incidence/incidence.c | 12 ++++++++++++ src/incidence/incidence.h | 2 ++ src/object/manifest.c | 16 +++++++++++++++- 4 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/crypto/hash.c b/src/crypto/hash.c index 1e7143eb..6a8366b2 100644 --- a/src/crypto/hash.c +++ b/src/crypto/hash.c @@ -5,6 +5,7 @@ #include #include /* For blksize_t */ +#include "common.h" #include "file.h" #include "log.h" #include "asn1/oid.h" @@ -101,7 +102,14 @@ end1: /** * Computes the hash of the file @uri, and compares it to @expected (The - * "expected" hash). Returns 0 if no errors happened and the hashes match. + * "expected" hash). + * + * Returns: + * 0 if no errors happened and the hashes match, or the hash doesn't match + * but there's an incidence to ignore such error. + * < 0 if there was an error that can't be ignored. + * > 0 if there was an error but it can be ignored (file not found and there's + * an incidence to ignore this). */ int hash_validate_mft_file(char const *algorithm, struct rpki_uri *uri, @@ -114,12 +122,26 @@ hash_validate_mft_file(char const *algorithm, struct rpki_uri *uri, if (expected->bits_unused != 0) return pr_err("Hash string has unused bits."); - error = hash_file(algorithm, uri, actual, &actual_len); - if (error) - return error; + do { + error = hash_file(algorithm, uri, actual, &actual_len); + if (!error) + break; + + if (error == EACCES || error == ENOENT) { + if (incidence(INID_MFT_FILE_NOT_FOUND, + "File '%s' listed at manifest doesn't exist", + uri_get_printable(uri))) + return -EINVAL; + + return error; + } + /* Any other error (crypto, enomem, file read) */ + return ENSURE_NEGATIVE(error); + } while (0); if (!hash_matches(expected->buf, expected->size, actual, actual_len)) { - return pr_err("File '%s' does not match its manifest hash.", + return incidence(INID_MFT_FILE_HASH_NOT_MATCH, + "File '%s' does not match its manifest hash.", uri_get_printable(uri)); } diff --git a/src/incidence/incidence.c b/src/incidence/incidence.c index 74f8effa..b916395a 100644 --- a/src/incidence/incidence.c +++ b/src/incidence/incidence.c @@ -29,6 +29,18 @@ static struct incidence incidences[__INID_MAX] = { "Object isn't DER encoded", INAC_IGNORE, }, + { + INID_MFT_FILE_NOT_FOUND, + "incid-file-at_mft-not-found", + "File listed at manifest doesn't exist", + INAC_ERROR + }, + { + INID_MFT_FILE_HASH_NOT_MATCH, + "incid-file-at-mft-hash-not-match", + "File hash listed at manifest doesn't match the actual file hash", + INAC_ERROR + }, }; static int diff --git a/src/incidence/incidence.h b/src/incidence/incidence.h index 3656a9c7..cba80d8e 100644 --- a/src/incidence/incidence.h +++ b/src/incidence/incidence.h @@ -10,6 +10,8 @@ enum incidence_id { INID_HASHALG_HAS_PARAMS, INID_OBJ_NOT_DER, + INID_MFT_FILE_NOT_FOUND, + INID_MFT_FILE_HASH_NOT_MATCH, __INID_MAX, }; diff --git a/src/object/manifest.c b/src/object/manifest.c index 677d79c9..bacbfce4 100644 --- a/src/object/manifest.c +++ b/src/object/manifest.c @@ -170,8 +170,22 @@ build_rpp(struct Manifest *mft, struct rpki_uri *mft_uri, struct rpp **pp) if (error) goto fail; + /* + * Expect: + * - Negative value: an error not to be ignored, the whole + * manifest will be discarded. + * - Zero value: hash at manifest matches file's hash, or it + * doesn't match its hash but there's an incidence to ignore + * such error. + * - Positive value: file doesn't exist and keep validating + * manifest. + */ error = hash_validate_mft_file("sha256", uri, &fah->hash); - if (error) { + if (error < 0) { + uri_refput(uri); + goto fail; + } + if (error > 0) { uri_refput(uri); continue; } -- 2.47.3