From be6e5ad57fd4d55e60a9c4c443d95557da338552 Mon Sep 17 00:00:00 2001 From: tb Date: Wed, 21 Feb 2024 09:17:06 +0000 Subject: [PATCH] rpki-client: remove the remaining struct parse 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 | 88 ++++++++++------------ usr.sbin/rpki-client/gbr.c | 41 ++++------- usr.sbin/rpki-client/geofeed.c | 49 ++++++------ usr.sbin/rpki-client/mft.c | 115 +++++++++++++---------------- usr.sbin/rpki-client/roa.c | 96 +++++++++++------------- usr.sbin/rpki-client/rsc.c | 131 +++++++++++++++------------------ usr.sbin/rpki-client/tak.c | 65 +++++++--------- 7 files changed, 257 insertions(+), 328 deletions(-) diff --git a/usr.sbin/rpki-client/aspa.c b/usr.sbin/rpki-client/aspa.c index 294c45b5443..6ec63b6fb7e 100644 --- a/usr.sbin/rpki-client/aspa.c +++ b/usr.sbin/rpki-client/aspa.c @@ -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 * Copyright (c) 2022 Theo Buehler @@ -32,14 +32,6 @@ #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; } /* diff --git a/usr.sbin/rpki-client/gbr.c b/usr.sbin/rpki-client/gbr.c index fab3c5a2562..81c7747d8be 100644 --- a/usr.sbin/rpki-client/gbr.c +++ b/usr.sbin/rpki-client/gbr.c @@ -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 * @@ -24,14 +24,6 @@ #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); diff --git a/usr.sbin/rpki-client/geofeed.c b/usr.sbin/rpki-client/geofeed.c index 4cde5ceae19..f7d321fa35f 100644 --- a/usr.sbin/rpki-client/geofeed.c +++ b/usr.sbin/rpki-client/geofeed.c @@ -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 * Copyright (c) 2019 Kristaps Dzonsons @@ -31,11 +31,6 @@ #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; } /* diff --git a/usr.sbin/rpki-client/mft.c b/usr.sbin/rpki-client/mft.c index 59285ca336f..bc3fb930b91 100644 --- a/usr.sbin/rpki-client/mft.c +++ b/usr.sbin/rpki-client/mft.c @@ -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 * Copyright (c) 2019 Kristaps Dzonsons @@ -34,15 +34,6 @@ #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; } /* diff --git a/usr.sbin/rpki-client/roa.c b/usr.sbin/rpki-client/roa.c index 633c200defc..9c98ca9f989 100644 --- a/usr.sbin/rpki-client/roa.c +++ b/usr.sbin/rpki-client/roa.c @@ -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 * Copyright (c) 2019 Kristaps Dzonsons @@ -31,14 +31,6 @@ #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; } /* diff --git a/usr.sbin/rpki-client/rsc.c b/usr.sbin/rpki-client/rsc.c index 6bac1f76784..19dddde3631 100644 --- a/usr.sbin/rpki-client/rsc.c +++ b/usr.sbin/rpki-client/rsc.c @@ -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 * Copyright (c) 2022 Job Snijders @@ -31,14 +31,6 @@ #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; } /* diff --git a/usr.sbin/rpki-client/tak.c b/usr.sbin/rpki-client/tak.c index 72a88614455..b0b15558c86 100644 --- a/usr.sbin/rpki-client/tak.c +++ b/usr.sbin/rpki-client/tak.c @@ -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 * Copyright (c) 2022 Theo Buehler @@ -31,14 +31,6 @@ #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; } /* -- 2.20.1