From 22cec6c4dff03086885f7951780dc92909e3cecc Mon Sep 17 00:00:00 2001 From: tb Date: Fri, 21 Jan 2022 18:49:44 +0000 Subject: [PATCH] Add function to determine the file type from the file name extension rpki-client uses the same idiom to determine the file type in too many places. Use one function that determines the appropriate RTYPE from the file name. Add that type to struct mftfile and use this new member to simplify queue_add_from_mft*(). input/ok claudio --- usr.sbin/rpki-client/extern.h | 37 ++++++++++++----------- usr.sbin/rpki-client/main.c | 48 +++++++++++------------------ usr.sbin/rpki-client/mft.c | 9 +++++- usr.sbin/rpki-client/parser.c | 20 ++----------- usr.sbin/rpki-client/validate.c | 53 +++++++++++++++++++++++---------- 5 files changed, 85 insertions(+), 82 deletions(-) diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 7b52516a783..e6f9b0018ee 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.110 2022/01/20 09:24:08 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.111 2022/01/21 18:49:44 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -148,11 +148,28 @@ struct tal { int id; /* ID of this 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, authcmp); 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 */ @@ -451,6 +452,8 @@ 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 *, const unsigned char *, size_t, diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index 8c8cf377ecb..bad56852417 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.180 2022/01/21 14:08:33 tb Exp $ */ +/* $OpenBSD: main.c,v 1.181 2022/01/21 18:49:44 tb Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -331,7 +331,7 @@ rrdp_http_done(unsigned int id, enum http_result res, const char *last_mod) */ 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, const struct mftfile *file, 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, const struct mftfile *file, 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; diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c index e393d25f0d3..779cd240977 100644 --- a/usr.sbin/rpki-client/mft.c +++ b/usr.sbin/rpki-client/mft.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mft.c,v 1.48 2022/01/18 16:24:55 claudio Exp $ */ +/* $OpenBSD: mft.c,v 1.49 2022/01/21 18:49:44 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -130,6 +130,7 @@ mft_parse_filehash(struct parse *p, const ASN1_OCTET_STRING *os) 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, const ASN1_OCTET_STRING *os) 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, const ASN1_OCTET_STRING *os) 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 mft *p) 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); } diff --git a/usr.sbin/rpki-client/parser.c b/usr.sbin/rpki-client/parser.c index 70b198f2a40..c6d0e5c0cfe 100644 --- a/usr.sbin/rpki-client/parser.c +++ b/usr.sbin/rpki-client/parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parser.c,v 1.48 2022/01/21 14:08:33 tb Exp $ */ +/* $OpenBSD: parser.c,v 1.49 2022/01/21 18:49:44 tb Exp $ */ /* * Copyright (c) 2019 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -912,25 +912,9 @@ proc_parser_file(char *file, unsigned char *buf, size_t len) 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) { diff --git a/usr.sbin/rpki-client/validate.c b/usr.sbin/rpki-client/validate.c index 797fada2da5..9f696d5ae88 100644 --- a/usr.sbin/rpki-client/validate.c +++ b/usr.sbin/rpki-client/validate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: validate.c,v 1.24 2022/01/13 13:46:03 claudio Exp $ */ +/* $OpenBSD: validate.c,v 1.25 2022/01/21 18:49:44 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -233,6 +233,35 @@ valid_roa(const char *fn, struct auth_tree *auths, struct roa *roa) return 1; } +/* + * 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 @@ -241,13 +270,8 @@ valid_roa(const char *fn, struct auth_tree *auths, struct roa *roa) 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; + } } /* -- 2.20.1