Spark certificates management update

This build https://bamboo.igniterealtime.org/browse/SPARK-NIGHTLY-1542/artifact/shared/Install4j-generated-media/ incorporates PR #550.

It is intended to fix these issues:
https://igniterealtime.atlassian.net/browse/SPARK-2184 - Spark should not reject end-entity certificates without basic constraints
https://igniterealtime.atlassian.net/browse/SPARK-2185 - The CertPath that’s verified should not be allowed to be empty
https://igniterealtime.atlassian.net/browse/SPARK-2186 - Certificate validation should target the end-entity certificate, not the CA
https://igniterealtime.atlassian.net/browse/SPARK-2187 - Spark should not offer to add CA certs that it already has in the truststore
https://igniterealtime.atlassian.net/browse/SPARK-2188 - Some certificate chain validations fail with ‘Certificate does not specify OCSP responder’

To be honest, i don’t understand much of issues described here :slight_smile: But i trust @guus. I have tried this build with a fresh profile and it works as intended with 3 servers i have tested it on.

@speedy @Alameyo @ilyaHlevnoy @R87A if you can take a look and provide any observations about the code or any issues noticed when running this build (specifically when signing in to servers and accepting certificates), this would be helpful to understand if this patch was successful and haven’t broken anything.

Famous last words.

1 Like

I seem to have found some problem:
I have a test Openfire server that has a certificate issued by a CA

I import the CA certificate into Spark, Spark says that this certificate already exists:

This is true, next I import the following CA:

and after that I try to connect to the server, but I get this error:

But if I delete the intermediate certificate GeoTrust RSA CA 2018 then I can connect to the server.

Very strange, I imported the complete certificate chain, but I can’t connect!
But if I don’t import the certificate chain then I can connect.

If I do the same in Spark 2.9.3. I import the full CA chain (root + CA), then I can connect, but why does Spark prompt me to add a certificate to the trusted one? I added the entire chain and instructed not to check the expiration date …


That is strange. Is this also happening with the version of Spark that does not include my changes?

It should not be needed to include all of the intermediate certificates, by the way. You only need the last certificate, the root CA. Still, even if you do install the intermediates, it should work.

I have completed the answer, please read it again)

1 Like

I have installed a new certificate.

I deleted the spark profile and try again.

Here, of course, it’s strange, the default Root certificate is already in the trusted certificates.

I add a CA certificate and now Spark does not ask me about the certificate and just connects, then the problem was in the expired certificate.

Can I connect to your server? Can you provide the certificates that you imported, so that I can try on my laptop?

I am now noticing that you have configured Openfire with two certificates. This can lead to very unexpected problems. Although this depends a little on the version of Java that you use, typically, Java will almost randomly choose one of the installed certificates even if it is expired, while the other one is not.

I advice you to remove all certificates from Openfire except for the one that you want to use.

Unfortunately, this server is inside the network, and I cannot give access (no rights), but I can provide certificates.

I installed a new certificate after my first post.
Ok, I deleted the old certificate.

But why does Spark suggest that I add a certificate to the trusted ones if the Root certificate is already in Java?
If I add an intermediate RSA 2018 certificate then Spark will quietly connect.

Here is the public key of the certificate chain, hopefully it helps:
INTERMEDIATE_CA.crt (1.6 КБ)

From my tests, I can make two conclusions:

  1. If you have an expired certificate (but the Root and CA certificate are valid) and you have enabled:
    Accept expires then you will get this error.
    2)This can be resolved by removing the CA certificate. If you delete the Root certificate, then Spark will still give an error. Therefore, I think Spark only sees the first CA and does not see the entire certificate chain = (

I can confirm that in Spark 2.9.4 if you import a valid CA certificate then Spark will just connect, it’s great!!

But I’m worried that your SSL will expire then you get an error: “Certificate path validation failed”

I think Spark should connect to the server even if your SSL certificate has expired and these items are enabled.
What do you think?
image

With these settings, I think Spark should accept the end-entity certificate, even if it is expired. If one of the intermediate certificates, or even the root CA certificate is expired, I’m not so sure if we should allow that with this setting. If that is now not the case, I’d be happy to leave that as-is.

So the fact of the matter is that my SSL certificate has expired.
But the Root certificate and the CA certificate have not expired.

My ssl certifiate - 17 sep 2019 - 16 oct 2020 (has expired)
My CA certificate - 06 nov 2017 - 06 now 2027 (GeoTrust RSA CA 2018)
My Root Certificate - 11 nov 2006 - 10 nov 2031 (DigiCert Global Root CA)

Therefore, I expect that if I enable the buttons in the screenshot above, I can go in, and I will not get an error.

Yes, I think that your expectation is correct.

But this does not happen = (
I get this error even if I enable these buttons.

I am trying to reproduce this problem, but so far, I’ve been unable to do so. Can you please copy/paste the stacktrace that is under the ‘details’ button @ilyaHlevnoy?

sure

org.jivesoftware.smack.SmackException: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Certificate path validation failed
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1176)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$1000(XMPPTCPConnection.java:1092)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:1112)
	at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Certificate path validation failed
	at sun.security.ssl.Alerts.getSSLException(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
	at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
	at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
	at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
	at sun.security.ssl.Handshaker.processLoop(Unknown Source)
	at sun.security.ssl.Handshaker.process_record(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:856)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$2000(XMPPTCPConnection.java:155)
	at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1171)
	... 3 more
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Certificate path validation failed
	at org.jivesoftware.sparkimpl.certificates.SparkTrustManager.checkServerTrusted(SparkTrustManager.java:97)
	at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown Source)
	... 14 more
Caused by: java.security.cert.CertPathValidatorException: Certificate path validation failed
	at org.jivesoftware.sparkimpl.certificates.SparkTrustManager.doTheChecks(SparkTrustManager.java:127)
	at org.jivesoftware.sparkimpl.certificates.SparkTrustManager.checkServerTrusted(SparkTrustManager.java:93)
	... 15 more
Caused by: java.security.cert.CertPathValidatorException: validity check failed
	at sun.security.provider.certpath.PKIXMasterCertPathValidator.validate(Unknown Source)
	at sun.security.provider.certpath.PKIXCertPathValidator.validate(Unknown Source)
	at sun.security.provider.certpath.PKIXCertPathValidator.validate(Unknown Source)
	at sun.security.provider.certpath.PKIXCertPathValidator.engineValidate(Unknown Source)
	at java.security.cert.CertPathValidator.validate(Unknown Source)
	at org.jivesoftware.sparkimpl.certificates.SparkTrustManager.validatePath(SparkTrustManager.java:274)
	at org.jivesoftware.sparkimpl.certificates.SparkTrustManager.doTheChecks(SparkTrustManager.java:123)
	... 16 more
Caused by: java.security.cert.CertificateExpiredException: NotAfter: Fri Oct 16 15:00:00 MSK 2020
	at sun.security.x509.CertificateValidity.valid(Unknown Source)
	at sun.security.x509.X509CertImpl.checkValidity(Unknown Source)
	at sun.security.provider.certpath.BasicChecker.verifyValidity(Unknown Source)
	at sun.security.provider.certpath.BasicChecker.check(Unknown Source)
	... 23 more

With @ilyaHlevnoy’s help, I’ve finally been able to reproduce this problem. I’ve raised it as https://igniterealtime.atlassian.net/browse/SPARK-2194

I’ve also identified the cause of this problem. The code to skip the date validation is using an API method that is intended for a very similar, but different purpose. To me, that was not clear even after reading the documentation (I had to debug, which is where @ilyaHlevnoy’s help was invaluable).

A fix has been supplied in https://github.com/igniterealtime/Spark/pull/553

1 Like

I am waiting build from bamboo for test. Thank you very much for paying attention to this problem.

Here you go https://bamboo.igniterealtime.org/browse/SPARK-NIGHTLY-1547/artifact/shared/Install4j-generated-media/

1 Like