X509ExtendedTrustManager Class
The X509ExtendedTrustManager class is an abstract implementation of the
X509TrustManager interface. The X509ExtendedTrustManager class
adds methods for connection-sensitive trust management. In addition, the class enables endpoint
verification at the TLS layer.
In TLS 1.2 and later, both client and server can specify which hash and signature algorithms they
will accept. To authenticate the remote side, authentication decisions must be based on both X509
certificates and the local accepted hash and signature algorithms. You can get the local accepted
hash and signature algorithms from the
ExtendedSSLSession.getLocalSupportedSignatureAlgorithms() method.
You can retrieve the ExtendedSSLSession by calling the
SSLSocket.getHandshakeSession() method or the
SSLEngine.getHandshakeSession() method.
The X509TrustManager interface is not connection-sensitive. The interface
provides no way to access SSLSocket or SSLEngine session
properties.
In addition to TLS 1.2 support, the X509ExtendedTrustManager class also supports
algorithm constraints and SSL layer hostname verification. For JSSE providers and trust manager
implementations, the X509ExtendedTrustManager class is highly recommended rather
than the legacy X509TrustManager interface.
Creating an X509ExtendedTrustManager subclass
You can either
create an X509ExtendedTrustManager subclass yourself, as described in the following
section, or obtain one from a provider-based TrustManagerFactory class, such as
that supplied by the IBMJSSE2 provider. The PKIX or IbmX509TrustManagerFactory
class returns an X509ExtendedTrustManager instance.Creating your own X509ExtendedTrustManager
subclass
This section describes how to create a subclass of the
X509ExtendedTrustManager class. The method is very similar to the method described
for the X509TrustManager class. TrustManagerFactory class to locate a default
X509ExtendedTrustManager object that will be used to make decisions about trust. If
the default trust manager fails, the subclass can add other behavior. In the example, these
locations are indicated by comments in the catch clauses.
import java.io.*;
import java.net.*;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
public class MyX509ExtendedTrustManager extends X509ExtendedTrustManager {
/*
* The default PKIX X509ExtendedTrustManager. We'll delegate
* decisions to it, and fall back to the logic in this class if the
* default X509ExtendedTrustManager doesn't trust it.
*/
X509ExtendedTrustManager pkixTrustManager;
MyX509ExtendedTrustManager() throws Exception {
// create a "default" JSSE X509ExtendedTrustManager.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("trustedCerts"),
"passphrase".toCharArray());
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);
TrustManager tms [] = tmf.getTrustManagers();
/*
* Iterate over the returned trustmanagers, look
* for an instance of X509TrustManager. If found,
* use that as our "default" trust manager.
*/
for (int i = 0; i <= dedTrustManager) tms[i];
return;
}
}
/*
* Find some other way to initialize, or else we have to fail the
* constructor.
*/
throw new Exception("Couldn't initialize");
}
/*
* Delegate to the default trust manager.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
pkixTrustManager.checkClientTrusted(chain, authType);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}
/*
* Delegate to the default trust manager.
*/
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
pkixTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException excep) {
/*
* Possibly pop up a dialog box asking whether to trust the
* cert chain.
*/
}
}
/*
* Connection-sensitive verification.
*/
public void checkClientTrusted(X509Certificate[] chain, String authType,
Socket socket)
throws CertificateException {
try {
pkixTrustManager.checkClientTrusted(chain, authType, socket);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}
public void checkClientTrusted(X509Certificate[] chain, String authType,
SSLEngine engine)
throws CertificateException {
try {
pkixTrustManager.checkClientTrusted(chain, authType, engine);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}
public void checkServerTrusted(X509Certificate[] chain, String authType,
Socket socket)
throws CertificateException {
try {
pkixTrustManager.checkServerTrusted(chain, authType, socket);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}
public void checkServerTrusted(X509Certificate[] chain, String authType,
SSLEngine engine)
throws CertificateException {
try {
pkixTrustManager.checkServerTrusted(chain, authType, engine);
} catch (CertificateException excep) {
// do any special handling here, or rethrow exception.
}
}
/*
* Merely pass this through.
*/
public X509Certificate[] getAcceptedIssuers() {
return pkixTrustManager.getAcceptedIssuers();
}
}