Factor out the SHA256 hash checks into valid_filehash() so that it can
authorclaudio <claudio@openbsd.org>
Fri, 5 Mar 2021 16:00:00 +0000 (16:00 +0000)
committerclaudio <claudio@openbsd.org>
Fri, 5 Mar 2021 16:00:00 +0000 (16:00 +0000)
be used by the RRDP code as well.
OK tb@

usr.sbin/rpki-client/extern.h
usr.sbin/rpki-client/mft.c
usr.sbin/rpki-client/validate.c

index fa862a6..4a77b43 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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. */
 
index 04944b7..992adf0 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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;
 }
 
index 88a9c6b..39779a3 100644 (file)
@@ -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 <kristaps@bsd.lv>
  *
@@ -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>
@@ -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;
+}