I’m connecting through a SSLSocket to a distant host which is using a certificate for the handshake. As we don’t use the default JVM truststore with all the certificate authorities, i need to add the remote host certificates to my truststore.
How can i get the certificates that i should trust from the SSLSocket? It seems do retrieve them i need to use the SSLSession which seems to require the handshake.
Why do we need to perform the handshake to be able to retrieve the certificates?
Is there any tool that permits to extract the remote host certificates used?
Normally, you shouldn’t get the certificate you should trust from an
SSLSocket, instead, it should be a configured setting that you obtained independently, as a reference for what you want to trust.What you seem to want to do is to get the certificate for the first connection, hoping that that connection wasn’t intercepted, and then use this as a reference for subsequent connections (similar to what’s commonly done with SSH, when you don’t necessarily know the server key’s fingerprint on the first connection, but check that you get the same later).
Security-wise, this isn’t ideal because the initial connection may be intercepted by a MITM attacker (which would make all subsequent connections vulnerable), but that’s certainly a way to mitigate the risks. Ideally, you should compare that certificate with a known reference you’ve obtained some other way.
You can access the remote certificate during the handshake using a custom
X509TrustManager(or you can disable trust verification with it and get the certificate later), which you can then use to initialise anSSLContext, from which you can obtain yourSSLSocketFactory. It’s generally a bad idea to disable trust verification in a trust manager (since it opens the connection to MITM attacks), but it can be acceptable for this purpose. You may be interested in theInstallCertutility, which should do more or less what you’re after.This is done during the handshake, because the purpose of the SSL/TLS socket API is to provide the application layer with a socket it can consider secure and use more or less as a normal socket at that stage. Typically, for most uses of JSSE (or generally other SSL/TLS stacks), as an application developer using that stack, you don’t want to have to do the verification explicitly. Checking the certificate during the handshake is also recommended as part of the TLS specification: