#include <sys/stat.h>
#include <sys/types.h> /* For blksize_t */
+#include "common.h"
#include "file.h"
#include "log.h"
#include "asn1/oid.h"
/**
* 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,
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));
}
"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
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;
}