oidc_child: add JWT and mTLS authentication#8708
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements support for MTLS (RFC 8705) and JWT-based (RFC 7523) client authentication within the oidc_child component. Key changes include the addition of CLI options for PKCS#12 credentials, the implementation of JWK generation from PKCS#12 files, and the integration of JWT signing using the Jose library. Review feedback highlights critical logic errors in Curl error handling, compatibility issues with OpenSSL versions prior to 3.0, and multiple memory leaks involving BIGNUM, EC_GROUP, and X509 objects.
b850393 to
a68301e
Compare
77591b5 to
57117fd
Compare
|
@sumit-bose, could you please convert corresponding commit messages to release notes? |
sssd-bot
left a comment
There was a problem hiding this comment.
Review done using Claude Code / claude-opus-4-6
Functional Issues
-
EC JWK missing
algfield breaks JWT signing with EC keys.ec_priv_key_jwk(src/util/cert/libcrypto/cert.c:388-395) emitskty,crv,x,y,d, andx5t#S256but no"alg"field. The RSA counterpartrsa_priv_key_jwkincludes"alg":"RS256"(line 602). Inget_jwt()(src/oidc_child/oidc_child_json.c:1256-1260),algis extracted viaget_json_const_string_from_keys(jwk, "alg")and the function fails with "JWK is missing required attributes" if it is NULL. This means JWT client assertion with EC keys will always fail. The EC JWK should include an appropriatealgvalue:"ES256"for P-256,"ES384"for P-384, or"ES512"for P-521. -
No OpenSSL < 3.0 compatibility for new crypto functions.
sss_rsa_get_priv_comps(src/util/cert/libcrypto/cert.c:417) andsss_ec_get_x_y_d(line 253) useEVP_PKEY_get_bn_param()andOSSL_PKEY_PARAM_*macros, which are OpenSSL 3.0+ only. Similarly,get_cert_sha256_hash(line 1038) usesEVP_MD_fetch()/EVP_MD_free(), also 3.0+ APIs. The<openssl/core_names.h>include is guarded by#if OPENSSL_VERSION_NUMBER >= 0x30000000L(line 24), so these functions will fail to compile on OpenSSL < 3.0. The existing functions in the same file (sss_rsa_get_key,sss_ec_get_key) have proper dual-path implementations for both pre- and post-3.0. Either add version guards/fallbacks, or guardget_jwk_from_pkcs12and its callees with#if OPENSSL_VERSION_NUMBER >= 0x30000000L, and provide a stub returningENOTSUPfor older versions. (I note the gemini bot claimed these were fixed after "/gemini see update" replies, but the code at the current PR HEAD — commit57117fd16— still lacks version guards.) -
client_credentials_grantdoes not support JWT/mTLS auth methods.client_credentials_grant()(src/oidc_child/oidc_child_curl.c:858-906) always appendsclient_secretdirectly to POST data (line 881) rather than routing throughappend_to_creds_to_post_data(). Whenoidc_get_id()calls this function withCAM_JWT, the PKCS#12 password is incorrectly sent asclient_secretin the POST body instead of a JWT client assertion. Similarly forCAM_MTLS— theclient_secret(which is actually the PKCS#12 password) should not appear in the POST data at all. -
refresh_tokendoes not support JWT/mTLS auth methods.refresh_token()(src/oidc_child/oidc_child_curl.c:939-946) directly appendsclient_secretto POST data rather than usingappend_to_creds_to_post_data(). Token refresh will fail when using JWT or mTLS client authentication. -
get_jwt_payloadtruncates timestamps toint. Inget_jwt_payload()(src/oidc_child/oidc_child_json.c:1202-1209),time_tvalues (iat,nbf,exp) are cast to(int)and packed withjson_packformat"s:i". On 32-bit platforms (or post-Y2038),time_tvalues will overflowint. Use"s:I"format (which expectsjson_int_t) instead.
Nits & Non-functional Issues
-
Missing space in error message. In
check_client_auth()(src/oidc_child/oidc_child.c:423-424), the string literals"not needed for"and"authentication with client secret.\n"are concatenated without a space, producing: "not needed forauthentication with client secret." -
Debug message copy-paste error. In
sss_ec_get_x_y_d()(src/util/cert/libcrypto/cert.c:280), the debug message for thed(private key) parameter says "Failed to retrieve EC y coordinate." — should say "private key" or "d parameter". -
Duplicate
JOSE_CFLAGS/JOSE_LIBSin Makefile.am.$(JOSE_CFLAGS)is added to bothSSS_CERT_CFLAGSand directly tolibsss_cert_la_CFLAGS. Sincelibsss_cert_la_CFLAGSalready includes$(SSS_CERT_CFLAGS), the jose flags appear twice. Same for$(JOSE_LIBS)inlibsss_cert_la_LIBADD. -
Dead code in
append_jwt_to_postdata. Atsrc/oidc_child/oidc_child_curl.c:567,talloc_free(out)is called whenoutis already NULL (sinceappend_to_post_datareturned NULL). The call is harmless but misleading. -
Missing
:relnote:tags. Commits "oidc_child: add JWT authentication" and "oidc_child: add pkcs12-client-creds option" introduce new user-visible CLI options (--pkcs12-client-creds,--client-auth-method) and new authentication methods but lack:relnote:tags in their commit messages. -
static char curve_name[4096]insss_ec_get_x_y_d. Thecurve_namebuffer atsrc/util/cert/libcrypto/cert.c:261is declaredstatic, which makes the function non-reentrant. While unlikely to cause issues in the current single-threaded usage, a stack-allocated buffer would be safer.
Review of Existing Review Comments
-
Gemini: curl
ret/resvariable mismatch inset_http_opts— The author responded with "/gemini see update" and gemini confirmed this was fixed. The current code atsrc/oidc_child/oidc_child_curl.c:377-397correctly usesresfor allcurl_easy_setoptcalls. Resolved. -
Gemini: OpenSSL 3.0+ API usage without version guards in
sss_ec_get_x_y_d— The author responded with "/gemini see update" and gemini claimed the fix was applied. However, examining the current PR HEAD (57117fd16),sss_ec_get_x_y_dat line 253 still uses OpenSSL 3.0+ APIs without#ifguards. Not resolved in the code I reviewed. -
Gemini:
sss_rsa_get_priv_compsincomplete for OpenSSL < 3.0 — Similar situation: gemini claimed the fix was applied, but the current code at line 417 still has a single implementation using only 3.0+ APIs. Not resolved in the code I reviewed. -
Gemini: BIGNUM memory leaks in
ec_priv_key_jwk— The current code atsrc/util/cert/libcrypto/cert.c:409-413properly freesx,y,dviaBN_free()andec_groupviaEC_GROUP_free()in the cleanup block. Resolved. -
Gemini: BIGNUM memory leaks in
rsa_priv_key_jwk— The current code at lines 626-633 properly frees all eight BIGNUMs. Resolved. -
Gemini: X509 cert memory leak in
get_jwk_from_pkcs12— The current code at line 1146 callsX509_free(cert)in thedoneblock. Resolved. -
CodeQL: Poorly documented functions —
sss_rsa_get_priv_comps(115 lines) andrsa_priv_key_jwk(113 lines) were flagged. SSSD coding style says "Avoid comments that do not add value to the code" — these functions are straightforward enough that their names describe their purpose. Not a concern per SSSD conventions.
To allow signing web tokens with the help of libjose the new function get_jwk_from_pkcs12() can generate a JSON Web Key (JWK) from a given PKCS#12 file.
With the new option pkcs12-client-creds a PKCS#12 file with certificate and private key can be specified for client authentication. The client credential will be used as a password to unlock the key in the PKCS#12 file. The PKCS#12 file is used in a way to make mutual TLS (mTLS) work with an IdP.
With the new option --client-auth-method oidc_child can select between authentication with a client secret, mutual-TLS/mTLS (RFC-8705) and JWT client assertion (RFC-7523). The latter require a PKCS#12 file with the client credentials (certificate and private key) and the password to unlock the private key must be provided with the --client-secret or --client-secret-stdin option.
57117fd to
ba1b54a
Compare
fixed
not fixed yet
fixed
fixed
fixed
fixed
fixed
fixed
fixed
not yet added
fixed
|
|
Hi, I have a question about where to add the code form the first patch, i.e.
However, due to the requirement to do base64-url encoding the dependency to libjose is added and as a result libjose is now linked into various SSSD components which have no use for it. As an alternative all the new functions can be move to a (new) file in What would you prefer? bye, |
This new test call oidc_child with the '--get-device-code' option with different client authentication methods.
ba1b54a to
31242a6
Compare
Via
Since |
With the new option --client-auth-method oidc_child can select between
authentication with a client secret, mutual-TLS/mTLS (RFC-8705) and JWT
client assertion (RFC-7523). The latter require a PKCS#12 file with the
client credentials (certificate and private key) and the password to
unlock the private key must be provided with the --client-secret or
--client-secret-stdin option.