Repository navigation
fix: include openssl/opensslv.h in src/jose.h - #1400
Conversation
|
Thanks @cyrilst for the report and the analysis. The diagnosis is correct, and so is where you put the fix: One correction to the scope, for anyone who finds this later: not every 2.4.20.x build is affected. The bug needs both 2.4.20 or later and cjose 0.8.0 or later. Up to and including 0.6.2.x,
An affected build fails all ES256/ES384/ES512 handling that goes through
RS*, PS* and HS* keep working. Compiling all of CI didn't catch this because it only ever built against the distribution's libcjose 0.6.2.x. The EC tests in The fix will ship in 2.4.20.4. |
|
Awesome, thank you! |
Summary
After upgrading 2.4.19.1 → 2.4.20.3 (FreeBSD port, OpenSSL 3.5.6, libcurl 8.23.0), every login against an OP that signs its id_tokens with ES256 (kanidm) fails with:
The JWKs URI is fetched correctly and contains the key, and the EC JWK parses fine — the failure is that
oidc_jwt_alg2kty()cannot mapES256to the EC key type in this build. WithLogLevel auth_openidc:debug:kty=2isOIDC_JOSE_JWK_KTY_EC— the parsed key, correct.requested kty=-1isoidc_alg2kty("ES256")returning-1.Root cause
src/jose.h:73:src/jose/jws.c:160(insideoidc_alg2kty(), defined at jose/jws.c:151):jose.hincludes no OpenSSL header, and nothing injose/jws.c's include chain does either (jose.h→const.h→httpd.h/http_log.h;jose/internal.h→cjose/cjose.h;<jansson.h>;util/util.h→json.h). In#ifevaluation the C preprocessor replaces an undefined identifier with0, so in that translation unit:and the
ES → ECbranch is silently compiled out ofoidc_alg2kty(). This is not platform-specific: no stock build of 2.4.20.x getsOPENSSL_VERSION_NUMBERdefined in that TU. Minimal demonstration on any platform with a C compiler:Two aggravating factors that make this look like a key/JWKs problem during diagnosis:
src/jose/jwk.cdoes include<openssl/opensslv.h>(with bn/err/evp/pem/rsa), so EC JWK import is compiled in: the key parses (kty=2) and is then skipped by the kty pre-filter inoidc_proto_jwks_key_apply()(proto/jwks.c:88) and by the kid-path check inoidc_jwt_verify()(jose/jws.c:443). A per-TU inconsistency.mod_auth_openidc … EC=yes) is evaluated inmod_auth_openidc.c's TU, which includesopensslv.h— it reports EC support thatjose/jws.cdoes not actually have.Regression introduced by
Commit
23103dde— "jose: split JWK/JWS/JWE implementations into a jose/ subdirectory" (2026-07-04, first released in 2.4.20).oidc_alg2kty()moved fromsrc/jose.c, which includes<openssl/opensslv.h>directly, intosrc/jose/jws.c, which does not.jose/jwk.ckept the OpenSSL includes;jose/jws.cdid not. The same setup worked on 2.4.19.1.Impact
oidc_alg2kty()fails: id_token verification against ES-signing OPs (kanidm OAuth2 RSs configured for ES256 hit this) with "could not find key with kid" or "key type of key with kid … does not match the JWT alg header".oidc_alg2kty()), presumably why this hasn't surfaced against the common RS256 OPs.OIDC_JOSE_GCM_SUPPORT(jose.h:74) has the identical latent pattern; it currently only survives because the TUs that use it happen to include OpenSSL headers.Suggested fix
Include
<openssl/opensslv.h>insrc/jose.hbefore theOIDC_JOSE_*_SUPPORTdefines, so every translation unit evaluates them against the real OpenSSL version (this also covers the GCM macro):Minimal alternative: add the include at the top of
src/jose/jws.conly, mirroringjose/jwk.c.Workaround
None on the RP side (the algorithm mapping is compiled out). Either apply the one-line patch above and rebuild, or switch the OP's signing algorithm to RS256.
Environment
www/mod_auth_openidc), Apache httpd 2.4, OpenSSL 3.5.6, libcurl 8.23.0id_token_signing_alg_values_supported: ["ES256"])OIDCProviderMetadataURL, shm cache,OIDCSessionType server-cache