All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.boot.comp.Pinning509TrustManager Maven / Gradle / Ivy

There is a newer version: 1.16.0
Show newest version
/*
 * @(#) $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);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy