X509 authentication fails with "No trusted certificate found"

Hi Everyone,

I’m running keycloak 11.0.3 and have configured the X509 Authentication as shown here : https://www.keycloak.org/docs/11.0/server_admin/#enable-x-509-client-certificate-user-authentication

I have my client certificate issued by a CA and that CA’s certificate is present in the truststore but during the handshake it throws the following error after consuming the client certificate.

2021-02-10 16:41:15,309 ERROR [stderr] (default task-7) javax.net.ssl|ERROR|03 81|default task-7|2021-02-10 16:41:15.309 IST|null:-1|Fatal (CERTIFICATE_UNKNOWN): No trusted certificate found (
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7) "throwable" : {
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)   sun.security.validator.ValidatorException: No trusted certificate found
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.validator.SimpleValidator.buildTrustedChain(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.validator.SimpleValidator.engineValidate(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.validator.Validator.validate(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.X509TrustManagerImpl.checkClientTrusted(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.checkClientCerts(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.onCertificate(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.CertificateMessage$T12CertificateConsumer.consume(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.SSLHandshake.consume(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.HandshakeContext.dispatch(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask$DelegatedAction.run(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/java.security.AccessController.doPrivileged(Native Method)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/sun.security.ssl.SSLEngineImpl$DelegatedTask.run(Unknown Source)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at io.undertow.core@2.1.3.Final//io.undertow.protocols.ssl.SslConduit$5.run(SslConduit.java:1107)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at org.jboss.threads@2.3.3.Final//org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at org.jboss.threads@2.3.3.Final//org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
2021-02-10 16:41:15,309 ERROR [stderr] (default task-7)         at java.base/java.lang.Thread.run(Unknown Source)}

Is there any other configuration needed apart from the ones mentioned in the above link ?

Are you sure the client certificate is being sent to Keycloak?

I was facing some challenges trying to get x509 authentication to work. I had to do the following to help troubleshoot my issues:

  1. Enable full SSL logging on my local environment with -Djava.net.debug=all. Now this produced massive amounts of logs, but it did help find that my truststore was not being properly loaded. I had to fix my truststore settings on standalone.xml. You can combine this option with a simple curl -v command to see what is happening both in the client and on the server side.
  2. Once you are certain you have a proper truststore, then undo the option set above, and enable TRACE logging on Keycloak. You can do so by starting Keycloak with KEYCLOAK_LOGLEVEL: TRACE if you are running on docker.
    1. This was helpful by having detailed information why authentication was failing.