On Thu, May 12, 2022 at 11:27:21AM +0200, Theo Buehler wrote:
> This aligns sbgp_ipaddrblk() with sbgp_assysnum(), giving it a similar
> treatment. We trade the reallocarray() per prefix or range with at most
> two recallocarray(). I took the liberty of trimming some RFC section
> numbers in warnings to avoid awkward line wrapping.

Looks good to me. Ok claudio@
 
> Index: cert.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
> retrieving revision 1.80
> diff -u -p -r1.80 cert.c
> --- cert.c    12 May 2022 08:53:33 -0000      1.80
> +++ cert.c    12 May 2022 09:13:15 -0000
> @@ -1,4 +1,4 @@
> -/*   $OpenBSD: cert.c,v 1.80 2022/05/12 08:53:33 tb Exp $ */
> +/*   $OpenBSD: cert.c,v 1.79 2022/05/12 07:45:27 claudio Exp $ */
>  /*
>   * Copyright (c) 2021 Job Snijders <[email protected]>
>   * Copyright (c) 2019 Kristaps Dzonsons <[email protected]>
> @@ -60,17 +60,9 @@ extern ASN1_OBJECT *notify_oid;    /* 1.3.6
>  static int
>  append_ip(struct parse *p, const struct cert_ip *ip)
>  {
> -     struct cert     *res = p->res;
> -
>       if (!ip_addr_check_overlap(ip, p->fn, p->res->ips, p->res->ipsz))
>               return 0;
> -     if (res->ipsz >= MAX_IP_SIZE)
> -             return 0;
> -     res->ips = reallocarray(res->ips, res->ipsz + 1,
> -         sizeof(struct cert_ip));
> -     if (res->ips == NULL)
> -             err(1, NULL);
> -     res->ips[res->ipsz++] = *ip;
> +     p->res->ips[p->res->ipsz++] = *ip;
>       return 1;
>  }
>  
> @@ -330,84 +322,6 @@ sbgp_addr_inherit(struct parse *p, enum 
>  }
>  
>  /*
> - * Parse an IP address or range, RFC 3779 2.2.3.7.
> - * We don't constrain this parse (as specified in section 2.2.3.6) to
> - * having any kind of order.
> - * Returns zero on failure, non-zero on success.
> - */
> -static int
> -sbgp_addr_or_range(struct parse *p, enum afi afi, const IPAddressOrRanges 
> *aors)
> -{
> -     const IPAddressOrRange  *aor;
> -     int                      i, rc = 0;
> -
> -     for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
> -             aor = sk_IPAddressOrRange_value(aors, i);
> -             switch (aor->type) {
> -             case IPAddressOrRange_addressPrefix:
> -                     if (!sbgp_addr(p, afi, aor->u.addressPrefix))
> -                             goto out;
> -                     break;
> -             case IPAddressOrRange_addressRange:
> -                     if (!sbgp_addr_range(p, afi, aor->u.addressRange))
> -                             goto out;
> -                     break;
> -             default:
> -                     warnx("%s: RFC 3779 section 2.2.3.7: IPAddressOrRange: "
> -                         "unknown type %d", p->fn, aor->type);
> -                     goto out;
> -             }
> -     }
> -
> -     rc = 1;
> - out:
> -     return rc;
> -}
> -
> -/*
> - * Parse a sequence of address families as in RFC 3779 sec. 2.2.3.2.
> - * Ignore several stipulations of the RFC (2.2.3.3).
> - * Namely, we don't require entries to be ordered in any way (type, AFI
> - * or SAFI group, etc.).
> - * This is because it doesn't matter for our purposes: we're going to
> - * validate in the same way regardless.
> - * Returns zero on failure, non-zero on success.
> - */
> -static int
> -sbgp_ipaddrfam(struct parse *p, const IPAddressFamily *af)
> -{
> -     enum afi                 afi;
> -     const IPAddressChoice   *choice;
> -     int                      rc = 0;
> -
> -     if (!ip_addr_afi_parse(p->fn, af->addressFamily, &afi)) {
> -             warnx("%s: RFC 3779 section 2.2.3.2: addressFamily: "
> -                 "invalid AFI", p->fn);
> -             goto out;
> -     }
> -
> -     choice = af->ipAddressChoice;
> -     switch (choice->type) {
> -     case IPAddressChoice_addressesOrRanges:
> -             if (!sbgp_addr_or_range(p, afi, choice->u.addressesOrRanges))
> -                     goto out;
> -             break;
> -     case IPAddressChoice_inherit:
> -             if (!sbgp_addr_inherit(p, afi))
> -                     goto out;
> -             break;
> -     default:
> -             warnx("%s: RFC 3779 section 2.2.3.2: IPAddressChoice: "
> -                 "unknown type %d", p->fn, choice->type);
> -             goto out;
> -     }
> -
> -     rc = 1;
> - out:
> -     return rc;
> -}
> -
> -/*
>   * 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.
> @@ -417,7 +331,11 @@ sbgp_ipaddrblk(struct parse *p, X509_EXT
>  {
>       STACK_OF(IPAddressFamily)       *addrblk = NULL;
>       const IPAddressFamily           *af;
> -     int                              i, rc = 0;
> +     const IPAddressOrRanges         *aors;
> +     const IPAddressOrRange          *aor;
> +     enum afi                         afi;
> +     size_t                           ipsz;
> +     int                              i, j, rc = 0;
>  
>       if (!X509_EXTENSION_get_critical(ext)) {
>               cryptowarnx("%s: RFC 6487 section 4.8.10: sbgp-ipAddrBlock: "
> @@ -433,8 +351,58 @@ sbgp_ipaddrblk(struct parse *p, X509_EXT
>  
>       for (i = 0; i < sk_IPAddressFamily_num(addrblk); i++) {
>               af = sk_IPAddressFamily_value(addrblk, i);
> -             if (!sbgp_ipaddrfam(p, af))
> +
> +             switch (af->ipAddressChoice->type) {
> +             case IPAddressChoice_inherit:
> +                     aors = NULL;
> +                     ipsz = p->res->ipsz + 1;
> +                     break;
> +             case IPAddressChoice_addressesOrRanges:
> +                     aors = af->ipAddressChoice->u.addressesOrRanges;
> +                     ipsz = p->res->ipsz + sk_IPAddressOrRange_num(aors);
> +                     break;
> +             default:
> +                     warnx("%s: RFC 3779: IPAddressChoice: unknown type %d",
> +                         p->fn, af->ipAddressChoice->type);
> +                     goto out;
> +             }
> +
> +             if (ipsz >= MAX_IP_SIZE)
> +                     goto out;
> +             p->res->ips = recallocarray(p->res->ips, p->res->ipsz, ipsz,
> +                 sizeof(struct cert_ip));
> +             if (p->res->ips == NULL)
> +                     err(1, NULL);
> +
> +             if (!ip_addr_afi_parse(p->fn, af->addressFamily, &afi)) {
> +                     warnx("%s: RFC 3779: invalid AFI", p->fn);
>                       goto out;
> +             }
> +
> +             if (aors == NULL) {
> +                     if (!sbgp_addr_inherit(p, afi))
> +                             goto out;
> +                     continue;
> +             }
> +
> +             for (j = 0; j < sk_IPAddressOrRange_num(aors); j++) {
> +                     aor = sk_IPAddressOrRange_value(aors, j);
> +                     switch (aor->type) {
> +                     case IPAddressOrRange_addressPrefix:
> +                             if (!sbgp_addr(p, afi, aor->u.addressPrefix))
> +                                     goto out;
> +                             break;
> +                     case IPAddressOrRange_addressRange:
> +                             if (!sbgp_addr_range(p, afi,
> +                                 aor->u.addressRange))
> +                                     goto out;
> +                             break;
> +                     default:
> +                             warnx("%s: RFC 3779: IPAddressOrRange: "
> +                                 "unknown type %d", p->fn, aor->type);
> +                             goto out;
> +                     }
> +             }
>       }
>  
>       rc = 1;
> 

-- 
:wq Claudio

Reply via email to