From 67d45509f5b927964a5fb84e9dc17fd377e66297 Mon Sep 17 00:00:00 2001 From: claudio Date: Fri, 5 Mar 2021 16:00:00 +0000 Subject: [PATCH] Factor out the SHA256 hash checks into valid_filehash() so that it can be used by the RRDP code as well. OK tb@ --- usr.sbin/rpki-client/extern.h | 3 +- usr.sbin/rpki-client/mft.c | 59 +++++++++------------------------ usr.sbin/rpki-client/validate.c | 34 ++++++++++++++++++- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index fa862a6ce7a..4a77b431b75 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $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 * @@ -354,6 +354,7 @@ int valid_ta(const char *, struct auth_tree *, 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. */ diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c index 04944b79369..992adf02fa6 100644 --- a/usr.sbin/rpki-client/mft.c +++ b/usr.sbin/rpki-client/mft.c @@ -1,4 +1,4 @@ -/* $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 * @@ -434,62 +434,33 @@ out: } /* - * 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; } diff --git a/usr.sbin/rpki-client/validate.c b/usr.sbin/rpki-client/validate.c index 88a9c6bb827..39779a3e6f2 100644 --- a/usr.sbin/rpki-client/validate.c +++ b/usr.sbin/rpki-client/validate.c @@ -1,4 +1,4 @@ -/* $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 * @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -240,3 +241,34 @@ valid_roa(const char *fn, struct auth_tree *auths, struct roa *roa) 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; +} -- 2.20.1