at.spardat.xma.boot.comp.Pinning509TrustManager Maven / Gradle / Ivy
/*
* @(#) $Id: $
*
* Copyright 2009/2010 by sIT Solutions, A-1110 Wien, Geiselbergstr.21-25. All rights reserved.
*/
package at.spardat.xma.boot.comp;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import at.spardat.xma.boot.comp.data.XMAApp;
import at.spardat.xma.boot.comp.data.XMASSLRestriction;
import at.spardat.xma.boot.exc.BRTCodes;
import at.spardat.xma.boot.exc.BootRuntimeException;
import at.spardat.xma.boot.logger.LogLevel;
import at.spardat.xma.boot.logger.Logger;
import at.spardat.xma.boot.transport.HostnameVerifierImpl;
public class Pinning509TrustManager implements X509TrustManager {
private static Logger log_;
private static Pinning509TrustManager instance;
private Set serverCertificateSet = new HashSet();
private final X509TrustManager defaultX509TrustManager;
public Pinning509TrustManager() throws NoSuchAlgorithmException, KeyStoreException {
log_ = Logger.getLogger("boot.appManager"); //$NON-NLS-1$
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore) null);
TrustManager tms[] = tmf.getTrustManagers();
/*
* Iterate over the returned trustmanagers, look for an instance of X509TrustManager. If found, use that as our
* "default" trust manager.
*/
X509TrustManager x509tm = null;
for (TrustManager tm : tms) {
if (tm instanceof X509TrustManager) {
x509tm = (X509TrustManager) tm;
break;
}
}
if (x509tm == null) {
throw new RuntimeException("No default 509 trust manager found");
}
defaultX509TrustManager = x509tm;
}
public static synchronized Pinning509TrustManager getInstance() {
if (instance == null) {
try {
instance = new Pinning509TrustManager();
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[] { instance }, null);
HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
} catch (Exception e) {
log_.log(LogLevel.SEVERE, "Error setting trust manager", e);
throw new RuntimeException("Error setting trust manager", e);
}
}
return instance;
}
public Set getServerCertificateSet() {
return serverCertificateSet;
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
defaultX509TrustManager.checkClientTrusted(chain, authType);
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
defaultX509TrustManager.checkServerTrusted(chain, authType);
serverCertificateSet.add(chain[0]);
}
public X509Certificate[] getAcceptedIssuers() {
return defaultX509TrustManager.getAcceptedIssuers();
}
public void checkCertificatePinning(XMAApp app) throws BootRuntimeException {
Iterator iterator = getServerCertificateSet().iterator();
while (iterator.hasNext()) {
X509Certificate cert = iterator.next();
checkCertificate(cert, app);
iterator.remove();
}
}
private void checkCertificate(X509Certificate cert, XMAApp app) throws BootRuntimeException {
List sslRestriction = app.getSSLRestriction();
if (!sslRestriction.isEmpty()) {
String server = app.getApplicationDescrURI().getServer();
String issuerDn = cert.getIssuerDN().getName();
String subjectDN = cert.getSubjectDN().getName();
for (XMASSLRestriction restriction : sslRestriction) {
boolean hostNameMatches = true;
if (restriction.getHostname() != null) {
HostnameVerifierImpl verifier = new HostnameVerifierImpl(restriction.getHostname());
hostNameMatches = verifier.verify(server);
}
if (hostNameMatches && restriction.matchesIssuer(issuerDn) && restriction.matchesSubject(subjectDN)) {
return;
}
}
log_.log(LogLevel.SEVERE, "SSL certificate pinning failed, certificate not accepted: \n{0}", cert);
throw new BootRuntimeException(BRTCodes.getText(BRTCodes.COMPONENT_NOT_ACCEPTED),
"SLL Certificate Pinning Error", server).setCode(BRTCodes.COMPONENT_NOT_ACCEPTED);
}
}
}