Java tutorial
/* * Copyright 2006, Queensland University of Technology * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.qut.middleware.deployer.logic; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyPair; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.util.Calendar; import org.apache.commons.codec.binary.Hex; import org.apache.commons.dbcp.BasicDataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.dao.DataAccessException; import org.w3c.dom.Element; import com.qut.middleware.crypto.CryptoProcessor; import com.qut.middleware.crypto.exception.CryptoException; import com.qut.middleware.deployer.Constants; import com.qut.middleware.deployer.bean.ContactPersonBean; import com.qut.middleware.deployer.bean.DeploymentBean; import com.qut.middleware.deployer.exception.ESOEDAOException; import com.qut.middleware.deployer.exception.RegisterESOEException; import com.qut.middleware.deployer.exception.RenderConfigException; import com.qut.middleware.deployer.sqlmap.ESOEDAO; import com.qut.middleware.saml2.AttributeFormatConstants; import com.qut.middleware.saml2.BindingConstants; import com.qut.middleware.saml2.NameIDFormatConstants; import com.qut.middleware.saml2.ProtocolConstants; import com.qut.middleware.saml2.exception.MarshallerException; import com.qut.middleware.saml2.handler.Marshaller; import com.qut.middleware.saml2.handler.impl.MarshallerImpl; import com.qut.middleware.saml2.identifier.IdentifierGenerator; import com.qut.middleware.saml2.schemas.metadata.AttributeAuthorityDescriptor; import com.qut.middleware.saml2.schemas.metadata.EndpointType; import com.qut.middleware.saml2.schemas.metadata.Extensions; import com.qut.middleware.saml2.schemas.metadata.IDPSSODescriptor; import com.qut.middleware.saml2.schemas.metadata.IndexedEndpointType; import com.qut.middleware.saml2.schemas.metadata.SPSSODescriptor; import com.qut.middleware.saml2.schemas.metadata.extensions.CacheClearService; import com.qut.middleware.saml2.schemas.metadata.extensions.SPEPStartupService; import com.qut.middleware.saml2.schemas.metadata.lxacml.LXACMLPDPDescriptor; import com.qut.middleware.tools.war.logic.GenerateWarLogic; public class RegisterESOELogic { GenerateWarLogic generateWarLogic; RenderESOEConfigLogic renderESOEConfigLogic; private CryptoProcessor cryptoProcessor; private IdentifierGenerator identifierGenerator; private BasicDataSource dataSource; private ESOEDAO esoeDAO; private byte[] defaultPolicyData; private byte[] defaultManagementPolicyData; private byte[] defaultAttributePolicyData; private String defaultPolicyID; private String defaultManagementPolicyID; private Marshaller<IDPSSODescriptor> idpMarshaller; private Marshaller<SPEPStartupService> spsMarshaller; private Marshaller<AttributeAuthorityDescriptor> aaMarshaller; private Marshaller<LXACMLPDPDescriptor> pdpMarshaller; private Marshaller<SPSSODescriptor> spMarshaller; private Marshaller<CacheClearService> cacheClearMarshaller; private final String[] idpSchemas = { Constants.samlMetadata }; private final String[] spsSchemas = { Constants.spepStartup }; private final String[] aaSchemas = { Constants.samlMetadata }; private final String[] pdpSchemas = { Constants.lxacmlMetadata }; private final String[] spSchemas = { Constants.samlMetadata, Constants.lxacmlMetadata, Constants.cacheClearService }; private final String[] ccSchemas = { Constants.cacheClearService }; private final String MAR_PKGNAMES = SPSSODescriptor.class.getPackage().getName() + Constants.SCHEMA_SEPERATOR + LXACMLPDPDescriptor.class.getPackage().getName() + Constants.SCHEMA_SEPERATOR + CacheClearService.class.getPackage().getName(); /* Local logging instance */ private Logger logger = LoggerFactory.getLogger(RegisterESOELogic.class.getName()); public RegisterESOELogic(GenerateWarLogic generateWarLogic, RenderESOEConfigLogic renderESOEConfigLogic, IdentifierGenerator identifierGenerator, ESOEDAO esoeDAO, BasicDataSource dataSource, File policyFile, File managementPolicyFile, File attributePolicyFile) throws MarshallerException, IOException { this.generateWarLogic = generateWarLogic; this.renderESOEConfigLogic = renderESOEConfigLogic; this.identifierGenerator = identifierGenerator; this.esoeDAO = esoeDAO; this.dataSource = dataSource; this.cryptoProcessor = new CryptoProcessorESOEImpl(); this.loadDefaultPolicy(policyFile); this.loadDefaultManagementPolicy(managementPolicyFile); this.loadDefaultAttributePolicy(attributePolicyFile); this.idpMarshaller = new MarshallerImpl<IDPSSODescriptor>(IDPSSODescriptor.class.getPackage().getName(), this.idpSchemas); this.spsMarshaller = new MarshallerImpl<SPEPStartupService>(SPEPStartupService.class.getPackage().getName(), this.spsSchemas); this.aaMarshaller = new MarshallerImpl<AttributeAuthorityDescriptor>( AttributeAuthorityDescriptor.class.getPackage().getName(), this.aaSchemas); this.pdpMarshaller = new MarshallerImpl<LXACMLPDPDescriptor>( LXACMLPDPDescriptor.class.getPackage().getName(), this.pdpSchemas); this.spMarshaller = new MarshallerImpl<SPSSODescriptor>(this.MAR_PKGNAMES, this.spSchemas); this.cacheClearMarshaller = new MarshallerImpl<CacheClearService>( CacheClearService.class.getPackage().getName(), this.ccSchemas); } private void configureDataLayer(DeploymentBean bean) throws RegisterESOEException { switch (bean.getDatabaseDriver()) { case mysql: dataSource.setDriverClassName(Constants.MYSQL_DRIVER); break; case oracle: dataSource.setDriverClassName(Constants.ORACLE_DRIVER); break; /* Attempt to connect to mysql source if not submitted */ default: dataSource.setDriverClassName(Constants.MYSQL_DRIVER); } try { dataSource.setUrl(bean.getDatabaseURL()); dataSource.setUsername(bean.getDatabaseUsername()); dataSource.setPassword(bean.getDatabasePassword()); } catch (DataAccessException e) { this.logger.error("Unable to connect with database " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException(e.getLocalizedMessage(), e); } } public void execute(DeploymentBean bean) throws RegisterESOEException { configureDataLayer(bean); /* Setup Crypto Processor with additional details */ this.cryptoProcessor.setCertIssuerDN(bean.getCertIssuerDN()); this.cryptoProcessor.setCertIssuerEmail(bean.getCertIssuerEmailAddress()); try { //Ensure ESOE EntID gets set first (ie to 1) bean.setEsoeEntID(this.esoeDAO.getNextEntID()); /* Create all crypto */ createKeyStores(bean); /* Create XML descriptors for ESOE and ESOE Manager webapp */ createESOEDescriptors(bean); createESOEManagerDescriptors(bean); /* Set expiry date of PKI data */ Calendar expiryDate = Calendar.getInstance(); expiryDate.add(Calendar.YEAR, this.cryptoProcessor.getCertExpiryIntervalInYears()); /* Store all crypto in data repository */ /* ESOE */ this.esoeDAO.insertPKIData(bean.getEsoeIdpDescID(), expiryDate.getTime(), bean.getEsoeKeystore(), bean.getEsoeKeyStorePassphrase(), bean.getEsoeKeyPairName(), bean.getEsoeKeyPairPassphrase()); this.esoeDAO.insertPKIData(bean.getEsoeAADescID(), expiryDate.getTime(), bean.getEsoeKeystore(), bean.getEsoeKeyStorePassphrase(), bean.getEsoeKeyPairName(), bean.getEsoeKeyPairPassphrase()); this.esoeDAO.insertPKIData(bean.getEsoeLxacmlDescID(), expiryDate.getTime(), bean.getEsoeKeystore(), bean.getEsoeKeyStorePassphrase(), bean.getEsoeKeyPairName(), bean.getEsoeKeyPairPassphrase()); this.esoeDAO.insertPublicKey(bean.getEsoeIdpDescID(), expiryDate.getTime(), bean.getEsoeKeyPairName(), this.cryptoProcessor.convertPublicKeyByteArray(bean.getEsoeKeyPair().getPublic())); this.esoeDAO.insertPublicKey(bean.getEsoeAADescID(), expiryDate.getTime(), bean.getEsoeKeyPairName(), this.cryptoProcessor.convertPublicKeyByteArray(bean.getEsoeKeyPair().getPublic())); this.esoeDAO.insertPublicKey(bean.getEsoeLxacmlDescID(), expiryDate.getTime(), bean.getEsoeKeyPairName(), this.cryptoProcessor.convertPublicKeyByteArray(bean.getEsoeKeyPair().getPublic())); /* ESOE Manager SPEP */ this.esoeDAO.insertPKIData(bean.getManagerDescID(), expiryDate.getTime(), bean.getEsoeManagerKeystore(), bean.getEsoeManagerKeyStorePassphrase(), bean.getEsoeManagerKeyPairName(), bean.getEsoeManagerKeyPairPassphrase()); this.esoeDAO.insertPublicKey(bean.getManagerDescID(), expiryDate.getTime(), bean.getEsoeManagerKeyPairName(), this.cryptoProcessor.convertPublicKeyByteArray(bean.getEsoeManagerKeyPair().getPublic())); /* Authentication network Metadata crypto */ this.esoeDAO.insertMetadataPKIData(expiryDate.getTime(), bean.getEsoeMetadataKeystore(), bean.getEsoeMetadataKeyStorePassphrase(), bean.getEsoeMetadataKeyPairName(), bean.getEsoeMetadataKeyPairPassphrase()); /* * Dynamically create config files for user deployments so they dont need to do manual config, nice chaps * aren't we. */ writeESOEContent(bean); writeESOEManagerContent(bean); writeSPEPContent(bean); } catch (FileNotFoundException e) { this.logger.error( "FileNotFoundException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "FileNotFoundException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (KeyStoreException e) { this.logger.error( "KeyStoreException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "KeyStoreException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (NoSuchAlgorithmException e) { this.logger.error("NoSuchAlgorithmException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException("NoSuchAlgorithmException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (CertificateException e) { this.logger.error( "CertificateException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "CertificateException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (CryptoException e) { this.logger .error("CryptoException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "CryptoException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (IOException e) { this.logger.error("IOException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "IOException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (RenderConfigException e) { this.logger.error( "RenderConfigException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "RenderConfigException when attempting to configure ESOE details " + e.getLocalizedMessage()); } catch (ESOEDAOException e) { this.logger .error("ESOEDAOException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "ESOEDAOException when attempting to configure ESOE details " + e.getLocalizedMessage()); } } private void writeESOEContent(DeploymentBean bean) throws FileNotFoundException, RenderConfigException, IOException { FileOutputStream configOutput = null; FileOutputStream keystoreOutput = null; File configDir = new File(bean.getEsoeConfiguration() + Constants.CONFIG_DIR); if (!configDir.exists() && !configDir.mkdir()) throw new IOException("Unable to create config directory, structure not writeable"); File loggingDir = new File(bean.getEsoeConfiguration() + Constants.LOGGING_DIR); if (!loggingDir.exists() && !loggingDir.mkdir()) throw new IOException("Unable to create config directory, structure not writeable"); try { /* Write config file */ configOutput = new FileOutputStream( bean.getEsoeConfiguration() + Constants.CONFIG_DIR + File.separatorChar + Constants.ESOECONFIG); configOutput.write(this.renderESOEConfigLogic.renderESOEConfig(bean, 0).getBytes()); configOutput.flush(); /* Write ESOE keystore file */ keystoreOutput = new FileOutputStream(bean.getEsoeConfiguration() + Constants.CONFIG_DIR + File.separatorChar + Constants.ESOE_KEYSTORE_NAME); keystoreOutput.write(bean.getEsoeKeystore()); keystoreOutput.flush(); } finally { if (configOutput != null) configOutput.close(); if (keystoreOutput != null) keystoreOutput.close(); } } private void writeESOEManagerContent(DeploymentBean bean) throws FileNotFoundException, RenderConfigException, IOException { FileOutputStream configOutput = null; FileOutputStream keystoreOutput = null; File configDir = new File(bean.getEsoeManagerConfiguration() + Constants.CONFIG_DIR); if (!configDir.exists() && !configDir.mkdir()) throw new IOException("Unable to create config directory, structure not writeable"); File metadataHistoryDir = new File(bean.getEsoeManagerConfiguration() + Constants.MD_HISTORICAL_DIR); if ((!metadataHistoryDir.exists()) && (!metadataHistoryDir.mkdir())) { throw new IOException("Unable to create metadata history directory, structure not writeable for " + metadataHistoryDir.getPath()); } File loggingDir = new File(bean.getEsoeManagerConfiguration() + Constants.LOGGING_DIR); if (!loggingDir.exists() && !loggingDir.mkdir()) throw new IOException("Unable to create config directory, structure not writeable"); try { /* Write config file */ configOutput = new FileOutputStream(bean.getEsoeManagerConfiguration() + Constants.CONFIG_DIR + File.separatorChar + Constants.ESOEMANAGERCONFIG); configOutput.write(this.renderESOEConfigLogic.renderESOEManagerConfig(bean, 0).getBytes()); configOutput.flush(); /* Write Metadata Keystore */ keystoreOutput = new FileOutputStream(bean.getEsoeManagerConfiguration() + Constants.CONFIG_DIR + File.separatorChar + Constants.METADATA_KEYSTORE_NAME); keystoreOutput.write(bean.getEsoeMetadataKeystore()); keystoreOutput.flush(); } finally { if (configOutput != null) configOutput.close(); if (keystoreOutput != null) keystoreOutput.close(); } } private void writeSPEPContent(DeploymentBean bean) throws FileNotFoundException, RenderConfigException, IOException { FileOutputStream configOutput = null; FileOutputStream keystoreOutput = null; File configDir = new File(bean.getEsoeManagerSpepConfiguration() + Constants.CONFIG_DIR); if (!configDir.exists() && !configDir.mkdir()) throw new IOException("Unable to create config directory, structure not writeable"); File loggingDir = new File(bean.getEsoeManagerSpepConfiguration() + Constants.LOGGING_DIR); if (!loggingDir.exists() && !loggingDir.mkdir()) throw new IOException("Unable to create config directory, structure not writeable"); try { configOutput = new FileOutputStream(bean.getEsoeManagerSpepConfiguration() + Constants.CONFIG_DIR + File.separatorChar + Constants.ESOEMANAGERSPEPCONFIG); configOutput.write(this.renderESOEConfigLogic.renderESOEManagerSPEPConfig(bean, 1).getBytes()); configOutput.flush(); /* Write SPEP keystore file */ keystoreOutput = new FileOutputStream(bean.getEsoeManagerSpepConfiguration() + Constants.CONFIG_DIR + File.separatorChar + Constants.ESOE_MANAGER_SPEP_KEYSTORE_NAME); keystoreOutput.write(bean.getEsoeManagerKeystore()); keystoreOutput.flush(); } finally { if (configOutput != null) configOutput.close(); if (keystoreOutput != null) keystoreOutput.close(); } } private void createESOEDescriptors(DeploymentBean bean) throws RegisterESOEException { try { bean.setEsoeIdpDescID(this.esoeDAO.getNextDescID()); bean.setEsoeAADescID(this.esoeDAO.getNextDescID()); bean.setEsoeLxacmlDescID(this.esoeDAO.getNextDescID()); this.esoeDAO.insertEntityDescriptor(bean.getEsoeEntID(), bean.getEsoeEntityID(), bean.getEsoeOrganizationName(), bean.getEsoeOrganizationDisplayName(), bean.getEsoeOrganizationURL(), Constants.ENTITY_ACTIVE); } catch (ESOEDAOException e) { this.logger .error("ESOEDAOException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "ESOEDAOException when attempting to configure ESOE details " + e.getLocalizedMessage()); } setContacts(bean.getEsoeEntID(), bean); try { createIDPDescriptor(bean); createAtributeAuthorityDescriptor(bean); createLXACMLPDPDescriptor(bean); /* Setup attribute release for this ESOE Instance */ this.esoeDAO.insertAttributePolicy(bean.getEsoeEntID(), this.defaultAttributePolicyData); } catch (MarshallerException e) { this.logger.error("Marshaller exception when attempting to create ESOE xml descriptor " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException("Marshaller exception when attempting to create ESOE xml descriptor " + e.getLocalizedMessage()); } catch (ESOEDAOException e) { this.logger.error("ESOEDAOException when attempting to configure insert ESOE xml descriptor details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "ESOEDAOException when attempting to configure insert ESOE xml descriptor details " + e.getLocalizedMessage()); } } private void createESOEManagerDescriptors(DeploymentBean bean) throws RegisterESOEException { try { bean.setManagerEntID(this.esoeDAO.getNextEntID()); bean.setManagerDescID(this.esoeDAO.getNextDescID()); this.esoeDAO.insertEntityDescriptor(bean.getManagerEntID(), bean.getManagerEntityID(), bean.getEsoeOrganizationName(), bean.getEsoeOrganizationDisplayName(), bean.getEsoeOrganizationURL(), Constants.ENTITY_ACTIVE); this.esoeDAO.insertServiceDescription(bean.getManagerEntID(), bean.getManagerServiceName(), bean.getManagerServiceNode(), bean.getManagerServiceDescription(), bean.getManagerAccessDenied()); } catch (ESOEDAOException e) { this.logger .error("ESOEDAOException when attempting to configure ESOE details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "ESOEDAOException when attempting to configure ESOE details " + e.getLocalizedMessage()); } setContacts(bean.getManagerEntID(), bean); try { createSPDescriptor(bean); } catch (MarshallerException e) { this.logger.error("Marshaller exception when attempting to create ESOE Manager xml descriptor " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "Marshaller exception when attempting to create ESOE Manager xml descriptor " + e.getLocalizedMessage()); } catch (ESOEDAOException e) { this.logger.error( "ESOEDAOException when attempting to configure insert ESOE Manager xml descriptor details " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException( "ESOEDAOException when attempting to configure insert ESOE Manager xml descriptor details " + e.getLocalizedMessage()); } } private void setContacts(Integer entID, DeploymentBean bean) throws RegisterESOEException { ContactPersonBean contact = bean.getContact(); /* Register the service contact points */ this.logger.info("Adding contact person with name" + contact.getGivenName() + " " + contact.getSurname() + " and generated id of " + contact.getId()); try { this.esoeDAO.insertServiceContacts(entID, contact.getId(), contact.getContactType(), contact.getCompany(), contact.getGivenName(), contact.getSurname(), contact.getEmail(), contact.getTelephone()); } catch (ESOEDAOException e) { this.logger.error("ESOEDAOException when attempting to configure insert ESOE contacts " + e.getLocalizedMessage()); this.logger.debug(e.toString()); throw new RegisterESOEException("ESOEDAOException when attempting to configure insert ESOE contacts " + e.getLocalizedMessage()); } } private void createIDPDescriptor(DeploymentBean bean) throws MarshallerException, ESOEDAOException { IDPSSODescriptor idpDescriptor = new IDPSSODescriptor(); SPEPStartupService spepStartupService = new SPEPStartupService(); Element spepStartupServiceXML; byte[] idpDescriptorXML; /* Setup SPEP Startup Service */ spepStartupService.setBinding(BindingConstants.soap); spepStartupService.setLocation(bean.getEsoeNode() + bean.getEsoeSPEPStartupService()); spepStartupServiceXML = this.spsMarshaller.marshallUnSignedElement(spepStartupService); /* Setup IDP */ EndpointType singleSignOnEndpoint = new EndpointType(); singleSignOnEndpoint.setBinding(BindingConstants.httpPost); singleSignOnEndpoint.setLocation(bean.getEsoeNode() + bean.getEsoeSingleSignOn()); Extensions extenstions = new Extensions(); extenstions.getImplementedExtensions().add(spepStartupServiceXML); idpDescriptor.setID(this.identifierGenerator.generateSAMLID()); idpDescriptor.setWantAuthnRequestsSigned(true); idpDescriptor.getAttributeProfiles().add(AttributeFormatConstants.basic); idpDescriptor.getProtocolSupportEnumerations().add(ProtocolConstants.protocol); idpDescriptor.getSingleSignOnServices().add(singleSignOnEndpoint); idpDescriptor.setExtensions(extenstions); idpDescriptor.getNameIDFormats().add(NameIDFormatConstants.trans); idpDescriptorXML = this.idpMarshaller.marshallUnSigned(idpDescriptor); this.esoeDAO.insertDescriptor(bean.getEsoeEntID(), bean.getEsoeIdpDescID(), idpDescriptor.getID(), idpDescriptorXML, Constants.IDP_DESCRIPTOR); bean.setIdpDescriptorXML(idpDescriptorXML); } private void createSPDescriptor(DeploymentBean bean) throws MarshallerException, ESOEDAOException { /* * Determine how many SP records were submitted for ID generation for endpoints this will assimilate each SP * created into a single record per metadata design */ SPSSODescriptor spDescriptor = new SPSSODescriptor(); byte[] spDescriptorXML; spDescriptor.setID(this.identifierGenerator.generateSAMLID()); Integer nodeID = 1; /* Add the configured assertion consumer service - ACS is set to the service URL, this ensures load balanced services are handled correctly with the SAML POST profile * single node service should have identical service and node urls */ IndexedEndpointType assertionConsumerService = new IndexedEndpointType(); assertionConsumerService.setLocation(bean.getManagerServiceNode() + bean.getSpAssertionConsumerService()); assertionConsumerService.setBinding(BindingConstants.httpPost); assertionConsumerService.setIndex(nodeID.intValue()); spDescriptor.getAssertionConsumerServices().add(assertionConsumerService); /* Add the configured single logout service (non indexed) */ EndpointType singleLogoutService = new EndpointType(); singleLogoutService.setLocation(bean.getManagerServiceNode() + bean.getSpSingleLogoutService()); singleLogoutService.setBinding(BindingConstants.soap); spDescriptor.getSingleLogoutServices().add(singleLogoutService); /* Add the configured cache clear service (non indexed) */ CacheClearService cacheClearService = new CacheClearService(); cacheClearService.setLocation(bean.getManagerServiceNode() + bean.getSpCacheClearService()); cacheClearService.setBinding(BindingConstants.soap); cacheClearService.setIndex(nodeID.intValue()); Extensions extensions = spDescriptor.getExtensions(); if (extensions == null) { extensions = new Extensions(); } extensions.getImplementedExtensions() .add(this.cacheClearMarshaller.marshallUnSignedElement(cacheClearService)); spDescriptor.setExtensions(extensions); spDescriptor.setAuthnRequestsSigned(true); spDescriptor.setWantAssertionsSigned(true); spDescriptor.getProtocolSupportEnumerations().add(ProtocolConstants.protocol); spDescriptor.getNameIDFormats().add(NameIDFormatConstants.trans); spDescriptorXML = this.spMarshaller.marshallUnSigned(spDescriptor); this.esoeDAO.insertDescriptor(bean.getManagerEntID(), bean.getManagerDescID(), spDescriptor.getID(), spDescriptorXML, Constants.SP_DESCRIPTOR); /* Write service node to data repository */ this.esoeDAO.insertServiceNode(nodeID.toString(), bean.getManagerDescID(), bean.getManagerServiceNode(), bean.getSpAssertionConsumerService(), bean.getSpSingleLogoutService(), bean.getSpCacheClearService()); /* * Set default policy for ESOEManager, generally this will be an allow all until administrators correct using * ESOEManager, by default the policyID is 0 */ this.esoeDAO.insertServiceAuthorizationPolicy(bean.getManagerEntID(), this.defaultPolicyID, this.defaultPolicyData); this.esoeDAO.insertServiceAuthorizationPolicy(bean.getManagerEntID(), this.defaultManagementPolicyID, this.defaultManagementPolicyData); } private void createAtributeAuthorityDescriptor(DeploymentBean bean) throws MarshallerException, ESOEDAOException { AttributeAuthorityDescriptor aaDescriptor = new AttributeAuthorityDescriptor(); byte[] aaDescriptorXML; EndpointType attributeService = new EndpointType(); attributeService.setBinding(BindingConstants.soap); attributeService.setLocation(bean.getEsoeNode() + bean.getEsoeAttributeService()); aaDescriptor.setID(this.identifierGenerator.generateSAMLID()); aaDescriptor.getProtocolSupportEnumerations().add(ProtocolConstants.protocol); aaDescriptor.getAttributeServices().add(attributeService); aaDescriptorXML = this.aaMarshaller.marshallUnSigned(aaDescriptor); this.esoeDAO.insertDescriptor(bean.getEsoeEntID(), bean.getEsoeAADescID(), aaDescriptor.getID(), aaDescriptorXML, Constants.ATTRIBUTE_AUTHORITY_DESCRIPTOR); bean.setAaDescriptorXML(aaDescriptorXML); } private void createLXACMLPDPDescriptor(DeploymentBean bean) throws MarshallerException, ESOEDAOException { LXACMLPDPDescriptor pdpDescriptor = new LXACMLPDPDescriptor(); byte[] pdpDescriptorXML; EndpointType authzService = new EndpointType(); authzService.setBinding(BindingConstants.soap); authzService.setLocation(bean.getEsoeNode() + bean.getEsoeLxacmlService()); pdpDescriptor.setID(this.identifierGenerator.generateSAMLID()); pdpDescriptor.getProtocolSupportEnumerations().add(ProtocolConstants.protocol); pdpDescriptor.getAuthzServices().add(authzService); pdpDescriptorXML = this.pdpMarshaller.marshallUnSigned(pdpDescriptor); this.esoeDAO.insertDescriptor(bean.getEsoeEntID(), bean.getEsoeLxacmlDescID(), pdpDescriptor.getID(), pdpDescriptorXML, Constants.LXACML_PDP_DESCRIPTOR); bean.setPdpDescriptorXML(pdpDescriptorXML); } private void createKeyStores(DeploymentBean bean) throws CryptoException, CertificateException, FileNotFoundException, KeyStoreException, IOException, NoSuchAlgorithmException { KeyPair esoeKeyPair; String esoeKeyPairName; KeyPair esoeManagerKeyPair; String esoeManagerKeyPairName; /* * Create keystore for Authentication Network Metadata. This public key will be inserted in every keystore * created for an IDP, SP etc so that metadata documents may be validated. This will be stored as * metadataKeystore.ks and supplied to the ESOEManager webapp. */ KeyStore metadataKeyStore; KeyPair mdKeyPair; String mdKeyStorePassphrase = this.generatePassphrase(); String mdKeyPairName = this.identifierGenerator.generateXMLKeyName(); String mdKeyPairPassphrase = this.generatePassphrase(); bean.setEsoeMetadataKeyStorePassphrase(mdKeyStorePassphrase); bean.setEsoeMetadataKeyPairName(mdKeyPairName); bean.setEsoeMetadataKeyPairPassphrase(mdKeyPairPassphrase); metadataKeyStore = this.cryptoProcessor.generateKeyStore(); mdKeyPair = this.cryptoProcessor.generateKeyPair(); this.cryptoProcessor.addKeyPair(metadataKeyStore, mdKeyStorePassphrase, mdKeyPair, mdKeyPairName, mdKeyPairPassphrase, Constants.METADATA_ISSUER + this.generateSubjectDN(bean.getEsoeNode())); bean.setEsoeMetadataKeystore( this.cryptoProcessor.convertKeystoreByteArray(metadataKeyStore, mdKeyStorePassphrase)); /* * Create keystore for ESOE, the generated keypair is configured to be used by the IDP, AA, LXACML PDP and other * ESOE services to reduce the number of keys present in metadata */ KeyStore esoeKeyStore; String esoeKeyStorePassphrase = this.generatePassphrase(); esoeKeyPairName = this.identifierGenerator.generateXMLKeyName(); String esoeKeyPairPassphrase = this.generatePassphrase(); bean.setEsoeKeyStorePassphrase(esoeKeyStorePassphrase); bean.setEsoeKeyPairName(esoeKeyPairName); bean.setEsoeKeyPairPassphrase(esoeKeyPairPassphrase); esoeKeyStore = this.cryptoProcessor.generateKeyStore(); esoeKeyPair = this.cryptoProcessor.generateKeyPair(); bean.setEsoeKeyPair(esoeKeyPair); this.cryptoProcessor.addKeyPair(esoeKeyStore, esoeKeyStorePassphrase, esoeKeyPair, esoeKeyPairName, esoeKeyPairPassphrase, this.generateSubjectDN(bean.getEsoeNode())); this.cryptoProcessor.addPublicKey(esoeKeyStore, mdKeyPair, mdKeyPairName, Constants.METADATA_ISSUER + this.generateSubjectDN(bean.getEsoeNode())); bean.setEsoeKeystore(this.cryptoProcessor.convertKeystoreByteArray(esoeKeyStore, esoeKeyStorePassphrase)); /* * Create keystore for ESOE Manager SPEP */ KeyStore esoeManagerKeyStore; String esoeManagerKeyStorePassphrase = this.generatePassphrase(); esoeManagerKeyPairName = this.identifierGenerator.generateXMLKeyName(); String esoeManagerKeyPairPassphrase = this.generatePassphrase(); bean.setEsoeManagerKeyStorePassphrase(esoeManagerKeyStorePassphrase); bean.setEsoeManagerKeyPairName(esoeManagerKeyPairName); bean.setEsoeManagerKeyPairPassphrase(esoeManagerKeyPairPassphrase); esoeManagerKeyStore = this.cryptoProcessor.generateKeyStore(); esoeManagerKeyPair = this.cryptoProcessor.generateKeyPair(); bean.setEsoeManagerKeyPair(esoeManagerKeyPair); this.cryptoProcessor.addKeyPair(esoeManagerKeyStore, esoeManagerKeyStorePassphrase, esoeManagerKeyPair, esoeManagerKeyPairName, esoeManagerKeyPairPassphrase, this.generateSubjectDN(bean.getManagerServiceNode())); this.cryptoProcessor.addPublicKey(esoeManagerKeyStore, mdKeyPair, mdKeyPairName, Constants.METADATA_ISSUER + this.generateSubjectDN(bean.getEsoeNode())); bean.setEsoeManagerKeystore( this.cryptoProcessor.convertKeystoreByteArray(esoeManagerKeyStore, esoeManagerKeyStorePassphrase)); } /* * Takes the service URL from the supplied bean and creates a subject DN */ private String generateSubjectDN(String dn) { try { String result = new String(); URL serviceURL = new URL(dn); String[] components = serviceURL.getHost().split("\\."); for (String component : components) { if (result.length() != 0) result = result + ","; result = result + "dc=" + component; } return result; } catch (MalformedURLException e) { this.logger.error("Error attempting to generate certificate subjectDN " + e.getLocalizedMessage()); this.logger.debug(e.toString()); return "dc=" + dn; } } /* * Generates a 10 byte passphrase for use with an SPEP @return populated passphrase */ private String generatePassphrase() { SecureRandom random; String passphrase; byte[] buf; try { /* Attempt to get the specified RNG instance */ random = SecureRandom.getInstance("SHA1PRNG"); } catch (NoSuchAlgorithmException nsae) { this.logger.error("NoSuchAlgorithmException when trying to create SecureRandom instance " //$NON-NLS-1$ + nsae.getLocalizedMessage()); this.logger.debug(nsae.getLocalizedMessage(), nsae); random = new SecureRandom(); } buf = new byte[Constants.PASSPHRASE_LENGTH]; random.nextBytes(buf); passphrase = new String(Hex.encodeHex(buf)); return passphrase; } private void loadDefaultPolicy(File policyFile) throws IOException { InputStream fileStream = null; try { long length = policyFile.length(); byte[] byteArray = new byte[(int) length]; fileStream = new FileInputStream(policyFile); fileStream.read(byteArray); fileStream.close(); /* * The default policy is assigned ID 0 on disk, should this need to change for some reason the below * assignment must be modified. */ this.defaultPolicyData = byteArray; this.defaultPolicyID = "spep-0"; } finally { if (fileStream != null) fileStream.close(); } } private void loadDefaultAttributePolicy(File attribPolicyFile) throws IOException { InputStream fileStream = null; try { long length = attribPolicyFile.length(); byte[] byteArray = new byte[(int) length]; fileStream = new FileInputStream(attribPolicyFile); fileStream.read(byteArray); fileStream.close(); this.defaultAttributePolicyData = byteArray; } finally { if (fileStream != null) fileStream.close(); } } private void loadDefaultManagementPolicy(File policyFile) throws IOException { InputStream fileStream = null; try { long length = policyFile.length(); byte[] byteArray = new byte[(int) length]; fileStream = new FileInputStream(policyFile); fileStream.read(byteArray); fileStream.close(); /* * The default policy is assigned ID 0 on disk, should this need to change for some reason the below * assignment must be modified. */ this.defaultManagementPolicyData = byteArray; this.defaultManagementPolicyID = "manager-0"; } finally { if (fileStream != null) fileStream.close(); } } }