From: Theo Buehler Subject: rpki-client: merge cert_parse() and cert_parse_pre() To: tech@openbsd.org Date: Mon, 14 Jul 2025 09:46:30 +0200 The split between cert_parse_pre() and cert_parse() is no longer meaningful, really. cert_parse_pre() has checks depending on the purpose which are now all part of cert_parse_extensions() except for the check that a cert coming through here is not supposed to be an EE cert, which I kept. cert_parse() itself only has some checks on extensions which are done as part of cert_parse_extensions() already. For TA certs we could not call cert_parse() previously because of AIA, CRLDP and SKI vs AKI, which we now handle depending on purpose in cert_parse_extensions(). We could consider making ta_parse() call cert_parse() directly, but it would add some complications to this diff and especially filemode is a bit messy (we don't know if a .cer is a TA, CA or BGPsec cert) and it doesn't really seem to help a lot. Index: regress/usr.sbin/rpki-client/test-cert.c =================================================================== RCS file: /cvs/src/regress/usr.sbin/rpki-client/test-cert.c,v diff -u -p -r1.25 test-cert.c --- regress/usr.sbin/rpki-client/test-cert.c 7 Jul 2025 17:57:16 -0000 1.25 +++ regress/usr.sbin/rpki-client/test-cert.c 14 Jul 2025 07:17:19 -0000 @@ -84,7 +84,7 @@ main(int argc, char *argv[]) break; buf = load_file(cert_path, &len); - p = cert_parse_pre(cert_path, buf, len); + p = cert_parse(cert_path, buf, len); free(buf); if (p == NULL) break; @@ -103,11 +103,8 @@ main(int argc, char *argv[]) size_t len; buf = load_file(argv[i], &len); - p = cert_parse_pre(argv[i], buf, len); + p = cert_parse(argv[i], buf, len); free(buf); - if (p == NULL) - break; - p = cert_parse(argv[i], p); if (p == NULL) break; if (verb) Index: usr.sbin/rpki-client/cert.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v diff -u -p -r1.193 cert.c --- usr.sbin/rpki-client/cert.c 14 Jul 2025 06:03:17 -0000 1.193 +++ usr.sbin/rpki-client/cert.c 14 Jul 2025 07:17:19 -0000 @@ -1875,7 +1875,7 @@ cert_parse_ee_cert(const char *fn, int t * Returns the parse results or NULL on failure. */ struct cert * -cert_parse_pre(const char *fn, const unsigned char *der, size_t len) +cert_parse(const char *fn, const unsigned char *der, size_t len) { struct cert *cert = NULL; const unsigned char *oder; @@ -1902,37 +1902,9 @@ cert_parse_pre(const char *fn, const uns if ((cert = cert_parse_internal(fn, x)) == NULL) goto out; - /* Validation on required fields. */ - switch (cert->purpose) { - case CERT_PURPOSE_TA: - /* XXX - caller should indicate if it expects TA or CA cert */ - case CERT_PURPOSE_CA: - if (cert->mft == NULL) { - warnx("%s: RFC 6487 section 4.8.8: missing SIA", fn); - goto out; - } - if (cert->num_ases == 0 && cert->num_ips == 0) { - warnx("%s: missing IP or AS resources", fn); - goto out; - } - break; - case CERT_PURPOSE_BGPSEC_ROUTER: - if (cert->num_ips > 0) { - warnx("%s: unexpected IP resources in BGPsec cert", fn); - goto out; - } - break; - case CERT_PURPOSE_EE: + if (cert->purpose == CERT_PURPOSE_EE) { warnx("%s: unexpected EE cert", fn); goto out; - default: - warnx("%s: x509_get_purpose failed in %s", fn, __func__); - goto out; - } - - if (cert->ski == NULL) { - warnx("%s: RFC 6487 section 8.4.2: missing SKI", fn); - goto out; } X509_free(x); @@ -1945,38 +1917,6 @@ cert_parse_pre(const char *fn, const uns } struct cert * -cert_parse(const char *fn, struct cert *p) -{ - if (p == NULL) - return NULL; - - if (p->aki == NULL) { - warnx("%s: RFC 6487 section 8.4.2: " - "non-trust anchor missing AKI", fn); - goto badcert; - } - if (strcmp(p->aki, p->ski) == 0) { - warnx("%s: RFC 6487 section 8.4.2: " - "non-trust anchor AKI may not match SKI", fn); - goto badcert; - } - if (p->aia == NULL) { - warnx("%s: RFC 6487 section 8.4.7: AIA: extension missing", fn); - goto badcert; - } - if (p->crl == NULL) { - warnx("%s: RFC 6487 section 4.8.6: CRL: " - "no CRL distribution point extension", fn); - goto badcert; - } - return p; - - badcert: - cert_free(p); - return NULL; -} - -struct cert * ta_parse(const char *fn, struct cert *p, const unsigned char *pkey, size_t pkeysz) { @@ -2008,21 +1948,6 @@ ta_parse(const char *fn, struct cert *p, } if (p->notafter < now) { warnx("%s: certificate has expired", fn); - goto badcert; - } - if (p->aki != NULL && strcmp(p->aki, p->ski)) { - warnx("%s: RFC 6487 section 4.8.3: " - "trust anchor AKI, if specified, must match SKI", fn); - goto badcert; - } - if (p->aia != NULL) { - warnx("%s: RFC 6487 section 4.8.7: " - "trust anchor must not have AIA", fn); - goto badcert; - } - if (p->crl != NULL) { - warnx("%s: RFC 6487 section 4.8.6: " - "trust anchor may not specify CRL resource", fn); goto badcert; } if (p->purpose != CERT_PURPOSE_TA) { Index: usr.sbin/rpki-client/extern.h =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v diff -u -p -r1.247 extern.h --- usr.sbin/rpki-client/extern.h 11 Jul 2025 09:20:23 -0000 1.247 +++ usr.sbin/rpki-client/extern.h 14 Jul 2025 07:17:19 -0000 @@ -716,8 +716,7 @@ void cert_buffer(struct ibuf *, const void cert_free(struct cert *); void auth_tree_free(struct auth_tree *); struct cert *cert_parse_ee_cert(const char *, int, X509 *); -struct cert *cert_parse_pre(const char *, const unsigned char *, size_t); -struct cert *cert_parse(const char *, struct cert *); +struct cert *cert_parse(const char *, const unsigned char *, size_t); struct cert *ta_parse(const char *, struct cert *, const unsigned char *, size_t); struct cert *cert_read(struct ibuf *); Index: usr.sbin/rpki-client/filemode.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/filemode.c,v diff -u -p -r1.62 filemode.c --- usr.sbin/rpki-client/filemode.c 25 Jun 2025 16:24:44 -0000 1.62 +++ usr.sbin/rpki-client/filemode.c 14 Jul 2025 07:17:19 -0000 @@ -151,7 +151,7 @@ parse_load_cert(char *uri) goto done; } - cert = cert_parse_pre(uri, f, flen); + cert = cert_parse(uri, f, flen); free(f); if (cert == NULL) @@ -260,7 +260,7 @@ parse_load_ta(struct tal *tal) } /* Extract certificate data. */ - cert = cert_parse_pre(file, f, flen); + cert = cert_parse(file, f, flen); cert = ta_parse(file, cert, tal->pkey, tal->pkeysz); if (cert == NULL) goto out; @@ -408,14 +408,10 @@ proc_parser_file(char *file, unsigned ch notafter = &aspa->notafter; break; case RTYPE_CER: - cert = cert_parse_pre(file, buf, len); + cert = cert_parse(file, buf, len); if (cert == NULL) break; is_ta = (cert->purpose == CERT_PURPOSE_TA); - if (!is_ta) - cert = cert_parse(file, cert); - if (cert == NULL) - break; aia = cert->aia; x509 = cert->x509; if (X509_up_ref(x509) == 0) Index: usr.sbin/rpki-client/parser.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v diff -u -p -r1.162 parser.c --- usr.sbin/rpki-client/parser.c 25 Jun 2025 16:24:44 -0000 1.162 +++ usr.sbin/rpki-client/parser.c 14 Jul 2025 07:17:19 -0000 @@ -588,8 +588,7 @@ proc_parser_cert(char *file, const unsig /* Extract certificate data. */ - cert = cert_parse_pre(file, der, len); - cert = cert_parse(file, cert); + cert = cert_parse(file, der, len); if (cert == NULL) goto out; @@ -693,7 +692,7 @@ proc_parser_root_cert(struct entity *ent file2 = parse_filepath(entp->repoid, entp->path, entp->file, DIR_VALID); der = load_file(file2, &der_len); - cert2 = cert_parse_pre(file2, der, der_len); + cert2 = cert_parse(file2, der, der_len); free(der); cert2 = ta_parse(file2, cert2, pkey, pkeysz); @@ -701,7 +700,7 @@ proc_parser_root_cert(struct entity *ent file1 = parse_filepath(entp->repoid, entp->path, entp->file, DIR_TEMP); der = load_file(file1, &der_len); - cert1 = cert_parse_pre(file1, der, der_len); + cert1 = cert_parse(file1, der, der_len); free(der); cert1 = ta_parse(file1, cert1, pkey, pkeysz); }