/* * Copyright 2003 Federal Chancellery Austria * MOA-SPSS 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.spss.server.iaik.config; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.LoggerFactory; import at.gv.egovernment.moa.spss.server.config.ConfigurationException; import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider; import at.gv.egovernment.moa.spss.server.config.KeyGroup; import at.gv.egovernment.moa.spss.server.config.KeyGroupEntry; import at.gv.egovernment.moa.spss.server.logging.TransactionId; import at.gv.egovernment.moa.spss.util.CertStoreConverter; import at.gv.egovernment.moa.spss.util.MessageProvider; import at.gv.egovernment.moa.spss.util.SecProviderUtils; import at.gv.egovernment.moaspss.logging.LogMsg; import at.gv.egovernment.moaspss.logging.Logger; import iaik.logging.LogFactory; import iaik.pki.PKIException; import iaik.pki.PKIFactory; import iaik.pki.store.revocation.RevocationFactory; import iaik.pki.store.revocation.RevocationSourceStore; import iaik.pki.store.truststore.TrustStoreFactory; import iaik.server.ConfigurationData; import iaik.server.Configurator; import iaik.server.modules.keys.KeyEntryID; import iaik.server.modules.keys.KeyModule; import iaik.server.modules.keys.KeyModuleFactory; import iaik.servertools.PublicAuthorityIdentifier; import iaik.x509.X509Extensions; /** * A class responsible for configuring the IAIK MOA modules. * * @author Patrick Peck * @version $Id$ */ public class IaikConfigurator extends Configurator { private static final org.slf4j.Logger logger = LoggerFactory.getLogger(IaikConfigurator.class); /** The warnings encountered during configuration. */ private static List warnings = new ArrayList<>(); /** * Configure the IAIK MOA subsystem. * * * @param moaConfig The underlying MOA configuration. * @return Returns the config data of the underlying MOA subsystem * @throws ConfigurationException An error occurred configuring the IAIK MOA * subsystem. */ public static ConfigurationData configure(ConfigurationProvider moaConfig) throws ConfigurationException { final ConfigurationData configData = new ConfigurationDataImpl(moaConfig); try { final TransactionId transId = new TransactionId("IaikConfigurator"); // iaik.esi.sva.Configuration config = new // Configuration(IaikConfigurator.class.getResourceAsStream("/sva.config")); // SecProviderUtils.dumpSecProviders("Starting configuration"); LogFactory.configure(configData.getLoggerConfig()); // initialize PKI commons initializePkiCommons(moaConfig, transId, configData); // initialze IAIK MOA customIaikInit(configData, transId); SecProviderUtils.dumpSecProviders("Fully configured!"); // Set customized CRL retriever to overcome a classloader problem when MOA is // deployed in Tomcat final RevocationSourceStore rss = RevocationFactory.getInstance(transId).getRevocationSourceStore(); // rss.setRetriever(new CRLRetriever(), RevocationSourceTypes.CRL); if (moaConfig.getSoftwareKeyModules().size() > 0 || moaConfig.getHardwareKeyModules().size() > 0) { dumpKeyEntryIDs(); } checkKeyGroupConfig(moaConfig); TrustStoreFactory.reset(); return configData; } catch (final iaik.server.ConfigurationException e) { logException(e); throw new ConfigurationException("config.08", null, e); } catch (final Throwable t) { logException(t); throw new ConfigurationException("config.08", null, t); } } public static void customIaikInit(ConfigurationData config, TransactionId transactionId) throws ConfigurationException, iaik.server.ConfigurationException { if (config == null) { throw new NullPointerException("Config data must not be null"); } else { initXSect(LogFactory.getLog("init-xsect"), transactionId); X509Extensions.register(PublicAuthorityIdentifier.oid, PublicAuthorityIdentifier.class); // initialize PKI module only if it is not done yet if (!PKIFactory.getInstance().isAlreadyConfigured()) { initPkiModule(config.getPKIConfiguration(), transactionId); } else { logger.trace("IAIK PKI-module is still configurated"); } initCryptoModule(config.getCryptoModuleConfigurations(), transactionId); initKeyModule(config.getKeyModuleConfigurations(), transactionId); } } private static void initializePkiCommons(ConfigurationProvider moaConfig, TransactionId transId, ConfigurationData configData) throws PKIException { if (!iaik.pki.Configurator.isInitialized()) { logger.info("Initializing IAIK PKI-Commons ... "); try { iaik.pki.Configurator.initCommon(configData.getLoggerConfig(), transId); final String certStoreRoot = moaConfig.getCertStoreLocation(); CertStoreConverter.convert(certStoreRoot, transId); } finally { // Security.removeProvider(ECCelerate.getInstance().getName()); } } else { logger.debug("IAIK PKI-Commons already initialized"); } } private static void logException(Throwable e) { final StringWriter out = new StringWriter(); final PrintWriter writer = new PrintWriter(out); e.printStackTrace(writer); logger.error("IAIK_Module error: {}", out.toString()); } /** * Return the warnings encountered during configuration. * * @return The warnings. */ public List getWarnings() { return warnings; } /** * Dump all KeyEntryIDs contained in the configured * KeyModules to the log file. */ private static void dumpKeyEntryIDs() { final MessageProvider msg = MessageProvider.getInstance(); final KeyModule module = KeyModuleFactory.getInstance(new TransactionId("dump")); final Set keyEntryIds = module.getPrivateKeyEntryIDs(); Iterator iter; for (iter = keyEntryIds.iterator(); iter.hasNext();) { final KeyEntryID keyEntryId = (KeyEntryID) iter.next(); Logger.info( new LogMsg(msg.getMessage("config.19", new Object[] { keyEntryId }))); } } /** * Check that each key group entry in each key group can be resolved to a * KeyEntryID. * * Logs a warning for each key group entry that cannot be resolved. * * @param moaConfig The MOA configuration to check. */ private static void checkKeyGroupConfig(ConfigurationProvider moaConfig) { final Map keyGroups = moaConfig.getKeyGroups(); Iterator iter; for (iter = keyGroups.values().iterator(); iter.hasNext();) { final KeyGroup keyGroup = (KeyGroup) iter.next(); final Set keyGroupEntries = keyGroup.getKeyGroupEntries(); Iterator kgIter; for (kgIter = keyGroupEntries.iterator(); kgIter.hasNext();) { final KeyGroupEntry entry = (KeyGroupEntry) kgIter.next(); if (!findKeyEntryID(entry)) { warn( "config.31", new Object[] { keyGroup.getId(), entry.getModuleID(), entry.getIssuerDN(), entry.getSerialNumber() }); } } } } /** * Find out that a certain KeyGroupEntry could be resolved to a KeyEntryID by * the Configurator. * * @param keyGroupEntry The key group entry to find. * @return true, if the keyGroupEntry could be * resolved to a KeyEntryID; otherwise false. */ private static boolean findKeyEntryID(KeyGroupEntry keyGroupEntry) { final KeyModule module = KeyModuleFactory.getInstance(new TransactionId("check")); final Set keyEntryIDs = module.getPrivateKeyEntryIDs(); Iterator iter; for (iter = keyEntryIDs.iterator(); iter.hasNext();) { final KeyEntryID entry = (KeyEntryID) iter.next(); if (entry.getCertificateIssuer().equals(keyGroupEntry.getIssuerDN()) && entry.getCertificateSerialNumber().equals( keyGroupEntry.getSerialNumber()) && entry.getModuleID().equals(keyGroupEntry.getModuleID())) { return true; } } return false; } /** * Log a warning. * * @param messageId The message ID. * @param args Additional parameters for the message. * @see at.gv.egovernment.moa.spss.server.util.MessageProvider */ private static void warn(String messageId, Object[] args) { final MessageProvider msg = MessageProvider.getInstance(); final String txt = msg.getMessage(messageId, args); Logger.warn(new LogMsg(txt)); warnings.add(txt); } }