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?
-- 
: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;
 }

Reply via email to