/******************************************************************************* * Copyright 2014 Federal Chancellery Austria * MOA-ID has been developed in a cooperation between BRZ, the Federal * Chancellery Austria - ICT staff unit, 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.egovernment.moa.id.configuration.validation.oa; import iaik.x509.X509Certificate; import java.io.IOException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.List; import java.util.Timer; import javax.net.ssl.SSLHandshakeException; import javax.servlet.http.HttpServletRequest; import org.apache.commons.httpclient.MOAHttpClient; import org.apache.log4j.Logger; import org.opensaml.Configuration; import org.opensaml.common.xml.SAMLSchemaBuilder; import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider; import org.opensaml.saml2.metadata.provider.MetadataFilter; import org.opensaml.saml2.metadata.provider.MetadataFilterChain; import org.opensaml.saml2.metadata.provider.MetadataProviderException; import org.opensaml.xml.io.Marshaller; import org.opensaml.xml.io.MarshallerFactory; import org.opensaml.xml.io.Unmarshaller; import org.opensaml.xml.io.UnmarshallerFactory; import org.opensaml.xml.parse.BasicParserPool; import org.opensaml.xml.security.x509.BasicX509Credential; import at.gv.egovernment.moa.id.commons.db.ConfigurationDBRead; import at.gv.egovernment.moa.id.commons.db.ConfigurationDBUtils; import at.gv.egovernment.moa.id.commons.db.dao.config.ChainingModeType; import at.gv.egovernment.moa.id.commons.db.dao.config.OnlineApplication; import at.gv.egovernment.moa.id.commons.ex.MOAHttpProtocolSocketFactoryException; import at.gv.egovernment.moa.id.commons.utils.MOAHttpProtocolSocketFactory; import at.gv.egovernment.moa.id.commons.validation.ValidationHelper; import at.gv.egovernment.moa.id.configuration.auth.pvp2.MetaDataVerificationFilter; import at.gv.egovernment.moa.id.configuration.config.ConfigurationProvider; import at.gv.egovernment.moa.id.configuration.data.oa.OAPVP2Config; import at.gv.egovernment.moa.id.configuration.exception.ConfigurationException; import at.gv.egovernment.moa.id.configuration.helper.LanguageHelper; import at.gv.egovernment.moa.id.protocols.pvp2x.verification.metadata.SchemaValidationFilter; import at.gv.egovernment.moa.util.MiscUtil; public class OAPVP2ConfigValidation { private static final Logger log = Logger.getLogger(OAPVP2ConfigValidation.class); public List validate(OAPVP2Config form, String oaID, HttpServletRequest request) { Timer timer = null; MOAHttpClient httpClient = null; HTTPMetadataProvider httpProvider = null; List errors = new ArrayList(); try { byte[] certSerialized = null; if (form.getFileUpload() != null) certSerialized = form.getCertificate(); else { OnlineApplication oa = ConfigurationDBRead.getOnlineApplication(oaID); if (oa != null && oa.getAuthComponentOA() != null && oa.getAuthComponentOA().getOAPVP2() != null) { certSerialized = oa.getAuthComponentOA().getOAPVP2().getCertificate(); } } String check = form.getMetaDataURL(); if (MiscUtil.isNotEmpty(check)) { if (!ValidationHelper.validateURL(check)) { log.info("MetaDataURL has no valid form."); errors.add(LanguageHelper.getErrorString("validation.pvp2.metadataurl.valid", request)); } else { if (certSerialized == null) { log.info("No certificate for metadata validation"); errors.add(LanguageHelper.getErrorString("validation.pvp2.certificate.notfound", request)); } else { X509Certificate cert = new X509Certificate(certSerialized); BasicX509Credential credential = new BasicX509Credential(); credential.setEntityCertificate(cert); timer = new Timer(); httpClient = new MOAHttpClient(); if (form.getMetaDataURL().startsWith("https:")) try { MOAHttpProtocolSocketFactory protoSocketFactory = new MOAHttpProtocolSocketFactory( "MOAMetaDataProvider", ConfigurationProvider.getInstance().getCertStoreDirectory(), ConfigurationProvider.getInstance().getTrustStoreDirectory(), null, ChainingModeType.PKIX, true); httpClient.setCustomSSLTrustStore( form.getMetaDataURL(), protoSocketFactory); } catch (MOAHttpProtocolSocketFactoryException e) { log.warn("MOA SSL-TrustStore can not initialized. Use default Java TrustStore.", e); } catch (ConfigurationException e) { log.info("No MOA specific SSL-TrustStore configured. Use default Java TrustStore.", e); } List filterList = new ArrayList(); filterList.add(new MetaDataVerificationFilter(credential)); filterList.add(new SchemaValidationFilter()); MetadataFilterChain filter = new MetadataFilterChain(); filter.setFilters(filterList); httpProvider = new HTTPMetadataProvider(timer, httpClient, form.getMetaDataURL()); httpProvider.setParserPool(new BasicParserPool()); httpProvider.setRequireValidMetadata(true); httpProvider.setMetadataFilter(filter); httpProvider.setMinRefreshDelay(1000*60*15); //15 minutes httpProvider.setMaxRefreshDelay(1000*60*60*24); //24 hours httpProvider.setRequireValidMetadata(true); httpProvider.initialize(); if (httpProvider.getMetadata() == null) { log.info("Metadata could be received but validation FAILED."); errors.add(LanguageHelper.getErrorString("validation.pvp2.metadata.validation", request)); } } } } } catch (CertificateException e) { log.info("Uploaded Certificate can not be found", e); errors.add(LanguageHelper.getErrorString("validation.pvp2.certificate.notfound", request)); } catch (IOException e) { log.info("Metadata can not be loaded from URL", e); errors.add(LanguageHelper.getErrorString("validation.pvp2.metadataurl.read", request)); } catch (MetadataProviderException e) { if (e.getCause() != null && e.getCause().getCause() instanceof SSLHandshakeException) { log.info("SSL Server certificate not trusted.", e); errors.add(LanguageHelper.getErrorString("validation.pvp2.metadata.ssl", request)); } else { log.info("MetaDate verification failed", e); errors.add(LanguageHelper.getErrorString("validation.pvp2.metadata.verify", request)); } } finally { if (httpProvider != null) httpProvider.destroy(); if (timer != null) timer.cancel(); } return errors; } }