From: Theo Buehler Subject: rpki-client: inline x509_cache_extensions() To: tech@openbsd.org Date: Mon, 21 Jul 2025 06:44:42 +0200 x509_cache_extensions() is now only used in one spot, so I think it's fine to call X509_check_purpose() directly there. Then we also don't need such an elaborate comment. Index: cert.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v diff -u -p -r1.195 cert.c --- cert.c 20 Jul 2025 06:15:50 -0000 1.195 +++ cert.c 21 Jul 2025 04:30:42 -0000 @@ -1353,8 +1353,15 @@ cert_check_purpose(const char *fn, struc cert->purpose = CERT_PURPOSE_INVALID; - if (!x509_cache_extensions(x, fn)) + /* + * Ensure the X.509v3 extensions can be parsed and are cached in x. + * Avoids unexpected failure modes of API such as X509_check_ca(), + * X509_cmp(), X509_get_extension_flags(), and X509_get*_key_usage(). + */ + if (X509_check_purpose(x, -1, 0) <= 0) { + warnx("%s: could not cache X509v3 extensions", fn); goto out; + } ext_flags = X509_get_extension_flags(x); Index: extern.h =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v diff -u -p -r1.252 extern.h --- extern.h 20 Jul 2025 12:00:49 -0000 1.252 +++ extern.h 21 Jul 2025 04:06:55 -0000 @@ -908,7 +908,6 @@ struct ibuf *io_buf_get(struct msgbuf *) /* X509 helpers. */ void x509_init_oid(void); -int x509_cache_extensions(X509 *, const char *); char *x509_pubkey_get_ski(X509_PUBKEY *, const char *); int x509_get_time(const ASN1_TIME *, time_t *); char *x509_convert_seqnum(const char *, const char *, Index: x509.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v diff -u -p -r1.115 x509.c --- x509.c 18 Jul 2025 13:19:59 -0000 1.115 +++ x509.c 21 Jul 2025 04:06:55 -0000 @@ -138,26 +138,6 @@ x509_init_oid(void) } /* - * A number of critical OpenSSL API functions can't properly indicate failure - * and are unreliable if the extensions aren't already cached. An old trick is - * to cache the extensions using an error-checked call to X509_check_purpose() - * with a purpose of -1. This way functions such as X509_check_ca(), X509_cmp(), - * X509_get_key_usage(), X509_get_extended_key_usage() won't lie. - * - * Should be called right after deserialization and is essentially free to call - * multiple times. - */ -int -x509_cache_extensions(X509 *x509, const char *fn) -{ - if (X509_check_purpose(x509, -1, 0) <= 0) { - warnx("%s: could not cache X509v3 extensions", fn); - return 0; - } - return 1; -} - -/* * Compute the SKI of an RSA public key in an X509_PUBKEY using SHA-1. * Returns allocated hex-encoded SKI on success, NULL on failure. */