summaryrefslogtreecommitdiff
path: root/usr.sbin/rpki-client/mft.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2022-01-24 17:29:38 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2022-01-24 17:29:38 +0000
commit356492d1b27d66f102f27bbb5fba7a545d170b8a (patch)
tree0369f60afbb2600d43f9312ba0f7d76bbdc5c12c /usr.sbin/rpki-client/mft.c
parent8647ea1cc526709ac02f6a9b0b43b2ffa43a6a03 (diff)
Adjust code to handle unsupported file types a bit more graceful.
The file still needs to match its hash to make the MFT valid but then there will only be a warning printed. Parsing of other files from that MFT are not influenced. OK tb@
Diffstat (limited to 'usr.sbin/rpki-client/mft.c')
-rw-r--r--usr.sbin/rpki-client/mft.c48
1 files changed, 29 insertions, 19 deletions
diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c
index 39feafd8931..d1e6c1e56cc 100644
--- a/usr.sbin/rpki-client/mft.c
+++ b/usr.sbin/rpki-client/mft.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mft.c,v 1.50 2022/01/22 09:18:48 tb Exp $ */
+/* $OpenBSD: mft.c,v 1.51 2022/01/24 17:29:37 claudio Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
@@ -152,22 +152,33 @@ rtype_from_file_extension(const char *fn)
/*
* Validate that a filename listed on a Manifest only contains characters
- * permitted in draft-ietf-sidrops-6486bis section 4.2.2 and check that
- * it's a CER, CRL, GBR or a ROA.
- * Returns corresponding rtype or RTYPE_INVALID on error.
+ * permitted in draft-ietf-sidrops-6486bis section 4.2.2
*/
-enum rtype
-rtype_from_mftfile(const char *fn)
+static int
+valid_filename(const char *fn, size_t len)
{
- const unsigned char *c;
- enum rtype type;
+ const unsigned char *c;
+ size_t i;
- for (c = fn; *c != '\0'; ++c)
+ for (c = fn, i = 0; i < len; i++, c++)
if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
- return RTYPE_INVALID;
+ return 0;
- if (strchr(fn, '.') != strrchr(fn, '.'))
- return RTYPE_INVALID;
+ c = memchr(fn, '.', len);
+ if (c == NULL || c != memrchr(fn, '.', len))
+ return 0;
+
+ return 1;
+}
+
+/*
+ * Check that the file is a CER, CRL, GBR or a ROA.
+ * Returns corresponding rtype or RTYPE_INVALID on error.
+ */
+static enum rtype
+rtype_from_mftfile(const char *fn)
+{
+ enum rtype type;
type = rtype_from_file_extension(fn);
switch (type) {
@@ -191,7 +202,6 @@ 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;
@@ -217,16 +227,16 @@ mft_parse_filehash(struct parse *p, const ASN1_OCTET_STRING *os)
p->fn, ASN1_tag2str(file->type), file->type);
goto out;
}
+ if (!valid_filename(file->value.ia5string->data,
+ file->value.ia5string->length)) {
+ warnx("%s: RFC 6486 section 4.2.2: bad filename", p->fn);
+ goto out;
+ }
fn = strndup((const char *)file->value.ia5string->data,
file->value.ia5string->length);
if (fn == NULL)
err(1, NULL);
- if ((type = rtype_from_mftfile(fn)) == RTYPE_INVALID) {
- warnx("%s: invalid filename: %s", p->fn, fn);
- goto out;
- }
-
/* Now hash value. */
hash = sk_ASN1_TYPE_value(seq, 1);
@@ -247,8 +257,8 @@ mft_parse_filehash(struct parse *p, const ASN1_OCTET_STRING *os)
/* Insert the filename and hash value. */
fent = &p->res->files[p->res->filesz++];
+ fent->type = rtype_from_mftfile(fn);
fent->file = fn;
- fent->type = type;
fn = NULL;
memcpy(fent->hash, hash->value.bit_string->data, SHA256_DIGEST_LENGTH);