From d3360602312aff7c1101b9533497fd59b3dd53ae Mon Sep 17 00:00:00 2001 From: Andreas Abraham Date: Mon, 10 Sep 2018 16:37:13 +0200 Subject: new pki module integration --- .../gv/egiz/bku/spring/PKIProfileFactoryBean.java | 570 +++++++++++---------- .../at/gv/egiz/bku/spring/PKITrustManager.java | 369 +++++++------ 2 files changed, 474 insertions(+), 465 deletions(-) (limited to 'bkucommon') diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java index 2debb2fc..5b57845a 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKIProfileFactoryBean.java @@ -1,280 +1,290 @@ -/* - * Copyright 2011 by Graz University of Technology, Austria - * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint - * initiative of the Federal Chancellery Austria and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - - -package at.gv.egiz.bku.spring; - -import iaik.logging.LogConfigurationException; -import iaik.logging.LoggerConfig; -import iaik.logging.impl.TransactionIdImpl; -import iaik.pki.DefaultPKIConfiguration; -import iaik.pki.DefaultPKIProfile; -import iaik.pki.PKIException; -import iaik.pki.PKIFactory; -import iaik.pki.PKIProfile; -import iaik.pki.revocation.RevocationSourceTypes; -import iaik.pki.store.certstore.CertStoreParameters; -import iaik.pki.store.certstore.directory.DefaultDirectoryCertStoreParameters; -import iaik.pki.store.truststore.DefaultTrustStoreProfile; -import iaik.pki.store.truststore.TrustStoreProfile; -import iaik.pki.store.truststore.TrustStoreTypes; - -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import org.apache.commons.configuration.CompositeConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.FileConfiguration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.context.ResourceLoaderAware; -import org.springframework.core.io.Resource; -import org.springframework.core.io.ResourceLoader; - -import at.gv.egiz.bku.conf.IAIKLogAdapterFactory; -import at.gv.egiz.bku.conf.MoccaConfigurationFacade; -import at.gv.egiz.bku.utils.ConfigurationUtil; - -public class PKIProfileFactoryBean implements FactoryBean, ResourceLoaderAware { - - protected static final Logger log = LoggerFactory.getLogger(PKIProfileFactoryBean.class); - - /** - * The configuration facade. - */ - protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); - - public class ConfigurationFacade implements MoccaConfigurationFacade { - - private Configuration configuration; - - public static final String SSL_CERT_DIRECTORY = "SSL.certDirectory"; - - public static final String SSL_CERT_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/certStore"; - - public static final String SSL_CA_DIRECTORY = "SSL.caDirectory"; - - public static final String SSL_CA_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/trustStore"; - - public static final String SSL_REVOCATION_SERVICE_ORDER = "SSL.revocationServiceOrder"; - - public URL getCertDirectory() throws MalformedURLException { - return getURL(SSL_CERT_DIRECTORY); - } - - public URL getCaDirectory() throws MalformedURLException { - return getURL(SSL_CA_DIRECTORY); - } - - public List getRevocationServiceOrder() throws Exception { - return ConfigurationUtil.getStringListFromObjectList( - configuration.getList(SSL_REVOCATION_SERVICE_ORDER)); - } - - private URL getURL(String key) throws MalformedURLException { - String url = configuration.getString(key); - if (url == null || url.isEmpty()) { - return null; - } - return new URL(getBasePath(key), configuration.getString(key)); - } - - private URL getBasePath(String key) { - Configuration configuration = this.configuration; - if (configuration instanceof CompositeConfiguration) { - CompositeConfiguration compositeConfiguration = (CompositeConfiguration) configuration; - for (int i = 0; i < compositeConfiguration.getNumberOfConfigurations(); i++) { - if (compositeConfiguration.getConfiguration(i).containsKey(key)) { - configuration = compositeConfiguration.getConfiguration(i); - break; - } - } - } - if (configuration instanceof FileConfiguration) { - return ((FileConfiguration) configuration).getURL(); - } - return null; - } - - } - - - private ResourceLoader resourceLoader; - - protected String trustProfileId; - - @Override - public void setResourceLoader(ResourceLoader loader) { - this.resourceLoader = loader; - } - - /** - * @return the configuration - */ - public Configuration getConfiguration() { - return configurationFacade.configuration; - } - - /** - * @param configuration the configuration to set - */ - public void setConfiguration(Configuration configuration) { - configurationFacade.configuration = configuration; - } - - /** - * @return the trustProfileId - */ - public String getTrustProfileId() { - return trustProfileId; - } - - /** - * @param trustProfileId the trustProfileId to set - */ - public void setTrustProfileId(String trustProfileId) { - this.trustProfileId = trustProfileId; - } - - protected File getDirectory(String url) throws IOException { - Resource resource = resourceLoader.getResource(url); - File path = resource.getFile(); - if (!path.exists() && !path.isDirectory()) { - throw new IOException("URL '" + url + "' is not a directory."); - } - return path; - } - - protected void configureIAIKLogging() { - // initialize IAIK logging for PKI module - iaik.logging.LogFactory.configure(new LoggerConfig() { - - @Override - public Properties getProperties() throws LogConfigurationException { - return null; - } - - @Override - public String getNodeId() { - return "pki"; - } - - @Override - public String getFactory() { - return IAIKLogAdapterFactory.class.getName(); - } - }); - } - - protected void configurePkiFactory() throws MalformedURLException, PKIException, IOException { - - URL url = configurationFacade.getCertDirectory(); - File certDirectory = (url != null) - ? getDirectory(url.toString()) - : getDirectory(ConfigurationFacade.SSL_CERT_DIRECTORY_DEFAULT); - - CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters( - "CS", certDirectory.getAbsolutePath(), true, false) }; - - DefaultPKIConfiguration pkiConfiguration = new DefaultPKIConfiguration(certStoreParameters); - - - PKIFactory pkiFactory = PKIFactory.getInstance(); - pkiFactory.configure(pkiConfiguration, new TransactionIdImpl("Configure-PKI")); - } - - protected TrustStoreProfile createDirectoryTrustStoreProfile() throws MalformedURLException, IOException { - - URL url = configurationFacade.getCaDirectory(); - File caDirectory = (url != null) - ? getDirectory(url.toString()) - : getDirectory(ConfigurationFacade.SSL_CA_DIRECTORY_DEFAULT); - - return new DefaultTrustStoreProfile(trustProfileId, - TrustStoreTypes.DIRECTORY, caDirectory.getAbsolutePath()); - - } - - protected String[] createRevocationServiceOrder() throws Exception { - List services = configurationFacade.getRevocationServiceOrder(); - - if (services != null) { - List order = new ArrayList(2); - for (String service : services) { - if ("OCSP".equals(service)) { - order.add(RevocationSourceTypes.OCSP); - } else if ("CRL".equals(service)) { - order.add(RevocationSourceTypes.CRL); - } else { - throw new Exception("Unsupported revocation service type " + service); - } - } - if (!order.isEmpty()) { - log.info("configure revocation service type order: {}", order); - return order.toArray(new String[order.size()]); - } - } - log.info("configure default revocation service type order: [CRL, OCSP]"); - return new String[] - { RevocationSourceTypes.CRL, RevocationSourceTypes.OCSP }; - } - - @Override - public Object getObject() throws Exception { - - configureIAIKLogging(); - - PKIFactory pkiFactory = PKIFactory.getInstance(); - - if (!pkiFactory.isAlreadyConfigured()) { - configurePkiFactory(); - } - - TrustStoreProfile trustProfile = createDirectoryTrustStoreProfile(); - - DefaultPKIProfile pkiProfile = new DefaultPKIProfile(trustProfile); - - pkiProfile.setAutoAddCertificates(true); - pkiProfile.setPreferredServiceOrder(createRevocationServiceOrder()); - - return pkiProfile; - } - - @Override - public Class getObjectType() { - return PKIProfile.class; - } - - @Override - public boolean isSingleton() { - return false; - } - -} +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + + +package at.gv.egiz.bku.spring; + +import iaik.logging.LogConfigurationException; +import iaik.logging.LoggerConfig; +import iaik.logging.TransactionId; +import iaik.logging.impl.TransactionIdImpl; +import iaik.pki.Configurator; +import iaik.pki.DefaultPKIConfiguration; +import iaik.pki.DefaultPKIProfile; +import iaik.pki.PKIException; +import iaik.pki.PKIFactory; +import iaik.pki.PKIProfile; +import iaik.pki.revocation.RevocationSourceTypes; +import iaik.pki.store.certstore.CertStoreParameters; +import iaik.pki.store.certstore.directory.DefaultDirectoryCertStoreParameters; +import iaik.pki.store.truststore.DefaultTrustStoreProfile; +import iaik.pki.store.truststore.TrustStoreProfile; +import iaik.pki.store.truststore.TrustStoreTypes; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import org.apache.commons.configuration.CompositeConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.FileConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.FactoryBean; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; + +import at.gv.egiz.bku.conf.IAIKLogAdapterFactory; +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; +import at.gv.egiz.bku.utils.ConfigurationUtil; + +public class PKIProfileFactoryBean implements FactoryBean, ResourceLoaderAware { + + protected static final Logger log = LoggerFactory.getLogger(PKIProfileFactoryBean.class); + + /** + * The configuration facade. + */ + protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + private Configuration configuration; + + public static final String SSL_CERT_DIRECTORY = "SSL.certDirectory"; + + public static final String SSL_CERT_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/certStore"; + + public static final String SSL_CA_DIRECTORY = "SSL.caDirectory"; + + public static final String SSL_CA_DIRECTORY_DEFAULT = "classpath:at/gv/egiz/bku/certs/trustStore"; + + public static final String SSL_REVOCATION_SERVICE_ORDER = "SSL.revocationServiceOrder"; + + public URL getCertDirectory() throws MalformedURLException { + return getURL(SSL_CERT_DIRECTORY); + } + + public URL getCaDirectory() throws MalformedURLException { + return getURL(SSL_CA_DIRECTORY); + } + + public List getRevocationServiceOrder() throws Exception { + return ConfigurationUtil.getStringListFromObjectList( + configuration.getList(SSL_REVOCATION_SERVICE_ORDER)); + } + + private URL getURL(String key) throws MalformedURLException { + String url = configuration.getString(key); + if (url == null || url.isEmpty()) { + return null; + } + return new URL(getBasePath(key), configuration.getString(key)); + } + + private URL getBasePath(String key) { + Configuration configuration = this.configuration; + if (configuration instanceof CompositeConfiguration) { + CompositeConfiguration compositeConfiguration = (CompositeConfiguration) configuration; + for (int i = 0; i < compositeConfiguration.getNumberOfConfigurations(); i++) { + if (compositeConfiguration.getConfiguration(i).containsKey(key)) { + configuration = compositeConfiguration.getConfiguration(i); + break; + } + } + } + if (configuration instanceof FileConfiguration) { + return ((FileConfiguration) configuration).getURL(); + } + return null; + } + + } + + + private ResourceLoader resourceLoader; + + protected String trustProfileId; + + @Override + public void setResourceLoader(ResourceLoader loader) { + this.resourceLoader = loader; + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configurationFacade.configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + configurationFacade.configuration = configuration; + } + + /** + * @return the trustProfileId + */ + public String getTrustProfileId() { + return trustProfileId; + } + + /** + * @param trustProfileId the trustProfileId to set + */ + public void setTrustProfileId(String trustProfileId) { + this.trustProfileId = trustProfileId; + } + + protected File getDirectory(String url) throws IOException { + Resource resource = resourceLoader.getResource(url); + File path = resource.getFile(); + if (!path.exists() && !path.isDirectory()) { + throw new IOException("URL '" + url + "' is not a directory."); + } + return path; + } + + protected void configureIAIKLogging() { + // initialize IAIK logging for PKI module + iaik.logging.LogFactory.configure(new LoggerConfig() { + + @Override + public Properties getProperties() throws LogConfigurationException { + return null; + } + + @Override + public String getNodeId() { + return "pki"; + } + + @Override + public String getFactory() { + return IAIKLogAdapterFactory.class.getName(); + } + }); + } + + protected void configurePkiFactory() throws MalformedURLException, PKIException, IOException { + + URL url = configurationFacade.getCertDirectory(); + File certDirectory = (url != null) + ? getDirectory(url.toString()) + : getDirectory(ConfigurationFacade.SSL_CERT_DIRECTORY_DEFAULT); + + CertStoreParameters[] certStoreParameters = { new DefaultDirectoryCertStoreParameters( + "CS", certDirectory.getAbsolutePath(), true, false) }; + + DefaultPKIConfiguration pkiConfiguration = new DefaultPKIConfiguration(certStoreParameters); + + +// PKIFactory pkiFactory = PKIFactory.getInstance(); +// pkiFactory.configure(pkiConfiguration, new TransactionIdImpl("Configure-PKI")); + TransactionId tid = new TransactionIdImpl("Configure-PKI"); + Configurator.initCommon(null, tid); + if (PKIFactory.getInstance().isAlreadyConfigured()) { + log.info("PKIfactory is already configured."); + } else { + PKIFactory.getInstance().configure(pkiConfiguration, tid); + } + + } + + protected TrustStoreProfile createDirectoryTrustStoreProfile() throws MalformedURLException, IOException { + + URL url = configurationFacade.getCaDirectory(); + File caDirectory = (url != null) + ? getDirectory(url.toString()) + : getDirectory(ConfigurationFacade.SSL_CA_DIRECTORY_DEFAULT); + + return new DefaultTrustStoreProfile(trustProfileId, + TrustStoreTypes.DIRECTORY, caDirectory.getAbsolutePath()); + + } + + protected String[] createRevocationServiceOrder() throws Exception { + List services = configurationFacade.getRevocationServiceOrder(); + + if (services != null) { + List order = new ArrayList(2); + for (String service : services) { + if ("OCSP".equals(service)) { + order.add(RevocationSourceTypes.OCSP); + } else if ("CRL".equals(service)) { + order.add(RevocationSourceTypes.CRL); + } else { + throw new Exception("Unsupported revocation service type " + service); + } + } + if (!order.isEmpty()) { + log.info("configure revocation service type order: {}", order); + return order.toArray(new String[order.size()]); + } + } + log.info("configure default revocation service type order: [CRL, OCSP]"); + return new String[] + { RevocationSourceTypes.CRL, RevocationSourceTypes.OCSP }; + } + + @Override + public Object getObject() throws Exception { + + configureIAIKLogging(); + + PKIFactory pkiFactory = PKIFactory.getInstance(); + + if (!pkiFactory.isAlreadyConfigured()) { + configurePkiFactory(); + } + + TrustStoreProfile trustProfile = createDirectoryTrustStoreProfile(); + + DefaultPKIProfile pkiProfile = new DefaultPKIProfile(trustProfile); + + pkiProfile.setAutoAddCertificates(PKIProfile.AUTO_ADD_EE_DISABLE); + pkiProfile.setPreferredServiceOrder(createRevocationServiceOrder()); + + return pkiProfile; + } + + @Override + public Class getObjectType() { + return PKIProfile.class; + } + + @Override + public boolean isSingleton() { + return false; + } + +} diff --git a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java index 076fdf11..7b82f2f8 100644 --- a/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java +++ b/bkucommon/src/main/java/at/gv/egiz/bku/spring/PKITrustManager.java @@ -1,185 +1,184 @@ -/* - * Copyright 2011 by Graz University of Technology, Austria - * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint - * initiative of the Federal Chancellery Austria and Graz University of Technology. - * - * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by - * the European Commission - subsequent versions of the EUPL (the "Licence"); - * You may not use this work except in compliance with the Licence. - * You may obtain a copy of the Licence at: - * http://www.osor.eu/eupl/ - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the Licence is distributed on an "AS IS" basis, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the Licence for the specific language governing permissions and - * limitations under the Licence. - * - * This product combines work with different licenses. See the "NOTICE" text - * file for details on the various modules and licenses. - * The "NOTICE" text file is part of the distribution. Any derivative works - * that you distribute must include a readable copy of the "NOTICE" text file. - */ - - - -package at.gv.egiz.bku.spring; - -import iaik.logging.TransactionId; -import iaik.pki.PKIException; -import iaik.pki.PKIFactory; -import iaik.pki.PKIModule; -import iaik.pki.PKIProfile; -import iaik.pki.store.truststore.TrustStore; -import iaik.pki.store.truststore.TrustStoreException; -import iaik.pki.store.truststore.TrustStoreFactory; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Date; -import java.util.Set; - -import javax.net.ssl.X509TrustManager; - -import org.apache.commons.configuration.Configuration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.MDC; - -import at.gv.egiz.bku.conf.MoccaConfigurationFacade; - -public class PKITrustManager implements X509TrustManager { - - Logger log = LoggerFactory.getLogger(PKITrustManager.class); - - protected PKIProfile pkiProfile; - - /** - * The configuration facade. - */ - protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); - - public class ConfigurationFacade implements MoccaConfigurationFacade { - - private Configuration configuration; - - public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks"; - - public boolean disableAllSslChecks() { - return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false); - } - - } - - /** - * @return the configuration - */ - public Configuration getConfiguration() { - return configurationFacade.configuration; - } - - /** - * @param configuration the configuration to set - */ - public void setConfiguration(Configuration configuration) { - configurationFacade.configuration = configuration; - } - - /** - * @return the pkiProfile - */ - public PKIProfile getPkiProfile() { - return pkiProfile; - } - - /** - * @param pkiProfile the pkiProfile to set - */ - public void setPkiProfile(PKIProfile pkiProfile) { - this.pkiProfile = pkiProfile; - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - checkServerTrusted(chain, authType); - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - - if (pkiProfile == null) { - throw new CertificateException("No PKI profile set. Configuration error."); - } - - if (configurationFacade.disableAllSslChecks()) { - log.warn("SSL certificate validation disabled. " + - "Accepted certificate {}.", chain[0].getSubjectDN()); - } else { - - iaik.x509.X509Certificate[] certs = convertCerts(chain); - - TransactionId tid = new MDCTransactionId(); - try { - PKIModule pkiModule = PKIFactory.getInstance().getPKIModule(pkiProfile); - if (!pkiModule.validateCertificate(new Date(), certs[0], certs, null, - tid).isCertificateValid()) { - throw new CertificateException("Certificate not valid."); - } - } catch (PKIException e) { - log.warn("Failed to validate certificate.", e); - throw new CertificateException("Failed to validate certificate. " + e.getMessage()); - } - - } - - } - - @Override - public X509Certificate[] getAcceptedIssuers() { - - if (pkiProfile == null) { - log.warn("No PKI profile set. Configuration error."); - return new X509Certificate[] {}; - } - - TransactionId tid = new MDCTransactionId(); - - try { - - TrustStore trustStore = TrustStoreFactory.getInstance(pkiProfile.getTrustStoreProfile(), tid); - @SuppressWarnings("unchecked") - Set certs = trustStore.getTrustedCertificates(tid); - return certs.toArray(new X509Certificate[certs.size()]); - } catch (TrustStoreException e) { - log.warn("Failed to get list of accepted issuers.", e); - return new X509Certificate[] {}; - } catch (ClassCastException e) { - log.error("Failed to cast list of accepted issuers.", e); - return new X509Certificate[] {}; - } - } - - private static iaik.x509.X509Certificate[] convertCerts( - X509Certificate[] certs) throws CertificateException { - iaik.x509.X509Certificate[] retVal = new iaik.x509.X509Certificate[certs.length]; - int i = 0; - for (X509Certificate cert : certs) { - if (cert instanceof iaik.x509.X509Certificate) { - retVal[i++] = (iaik.x509.X509Certificate) cert; - } else { - retVal[i++] = new iaik.x509.X509Certificate(cert.getEncoded()); - } - } - return retVal; - } - - private static class MDCTransactionId implements TransactionId { - @Override - public String getLogID() { - String sessionId = MDC.get("SessionId"); - return (sessionId != null) ? sessionId : "PKITrustManager"; - } - } -} +/* + * Copyright 2011 by Graz University of Technology, Austria + * MOCCA has been developed by the E-Government Innovation Center EGIZ, a joint + * initiative of the Federal Chancellery Austria and Graz University of Technology. + * + * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by + * the European Commission - subsequent versions of the EUPL (the "Licence"); + * You may not use this work except in compliance with the Licence. + * You may obtain a copy of the Licence at: + * http://www.osor.eu/eupl/ + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the Licence is distributed on an "AS IS" basis, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the Licence for the specific language governing permissions and + * limitations under the Licence. + * + * This product combines work with different licenses. See the "NOTICE" text + * file for details on the various modules and licenses. + * The "NOTICE" text file is part of the distribution. Any derivative works + * that you distribute must include a readable copy of the "NOTICE" text file. + */ + + + +package at.gv.egiz.bku.spring; + +import iaik.logging.TransactionId; +import iaik.pki.PKIException; +import iaik.pki.PKIFactory; +import iaik.pki.PKIModule; +import iaik.pki.PKIProfile; +import iaik.pki.store.truststore.TrustStore; +import iaik.pki.store.truststore.TrustStoreException; +import iaik.pki.store.truststore.TrustStoreFactory; + +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Date; +import java.util.Set; + +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.configuration.Configuration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import at.gv.egiz.bku.conf.MoccaConfigurationFacade; + +public class PKITrustManager implements X509TrustManager { + + Logger log = LoggerFactory.getLogger(PKITrustManager.class); + + protected PKIProfile pkiProfile; + + /** + * The configuration facade. + */ + protected final ConfigurationFacade configurationFacade = new ConfigurationFacade(); + + public class ConfigurationFacade implements MoccaConfigurationFacade { + + private Configuration configuration; + + public static final String SSL_DISSABLE_ALL_CHECKS = "SSL.disableAllChecks"; + + public boolean disableAllSslChecks() { + return configuration.getBoolean(SSL_DISSABLE_ALL_CHECKS, false); + } + + } + + /** + * @return the configuration + */ + public Configuration getConfiguration() { + return configurationFacade.configuration; + } + + /** + * @param configuration the configuration to set + */ + public void setConfiguration(Configuration configuration) { + configurationFacade.configuration = configuration; + } + + /** + * @return the pkiProfile + */ + public PKIProfile getPkiProfile() { + return pkiProfile; + } + + /** + * @param pkiProfile the pkiProfile to set + */ + public void setPkiProfile(PKIProfile pkiProfile) { + this.pkiProfile = pkiProfile; + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + checkServerTrusted(chain, authType); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) + throws CertificateException { + + if (pkiProfile == null) { + throw new CertificateException("No PKI profile set. Configuration error."); + } + + if (configurationFacade.disableAllSslChecks()) { + log.warn("SSL certificate validation disabled. " + + "Accepted certificate {}.", chain[0].getSubjectDN()); + } else { + + iaik.x509.X509Certificate[] certs = convertCerts(chain); + + TransactionId tid = new MDCTransactionId(); + try { + PKIModule pkiModule = PKIFactory.getInstance().getPKIModule(pkiProfile); + if (!pkiModule.validateCertificate(new Date(), certs[0], certs, null, + tid).isCertificateValid()) { + throw new CertificateException("Certificate not valid."); + } + } catch (PKIException e) { + log.warn("Failed to validate certificate.", e); + throw new CertificateException("Failed to validate certificate. " + e.getMessage()); + } + + } + + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + + if (pkiProfile == null) { + log.warn("No PKI profile set. Configuration error."); + return new X509Certificate[] {}; + } + + TransactionId tid = new MDCTransactionId(); + + try { + + TrustStore trustStore = TrustStoreFactory.getInstance(pkiProfile.getTrustStoreProfile(), tid); + Set certs = trustStore.getTrustedCertificates(tid); + return certs.toArray(new X509Certificate[certs.size()]); + } catch (TrustStoreException e) { + log.warn("Failed to get list of accepted issuers.", e); + return new X509Certificate[] {}; + } catch (ClassCastException e) { + log.error("Failed to cast list of accepted issuers.", e); + return new X509Certificate[] {}; + } + } + + private static iaik.x509.X509Certificate[] convertCerts( + X509Certificate[] certs) throws CertificateException { + iaik.x509.X509Certificate[] retVal = new iaik.x509.X509Certificate[certs.length]; + int i = 0; + for (X509Certificate cert : certs) { + if (cert instanceof iaik.x509.X509Certificate) { + retVal[i++] = (iaik.x509.X509Certificate) cert; + } else { + retVal[i++] = new iaik.x509.X509Certificate(cert.getEncoded()); + } + } + return retVal; + } + + private static class MDCTransactionId implements TransactionId { + @Override + public String getLogID() { + String sessionId = MDC.get("SessionId"); + return (sessionId != null) ? sessionId : "PKITrustManager"; + } + } +} -- cgit v1.2.3