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

org.bouncycastle.jsse.provider.ProvTrustManagerFactorySpi Maven / Gradle / Ivy

Go to download

The Bouncy Castle Java APIs for the TLS, including a JSSE provider. The APIs are designed primarily to be used in conjunction with the BC FIPS provider. The APIs may also be used with other providers although if being used in a FIPS context it is the responsibility of the user to ensure that any other providers used are FIPS certified and used appropriately.

There is a newer version: 2.0.19
Show newest version
package org.bouncycastle.jsse.provider;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.cert.CertPathParameters;
import java.security.cert.Certificate;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.net.ssl.CertPathTrustManagerParameters;
import javax.net.ssl.ManagerFactoryParameters;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactorySpi;

class ProvTrustManagerFactorySpi
    extends TrustManagerFactorySpi
{
    private static final Logger LOG = Logger.getLogger(ProvTrustManagerFactorySpi.class.getName());

    static KeyStore getDefaultTrustStore() throws Exception
    {
        String defaultType = KeyStore.getDefaultType();

        String tsPath = null;
        char[] tsPassword = null;

        String tsPathProp = PropertyUtils.getSystemProperty("javax.net.ssl.trustStore");
        if ("NONE".equals(tsPathProp))
        {
            // Do not try to load any file
        }
        else if (null != tsPathProp)
        {
            if (new File(tsPathProp).exists())
            {
                tsPath = tsPathProp;
            }
        }
        else
        {
            String javaHome = PropertyUtils.getSystemProperty("java.home");
            if (null != javaHome)
            {
                String jsseCacertsPath = javaHome + "/lib/security/jssecacerts".replace("/", File.separator);
                if (new File(jsseCacertsPath).exists())
                {
                    defaultType = "jks";
                    tsPath = jsseCacertsPath;
                }
                else
                {
                    String cacertsPath = javaHome + "/lib/security/cacerts".replace("/", File.separator);
                    if (new File(cacertsPath).exists())
                    {
                        defaultType = "jks";
                        tsPath = cacertsPath;
                    }
                }
            }
        }

        KeyStore ks = createTrustStore(defaultType);

        String tsPasswordProp = PropertyUtils.getSystemProperty("javax.net.ssl.trustStorePassword");
        if (null != tsPasswordProp)
        {
            tsPassword = tsPasswordProp.toCharArray();
        }

        InputStream tsInput = null;
        try
        {
            if (null == tsPath)
            {
                LOG.info("Initializing empty trust store");
            }
            else
            {
                LOG.info("Initializing with trust store at path: " + tsPath);
                tsInput = new BufferedInputStream(new FileInputStream(tsPath));
            }

            ks.load(tsInput, tsPassword);
        }
        finally
        {
            if (null != tsInput)
            {
                tsInput.close();
            }
        }

        return ks;
    }

    protected final Provider pkixProvider;

    protected ProvX509TrustManager x509TrustManager;

    ProvTrustManagerFactorySpi(Provider pkixProvider)
    {
        this.pkixProvider = pkixProvider;
    }

    @Override
    protected TrustManager[] engineGetTrustManagers()
    {
        if (null == x509TrustManager)
        {
            throw new IllegalStateException("TrustManagerFactory not initialized");
        }

        return new TrustManager[]{ x509TrustManager.getExportX509TrustManager() };
    }

    @Override
    protected void engineInit(KeyStore ks)
        throws KeyStoreException
    {
        if (null == ks)
        {
            try
            {
                ks = getDefaultTrustStore();
            }
            catch (SecurityException e)
            {
                LOG.log(Level.WARNING, "Skipped default trust store", e);
                // Ignore
            }
            catch (Error e)
            {
                LOG.log(Level.WARNING, "Skipped default trust store", e);
                throw e;
            }
            catch (RuntimeException e)
            {
                LOG.log(Level.WARNING, "Skipped default trust store", e);
                throw e;
            }
            catch (Exception e)
            {
                LOG.log(Level.WARNING, "Skipped default trust store", e);
                throw new KeyStoreException("Failed to load default trust store", e);
            }
        }

        Set trustAnchors = getTrustAnchors(ks);

        try
        {
            this.x509TrustManager = new ProvX509TrustManager(pkixProvider, trustAnchors);
        }
        catch (InvalidAlgorithmParameterException e)
        {
            throw new KeyStoreException("Failed to create trust manager", e);
        }
    }

    @Override
    protected void engineInit(ManagerFactoryParameters spec)
        throws InvalidAlgorithmParameterException
    {
        if (spec instanceof CertPathTrustManagerParameters)
        {
            try
            {
                CertPathParameters param = ((CertPathTrustManagerParameters)spec).getParameters();

                if (!(param instanceof PKIXParameters))
                {
                    throw new InvalidAlgorithmParameterException("parameters must inherit from PKIXParameters");
                }

                PKIXParameters pkixParam = (PKIXParameters)param;

                this.x509TrustManager = new ProvX509TrustManager(pkixProvider, pkixParam);
            }
            catch (GeneralSecurityException e)
            {
                throw new InvalidAlgorithmParameterException("unable to process parameters: " + e.getMessage(), e);
            }
        }
        else
        {
            if (spec == null)
            {
                throw new InvalidAlgorithmParameterException("spec cannot be null");
            }
            throw new InvalidAlgorithmParameterException("unknown spec: " + spec.getClass().getName());
        }
    }

    private static KeyStore createTrustStore(String defaultType)
        throws NoSuchProviderException, KeyStoreException
    {
        String tsType = getTrustStoreType(defaultType);
        String tsProv = PropertyUtils.getSystemProperty("javax.net.ssl.trustStoreProvider");
        return (null == tsProv || tsProv.length() < 1)
            ?   KeyStore.getInstance(tsType)
            :   KeyStore.getInstance(tsType, tsProv);
    }

    private static Set getTrustAnchors(KeyStore trustStore)
        throws KeyStoreException
    {
        if (null == trustStore)
        {
            return Collections.emptySet();
        }

        Set anchors = new HashSet(trustStore.size());
        for (Enumeration en = trustStore.aliases(); en.hasMoreElements();)
        {
            String alias = (String)en.nextElement();
            if (trustStore.isCertificateEntry(alias))
            {
                Certificate cert = trustStore.getCertificate(alias);
                if (cert instanceof X509Certificate)
                {
                    anchors.add(new TrustAnchor((X509Certificate)cert, null));
                }
            }
        }
        return anchors;
    }

    private static String getTrustStoreType(String defaultType)
    {
        String tsType = PropertyUtils.getSystemProperty("javax.net.ssl.trustStoreType");
        return (null == tsType) ? defaultType : tsType;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy