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

Reply via email to