On Mon, Apr 11, 2022 at 11:37:11AM +0200, Theo Buehler wrote:
> This should be the last step. It inlines sbgp_sia_resource_entry() into
> sbgp_sia() and dedups the sbgp_sia_resource_{notify,mft,carepo}() using
> a new sbgp_sia_location(). Move the GEN_URI check to sbgp_sia_location()
> since that seems cleaner.
>
> Index: cert.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
> retrieving revision 1.65
> diff -u -p -r1.65 cert.c
> --- cert.c 11 Apr 2022 08:28:54 -0000 1.65
> +++ cert.c 11 Apr 2022 09:27:53 -0000
> @@ -125,132 +125,40 @@ sbgp_addr(struct parse *p,
> }
>
> /*
> - * Parse the SIA notify URL, 4.8.8.1.
> - * Returns zero on failure, non-zero on success.
> + * Extract and validate a SIA accessLocation, RFC 6487, 4.8.8 and RFC 8192,
> 3.2.
> + * Returns 0 on failure and 1 on success.
> */
> static int
> -sbgp_sia_resource_notify(struct parse *p, const char *d, size_t dsz)
> +sbgp_sia_location(const char *fn, const char *descr, const char *proto,
> + GENERAL_NAME *location, char **out)
> {
> - if (p->res->notify != NULL) {
> - warnx("%s: RFC 6487 section 4.8.8: SIA: "
> - "Notify location already specified", p->fn);
> - return 0;
> - }
> -
> - /* Make sure it's a https:// address. */
> - if (!valid_uri(d, dsz, "https://")) {
> - warnx("%s: RFC 8182 section 3.2: bad Notify URI", p->fn);
> - return 0;
> - }
> + ASN1_IA5STRING *uri;
>
> - if ((p->res->notify = strndup(d, dsz)) == NULL)
> - err(1, NULL);
> -
> - return 1;
> -}
> -
> -/*
> - * Parse the SIA manifest, 4.8.8.1.
> - * Returns zero on failure, non-zero on success.
> - */
> -static int
> -sbgp_sia_resource_mft(struct parse *p, const char *d, size_t dsz)
> -{
> - if (p->res->mft != NULL) {
> - warnx("%s: RFC 6487 section 4.8.8: SIA: "
> - "MFT location already specified", p->fn);
> + if (*out != NULL) {
> + warnx("%s: RFC 6487 section 4.8.8: SIA: %s already specified",
> + fn, descr);
> return 0;
> }
>
> - /* Make sure it's an rsync address. */
> - if (!valid_uri(d, dsz, "rsync://")) {
> - warnx("%s: RFC 6487 section 4.8.8: bad MFT location", p->fn);
> + if (location->type != GEN_URI) {
> + warnx("%s: RFC 6487 section 4.8.8: SIA: %s not URI", fn, descr);
> return 0;
> }
>
> - if ((p->res->mft = strndup(d, dsz)) == NULL)
> - err(1, NULL);
> + uri = location->d.uniformResourceIdentifier;
>
> - 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 char *d, size_t dsz)
> -{
> - if (p->res->repo != NULL) {
> - warnx("%s: RFC 6487 section 4.8.8: SIA: "
> - "CA repository already specified", p->fn);
> + if (!valid_uri(uri->data, uri->length, proto)) {
> + warnx("%s: RFC 6487 section 4.8.8: bad %s location", fn, descr);
> return 0;
> }
>
> - /* Make sure it's an rsync:// address. */
> - if (!valid_uri(d, dsz, "rsync://")) {
> - warnx("%s: RFC 6487 section 4.8.8: bad CA repository URI",
> - p->fn);
> - return 0;
> - }
> -
> - if ((p->res->repo = strndup(d, dsz)) == NULL)
> + if ((*out = strndup(uri->data, uri->length)) == 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
> - * out all but the matching resource type. Currently only two entries
> - * are of interest: rpkiManifest and rpkiNotify.
> - * Returns zero on failure, non-zero on success.
> - */
> -static int
> -sbgp_sia_resource_entry(struct parse *p, ACCESS_DESCRIPTION *ad)
> -{
> - ASN1_OBJECT *oid;
> - ASN1_IA5STRING *uri = NULL;
> - int rc = 0;
> -
> - if (ad->location->type == GEN_URI)
> - uri = ad->location->d.uniformResourceIdentifier;
> -
> - oid = ad->method;
> -
> - if (OBJ_cmp(oid, carepo_oid) == 0) {
> - if (uri == NULL) {
> - warnx("%s: RFC 6487: 4.8.8.1 caRepository without URI",
> - p->fn);
> - goto out;
> - }
> - if (!sbgp_sia_resource_carepo(p, uri->data, uri->length))
> - goto out;
> - } else if (OBJ_cmp(oid, manifest_oid) == 0) {
> - if (uri == NULL) {
> - warnx("%s: RFC 6487: 4.8.8 SIA manifest without URI",
> - p->fn);
> - goto out;
> - }
> - if (!sbgp_sia_resource_mft(p, uri->data, uri->length))
> - goto out;
> - } else if (OBJ_cmp(oid, notify_oid) == 0) {
> - if (uri == NULL) {
> - warnx("%s: RFC 6487: 4.8.8 SIA resourceNotify "
> - "without URI", p->fn);
> - goto out;
> - }
> - if (!sbgp_sia_resource_notify(p, uri->data, uri->length))
> - goto out;
> - }
> -
> - rc = 1;
> - out:
> - return rc;
> -}
> -
> -/*
> * Parse "Subject Information Access" extension, RFC 6487 4.8.8.
> * Returns zero on failure, non-zero on success.
> */
> @@ -259,6 +167,7 @@ sbgp_sia(struct parse *p, X509_EXTENSION
> {
> AUTHORITY_INFO_ACCESS *sia = NULL;
> ACCESS_DESCRIPTION *ad;
> + ASN1_OBJECT *oid;
> int i, rc = 0;
>
> if (X509_EXTENSION_get_critical(ext)) {
> @@ -275,8 +184,22 @@ sbgp_sia(struct parse *p, X509_EXTENSION
>
> for (i = 0; i < sk_ACCESS_DESCRIPTION_num(sia); i++) {
> ad = sk_ACCESS_DESCRIPTION_value(sia, i);
> - if (!sbgp_sia_resource_entry(p, ad))
> - goto out;
> +
> + oid = ad->method;
> +
> + if (OBJ_cmp(oid, carepo_oid) == 0) {
> + if (!sbgp_sia_location(p->fn, "caRepository",
> + "rsync://", ad->location, &p->res->repo))
> + goto out;
> + } else if (OBJ_cmp(oid, manifest_oid) == 0) {
> + if (!sbgp_sia_location(p->fn, "rpkiManifest",
> + "rsync://", ad->location, &p->res->mft))
> + goto out;
> + } else if (OBJ_cmp(oid, notify_oid) == 0) {
> + if (!sbgp_sia_location(p->fn, "rpkiNotify",
> + "https://", ad->location, &p->res->notify))
> + goto out;
> + }
> }
>
> if (p->res->mft == NULL || p->res->repo == NULL) {
>
OK claudio@
--
:wq Claudio