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.pki.revocation.RevocationSourceTypes; 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 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 distributionPoints;
/**
* The CRL archive duration.
*/
private int cRLArchiveDuration;
/**
* Indicates whether revocation information should be archived.
*/
private boolean enableRevocationArchiving_;
/**
* The location of the certificate store.
*/
private String certStoreLocation_;
/**
* 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;
/**
* The JDBC URL for the revocation archive database.
*/
private String revocationArchiveJDBCURL_;
/**
* The JDBC driver class name for the revocation archive database.
*/
private String revocationArchiveJDBCDriverClass_;
/**
* Indicates whether revocation checking should be done.
*/
private boolean enableRevocationChecking_;
/**
* The maximum age of a revocation information for considering it still as valid.
*/
private long maxRevocationAge_;
/**
* The service order for revocation checking.
*/
private String[] serviceOrder_;
/**
* Indicates whether certificates found during certificate path construction
* should be added to the certificate store.
*/
private boolean autoAddCertificates_;
/**
* Indicates whether the certificate extension Authority Info Access should
* be used during certificate path construction.
*/
private boolean useAuthorityInfoAccess_;
/**
* 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, configRoot);
digestMethodAlgorithmName = builder.getDigestMethodAlgorithmName();
canonicalizationAlgorithmName =
builder.getCanonicalizationAlgorithmName();
hardwareCryptoModules = builder.buildHardwareCryptoModules();
hardwareKeyModules =
builder.buildHardwareKeyModules(Collections.EMPTY_LIST);
softwareKeyModules =
builder.buildSoftwareKeyModules(hardwareKeyModules);
allKeyModules = new ArrayList(hardwareKeyModules);
allKeyModules.addAll(softwareKeyModules);
keyGroups = builder.buildKeyGroups(allKeyModules);
keyGroupMappings =
builder.buildKeyGroupMappings(keyGroups, ANONYMOUS_ISSUER_SERIAL);
defaultChainingMode = builder.getDefaultChainingMode();
chainingModes = builder.buildChainingModes();
useAuthorityInfoAccess_ = builder.getUseAuthorityInfoAccess();
autoAddCertificates_ = builder.getAutoAddCertificates();
trustProfiles = builder.buildTrustProfiles();
distributionPoints = builder.buildDistributionPoints();
enableRevocationChecking_ = builder.getEnableRevocationChecking();
maxRevocationAge_ = builder.getMaxRevocationAge();
serviceOrder_ = builder.getServiceOrder();
enableRevocationArchiving_ = builder.getEnableRevocationArchiving();
cRLArchiveDuration = builder.getRevocationArchiveDuration();
revocationArchiveJDBCURL_ = builder.getRevocationArchiveJDBCURL();
revocationArchiveJDBCDriverClass_ = builder.getRevocationArchiveJDBCDriverClass();
certStoreLocation_ = builder.getCertStoreLocation();
createTransformsInfoProfiles = builder.buildCreateTransformsInfoProfiles();
createSignatureEnvironmentProfiles = builder.buildCreateSignatureEnvironmentProfiles();
verifyTransformsInfoProfiles = builder.buildVerifyTransformsInfoProfiles();
supplementProfiles = builder.buildSupplementProfiles();
warnings = new ArrayList(builder.getWarnings());
} 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;
}
/**
* 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();
}
}
// If no key group is available for a client identified by a certificate,
// try to find a key group in the anonymous key group mapping
if (issuer != null || serial != null)
{
mapping = (Map) keyGroupMappings.get(ANONYMOUS_ISSUER_SERIAL);
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 distribution points for a given CA.
*
* @param cert The certificate for which the 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 getDistributionPoints(X509Certificate cert)
{
try {
RFC2253NameParser nameParser =
new RFC2253NameParser(cert.getIssuerDN().toString());
String caIssuerDN = nameParser.parse().getName();
Set dps = (Set) distributionPoints.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;
}
/**
* Returns whether revocation information should be archived.
*
* @return whether revocation information should be archived.
*/
public boolean getEnableRevocationArchiving()
{
return enableRevocationArchiving_;
}
/**
* Returns the location of the certificate store.
*
* @return the location of the certificate store.
*/
public String getCertStoreLocation()
{
return certStoreLocation_;
}
/**
* 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);
}
/**
* Returns the JDBC URL for the revocation archive database.
*
* @return the JDBC URL for the revocation archive database.
*/
public String getRevocationArchiveJDBCURL()
{
return revocationArchiveJDBCURL_;
}
/**
* Returns the JDBC driver class name for the revocation archive database.
*
* @return the JDBC driver class name for the revocation archive database.
*/
public String getRevocationArchiveJDBCDriverClass()
{
return revocationArchiveJDBCDriverClass_;
}
/**
* Returns whether revocation checking should be done.
*
* @return whether revocation checking should be done.
*/
public boolean getEnableRevocationChecking()
{
return enableRevocationChecking_;
}
/**
* Returns the maximum age of a revocation information for considering it
* still as valid.
*
* @return the maximum age of a revocation information for considering it
* still as valid.
*/
public long getMaxRevocationAge()
{
return maxRevocationAge_;
}
/**
* Returns the service order for revocation checking.
*
* @return the service order for revocation checking. Valid array entries are
* {@link RevocationSourceTypes#OCSP} and {@link RevocationSourceTypes#CRL}.
*/
public String[] getServiceOrder()
{
return serviceOrder_;
}
/**
* Returns whether certificates found during certificate path construction
* should be added to the certificate store.
*
* @return whether certificates found during certificate path construction
* should be added to the certificate store.
*/
public boolean getAutoAddCertificates()
{
return autoAddCertificates_;
}
/**
* Returns whether the certificate extension Authority Info Access should
* be used during certificate path construction.
*
* @return whether the certificate extension Authority Info Access should
* be used during certificate path construction.
*/
public boolean getUseAuthorityInfoAccess()
{
return useAuthorityInfoAccess_;
}
}