From: Theo Buehler Subject: Re: rpki-client: const shuffling for openssl 4 To: tech@openbsd.org Date: Thu, 2 Apr 2026 17:39:57 +0200 On Thu, Apr 02, 2026 at 05:12:08PM +0200, Claudio Jeker wrote: > On Thu, Apr 02, 2026 at 04:40:43PM +0200, Theo Buehler wrote: > > On Sat, Mar 28, 2026 at 10:21:15AM +0100, Theo Buehler wrote: > > > OpenSSL 4 went on a const sprinkling spree which requires us to think > > > about how we can compile cleanly with various versions of the libs so > > > we can catch more serious warnings. > > > > > > We can adapt the xissuer in print.c to be const. It hasn't been const > > > because X509_get_issuer_name() isn't const correct. > > > > > > cert.c is a bit tricky even if it only parses things and hence doesn't > > > modify libcrypto objects it doesn't own. > > > > > > There are two pieces to the puzzle. > > > > > > In cert_check_spki() the pubkey is a libcrypto-internal pointer hanging > > > off cert->x509, which is then passed to the very const-incorrect getter > > > X509_PUBKEY_get0_param(): that's a piece of art which hands back pointers > > > to things deeper down in the x509 - some of them const, some non-const. > > > OpenSSL 3 made its X509_PUBKEY argument const, but their X509_ALGOR ** > > > still isn't. I don't believe they thought about it in #11894 as they had > > > a _cmp() vs _eq() bikeshed to sort out. > > > > > > Our choices are to cast the pubkey coming from X509_get_X509_PUBKEY() > > > or the one passed to X509_PUBKEY_get0_param(). Since the latter call is > > > tricky I chose the former. > > > > > > Of course I saved the best for last: > > > > > > The individual extension handlers don't take a const X509_EXTENSION * > > > mainly because each of them calls X509V3_EXT_d2i() which should have > > > been const but isn't. We could cast away const in all nine of its > > > callers, which might be the least evil approach if we can live with a > > > it of churn. That works out nicely except that we also need to cast the > > > ext passed to X509_EXTENSION_get_object(). Happy to go this way if you > > > prefer that. > > > > That diff would be the below. > > > > > As an aside, a single wrapper function that allows casting away const > > > only once seems a bad idea: > > > > > > /* > > > * Decode extension data from DER. It's the caller's responsibility to > > > * assign the return value to the correct pointer type and to free it. > > > */ > > > static void * > > > cert_yolo_decode_extension_data(const X509_EXTENSION *ext) > > > > Maybe we could get away with this by calling it X509V3_EXT_d2i_const() > > or something. Still not a fan. > > > > > { > > > /* XXX - const correct only in OpenSSL 4. */ > > > return X509V3_EXT_d2i((X509_EXTENSION *)ext); > > > } > > > > > > I don't see how to add belts and suspenders to make this interface less > > > terrible and trappy. > > > > > > Yet another approach is the below: cast away const from X509_get_ext(). > > > "grep -w ext cert.c" will show you that ext is only passed to > > > X509V3_EXT_d2i() and X509_EXTENSION_get_object() already mentioned above > > > and to X509_EXTENSION_get_critical() which is already const correct. > > > > It would be nice to get a version of this diff in so the next rpki-client > > release can support OpenSSL 4 ootb (needs some portable massaging on top, > > but that isn't hard). It works well in my testing. > > > > I know the new certificate_policies() line below is too long. We could > > wrap it or rename the function to cert_policies(). And then I need to > > figure out what to do about the sbgp_* functions... > > As usual there is not enough lipstick to make this pig pretty. Indeed. > Even if libressl fixes the API to follow openssl 4 we still need to > support openssl 3 for a while so the cast will remain for a while. True. We have regress that ensures that openssl 3 doesn't break and I will make sure to add the openssl 4 version once released so we notice if we break things. Should I annotate the casts with /* Needed for OpenSSL 3 and LibreSSL */ if ((os = X509V3_EXT_d2i((X509_EXTENSION *)ext)) == NULL) { I know I will forget at some point.... > That said I do prefer the diff below a tad bit better. > My reasoning being that this makes the rpki-client code more const > correct and pushes the cast to the openssl calls. While your first diff > removes the const early on but this leaves the rpki-client code incorrect. Thanks. Makes sense. I was thinking the maintenance burden is smaller with fewer hacks, but maybe I tried too hard to minimize those... Then I suggest I rename certificate_policies() into cert_policies() and land the diff.