From 87c7c78d66ac35a608680cbeb03b3c349e9aacaf Mon Sep 17 00:00:00 2001 From: claudio Date: Thu, 13 Jan 2022 13:46:03 +0000 Subject: [PATCH] Alter valid_filehash() to take a file descriptor instead of a path. This is needed so that callers can allow a file to be in multiple locations. Also move mft_check() from mft.c to parser.c. OK tb@ --- usr.sbin/rpki-client/extern.h | 4 ++-- usr.sbin/rpki-client/mft.c | 41 +------------------------------- usr.sbin/rpki-client/parser.c | 42 ++++++++++++++++++++++++++++++++- usr.sbin/rpki-client/repo.c | 7 +++--- usr.sbin/rpki-client/validate.c | 12 +++++----- 5 files changed, 54 insertions(+), 52 deletions(-) diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index c69fb03c417..aa683901e0d 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.102 2022/01/13 13:18:41 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.103 2022/01/13 13:46:03 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -446,7 +446,7 @@ int valid_cert(const char *, struct auth_tree *, const struct cert *); int valid_roa(const char *, struct auth_tree *, struct roa *); int valid_filename(const char *); -int valid_filehash(const char *, const char *, size_t); +int valid_filehash(int, const char *, size_t); int valid_uri(const char *, size_t, const char *); int valid_origin(const char *, const char *); diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c index d9268fda7d6..bd8be3091aa 100644 --- a/usr.sbin/rpki-client/mft.c +++ b/usr.sbin/rpki-client/mft.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mft.c,v 1.44 2022/01/11 13:06:07 claudio Exp $ */ +/* $OpenBSD: mft.c,v 1.45 2022/01/13 13:46:03 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -458,44 +457,6 @@ out: return p.res; } -/* - * 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; - char *cp, *h, *path = NULL; - - /* Check hash of file now, but first build path for it */ - cp = strrchr(fn, '/'); - assert(cp != NULL); - assert(cp - fn < INT_MAX); - - for (i = 0; i < p->filesz; i++) { - const struct mftfile *m = &p->files[i]; - if (!valid_filename(m->file)) { - if (base64_encode(m->hash, sizeof(m->hash), &h) == -1) - errx(1, "base64_encode failed in %s", __func__); - warnx("%s: unsupported filename for %s", fn, h); - free(h); - continue; - } - 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 rc; -} - /* * Free an MFT pointer. * Safe to call with NULL. diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c index 782b80aa5bc..0018e9ecbf8 100644 --- a/usr.sbin/rpki-client/parser.c +++ b/usr.sbin/rpki-client/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.34 2022/01/11 13:06:07 claudio Exp $ */ +/* $OpenBSD: parser.c,v 1.35 2022/01/13 13:46:03 claudio Exp $ */ /* * Copyright (c) 2019 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -220,6 +221,45 @@ proc_parser_roa(char *file, const unsigned char *der, size_t len) return roa; } +/* + * 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 fd, rc = 1; + char *cp, *h, *path = NULL; + + /* Check hash of file now, but first build path for it */ + cp = strrchr(fn, '/'); + assert(cp != NULL); + assert(cp - fn < INT_MAX); + + for (i = 0; i < p->filesz; i++) { + const struct mftfile *m = &p->files[i]; + if (!valid_filename(m->file)) { + if (base64_encode(m->hash, sizeof(m->hash), &h) == -1) + errx(1, "base64_encode failed in %s", __func__); + warnx("%s: unsupported filename for %s", fn, h); + free(h); + continue; + } + if (asprintf(&path, "%.*s/%s", (int)(cp - fn), fn, + m->file) == -1) + err(1, NULL); + fd = open(path, O_RDONLY); + if (!valid_filehash(fd, m->hash, sizeof(m->hash))) { + warnx("%s: bad message digest for %s", fn, m->file); + rc = 0; + } + free(path); + } + + return rc; +} + /* * Parse and validate a manifest file. * Here we *don't* validate against the list of CRLs, because the diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c index 6bd584d9601..162f31117ca 100644 --- a/usr.sbin/rpki-client/repo.c +++ b/usr.sbin/rpki-client/repo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: repo.c,v 1.22 2022/01/13 13:18:41 claudio Exp $ */ +/* $OpenBSD: repo.c,v 1.23 2022/01/13 13:46:03 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -841,8 +841,9 @@ rrdp_handle_file(unsigned int id, enum publish_type pt, char *uri, if ((fn = rrdp_filename(rr, uri, 1)) == NULL) return 0; } - if (!valid_filehash(fn, hash, hlen)) { - warnx("%s: bad message digest", fn); + fd = open(fn, O_RDONLY); + if (!valid_filehash(fd, hash, hlen)) { + warnx("%s: bad file digest for %s", rr->notifyuri, fn); free(fn); return 0; } diff --git a/usr.sbin/rpki-client/validate.c b/usr.sbin/rpki-client/validate.c index 9a9c93232a0..797fada2da5 100644 --- a/usr.sbin/rpki-client/validate.c +++ b/usr.sbin/rpki-client/validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: validate.c,v 1.23 2021/12/26 12:32:28 tb Exp $ */ +/* $OpenBSD: validate.c,v 1.24 2022/01/13 13:46:03 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -269,29 +269,29 @@ valid_filename(const char *fn) /* * Validate a file by verifying the SHA256 hash of that file. - * Returns 1 if valid, 0 otherwise. + * The file to check is passed as a file descriptor. + * Returns 1 if hash matched, 0 otherwise. Closes fd when done. */ int -valid_filehash(const char *fn, const char *hash, size_t hlen) +valid_filehash(int fd, 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) + if (fd == -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; -- 2.20.1