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

Reply via email to