On Fri, Jan 21, 2022 at 04:49:47PM +0100, Theo Buehler wrote:
> On Fri, Jan 21, 2022 at 02:58:57PM +0100, Claudio Jeker wrote:
> > On Wed, Jan 19, 2022 at 06:01:38PM +0100, Theo Buehler wrote:
> > > Not sure if it is that much of a win, but it saves some repetition and
> > > makes sure we don't forget checking the file name to be longer than 4
> > > another time (missed on review in main() and proc_parser_file()).
> >
> > I like the diff. It is a good first step.
> > One thing below but the diff is OK claudio@
>
> Thanks. I had a stupid logic error in rtype_from_file_extension() which
> is fixed below.
>
> [...]
>
> > I was a bit confused here because you did not adjust the first for loop
> > that just checks for .crl. I wonder if we should pass the RTYPE value in
> > struct mftfile. This would make this code a lot simpler.
>
> I didn't like that part of the diff either.
>
> Here's a diff that extends struct mftfile as you suggested and
> simplifies queue_add_from_mft*() using the new type member.
>
> One thing I don't like is that we call rtype_from_file_extension() twice
> from mft_parse_filehash(), once in valid_filename() and once directly.
>
> It would make more sense to change valid_filename() to return an enum
> rtype directly. The only reason I didn't do it is that I couldn't come
> up with a good name (type = valid_filename(fn) looks weird).
Lets start with that and optimize this in tree. I think we can rename the
function to something like rtype_from_mftfile(). In that case I would move
the function as well...
The diff is OK claudio@
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.110
> diff -u -p -r1.110 extern.h
> --- extern.h 20 Jan 2022 09:24:08 -0000 1.110
> +++ extern.h 21 Jan 2022 15:00:16 -0000
> @@ -149,10 +149,27 @@ struct tal {
> };
>
> /*
> + * Resource types specified by the RPKI profiles.
> + * There might be others we don't consider.
> + */
> +enum rtype {
> + RTYPE_INVALID,
> + RTYPE_TAL,
> + RTYPE_MFT,
> + RTYPE_ROA,
> + RTYPE_CER,
> + RTYPE_CRL,
> + RTYPE_GBR,
> + RTYPE_REPO,
> + RTYPE_FILE,
> +};
> +
> +/*
> * Files specified in an MFT have their bodies hashed with SHA256.
> */
> struct mftfile {
> char *file; /* filename (CER/ROA/CRL, no path) */
> + enum rtype type; /* file type as determined by extension */
> unsigned char hash[SHA256_DIGEST_LENGTH]; /* sha256 of body */
> };
>
> @@ -281,22 +298,6 @@ RB_PROTOTYPE(auth_tree, auth, entry, aut
> struct auth *auth_find(struct auth_tree *, const char *);
> void auth_insert(struct auth_tree *, struct cert *, struct auth *);
>
> -/*
> - * Resource types specified by the RPKI profiles.
> - * There might be others we don't consider.
> - */
> -enum rtype {
> - RTYPE_EOF = 0,
> - RTYPE_TAL,
> - RTYPE_MFT,
> - RTYPE_ROA,
> - RTYPE_CER,
> - RTYPE_CRL,
> - RTYPE_GBR,
> - RTYPE_REPO,
> - RTYPE_FILE,
> -};
> -
> enum http_result {
> HTTP_FAILED, /* anything else */
> HTTP_OK, /* 200 OK */
> @@ -450,6 +451,8 @@ int valid_filename(const char *);
> int valid_filehash(int, const char *, size_t);
> int valid_uri(const char *, size_t, const char *);
> int valid_origin(const char *, const char *);
> +
> +enum rtype rtype_from_file_extension(const char *);
>
> /* Working with CMS. */
> unsigned char *cms_parse_validate(X509 **, const char *,
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
> retrieving revision 1.180
> diff -u -p -r1.180 main.c
> --- main.c 21 Jan 2022 14:08:33 -0000 1.180
> +++ main.c 21 Jan 2022 15:30:03 -0000
> @@ -331,7 +331,7 @@ rrdp_http_done(unsigned int id, enum htt
> */
> static void
> queue_add_from_mft(const char *path, const struct mftfile *file,
> - enum rtype type, struct repo *rp)
> + struct repo *rp)
> {
> char *nfile, *npath = NULL;
>
> @@ -341,7 +341,7 @@ queue_add_from_mft(const char *path, con
> if ((nfile = strdup(file->file)) == NULL)
> err(1, NULL);
>
> - entityq_add(npath, nfile, type, rp, NULL, 0, -1);
> + entityq_add(npath, nfile, file->type, rp, NULL, 0, -1);
> }
>
> /*
> @@ -355,33 +355,29 @@ queue_add_from_mft(const char *path, con
> static void
> queue_add_from_mft_set(const struct mft *mft, const char *name, struct repo
> *rp)
> {
> - size_t i, sz;
> + size_t i;
> const struct mftfile *f;
>
> for (i = 0; i < mft->filesz; i++) {
> f = &mft->files[i];
> - sz = strlen(f->file);
> - assert(sz > 4);
> - if (strcasecmp(f->file + sz - 4, ".crl") != 0)
> + if (f->type != RTYPE_CRL)
> continue;
> - queue_add_from_mft(mft->path, f, RTYPE_CRL, rp);
> + queue_add_from_mft(mft->path, f, rp);
> }
>
> for (i = 0; i < mft->filesz; i++) {
> f = &mft->files[i];
> - sz = strlen(f->file);
> - assert(sz > 4);
> - if (strcasecmp(f->file + sz - 4, ".crl") == 0)
> + switch (f->type) {
> + case RTYPE_CER:
> + case RTYPE_ROA:
> + case RTYPE_GBR:
> + queue_add_from_mft(mft->path, f, rp);
> + break;
> + case RTYPE_CRL:
> continue;
> - else if (strcasecmp(f->file + sz - 4, ".cer") == 0)
> - queue_add_from_mft(mft->path, f, RTYPE_CER, rp);
> - else if (strcasecmp(f->file + sz - 4, ".roa") == 0)
> - queue_add_from_mft(mft->path, f, RTYPE_ROA, rp);
> - else if (strcasecmp(f->file + sz - 4, ".gbr") == 0)
> - queue_add_from_mft(mft->path, f, RTYPE_GBR, rp);
> - else
> - logx("%s: unsupported file type: %s", name,
> - f->file);
> + default:
> + logx("%s: unsupported file type: %s", name, f->file);
> + }
> }
> }
>
> @@ -839,17 +835,7 @@ main(int argc, char *argv[])
> goto usage;
> }
> if (file != NULL) {
> - size_t sz;
> -
> - sz = strlen(file);
> - if (sz < 5)
> - errx(1, "unsupported or invalid file: %s", file);
> - if (strcasecmp(file + sz - 4, ".tal") != 0 &&
> - strcasecmp(file + sz - 4, ".cer") != 0 &&
> - strcasecmp(file + sz - 4, ".crl") != 0 &&
> - strcasecmp(file + sz - 4, ".mft") != 0 &&
> - strcasecmp(file + sz - 4, ".roa") != 0 &&
> - strcasecmp(file + sz - 4, ".gbr") != 0)
> + if (rtype_from_file_extension(file) == RTYPE_INVALID)
> errx(1, "unsupported or invalid file: %s", file);
>
> outputdir = NULL;
> Index: mft.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 mft.c
> --- mft.c 18 Jan 2022 16:24:55 -0000 1.48
> +++ mft.c 21 Jan 2022 15:29:25 -0000
> @@ -130,6 +130,7 @@ mft_parse_filehash(struct parse *p, cons
> ASN1_SEQUENCE_ANY *seq;
> const ASN1_TYPE *file, *hash;
> char *fn = NULL;
> + enum rtype type;
> const unsigned char *d = os->data;
> size_t dsz = os->length;
> int rc = 0;
> @@ -165,6 +166,8 @@ mft_parse_filehash(struct parse *p, cons
> goto out;
> }
>
> + type = rtype_from_file_extension(fn);
> +
> /* Now hash value. */
>
> hash = sk_ASN1_TYPE_value(seq, 1);
> @@ -186,6 +189,7 @@ mft_parse_filehash(struct parse *p, cons
> fent = &p->res->files[p->res->filesz++];
>
> fent->file = fn;
> + fent->type = type;
> fn = NULL;
> memcpy(fent->hash, hash->value.bit_string->data, SHA256_DIGEST_LENGTH);
>
> @@ -495,6 +499,8 @@ mft_buffer(struct ibuf *b, const struct
> io_simple_buffer(b, &p->filesz, sizeof(size_t));
> for (i = 0; i < p->filesz; i++) {
> io_str_buffer(b, p->files[i].file);
> + io_simple_buffer(b, &p->files[i].type,
> + sizeof(p->files[i].type));
> io_simple_buffer(b, p->files[i].hash, SHA256_DIGEST_LENGTH);
> }
> }
> @@ -527,6 +533,7 @@ mft_read(struct ibuf *b)
>
> for (i = 0; i < p->filesz; i++) {
> io_read_str(b, &p->files[i].file);
> + io_read_buf(b, &p->files[i].type, sizeof(p->files[i].type));
> io_read_buf(b, p->files[i].hash, SHA256_DIGEST_LENGTH);
> }
>
> Index: parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 parser.c
> --- parser.c 21 Jan 2022 14:08:33 -0000 1.48
> +++ parser.c 21 Jan 2022 15:31:54 -0000
> @@ -912,25 +912,9 @@ proc_parser_file(char *file, unsigned ch
> struct tal *tal = NULL;
> enum rtype type;
> char *aia = NULL, *aki = NULL, *ski = NULL;
> - size_t sz;
> unsigned long verify_flags = X509_V_FLAG_CRL_CHECK;
>
> - sz = strlen(file);
> - if (sz < 5)
> - errx(1, "%s: unsupported file type", file);
> - if (strcasecmp(file + sz - 4, ".tal") == 0)
> - type = RTYPE_TAL;
> - else if (strcasecmp(file + sz - 4, ".cer") == 0)
> - type = RTYPE_CER;
> - else if (strcasecmp(file + sz - 4, ".crl") == 0)
> - type = RTYPE_CRL;
> - else if (strcasecmp(file + sz - 4, ".mft") == 0)
> - type = RTYPE_MFT;
> - else if (strcasecmp(file + sz - 4, ".roa") == 0)
> - type = RTYPE_ROA;
> - else if (strcasecmp(file + sz - 4, ".gbr") == 0)
> - type = RTYPE_GBR;
> - else
> + if ((type = rtype_from_file_extension(file)) == RTYPE_INVALID)
> errx(1, "%s: unsupported file type", file);
>
> switch (type) {
> Index: validate.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
> retrieving revision 1.24
> diff -u -p -r1.24 validate.c
> --- validate.c 13 Jan 2022 13:46:03 -0000 1.24
> +++ validate.c 21 Jan 2022 15:24:00 -0000
> @@ -234,6 +234,35 @@ valid_roa(const char *fn, struct auth_tr
> }
>
> /*
> + * Determine rtype corresponding to file extension. Returns RTYPE_INVALID
> + * on error or unkown extension.
> + */
> +enum rtype
> +rtype_from_file_extension(const char *fn)
> +{
> + size_t sz;
> +
> + sz = strlen(fn);
> + if (sz < 5)
> + return RTYPE_INVALID;
> +
> + if (strcasecmp(fn + sz - 4, ".tal") == 0)
> + return RTYPE_TAL;
> + if (strcasecmp(fn + sz - 4, ".cer") == 0)
> + return RTYPE_CER;
> + if (strcasecmp(fn + sz - 4, ".crl") == 0)
> + return RTYPE_CRL;
> + if (strcasecmp(fn + sz - 4, ".mft") == 0)
> + return RTYPE_MFT;
> + if (strcasecmp(fn + sz - 4, ".roa") == 0)
> + return RTYPE_ROA;
> + if (strcasecmp(fn + sz - 4, ".gbr") == 0)
> + return RTYPE_GBR;
> +
> + return RTYPE_INVALID;
> +}
> +
> +/*
> * Validate a filename listed on a Manifest.
> * draft-ietf-sidrops-6486bis section 4.2.2
> * Returns 1 if filename is valid, otherwise 0.
> @@ -241,13 +270,8 @@ valid_roa(const char *fn, struct auth_tr
> int
> valid_filename(const char *fn)
> {
> - size_t sz;
> const unsigned char *c;
>
> - sz = strlen(fn);
> - if (sz < 5)
> - return 0;
> -
> for (c = fn; *c != '\0'; ++c)
> if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
> return 0;
> @@ -255,16 +279,15 @@ valid_filename(const char *fn)
> if (strchr(fn, '.') != strrchr(fn, '.'))
> return 0;
>
> - if (strcasecmp(fn + sz - 4, ".cer") == 0)
> - return 1;
> - if (strcasecmp(fn + sz - 4, ".crl") == 0)
> + switch (rtype_from_file_extension(fn)) {
> + case RTYPE_CER:
> + case RTYPE_CRL:
> + case RTYPE_GBR:
> + case RTYPE_ROA:
> return 1;
> - if (strcasecmp(fn + sz - 4, ".gbr") == 0)
> - return 1;
> - if (strcasecmp(fn + sz - 4, ".roa") == 0)
> - return 1;
> -
> - return 0;
> + default:
> + return 0;
> + }
> }
>
> /*
>
--
:wq Claudio