Confluence and Crowd - TLS accepts expired certificate in Java

Still need help?

The Atlassian Community is here for you.

Ask the community


Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.

Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Except Fisheye and Crucible

Summary

When connecting Confluence and Crowd using TLS (HTTPS), it is essential to import the application's SSL certificate to prevent connection failures (PKIX errors).

In certain scenarios, if you are using a server certificate (rather than a CA certificate), Confluence and Crowd may continue to operate with expired TLS certificates. This is considered not optimal.

Diagnosis

There are several ways to check your certificate.

You can verify the certificate validity date by using the web browser or by using the following OpenSSL command. 

openssl s_client -showcerts -servername <Server CN or FQDN> -connect <Server CN or FQDN>:443 | openssl x509 -noout -dates

(info) Please change <Server CN or FQDN> to match your server address like atlassian.net

With org.apache.http debug logs enabled, we don't see it verifying the certificate expiry date.

2024-09-09 13:10:02,229 DEBUG [http-nio-8090-exec-8 url: /confluence/rest/applinks/3.0/status/7422c381-13db-386b-a0d9-438bcea07c12; user: admin] [http.conn.ssl.SSLConnectionSocketFactory] createLayeredSocket Starting handshake
2024-09-09 13:10:02,230 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] createLayeredSocket Enabled protocols: [TLSv1.3, TLSv1.2]
...
2024-09-09 13:10:02,231 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] createLayeredSocket Starting handshake
2024-09-09 13:10:02,272 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname Secure session established
2024-09-09 13:10:02,272 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname  negotiated protocol: TLSv1.3
2024-09-09 13:10:02,272 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname  negotiated cipher suite: TLS_AES_128_GCM_SHA256
2024-09-09 13:10:02,272 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname  peer principal: CN=test.com, O=Internet Widgits Pty Ltd, ST=Some-State, C=AU
2024-09-09 13:10:02,272 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname  issuer principal: CN=test.com, O=Internet Widgits Pty Ltd, ST=Some-State, C=AU
...
2024-09-09 13:10:02,273 DEBUG [AppLinks ConcurrentExecutor:thread-2] [http.impl.conn.DefaultHttpClientConnectionOperator] connect Connection established 172.50.0.4:34142<->172.50.0.5:443
...
2024-09-09 13:10:02,280 DEBUG [http-nio-8090-exec-8 url: /confluence/rest/applinks/3.0/status/7422c381-13db-386b-a0d9-438bcea07c12; user: admin] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname Secure session established
2024-09-09 13:10:02,280 DEBUG [http-nio-8090-exec-8 url: /confluence/rest/applinks/3.0/status/7422c381-13db-386b-a0d9-438bcea07c12; user: admin] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname  negotiated protocol: TLSv1.3
2024-09-09 13:10:02,280 DEBUG [http-nio-8090-exec-8 url: /confluence/rest/applinks/3.0/status/7422c381-13db-386b-a0d9-438bcea07c12; user: admin] [http.conn.ssl.SSLConnectionSocketFactory] verifyHostname  negotiated cipher suite: TLS_AES_128_GCM_SHA256


Cause

Such behavior is correct ("as designed") if the certificate itself is listed in the truststore of the verifying party.

When the checked certificate is directly listed in the truststore, the certpath validation is skipped in Java:

It doesn't contradict the Section 6 in RFC 5280

As a result, not-yet-valid and expired certificates are accepted (considered valid) when listed directly in the Java truststore.

Solution

If you want to have the certificate validity checked during the TLS handshake, then we need to remove the server certificate and add the issuing CA's certificate into the truststore. Don't place there the server certificate itself.

We can use the java keytool to remove the server certificate. The following command to list all imported certificates and their expiration date:

keytool -list -v -keystore <path to your cacerts> |grep -E '^Alias name:|^Valid

Then remove the old server certificate by using:

keytool -delete -noprompt -alias confluence  -keystore <path to your cacerts>

Lastly, we can import the CA certificate by using:

keytool -importcert -alias my-ca -keystore <path to your cacerts> -file <your CA certificate file>

(info) Remember to change <path to your cacerts>,  <your CA certificate file> to match yours.

(info) In the import command we are using my-ca as an alias, you can change it as needed.

Now if the certificate expire, the connection will fail with the PKIX error. Like this:

Security logs:

2024-09-09 14:56:11,985 ERROR [Caesium-1-2] [atlassian.crowd.directory.DbCachingDirectoryPoller] pollChanges Error occurred while refreshing the cache for directory [ 393218 ].
com.atlassian.crowd.exception.OperationFailedException: javax.net.ssl.SSLHandshakeException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
...
Caused by: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: validity check failed
...
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Sat Sep 07 13:00:00 UTC 2024 

Confluence debug logs:

2024-09-09 14:56:11,809 DEBUG [Caesium-1-2] [http.conn.ssl.SSLConnectionSocketFactory] createLayeredSocket Starting handshake
2024-09-09 14:56:11,851 DEBUG [Caesium-1-2] [http.impl.conn.DefaultManagedHttpClientConnection] shutdown http-outgoing-54: Shutdown connection
2024-09-09 14:56:11,851 DEBUG [Caesium-1-2] [http.impl.execchain.MainClientExec] abortConnection Connection discarded


Notes

https://confluence.atlassian.com/doc/running-confluence-over-ssl-or-https-161203.html

How to import a public SSL certificate into a JVM

How to import an existing SSL certificate for use in Tomcat

https://confluence.atlassian.com/kb/unable-to-connect-to-ssl-services-due-to-pkix-path-building-failed-error-779355358.html


Last modified on Sep 9, 2024

Was this helpful?

Yes
No
Provide feedback about this article
Powered by Confluence and Scroll Viewport.