There is little chance that the answers to 2 questions is going to be the same because I don't think the TrustMananger gets the domain name of the server at all.
Actually, the trust manager can get the name of the host name you were after. It depends on a number of factors though.
Let's just assume your clients are running on Java 7.
If you follow the same method as in this other answer but use an X509ExtendedTrustManager
(introduced in Java 7, as opposed to a plain X509TrustManager
), you'll get additional overloaded methods that give you the current SSLSocket
or SSLEngine
as well.
The SSLContext
makes use of these methods when initialised with an X509ExtendedTrustManager
instance, but not when it's a plain X509TrustManager
, so it must be checking the type before making those calls (see quick test at the end of this answer, base on the code in that answer).
I'm not sure where this behaviour is specified the API. There doesn't seem to be anything about this X509ExtendedTrustManager
type-check in the JSSE Reference Guide.
One way of making sure the extended methods are used would be to set an enpoint identification algorithm (like HTTPS) in your SSLParameters
, but you'd need some degree of control of the client code and the libraries it uses. (This is also a feature introduced in Java 7.)
From the SSLSocket
or SSLEngine
obtained there, you can get the SSLSession
and the peer host, so you could perform checks there. (Note that the host name may not quite match what was intended if the library creating the SSLSocket
or SSLEngine
didn't use one of the method that passes that name as a String
, but passed an InetAddress
instead. You'll also lose SNI in this case.)
You could then use such a trust manager in your default SSLContext
(with setDefault(...)
).
If you don't want to affect the default SSLContext
(a sensible choice for these kind of tweaking), you'll need to figure out how your client library can use a different one per connection. This depends entirely on what's used.
For a traditional URLConnection
, cast it as an HttpsURLConnection
and set is SSLSocketFactory
as one build from your custom SSLContext
.
Which methods are used will depend on whether you've instantiated an X509ExtendedTrustManager
or a X509TrustManager
:
X509TrustManager customTm = new X509ExtendedTrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return finalTm.getAcceptedIssuers();
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
System.out
.println("Current method: checkServerTrusted(chain, authType)");
finalTm.checkServerTrusted(chain, authType);
}
//@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType, Socket socket) throws CertificateException {
System.out
.println("Current method: checkServerTrusted(chain, authType, socket)");
finalTm.checkServerTrusted(chain, authType, socket);
}
//@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType, SSLEngine engine)
throws CertificateException {
System.out
.println("Current method: checkServerTrusted(chain, authType, engine)");
finalTm.checkServerTrusted(chain, authType, engine);
}
// Same for client-related methods.
};