On Mon, Sep 25, 2023 at 04:38:48PM +0200, Theo Buehler wrote: > On Mon, Sep 25, 2023 at 02:47:37PM +0200, Claudio Jeker wrote: > > On Sat, Sep 23, 2023 at 01:23:34PM +0200, Theo Buehler wrote: > > > This is a second chunk split out of the diff mentioned in my previous > > > mail. It factors the parsing of ASIdentifiers and IPAddrBlocks out of > > > sbgp_assysnum() and sbgp_ipaddrblk() and makes the latter only extract > > > the info from the X509_EXTENSION. This should not change anything, but > > > the logic is a bit tricky. > > > > > > We could initialize *as and *asz, as well as *ips and *ipsz to NULL/0, > > > at the top of the two new sbgp_parse_*. > > > > It looks inded like nthing is changed. The thing I dislike a bit is how > > **as and *asz are updated inside the sbgp_parse_* functions. There is > > return 0 before and after the calloc / recallocarray calls and so it > > depends a lot on the caller to be careful here. The code right now is ok. > > Thanks for that clue. I didn't particularly like my diff either. The > below is better, has less churn and should be easier to review. This way > the caller doesn't have to be careful. > > I left the currently existing variables asz and ipsz untouched since it > becomes too confusing. I want to rename asz -> sz and new_asz -> asz in > a follow-up, similarly for ipsz.
Indeed much better. OK claudio@ > Index: cert.c > =================================================================== > RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v > retrieving revision 1.115 > diff -u -p -r1.115 cert.c > --- cert.c 12 Sep 2023 09:33:30 -0000 1.115 > +++ cert.c 25 Sep 2023 14:29:56 -0000 > @@ -153,40 +153,26 @@ sbgp_as_inherit(const char *fn, struct c > 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_EXTE > 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_EXTE > 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 > 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; > + 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 (!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; > - } > + 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_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,22 +411,59 @@ sbgp_ipaddrblk(struct parse *p, X509_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); > -- :wq Claudio