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_*.

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      23 Sep 2023 11:03:48 -0000
@@ -153,74 +153,56 @@ 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 **as, size_t *asz)
 {
-       ASIdentifiers           *asidentifiers = NULL;
        const ASIdOrRanges      *aors = NULL;
-       size_t                   asz;
-       int                      i, 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;
-       }
+       size_t                   sz;
+       int                      i;
 
        if (asidentifiers->rdi != NULL) {
                warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: "
-                   "should not have RDI values", p->fn);
-               goto out;
+                   "should not have RDI values", fn);
+               return 0;
        }
 
        if (asidentifiers->asnum == NULL) {
                warnx("%s: RFC 6487 section 4.8.11: autonomousSysNum: "
-                   "no AS number resource set", p->fn);
-               goto out;
+                   "no AS number resource set", fn);
+               return 0;
        }
 
        switch (asidentifiers->asnum->type) {
        case ASIdentifierChoice_inherit:
-               asz = 1;
+               sz = 1;
                break;
        case ASIdentifierChoice_asIdsOrRanges:
                aors = asidentifiers->asnum->u.asIdsOrRanges;
-               asz = sk_ASIdOrRange_num(aors);
+               sz = sk_ASIdOrRange_num(aors);
                break;
        default:
                warnx("%s: RFC 3779 section 3.2.3.2: ASIdentifierChoice: "
-                   "unknown type %d", p->fn, asidentifiers->asnum->type);
-               goto out;
+                   "unknown type %d", fn, asidentifiers->asnum->type);
+               return 0;
        }
 
-       if (asz == 0) {
-               warnx("%s: RFC 6487 section 4.8.11: empty asIdsOrRanges",
-                   p->fn);
-               goto out;
+       if (sz == 0) {
+               warnx("%s: RFC 6487 section 4.8.11: empty asIdsOrRanges", fn);
+               return 0;
        }
-       if (asz >= MAX_AS_SIZE) {
+       if (sz >= MAX_AS_SIZE) {
                warnx("%s: too many AS number entries: limit %d",
-                   p->fn, MAX_AS_SIZE);
-               goto out;
+                   fn, MAX_AS_SIZE);
+               return 0;
        }
-       p->res->as = calloc(asz, sizeof(struct cert_as));
-       if (p->res->as == NULL)
+       *as = calloc(sz, 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))
-                       goto out;
+               if (!sbgp_as_inherit(fn, *as, asz))
+                       return 0;
        }
 
        for (i = 0; i < sk_ASIdOrRange_num(aors); i++) {
@@ -229,22 +211,49 @@ 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))
-                               goto out;
+                       if (!sbgp_as_id(fn, *as, asz, aor->u.id))
+                               return 0;
                        break;
                case ASIdOrRange_range:
-                       if (!sbgp_as_range(p->fn, p->res->as, &p->res->asz,
-                           aor->u.range))
-                               goto out;
+                       if (!sbgp_as_range(fn, *as, asz, aor->u.range))
+                               return 0;
                        break;
                default:
                        warnx("%s: RFC 3779 section 3.2.3.5: ASIdOrRange: "
-                           "unknown type %d", p->fn, aor->type);
-                       goto out;
+                           "unknown type %d", fn, aor->type);
+                       return 0;
                }
        }
 
+       return 1;
+}
+
+/*
+ * 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 +340,16 @@ 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 **ips, size_t *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;
-       }
-
-       if ((addrblk = X509V3_EXT_d2i(ext)) == NULL) {
-               warnx("%s: RFC 6487 section 4.8.10: sbgp-ipAddrBlock: "
-                   "failed extension parse", p->fn);
-               goto out;
-       }
+       const IPAddressFamily   *af;
+       const IPAddressOrRanges *aors;
+       const IPAddressOrRange  *aor;
+       enum afi                 afi;
+       size_t                   sz;
+       int                      i, j;
 
        for (i = 0; i < sk_IPAddressFamily_num(addrblk); i++) {
                af = sk_IPAddressFamily_value(addrblk, i);
@@ -365,39 +357,37 @@ sbgp_ipaddrblk(struct parse *p, X509_EXT
                switch (af->ipAddressChoice->type) {
                case IPAddressChoice_inherit:
                        aors = NULL;
-                       ipsz = p->res->ipsz + 1;
+                       sz = *ipsz + 1;
                        break;
                case IPAddressChoice_addressesOrRanges:
                        aors = af->ipAddressChoice->u.addressesOrRanges;
-                       ipsz = p->res->ipsz + sk_IPAddressOrRange_num(aors);
+                       sz = *ipsz + sk_IPAddressOrRange_num(aors);
                        break;
                default:
                        warnx("%s: RFC 3779: IPAddressChoice: unknown type %d",
-                           p->fn, af->ipAddressChoice->type);
-                       goto out;
+                           fn, af->ipAddressChoice->type);
+                       return 0;
                }
-               if (ipsz == p->res->ipsz) {
+               if (sz == *ipsz) {
                        warnx("%s: RFC 6487 section 4.8.10: "
-                           "empty ipAddressesOrRanges", p->fn);
-                       goto out;
+                           "empty ipAddressesOrRanges", fn);
+                       return 0;
                }
 
-               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)
+               if (sz >= MAX_IP_SIZE)
+                       return 0;
+               *ips = recallocarray(*ips, *ipsz, sz, sizeof(struct cert_ip));
+               if (*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 (!ip_addr_afi_parse(fn, af->addressFamily, &afi)) {
+                       warnx("%s: RFC 3779: invalid AFI", fn);
+                       return 0;
                }
 
                if (aors == NULL) {
-                       if (!sbgp_addr_inherit(p->fn, p->res->ips,
-                           &p->res->ipsz, afi))
-                               goto out;
+                       if (!sbgp_addr_inherit(fn, *ips, ipsz, afi))
+                               return 0;
                        continue;
                }
 
@@ -405,22 +395,51 @@ 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))
-                                       goto out;
+                               if (!sbgp_addr(fn, *ips, ipsz, afi,
+                                   aor->u.addressPrefix))
+                                       return 0;
                                break;
                        case IPAddressOrRange_addressRange:
-                               if (!sbgp_addr_range(p->fn, p->res->ips,
-                                   &p->res->ipsz, afi, aor->u.addressRange))
-                                       goto out;
+                               if (!sbgp_addr_range(fn, *ips, ipsz, afi,
+                                   aor->u.addressRange))
+                                       return 0;
                                break;
                        default:
                                warnx("%s: RFC 3779: IPAddressOrRange: "
-                                   "unknown type %d", p->fn, aor->type);
-                               goto out;
+                                   "unknown type %d", fn, aor->type);
+                               return 0;
                        }
                }
        }
+
+       return 1;
+}
+
+/*
+ * 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);
Index: extern.h
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.189
diff -u -p -r1.189 extern.h
--- extern.h    12 Sep 2023 09:33:30 -0000      1.189
+++ extern.h    23 Sep 2023 11:04:23 -0000
@@ -721,6 +721,9 @@ int          sbgp_addr(const char *, struct cer
 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 *);
@@ -733,6 +736,9 @@ int          sbgp_as_id(const char *, struct ce
                    const ASN1_INTEGER *);
 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 *);

Reply via email to