package at.gv.egovernment.moa.spss.server.config; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.math.BigInteger; import java.net.URL; import java.security.Principal; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; import org.w3c.dom.Element; import iaik.asn1.structures.Name; import iaik.utils.RFC2253NameParser; import iaik.utils.RFC2253NameParserException; import at.gv.egovernment.moa.logging.LogMsg; import at.gv.egovernment.moa.logging.Logger; import at.gv.egovernment.moa.util.DOMUtils; import at.gv.egovernment.moa.spss.util.MessageProvider; /** * A class providing access to the MOA configuration data. * *
Configuration data is read from an XML file, whose location is given by
* the moa.spss.server.configuration
system property.
This class implements the Singleton pattern. The reload()
* method can be used to update the configuration data. Therefore, it is not
* guaranteed that consecutive calls to getInstance()
will return
* the same ConfigurationProvider
all the time. During the
* processing of a web service request, the current
* TransactionContext
should be used to obtain the
* ConfigurationProvider
local to that request.
IssuerAndSerial
object for storing KeyGroup information
* accessible by all clients.
*/
private static final IssuerAndSerial ANONYMOUS_ISSUER_SERIAL =
new IssuerAndSerial(new Name(), new BigInteger("0"));
/** Singleton instance. null
, if none has been created. */
private static ConfigurationProvider instance;
//
// configuration data
//
/** The warnings generated when building the configuration. */
private List warnings = new ArrayList();
/** The default digest method algorithm name */
private String digestMethodAlgorithmName;
/** The default canonicalization algorithm name */
private String canonicalizationAlgorithmName;
/**
* A Map
which contains generic configuration information. Maps a
* configuration name (a String
) to a configuration value (also a
* String
).
*/
private Map genericConfiguration;
/**
* A List
of HardwareCryptoModule
objects for
* configuring hardware modules.
*/
private List hardwareCryptoModules;
/**
* A List
of HardwareKey
objects containing the
* configuration data for hardware keys.
*/
private List hardwareKeyModules;
/**
* A List
of SoftwareKey
objects containing the
* configuration data for software keys.
*/
private List softwareKeyModules;
/**
* A Map
which contains a KeyGroupId (a String
) to
* KeyGroup mapping.
*/
private Map keyGroups;
/**
* A Map
which contains the IssuerAndSerial
to
* KeyGroup
mapping.
*/
private Map keyGroupMappings;
/** The default chaining mode. */
private String defaultChainingMode;
/**
* A Map
which contains the IssuerAndSerial
to
* chaining mode (a String
) mapping.
*/
private Map chainingModes;
/**
* A Map
which contains the CAIssuerDN (a String
)
* to distribution points (a Set
of
* DistributionPoint
s) mapping.
*/
private Map crlDistributionPoints;
/** The CRL archive duration. */
private int cRLArchiveDuration;
/**
* A Map
which contains a mapping from
* CreateSignatureEnvironmentProfile Ids (String
) to
* CreateSignatureEnvironmentProfile elements (an Element
).
*/
private Map createSignatureEnvironmentProfiles;
/**
* A Map
which contains a mapping from
* CreateTransformsInfoProfile Ids (String
) to
* CreateTransformsInfoProfile elements (an Element
).
*/
private Map createTransformsInfoProfiles;
/**
* A Map
which contains a mapping from
* VerifyTransformsInfoProfile Ids (String
) to
* VerifyTransformsInfoProfile elements (an Element
).
*/
private Map verifyTransformsInfoProfiles;
/**
* A Map
which contains a mapping from
* SupplementProfile Ids (String
) to SupplementProfile elements
* (an Element
).
*/
private Map supplementProfiles;
/**
* A Map
which contains a TrustProfile Id (a String
* to trust profile (a TrustProfile
) mapping.
*/
private Map trustProfiles;
/**
* Return the single instance of configuration data.
*
* @return MOAConfigurationProvider The current configuration data.
* @throws ConfigurationException Failure to load the configuration data.
*/
public static synchronized ConfigurationProvider getInstance()
throws ConfigurationException {
if (instance == null) {
reload();
}
return instance;
}
/**
* Reload the configuration data and set it if successful.
*
* @return MOAConfigurationProvider The loaded configuration data.
* @throws ConfigurationException Failure to load the configuration data.
*/
public static synchronized ConfigurationProvider reload()
throws ConfigurationException {
String fileName = System.getProperty(CONFIG_PROPERTY_NAME);
if (fileName == null) {
// find out where we are running and use the configuration provided
// under WEB-INF/conf/moa-spss/MOA-SPSSConfiguration
URL url = ConfigurationProvider.class.getResource("/");
fileName =
new File(url.getPath()).getParent()
+ "/conf/moa-spss/MOA-SPSSConfiguration.xml";
info("config.05", new Object[] { CONFIG_PROPERTY_NAME });
}
instance = new ConfigurationProvider(fileName);
return instance;
}
/**
* Constructor for ConfigurationProvider.
*
* @param fileName The name of the configuration file.
* @throws ConfigurationException An error occurred loading the configuration.
*/
public ConfigurationProvider(String fileName) throws ConfigurationException {
load(fileName);
}
/**
* Load the configuration data from XML file with the given name and build
* the internal data structures representing the MOA configuration.
*
* @param fileName The name of the XML file to load.
* @throws ConfigurationException The MOA configuration could not be
* read/built.
*/
private void load(String fileName) throws ConfigurationException {
FileInputStream stream = null;
File configFile;
File configRoot;
Element configElem;
ConfigurationPartsBuilder builder;
List allKeyModules;
// load the main config file
try {
configFile = new File(fileName);
configRoot = new File(configFile.getParent());
info("config.21", new Object[] { configFile.getAbsoluteFile()});
stream = new FileInputStream(fileName);
configElem = DOMUtils.parseXmlValidating(new FileInputStream(fileName));
} catch (Throwable t) {
throw new ConfigurationException("config.10", null, t);
}
// build the internal datastructures
try {
builder = new ConfigurationPartsBuilder(configElem);
digestMethodAlgorithmName = builder.getDigestMethodAlgorithmName();
canonicalizationAlgorithmName =
builder.getCanonicalizationAlgorithmName();
hardwareCryptoModules = builder.buildHardwareCryptoModules();
hardwareKeyModules =
builder.buildHardwareKeyModules(Collections.EMPTY_LIST);
softwareKeyModules =
builder.buildSoftwareKeyModules(hardwareKeyModules, configRoot);
allKeyModules = new ArrayList(hardwareKeyModules);
allKeyModules.addAll(softwareKeyModules);
keyGroups = builder.buildKeyGroups(allKeyModules);
keyGroupMappings =
builder.buildKeyGroupMappings(keyGroups, ANONYMOUS_ISSUER_SERIAL);
defaultChainingMode = builder.getDefaultChainingMode();
chainingModes = builder.buildChainingModes();
crlDistributionPoints = builder.buildCRLDistributionPoints();
cRLArchiveDuration = builder.getCRLArchiveDuration();
genericConfiguration = builder.buildGenericConfiguration();
absolutizeCertStoreRoot(configRoot);
createTransformsInfoProfiles =
builder.buildCreateTransformsInfoProfiles(configRoot);
createSignatureEnvironmentProfiles =
builder.buildCreateSignatureEnvironmentProfiles(configRoot);
verifyTransformsInfoProfiles =
builder.buildVerifyTransformsInfoProfiles(configRoot);
supplementProfiles = builder.buildSupplementProfiles(configRoot);
trustProfiles = builder.buildTrustProfiles(configRoot);
warnings = new ArrayList(builder.getWarnings());
checkConsistency();
} catch (Throwable t) {
throw new ConfigurationException("config.11", null, t);
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
// don't complain about this
}
}
}
/**
* Returns the warnings encountered during building the configuration.
*
* @return A List
of String
s, containing the
* warning messages.
*/
public List getWarnings() {
return warnings;
}
/**
* Make the DIRECTORY_CERTSTORE_PARAMETER_PROPERTY
generic
* configuration value an absolute file name.
*
* @param configRoot The root directory of the main configuration file.
*/
private void absolutizeCertStoreRoot(File configRoot) {
String certStoreRoot =
getGenericConfiguration(DIRECTORY_CERTSTORE_PARAMETER_PROPERTY);
if (certStoreRoot != null) {
if (!new File(certStoreRoot).isAbsolute()) {
// make the cert store absolute
File absCertStore = new File(configRoot, certStoreRoot);
setGenericConfiguration(
DIRECTORY_CERTSTORE_PARAMETER_PROPERTY,
absCertStore.getAbsolutePath());
}
} else {
// no value given: set it to a reasonable (absolute) default
File absCertStore = new File(configRoot, "certstore");
setGenericConfiguration(
DIRECTORY_CERTSTORE_PARAMETER_PROPERTY,
absCertStore.getAbsolutePath());
}
}
/**
* Do some additional consistency checks on the configuration.
*/
private void checkConsistency() {
// check for valid DirectoryCertStoreParameters.RootDir
String certStoreRoot =
getGenericConfiguration(DIRECTORY_CERTSTORE_PARAMETER_PROPERTY);
if (certStoreRoot != null) {
File certStore = new File(certStoreRoot);
if (!certStore.exists() && !certStore.isDirectory()) {
boolean created = false;
try {
created = certStore.mkdirs();
} finally {
if (!created) {
warn(
"config.30",
new Object[] { DIRECTORY_CERTSTORE_PARAMETER_PROPERTY });
}
}
}
}
}
/**
* Return the name of the digest algorithm used during signature creation.
*
* @return The digest method algorithm name, or an empty String
,
* if none has been configured.
*/
public String getDigestMethodAlgorithmName() {
return digestMethodAlgorithmName;
}
/**
* Return the name of the canonicalization algorithm used during signature
* creation.
*
* @return The canonicalization algorithm name, or an empty
* String
if none has been configured.
*/
public String getCanonicalizationAlgorithmName() {
return canonicalizationAlgorithmName;
}
/**
* Return the configured hardware crypto modules.
*
* @return A List
of HardwareCryptoModule
objects
* containing the hardware crypto module configurations.
*/
public List getHardwareCryptoModules() {
return hardwareCryptoModules;
}
/**
* Return the hardware key modules configuration.
*
* @return A List
of HardwareKeyModule
objects
* containing the configuration of the hardware key modules.
*/
public List getHardwareKeyModules() {
return hardwareKeyModules;
}
/**
* Return the software key module configuration.
*
* @return A List
of SoftwareKeyModule
objects
* containing the configuration of the software key modules.
*/
public List getSoftwareKeyModules() {
return softwareKeyModules;
}
/**
* Return the key group mapping.
*
* @return A mapping from key group ID (a String
) to
* KeyGroup
mapping.
*/
public Map getKeyGroups() {
return keyGroups;
}
/**
* Return the set of KeyGroupEntry
s of a given key group, which a
* client (identified by an issuer/serial pair) may access.
*
* @param issuer The issuer of the client certificate.
* @param serial The serial number of the client certificate.
* @param keyGroupId The ID of the key group.
* @return A Set
of all the KeyGroupEntry
s in the
* given key group, if the user may access them. Returns null
, if
* the user may not access the given key group or if the key group does not
* exist.
*/
public Set getKeyGroupEntries(
Principal issuer,
BigInteger serial,
String keyGroupId) {
IssuerAndSerial issuerAndSerial;
Map mapping;
if (issuer == null && serial == null) {
issuerAndSerial = ANONYMOUS_ISSUER_SERIAL;
} else {
issuerAndSerial = new IssuerAndSerial(issuer, serial);
}
mapping = (Map) keyGroupMappings.get(issuerAndSerial);
if (mapping != null) {
KeyGroup keyGroup = (KeyGroup) mapping.get(keyGroupId);
if (keyGroup != null) {
return keyGroup.getKeyGroupEntries();
}
}
return null;
}
/**
* Return the chaining mode for a given trust anchor.
*
* @param trustAnchor The trust anchor for which the chaining mode should be
* returned.
* @return The chaining mode for the given trust anchor. If the trust anchor
* has not been configured separately, the system default will be returned.
*/
public String getChainingMode(X509Certificate trustAnchor) {
Principal issuer = trustAnchor.getIssuerDN();
BigInteger serial = trustAnchor.getSerialNumber();
IssuerAndSerial issuerAndSerial = new IssuerAndSerial(issuer, serial);
String mode = (String) chainingModes.get(issuerAndSerial);
return mode != null ? mode : defaultChainingMode;
}
/**
* Return the CRL distribution points for a given CA.
*
* @param cert The certificate for which the CRL distribution points should be
* looked up. The issuer information is used to perform the lookup.
* @return A Set
of DistributionPoint
objects. The
* set will be empty, if no distribution points have been configured for this
* certificate.
*/
public Set getCRLDP(X509Certificate cert) {
try {
RFC2253NameParser nameParser =
new RFC2253NameParser(cert.getIssuerDN().toString());
String caIssuerDN = nameParser.parse().getName();
Set dps = (Set) crlDistributionPoints.get(caIssuerDN);
if (dps == null) {
return Collections.EMPTY_SET;
}
return dps;
} catch (RFC2253NameParserException e) {
return Collections.EMPTY_SET;
}
}
/**
* Return the CRL archive duration.
*
* @return The duration of how long to keep CRL archive entries (measured in
* days).
*/
public int getCRLArchiveDuration() {
return cRLArchiveDuration;
}
/**
* Sets a generic configuration value.
*
* Existing values are overridden.
*
* @param name The name of the generic configuration.
* @param value The new value of the generic configuration.
*/
private void setGenericConfiguration(String name, String value) {
genericConfiguration.put(name, value);
}
/**
* Return the value of a generic configuration.
*
* @param name The name of the generic configuration.
* @return The value of the generic configuration with the given name, or
* null
, if none can be found.
*/
public String getGenericConfiguration(String name) {
return (String) genericConfiguration.get(name);
}
/**
* Return the value of a generic configuration, or a given default value.
*
* @param name The name of the generic configuration.
* @param defaultValue A default value to be returned in case that the generic
* configuration with the given name does not exist.
* @return The value of the generic configuration with the given name, or the
* defaultValue
, if none can be found.
*/
public String getGenericConfiguration(String name, String defaultValue) {
String value = (String) genericConfiguration.get(name);
return value != null ? value : defaultValue;
}
/**
* Return a CreateTransformsInfoProfile
with the given ID.
*
* @param id The CreateTransformsInfoProfile
ID.
* @return The CreateTransformsInfoProfile
with the given
* ID or null
, if none exists.
*/
public Element getCreateTransformsInfoProfile(String id) {
return (Element) createTransformsInfoProfiles.get(id);
}
/**
* Return a CreateSignatureEnvironmentProfile
with the given ID.
*
* @param id The CreateSignatureEnvironmentProfile
ID.
* @return The CreateSignatureEnvironmentProfile
with the given
* ID or null
, if none exists.
*/
public Element getCreateSignatureEnvironmentProfile(String id) {
return (Element) createSignatureEnvironmentProfiles.get(id);
}
/**
* Return a VerifyTransformsInfoProfile
with the given ID.
*
* @param id The VerifyTransformsInfoProfile
ID.
* @return The VerifyTransformsInfoProfile
with the given ID or
* null
, if none exists.
*/
public Element getVerifyTransformsInfoProfile(String id) {
return (Element) verifyTransformsInfoProfiles.get(id);
}
/**
* Return a SupplementProfile
with the given ID.
*
* @param id The SupplementProfile
ID.
* @return The SupplementProfile
with the given ID or
* null
, if none exists.
*/
public Element getSupplementProfile(String id) {
return (Element) supplementProfiles.get(id);
}
/**
* Return a TrustProfile
with the given ID.
*
* @param id The TrustProfile
ID.
* @return The TrustProfile
with the given ID or
* null
, if none exists.
*/
public TrustProfile getTrustProfile(String id) {
return (TrustProfile) trustProfiles.get(id);
}
/**
* Log a warning.
*
* @param messageId The message ID.
* @param parameters Additional parameters for the message.
* @see at.gv.egovernment.moa.spss.server.util.MessageProvider
*/
private static void info(String messageId, Object[] parameters) {
MessageProvider msg = MessageProvider.getInstance();
Logger.info(new LogMsg(msg.getMessage(messageId, parameters)));
}
/**
* 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 void warn(String messageId, Object[] args) {
MessageProvider msg = MessageProvider.getInstance();
String txt = msg.getMessage(messageId, args);
Logger.warn(new LogMsg(txt));
warnings.add(txt);
}
}