From 84c20e473c000c4c012e6fd34e8def3139040a69 Mon Sep 17 00:00:00 2001 From: claudio Date: Mon, 8 Feb 2021 09:22:53 +0000 Subject: [PATCH] Extract the 1.3.6.1.5.5.7.48.5 (caRepository) SIA from the certificate. Make sure that the caRepository matches the start of the URI of rpkiManifest. The MFT must be a file inside the caRepository. OK tb@ --- usr.sbin/rpki-client/cert.c | 55 +++++++++++++++++++++++++++++++++-- usr.sbin/rpki-client/extern.h | 3 +- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index b857b4f541d..130794eed28 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.24 2021/02/04 08:58:19 claudio Exp $ */ +/* $OpenBSD: cert.c,v 1.25 2021/02/08 09:22:53 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -194,6 +194,7 @@ sbgp_sia_resource_mft(struct parse *p, p->fn); return 0; } + if (strcasecmp(d + dsz - 4, ".mft") != 0) { warnx("%s: RFC 6487 section 4.8.8: SIA: " "invalid rsync URI suffix", p->fn); @@ -213,6 +214,43 @@ sbgp_sia_resource_mft(struct parse *p, return 1; } +/* + * Parse the SIA manifest, 4.8.8.1. + * Returns zero on failure, non-zero on success. + */ +static int +sbgp_sia_resource_carepo(struct parse *p, + const unsigned char *d, size_t dsz) +{ + size_t i; + + if (p->res->repo != NULL) { + warnx("%s: RFC 6487 section 4.8.8: SIA: " + "CA repository already specified", p->fn); + return 0; + } + + /* Make sure it's an rsync:// address. */ + if (dsz <= 8 || strncasecmp(d, "rsync://", 8)) { + warnx("%s: RFC 6487 section 4.8.8: not using rsync schema", + p->fn); + return 0; + } + + /* make sure only US-ASCII chars are in the URL */ + for (i = 0; i < dsz; i++) { + if (isalnum(d[i]) || ispunct(d[i])) + continue; + warnx("%s: invalid URI", p->fn); + return 0; + } + + if ((p->res->repo = strndup((const char *)d, dsz)) == NULL) + err(1, NULL); + + return 1; +} + /* * Parse the SIA entries, 4.8.8.1. * There may be multiple different resources at this location, so throw @@ -271,11 +309,13 @@ sbgp_sia_resource_entry(struct parse *p, /* * Ignore all but manifest and RRDP notify URL. * Things we may see: + * - 1.3.6.1.5.5.7.48.5 (caRepository) * - 1.3.6.1.5.5.7.48.10 (rpkiManifest) * - 1.3.6.1.5.5.7.48.13 (rpkiNotify) - * - 1.3.6.1.5.5.7.48.5 (CA repository) */ - if (strcmp(buf, "1.3.6.1.5.5.7.48.10") == 0) + if (strcmp(buf, "1.3.6.1.5.5.7.48.5") == 0) + rc = sbgp_sia_resource_carepo(p, d, plen); + else if (strcmp(buf, "1.3.6.1.5.5.7.48.10") == 0) rc = sbgp_sia_resource_mft(p, d, plen); else if (strcmp(buf, "1.3.6.1.5.5.7.48.13") == 0) rc = sbgp_sia_resource_notify(p, d, plen); @@ -317,6 +357,12 @@ sbgp_sia_resource(struct parse *p, const unsigned char *d, size_t dsz) goto out; } + if (strstr(p->res->mft, p->res->repo) != p->res->mft) { + warnx("%s: RFC 6487 section 4.8.8: SIA: " + "conflicting URIs for caRepository and rpkiManifest", + p->fn); + goto out; + } rc = 1; out: sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free); @@ -1172,6 +1218,7 @@ cert_free(struct cert *p) return; free(p->crl); + free(p->repo); free(p->mft); free(p->notify); free(p->ips); @@ -1230,6 +1277,7 @@ cert_buffer(struct ibuf *b, const struct cert *p) io_str_buffer(b, p->mft); io_str_buffer(b, p->notify); + io_str_buffer(b, p->repo); io_str_buffer(b, p->crl); io_str_buffer(b, p->aki); io_str_buffer(b, p->ski); @@ -1297,6 +1345,7 @@ cert_read(int fd) io_str_read(fd, &p->mft); assert(p->mft); io_str_read(fd, &p->notify); + io_str_read(fd, &p->repo); io_str_read(fd, &p->crl); io_str_read(fd, &p->aki); io_str_read(fd, &p->ski); diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index a32f09b94ba..edd446e882a 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.41 2021/02/04 14:32:01 claudio Exp $ */ +/* $OpenBSD: extern.h,v 1.42 2021/02/08 09:22:53 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -112,6 +112,7 @@ struct cert { size_t ipsz; /* length of "ips" */ struct cert_as *as; /* list of AS numbers and ranges */ size_t asz; /* length of "asz" */ + char *repo; /* CA repository (rsync:// uri) */ char *mft; /* manifest (rsync:// uri) */ char *notify; /* RRDP notify (https:// uri) */ char *crl; /* CRL location (rsync:// or NULL) */ -- 2.20.1