From: tb Date: Mon, 25 Sep 2023 14:56:20 +0000 (+0000) Subject: rpki-client: Refactor sbgp_assysnum() and sbgp_addrblk() X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=18c42b3002250aa4c4ac0a97c4f21e2dc9907d5e;p=openbsd rpki-client: Refactor sbgp_assysnum() and sbgp_addrblk() An upcoming diff requires the ability to convert ASIdentifiers and IpAddrBlocks into rpki-client's internal structures. Accordingly, split already existing code into dedicated parsing functions . The original functions now only extract the extension-specific data from the X509_EXTENSION. input/ok claudio --- diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index c123640f6ad..e4ad31a7776 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.115 2023/09/12 09:33:30 job Exp $ */ +/* $OpenBSD: cert.c,v 1.116 2023/09/25 14:56:20 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler * Copyright (c) 2021 Job Snijders @@ -153,40 +153,26 @@ sbgp_as_inherit(const char *fn, struct cert_as *ases, size_t *asz) return append_as(fn, ases, asz, &as); } -/* - * Parse RFC 6487 4.8.11 X509v3 extension, with syntax documented in RFC - * 3779 starting in section 3.2. - * Returns zero on failure, non-zero on success. - */ -static int -sbgp_assysnum(struct parse *p, X509_EXTENSION *ext) +int +sbgp_parse_assysnum(const char *fn, const ASIdentifiers *asidentifiers, + struct cert_as **out_as, size_t *out_asz) { - ASIdentifiers *asidentifiers = NULL; const ASIdOrRanges *aors = NULL; - size_t asz; - int i, rc = 0; + struct cert_as *as = NULL; + size_t asz, new_asz = 0; + int i; - if (!X509_EXTENSION_get_critical(ext)) { - warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: " - "extension not critical", p->fn); - goto out; - } - - if ((asidentifiers = X509V3_EXT_d2i(ext)) == NULL) { - warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: " - "failed extension parse", p->fn); - goto out; - } + assert(*out_as == NULL && *out_asz == 0); if (asidentifiers->rdi != NULL) { warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: " - "should not have RDI values", p->fn); + "should not have RDI values", fn); goto out; } if (asidentifiers->asnum == NULL) { warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: " - "no AS number resource set", p->fn); + "no AS number resource set", fn); goto out; } @@ -200,26 +186,25 @@ sbgp_assysnum(struct parse *p, X509_EXTENSION *ext) break; default: warnx("%s: RFC 3779 section 3.2.3.2: ASIdentifierChoice: " - "unknown type %d", p->fn, asidentifiers->asnum->type); + "unknown type %d", fn, asidentifiers->asnum->type); goto out; } if (asz == 0) { - warnx("%s: RFC 6487 section 4.8.11: empty asIdsOrRanges", - p->fn); + warnx("%s: RFC 6487 section 4.8.11: empty asIdsOrRanges", fn); goto out; } if (asz >= MAX_AS_SIZE) { warnx("%s: too many AS number entries: limit %d", - p->fn, MAX_AS_SIZE); + fn, MAX_AS_SIZE); goto out; } - p->res->as = calloc(asz, sizeof(struct cert_as)); - if (p->res->as == NULL) + as = calloc(asz, sizeof(struct cert_as)); + if (as == NULL) err(1, NULL); if (aors == NULL) { - if (!sbgp_as_inherit(p->fn, p->res->as, &p->res->asz)) + if (!sbgp_as_inherit(fn, as, &new_asz)) goto out; } @@ -229,22 +214,58 @@ sbgp_assysnum(struct parse *p, X509_EXTENSION *ext) aor = sk_ASIdOrRange_value(aors, i); switch (aor->type) { case ASIdOrRange_id: - if (!sbgp_as_id(p->fn, p->res->as, &p->res->asz, - aor->u.id)) + if (!sbgp_as_id(fn, as, &new_asz, aor->u.id)) goto out; break; case ASIdOrRange_range: - if (!sbgp_as_range(p->fn, p->res->as, &p->res->asz, - aor->u.range)) + if (!sbgp_as_range(fn, as, &new_asz, aor->u.range)) goto out; break; default: warnx("%s: RFC 3779 section 3.2.3.5: ASIdOrRange: " - "unknown type %d", p->fn, aor->type); + "unknown type %d", fn, aor->type); goto out; } } + *out_as = as; + *out_asz = new_asz; + + return 1; + + out: + free(as); + + return 0; +} + +/* + * Parse RFC 6487 4.8.11 X509v3 extension, with syntax documented in RFC + * 3779 starting in section 3.2. + * Returns zero on failure, non-zero on success. + */ +static int +sbgp_assysnum(struct parse *p, X509_EXTENSION *ext) +{ + ASIdentifiers *asidentifiers = NULL; + int rc = 0; + + if (!X509_EXTENSION_get_critical(ext)) { + warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: " + "extension not critical", p->fn); + goto out; + } + + if ((asidentifiers = X509V3_EXT_d2i(ext)) == NULL) { + warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: " + "failed extension parse", p->fn); + goto out; + } + + if (!sbgp_parse_assysnum(p->fn, asidentifiers, + &p->res->as, &p->res->asz)) + goto out; + rc = 1; out: ASIdentifiers_free(asidentifiers); @@ -331,33 +352,19 @@ sbgp_addr_inherit(const char *fn, struct cert_ip *ips, size_t *ipsz, return append_ip(fn, ips, ipsz, &ip); } -/* - * Parse an sbgp-ipAddrBlock X509 extension, RFC 6487 4.8.10, with - * syntax documented in RFC 3779 starting in section 2.2. - * Returns zero on failure, non-zero on success. - */ -static int -sbgp_ipaddrblk(struct parse *p, X509_EXTENSION *ext) +int +sbgp_parse_ipaddrblk(const char *fn, const IPAddrBlocks *addrblk, + struct cert_ip **out_ips, size_t *out_ipsz) { - STACK_OF(IPAddressFamily) *addrblk = NULL; - const IPAddressFamily *af; - const IPAddressOrRanges *aors; - const IPAddressOrRange *aor; - enum afi afi; - size_t ipsz; - int i, j, rc = 0; - - if (!X509_EXTENSION_get_critical(ext)) { - warnx("%s: RFC 6487 section 4.8.10: sbgp-ipAddrBlock: " - "extension not critical", p->fn); - goto out; - } + const IPAddressFamily *af; + const IPAddressOrRanges *aors; + const IPAddressOrRange *aor; + enum afi afi; + struct cert_ip *ips = NULL; + size_t ipsz, new_ipsz = 0; + int i, j; - if ((addrblk = X509V3_EXT_d2i(ext)) == NULL) { - warnx("%s: RFC 6487 section 4.8.10: sbgp-ipAddrBlock: " - "failed extension parse", p->fn); - goto out; - } + assert(*out_ips == NULL && *out_ipsz == 0); for (i = 0; i < sk_IPAddressFamily_num(addrblk); i++) { af = sk_IPAddressFamily_value(addrblk, i); @@ -365,38 +372,37 @@ sbgp_ipaddrblk(struct parse *p, X509_EXTENSION *ext) switch (af->ipAddressChoice->type) { case IPAddressChoice_inherit: aors = NULL; - ipsz = p->res->ipsz + 1; + ipsz = new_ipsz + 1; break; case IPAddressChoice_addressesOrRanges: aors = af->ipAddressChoice->u.addressesOrRanges; - ipsz = p->res->ipsz + sk_IPAddressOrRange_num(aors); + ipsz = new_ipsz + sk_IPAddressOrRange_num(aors); break; default: warnx("%s: RFC 3779: IPAddressChoice: unknown type %d", - p->fn, af->ipAddressChoice->type); + fn, af->ipAddressChoice->type); goto out; } - if (ipsz == p->res->ipsz) { + if (ipsz == new_ipsz) { warnx("%s: RFC 6487 section 4.8.10: " - "empty ipAddressesOrRanges", p->fn); + "empty ipAddressesOrRanges", fn); goto out; } if (ipsz >= MAX_IP_SIZE) goto out; - p->res->ips = recallocarray(p->res->ips, p->res->ipsz, ipsz, + ips = recallocarray(ips, new_ipsz, ipsz, sizeof(struct cert_ip)); - if (p->res->ips == NULL) + if (ips == NULL) err(1, NULL); - if (!ip_addr_afi_parse(p->fn, af->addressFamily, &afi)) { - warnx("%s: RFC 3779: invalid AFI", p->fn); + if (!ip_addr_afi_parse(fn, af->addressFamily, &afi)) { + warnx("%s: RFC 3779: invalid AFI", fn); goto out; } if (aors == NULL) { - if (!sbgp_addr_inherit(p->fn, p->res->ips, - &p->res->ipsz, afi)) + if (!sbgp_addr_inherit(fn, ips, &new_ipsz, afi)) goto out; continue; } @@ -405,23 +411,60 @@ sbgp_ipaddrblk(struct parse *p, X509_EXTENSION *ext) aor = sk_IPAddressOrRange_value(aors, j); switch (aor->type) { case IPAddressOrRange_addressPrefix: - if (!sbgp_addr(p->fn, p->res->ips, - &p->res->ipsz, afi, aor->u.addressPrefix)) + if (!sbgp_addr(fn, ips, &new_ipsz, afi, + aor->u.addressPrefix)) goto out; break; case IPAddressOrRange_addressRange: - if (!sbgp_addr_range(p->fn, p->res->ips, - &p->res->ipsz, afi, aor->u.addressRange)) + if (!sbgp_addr_range(fn, ips, &new_ipsz, afi, + aor->u.addressRange)) goto out; break; default: warnx("%s: RFC 3779: IPAddressOrRange: " - "unknown type %d", p->fn, aor->type); + "unknown type %d", fn, aor->type); goto out; } } } + *out_ips = ips; + *out_ipsz = new_ipsz; + + return 1; + + out: + free(ips); + + return 0; +} + +/* + * Parse an sbgp-ipAddrBlock X509 extension, RFC 6487 4.8.10, with + * syntax documented in RFC 3779 starting in section 2.2. + * Returns zero on failure, non-zero on success. + */ +static int +sbgp_ipaddrblk(struct parse *p, X509_EXTENSION *ext) +{ + STACK_OF(IPAddressFamily) *addrblk = NULL; + int rc = 0; + + if (!X509_EXTENSION_get_critical(ext)) { + warnx("%s: RFC 6487 section 4.8.10: sbgp-ipAddrBlock: " + "extension not critical", p->fn); + goto out; + } + + if ((addrblk = X509V3_EXT_d2i(ext)) == NULL) { + warnx("%s: RFC 6487 section 4.8.10: sbgp-ipAddrBlock: " + "failed extension parse", p->fn); + goto out; + } + + if (!sbgp_parse_ipaddrblk(p->fn, addrblk, &p->res->ips, &p->res->ipsz)) + goto out; + if (p->res->ipsz == 0) { warnx("%s: RFC 6487 section 4.8.10: empty ipAddrBlock", p->fn); goto out; diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index 54975251ab9..53ff444e843 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.191 2023/09/25 11:08:45 tb Exp $ */ +/* $OpenBSD: extern.h,v 1.192 2023/09/25 14:56:20 tb Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -723,6 +723,9 @@ int sbgp_addr(const char *, struct cert_ip *, size_t *, int sbgp_addr_range(const char *, struct cert_ip *, size_t *, enum afi, const IPAddressRange *); +int sbgp_parse_ipaddrblk(const char *, const IPAddrBlocks *, + struct cert_ip **, size_t *); + /* Work with RFC 3779 AS numbers, ranges. */ int as_id_parse(const ASN1_INTEGER *, uint32_t *); @@ -736,6 +739,9 @@ int sbgp_as_id(const char *, struct cert_as *, size_t *, int sbgp_as_range(const char *, struct cert_as *, size_t *, const ASRange *); +int sbgp_parse_assysnum(const char *, const ASIdentifiers *, + struct cert_as **, size_t *); + /* Parser-specific */ void entity_free(struct entity *); void entity_read_req(struct ibuf *, struct entity *);