rpki-client: remove the remaining struct parse
authortb <tb@openbsd.org>
Wed, 21 Feb 2024 09:17:06 +0000 (09:17 +0000)
committertb <tb@openbsd.org>
Wed, 21 Feb 2024 09:17:06 +0000 (09:17 +0000)
With the exception of mft.c where there is an additional boolean, this
struct carries a file name and a result. This means functions having
struct parse in the signature can't be shared between files, which has
been annoying. Simply pass file name and necessary info directly as a
function parameter and add a small dance to handle the boolean in mft.c.

ok job

usr.sbin/rpki-client/aspa.c
usr.sbin/rpki-client/gbr.c
usr.sbin/rpki-client/geofeed.c
usr.sbin/rpki-client/mft.c
usr.sbin/rpki-client/roa.c
usr.sbin/rpki-client/rsc.c
usr.sbin/rpki-client/tak.c

index 294c45b..6ec63b6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: aspa.c,v 1.27 2024/02/16 15:13:49 tb Exp $ */
+/*     $OpenBSD: aspa.c,v 1.28 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2022 Job Snijders <job@fastly.com>
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
 
 #include "extern.h"
 
-/*
- * Parse results and data of the ASPA object.
- */
-struct parse {
-       const char       *fn; /* ASPA file name */
-       struct aspa      *res; /* results */
-};
-
 extern ASN1_OBJECT     *aspa_oid;
 
 /*
@@ -68,26 +60,26 @@ IMPLEMENT_ASN1_FUNCTIONS(ASProviderAttestation);
  * Return zero on failure, non-zero on success.
  */
 static int
-aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
+aspa_parse_providers(const char *fn, struct aspa *aspa,
+    const STACK_OF(ASN1_INTEGER) *providers)
 {
        const ASN1_INTEGER      *pa;
        uint32_t                 provider;
        size_t                   providersz, i;
 
        if ((providersz = sk_ASN1_INTEGER_num(providers)) == 0) {
-               warnx("%s: ASPA: ProviderASSet needs at least one entry",
-                   p->fn);
+               warnx("%s: ASPA: ProviderASSet needs at least one entry", fn);
                return 0;
        }
 
        if (providersz >= MAX_ASPA_PROVIDERS) {
-               warnx("%s: ASPA: too many providers (more than %d)", p->fn,
+               warnx("%s: ASPA: too many providers (more than %d)", fn,
                    MAX_ASPA_PROVIDERS);
                return 0;
        }
 
-       p->res->providers = calloc(providersz, sizeof(provider));
-       if (p->res->providers == NULL)
+       aspa->providers = calloc(providersz, sizeof(provider));
+       if (aspa->providers == NULL)
                err(1, NULL);
 
        for (i = 0; i < providersz; i++) {
@@ -96,29 +88,29 @@ aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
                memset(&provider, 0, sizeof(provider));
 
                if (!as_id_parse(pa, &provider)) {
-                       warnx("%s: ASPA: malformed ProviderAS", p->fn);
+                       warnx("%s: ASPA: malformed ProviderAS", fn);
                        return 0;
                }
 
-               if (p->res->custasid == provider) {
+               if (aspa->custasid == provider) {
                        warnx("%s: ASPA: CustomerASID can't also be Provider",
-                           p->fn);
+                           fn);
                        return 0;
                }
 
                if (i > 0) {
-                       if  (p->res->providers[i - 1] > provider) {
+                       if (aspa->providers[i - 1] > provider) {
                                warnx("%s: ASPA: invalid ProviderASSet order",
-                                   p->fn);
+                                   fn);
                                return 0;
                        }
-                       if (p->res->providers[i - 1] == provider) {
-                               warnx("%s: ASPA: duplicate ProviderAS", p->fn);
+                       if (aspa->providers[i - 1] == provider) {
+                               warnx("%s: ASPA: duplicate ProviderAS", fn);
                                return 0;
                        }
                }
 
-               p->res->providers[p->res->providersz++] = provider;
+               aspa->providers[aspa->providersz++] = provider;
        }
 
        return 1;
@@ -129,7 +121,8 @@ aspa_parse_providers(struct parse *p, const STACK_OF(ASN1_INTEGER) *providers)
  * Returns zero on failure, non-zero on success.
  */
 static int
-aspa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
+aspa_parse_econtent(const char *fn, struct aspa *aspa, const unsigned char *d,
+    size_t dsz)
 {
        const unsigned char     *oder;
        ASProviderAttestation   *aspa_asn1;
@@ -137,24 +130,24 @@ aspa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
 
        oder = d;
        if ((aspa_asn1 = d2i_ASProviderAttestation(NULL, &d, dsz)) == NULL) {
-               warnx("%s: ASPA: failed to parse ASProviderAttestation", p->fn);
+               warnx("%s: ASPA: failed to parse ASProviderAttestation", fn);
                goto out;
        }
        if (d != oder + dsz) {
-               warnx("%s: %td bytes trailing garbage in eContent", p->fn,
+               warnx("%s: %td bytes trailing garbage in eContent", fn,
                    oder + dsz - d);
                goto out;
        }
 
-       if (!valid_econtent_version(p->fn, aspa_asn1->version, 1))
+       if (!valid_econtent_version(fn, aspa_asn1->version, 1))
                goto out;
 
-       if (!as_id_parse(aspa_asn1->customerASID, &p->res->custasid)) {
-               warnx("%s: malformed CustomerASID", p->fn);
+       if (!as_id_parse(aspa_asn1->customerASID, &aspa->custasid)) {
+               warnx("%s: malformed CustomerASID", fn);
                goto out;
        }
 
-       if (!aspa_parse_providers(p, aspa_asn1->providers))
+       if (!aspa_parse_providers(fn, aspa, aspa_asn1->providers))
                goto out;
 
        rc = 1;
@@ -171,36 +164,33 @@ struct aspa *
 aspa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
     size_t len)
 {
-       struct parse     p;
+       struct aspa     *aspa;
        size_t           cmsz;
        unsigned char   *cms;
        struct cert     *cert = NULL;
        time_t           signtime = 0;
        int              rc = 0;
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
        cms = cms_parse_validate(x509, fn, der, len, aspa_oid, &cmsz,
            &signtime);
        if (cms == NULL)
                return NULL;
 
-       if ((p.res = calloc(1, sizeof(*p.res))) == NULL)
+       if ((aspa = calloc(1, sizeof(*aspa))) == NULL)
                err(1, NULL);
 
-       p.res->signtime = signtime;
+       aspa->signtime = signtime;
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &aspa->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &aspa->aki))
                goto out;
-       if (!x509_get_sia(*x509, fn, &p.res->sia))
+       if (!x509_get_sia(*x509, fn, &aspa->sia))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &aspa->ski))
                goto out;
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
-           p.res->ski == NULL) {
+       if (aspa->aia == NULL || aspa->aki == NULL || aspa->sia == NULL ||
+           aspa->ski == NULL) {
                warnx("%s: RFC 6487 section 4.8: "
                    "missing AIA, AKI, SIA, or SKI X509 extension", fn);
                goto out;
@@ -211,9 +201,9 @@ aspa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
                goto out;
        }
 
-       if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
+       if (!x509_get_notbefore(*x509, fn, &aspa->notbefore))
                goto out;
-       if (!x509_get_notafter(*x509, fn, &p.res->notafter))
+       if (!x509_get_notafter(*x509, fn, &aspa->notafter))
                goto out;
 
        if (x509_any_inherits(*x509)) {
@@ -221,25 +211,25 @@ aspa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
                goto out;
        }
 
-       if (!aspa_parse_econtent(cms, cmsz, &p))
+       if (!aspa_parse_econtent(fn, aspa, cms, cmsz))
                goto out;
 
        if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
                goto out;
 
-       p.res->valid = valid_aspa(fn, cert, p.res);
+       aspa->valid = valid_aspa(fn, cert, aspa);
 
        rc = 1;
  out:
        if (rc == 0) {
-               aspa_free(p.res);
-               p.res = NULL;
+               aspa_free(aspa);
+               aspa = NULL;
                X509_free(*x509);
                *x509 = NULL;
        }
        cert_free(cert);
        free(cms);
-       return p.res;
+       return aspa;
 }
 
 /*
index fab3c5a..81c7747 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gbr.c,v 1.29 2023/10/13 12:06:49 job Exp $ */
+/*     $OpenBSD: gbr.c,v 1.30 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
  *
 
 #include "extern.h"
 
-/*
- * Parse results and data of the manifest file.
- */
-struct parse {
-       const char       *fn; /* manifest file name */
-       struct gbr       *res; /* results */
-};
-
 extern ASN1_OBJECT     *gbr_oid;
 
 /*
@@ -43,44 +35,41 @@ struct gbr *
 gbr_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
     size_t len)
 {
-       struct parse     p;
+       struct gbr      *gbr;
        struct cert     *cert = NULL;
        size_t           cmsz;
        unsigned char   *cms;
        time_t           signtime = 0;
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
        cms = cms_parse_validate(x509, fn, der, len, gbr_oid, &cmsz, &signtime);
        if (cms == NULL)
                return NULL;
 
-       if ((p.res = calloc(1, sizeof(*p.res))) == NULL)
+       if ((gbr = calloc(1, sizeof(*gbr))) == NULL)
                err(1, NULL);
-       p.res->signtime = signtime;
-       if ((p.res->vcard = strndup(cms, cmsz)) == NULL)
+       gbr->signtime = signtime;
+       if ((gbr->vcard = strndup(cms, cmsz)) == NULL)
                err(1, NULL);
        free(cms);
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &gbr->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &gbr->aki))
                goto out;
-       if (!x509_get_sia(*x509, fn, &p.res->sia))
+       if (!x509_get_sia(*x509, fn, &gbr->sia))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &gbr->ski))
                goto out;
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
-           p.res->ski == NULL) {
+       if (gbr->aia == NULL || gbr->aki == NULL || gbr->sia == NULL ||
+           gbr->ski == NULL) {
                warnx("%s: RFC 6487 section 4.8: "
                    "missing AIA, AKI, SIA or SKI X509 extension", fn);
                goto out;
        }
 
-       if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
+       if (!x509_get_notbefore(*x509, fn, &gbr->notbefore))
                goto out;
-       if (!x509_get_notafter(*x509, fn, &p.res->notafter))
+       if (!x509_get_notafter(*x509, fn, &gbr->notafter))
                goto out;
 
        if (!x509_inherits(*x509)) {
@@ -91,10 +80,10 @@ gbr_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
        if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
                goto out;
 
-       return p.res;
+       return gbr;
 
  out:
-       gbr_free(p.res);
+       gbr_free(gbr);
        X509_free(*x509);
        *x509 = NULL;
        cert_free(cert);
index 4cde5ce..f7d321f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: geofeed.c,v 1.15 2023/10/13 12:06:49 job Exp $ */
+/*     $OpenBSD: geofeed.c,v 1.16 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2022 Job Snijders <job@fastly.com>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
 
 #include "extern.h"
 
-struct parse {
-       const char      *fn;
-       struct geofeed  *res;
-};
-
 extern ASN1_OBJECT     *geofeed_oid;
 
 /*
@@ -43,7 +38,7 @@ extern ASN1_OBJECT    *geofeed_oid;
  * Returns 1 on success, 0 on failure.
  */
 static int
-geofeed_parse_geoip(struct geofeed *res, char *cidr, char *loc)
+geofeed_parse_geoip(struct geofeed *geofeed, char *cidr, char *loc)
 {
        struct geoip    *geoip;
        struct ip_addr  *ipaddr;
@@ -73,11 +68,11 @@ geofeed_parse_geoip(struct geofeed *res, char *cidr, char *loc)
 
        ipaddr->prefixlen = plen;
 
-       res->geoips = recallocarray(res->geoips, res->geoipsz,
-           res->geoipsz + 1, sizeof(struct geoip));
-       if (res->geoips == NULL)
+       geofeed->geoips = recallocarray(geofeed->geoips, geofeed->geoipsz,
+           geofeed->geoipsz + 1, sizeof(struct geoip));
+       if (geofeed->geoips == NULL)
                err(1, NULL);
-       geoip = &res->geoips[res->geoipsz++];
+       geoip = &geofeed->geoips[geofeed->geoipsz++];
 
        if ((geoip->ip = calloc(1, sizeof(struct cert_ip))) == NULL)
                err(1, NULL);
@@ -102,7 +97,7 @@ geofeed_parse_geoip(struct geofeed *res, char *cidr, char *loc)
 struct geofeed *
 geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
 {
-       struct parse     p;
+       struct geofeed  *geofeed;
        char            *delim, *line, *loc, *nl;
        ssize_t          linelen;
        BIO             *bio;
@@ -118,10 +113,7 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
        if (bio == NULL)
                errx(1, "BIO_new");
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
-       if ((p.res = calloc(1, sizeof(struct geofeed))) == NULL)
+       if ((geofeed = calloc(1, sizeof(*geofeed))) == NULL)
                err(1, NULL);
 
        while ((nl = memchr(buf, '\n', len)) != NULL) {
@@ -217,7 +209,7 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
                        loc = "";
 
                /* read each prefix  */
-               if (!geofeed_parse_geoip(p.res, line, loc))
+               if (!geofeed_parse_geoip(geofeed, line, loc))
                        goto out;
        }
 
@@ -232,24 +224,25 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
        }
 
        if (!cms_parse_validate_detached(x509, fn, der, dersz, geofeed_oid,
-           bio, &p.res->signtime))
+           bio, &geofeed->signtime))
                goto out;
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &geofeed->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &geofeed->aki))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &geofeed->ski))
                goto out;
 
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+       if (geofeed->aia == NULL || geofeed->aki == NULL ||
+           geofeed->ski == NULL) {
                warnx("%s: missing AIA, AKI, or SKI X509 extension", fn);
                goto out;
        }
 
-       if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
+       if (!x509_get_notbefore(*x509, fn, &geofeed->notbefore))
                goto out;
-       if (!x509_get_notafter(*x509, fn, &p.res->notafter))
+       if (!x509_get_notafter(*x509, fn, &geofeed->notafter))
                goto out;
 
        if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
@@ -265,13 +258,13 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
                goto out;
        }
 
-       p.res->valid = valid_geofeed(fn, cert, p.res);
+       geofeed->valid = valid_geofeed(fn, cert, geofeed);
 
        rc = 1;
  out:
        if (rc == 0) {
-               geofeed_free(p.res);
-               p.res = NULL;
+               geofeed_free(geofeed);
+               geofeed = NULL;
                X509_free(*x509);
                *x509 = NULL;
        }
@@ -280,7 +273,7 @@ geofeed_parse(X509 **x509, const char *fn, int talid, char *buf, size_t len)
        free(b64);
        free(der);
 
-       return p.res;
+       return geofeed;
 }
 
 /*
index 59285ca..bc3fb93 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: mft.c,v 1.110 2024/02/16 15:18:08 tb Exp $ */
+/*     $OpenBSD: mft.c,v 1.111 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
 
 #include "extern.h"
 
-/*
- * Parse results and data of the manifest file.
- */
-struct parse {
-       const char      *fn; /* manifest file name */
-       struct mft      *res; /* result object */
-       int              found_crl;
-};
-
 extern ASN1_OBJECT     *mft_oid;
 
 /*
@@ -183,7 +174,8 @@ rtype_from_mftfile(const char *fn)
  * Return zero on failure, non-zero on success.
  */
 static int
-mft_parse_filehash(struct parse *p, const FileAndHash *fh)
+mft_parse_filehash(const char *fn, struct mft *mft, const FileAndHash *fh,
+    int *found_crl)
 {
        char                    *file = NULL;
        int                      rc = 0;
@@ -192,7 +184,7 @@ mft_parse_filehash(struct parse *p, const FileAndHash *fh)
        size_t                   new_idx = 0;
 
        if (!valid_mft_filename(fh->file->data, fh->file->length)) {
-               warnx("%s: RFC 6486 section 4.2.2: bad filename", p->fn);
+               warnx("%s: RFC 6486 section 4.2.2: bad filename", fn);
                goto out;
        }
        file = strndup(fh->file->data, fh->file->length);
@@ -201,25 +193,24 @@ mft_parse_filehash(struct parse *p, const FileAndHash *fh)
 
        if (fh->hash->length != SHA256_DIGEST_LENGTH) {
                warnx("%s: RFC 6486 section 4.2.1: hash: "
-                   "invalid SHA256 length, have %d",
-                   p->fn, fh->hash->length);
+                   "invalid SHA256 length, have %d", fn, fh->hash->length);
                goto out;
        }
 
        type = rtype_from_mftfile(file);
        /* remember the filehash for the CRL in struct mft */
-       if (type == RTYPE_CRL && strcmp(file, p->res->crl) == 0) {
-               memcpy(p->res->crlhash, fh->hash->data, SHA256_DIGEST_LENGTH);
-               p->found_crl = 1;
+       if (type == RTYPE_CRL && strcmp(file, mft->crl) == 0) {
+               memcpy(mft->crlhash, fh->hash->data, SHA256_DIGEST_LENGTH);
+               *found_crl = 1;
        }
 
        if (filemode)
-               fent = &p->res->files[p->res->filesz++];
+               fent = &mft->files[mft->filesz++];
        else {
                /* Fisher-Yates shuffle */
-               new_idx = arc4random_uniform(p->res->filesz + 1);
-               p->res->files[p->res->filesz++] = p->res->files[new_idx];
-               fent = &p->res->files[new_idx];
+               new_idx = arc4random_uniform(mft->filesz + 1);
+               mft->files[mft->filesz++] = mft->files[new_idx];
+               fent = &mft->files[new_idx];
        }
 
        fent->type = type;
@@ -308,30 +299,30 @@ mft_has_unique_names_and_hashes(const char *fn, const Manifest *mft)
  * Returns 0 on failure and 1 on success.
  */
 static int
-mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
+mft_parse_econtent(const char *fn, struct mft *mft, const unsigned char *d,
+    size_t dsz)
 {
        const unsigned char     *oder;
        Manifest                *mft_asn1;
        FileAndHash             *fh;
-       int                      i, rc = 0;
+       int                      found_crl, i, rc = 0;
 
        oder = d;
        if ((mft_asn1 = d2i_Manifest(NULL, &d, dsz)) == NULL) {
-               warnx("%s: RFC 6486 section 4: failed to parse Manifest",
-                   p->fn);
+               warnx("%s: RFC 6486 section 4: failed to parse Manifest", fn);
                goto out;
        }
        if (d != oder + dsz) {
-               warnx("%s: %td bytes trailing garbage in eContent", p->fn,
+               warnx("%s: %td bytes trailing garbage in eContent", fn,
                    oder + dsz - d);
                goto out;
        }
 
-       if (!valid_econtent_version(p->fn, mft_asn1->version, 0))
+       if (!valid_econtent_version(fn, mft_asn1->version, 0))
                goto out;
 
-       p->res->seqnum = x509_convert_seqnum(p->fn, mft_asn1->manifestNumber);
-       if (p->res->seqnum == NULL)
+       mft->seqnum = x509_convert_seqnum(fn, mft_asn1->manifestNumber);
+       if (mft->seqnum == NULL)
                goto out;
 
        /*
@@ -339,60 +330,61 @@ mft_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
         * which doesn't conform to RFC 5280. So, double check.
         */
        if (ASN1_STRING_length(mft_asn1->thisUpdate) != GENTIME_LENGTH) {
-               warnx("%s: embedded from time format invalid", p->fn);
+               warnx("%s: embedded from time format invalid", fn);
                goto out;
        }
        if (ASN1_STRING_length(mft_asn1->nextUpdate) != GENTIME_LENGTH) {
-               warnx("%s: embedded until time format invalid", p->fn);
+               warnx("%s: embedded until time format invalid", fn);
                goto out;
        }
 
-       if (!x509_get_time(mft_asn1->thisUpdate, &p->res->thisupdate)) {
-               warn("%s: parsing manifest thisUpdate failed", p->fn);
+       if (!x509_get_time(mft_asn1->thisUpdate, &mft->thisupdate)) {
+               warn("%s: parsing manifest thisUpdate failed", fn);
                goto out;
        }
-       if (!x509_get_time(mft_asn1->nextUpdate, &p->res->nextupdate)) {
-               warn("%s: parsing manifest nextUpdate failed", p->fn);
+       if (!x509_get_time(mft_asn1->nextUpdate, &mft->nextupdate)) {
+               warn("%s: parsing manifest nextUpdate failed", fn);
                goto out;
        }
 
-       if (p->res->thisupdate > p->res->nextupdate) {
-               warnx("%s: bad update interval", p->fn);
+       if (mft->thisupdate > mft->nextupdate) {
+               warnx("%s: bad update interval", fn);
                goto out;
        }
 
        if (OBJ_obj2nid(mft_asn1->fileHashAlg) != NID_sha256) {
                warnx("%s: RFC 6486 section 4.2.1: fileHashAlg: "
-                   "want SHA256 object, have %s (NID %d)", p->fn,
+                   "want SHA256 object, have %s (NID %d)", fn,
                    ASN1_tag2str(OBJ_obj2nid(mft_asn1->fileHashAlg)),
                    OBJ_obj2nid(mft_asn1->fileHashAlg));
                goto out;
        }
 
        if (sk_FileAndHash_num(mft_asn1->fileList) >= MAX_MANIFEST_ENTRIES) {
-               warnx("%s: %d exceeds manifest entry limit (%d)", p->fn,
+               warnx("%s: %d exceeds manifest entry limit (%d)", fn,
                    sk_FileAndHash_num(mft_asn1->fileList),
                    MAX_MANIFEST_ENTRIES);
                goto out;
        }
 
-       p->res->files = calloc(sk_FileAndHash_num(mft_asn1->fileList),
+       mft->files = calloc(sk_FileAndHash_num(mft_asn1->fileList),
            sizeof(struct mftfile));
-       if (p->res->files == NULL)
+       if (mft->files == NULL)
                err(1, NULL);
 
+       found_crl = 0;
        for (i = 0; i < sk_FileAndHash_num(mft_asn1->fileList); i++) {
                fh = sk_FileAndHash_value(mft_asn1->fileList, i);
-               if (!mft_parse_filehash(p, fh))
+               if (!mft_parse_filehash(fn, mft, fh, &found_crl))
                        goto out;
        }
 
-       if (!p->found_crl) {
-               warnx("%s: CRL not part of MFT fileList", p->fn);
+       if (!found_crl) {
+               warnx("%s: CRL not part of MFT fileList", fn);
                goto out;
        }
 
-       if (!mft_has_unique_names_and_hashes(p->fn, mft_asn1))
+       if (!mft_has_unique_names_and_hashes(fn, mft_asn1))
                goto out;
 
        rc = 1;
@@ -409,7 +401,7 @@ struct mft *
 mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
     size_t len)
 {
-       struct parse     p;
+       struct mft      *mft;
        struct cert     *cert = NULL;
        int              rc = 0;
        size_t           cmsz;
@@ -417,28 +409,25 @@ mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
        char            *crldp = NULL, *crlfile;
        time_t           signtime = 0;
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
        cms = cms_parse_validate(x509, fn, der, len, mft_oid, &cmsz, &signtime);
        if (cms == NULL)
                return NULL;
        assert(*x509 != NULL);
 
-       if ((p.res = calloc(1, sizeof(struct mft))) == NULL)
+       if ((mft = calloc(1, sizeof(*mft))) == NULL)
                err(1, NULL);
-       p.res->signtime = signtime;
+       mft->signtime = signtime;
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &mft->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &mft->aki))
                goto out;
-       if (!x509_get_sia(*x509, fn, &p.res->sia))
+       if (!x509_get_sia(*x509, fn, &mft->sia))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &mft->ski))
                goto out;
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
-           p.res->ski == NULL) {
+       if (mft->aia == NULL || mft->aki == NULL || mft->sia == NULL ||
+           mft->ski == NULL) {
                warnx("%s: RFC 6487 section 4.8: "
                    "missing AIA, AKI, SIA, or SKI X509 extension", fn);
                goto out;
@@ -470,16 +459,16 @@ mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
                    "bad CRL distribution point extension", fn);
                goto out;
        }
-       if ((p.res->crl = strdup(crlfile)) == NULL)
+       if ((mft->crl = strdup(crlfile)) == NULL)
                err(1, NULL);
 
-       if (mft_parse_econtent(cms, cmsz, &p) == 0)
+       if (mft_parse_econtent(fn, mft, cms, cmsz) == 0)
                goto out;
 
        if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
                goto out;
 
-       if (p.res->signtime > p.res->nextupdate) {
+       if (mft->signtime > mft->nextupdate) {
                warnx("%s: dating issue: CMS signing-time after MFT nextUpdate",
                    fn);
                goto out;
@@ -488,15 +477,15 @@ mft_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
        rc = 1;
 out:
        if (rc == 0) {
-               mft_free(p.res);
-               p.res = NULL;
+               mft_free(mft);
+               mft = NULL;
                X509_free(*x509);
                *x509 = NULL;
        }
        free(crldp);
        cert_free(cert);
        free(cms);
-       return p.res;
+       return mft;
 }
 
 /*
index 633c200..9c98ca9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: roa.c,v 1.76 2024/02/16 15:13:49 tb Exp $ */
+/*     $OpenBSD: roa.c,v 1.77 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
  * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
 
 #include "extern.h"
 
-/*
- * Parse results and data of the manifest file.
- */
-struct parse {
-       const char       *fn; /* manifest file name */
-       struct roa       *res; /* results */
-};
-
 extern ASN1_OBJECT     *roa_oid;
 
 /*
@@ -103,7 +95,8 @@ IMPLEMENT_ASN1_FUNCTIONS(RouteOriginAttestation);
  * Returns zero on failure, non-zero on success.
  */
 static int
-roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
+roa_parse_econtent(const char *fn, struct roa *roa, const unsigned char *d,
+    size_t dsz)
 {
        const unsigned char             *oder;
        RouteOriginAttestation          *roa_asn1;
@@ -121,39 +114,40 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
        oder = d;
        if ((roa_asn1 = d2i_RouteOriginAttestation(NULL, &d, dsz)) == NULL) {
                warnx("%s: RFC 6482 section 3: failed to parse "
-                   "RouteOriginAttestation", p->fn);
+                   "RouteOriginAttestation", fn);
                goto out;
        }
        if (d != oder + dsz) {
-               warnx("%s: %td bytes trailing garbage in eContent", p->fn,
+               warnx("%s: %td bytes trailing garbage in eContent", fn,
                    oder + dsz - d);
                goto out;
        }
 
-       if (!valid_econtent_version(p->fn, roa_asn1->version, 0))
+       if (!valid_econtent_version(fn, roa_asn1->version, 0))
                goto out;
 
-       if (!as_id_parse(roa_asn1->asid, &p->res->asid)) {
+       if (!as_id_parse(roa_asn1->asid, &roa->asid)) {
                warnx("%s: RFC 6482 section 3.2: asID: "
-                   "malformed AS identifier", p->fn);
+                   "malformed AS identifier", fn);
                goto out;
        }
 
        ipaddrblocksz = sk_ROAIPAddressFamily_num(roa_asn1->ipAddrBlocks);
        if (ipaddrblocksz != 1 && ipaddrblocksz != 2) {
                warnx("%s: draft-rfc6482bis: unexpected number of ipAddrBlocks "
-                   "(got %d, expected 1 or 2)", p->fn, ipaddrblocksz);
+                   "(got %d, expected 1 or 2)", fn, ipaddrblocksz);
                goto out;
        }
 
        for (i = 0; i < ipaddrblocksz; i++) {
-               addrfam = sk_ROAIPAddressFamily_value(roa_asn1->ipAddrBlocks, i);
+               addrfam = sk_ROAIPAddressFamily_value(roa_asn1->ipAddrBlocks,
+                   i);
                addrs = addrfam->addresses;
                addrsz = sk_ROAIPAddress_num(addrs);
 
-               if (!ip_addr_afi_parse(p->fn, addrfam->addressFamily, &afi)) {
+               if (!ip_addr_afi_parse(fn, addrfam->addressFamily, &afi)) {
                        warnx("%s: RFC 6482 section 3.3: addressFamily: "
-                           "invalid", p->fn);
+                           "invalid", fn);
                        goto out;
                }
 
@@ -161,14 +155,14 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
                case AFI_IPV4:
                        if (ipv4_seen++ > 0) {
                                warnx("%s: RFC 6482bis section 4.3.2: "
-                                   "IPv4 appears twice", p->fn);
+                                   "IPv4 appears twice", fn);
                                goto out;
                        }
                        break;
                case AFI_IPV6:
                        if (ipv6_seen++ > 0) {
                                warnx("%s: RFC 6482bis section 4.3.2: "
-                                   "IPv6 appears twice", p->fn);
+                                   "IPv6 appears twice", fn);
                                goto out;
                        }
                        break;
@@ -176,27 +170,26 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
 
                if (addrsz == 0) {
                        warnx("%s: RFC 6482bis, section 4.3.2: "
-                           "empty ROAIPAddressFamily", p->fn);
+                           "empty ROAIPAddressFamily", fn);
                        goto out;
                }
 
-               if (p->res->ipsz + addrsz >= MAX_IP_SIZE) {
+               if (roa->ipsz + addrsz >= MAX_IP_SIZE) {
                        warnx("%s: too many ROAIPAddress entries: limit %d",
-                           p->fn, MAX_IP_SIZE);
+                           fn, MAX_IP_SIZE);
                        goto out;
                }
-               p->res->ips = recallocarray(p->res->ips, p->res->ipsz,
-                   p->res->ipsz + addrsz, sizeof(struct roa_ip));
-               if (p->res->ips == NULL)
+               roa->ips = recallocarray(roa->ips, roa->ipsz,
+                   roa->ipsz + addrsz, sizeof(struct roa_ip));
+               if (roa->ips == NULL)
                        err(1, NULL);
 
                for (j = 0; j < addrsz; j++) {
                        addr = sk_ROAIPAddress_value(addrs, j);
 
-                       if (!ip_addr_parse(addr->address, afi, p->fn,
-                           &ipaddr)) {
+                       if (!ip_addr_parse(addr->address, afi, fn, &ipaddr)) {
                                warnx("%s: RFC 6482 section 3.3: address: "
-                                   "invalid IP address", p->fn);
+                                   "invalid IP address", fn);
                                goto out;
                        }
                        maxlen = ipaddr.prefixlen;
@@ -206,24 +199,24 @@ roa_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
                                    addr->maxLength)) {
                                        warnx("%s: RFC 6482 section 3.2: "
                                            "ASN1_INTEGER_get_uint64 failed",
-                                           p->fn);
+                                           fn);
                                        goto out;
                                }
                                if (ipaddr.prefixlen > maxlen) {
                                        warnx("%s: prefixlen (%d) larger than "
-                                           "maxLength (%llu)", p->fn,
+                                           "maxLength (%llu)", fn,
                                            ipaddr.prefixlen,
                                            (unsigned long long)maxlen);
                                        goto out;
                                }
                                if (maxlen > ((afi == AFI_IPV4) ? 32 : 128)) {
                                        warnx("%s: maxLength (%llu) too large",
-                                           p->fn, (unsigned long long)maxlen);
+                                           fn, (unsigned long long)maxlen);
                                        goto out;
                                }
                        }
 
-                       res = &p->res->ips[p->res->ipsz++];
+                       res = &roa->ips[roa->ipsz++];
                        res->addr = ipaddr;
                        res->afi = afi;
                        res->maxlength = maxlen;
@@ -245,45 +238,42 @@ struct roa *
 roa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
     size_t len)
 {
-       struct parse     p;
+       struct roa      *roa;
        size_t           cmsz;
        unsigned char   *cms;
        struct cert     *cert = NULL;
        time_t           signtime = 0;
        int              rc = 0;
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
        cms = cms_parse_validate(x509, fn, der, len, roa_oid, &cmsz, &signtime);
        if (cms == NULL)
                return NULL;
 
-       if ((p.res = calloc(1, sizeof(struct roa))) == NULL)
+       if ((roa = calloc(1, sizeof(struct roa))) == NULL)
                err(1, NULL);
-       p.res->signtime = signtime;
+       roa->signtime = signtime;
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &roa->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &roa->aki))
                goto out;
-       if (!x509_get_sia(*x509, fn, &p.res->sia))
+       if (!x509_get_sia(*x509, fn, &roa->sia))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &roa->ski))
                goto out;
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
-           p.res->ski == NULL) {
+       if (roa->aia == NULL || roa->aki == NULL || roa->sia == NULL ||
+           roa->ski == NULL) {
                warnx("%s: RFC 6487 section 4.8: "
                    "missing AIA, AKI, SIA, or SKI X509 extension", fn);
                goto out;
        }
 
-       if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
+       if (!x509_get_notbefore(*x509, fn, &roa->notbefore))
                goto out;
-       if (!x509_get_notafter(*x509, fn, &p.res->notafter))
+       if (!x509_get_notafter(*x509, fn, &roa->notafter))
                goto out;
 
-       if (!roa_parse_econtent(cms, cmsz, &p))
+       if (!roa_parse_econtent(fn, roa, cms, cmsz))
                goto out;
 
        if (x509_any_inherits(*x509)) {
@@ -303,19 +293,19 @@ roa_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
         * If the ROA isn't valid, we accept it anyway and depend upon
         * the code around roa_read() to check the "valid" field itself.
         */
-       p.res->valid = valid_roa(fn, cert, p.res);
+       roa->valid = valid_roa(fn, cert, roa);
 
        rc = 1;
 out:
        if (rc == 0) {
-               roa_free(p.res);
-               p.res = NULL;
+               roa_free(roa);
+               roa = NULL;
                X509_free(*x509);
                *x509 = NULL;
        }
        cert_free(cert);
        free(cms);
-       return p.res;
+       return roa;
 }
 
 /*
index 6bac1f7..19dddde 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rsc.c,v 1.33 2024/02/16 15:19:02 tb Exp $ */
+/*     $OpenBSD: rsc.c,v 1.34 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
  * Copyright (c) 2022 Job Snijders <job@fastly.com>
 
 #include "extern.h"
 
-/*
- * Parse results and data of the Signed Checklist file.
- */
-struct parse {
-       const char      *fn; /* Signed Checklist file name */
-       struct rsc      *res; /* results */
-};
-
 extern ASN1_OBJECT     *rsc_oid;
 
 /*
@@ -135,7 +127,8 @@ IMPLEMENT_ASN1_FUNCTIONS(RpkiSignedChecklist);
  * Return 0 on failure.
  */
 static int
-rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
+rsc_parse_aslist(const char *fn, struct rsc *rsc,
+    const ConstrainedASIdentifiers *asids)
 {
        int      i, asz;
 
@@ -143,18 +136,18 @@ rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
                return 1;
 
        if ((asz = sk_ASIdOrRange_num(asids->asnum)) == 0) {
-               warnx("%s: RSC asID empty", p->fn);
+               warnx("%s: RSC asID empty", fn);
                return 0;
        }
 
        if (asz >= MAX_AS_SIZE) {
                warnx("%s: too many AS number entries: limit %d",
-                   p->fn, MAX_AS_SIZE);
+                   fn, MAX_AS_SIZE);
                return 0;
        }
 
-       p->res->as = calloc(asz, sizeof(struct cert_as));
-       if (p->res->as == NULL)
+       rsc->as = calloc(asz, sizeof(struct cert_as));
+       if (rsc->as == NULL)
                err(1, NULL);
 
        for (i = 0; i < asz; i++) {
@@ -164,18 +157,16 @@ rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
 
                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, rsc->as, &rsc->asz, aor->u.id))
                                return 0;
                        break;
                case ASIdOrRange_range:
-                       if (!sbgp_as_range(p->fn, p->res->as, &p->res->asz,
+                       if (!sbgp_as_range(fn, rsc->as, &rsc->asz,
                            aor->u.range))
                                return 0;
                        break;
                default:
-                       warnx("%s: RSC AsList: unknown type %d", p->fn,
-                           aor->type);
+                       warnx("%s: RSC AsList: unknown type %d", fn, aor->type);
                        return 0;
                }
        }
@@ -184,7 +175,8 @@ rsc_parse_aslist(struct parse *p, const ConstrainedASIdentifiers *asids)
 }
 
 static int
-rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
+rsc_parse_iplist(const char *fn, struct rsc *rsc,
+    const ConstrainedIPAddrBlocks *ipAddrBlocks)
 {
        const ConstrainedIPAddressFamily        *af;
        const IPAddressOrRanges                 *aors;
@@ -197,7 +189,7 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
                return 1;
 
        if (sk_ConstrainedIPAddressFamily_num(ipAddrBlocks) == 0) {
-               warnx("%s: RSC ipAddrBlocks empty", p->fn);
+               warnx("%s: RSC ipAddrBlocks empty", fn);
                return 0;
        }
 
@@ -205,20 +197,20 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
                af = sk_ConstrainedIPAddressFamily_value(ipAddrBlocks, i);
                aors = af->addressesOrRanges;
 
-               ipsz = p->res->ipsz + sk_IPAddressOrRange_num(aors);
+               ipsz = rsc->ipsz + sk_IPAddressOrRange_num(aors);
                if (ipsz >= MAX_IP_SIZE) {
                        warnx("%s: too many IP address entries: limit %d",
-                           p->fn, MAX_IP_SIZE);
+                           fn, MAX_IP_SIZE);
                        return 0;
                }
 
-               p->res->ips = recallocarray(p->res->ips, p->res->ipsz, ipsz,
+               rsc->ips = recallocarray(rsc->ips, rsc->ipsz, ipsz,
                    sizeof(struct cert_ip));
-               if (p->res->ips == NULL)
+               if (rsc->ips == NULL)
                        err(1, NULL);
 
-               if (!ip_addr_afi_parse(p->fn, af->addressFamily, &afi)) {
-                       warnx("%s: RSC: invalid AFI", p->fn);
+               if (!ip_addr_afi_parse(fn, af->addressFamily, &afi)) {
+                       warnx("%s: RSC: invalid AFI", fn);
                        return 0;
                }
 
@@ -226,18 +218,18 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
                        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, rsc->ips,
+                                   &rsc->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))
+                               if (!sbgp_addr_range(fn, rsc->ips,
+                                   &rsc->ipsz, afi, aor->u.addressRange))
                                        return 0;
                                break;
                        default:
                                warnx("%s: RFC 3779: IPAddressOrRange: "
-                                   "unknown type %d", p->fn, aor->type);
+                                   "unknown type %d", fn, aor->type);
                                return 0;
                        }
                }
@@ -247,7 +239,7 @@ rsc_parse_iplist(struct parse *p, const ConstrainedIPAddrBlocks *ipAddrBlocks)
 }
 
 static int
-rsc_check_digesttype(struct parse *p, const X509_ALGOR *alg)
+rsc_check_digesttype(const char *fn, struct rsc *rsc, const X509_ALGOR *alg)
 {
        const ASN1_OBJECT       *obj;
        int                      type, nid;
@@ -256,13 +248,13 @@ rsc_check_digesttype(struct parse *p, const X509_ALGOR *alg)
 
        if (type != V_ASN1_UNDEF) {
                warnx("%s: RSC DigestAlgorithmIdentifier unexpected parameters:"
-                   " %d", p->fn, type);
+                   " %d", fn, type);
                return 0;
        }
 
        if ((nid = OBJ_obj2nid(obj)) != NID_sha256) {
                warnx("%s: RSC DigestAlgorithmIdentifier: want SHA256, have %s"
-                   " (NID %d)", p->fn, ASN1_tag2str(nid), nid);
+                   " (NID %d)", fn, ASN1_tag2str(nid), nid);
                return 0;
        }
 
@@ -274,7 +266,8 @@ rsc_check_digesttype(struct parse *p, const X509_ALGOR *alg)
  * Return zero on failure, non-zero on success.
  */
 static int
-rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
+rsc_parse_checklist(const char *fn, struct rsc *rsc,
+    const STACK_OF(FileNameAndHash) *checkList)
 {
        FileNameAndHash         *fh;
        ASN1_IA5STRING          *fileName;
@@ -282,28 +275,28 @@ rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
        size_t                   sz, i;
 
        if ((sz = sk_FileNameAndHash_num(checkList)) == 0) {
-               warnx("%s: RSC checkList needs at least one entry", p->fn);
+               warnx("%s: RSC checkList needs at least one entry", fn);
                return 0;
        }
 
        if (sz >= MAX_CHECKLIST_ENTRIES) {
-               warnx("%s: %zu exceeds checklist entry limit (%d)", p->fn, sz,
+               warnx("%s: %zu exceeds checklist entry limit (%d)", fn, sz,
                    MAX_CHECKLIST_ENTRIES);
                return 0;
        }
 
-       p->res->files = calloc(sz, sizeof(struct rscfile));
-       if (p->res->files == NULL)
+       rsc->files = calloc(sz, sizeof(struct rscfile));
+       if (rsc->files == NULL)
                err(1, NULL);
-       p->res->filesz = sz;
+       rsc->filesz = sz;
 
        for (i = 0; i < sz; i++) {
                fh = sk_FileNameAndHash_value(checkList, i);
 
-               file = &p->res->files[i];
+               file = &rsc->files[i];
 
                if (fh->hash->length != SHA256_DIGEST_LENGTH) {
-                       warnx("%s: RSC Digest: invalid SHA256 length", p->fn);
+                       warnx("%s: RSC Digest: invalid SHA256 length", fn);
                        return 0;
                }
                memcpy(file->hash, fh->hash->data, SHA256_DIGEST_LENGTH);
@@ -312,7 +305,7 @@ rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
                        continue;
 
                if (!valid_filename(fileName->data, fileName->length)) {
-                       warnx("%s: RSC FileNameAndHash: bad filename", p->fn);
+                       warnx("%s: RSC FileNameAndHash: bad filename", fn);
                        return 0;
                }
 
@@ -330,7 +323,8 @@ rsc_parse_checklist(struct parse *p, const STACK_OF(FileNameAndHash) *checkList)
  * Returns zero on failure, non-zero on success.
  */
 static int
-rsc_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
+rsc_parse_econtent(const char *fn, struct rsc *rsc, const unsigned char *d,
+    size_t dsz)
 {
        const unsigned char     *oder;
        RpkiSignedChecklist     *rsc_asn1;
@@ -343,35 +337,35 @@ rsc_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
 
        oder = d;
        if ((rsc_asn1 = d2i_RpkiSignedChecklist(NULL, &d, dsz)) == NULL) {
-               warnx("%s: RSC: failed to parse RpkiSignedChecklist", p->fn);
+               warnx("%s: RSC: failed to parse RpkiSignedChecklist", fn);
                goto out;
        }
        if (d != oder + dsz) {
-               warnx("%s: %td bytes trailing garbage in eContent", p->fn,
+               warnx("%s: %td bytes trailing garbage in eContent", fn,
                    oder + dsz - d);
                goto out;
        }
 
-       if (!valid_econtent_version(p->fn, rsc_asn1->version, 0))
+       if (!valid_econtent_version(fn, rsc_asn1->version, 0))
                goto out;
 
        resources = rsc_asn1->resources;
        if (resources->asID == NULL && resources->ipAddrBlocks == NULL) {
                warnx("%s: RSC: one of asID or ipAddrBlocks must be present",
-                   p->fn);
+                   fn);
                goto out;
        }
 
-       if (!rsc_parse_aslist(p, resources->asID))
+       if (!rsc_parse_aslist(fn, rsc, resources->asID))
                goto out;
 
-       if (!rsc_parse_iplist(p, resources->ipAddrBlocks))
+       if (!rsc_parse_iplist(fn, rsc, resources->ipAddrBlocks))
                goto out;
 
-       if (!rsc_check_digesttype(p, rsc_asn1->digestAlgorithm))
+       if (!rsc_check_digesttype(fn, rsc, rsc_asn1->digestAlgorithm))
                goto out;
 
-       if (!rsc_parse_checklist(p, rsc_asn1->checkList))
+       if (!rsc_parse_checklist(fn, rsc, rsc_asn1->checkList))
                goto out;
 
        rc = 1;
@@ -388,40 +382,37 @@ struct rsc *
 rsc_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
     size_t len)
 {
-       struct parse             p;
+       struct rsc              *rsc;
        unsigned char           *cms;
        size_t                   cmsz;
        struct cert             *cert = NULL;
        time_t                   signtime = 0;
        int                      rc = 0;
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
        cms = cms_parse_validate(x509, fn, der, len, rsc_oid, &cmsz,
            &signtime);
        if (cms == NULL)
                return NULL;
 
-       if ((p.res = calloc(1, sizeof(struct rsc))) == NULL)
+       if ((rsc = calloc(1, sizeof(struct rsc))) == NULL)
                err(1, NULL);
-       p.res->signtime = signtime;
+       rsc->signtime = signtime;
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &rsc->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &rsc->aki))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &rsc->ski))
                goto out;
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->ski == NULL) {
+       if (rsc->aia == NULL || rsc->aki == NULL || rsc->ski == NULL) {
                warnx("%s: RFC 6487 section 4.8: "
                    "missing AIA, AKI or SKI X509 extension", fn);
                goto out;
        }
 
-       if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
+       if (!x509_get_notbefore(*x509, fn, &rsc->notbefore))
                goto out;
-       if (!x509_get_notafter(*x509, fn, &p.res->notafter))
+       if (!x509_get_notafter(*x509, fn, &rsc->notafter))
                goto out;
 
        if (X509_get_ext_by_NID(*x509, NID_sinfo_access, -1) != -1) {
@@ -434,25 +425,25 @@ rsc_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
                goto out;
        }
 
-       if (!rsc_parse_econtent(cms, cmsz, &p))
+       if (!rsc_parse_econtent(fn, rsc, cms, cmsz))
                goto out;
 
        if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
                goto out;
 
-       p.res->valid = valid_rsc(fn, cert, p.res);
+       rsc->valid = valid_rsc(fn, cert, rsc);
 
        rc = 1;
  out:
        if (rc == 0) {
-               rsc_free(p.res);
-               p.res = NULL;
+               rsc_free(rsc);
+               rsc = NULL;
                X509_free(*x509);
                *x509 = NULL;
        }
        cert_free(cert);
        free(cms);
-       return p.res;
+       return rsc;
 }
 
 /*
index 72a8861..b0b1555 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: tak.c,v 1.18 2024/02/16 15:13:49 tb Exp $ */
+/*     $OpenBSD: tak.c,v 1.19 2024/02/21 09:17:06 tb Exp $ */
 /*
  * Copyright (c) 2022 Job Snijders <job@fastly.com>
  * Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
 
 #include "extern.h"
 
-/*
- * Parse results and data of the Trust Anchor Key file.
- */
-struct parse {
-       const char      *fn; /* TAK file name */
-       struct tak      *res; /* results */
-};
-
 extern ASN1_OBJECT     *tak_oid;
 
 /*
@@ -161,22 +153,20 @@ parse_takey(const char *fn, const TAKey *takey)
  * Returns zero on failure, non-zero on success.
  */
 static int
-tak_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
+tak_parse_econtent(const char *fn, struct tak *tak, const unsigned char *d,
+    size_t dsz)
 {
        const unsigned char     *oder;
        TAK                     *tak_asn1;
-       const char              *fn;
        int                      rc = 0;
 
-       fn = p->fn;
-
        oder = d;
        if ((tak_asn1 = d2i_TAK(NULL, &d, dsz)) == NULL) {
                warnx("%s: failed to parse Trust Anchor Key", fn);
                goto out;
        }
        if (d != oder + dsz) {
-               warnx("%s: %td bytes trailing garbage in eContent", p->fn,
+               warnx("%s: %td bytes trailing garbage in eContent", fn,
                    oder + dsz - d);
                goto out;
        }
@@ -184,19 +174,19 @@ tak_parse_econtent(const unsigned char *d, size_t dsz, struct parse *p)
        if (!valid_econtent_version(fn, tak_asn1->version, 0))
                goto out;
 
-       p->res->current = parse_takey(fn, tak_asn1->current);
-       if (p->res->current == NULL)
+       tak->current = parse_takey(fn, tak_asn1->current);
+       if (tak->current == NULL)
                goto out;
 
        if (tak_asn1->predecessor != NULL) {
-               p->res->predecessor = parse_takey(fn, tak_asn1->predecessor);
-               if (p->res->predecessor == NULL)
+               tak->predecessor = parse_takey(fn, tak_asn1->predecessor);
+               if (tak->predecessor == NULL)
                        goto out;
        }
 
        if (tak_asn1->successor != NULL) {
-               p->res->successor = parse_takey(fn, tak_asn1->successor);
-               if (p->res->successor == NULL)
+               tak->successor = parse_takey(fn, tak_asn1->successor);
+               if (tak->successor == NULL)
                        goto out;
        }
 
@@ -214,42 +204,39 @@ struct tak *
 tak_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
     size_t len)
 {
-       struct parse             p;
+       struct tak              *tak;
        struct cert             *cert = NULL;
        unsigned char           *cms;
        size_t                   cmsz;
        time_t                   signtime = 0;
        int                      rc = 0;
 
-       memset(&p, 0, sizeof(struct parse));
-       p.fn = fn;
-
        cms = cms_parse_validate(x509, fn, der, len, tak_oid, &cmsz, &signtime);
        if (cms == NULL)
                return NULL;
 
-       if ((p.res = calloc(1, sizeof(struct tak))) == NULL)
+       if ((tak = calloc(1, sizeof(struct tak))) == NULL)
                err(1, NULL);
-       p.res->signtime = signtime;
+       tak->signtime = signtime;
 
-       if (!x509_get_aia(*x509, fn, &p.res->aia))
+       if (!x509_get_aia(*x509, fn, &tak->aia))
                goto out;
-       if (!x509_get_aki(*x509, fn, &p.res->aki))
+       if (!x509_get_aki(*x509, fn, &tak->aki))
                goto out;
-       if (!x509_get_sia(*x509, fn, &p.res->sia))
+       if (!x509_get_sia(*x509, fn, &tak->sia))
                goto out;
-       if (!x509_get_ski(*x509, fn, &p.res->ski))
+       if (!x509_get_ski(*x509, fn, &tak->ski))
                goto out;
-       if (p.res->aia == NULL || p.res->aki == NULL || p.res->sia == NULL ||
-           p.res->ski == NULL) {
+       if (tak->aia == NULL || tak->aki == NULL || tak->sia == NULL ||
+           tak->ski == NULL) {
                warnx("%s: RFC 6487 section 4.8: "
                    "missing AIA, AKI, SIA, or SKI X509 extension", fn);
                goto out;
        }
 
-       if (!x509_get_notbefore(*x509, fn, &p.res->notbefore))
+       if (!x509_get_notbefore(*x509, fn, &tak->notbefore))
                goto out;
-       if (!x509_get_notafter(*x509, fn, &p.res->notafter))
+       if (!x509_get_notafter(*x509, fn, &tak->notafter))
                goto out;
 
        if (!x509_inherits(*x509)) {
@@ -257,13 +244,13 @@ tak_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
                goto out;
        }
 
-       if (!tak_parse_econtent(cms, cmsz, &p))
+       if (!tak_parse_econtent(fn, tak, cms, cmsz))
                goto out;
 
        if ((cert = cert_parse_ee_cert(fn, talid, *x509)) == NULL)
                goto out;
 
-       if (strcmp(p.res->aki, p.res->current->ski) != 0) {
+       if (strcmp(tak->aki, tak->current->ski) != 0) {
                warnx("%s: current TAKey's SKI does not match EE AKI", fn);
                goto out;
        }
@@ -271,14 +258,14 @@ tak_parse(X509 **x509, const char *fn, int talid, const unsigned char *der,
        rc = 1;
  out:
        if (rc == 0) {
-               tak_free(p.res);
-               p.res = NULL;
+               tak_free(tak);
+               tak = NULL;
                X509_free(*x509);
                *x509 = NULL;
        }
        cert_free(cert);
        free(cms);
-       return p.res;
+       return tak;
 }
 
 /*