Download raw body.
rpki-client: introduce and use signed_object_parse()
On Thu, Sep 03, 2026 at 03:39:41PM +0200, Theo Buehler wrote:
> This refactoring diff does two simple things:
>
> Hang an ->oid() getter off struct signed obj. Since foo_oid is populated
> at runtime it's not a compile time constant, so we can't add it directly
> to the static structs.
>
> The six copies of foo_parse() get replaced by signed_object_parse() and
> for now we pass in the rtype and use that to resolve the signed object
> handler which is only used in there. cms_parse_validate() can be made
> static and regress get a similar adjustment as well.
>
> There is one subtle difference between the foo_parse() copies that
> I should call out: mft and tak check the result of *_validate()
> while aspa, roa, rsp, and spl do not. The latter always succeed, so
> the switch from (void)foo_validate() to !sobj->validate() does not
> change anything.
>
> The .rtype member is currently unused. I chose to leave it there for now.
I like it a lot. OK claudio@
> Index: usr.sbin/rpki-client/aspa.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/aspa.c,v
> diff -u -p -r1.44 aspa.c
> --- usr.sbin/rpki-client/aspa.c 25 Jun 2026 07:51:58 -0000 1.44
> +++ usr.sbin/rpki-client/aspa.c 3 Sep 2026 12:46:09 -0000
> @@ -179,6 +179,12 @@ aspa_validate(const char *fn, void *obj,
> return 1; /* XXX */
> }
>
> +static const ASN1_OBJECT *
> +aspa_obj_oid(void)
> +{
> + return aspa_oid;
> +}
> +
> static void *
> aspa_obj_new(size_t der_len, time_t signtime)
> {
> @@ -199,60 +205,20 @@ aspa_obj_free(void *obj)
>
> static const struct signed_obj aspa_signed_obj = {
> .rtype = RTYPE_ASPA,
> +
> .new = aspa_obj_new,
> .free = aspa_obj_free,
> .cert_info = aspa_cert_info,
> .parse_econtent = aspa_parse_econtent,
> .validate = aspa_validate,
> +
> + .oid = aspa_obj_oid,
> };
>
> const struct signed_obj *
> aspa_obj(void)
> {
> return &aspa_signed_obj;
> -}
> -
> -/*
> - * Parse a full ASPA file.
> - * Returns the payload or NULL if the file was malformed.
> - */
> -struct aspa *
> -aspa_parse(struct cert **out_cert, const char *fn, int talid,
> - const unsigned char *der, size_t len)
> -{
> - struct aspa *aspa;
> - struct cert *cert = NULL;
> - size_t cmsz;
> - unsigned char *cms;
> - time_t signtime = 0;
> - int rc = 0;
> -
> - assert(*out_cert == NULL);
> -
> - cms = cms_parse_validate(&cert, fn, talid, der, len, aspa_oid, &cmsz,
> - &signtime);
> - if (cms == NULL)
> - return NULL;
> -
> - aspa = aspa_obj_new(len, signtime);
> - if (!aspa_cert_info(fn, aspa, cert))
> - goto out;
> - if (!aspa_parse_econtent(fn, aspa, cms, cmsz))
> - goto out;
> - (void)aspa_validate(fn, aspa, cert);
> -
> - *out_cert = cert;
> - cert = NULL;
> -
> - rc = 1;
> - out:
> - if (rc == 0) {
> - aspa_free(aspa);
> - aspa = NULL;
> - }
> - cert_free(cert);
> - free(cms);
> - return aspa;
> }
>
> /*
> Index: usr.sbin/rpki-client/cms.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v
> diff -u -p -r1.61 cms.c
> --- usr.sbin/rpki-client/cms.c 26 Aug 2026 05:57:47 -0000 1.61
> +++ usr.sbin/rpki-client/cms.c 3 Sep 2026 13:30:54 -0000
> @@ -401,7 +401,7 @@ cms_parse_validate_internal(struct cert
> * The eContentType of the message must be an oid object.
> * Return the eContent as a string and set "rsz" to be its length.
> */
> -unsigned char *
> +static unsigned char *
> cms_parse_validate(struct cert **out_cert, const char *fn, int talid,
> const unsigned char *der, size_t derlen, const ASN1_OBJECT *oid,
> size_t *rsz, time_t *st)
> @@ -413,4 +413,71 @@ cms_parse_validate(struct cert **out_cer
> return NULL;
>
> return res;
> +}
> +
> +static const struct signed_obj *
> +cms_object_from_rtype(const char *fn, enum rtype rtype)
> +{
> + switch (rtype) {
> + case RTYPE_ASPA:
> + return aspa_obj();
> + case RTYPE_MFT:
> + return mft_obj();
> + case RTYPE_ROA:
> + return roa_obj();
> + case RTYPE_RSC:
> + return rsc_obj();
> + case RTYPE_SPL:
> + return spl_obj();
> + case RTYPE_TAK:
> + return tak_obj();
> + default:
> + errx(1, "%s: unsupported signed object", fn);
> + }
> +}
> +
> +void *
> +signed_object_parse(struct cert **out_cert, const char *fn, enum rtype rtype,
> + int talid, const unsigned char *der, size_t len)
> +{
> + const struct signed_obj *sobj;
> + const ASN1_OBJECT *oid;
> + void *obj = NULL;
> + struct cert *cert = NULL;
> + size_t cmsz;
> + unsigned char *cms;
> + time_t signtime = 0;
> + int rc = 0;
> +
> + assert(*out_cert == NULL);
> +
> + sobj = cms_object_from_rtype(fn, rtype);
> + oid = sobj->oid();
> +
> + cms = cms_parse_validate(&cert, fn, talid, der, len, oid, &cmsz,
> + &signtime);
> + if (cms == NULL)
> + return NULL;
> +
> + obj = sobj->new(len, signtime);
> + if (!sobj->cert_info(fn, obj, cert))
> + goto out;
> + if (!sobj->parse_econtent(fn, obj, cms, cmsz))
> + goto out;
> + if (!sobj->validate(fn, obj, cert))
> + goto out;
> +
> + *out_cert = cert;
> + cert = NULL;
> +
> + rc = 1;
> +
> + out:
> + if (rc == 0) {
> + sobj->free(obj);
> + obj = NULL;
> + }
> + cert_free(cert);
> + free(cms);
> + return obj;
> }
> Index: usr.sbin/rpki-client/extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> diff -u -p -r1.291 extern.h
> --- usr.sbin/rpki-client/extern.h 25 Aug 2026 08:41:14 -0000 1.291
> +++ usr.sbin/rpki-client/extern.h 3 Sep 2026 13:04:51 -0000
> @@ -244,6 +244,7 @@ enum location {
>
> struct signed_obj {
> enum rtype rtype;
> +
> void *(*new)(size_t, time_t);
> void (*free)(void *);
> int (*cert_info)(const char *, void *, const struct cert *);
> @@ -251,6 +252,8 @@ struct signed_obj {
> int (*parse_detached)(const char *, void *, BIO *, char *, size_t,
> uint8_t **, size_t *);
> int (*validate)(const char *, void *, struct cert *);
> +
> + const ASN1_OBJECT *(*oid)(void);
> };
>
> /*
> @@ -776,8 +779,6 @@ void nca_tree_remove_cert(struct nca_t
> enum rtype rtype_from_file_extension(const char *);
> void mft_buffer(struct ibuf *, const struct mft *);
> void mft_free(struct mft *);
> -struct mft *mft_parse(struct cert **, const char *, int,
> - const unsigned char *, size_t);
> const struct signed_obj *mft_obj(void);
> struct mft *mft_read(struct ibuf *);
> int mft_compare_issued(const struct mft *, const struct mft *);
> @@ -787,8 +788,6 @@ int mft_seqnum_gap_present(const struc
>
> void roa_buffer(struct ibuf *, const struct roa *);
> void roa_free(struct roa *);
> -struct roa *roa_parse(struct cert **, const char *, int,
> - const unsigned char *, size_t);
> const struct signed_obj *roa_obj(void);
> struct roa *roa_read(struct ibuf *);
> void roa_insert_vrps(struct vrp_tree *, struct roa *,
> @@ -796,30 +795,22 @@ void roa_insert_vrps(struct vrp_tree *
>
> void spl_buffer(struct ibuf *, const struct spl *);
> void spl_free(struct spl *);
> -struct spl *spl_parse(struct cert **, const char *, int,
> - const unsigned char *, size_t);
> const struct signed_obj *spl_obj(void);
> struct spl *spl_read(struct ibuf *);
> void spl_insert_vsps(struct vsp_tree *, struct spl *,
> struct repo *);
>
> void rsc_free(struct rsc *);
> -struct rsc *rsc_parse(struct cert **, const char *, int,
> - const unsigned char *, size_t);
> const struct signed_obj *rsc_obj(void);
>
> void takey_free(struct takey *);
> void tak_free(struct tak *);
> -struct tak *tak_parse(struct cert **, const char *, int,
> - const unsigned char *, size_t);
> const struct signed_obj *tak_obj(void);
>
> void aspa_buffer(struct ibuf *, const struct aspa *);
> void aspa_free(struct aspa *);
> void aspa_insert_vaps(char *, struct vap_tree *, struct aspa *,
> struct repo *);
> -struct aspa *aspa_parse(struct cert **, const char *, int,
> - const unsigned char *, size_t);
> const struct signed_obj *aspa_obj(void);
> struct aspa *aspa_read(struct ibuf *);
>
> @@ -849,9 +840,8 @@ int valid_uuid(const char *);
> int valid_spl(const char *, struct cert *, struct spl *);
>
> /* Working with CMS. */
> -unsigned char *cms_parse_validate(struct cert **, const char *, int,
> - const unsigned char *, size_t, const ASN1_OBJECT *,
> - size_t *, time_t *);
> +void *signed_object_parse(struct cert **, const char *, enum rtype,
> + int, const unsigned char *, size_t);
>
> /* Work with RFC 3779 IP addresses, prefixes, ranges. */
>
> Index: usr.sbin/rpki-client/filemode.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v
> diff -u -p -r1.86 filemode.c
> --- usr.sbin/rpki-client/filemode.c 9 Jul 2026 11:39:19 -0000 1.86
> +++ usr.sbin/rpki-client/filemode.c 3 Sep 2026 12:46:09 -0000
> @@ -500,7 +500,7 @@ proc_parser_file(char *file, unsigned ch
>
> switch (type) {
> case RTYPE_ASPA:
> - aspa = aspa_parse(&cert, file, -1, buf, len);
> + aspa = signed_object_parse(&cert, file, type, -1, buf, len);
> if (aspa == NULL)
> break;
> aia = cert->aia;
> @@ -531,7 +531,7 @@ proc_parser_file(char *file, unsigned ch
> crl_print(crl);
> break;
> case RTYPE_MFT:
> - mft = mft_parse(&cert, file, -1, buf, len);
> + mft = signed_object_parse(&cert, file, type, -1, buf, len);
> if (mft == NULL)
> break;
> aia = cert->aia;
> @@ -540,7 +540,7 @@ proc_parser_file(char *file, unsigned ch
> notafter = &mft->nextupdate;
> break;
> case RTYPE_ROA:
> - roa = roa_parse(&cert, file, -1, buf, len);
> + roa = signed_object_parse(&cert, file, type, -1, buf, len);
> if (roa == NULL)
> break;
> aia = cert->aia;
> @@ -549,7 +549,7 @@ proc_parser_file(char *file, unsigned ch
> notafter = &cert->notafter;
> break;
> case RTYPE_RSC:
> - rsc = rsc_parse(&cert, file, -1, buf, len);
> + rsc = signed_object_parse(&cert, file, type, -1, buf, len);
> if (rsc == NULL)
> break;
> aia = cert->aia;
> @@ -558,7 +558,7 @@ proc_parser_file(char *file, unsigned ch
> notafter = &cert->notafter;
> break;
> case RTYPE_SPL:
> - spl = spl_parse(&cert, file, -1, buf, len);
> + spl = signed_object_parse(&cert, file, type, -1, buf, len);
> if (spl == NULL)
> break;
> aia = cert->aia;
> @@ -567,7 +567,7 @@ proc_parser_file(char *file, unsigned ch
> notafter = &cert->notafter;
> break;
> case RTYPE_TAK:
> - tak = tak_parse(&cert, file, -1, buf, len);
> + tak = signed_object_parse(&cert, file, type, -1, buf, len);
> if (tak == NULL)
> break;
> aia = cert->aia;
> Index: usr.sbin/rpki-client/mft.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
> diff -u -p -r1.141 mft.c
> --- usr.sbin/rpki-client/mft.c 25 Jun 2026 07:51:58 -0000 1.141
> +++ usr.sbin/rpki-client/mft.c 3 Sep 2026 12:46:09 -0000
> @@ -424,6 +424,12 @@ mft_validate(const char *fn, void *obj,
> return 1;
> }
>
> +static const ASN1_OBJECT *
> +mft_obj_oid(void)
> +{
> + return mft_oid;
> +}
> +
> static void *
> mft_obj_new(size_t der_len, time_t signtime)
> {
> @@ -445,61 +451,20 @@ mft_obj_free(void *obj)
>
> static const struct signed_obj mft_signed_obj = {
> .rtype = RTYPE_MFT,
> +
> .new = mft_obj_new,
> .free = mft_obj_free,
> .cert_info = mft_cert_info,
> .parse_econtent = mft_parse_econtent,
> .validate = mft_validate,
> +
> + .oid = mft_obj_oid,
> };
>
> const struct signed_obj *
> mft_obj(void)
> {
> return &mft_signed_obj;
> -}
> -
> -/*
> - * Parse the objects that have been published in the manifest.
> - * Return mft if it conforms to RFC 9286, otherwise NULL.
> - */
> -struct mft *
> -mft_parse(struct cert **out_cert, const char *fn, int talid,
> - const unsigned char *der, size_t len)
> -{
> - struct mft *mft;
> - struct cert *cert = NULL;
> - int rc = 0;
> - size_t cmsz;
> - unsigned char *cms;
> - time_t signtime = 0;
> -
> - assert(*out_cert == NULL);
> -
> - cms = cms_parse_validate(&cert, fn, talid, der, len, mft_oid, &cmsz,
> - &signtime);
> - if (cms == NULL)
> - return NULL;
> -
> - mft = mft_obj_new(len, signtime);
> - if (!mft_cert_info(fn, mft, cert))
> - goto out;
> - if (!mft_parse_econtent(fn, mft, cms, cmsz))
> - goto out;
> - if (!mft_validate(fn, mft, cert))
> - goto out;
> -
> - *out_cert = cert;
> - cert = NULL;
> -
> - rc = 1;
> - out:
> - if (rc == 0) {
> - mft_free(mft);
> - mft = NULL;
> - }
> - cert_free(cert);
> - free(cms);
> - return mft;
> }
>
> /*
> Index: usr.sbin/rpki-client/parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> diff -u -p -r1.183 parser.c
> --- usr.sbin/rpki-client/parser.c 21 Jul 2026 12:21:42 -0000 1.183
> +++ usr.sbin/rpki-client/parser.c 3 Sep 2026 12:56:08 -0000
> @@ -211,7 +211,8 @@ proc_parser_roa(char *file, const unsign
> struct crl *crl;
> const char *errstr;
>
> - if ((roa = roa_parse(&cert, file, entp->talid, der, len)) == NULL)
> + if ((roa = signed_object_parse(&cert, file, RTYPE_ROA, entp->talid,
> + der, len)) == NULL)
> goto out;
>
> a = find_issuer(file, entp->certid, cert->aki, entp->mftaki);
> @@ -252,7 +253,8 @@ proc_parser_spl(char *file, const unsign
> struct crl *crl;
> const char *errstr;
>
> - if ((spl = spl_parse(&cert, file, entp->talid, der, len)) == NULL)
> + if ((spl = signed_object_parse(&cert, file, RTYPE_SPL, entp->talid,
> + der, len)) == NULL)
> goto out;
>
> a = find_issuer(file, entp->certid, cert->aki, entp->mftaki);
> @@ -412,7 +414,8 @@ proc_parser_mft_pre(struct entity *entp,
> if (der == NULL && errno != ENOENT)
> warn("parse file %s", file);
>
> - if ((mft = mft_parse(&cert, file, entp->talid, der, len)) == NULL) {
> + if ((mft = signed_object_parse(&cert, file, RTYPE_MFT, entp->talid,
> + der, len)) == NULL) {
> free(der);
> return NULL;
> }
> @@ -772,7 +775,8 @@ proc_parser_aspa(char *file, const unsig
> struct crl *crl;
> const char *errstr;
>
> - if ((aspa = aspa_parse(&cert, file, entp->talid, der, len)) == NULL)
> + if ((aspa = signed_object_parse(&cert, file, RTYPE_ASPA, entp->talid,
> + der, len)) == NULL)
> goto out;
>
> a = find_issuer(file, entp->certid, cert->aki, entp->mftaki);
> @@ -812,7 +816,8 @@ proc_parser_tak(char *file, const unsign
> struct auth *a;
> const char *errstr;
>
> - if ((tak = tak_parse(&cert, file, entp->talid, der, len)) == NULL)
> + if ((tak = signed_object_parse(&cert, file, RTYPE_TAK, entp->talid,
> + der, len)) == NULL)
> goto out;
>
> a = find_issuer(file, entp->certid, cert->aki, entp->mftaki);
> Index: usr.sbin/rpki-client/roa.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/roa.c,v
> diff -u -p -r1.90 roa.c
> --- usr.sbin/rpki-client/roa.c 25 Jun 2026 07:51:58 -0000 1.90
> +++ usr.sbin/rpki-client/roa.c 3 Sep 2026 12:46:09 -0000
> @@ -236,6 +236,12 @@ roa_validate(const char *fn, void *obj,
> return 1; /* XXX */
> }
>
> +static const ASN1_OBJECT *
> +roa_obj_oid(void)
> +{
> + return roa_oid;
> +}
> +
> static void *
> roa_obj_new(size_t der_len, time_t signtime)
> {
> @@ -256,60 +262,20 @@ roa_obj_free(void *obj)
>
> static const struct signed_obj roa_signed_obj = {
> .rtype = RTYPE_ROA,
> +
> .new = roa_obj_new,
> .free = roa_obj_free,
> .cert_info = roa_cert_info,
> .parse_econtent = roa_parse_econtent,
> .validate = roa_validate,
> +
> + .oid = roa_obj_oid,
> };
>
> const struct signed_obj *
> roa_obj(void)
> {
> return &roa_signed_obj;
> -}
> -
> -/*
> - * Parse a full RFC 9582 file.
> - * Returns the ROA or NULL if the document was malformed.
> - */
> -struct roa *
> -roa_parse(struct cert **out_cert, const char *fn, int talid,
> - const unsigned char *der, size_t len)
> -{
> - struct roa *roa;
> - struct cert *cert = NULL;
> - size_t cmsz;
> - unsigned char *cms;
> - time_t signtime = 0;
> - int rc = 0;
> -
> - assert(*out_cert == NULL);
> -
> - cms = cms_parse_validate(&cert, fn, talid, der, len, roa_oid, &cmsz,
> - &signtime);
> - if (cms == NULL)
> - return NULL;
> -
> - roa = roa_obj_new(len, signtime);
> - if (!roa_cert_info(fn, roa, cert))
> - goto out;
> - if (!roa_parse_econtent(fn, roa, cms, cmsz))
> - goto out;
> - (void)roa_validate(fn, roa, cert);
> -
> - *out_cert = cert;
> - cert = NULL;
> -
> - rc = 1;
> - out:
> - if (rc == 0) {
> - roa_free(roa);
> - roa = NULL;
> - }
> - cert_free(cert);
> - free(cms);
> - return roa;
> }
>
> /*
> Index: usr.sbin/rpki-client/rsc.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/rsc.c,v
> diff -u -p -r1.47 rsc.c
> --- usr.sbin/rpki-client/rsc.c 9 Jul 2026 12:13:56 -0000 1.47
> +++ usr.sbin/rpki-client/rsc.c 3 Sep 2026 12:46:09 -0000
> @@ -366,6 +366,12 @@ rsc_validate(const char *fn, void *obj,
> return 1; /* XXX */
> }
>
> +static const ASN1_OBJECT *
> +rsc_obj_oid(void)
> +{
> + return rsc_oid;
> +}
> +
> static void *
> rsc_obj_new(size_t der_len, time_t signtime)
> {
> @@ -386,60 +392,20 @@ rsc_obj_free(void *obj)
>
> static const struct signed_obj rsc_signed_obj = {
> .rtype = RTYPE_RSC,
> +
> .new = rsc_obj_new,
> .free = rsc_obj_free,
> .cert_info = rsc_cert_info,
> .parse_econtent = rsc_parse_econtent,
> .validate = rsc_validate,
> +
> + .oid = rsc_obj_oid,
> };
>
> const struct signed_obj *
> rsc_obj(void)
> {
> return &rsc_signed_obj;
> -}
> -
> -/*
> - * Parse a full RFC 9323 file.
> - * Returns the RSC or NULL if the object was malformed.
> - */
> -struct rsc *
> -rsc_parse(struct cert **out_cert, const char *fn, int talid,
> - const unsigned char *der, size_t len)
> -{
> - struct rsc *rsc;
> - struct cert *cert = NULL;
> - unsigned char *cms;
> - size_t cmsz;
> - time_t signtime = 0;
> - int rc = 0;
> -
> - assert(*out_cert == NULL);
> -
> - cms = cms_parse_validate(&cert, fn, talid, der, len, rsc_oid, &cmsz,
> - &signtime);
> - if (cms == NULL)
> - return NULL;
> -
> - rsc = rsc_obj_new(len, signtime);
> - if (!rsc_cert_info(fn, rsc, cert))
> - goto out;
> - if (!rsc_parse_econtent(fn, rsc, cms, cmsz))
> - goto out;
> - (void)rsc_validate(fn, rsc, cert);
> -
> - *out_cert = cert;
> - cert = NULL;
> -
> - rc = 1;
> - out:
> - if (rc == 0) {
> - rsc_free(rsc);
> - rsc = NULL;
> - }
> - cert_free(cert);
> - free(cms);
> - return rsc;
> }
>
> /*
> Index: usr.sbin/rpki-client/spl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/spl.c,v
> diff -u -p -r1.18 spl.c
> --- usr.sbin/rpki-client/spl.c 25 Jun 2026 07:51:58 -0000 1.18
> +++ usr.sbin/rpki-client/spl.c 3 Sep 2026 12:46:09 -0000
> @@ -241,6 +241,12 @@ spl_validate(const char *fn, void *obj,
> return 1; /* XXX */
> }
>
> +static const ASN1_OBJECT *
> +spl_obj_oid(void)
> +{
> + return spl_oid;
> +}
> +
> static void *
> spl_obj_new(size_t der_len, time_t signtime)
> {
> @@ -261,60 +267,20 @@ spl_obj_free(void *obj)
>
> static const struct signed_obj spl_signed_obj = {
> .rtype = RTYPE_SPL,
> +
> .new = spl_obj_new,
> .free = spl_obj_free,
> .cert_info = spl_cert_info,
> .parse_econtent = spl_parse_econtent,
> .validate = spl_validate,
> +
> + .oid = spl_obj_oid,
> };
>
> const struct signed_obj *
> spl_obj(void)
> {
> return &spl_signed_obj;
> -}
> -
> -/*
> - * Parse a full Signed Prefix List file.
> - * Returns the SPL, or NULL if the object was malformed.
> - */
> -struct spl *
> -spl_parse(struct cert **out_cert, const char *fn, int talid,
> - const unsigned char *der, size_t len)
> -{
> - struct spl *spl;
> - struct cert *cert = NULL;
> - size_t cmsz;
> - unsigned char *cms;
> - time_t signtime = 0;
> - int rc = 0;
> -
> - assert(*out_cert == NULL);
> -
> - cms = cms_parse_validate(&cert, fn, talid, der, len, spl_oid, &cmsz,
> - &signtime);
> - if (cms == NULL)
> - return NULL;
> -
> - spl = spl_obj_new(len, signtime);
> - if (!spl_cert_info(fn, spl, cert))
> - goto out;
> - if (!spl_parse_econtent(fn, spl, cms, cmsz))
> - goto out;
> - (void)spl_validate(fn, spl, cert);
> -
> - *out_cert = cert;
> - cert = NULL;
> -
> - rc = 1;
> - out:
> - if (rc == 0) {
> - spl_free(spl);
> - spl = NULL;
> - }
> - cert_free(cert);
> - free(cms);
> - return spl;
> }
>
> void
> Index: usr.sbin/rpki-client/tak.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/tak.c,v
> diff -u -p -r1.32 tak.c
> --- usr.sbin/rpki-client/tak.c 7 Jul 2026 13:45:59 -0000 1.32
> +++ usr.sbin/rpki-client/tak.c 3 Sep 2026 12:46:09 -0000
> @@ -208,6 +208,12 @@ tak_validate(const char *fn, void *obj,
> return 1;
> }
>
> +static const ASN1_OBJECT *
> +tak_obj_oid(void)
> +{
> + return tak_oid;
> +}
> +
> static void *
> tak_obj_new(size_t der_len, time_t signtime)
> {
> @@ -228,61 +234,20 @@ tak_obj_free(void *obj)
>
> static const struct signed_obj tak_signed_obj = {
> .rtype = RTYPE_TAK,
> +
> .new = tak_obj_new,
> .free = tak_obj_free,
> .cert_info = tak_cert_info,
> .parse_econtent = tak_parse_econtent,
> .validate = tak_validate,
> +
> + .oid = tak_obj_oid,
> };
>
> const struct signed_obj *
> tak_obj(void)
> {
> return &tak_signed_obj;
> -}
> -
> -/*
> - * Parse a full RFC 9691 Trust Anchor Key file.
> - * Returns the TAK or NULL if the object was malformed.
> - */
> -struct tak *
> -tak_parse(struct cert **out_cert, const char *fn, int talid,
> - const unsigned char *der, size_t len)
> -{
> - struct tak *tak;
> - struct cert *cert = NULL;
> - unsigned char *cms;
> - size_t cmsz;
> - time_t signtime = 0;
> - int rc = 0;
> -
> - assert(*out_cert == NULL);
> -
> - cms = cms_parse_validate(&cert, fn, talid, der, len, tak_oid, &cmsz,
> - &signtime);
> - if (cms == NULL)
> - return NULL;
> -
> - tak = tak_obj_new(len, signtime);
> - if (!tak_cert_info(fn, tak, cert))
> - goto out;
> - if (!tak_parse_econtent(fn, tak, cms, cmsz))
> - goto out;
> - if (!tak_validate(fn, tak, cert))
> - goto out;
> -
> - *out_cert = cert;
> - cert = NULL;
> -
> - rc = 1;
> - out:
> - if (rc == 0) {
> - tak_free(tak);
> - tak = NULL;
> - }
> - cert_free(cert);
> - free(cms);
> - return tak;
> }
>
> /*
> Index: regress/usr.sbin/rpki-client/test-aspa.c
> ===================================================================
> RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-aspa.c,v
> diff -u -p -r1.12 test-aspa.c
> --- regress/usr.sbin/rpki-client/test-aspa.c 23 Oct 2025 05:35:46 -0000 1.12
> +++ regress/usr.sbin/rpki-client/test-aspa.c 3 Sep 2026 12:46:09 -0000
> @@ -63,7 +63,8 @@ main(int argc, char *argv[])
>
> for (i = 0; i < argc; i++) {
> buf = load_file(argv[i], &len);
> - if ((p = aspa_parse(&cert, argv[i], -1, buf, len)) == NULL) {
> + if ((p = signed_object_parse(&cert, argv[i], RTYPE_ASPA, -1,
> + buf, len)) == NULL) {
> free(buf);
> break;
> }
> Index: regress/usr.sbin/rpki-client/test-mft.c
> ===================================================================
> RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-mft.c,v
> diff -u -p -r1.33 test-mft.c
> --- regress/usr.sbin/rpki-client/test-mft.c 23 Oct 2025 05:35:46 -0000 1.33
> +++ regress/usr.sbin/rpki-client/test-mft.c 3 Sep 2026 12:46:09 -0000
> @@ -65,7 +65,8 @@ main(int argc, char *argv[])
>
> for (i = 0; i < argc; i++) {
> buf = load_file(argv[i], &len);
> - if ((p = mft_parse(&cert, argv[i], -1, buf, len)) == NULL) {
> + if ((p = signed_object_parse(&cert, argv[i], RTYPE_MFT, -1,
> + buf, len)) == NULL) {
> free(buf);
> break;
> }
> Index: regress/usr.sbin/rpki-client/test-roa.c
> ===================================================================
> RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-roa.c,v
> diff -u -p -r1.30 test-roa.c
> --- regress/usr.sbin/rpki-client/test-roa.c 23 Oct 2025 05:35:46 -0000 1.30
> +++ regress/usr.sbin/rpki-client/test-roa.c 3 Sep 2026 12:46:09 -0000
> @@ -62,7 +62,8 @@ main(int argc, char *argv[])
>
> for (i = 0; i < argc; i++) {
> buf = load_file(argv[i], &len);
> - if ((p = roa_parse(&cert, argv[i], -1, buf, len)) == NULL) {
> + if ((p = signed_object_parse(&cert, argv[i], RTYPE_ROA, -1,
> + buf, len)) == NULL) {
> free(buf);
> break;
> }
> Index: regress/usr.sbin/rpki-client/test-rsc.c
> ===================================================================
> RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-rsc.c,v
> diff -u -p -r1.15 test-rsc.c
> --- regress/usr.sbin/rpki-client/test-rsc.c 23 Oct 2025 05:35:46 -0000 1.15
> +++ regress/usr.sbin/rpki-client/test-rsc.c 3 Sep 2026 12:46:09 -0000
> @@ -65,7 +65,8 @@ main(int argc, char *argv[])
>
> for (i = 0; i < argc; i++) {
> buf = load_file(argv[i], &len);
> - if ((p = rsc_parse(&cert, argv[i], -1, buf, len)) == NULL) {
> + if ((p = signed_object_parse(&cert, argv[i], RTYPE_RSC, -1,
> + buf, len)) == NULL) {
> free(buf);
> break;
> }
> Index: regress/usr.sbin/rpki-client/test-spl.c
> ===================================================================
> RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-spl.c,v
> diff -u -p -r1.7 test-spl.c
> --- regress/usr.sbin/rpki-client/test-spl.c 23 Oct 2025 05:35:46 -0000 1.7
> +++ regress/usr.sbin/rpki-client/test-spl.c 3 Sep 2026 12:46:09 -0000
> @@ -63,7 +63,8 @@ main(int argc, char *argv[])
>
> for (i = 0; i < argc; i++) {
> buf = load_file(argv[i], &len);
> - if ((p = spl_parse(&cert, argv[i], -1, buf, len)) == NULL) {
> + if ((p = signed_object_parse(&cert, argv[i], RTYPE_SPL,
> + -1, buf, len)) == NULL) {
> free(buf);
> break;
> }
> Index: regress/usr.sbin/rpki-client/test-tak.c
> ===================================================================
> RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-tak.c,v
> diff -u -p -r1.12 test-tak.c
> --- regress/usr.sbin/rpki-client/test-tak.c 23 Oct 2025 05:35:46 -0000 1.12
> +++ regress/usr.sbin/rpki-client/test-tak.c 3 Sep 2026 12:46:09 -0000
> @@ -63,7 +63,8 @@ main(int argc, char *argv[])
>
> for (i = 0; i < argc; i++) {
> buf = load_file(argv[i], &len);
> - if ((p = tak_parse(&cert, argv[i], -1, buf, len)) == NULL) {
> + if ((p = signed_object_parse(&cert, argv[i], RTYPE_TAK, -1,
> + buf, len)) == NULL) {
> free(buf);
> break;
> }
>
--
:wq Claudio
rpki-client: introduce and use signed_object_parse()