On Fri, Mar 05, 2021 at 03:15:48PM +0100, Claudio Jeker wrote: > RRDP also uses SHA256 hashes to validate files (before withdraws and > updates). Again move this from the implementation in mft.c to validate.c > this way it can be reused. > > OK?
ok tb > -- > :wq Claudio > > Index: extern.h > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v > retrieving revision 1.51 > diff -u -p -r1.51 extern.h > --- extern.h 5 Mar 2021 12:33:19 -0000 1.51 > +++ extern.h 5 Mar 2021 14:00:29 -0000 > @@ -354,6 +354,7 @@ int valid_ta(const char *, struct auth > 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. */ > > Index: mft.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v > retrieving revision 1.28 > diff -u -p -r1.28 mft.c > --- mft.c 4 Mar 2021 14:24:17 -0000 1.28 > +++ mft.c 5 Mar 2021 12:33:50 -0000 > @@ -434,61 +434,32 @@ 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; > } > Index: validate.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v > retrieving revision 1.11 > diff -u -p -r1.11 validate.c > --- validate.c 12 Sep 2020 15:46:48 -0000 1.11 > +++ validate.c 5 Mar 2021 13:59:46 -0000 > @@ -20,6 +20,7 @@ > #include <arpa/inet.h> > #include <assert.h> > #include <err.h> > +#include <fcntl.h> > #include <inttypes.h> > #include <stdarg.h> > #include <stdlib.h> > @@ -237,6 +238,37 @@ valid_roa(const char *fn, struct auth_tr > tracewarn(a); > return 0; > } > + > + 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; > } >