-/* $OpenBSD: extern.h,v 1.51 2021/03/05 12:33:19 claudio Exp $ */
+/* $OpenBSD: extern.h,v 1.52 2021/03/05 16:00:00 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
int valid_cert(const char *, struct auth_tree *,
const struct cert *);
int valid_roa(const char *, struct auth_tree *, struct roa *);
+int valid_filehash(const char *, const char *, size_t);
/* Working with CMS files. */
-/* $OpenBSD: mft.c,v 1.28 2021/03/04 14:24:17 claudio Exp $ */
+/* $OpenBSD: mft.c,v 1.29 2021/03/05 16:00:00 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
}
/*
- * Check the hash value of a file.
+ * Check all files and their hashes in a MFT structure.
* Return zero on failure, non-zero on success.
*/
-static int
-mft_validfilehash(const char *fn, const struct mftfile *m)
+int
+mft_check(const char *fn, struct mft *p)
{
- char filehash[SHA256_DIGEST_LENGTH];
- char buffer[8192];
+ size_t i;
+ int rc = 1;
char *cp, *path = NULL;
- SHA256_CTX ctx;
- ssize_t nr;
- int fd;
/* Check hash of file now, but first build path for it */
cp = strrchr(fn, '/');
assert(cp != NULL);
assert(cp - fn < INT_MAX);
- if (asprintf(&path, "%.*s/%s", (int)(cp - fn), fn, m->file) == -1)
- err(1, NULL);
- if ((fd = open(path, O_RDONLY)) == -1) {
- warn("%s: referenced file %s", fn, m->file);
+ for (i = 0; i < p->filesz; i++) {
+ const struct mftfile *m = &p->files[i];
+ if (asprintf(&path, "%.*s/%s", (int)(cp - fn), fn,
+ m->file) == -1)
+ err(1, NULL);
+ if (!valid_filehash(path, m->hash, sizeof(m->hash))) {
+ warnx("%s: bad message digest for %s", fn, m->file);
+ rc = 0;
+ }
free(path);
- return 0;
- }
- free(path);
-
- SHA256_Init(&ctx);
- while ((nr = read(fd, buffer, sizeof(buffer))) > 0) {
- SHA256_Update(&ctx, buffer, nr);
- }
- close(fd);
-
- SHA256_Final(filehash, &ctx);
- if (memcmp(m->hash, filehash, SHA256_DIGEST_LENGTH) != 0) {
- warnx("%s: bad message digest for %s", fn, m->file);
- return 0;
}
- return 1;
-}
-
-/*
- * Check all files and their hashes in a MFT structure.
- * Return zero on failure, non-zero on success.
- */
-int
-mft_check(const char *fn, struct mft *p)
-{
- size_t i;
- int rc = 1;
-
- for (i = 0; i < p->filesz; i++)
- if (!mft_validfilehash(fn, &p->files[i]))
- rc = 0;
-
return rc;
}
-/* $OpenBSD: validate.c,v 1.11 2020/09/12 15:46:48 claudio Exp $ */
+/* $OpenBSD: validate.c,v 1.12 2021/03/05 16:00:00 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
#include <arpa/inet.h>
#include <assert.h>
#include <err.h>
+#include <fcntl.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdlib.h>
return 1;
}
+
+/*
+ * Validate a file by verifying the SHA256 hash of that file.
+ * Returns 1 if valid, 0 otherwise.
+ */
+int
+valid_filehash(const char *fn, const char *hash, size_t hlen)
+{
+ SHA256_CTX ctx;
+ char filehash[SHA256_DIGEST_LENGTH];
+ char buffer[8192];
+ ssize_t nr;
+ int fd;
+
+ if (hlen != sizeof(filehash))
+ errx(1, "bad hash size");
+
+ if ((fd = open(fn, O_RDONLY)) == -1)
+ return 0;
+
+ SHA256_Init(&ctx);
+ while ((nr = read(fd, buffer, sizeof(buffer))) > 0)
+ SHA256_Update(&ctx, buffer, nr);
+ close(fd);
+
+ SHA256_Final(filehash, &ctx);
+ if (memcmp(hash, filehash, sizeof(filehash)) != 0)
+ return 0;
+
+ return 1;
+}