aboutsummaryrefslogtreecommitdiff
path: root/spss.server/src/at/gv/egovernment/moa/spss/server
diff options
context:
space:
mode:
Diffstat (limited to 'spss.server/src/at/gv/egovernment/moa/spss/server')
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java34
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java956
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java666
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java134
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java60
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java59
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java115
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java69
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java106
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java41
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java48
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java43
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java37
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java36
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java48
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java62
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java54
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java54
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java121
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java33
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java81
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java51
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java55
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java162
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java34
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java85
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java73
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java75
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java56
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java127
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java113
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java65
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java119
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java43
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java54
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java49
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java43
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java87
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java42
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java71
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java34
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java43
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java46
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java47
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java43
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java116
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java82
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java98
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java168
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java150
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java276
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java45
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java131
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java42
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java122
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java207
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java61
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java71
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java717
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java127
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java267
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java63
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java249
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java51
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java45
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java72
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java258
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java86
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java317
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java522
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java448
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java580
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java147
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java126
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java42
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java54
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java38
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java252
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java120
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java83
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java72
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java90
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java130
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java242
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java90
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java62
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java51
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java61
88 files changed, 11505 insertions, 0 deletions
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java
new file mode 100644
index 000000000..f2b847053
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationException.java
@@ -0,0 +1,34 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+import at.gv.egovernment.moa.spss.MOASystemException;
+
+/**
+ * Exception signalling an error in the configuration.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ConfigurationException extends MOASystemException {
+
+ /**
+ * Create a <code>ConfigurationException</code>.
+ *
+ * @see at.gv.egovernment.moa.spss.server.MOAException#MOAException(String, Object[])
+ */
+ public ConfigurationException(String messageId, Object[] parameters) {
+ super(messageId, parameters);
+ }
+
+ /**
+ * Create a <code>ConfigurationException</code>.
+ * @see at.gv.egovernment.moa.spss.server.MOAException#MOAException(String, Object[], Throwable)
+ */
+ public ConfigurationException(
+ String messageId,
+ Object[] parameters,
+ Throwable wrapped) {
+
+ super(messageId, parameters, wrapped);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java
new file mode 100644
index 000000000..1e966911b
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationPartsBuilder.java
@@ -0,0 +1,956 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.MalformedURLException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
+
+import org.xml.sax.SAXException;
+
+import iaik.ixsil.exceptions.URIException;
+import iaik.ixsil.util.URI;
+import iaik.pki.pathvalidation.ChainingModes;
+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.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A class that builds configuration data from a DOM based representation.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ConfigurationPartsBuilder {
+
+ //
+ // XPath namespace prefix shortcuts
+ //
+
+ private static final String CONF = Constants.MOA_CONFIG_PREFIX + ":";
+ private static final String DSIG = Constants.DSIG_PREFIX + ":";
+
+ //
+ // chaining mode constants appearing in the configuration file
+ //
+
+ private static final String CM_CHAINING = "chaining";
+ private static final String CM_PKIX = "pkix";
+
+ //
+ // XPath expressions to select certain parts of the configuration
+ //
+
+ private static final String ROOT = "/" + CONF + "MOAConfiguration/";
+ private static final String DIGEST_METHOD_XPATH =
+ ROOT + CONF + "DigestMethodAlgorithm/@name";
+ private static final String C14N_ALGORITHM_XPATH =
+ ROOT + CONF + "CanonicalizationAlgorithm/@name";
+ private static final String HARDWARE_CRYPTO_MODULE_XPATH =
+ ROOT + CONF + "HardwareCryptoModule";
+ private static final String HARDWARE_KEY_XPATH =
+ ROOT + CONF + "HardwareKeyModule";
+ private static final String SOFTWARE_KEY_XPATH =
+ ROOT + CONF + "SoftwareKeyModule";
+ private static final String KEYGROUP_XPATH = ROOT + CONF + "KeyGroup";
+ private static final String KEY_XPATH = CONF + "Key";
+ private static final String KEY_MODULE_ID_XPATH = CONF + "KeyModuleID";
+ private static final String KEY_CERT_XPATH = CONF + "KeyCertIssuerSerial";
+ private static final String KEYGROUP_MAPPING_XPATH =
+ ROOT + CONF + "KeyGroupMapping";
+ private static final String KEYGROUP_MAPPING_KEYGROUP_XPATH =
+ CONF + "KeyGroup";
+ private static final String ISSUER_SERIAL_XPATH = CONF + "X509IssuerSerial";
+ private static final String ISSUER_XPATH = DSIG + "X509IssuerName";
+ private static final String SERIAL_XPATH = DSIG + "X509SerialNumber";
+ private static final String CHAINING_MODES_XPATH =
+ ROOT + CONF + "ChainingModes";
+ private static final String CHAINING_MODES_DEFAULT_XPATH =
+ CHAINING_MODES_XPATH + "/@systemDefaultMode";
+ private static final String TRUST_ANCHOR_XPATH =
+ ROOT + CONF + "ChainingModes/" + CONF + "TrustAnchor";
+ private static final String CRL_DISTRIBUTION_POINT_XPATH =
+ ROOT + CONF + "CRLDistributionPoint";
+ private static final String CA_ISSUER_DN_XPATH = CONF + "CAIssuerDN";
+ private static final String DISTRIBUTION_POINT_XPATH =
+ CONF + "DistributionPoint";
+ private static final String CRL_ARCHIVE_XPATH = ROOT + CONF + "CRLArchive";
+ private static final String GENERIC_CONFIGURATION_XPATH =
+ ROOT + CONF + "GenericConfiguration";
+ private static final String CREATE_TRANSFORMS_INFO_PROFILE_XPATH =
+ ROOT + CONF + "CreateTransformsInfoProfile";
+ private static final String CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH =
+ ROOT + CONF + "CreateSignatureEnvironmentProfile";
+ private static final String VERIFY_TRANSFORMS_INFO_PROFILE_XPATH =
+ ROOT + CONF + "VerifyTransformsInfoProfile";
+ private static final String SUPPLEMENT_PROFILE_XPATH =
+ ROOT + CONF + "SupplementProfile";
+ private static final String TRUST_PROFILE_XPATH =
+ ROOT + CONF + "TrustProfile";
+
+ //
+ // default values for configuration parameters
+ //
+
+ /** The accepted canonicalization algorithm URIs, as an array */
+ private static final String[] ACCEPTED_C14N_ALGORITHMS_ARRAY =
+ {
+ Constants.C14N_URI,
+ Constants.C14N_WITH_COMMENTS_URI,
+ Constants.EXC_C14N_URI,
+ Constants.EXC_C14N_WITH_COMMENTS_URI };
+
+ /** The accepted canonicalization algorithm URIs, as a Set */
+ private static final Set ACCEPTED_C14N_ALGORITHMS =
+ new HashSet(Arrays.asList(ACCEPTED_C14N_ALGORITHMS_ARRAY));
+
+ /** Default canonicalization algorithm, if none/illegal has been configured */
+ private static final String C14N_ALGORITHM_DEFAULT = Constants.C14N_URI;
+
+ /** The accepted digest method algorithm URIs, as an array */
+ private static final String[] ACCEPTED_DIGEST_ALGORITHMS_ARRAY =
+ { Constants.SHA1_URI };
+
+ /** The accepted digest method algorithm URIs, as a Set */
+ private static final Set ACCEPTED_DIGEST_ALGORITHMS =
+ new HashSet(Arrays.asList(ACCEPTED_DIGEST_ALGORITHMS_ARRAY));
+
+ /** Default digest algorithm URI, if none/illegal has been configured */
+ private static final String DIGEST_ALGORITHM_DEFAULT = Constants.SHA1_URI;
+
+ /** The root element of the MOA configuration */
+ private Element configElem;
+
+ /** Whether any warnings were encountered building the configuration. */
+ private List warnings = new ArrayList();
+
+ /**
+ * Create a new <code>ConfigurationPartsBuilder</code>.
+ *
+ * @param configElem The root element of the MOA configuration.
+ */
+ public ConfigurationPartsBuilder(Element configElem) {
+ this.configElem = configElem;
+ }
+
+ /**
+ * Returns the root element of the MOA configuration.
+ *
+ * @return The root element of the MOA configuration.
+ */
+ public Element getConfigElem() {
+ return configElem;
+ }
+
+ /**
+ * Returns the warnings encountered during building the configuration.
+ *
+ * @return A <code>List</code> of <code>String</code>s, containing the
+ * warning messages.
+ */
+ public List getWarnings() {
+ return warnings;
+ }
+
+ /**
+ * Returns the digest method algorithm name.
+ *
+ * @return The digest method algorithm name from the configuration.
+ */
+ public String getDigestMethodAlgorithmName() {
+ String digestMethod =
+ getAttributeValue(getConfigElem(), DIGEST_METHOD_XPATH, null);
+
+ if (digestMethod == null
+ || !ACCEPTED_DIGEST_ALGORITHMS.contains(digestMethod)) {
+ warn(
+ "config.23",
+ new Object[] { "DigestMethodAlgorithm", DIGEST_ALGORITHM_DEFAULT });
+ digestMethod = DIGEST_ALGORITHM_DEFAULT;
+ }
+
+ return digestMethod;
+ }
+
+ /**
+ * Returns the canonicalization algorithm name.
+ *
+ * @return The canonicalization algorithm name from the configuration.
+ */
+ public String getCanonicalizationAlgorithmName() {
+ String c14nAlgorithm =
+ getAttributeValue(getConfigElem(), C14N_ALGORITHM_XPATH, null);
+
+ if (c14nAlgorithm == null
+ || !ACCEPTED_C14N_ALGORITHMS.contains(c14nAlgorithm)) {
+ warn(
+ "config.23",
+ new Object[] { "CanonicalizationAlgorithm", C14N_ALGORITHM_DEFAULT });
+ c14nAlgorithm = C14N_ALGORITHM_DEFAULT;
+ }
+
+ return c14nAlgorithm;
+ }
+
+ /**
+ * Build the mapping of generic configuration properties.
+ *
+ * @return The mapping of generic configuration properties (a name to value
+ * mapping) from the configuration.
+ */
+ public Map buildGenericConfiguration() {
+ Map genericConfiguration = new HashMap();
+ NodeIterator gcIter =
+ XPathUtils.selectNodeIterator(
+ getConfigElem(),
+ GENERIC_CONFIGURATION_XPATH);
+ Element gcElem;
+
+ while ((gcElem = (Element) gcIter.nextNode()) != null) {
+ String gcName = gcElem.getAttribute("name");
+ String gcValue = gcElem.getAttribute("value");
+
+ if (genericConfiguration.containsKey(gcName)) {
+ warn("config.24", new Object[] { gcName });
+ } else {
+ genericConfiguration.put(gcName, gcValue);
+ }
+ }
+
+ return genericConfiguration;
+ }
+
+ /**
+ * Build the configured hardware crypto modules.
+ *
+ * @return The hardware crypto modules from the configuration.
+ */
+ public List buildHardwareCryptoModules() {
+ List modules = new ArrayList();
+ NodeIterator modIter =
+ XPathUtils.selectNodeIterator(
+ getConfigElem(),
+ HARDWARE_CRYPTO_MODULE_XPATH);
+ Element modElem;
+
+ while ((modElem = (Element) modIter.nextNode()) != null) {
+ String name = modElem.getAttribute("name");
+ String slotID = modElem.getAttribute("slotID");
+ String userPIN = modElem.getAttribute("userPIN");
+ HardwareCryptoModule module =
+ new HardwareCryptoModule(name, slotID, userPIN);
+ modules.add(module);
+ }
+
+ return modules;
+ }
+
+ /**
+ * Build the configured hardware keys.
+ *
+ * @param The keyModules that the configuration already knows about. To
+ * prevent multiple key modules with the same ID.
+ * @return The hardware keys contained in the configuration.
+ */
+ public List buildHardwareKeyModules(List keyModules) {
+ Set existingIds = toIdSet(keyModules);
+ List hardwareKeys = new ArrayList();
+ NodeIterator hkIter =
+ XPathUtils.selectNodeIterator(getConfigElem(), HARDWARE_KEY_XPATH);
+ Element keyElem;
+
+ while ((keyElem = (Element) hkIter.nextNode()) != null) {
+ String id = keyElem.getAttribute("id");
+ String name = keyElem.getAttribute("name");
+ String slotID = keyElem.getAttribute("slotID");
+ String userPIN = keyElem.getAttribute("userPIN");
+
+ if (existingIds.contains(id)) {
+ warn(
+ "config.04",
+ new Object[] { "Hardware- oder SoftwareKeyModule", id });
+ } else {
+ KeyModule key = new HardwareKeyModule(id, name, slotID, userPIN);
+ hardwareKeys.add(key);
+ existingIds.add(id);
+ }
+
+ }
+
+ return hardwareKeys;
+ }
+
+ /**
+ * Build the configured software keys.
+ *
+ * @param The keyModules that the configuration already knows about. To
+ * prevent multiple key modules with the same ID.
+ * @param configRoot The directory containing the main configuration file.
+ * Used to resolve keystore files configured using a relative URI.
+ * @return The software keys contained in the configuration.
+ */
+ public List buildSoftwareKeyModules(List keyModules, File configRoot) {
+ Set existingIds = toIdSet(keyModules);
+ List softwareKeys = new ArrayList();
+ NodeIterator skIter =
+ XPathUtils.selectNodeIterator(getConfigElem(), SOFTWARE_KEY_XPATH);
+
+ Element keyElem;
+
+ while ((keyElem = (Element) skIter.nextNode()) != null) {
+ String id = keyElem.getAttribute("id");
+ String fileName = keyElem.getAttribute("filename");
+ String passWord = keyElem.getAttribute("password");
+
+ if (existingIds.contains(id)) {
+ warn(
+ "config.04",
+ new Object[] { "Hardware- oder SoftwareKeyModule", id });
+ } else {
+ File keyFile;
+ KeyModule key;
+
+ // make keyFile absolute
+ keyFile = new File(fileName);
+ if (!keyFile.isAbsolute()) {
+ keyFile = new File(configRoot, fileName);
+ }
+
+ // check for existence
+ if (!keyFile.exists() || keyFile.isDirectory()) {
+ warn("config.25", new Object[] { id, keyFile.getAbsolutePath()});
+ } else {
+ // create a new key module
+ key = new SoftwareKeyModule(id, keyFile.getAbsolutePath(), passWord);
+ softwareKeys.add(key);
+ existingIds.add(id);
+ }
+ }
+
+ }
+
+ return softwareKeys;
+ }
+
+ /**
+ * Build the key group configuration.
+ *
+ * @param keyModules The <code>KeyModule</code>s that the configuration
+ * knows about. Used to check for errors in the configuration.
+ * @return The mapping between key group IDs and key groups.
+ */
+ public Map buildKeyGroups(List keyModules) {
+ Set keyModuleIds = toIdSet(keyModules);
+ Map keyGroups = new HashMap();
+ NodeIterator kgIter;
+ Element keyGroupElem;
+
+ // select all KeyGroup elements and build the KeyGroup objects from them
+ kgIter = XPathUtils.selectNodeIterator(getConfigElem(), KEYGROUP_XPATH);
+ while ((keyGroupElem = (Element) kgIter.nextNode()) != null) {
+ String keyGroupId = keyGroupElem.getAttribute("id");
+ Set keyGroupEntries =
+ buildKeyGroupEntries(keyGroupId, keyModuleIds, keyGroupElem);
+ KeyGroup keyGroup = new KeyGroup(keyGroupId, keyGroupEntries);
+
+ if (keyGroups.containsKey(keyGroupId)) {
+ warn("config.04", new Object[] { "KeyGroup", keyGroupId });
+ } else {
+ keyGroups.put(keyGroup.getId(), keyGroup);
+ }
+ }
+
+ return keyGroups;
+ }
+
+ /**
+ * Return the set of IDs contained in the given <code>KeyModule</code>s.
+ *
+ * @param keyModules The <code>KeyModule</code>s from which to extract the
+ * IDs.
+ * @return The IDs from the given <code>KeyModule</code>s.
+ */
+ private Set toIdSet(List keyModules) {
+ Set ids = new HashSet();
+ Iterator iter;
+
+ for (iter = keyModules.iterator(); iter.hasNext();) {
+ KeyModule keyModule = (KeyModule) iter.next();
+ ids.add(keyModule.getId());
+ }
+
+ return ids;
+ }
+
+ /**
+ * Build the key entries belonging to a key group.
+ *
+ * @param keyGroupId The ID of the key group we are building here. Passed
+ * for logging purposes.
+ * @param keyModuleIds The IDs of the <code>HardwareKeyModule</code>s and
+ * <code>SoftwareKeyModule</code>s that exist in the configuration.
+ * @param keyGroupElem The <code>KeyGroup</code> DOM element to parse.
+ * @return A <code>Set</code> of <code>KeyGroupEntry</code> objects.
+ */
+ private Set buildKeyGroupEntries(
+ String keyGroupId,
+ Set keyModuleIds,
+ Element keyGroupElem) {
+
+ Set entries = new HashSet();
+ NodeIterator keyEntryIter;
+ Element keyEntryElem;
+
+ // select all Key elements and put them into the Map
+ keyEntryIter = XPathUtils.selectNodeIterator(keyGroupElem, KEY_XPATH);
+ while ((keyEntryElem = (Element) keyEntryIter.nextNode()) != null) {
+ String keyModuleId =
+ getElementValue(keyEntryElem, KEY_MODULE_ID_XPATH, "");
+ Element keyCertElem =
+ (Element) XPathUtils.selectSingleNode(keyEntryElem, KEY_CERT_XPATH);
+ IssuerAndSerial issuerSerial = buildIssuerAndSerial(keyCertElem);
+
+ if (!keyModuleIds.contains(keyModuleId)) {
+ warn("config.26", new Object[] { keyGroupId, keyModuleId });
+ } else if (issuerSerial != null) {
+ KeyGroupEntry entry = new KeyGroupEntry(keyModuleId, issuerSerial);
+ entries.add(entry);
+ }
+ }
+ return entries;
+ }
+
+ /**
+ * Build the key group mapping.
+ *
+ * @param keyGroups The available key groups.
+ * @param anonymous The <code>IssuerAndSerial</code> to be used for key group
+ * mappings not protected by a certificate.
+ * @return The key group mapping.
+ */
+ public Map buildKeyGroupMappings(Map keyGroups, IssuerAndSerial anonymous) {
+ Map mappings = new HashMap();
+ NodeIterator mappingIter;
+ Element mappingElem;
+
+ // select all KeyGroupMapping elements
+ mappingIter =
+ XPathUtils.selectNodeIterator(getConfigElem(), KEYGROUP_MAPPING_XPATH);
+
+ // build the mapping for each KeyGroupMapping element
+ while ((mappingElem = (Element) mappingIter.nextNode()) != null) {
+ Element issuerSerialElem =
+ (Element) XPathUtils.selectSingleNode(mappingElem, ISSUER_SERIAL_XPATH);
+ IssuerAndSerial issuerAndSerial;
+
+ // build the IssuerAndSerial who has access to the key groups
+ if (issuerSerialElem != null) {
+ issuerAndSerial = buildIssuerAndSerial(issuerSerialElem);
+ } else {
+ // IssuerSerial element: the keygroup is generally available
+ issuerAndSerial = anonymous;
+ }
+
+ // add the key groups to the mappings
+ if (issuerAndSerial != null) {
+ Map groups = (Map) mappings.get(issuerAndSerial);
+ NodeIterator keyGroupIter;
+ Element keyGroupElem;
+
+ if (groups == null) {
+ // no mapping exist -> build one
+ groups = new HashMap();
+ mappings.put(issuerAndSerial, groups);
+ }
+
+ // select the available key groups and add them to the mapping
+ keyGroupIter =
+ XPathUtils.selectNodeIterator(
+ mappingElem,
+ KEYGROUP_MAPPING_KEYGROUP_XPATH);
+ while ((keyGroupElem = (Element) keyGroupIter.nextNode()) != null) {
+ String keyGroupId = keyGroupElem.getAttribute("id");
+ KeyGroup keyGroup = (KeyGroup) keyGroups.get(keyGroupId);
+
+ if (keyGroup != null) {
+ groups.put(keyGroupId, keyGroup);
+ } else {
+ warn("config.00", new Object[] { keyGroupId });
+ }
+ }
+ }
+ }
+
+ return mappings;
+ }
+
+ /**
+ * Returns the default chaining mode from the configuration.
+ *
+ * @return The default chaining mode.
+ */
+ public String getDefaultChainingMode() {
+ String defaultChaining =
+ getAttributeValue(
+ getConfigElem(),
+ CHAINING_MODES_DEFAULT_XPATH,
+ CM_CHAINING);
+
+ return translateChainingMode(defaultChaining);
+
+ }
+
+ /**
+ * Build the chaining modes for all configured trust anchors.
+ *
+ * @return The mapping from trust anchors to chaining modes.
+ */
+ public Map buildChainingModes() {
+ Map chainingModes = new HashMap();
+ NodeIterator trustIter =
+ XPathUtils.selectNodeIterator(getConfigElem(), TRUST_ANCHOR_XPATH);
+ Element trustAnchorElem;
+
+ while ((trustAnchorElem = (Element) trustIter.nextNode()) != null) {
+ IssuerAndSerial issuerAndSerial = buildIssuerAndSerial(trustAnchorElem);
+ String mode = trustAnchorElem.getAttribute("mode");
+
+ if (issuerAndSerial != null) {
+ chainingModes.put(issuerAndSerial, translateChainingMode(mode));
+ }
+ }
+
+ return chainingModes;
+ }
+
+ /**
+ * Build an <code>IssuerAndSerial</code> from the DOM representation.
+ *
+ * @param root The root element (being of type <code>dsig:
+ * X509IssuerSerialType</code>.
+ * @return The issuer and serial number contained in the <code>root</code>
+ * element or <code>null</code> if could not be built for any reason.
+ */
+ private IssuerAndSerial buildIssuerAndSerial(Element root) {
+ String issuer = getElementValue(root, ISSUER_XPATH, null);
+ String serial = getElementValue(root, SERIAL_XPATH, null);
+
+ if (issuer != null && serial != null) {
+ try {
+ RFC2253NameParser nameParser = new RFC2253NameParser(issuer);
+ Principal issuerDN = nameParser.parse();
+
+ return new IssuerAndSerial(issuerDN, new BigInteger(serial));
+ } catch (RFC2253NameParserException e) {
+ warn("config.16", new Object[] { issuer, serial }, e);
+ return null;
+ } catch (NumberFormatException e) {
+ warn("config.16", new Object[] { issuer, serial }, e);
+ return null;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Translate the chaining mode from the configuration file to one used in the
+ * IAIK MOA API.
+ *
+ * @param chainingMode The chaining mode from the configuration.
+ * @return The chaining mode as provided by the <code>ChainingModes</code>
+ * interface.
+ * @see iaik.pki.pathvalidation.ChainingModes
+ */
+ private String translateChainingMode(String chainingMode) {
+ if (chainingMode.equals(CM_CHAINING)) {
+ return ChainingModes.CHAIN_MODE;
+ } else if (chainingMode.equals(CM_PKIX)) {
+ return ChainingModes.PKIX_MODE;
+ } else {
+ return ChainingModes.CHAIN_MODE;
+ }
+ }
+
+ /**
+ * Build the CRL distribution points mapping.
+ *
+ * @return The mapping from certificate authorities to distribution points.
+ */
+ public Map buildCRLDistributionPoints() {
+ Map crlDps = new HashMap();
+ NodeIterator crlDpIter;
+ Element crlDpElem;
+
+ // select all CRLDistributionPoint elements and build the
+ // CRLDistributionPoints
+ crlDpIter =
+ XPathUtils.selectNodeIterator(
+ getConfigElem(),
+ CRL_DISTRIBUTION_POINT_XPATH);
+
+ // build the mapping of CA name to distribution points
+ while ((crlDpElem = (Element) crlDpIter.nextNode()) != null) {
+ String caIssuerDNText =
+ getElementValue(crlDpElem, CA_ISSUER_DN_XPATH, "");
+ RFC2253NameParser nameParser = new RFC2253NameParser(caIssuerDNText);
+ NodeIterator dpIter =
+ XPathUtils.selectNodeIterator(crlDpElem, DISTRIBUTION_POINT_XPATH);
+ String caIssuerDN;
+ Set dps;
+ Element dpElem;
+
+ try {
+ caIssuerDN = nameParser.parse().getName();
+
+ // check, if a mapping exists or make a new mapping
+ dps = (Set) crlDps.get(caIssuerDN);
+ if (dps == null) {
+ dps = new HashSet();
+ crlDps.put(caIssuerDN, dps);
+ }
+
+ // add the distribution points of this CA to the set
+ while ((dpElem = (Element) dpIter.nextNode()) != null) {
+ DistributionPoint dp = buildDistributionPoint(dpElem);
+ dps.add(dp);
+ }
+ } catch (RFC2253NameParserException e) {
+ warn("config.13", new Object[] { caIssuerDNText }, e);
+ }
+
+ }
+
+ return crlDps;
+ }
+
+ /**
+ * Build a distribution point from the DOM representation.
+ *
+ * @param dpElem The root element of the distribution point.
+ * @return The distribution point.
+ */
+ private DistributionPoint buildDistributionPoint(Element dpElem) {
+ String uri = dpElem.getAttribute("uri");
+ String reasonCodes = dpElem.getAttribute("reasonCodes");
+
+ return new DistributionPoint(uri, reasonCodes != null ? reasonCodes : "");
+ }
+
+ /**
+ * Return the CRL archive duration.
+ *
+ * @return The value of the CRL archive duration setting from the
+ * configuration.
+ */
+ public int getCRLArchiveDuration() {
+ Element crlArchiveElem =
+ (Element) XPathUtils.selectSingleNode(getConfigElem(), CRL_ARCHIVE_XPATH);
+ String crlArchiveDuration;
+
+ if (crlArchiveElem == null) {
+ return 0;
+ }
+
+ try {
+ crlArchiveDuration = crlArchiveElem.getAttribute("duration");
+ return Integer.parseInt(crlArchiveDuration);
+ } catch (NumberFormatException e) {
+ warn("config.01", null);
+ return 0;
+ }
+ }
+
+ /**
+ * Build the <code>CreateTransformsInfoProfile</code>s.
+ *
+ * @param configRoot The directory of the main configuration file. Used for
+ * lookup of profiles with relative file names.
+ * @return The mapping from profile ID to profile.
+ */
+ public Map buildCreateTransformsInfoProfiles(File configRoot) {
+ return loadProfiles(
+ configRoot,
+ CREATE_TRANSFORMS_INFO_PROFILE_XPATH,
+ "CreateTransformsInfoProfile");
+ }
+
+ /**
+ * Build the <code>CreateSignatureEnvironmentProfile</code>s.
+ *
+ * @param configRoot The directory of the main configuration file. Used for
+ * lookup of profiles with relative file names.
+ * @return The mapping from profile ID to profile.
+ */
+ public Map buildCreateSignatureEnvironmentProfiles(File configRoot) {
+ return loadProfiles(
+ configRoot,
+ CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH,
+ "CreateSignatureEnvironmentProfile");
+ }
+
+ /**
+ * Build the <code>VerifyTransformsInfoProfile</code>s.
+ *
+ * @param configRoot The directory of the main configuration file. Used for
+ * lookup of profiles with relative file names.
+ * @return The mapping from profile ID to profile.
+ */
+ public Map buildVerifyTransformsInfoProfiles(File configRoot) {
+ return loadProfiles(
+ configRoot,
+ VERIFY_TRANSFORMS_INFO_PROFILE_XPATH,
+ "VerifyTransformsInfoProfile");
+ }
+
+ /**
+ * Build the <code>SupplementProfile</code>s.
+ *
+ * @param configRoot The directory of the main configuration file. Used for
+ * lookup of profiles with relative file names.
+ * @return The mapping from profile ID to profile.
+ */
+ public Map buildSupplementProfiles(File configRoot) {
+ return loadProfiles(
+ configRoot,
+ SUPPLEMENT_PROFILE_XPATH,
+ "SupplementProfile");
+ }
+
+ /**
+ * Load a profile mapping.
+ *
+ * @param root The absolute directory path of the main configuration file.
+ * @param xpath The XPath to select the profiles from the configuration.
+ * @param profileRoot The name of the profile root element.
+ * @return Map The profile ID to profile mapping.
+ */
+ private Map loadProfiles(File root, String xpath, String profileRoot) {
+ Map profiles = new HashMap();
+ NodeIterator profileIter =
+ XPathUtils.selectNodeIterator(getConfigElem(), xpath);
+ Element profileElem;
+
+ while ((profileElem = (Element) profileIter.nextNode()) != null) {
+ String id = profileElem.getAttribute("id");
+ String fileName = profileElem.getAttribute("filename");
+
+ if (profiles.containsKey(id)) {
+ warn("config.04", new Object[] { profileRoot, id });
+ } else {
+ Element profile;
+
+ try {
+ File profileFile = new File(fileName);
+
+ // make profileFile absolute
+ if (!profileFile.isAbsolute()) {
+ profileFile = new File(root, fileName);
+ }
+
+ // load the profile
+ info(
+ "config.22",
+ new Object[] { profileRoot, id, profileFile.getAbsoluteFile()});
+ profile = loadProfile(profileFile);
+
+ if (profile.getTagName().equals(profileRoot)) {
+ profiles.put(id, profile);
+ } else {
+ warn("config.02", new Object[] { profileRoot, id, fileName });
+ }
+ } catch (ConfigurationException e) {
+ warn("config.03", new Object[] { profileRoot, id });
+ }
+ }
+
+ }
+
+ return profiles;
+ }
+
+ /**
+ * Load a profile from a file.
+ *
+ * @param root The absolute directory path of the main configuration file.
+ * @param profileFile The file containing the profile.
+ * @return The profile in its DOM representation.
+ * @throws ConfigurationException An error occurred loading the profile.
+ */
+ private Element loadProfile(File profileFile) throws ConfigurationException {
+
+ Element profile;
+
+ try {
+ profile = parseXml(new FileInputStream(profileFile));
+ } catch (Exception e) {
+ throw new ConfigurationException("config.12", null, e);
+ }
+
+ return profile;
+ }
+
+ /**
+ * Bulid the trust profile mapping.
+ *
+ * @param configRoot The absolute path to the main configuration file.
+ * @return The profile ID to profile mapping.
+ */
+ public Map buildTrustProfiles(File configRoot) {
+ Map trustProfiles = new HashMap();
+ NodeIterator profileIter =
+ XPathUtils.selectNodeIterator(getConfigElem(), TRUST_PROFILE_XPATH);
+ Element profileElem;
+
+ while ((profileElem = (Element) profileIter.nextNode()) != null) {
+ String id = profileElem.getAttribute("id");
+ String uriStr = profileElem.getAttribute("uri");
+
+ try {
+ URI uri = new URI(uriStr);
+ TrustProfile profile;
+ File profileDir;
+
+ if (!uri.isAbsolute()) { // make it absolute to the config file
+ uri = new URI(configRoot.toURL() + uriStr);
+ }
+
+ profileDir = new File(uri.getPath());
+ if (!profileDir.exists() || !profileDir.isDirectory()) {
+ warn("config.27", new Object[] { id });
+ }
+
+ if (trustProfiles.containsKey(id)) {
+ warn("config.04", new Object[] { "TrustProfile", id });
+ } else {
+ profile = new TrustProfile(id, uri.toString());
+ trustProfiles.put(id, profile);
+ }
+
+ } catch (URIException e) {
+ warn("config.14", new Object[] { id, uriStr }, e);
+ } catch (MalformedURLException e) {
+ warn("config.15", null, e);
+ }
+ }
+
+ return trustProfiles;
+ }
+
+ //
+ // various utility methods
+ //
+
+ /**
+ * Parse a configuration XML file.
+ *
+ * @param inputStream The stream from which to read the XML data.
+ * @return The DOM representation of the XML data.
+ * @throws ParserConfigurationException XML parser not configured properly.
+ * @throws SAXException An error parsing the XML file.
+ * @throws IOException An error reading the stream.
+ */
+ private static Element parseXml(InputStream inputStream)
+ throws ParserConfigurationException, SAXException, IOException {
+ return DOMUtils
+ .parseDocument(inputStream, true, Constants.ALL_SCHEMA_LOCATIONS, null)
+ .getDocumentElement();
+ }
+
+ /**
+ * Return the value of an element located by an XPath.
+ *
+ * @param root The root element from which to evaluate the <code>xpath</code>.
+ * @param xpath The XPath pointing to the element.
+ * @param def The default value, if no element can be found with the given
+ * <code>xpath</code>.
+ * @return The element value or <code>def</code>, if the element cannot be
+ * found.
+ */
+ private String getElementValue(Element root, String xpath, String def) {
+
+ Element elem = (Element) XPathUtils.selectSingleNode(root, xpath);
+ return elem != null ? DOMUtils.getText(elem) : def;
+ }
+
+ /**
+ * Return the value of an attribute located by an XPath.
+ *
+ * @param root The root element from which to evaluate the <code>xpath</code>.
+ * @param xpath The XPath pointing to the attribute.
+ * @param def The default value, if no attribute can be found with the given
+ * <code>xpath</code>.
+ * @return The element value or <code>def</code>, if the attribute cannot be
+ * found.
+ */
+ private String getAttributeValue(Element root, String xpath, String def) {
+ Attr attr = (Attr) XPathUtils.selectSingleNode(root, xpath);
+ return attr != null ? attr.getValue() : def;
+ }
+
+ /**
+ * Log an info message.
+ *
+ * @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);
+ }
+
+ /**
+ * Log a warning.
+ *
+ * @param messageId The message ID.
+ * @param args Additional parameters for the message.
+ * @param t An exception being the cause of the warning.
+ * @see at.gv.egovernment.moa.spss.server.util.MessageProvider
+ */
+ private void warn(String messageId, Object[] args, Throwable t) {
+ MessageProvider msg = MessageProvider.getInstance();
+ String txt = msg.getMessage(messageId, args);
+
+ Logger.warn(new LogMsg(txt), t);
+ warnings.add(txt);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java
new file mode 100644
index 000000000..fbae33b72
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/ConfigurationProvider.java
@@ -0,0 +1,666 @@
+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.
+ *
+ * <p>Configuration data is read from an XML file, whose location is given by
+ * the <code>moa.spss.server.configuration</code> system property.</p>
+ * <p>This class implements the Singleton pattern. The <code>reload()</code>
+ * method can be used to update the configuration data. Therefore, it is not
+ * guaranteed that consecutive calls to <code>getInstance()</code> will return
+ * the same <code>ConfigurationProvider</code> all the time. During the
+ * processing of a web service request, the current
+ * <code>TransactionContext</code> should be used to obtain the
+ * <code>ConfigurationProvider</code> local to that request.</p>
+ *
+ * @author Patrick Peck
+ * @author Sven Aigner
+ * @version $Id$
+ */
+public class ConfigurationProvider {
+
+ /**
+ * The name of the system property which contains the file name of the
+ * configuration file.
+ */
+ public static final String CONFIG_PROPERTY_NAME =
+ "moa.spss.server.configuration";
+
+ /**
+ * The name of the generic configuration property giving the root directory of
+ * a directory based cert store.
+ */
+ public static final String DIRECTORY_CERTSTORE_PARAMETER_PROPERTY =
+ "DirectoryCertStoreParameters.RootDir";
+
+ /** The name of the generic configuration property which determines if
+ * certificates should be added to the cert store automatically. */
+ public static final String AUTO_ADD_CERTIFICATES_PROPERTY =
+ "autoAddCertificates";
+
+ /** The name of the generic configuration property whether the authority
+ * info access should be used. */
+ public static final String USE_AUTHORITY_INFO_ACCESS_PROPERTY =
+ "useAuthorityInfoAccess";
+
+ /** The name of the generic configuration property determining the maximum
+ * age of CRL entries. */
+ public static final String MAX_REVOCATION_AGE_PROPERTY = "maxRevocationAge";
+
+ /**
+ * The name of the generic configuration property giving the database URL of
+ * the CRL archive.
+ */
+ public static final String DATABASE_ARCHIVE_PARAMETER_PROPERTY =
+ "DataBaseArchiveParameter.JDBCUrl";
+
+ /** The name of the generic configuration property determining whether
+ * to check the revocation status of signer certificates. */
+ public static final String REVOCATION_CHECKING_PROPERTY = "checkRevocation";
+
+ /** The name of the generic configuration property determining whether to
+ * archive revocation information. */
+ public static final String ARCHIVE_REVOCATION_INFO_PROPERTY =
+ "archiveRevocationInfo";
+
+ /** The name of the generic configuration property used for setting the
+ * signing time to a predefined value. (Use for testing purposes only). */
+ public static final String TEST_SIGNING_TIME_PROPERTY = "test.SigningTime";
+
+ /**
+ * A fake <code>IssuerAndSerial</code> 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. <code>null</code>, 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 <code>Map</code> which contains generic configuration information. Maps a
+ * configuration name (a <code>String</code>) to a configuration value (also a
+ * <code>String</code>).
+ */
+ private Map genericConfiguration;
+
+ /**
+ * A <code>List</code> of <code>HardwareCryptoModule</code> objects for
+ * configuring hardware modules.
+ */
+ private List hardwareCryptoModules;
+
+ /**
+ * A <code>List</code> of <code>HardwareKey</code> objects containing the
+ * configuration data for hardware keys.
+ */
+ private List hardwareKeyModules;
+
+ /**
+ * A <code>List</code> of <code>SoftwareKey</code> objects containing the
+ * configuration data for software keys.
+ */
+ private List softwareKeyModules;
+
+ /**
+ * A <code>Map</code> which contains a KeyGroupId (a <code>String</code>) to
+ * KeyGroup mapping.
+ */
+ private Map keyGroups;
+
+ /**
+ * A <code>Map</code> which contains the <code>IssuerAndSerial</code> to
+ * <code>KeyGroup</code> mapping.
+ */
+ private Map keyGroupMappings;
+
+ /** The default chaining mode. */
+ private String defaultChainingMode;
+
+ /**
+ * A <code>Map</code> which contains the <code>IssuerAndSerial</code> to
+ * chaining mode (a <code>String</code>) mapping.
+ */
+ private Map chainingModes;
+
+ /**
+ * A <code>Map</code> which contains the CAIssuerDN (a <code>String</code>)
+ * to distribution points (a <code>Set</code> of
+ * <code>DistributionPoint</code>s) mapping.
+ */
+ private Map crlDistributionPoints;
+
+ /** The CRL archive duration. */
+ private int cRLArchiveDuration;
+
+ /**
+ * A <code>Map</code> which contains a mapping from
+ * CreateSignatureEnvironmentProfile Ids (<code>String</code>) to
+ * CreateSignatureEnvironmentProfile elements (an <code>Element</code>).
+ */
+ private Map createSignatureEnvironmentProfiles;
+
+ /**
+ * A <code>Map</code> which contains a mapping from
+ * CreateTransformsInfoProfile Ids (<code>String</code>) to
+ * CreateTransformsInfoProfile elements (an <code>Element</code>).
+ */
+ private Map createTransformsInfoProfiles;
+
+ /**
+ * A <code>Map</code> which contains a mapping from
+ * VerifyTransformsInfoProfile Ids (<code>String</code>) to
+ * VerifyTransformsInfoProfile elements (an <code>Element</code>).
+ */
+ private Map verifyTransformsInfoProfiles;
+
+ /**
+ * A <code>Map</code> which contains a mapping from
+ * SupplementProfile Ids (<code>String</code>) to SupplementProfile elements
+ * (an <code>Element</code>).
+ */
+ private Map supplementProfiles;
+
+ /**
+ * A <code>Map</code> which contains a TrustProfile Id (a <code>String</code>
+ * to trust profile (a <code>TrustProfile</code>) 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 <code>List</code> of <code>String</code>s, containing the
+ * warning messages.
+ */
+ public List getWarnings() {
+ return warnings;
+ }
+
+ /**
+ * Make the <code>DIRECTORY_CERTSTORE_PARAMETER_PROPERTY</code> 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 <code>String</code>,
+ * 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
+ * <code>String</code> if none has been configured.
+ */
+ public String getCanonicalizationAlgorithmName() {
+ return canonicalizationAlgorithmName;
+ }
+
+ /**
+ * Return the configured hardware crypto modules.
+ *
+ * @return A <code>List</code> of <code>HardwareCryptoModule</code> objects
+ * containing the hardware crypto module configurations.
+ */
+ public List getHardwareCryptoModules() {
+ return hardwareCryptoModules;
+ }
+
+ /**
+ * Return the hardware key modules configuration.
+ *
+ * @return A <code>List</code> of <code>HardwareKeyModule</code> objects
+ * containing the configuration of the hardware key modules.
+ */
+ public List getHardwareKeyModules() {
+ return hardwareKeyModules;
+ }
+
+ /**
+ * Return the software key module configuration.
+ *
+ * @return A <code>List</code> of <code>SoftwareKeyModule</code> 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 <code>String</code>) to
+ * <code>KeyGroup</code> mapping.
+ */
+ public Map getKeyGroups() {
+ return keyGroups;
+ }
+
+ /**
+ * Return the set of <code>KeyGroupEntry</code>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 <code>Set</code> of all the <code>KeyGroupEntry</code>s in the
+ * given key group, if the user may access them. Returns <code>null</code>, 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 <code>Set</code> of <code>DistributionPoint</code> 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
+ * <code>null</code>, 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
+ * <code>defaultValue</code>, 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 <code>CreateTransformsInfoProfile</code> with the given ID.
+ *
+ * @param id The <code>CreateTransformsInfoProfile</code> ID.
+ * @return The <code>CreateTransformsInfoProfile</code> with the given
+ * ID or <code>null</code>, if none exists.
+ */
+ public Element getCreateTransformsInfoProfile(String id) {
+ return (Element) createTransformsInfoProfiles.get(id);
+ }
+
+ /**
+ * Return a <code>CreateSignatureEnvironmentProfile</code> with the given ID.
+ *
+ * @param id The <code>CreateSignatureEnvironmentProfile</code> ID.
+ * @return The <code>CreateSignatureEnvironmentProfile</code> with the given
+ * ID or <code>null</code>, if none exists.
+ */
+ public Element getCreateSignatureEnvironmentProfile(String id) {
+ return (Element) createSignatureEnvironmentProfiles.get(id);
+ }
+
+ /**
+ * Return a <code>VerifyTransformsInfoProfile</code> with the given ID.
+ *
+ * @param id The <code>VerifyTransformsInfoProfile</code> ID.
+ * @return The <code>VerifyTransformsInfoProfile</code> with the given ID or
+ * <code>null</code>, if none exists.
+ */
+ public Element getVerifyTransformsInfoProfile(String id) {
+ return (Element) verifyTransformsInfoProfiles.get(id);
+ }
+
+ /**
+ * Return a <code>SupplementProfile</code> with the given ID.
+ *
+ * @param id The <code>SupplementProfile</code> ID.
+ * @return The <code>SupplementProfile</code> with the given ID or
+ * <code>null</code>, if none exists.
+ */
+ public Element getSupplementProfile(String id) {
+ return (Element) supplementProfiles.get(id);
+ }
+
+ /**
+ * Return a <code>TrustProfile</code> with the given ID.
+ *
+ * @param id The <code>TrustProfile</code> ID.
+ * @return The <code>TrustProfile</code> with the given ID or
+ * <code>null</code>, 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);
+ }
+
+} \ No newline at end of file
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java
new file mode 100644
index 000000000..ce9588c87
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/DistributionPoint.java
@@ -0,0 +1,134 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A class containing information about a CRL distribution point.
+ *
+ * @author Sven Aigner
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class DistributionPoint {
+
+ private static Map RC_MAPPING = new HashMap();
+
+ static {
+
+ // create the mapping between reason code strings and their integer values
+ RC_MAPPING.put(
+ "unused",
+ new Integer(iaik.asn1.structures.DistributionPoint.unused));
+ RC_MAPPING.put(
+ "keyCompromise",
+ new Integer(iaik.asn1.structures.DistributionPoint.keyCompromise));
+ RC_MAPPING.put(
+ "cACompromise",
+ new Integer(iaik.asn1.structures.DistributionPoint.cACompromise));
+ RC_MAPPING.put(
+ "affiliationChanged",
+ new Integer(iaik.asn1.structures.DistributionPoint.affiliationChanged));
+ RC_MAPPING.put(
+ "superseded",
+ new Integer(iaik.asn1.structures.DistributionPoint.superseded));
+ RC_MAPPING.put(
+ "cessationOfOperation",
+ new Integer(iaik.asn1.structures.DistributionPoint.cessationOfOperation));
+ RC_MAPPING.put(
+ "certificateHold",
+ new Integer(iaik.asn1.structures.DistributionPoint.certificateHold));
+ RC_MAPPING.put(
+ "privilegeWithdrawn",
+ new Integer(iaik.asn1.structures.DistributionPoint.privilegeWithdrawn));
+ RC_MAPPING.put(
+ "aACompromise",
+ new Integer(iaik.asn1.structures.DistributionPoint.aACompromise));
+ }
+
+ /** The distribution point URI. */
+ private String uri;
+ /** The reason codes applicable for the distribution point. */
+ private int reasonCodes;
+
+ /**
+ * Create a <code>DistributionPoint</code> with a URI and a list of reason
+ * codes.
+ *
+ * @param uri The URI of the distribution point.
+ * @param reasonCodeStr A list of reason codes (a space-separated
+ * enumeration).
+ */
+ public DistributionPoint(String uri, String reasonCodeStr) {
+ this.uri = uri;
+ this.reasonCodes = extractReasonCodes(reasonCodeStr);
+ }
+
+ /**
+ * Convert a list of reason codes provided as a <code>String</code> to a
+ * binary representation.
+ *
+ * @param reasonCodeStr A <code>String</code> containing a blank-separated,
+ * textual representation of reason codes.
+ * @return int A binary representation of reason codes.
+ * @see iaik.asn1.structures.DistributionPoint
+ */
+ private int extractReasonCodes(String reasonCodeStr) {
+ int codes = 0;
+ StringTokenizer tokenizer = new StringTokenizer(reasonCodeStr);
+ String token;
+ Integer reasonCode;
+
+ while (tokenizer.hasMoreTokens()) {
+ token = tokenizer.nextToken();
+ reasonCode = (Integer) RC_MAPPING.get(token);
+ if (reasonCode != null) {
+ codes |= reasonCode.intValue();
+ } else {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.warn(
+ new LogMsg(msg.getMessage("config.07", new Object[] { token })));
+ }
+ }
+
+ return codes;
+ }
+
+ /**
+ * Return the URI of the distribution point.
+ *
+ * @return The URI of the distribution point.
+ */
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * Return a binary representation of the reason codes of this distribution
+ * point.
+ *
+ * @return The binary representation of the reason codes.
+ */
+ public int getReasonCodes() {
+ return reasonCodes;
+ }
+
+ /**
+ * Return a <code>String</code> representation of this distribution point.
+ *
+ * @return The <code>String</code> representation of this distribution point.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "(DistributionPoint - "
+ + ("URI<" + getUri())
+ + ("> REASONCODES<" + getReasonCodes() + ">)");
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java
new file mode 100644
index 000000000..62e8d63a6
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareCryptoModule.java
@@ -0,0 +1,60 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+/**
+ * Contains configuration data for a hardware crypto module.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class HardwareCryptoModule {
+ /** The name of the module. */
+ private String name;
+ /** The slod ID of the module. */
+ private String slotID;
+ /** The user PIN of the module. */
+ private String userPIN;
+
+ /**
+ * Create a new <code>HardwareCryptoModule</code>.
+ *
+ * @param name The name of this <code>HardwareCryptoModule</code>.
+ * @param slotID The slot ID of this <code>HardwareCryptoModule</code>.
+ * @param userPIN The user PIN to access this
+ * <code>HardwareCryptoModule</code>.
+ */
+ public HardwareCryptoModule(String name, String slotID, String userPIN) {
+ this.name = name;
+ this.slotID = slotID;
+ this.userPIN = userPIN;
+ }
+
+ /**
+ * Returns the name of this <code>HardwareCryptoModule</code>.
+ *
+ * @return The name of this <code>HardwareCryptoModule</code>.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the slot ID of this <code>HardwareCryptoModule</code>.
+ *
+ * @return The slot ID.
+ */
+ public String getSlotID() {
+ return slotID;
+ }
+
+
+ /**
+ * Returns the user PIN of this <code>HardwareCryptoModule</code>.
+ *
+ * @return The user PIN used to access the module.
+ */
+ public String getUserPIN() {
+ return userPIN;
+ }
+
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java
new file mode 100644
index 000000000..622c8d110
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/HardwareKeyModule.java
@@ -0,0 +1,59 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+/**
+ * A class that contains information about a hardware key module.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class HardwareKeyModule extends KeyModule {
+ /** The name of the module. */
+ private String name;
+ /** The slod ID of the module. */
+ private String slotID;
+ /** The user PIN of the module. */
+ private String userPIN;
+
+ /**
+ * Create a new <code>HardwareKey</code>.
+ *
+ * @param id The key module ID.
+ * @param name The name of the key.
+ * @param slotID The slot ID of the key within the hardware module. May be
+ * <code>null</code>.
+ * @param userPIN The user PIN to access the key.
+ */
+ public HardwareKeyModule(String id, String name, String slotID, String userPIN) {
+ super(id);
+ this.name = name;
+ this.slotID = slotID;
+ this.userPIN = userPIN;
+ }
+
+ /**
+ * Return the name of this <code>HardwareKey</code>.
+ *
+ * @return The name of this <code>HardwareKey</code>.
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Return the slot ID of this <code>HardwareKey</code>.
+ *
+ * @return The slot ID of this <code>HardwareKey</code>.
+ */
+ public String getSlotID() {
+ return slotID;
+ }
+
+ /**
+ * Return the user PIN to access this <code>HardwareKey</code>.
+ *
+ * @return The user PIN to access this <code>HardwareKey</code>.
+ */
+ public String getUserPIN() {
+ return userPIN;
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java
new file mode 100644
index 000000000..9d9262785
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/IssuerAndSerial.java
@@ -0,0 +1,115 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+import java.math.BigInteger;
+import java.security.Principal;
+
+import iaik.asn1.structures.Name;
+import iaik.utils.RFC2253NameParser;
+import iaik.utils.RFC2253NameParserException;
+
+/**
+ * A class containing the issuer and serial number of a certificate, which can
+ * be used to uniquely identify the certificate.
+ *
+ * The issuer is contained as an RFC2253 encoded <code>String</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class IssuerAndSerial {
+
+ /** The issuer distinguished name. */
+ private String issuerDN;
+ /** The certificate serial number. */
+ private BigInteger serial;
+
+ /**
+ * Create an <code>IssuerAndSerial</code> object.
+ *
+ * The name of the issuer is converted to RFC2253. If it cannot be parsed, the
+ * DN contained in the <code>issuer</code> is set.
+ *
+ * @param issuer The isser of a certificate.
+ * @param serial The serial number of the certificate.
+ */
+ public IssuerAndSerial(Principal issuer, BigInteger serial) {
+ RFC2253NameParser parser = new RFC2253NameParser(issuer.getName());
+
+ try {
+ this.issuerDN = ((Name) parser.parse()).getRFC2253String();
+ } catch (RFC2253NameParserException e) {
+ this.issuerDN = issuer.getName();
+ }
+ this.serial = serial;
+ }
+
+ /**
+ * Create an <code>IssuerAndSerial</code> object.
+ *
+ * @param issuerDN The issuer distinguished name. Should be an RFC2253 name.
+ * @param serial The serial number of the certificate.
+ */
+ public IssuerAndSerial(String issuerDN, BigInteger serial) {
+ this.issuerDN = issuerDN;
+ this.serial = serial;
+ }
+
+ /**
+ * Return the issuer DN in RFC2253 format.
+ *
+ * @return The issuer part of this object.
+ */
+ public String getIssuerDN() {
+ return issuerDN;
+ }
+
+ /**
+ * Return the serial number.
+ *
+ * @return The serial number of this object.
+ */
+ public BigInteger getSerial() {
+ return serial;
+ }
+
+ /**
+ * Compare this <code>IssuerAndSerial</code> to another object.
+ *
+ * @param other The object to compare this <code>IssuerAndSerial</code> to.
+ * @return <code>true</code>, if <code>other</code> is an
+ * <code>IssuerAndSerial</code> object and the <code>issuer</code> and
+ * <code>serial</code> fields are both equal. <code>false</code> otherwise.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof IssuerAndSerial) {
+ IssuerAndSerial ias = (IssuerAndSerial) other;
+ return getIssuerDN().equals(ias.getIssuerDN())
+ && getSerial().equals(ias.getSerial());
+ }
+ return false;
+ }
+
+ /**
+ * Return the hash code of this <code>IssuerAndSerial</code>.
+ *
+ * @return The hash code of this <code>IssuerAndSerial</code>.
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return issuerDN.hashCode() ^ serial.hashCode();
+ }
+
+ /**
+ * Return a <code>String</code> representation of this
+ * <code>IssuerAndSerial</code> object.
+ *
+ * @return The <code>String</code> representation.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return ("(IssuerAndSerial - Issuer<" + getIssuerDN())
+ + ("> Serial<" + serial.toString() + ">)");
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java
new file mode 100644
index 000000000..5fd108e1a
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroup.java
@@ -0,0 +1,69 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * A collection of <code>KeyGroupEntry</code>s with its own ID.
+ *
+ * @author Sven Aigner
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class KeyGroup {
+
+ /** The keys belonging to this key group. */
+ private Set keyGroupEntries;
+ /** The key group ID. */
+ private String id;
+
+ /**
+ * Create a <code>KeyGroup</code>.
+ *
+ * @param id The ID of this <code>KeyGroup</code>.
+ * @param keyGroupEntries The keys belonging to this <code>KeyGroup</code>.
+ */
+ public KeyGroup(String id, Set keyGroupEntries) {
+ this.id = id;
+ this.keyGroupEntries = keyGroupEntries;
+ }
+
+ /**
+ * Return the <code>KeyEntry</code>s contained in this <code>KeyGroup</code>.
+ *
+ * @return The <code>KeyEntry</code>s contained in this <code>KeyGroup</code>.
+ */
+ public Set getKeyGroupEntries() {
+ return keyGroupEntries;
+ }
+
+ /**
+ * Return the ID of this <code>KeyGroup</code>.
+ *
+ * @return The <code>KeyGroup</code> ID.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Return a <code>String</code> representation of this <code>KeyGroup</code>.
+ *
+ * @return The <code>String</code> representation.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ Iterator i;
+
+ if (getKeyGroupEntries() != null) {
+ i = getKeyGroupEntries().iterator();
+
+ while (i.hasNext()) {
+ sb.append(" " + i.next());
+ }
+ }
+ return "(KeyGroup - ID:" + id + " " + sb.toString() + ")";
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java
new file mode 100644
index 000000000..2e39d6aa3
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyGroupEntry.java
@@ -0,0 +1,106 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+import java.math.BigInteger;
+
+/**
+ * A class containing information about an entry in a key group.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class KeyGroupEntry {
+ /** The module ID of the key. */
+ private String moduleID;
+ /** The issuer DN of the certificate identifying the key. */
+ private String issuerDN;
+ /** The serial number of the certificate identifying the key. */
+ private BigInteger serialNumber;
+
+ /**
+ * Create a new <code>KeyGroupEntry</code>.
+ *
+ * @param moduleID The key module ID to which this entry belongs to.
+ * @param issuerAndSerial The issuer and serial number which uniquely
+ * identifies a certificate within the key module.
+ */
+ public KeyGroupEntry(String moduleID, IssuerAndSerial issuerAndSerial) {
+ this.moduleID = moduleID;
+ this.issuerDN = issuerAndSerial.getIssuerDN();
+ this.serialNumber = issuerAndSerial.getSerial();
+ }
+
+ /**
+ * Create a new <code>KeyGroupEntry</code>.
+ *
+ * @param moduleID The key module ID to which this entry belongs to.
+ * @param issuerDN The isser DN of the certificate within the key module.
+ * @param serialNumber The serial number of the certificate within the key
+ * module.
+ */
+ public KeyGroupEntry(
+ String moduleID,
+ String issuerDN,
+ BigInteger serialNumber) {
+ this.moduleID = moduleID;
+ this.issuerDN = issuerDN;
+ this.serialNumber = serialNumber;
+ }
+
+ /**
+ * Return the key module ID to which this <code>KeyGroupEntry</code> belongs
+ * to.
+ *
+ * @return The key module ID.
+ */
+ public String getModuleID() {
+ return moduleID;
+ }
+
+ /**
+ * Return the issuer DN of this <code>KeyGroupEntry</code> for identifying the
+ * certificate within the key module.
+ *
+ * @return The issuer DN of the certificate.
+ */
+ public String getIssuerDN() {
+ return issuerDN;
+ }
+
+ /**
+ * Return the serial number of this <code>KeyGroupEntry</code> for identifying
+ * the certificate within the key module.
+ *
+ * @return The serial number of the certificate.
+ */
+ public BigInteger getSerialNumber() {
+ return serialNumber;
+ }
+
+ /**
+ * Compare this <code>KeyGroupEntry</code> to another.
+ *
+ * @param other The <code>KeyGroupEntry</code> to compare to.
+ * @return <code>true</code>, if module ID, isser DN and serial number of
+ * <code>other</code> match the ones contained in this object, otherwise
+ * <code>false</code>.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof KeyGroupEntry) {
+ KeyGroupEntry entry = (KeyGroupEntry) other;
+ return getModuleID().equals(entry.getModuleID())
+ && getIssuerDN().equals(entry.getIssuerDN())
+ && getSerialNumber().equals(entry.getSerialNumber());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return getModuleID().hashCode()
+ ^ getIssuerDN().hashCode()
+ ^ getSerialNumber().hashCode();
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java
new file mode 100644
index 000000000..412516d82
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/KeyModule.java
@@ -0,0 +1,41 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+/**
+ * A class that contains information about a key module.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class KeyModule {
+
+ /** The key module ID. */
+ private String id;
+
+ /**
+ * Create a <code>Key</code> object.
+ *
+ * @param id The key module ID.
+ */
+ public KeyModule(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Return the key ID.
+ *
+ * @return The key ID.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Return a <code>String</code> representation of this <code>Key</code>.
+ *
+ * @return The <code>String</code> representation.
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return "(Key - Id<" + id + ">)";
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java
new file mode 100644
index 000000000..479e98ca5
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/SoftwareKeyModule.java
@@ -0,0 +1,48 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+/**
+ * A class containing information about a software key, stored in PKCS12 format.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SoftwareKeyModule extends KeyModule {
+ /** The name of the file containing the keys. */
+ private String fileName;
+ /** The password for accessing the file. */
+ private String passWord;
+
+ /**
+ * Create a new <code>SoftwareKey</code>.
+ *
+ * @param id The key ID.
+ * @param fileName The name of the PKCS12 keystore file containing the key.
+ * @param passWord The password to access the keystore file.
+ */
+ public SoftwareKeyModule(String id, String fileName, String passWord) {
+ super(id);
+ this.fileName = fileName;
+ this.passWord = passWord;
+ }
+
+ /**
+ * Return the name of the PKCS12 keystore file containing this
+ * <code>SoftwareKey</code>.
+ *
+ * @return The name of the PKCS12 keystore file.
+ */
+ public String getFileName() {
+ return fileName;
+ }
+
+ /**
+ * Return the password to access the keystore file.
+ *
+ * @return The password to access the keystore file.
+ */
+ public String getPassWord() {
+ return passWord;
+ }
+
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java b/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java
new file mode 100644
index 000000000..6ba33be63
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/config/TrustProfile.java
@@ -0,0 +1,43 @@
+package at.gv.egovernment.moa.spss.server.config;
+
+/**
+ * Information about a trust profile.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class TrustProfile {
+ /** The ID of the trust profile. */
+ private String id;
+ /** The URI giving the location of the trust profile. */
+ private String uri;
+
+ /**
+ * Create a <code>TrustProfile</code>.
+ *
+ * @param id The ID of the <code>TrustProfile</code> to create.
+ * @param uri The URI of the <code>TrustProfile</code> to create.
+ */
+ public TrustProfile(String id, String uri) {
+ this.id = id;
+ this.uri = uri;
+ }
+
+ /**
+ * Return the ID of this <code>TrustProfile</code>.
+ *
+ * @return The <code>TrustProfile</code> ID.
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Return the URI of this <code>TrustProfile</code>.
+ *
+ * @return The URI of <code>TrustProfile</code>.
+ */
+ public String getUri() {
+ return uri;
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java
new file mode 100644
index 000000000..eaee58d3f
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/cmsverify/CMSSignatureVerificationProfileImpl.java
@@ -0,0 +1,37 @@
+package at.gv.egovernment.moa.spss.server.iaik.cmsverify;
+
+import iaik.pki.PKIProfile;
+import iaik.server.modules.cmsverify.CMSSignatureVerificationProfile;
+
+/**
+ * An implementation of the <code>CMSSignatureVerificationProfile</code>
+ * interface.
+ *
+ * @see iaik.server.modules.cmsverify.CMSSignatureVerificationProfile
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CMSSignatureVerificationProfileImpl
+ implements CMSSignatureVerificationProfile {
+
+ /** The profile for validating the certificate. */
+ private PKIProfile certificateValidationProfile;
+
+ /**
+ * @see iaik.server.modules.cmsverify.CMSSignatureVerificationProfile#getCertificateValidationProfile()
+ */
+ public PKIProfile getCertificateValidationProfile() {
+ return certificateValidationProfile;
+ }
+
+ /**
+ * Sets the profile for validating the signer certificate.
+ *
+ * @param certificateValidationProfile The certificate validation profile to
+ * set.
+ */
+ public void setCertificateValidationProfile(PKIProfile certificateValidationProfile) {
+ this.certificateValidationProfile = certificateValidationProfile;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java
new file mode 100644
index 000000000..713891714
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractKeyModuleConfigurationImpl.java
@@ -0,0 +1,36 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.server.modules.keys.KeyModuleConfiguration;
+
+/**
+ * Base implementation class for the <code>KeyModuleConfiguration</code>
+ * interface and the interfaces derived from it.
+ *
+ * @see iaik.server.modules.keys.KeyModuleConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public abstract class AbstractKeyModuleConfigurationImpl
+ implements KeyModuleConfiguration {
+
+ /** The module ID. */
+ private String moduleID;
+
+ /**
+ * Creata new <code>AbstractKeyModuleConfigurationImpl</code>.
+ *
+ * @param moduleID The key module ID of this
+ * <code>KeyModuleConfiguration</code>.
+ */
+ public AbstractKeyModuleConfigurationImpl(String moduleID) {
+ this.moduleID = moduleID;
+ }
+
+ /**
+ * @see iaik.server.modules.keys.KeyModuleConfiguration#getModuleID()
+ */
+ public String getModuleID() {
+ return moduleID;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java
new file mode 100644
index 000000000..ac4286701
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/AbstractObservableConfiguration.java
@@ -0,0 +1,48 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import iaik.servertools.observer.NotificationData;
+import iaik.servertools.observer.Observable;
+import iaik.servertools.observer.Observer;
+
+/**
+ * A base class for observable configuration data.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public abstract class AbstractObservableConfiguration implements Observable {
+
+ /** The observers registered with this <code>Observable</code>. */
+ private List observers = new ArrayList();
+
+ /**
+ * @see iaik.utils.observer.Observable#addObserver(iaik.utils.observer.Observer)
+ */
+ public void addObserver(Observer observer) {
+ observers.add(observer);
+ }
+
+ /**
+ * @see iaik.utils.observer.Observable#removeObserver(iaik.utils.observer.Observer)
+ */
+ public boolean removeObserver(Observer observer) {
+ return observers.remove(observer);
+ }
+
+ /**
+ * @see iaik.utils.observer.Observable#notify(iaik.utils.observer.NotificationData)
+ */
+ public void notify(NotificationData data) {
+ Iterator iter = observers.iterator();
+
+ for (iter = observers.iterator(); iter.hasNext();) {
+ Observer observer = (Observer) iter.next();
+ observer.notify(data);
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java
new file mode 100644
index 000000000..22d798bc3
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ArchiveConfigurationImpl.java
@@ -0,0 +1,62 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.pki.store.revocation.archive.ArchiveConfiguration;
+import iaik.pki.store.revocation.archive.ArchiveParameter;
+import iaik.pki.store.revocation.archive.ArchiveTypes;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * An implementation of the <code>ArchiveConfiguration</code> interface
+ * using configuration data provided by the MOA configuration file.
+ *
+ * @see iaik.pki.store.revocation.archive.ArchiveConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ArchiveConfigurationImpl
+ extends AbstractObservableConfiguration
+ implements ArchiveConfiguration {
+
+ /** The configuration parameters of the archive. */
+ private ArchiveParameter archiveParameters;
+
+ /**
+ * Create a new <code>ArchiveConfigurationImpl</code>.
+ *
+ * @param config The MOA configuration from which the configuration data is
+ * being read.
+ */
+ public ArchiveConfigurationImpl(ConfigurationProvider config) {
+ String jdbcUrl =
+ config.getGenericConfiguration(
+ ConfigurationProvider.DATABASE_ARCHIVE_PARAMETER_PROPERTY);
+
+ if (jdbcUrl != null) {
+ this.archiveParameters = new DataBaseArchiveParameterImpl(jdbcUrl);
+ }
+ }
+
+ /**
+ * Return the type of archive.
+ *
+ * This will always return <code>ArchiveTypes.DATABASE</code>.
+ * @return <code>ArchiveTypes.DATABASE</code>.
+ * @see iaik.pki.store.revocation.archive.ArchiveConfiguration#getType()
+ */
+ public String getType() {
+ return ArchiveTypes.DATABASE;
+ }
+
+ /**
+ * Return the <code>ArchiveParameters</code> describing this
+ * <code>ArchiveConfiguration</code>.
+ *
+ * @return The archive parameters.
+ * @see iaik.pki.store.revocation.archive.ArchiveConfiguration#getArchiveParameters()
+ */
+ public ArchiveParameter getArchiveParameters() {
+ return archiveParameters;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java
new file mode 100644
index 000000000..1c2df80a5
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CRLDistributionPointAdapter.java
@@ -0,0 +1,54 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.pki.revocation.CRLDistributionPoint;
+import iaik.pki.revocation.RevocationSourceTypes;
+
+import at.gv.egovernment.moa.spss.server.config.DistributionPoint;
+
+/**
+ * A class that wraps an
+ * at.gv.egovernment.moa.spss.server.config.DistributionPoint as a
+ * iaik.pki.revocation.CRLDistributionPoint.
+ *
+ * @see iaik.pki.revocation.CRLDistributionPoint
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CRLDistributionPointAdapter implements CRLDistributionPoint {
+
+ /** The wrapped <code>DistributionPoint</code>. */
+ private DistributionPoint distributionPoint;
+
+ /**
+ * Create a new <code>CRLDistributionPointAdapter</code>.
+ *
+ * @param distributionPoint The <code>DistributionPoint</code> to wrap. It
+ * contains the data configured in the MOA configuration.
+ */
+ public CRLDistributionPointAdapter(DistributionPoint distributionPoint) {
+ this.distributionPoint = distributionPoint;
+ }
+
+ /**
+ * @see iaik.pki.revocation.CRLDistributionPoint#getReasonCodes()
+ */
+ public int getReasonCodes() {
+ return distributionPoint.getReasonCodes();
+ }
+
+ /**
+ * @return <code>RevocationSourceTypes.CRL</code>
+ * @see iaik.pki.revocation.DistributionPoint#getType()
+ */
+ public String getType() {
+ return RevocationSourceTypes.CRL;
+ }
+
+ /**
+ * @see iaik.pki.revocation.DistributionPoint#getUri()
+ */
+ public String getUri() {
+ return distributionPoint.getUri();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java
new file mode 100644
index 000000000..c9be3fc2b
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/CertStoreConfigurationImpl.java
@@ -0,0 +1,54 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.pki.store.certstore.CertStoreConfiguration;
+import iaik.pki.store.certstore.CertStoreParameters;
+import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * An implementation of the <code>CertStoreConfiguration</code> interface based
+ * on MOA configuration data.
+ *
+ * @see iaik.pki.store.certstore.CertStoreConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CertStoreConfigurationImpl
+ extends AbstractObservableConfiguration
+ implements CertStoreConfiguration {
+
+ /** The configuration parameters of the <code>CertStore</code>. */
+ private CertStoreParameters[] parameters;
+
+ /**
+ * Create a new <code>CertStoreConfigurationImpl</code>.
+ *
+ * @param config The MOA configuration from which the configuration data is
+ * being read.
+ */
+ public CertStoreConfigurationImpl(ConfigurationProvider config) {
+ String certStoreRoot =
+ config.getGenericConfiguration(
+ ConfigurationProvider.DIRECTORY_CERTSTORE_PARAMETER_PROPERTY,
+ "certstore");
+
+ if (certStoreRoot != null) {
+ DirectoryCertStoreParameters dirParameters =
+ new DirectoryCertStoreParametersImpl(
+ "MOA Directory CertStore",
+ certStoreRoot,
+ true,
+ false);
+ parameters = new CertStoreParameters[] { dirParameters };
+ }
+ }
+
+ /**
+ * @see iaik.pki.store.certstore.CertStoreConfiguration#getParameters()
+ */
+ public CertStoreParameters[] getParameters() {
+ return parameters;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java
new file mode 100644
index 000000000..7aa4cbe4b
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ConfigurationDataImpl.java
@@ -0,0 +1,121 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import iaik.logging.LoggerConfig;
+import iaik.pki.PKIConfiguration;
+import iaik.server.ConfigurationData;
+
+import at.gv.egovernment.moa.spss.server.config.HardwareCryptoModule;
+import at.gv.egovernment.moa.spss.server.config.HardwareKeyModule;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.config.SoftwareKeyModule;
+
+/**
+ * An implementation of the <code>ConfigurationData</code> interface using
+ * MOA configuration data.
+ *
+ * @see iaik.server.ConfigurationData
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ConfigurationDataImpl implements ConfigurationData {
+ /** PKI configuration data. */
+ private PKIConfiguration pkiConfiguration;
+ /** Crypto modules configuration data. */
+ private List cryptoModuleConfigurations;
+ /** Key modules configuration data. */
+ private List keyModuleConfigurations;
+ /** Logging configuration data. */
+ private LoggerConfig loggerConfig;
+
+ /**
+ * Create a new <code>ConfigurationDataImpl</code>.
+ *
+ * @param config The underlying MOA configuration data.
+ */
+ public ConfigurationDataImpl(ConfigurationProvider config) {
+ this.pkiConfiguration = new PKIConfigurationImpl(config);
+ this.cryptoModuleConfigurations = buildCryptoModuleConfigurations(config);
+ this.keyModuleConfigurations = buildKeyModuleConfigurations(config);
+ this.loggerConfig = new LoggerConfigImpl();
+ }
+
+ /**
+ * Build the list of <code>CryptoModuleConfiguration</code>s.
+ *
+ * @param config The underlying MOA configuration data.
+ * @return The list of <code>CryptoModuleConfiguration</code>s configured in
+ * the MOA configuration.
+ */
+ private List buildCryptoModuleConfigurations(ConfigurationProvider config) {
+ List modules = new ArrayList();
+ Iterator iter = config.getHardwareCryptoModules().iterator();
+
+ while (iter.hasNext()) {
+ HardwareCryptoModule module = (HardwareCryptoModule) iter.next();
+ modules.add(new HardwareCryptoModuleConfigurationImpl(module));
+ }
+
+ return modules;
+ }
+
+ /**
+ * Build the list of <code>KeyModuleConfiguration</code>s.
+ *
+ * @param config The underlying MOA configuration data.
+ * @return The list of <code>KeyModuleConfiguration</code>s configured in the
+ * MOA configuration.
+ */
+ private List buildKeyModuleConfigurations(ConfigurationProvider config) {
+ List keys = new ArrayList();
+ Iterator iter;
+
+ // add the hardware keys
+ iter = config.getHardwareKeyModules().iterator();
+ while (iter.hasNext()) {
+ HardwareKeyModule key = (HardwareKeyModule) iter.next();
+ keys.add(new HardwareKeyModuleConfigurationImpl(key));
+ }
+
+ // add the software keys
+ iter = config.getSoftwareKeyModules().iterator();
+ while (iter.hasNext()) {
+ SoftwareKeyModule key = (SoftwareKeyModule) iter.next();
+ keys.add(new SoftwareKeyModuleConfigurationImpl(key));
+ }
+
+ return keys;
+ }
+
+ /**
+ * @see iaik.server.ConfigurationData#getPKIConfiguration()
+ */
+ public PKIConfiguration getPKIConfiguration() {
+ return pkiConfiguration;
+ }
+
+ /**
+ * @see iaik.server.ConfigurationData#getCryptoModuleConfigurations()
+ */
+ public List getCryptoModuleConfigurations() {
+ return cryptoModuleConfigurations;
+ }
+
+ /**
+ * @see iaik.server.ConfigurationData#getKeyModuleConfigurations()
+ */
+ public List getKeyModuleConfigurations() {
+ return keyModuleConfigurations;
+ }
+
+ /**
+ * @see iaik.server.ConfigurationData#getLoggerConfig()
+ */
+ public LoggerConfig getLoggerConfig() {
+ return loggerConfig;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java
new file mode 100644
index 000000000..d67523944
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DataBaseArchiveParameterImpl.java
@@ -0,0 +1,33 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.pki.store.revocation.archive.db.DataBaseArchiveParameter;
+
+/**
+ * An implementation of the <code>DataBaseArchiveParameter</code> interface.
+ *
+ * @see iaik.pki.store.revocation.archive.db.DataBaseArchiveParameter
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class DataBaseArchiveParameterImpl implements DataBaseArchiveParameter {
+
+ /** The JDBC URL for accessing the archive. */
+ private String jDBCUrl;
+
+ /**
+ * Create a new <code>DataBaseArchiveParameterImpl</code>.
+ *
+ * @param jDBCUrl The JDBC URL of the archive.
+ */
+ public DataBaseArchiveParameterImpl(String jDBCUrl) {
+ this.jDBCUrl = jDBCUrl;
+ }
+
+ /**
+ * @see iaik.pki.store.revocation.archive.db.DataBaseArchiveParameter#getJDBCUrl()
+ */
+ public String getJDBCUrl() {
+ return jDBCUrl;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java
new file mode 100644
index 000000000..2b00d6766
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/DirectoryCertStoreParametersImpl.java
@@ -0,0 +1,81 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.pki.store.certstore.CertStoreTypes;
+import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters;
+
+/**
+ * An implementation of the <code>DirectoryCertStoreParameters</code> interface.
+ *
+ * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class DirectoryCertStoreParametersImpl
+ implements DirectoryCertStoreParameters {
+
+ /** The root directory of the <code>CertStore</code>. */
+ private String rootDirectory;
+ /** Whether a new directory may be created. */
+ private boolean createNew;
+ /** The <code>CertStore</code> ID. */
+ private String id;
+ /** Whether the <code>CertStore</code> is read-only. */
+ private boolean readOnly;
+
+ /**
+ * Create a new <code>DirectoryCertStoreParameterImpl</code>.
+ *
+ * @param id The <code>CertStore</code> ID.
+ * @param rootDirectory The root directory of the <code>CertStore</code>.
+ * @param createNew Whether a new directory may be created.
+ * @param readOnly Whether the <code>CertStore</code> is read-only.
+ */
+ public DirectoryCertStoreParametersImpl(
+ String id,
+ String rootDirectory,
+ boolean createNew,
+ boolean readOnly) {
+
+ this.id = id;
+ this.rootDirectory = rootDirectory;
+ this.createNew = createNew;
+ this.readOnly = readOnly;
+ }
+
+ /**
+ * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#getRootDirectory()
+ */
+ public String getRootDirectory() {
+ return rootDirectory;
+ }
+
+ /**
+ * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#createNew()
+ */
+ public boolean createNew() {
+ return createNew;
+ }
+
+ /**
+ * @see iaik.pki.store.certstore.CertStoreParameters#getId()
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @see iaik.pki.store.certstore.CertStoreParameters#isReadOnly()
+ */
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ /**
+ * @return <code>CertStoreTypes.DIRECTORY</code>
+ * @see iaik.pki.store.certstore.CertStoreParameters#getType()
+ */
+ public String getType() {
+ return CertStoreTypes.DIRECTORY;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java
new file mode 100644
index 000000000..3c8f4c002
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareCryptoModuleConfigurationImpl.java
@@ -0,0 +1,51 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.server.modules.crypto.HardwareCryptoModuleConfiguration;
+
+import at.gv.egovernment.moa.spss.server.config.HardwareCryptoModule;
+
+/**
+ * An implementation of the <code>HardwareCryptoModuleConfiguration</code>
+ * wrapping a <code>HardwareCryptoModule</code> from the MOA configuration.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class HardwareCryptoModuleConfigurationImpl
+ implements HardwareCryptoModuleConfiguration {
+
+ /** The wrapped <code>HardwareCryptoModule</code>. */
+ private HardwareCryptoModule module;
+
+ /**
+ * Create a new <code>HardwareCryptoModuleConfigurationImpl</code>.
+ *
+ * @param module The <code>HardwareCryptoModule</code> from the underlying MOA
+ * configuration.
+ */
+ public HardwareCryptoModuleConfigurationImpl(HardwareCryptoModule module) {
+ this.module = module;
+ }
+
+ /**
+ * @see iaik.server.modules.crypto.HardwareCryptoModuleConfiguration#getModuleName()
+ */
+ public String getModuleName() {
+ return module.getName();
+ }
+
+ /**
+ * @see iaik.server.modules.crypto.HardwareCryptoModuleConfiguration#getSlotID()
+ */
+ public String getSlotID() {
+ return module.getSlotID();
+ }
+
+ /**
+ * @see iaik.server.modules.crypto.HardwareCryptoModuleConfiguration#getUserPIN()
+ */
+ public char[] getUserPIN() {
+ return module.getUserPIN().toCharArray();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java
new file mode 100644
index 000000000..d905588c6
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/HardwareKeyModuleConfigurationImpl.java
@@ -0,0 +1,55 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.server.modules.keys.HardwareKeyModuleConfiguration;
+
+import at.gv.egovernment.moa.spss.server.config.HardwareKeyModule;
+
+/**
+ * An implementation of the <code>HardwareKeyModuleConfiguration</code>
+ * interface wrapping a <code>HardwareKeyModule</code> from the MOA
+ * configuration.
+ *
+ * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class HardwareKeyModuleConfigurationImpl
+ extends AbstractKeyModuleConfigurationImpl
+ implements HardwareKeyModuleConfiguration {
+
+ /** The wrapped <code>HardwareKeyModule</code>. */
+ private HardwareKeyModule keyModule;
+
+ /**
+ * Create a new <code>HardwareKeyModuleConfigurationImpl</code>.
+ *
+ * @param keyModule The <code>HardwareKeyModule</code> from the underlying
+ * MOA configuration.
+ */
+ public HardwareKeyModuleConfigurationImpl(HardwareKeyModule keyModule) {
+ super(keyModule.getId());
+ this.keyModule = keyModule;
+ }
+
+ /**
+ * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration#getModuleName()
+ */
+ public String getModuleName() {
+ return keyModule.getName();
+ }
+
+ /**
+ * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration#getSlotID()
+ */
+ public String getSlotID() {
+ return keyModule.getSlotID();
+ }
+
+ /**
+ * @see iaik.server.modules.keys.HardwareKeyModuleConfiguration#getUserPIN()
+ */
+ public char[] getUserPIN() {
+ return keyModule.getUserPIN().toCharArray();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java
new file mode 100644
index 000000000..8bd410ac7
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/IaikConfigurator.java
@@ -0,0 +1,162 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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 at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+
+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.MessageProvider;
+
+/**
+ * A class responsible for configuring the IAIK MOA modules.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class IaikConfigurator {
+
+ /** The warnings encountered during configuration. */
+ private List warnings = new ArrayList();
+
+ /**
+ * Configure the IAIK MOA subsystem.
+ *
+ * @param moaConfig The underlying MOA configuration.
+ * @throws ConfigurationException An error occurred configuring the IAIK
+ * MOA subsystem.
+ */
+ public void configure(ConfigurationProvider moaConfig)
+ throws ConfigurationException {
+ ConfigurationData configData = new ConfigurationDataImpl(moaConfig);
+
+ warnings = new ArrayList();
+
+ try {
+ Configurator.init(configData, new TransactionId("IaikConfigurator"));
+ dumpKeyEntryIDs();
+ checkKeyGroupConfig(moaConfig);
+ TrustStoreFactory.reset();
+ } catch (iaik.server.ConfigurationException e) {
+ throw new ConfigurationException("config.08", null, e);
+ } catch (Throwable t) {
+ throw new ConfigurationException("config.08", null, t);
+ }
+ }
+
+ /**
+ * Return the warnings encountered during configuration.
+ *
+ * @return The warnings.
+ */
+ public List getWarnings() {
+ return warnings;
+ }
+
+ /**
+ * Dump all <code>KeyEntryID</code>s contained in the configured
+ * <code>KeyModule</code>s to the log file.
+ */
+ private void dumpKeyEntryIDs() {
+ MessageProvider msg = MessageProvider.getInstance();
+ KeyModule module = KeyModuleFactory.getInstance(new TransactionId("dump"));
+ Set keyEntryIds = module.getPrivateKeyEntryIDs();
+ Iterator iter;
+
+ for (iter = keyEntryIds.iterator(); iter.hasNext();) {
+ 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 void checkKeyGroupConfig(ConfigurationProvider moaConfig) {
+ Map keyGroups = moaConfig.getKeyGroups();
+ Iterator iter;
+
+ for (iter = keyGroups.values().iterator(); iter.hasNext();) {
+ KeyGroup keyGroup = (KeyGroup) iter.next();
+ Set keyGroupEntries = keyGroup.getKeyGroupEntries();
+ Iterator kgIter;
+
+ for (kgIter = keyGroupEntries.iterator(); kgIter.hasNext();) {
+ 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 <code>true</code>, if the <code>keyGroupEntry</code> could be
+ * resolved to a <code>KeyEntryID</code>; otherwise <code>false</code>.
+ */
+ private boolean findKeyEntryID(KeyGroupEntry keyGroupEntry) {
+ KeyModule module = KeyModuleFactory.getInstance(new TransactionId("check"));
+ Set keyEntryIDs = module.getPrivateKeyEntryIDs();
+ Iterator iter;
+
+ for (iter = keyEntryIDs.iterator(); iter.hasNext();) {
+ 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 void warn(String messageId, Object[] args) {
+ MessageProvider msg = MessageProvider.getInstance();
+ String txt = msg.getMessage(messageId, args);
+
+ Logger.warn(new LogMsg(txt));
+ warnings.add(txt);
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java
new file mode 100644
index 000000000..9679e8d18
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/LoggerConfigImpl.java
@@ -0,0 +1,34 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.util.Properties;
+
+import iaik.logging.LogConfigurationException;
+import iaik.logging.LoggerConfig;
+
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+
+/**
+ * Default implementation of the <code>LoggerConfig</code> interface.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class LoggerConfigImpl implements LoggerConfig {
+
+ /** The implementation of iaik.logging.LogFactory. */
+ private static final String DEFAULT_IMPLEMENTATION =
+ "at.gv.egovernment.moa.spss.server.logging.IaikLogFactory";
+
+ public String getFactory() {
+ return DEFAULT_IMPLEMENTATION;
+ }
+
+ public Properties getProperties() throws LogConfigurationException {
+ return new Properties();
+ }
+
+ public String getNodeId() {
+ return LoggingContextManager.getInstance().getLoggingContext().getNodeID();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java
new file mode 100644
index 000000000..0703cd326
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/PKIConfigurationImpl.java
@@ -0,0 +1,85 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import iaik.pki.PKIConfiguration;
+import iaik.pki.pathvalidation.ValidationConfiguration;
+import iaik.pki.revocation.RevocationConfiguration;
+import iaik.pki.store.certstore.CertStoreConfiguration;
+import iaik.pki.store.revocation.archive.ArchiveConfiguration;
+
+import at.gv.egovernment.moa.util.BoolUtils;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * An implementation of the <code>PKIConfiguration</code> interface using data
+ * from the MOA configuration.
+ *
+ * @see iaik.pki.PKIConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class PKIConfigurationImpl implements PKIConfiguration {
+ /** The <code>CertStore</code> configuration. */
+ private CertStoreConfiguration certStoreConfiguration;
+ /** The revocation checking configuration. */
+ private RevocationConfiguration revocationConfiguration;
+ /** The revocation archive configuration. */
+ private ArchiveConfiguration archiveConfiguration;
+ /** The certificate validation configuration. */
+ private ValidationConfiguration validationConfiguration;
+
+ /**
+ * Create a new <code>PKIConfigurationImpl</code>.
+ *
+ * @param config The underlying MOA configuration which will be used to build
+ * the configuration data contained in this object.
+ */
+ public PKIConfigurationImpl(ConfigurationProvider config) {
+ String archiveInfo;
+
+ this.certStoreConfiguration = new CertStoreConfigurationImpl(config);
+
+ this.revocationConfiguration = new RevocationConfigurationImpl(config);
+
+ archiveInfo =
+ config.getGenericConfiguration(
+ ConfigurationProvider.ARCHIVE_REVOCATION_INFO_PROPERTY,
+ "false");
+ if (archiveInfo != null && BoolUtils.valueOf(archiveInfo)) {
+ this.archiveConfiguration = new ArchiveConfigurationImpl(config);
+ } else {
+ this.archiveConfiguration = null;
+ }
+
+ this.validationConfiguration = new ValidationConfigurationImpl(config);
+ }
+
+ /**
+ * @see iaik.pki.PKIConfiguration#getCertStoreConfiguration()
+ */
+ public CertStoreConfiguration getCertStoreConfiguration() {
+ return certStoreConfiguration;
+ }
+
+ /**
+ * @see iaik.pki.PKIConfiguration#getRevocationConfiguration()
+ */
+ public RevocationConfiguration getRevocationConfiguration() {
+ return revocationConfiguration;
+ }
+
+ /**
+ * @see iaik.pki.PKIConfiguration#getArchiveConfiguration()
+ */
+ public ArchiveConfiguration getArchiveConfiguration() {
+ return archiveConfiguration;
+ }
+
+ /**
+ * @see iaik.pki.PKIConfiguration#getValidationConfiguration()
+ */
+ public ValidationConfiguration getValidationConfiguration() {
+ return validationConfiguration;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java
new file mode 100644
index 000000000..466234a11
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/RevocationConfigurationImpl.java
@@ -0,0 +1,73 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import iaik.pki.revocation.RevocationConfiguration;
+
+import at.gv.egovernment.moa.util.BoolUtils;
+
+import at.gv.egovernment.moa.spss.server.config.DistributionPoint;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * An implementation of the <code>RevocationConfiguration</code> interface using
+ * MOA configuration data.
+ *
+ * @see iaik.pki.revocation.RevocationConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class RevocationConfigurationImpl
+ extends AbstractObservableConfiguration
+ implements RevocationConfiguration {
+
+ /** The <code>ConfigurationProvider</code> to read the configuration data
+ * from. */
+ private ConfigurationProvider config;
+
+ /**
+ * Create a new <code>RevocationConfigurationImpl</code>.
+ *
+ * @param config The underlying MOA configuration containing the configuration
+ * data.
+ */
+ public RevocationConfigurationImpl(ConfigurationProvider config) {
+ this.config = config;
+ }
+
+ /**
+ * @see iaik.pki.revocation.RevocationConfiguration#getAlternativeDistributionPoints(java.security.cert.X509Certificate, java.util.Date)
+ */
+ public Set getAlternativeDistributionPoints(
+ X509Certificate cert,
+ Date date) {
+
+ Set configuredPoints = config.getCRLDP(cert);
+ Set distributionPoints = new HashSet();
+ Iterator iter;
+
+ for (iter = configuredPoints.iterator(); iter.hasNext();) {
+ DistributionPoint dp = (DistributionPoint) iter.next();
+ distributionPoints.add(new CRLDistributionPointAdapter(dp));
+ }
+
+ return distributionPoints;
+ }
+
+ /**
+ * @see iaik.pki.revocation.RevocationConfiguration#archiveRevocationInfo(java.lang.String, java.lang.String)
+ */
+ public boolean archiveRevocationInfo(String type, String uri) {
+ String info =
+ config.getGenericConfiguration(
+ ConfigurationProvider.ARCHIVE_REVOCATION_INFO_PROPERTY,
+ "false");
+
+ return info != null ? BoolUtils.valueOf(info) : false;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java
new file mode 100644
index 000000000..343f096ef
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/SoftwareKeyModuleConfigurationImpl.java
@@ -0,0 +1,75 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+import iaik.server.modules.keys.ConfigurationException;
+import iaik.server.modules.keys.SoftwareKeyModuleConfiguration;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+
+import at.gv.egovernment.moa.spss.server.config.SoftwareKeyModule;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * An implementation of the <code>SoftwareKeyModuleConfiguration</code> wrapping
+ * a <code>SoftwareKeyModule</code> from the MOA configuration.
+ *
+ * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SoftwareKeyModuleConfigurationImpl
+ extends AbstractKeyModuleConfigurationImpl
+ implements SoftwareKeyModuleConfiguration {
+
+ /** The wrapped <code>SoftwareKeyModule</code>. */
+ private SoftwareKeyModule keyModule;
+
+ /**
+ * Create a new <code>SoftwareKeyModuleConfigurationImpl</code>.
+ *
+ * @param keyModule The <code>SoftwareKeyModule</code> from the underlying MOA
+ * configuration.
+ */
+ public SoftwareKeyModuleConfigurationImpl(SoftwareKeyModule keyModule) {
+ super(keyModule.getId());
+ this.keyModule = keyModule;
+ }
+
+ /**
+ * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration#getKeyStoreTypeName()
+ */
+ public String getKeyStoreTypeName() {
+ return KEY_STORE_TYPE_NAME_PKCS12;
+ }
+
+ /**
+ * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration#getKeyStoreAsStream()
+ */
+ public InputStream getKeyStoreAsStream() {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ try {
+ String message =
+ msg.getMessage("config.18", new Object[] { keyModule.getFileName()});
+ Logger.info(new LogMsg(message));
+ return new FileInputStream(keyModule.getFileName());
+ } catch (FileNotFoundException e) {
+ String message =
+ msg.getMessage("config.09", new Object[] { keyModule.getFileName()});
+
+ throw new ConfigurationException(message, e, null);
+ }
+ }
+
+ /**
+ * @see iaik.server.modules.keys.SoftwareKeyModuleConfiguration#getKeyStoreAuthenticationData()
+ */
+ public char[] getKeyStoreAuthenticationData() {
+ return keyModule.getPassWord().toCharArray();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java
new file mode 100644
index 000000000..f6fbad215
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/config/ValidationConfigurationImpl.java
@@ -0,0 +1,56 @@
+package at.gv.egovernment.moa.spss.server.iaik.config;
+
+import java.security.cert.X509Certificate;
+import java.security.spec.AlgorithmParameterSpec;
+
+import iaik.pki.pathvalidation.ValidationConfiguration;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * An implementation of the <code>ValidationConfiguration</code> interface using
+ * MOA configuration data.
+ *
+ * @see iaik.pki.pathvalidation.ValidationConfiguration
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ValidationConfigurationImpl
+ extends AbstractObservableConfiguration
+ implements ValidationConfiguration {
+
+ /** The <code>ConfigurationProvider</code> to read the configuration data
+ * from. */
+ private ConfigurationProvider config;
+
+ /**
+ * Create a new <code>ValidationConfigurationImpl</code>.
+ *
+ * @param config The underlying MOA configuration data.
+ */
+ public ValidationConfigurationImpl(ConfigurationProvider config) {
+ this.config = config;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationConfiguration#getChainingMode(java.security.cert.X509Certificate)
+ */
+ public String getChainingMode(X509Certificate cert) {
+ return config.getChainingMode(cert);
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationConfiguration#getPublicKeyParamsAsSpec(java.security.cert.X509Certificate)
+ */
+ public AlgorithmParameterSpec getPublicKeyParamsAsSpec(X509Certificate cert) {
+ return null;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationConfiguration#getPublicKeyParamsAsCert(java.security.cert.X509Certificate)
+ */
+ public X509Certificate getPublicKeyParamsAsCert(X509Certificate cert) {
+ return null;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java
new file mode 100644
index 000000000..c204eface
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/PKIProfileImpl.java
@@ -0,0 +1,127 @@
+package at.gv.egovernment.moa.spss.server.iaik.pki;
+
+import iaik.pki.PKIProfile;
+import iaik.pki.pathvalidation.ValidationProfile;
+import iaik.pki.revocation.RevocationProfile;
+import iaik.pki.store.truststore.TrustStoreProfile;
+
+import at.gv.egovernment.moa.util.BoolUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.pki.pathvalidation.ValidationProfileImpl;
+import at.gv.egovernment.moa.spss.server.iaik.pki.revocation.RevocationProfileImpl;
+import at.gv.egovernment.moa.spss.server.iaik.pki.store.truststore.TrustStoreProfileImpl;
+
+/**
+ * Implementation of the <code>PKIProfile</code> interface containing
+ * information needed for certificate path validation. It uses configuration
+ * data from the MOA configuration.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class PKIProfileImpl implements PKIProfile {
+
+ /** Profile information for revocation checking. */
+ private RevocationProfile revocationProfile;
+ /** Profile information about the trust profile to use. */
+ private TrustStoreProfile trustStoreProfile;
+ /** Profile information about the certificate validation. */
+ private ValidationProfile validationProfile;
+ /** The <code>ConfigurationProvider</code> to read the MOA configuration data
+ * from. */
+ private ConfigurationProvider config;
+
+ /**
+ * Create a new <code>PKIProfileImpl</code>.
+ *
+ * @param config The MOA configuration providing configuration data about
+ * certificate path validation.
+ * @param trustProfileID The trust profile ID denoting the location of the
+ * trust store.
+ * @throws MOAApplicationException An error occurred building the profile.
+ */
+ public PKIProfileImpl(ConfigurationProvider config, String trustProfileID)
+ throws MOAApplicationException {
+
+ this.config = config;
+ setRevocationProfile(new RevocationProfileImpl(config));
+ setTrustStoreProfile(new TrustStoreProfileImpl(config, trustProfileID));
+ setValidationProfile(new ValidationProfileImpl(config));
+ }
+
+ /**
+ * @see iaik.pki.PKIProfile#autoAddCertificates()
+ */
+ public boolean autoAddCertificates() {
+ String boolStr =
+ config.getGenericConfiguration(
+ ConfigurationProvider.AUTO_ADD_CERTIFICATES_PROPERTY,
+ "true");
+ boolean boolValue = BoolUtils.valueOf(boolStr);
+
+ return useAuthorityInfoAccess() ? true : boolValue;
+ }
+
+ /**
+ * @see iaik.pki.PKIProfile#getRevocationProfile()
+ */
+ public RevocationProfile getRevocationProfile() {
+ return revocationProfile;
+ }
+
+ /**
+ * Sets the <code>RevocationProfile</code>.
+ *
+ * @param revocationProfile The <code>RevocationProfile</code> used for
+ * revocation checking.
+ */
+ protected void setRevocationProfile(RevocationProfile revocationProfile) {
+ this.revocationProfile = revocationProfile;
+ }
+
+ /**
+ * @see iaik.pki.PKIProfile#getTrustStoreProfile()
+ */
+ public TrustStoreProfile getTrustStoreProfile() {
+ return trustStoreProfile;
+ }
+
+ /**
+ * Sets the <code>TrustStoreProfile</code>.
+ *
+ * @param trustStoreProfile The <code>TrustStoreProfile</code>.
+ */
+ protected void setTrustStoreProfile(TrustStoreProfile trustStoreProfile) {
+ this.trustStoreProfile = trustStoreProfile;
+ }
+
+ /**
+ * @see iaik.pki.PKIProfile#getValidationProfile()
+ */
+ public ValidationProfile getValidationProfile() {
+ return validationProfile;
+ }
+
+ /**
+ * Sets the <code>ValidationProfile</code>.
+ *
+ * @param validationProfile The <code>ValidationProfile</code> to set.
+ */
+ protected void setValidationProfile(ValidationProfile validationProfile) {
+ this.validationProfile = validationProfile;
+ }
+
+ /**
+ * @see iaik.pki.PKIProfile#useAuthorityInfoAccess()
+ */
+ public boolean useAuthorityInfoAccess() {
+ String boolStr =
+ config.getGenericConfiguration(
+ ConfigurationProvider.USE_AUTHORITY_INFO_ACCESS_PROPERTY,
+ "true");
+ return BoolUtils.valueOf(boolStr);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java
new file mode 100644
index 000000000..3327b3a50
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/pathvalidation/ValidationProfileImpl.java
@@ -0,0 +1,113 @@
+package at.gv.egovernment.moa.spss.server.iaik.pki.pathvalidation;
+
+import iaik.pki.pathvalidation.ValidationProfile;
+
+import at.gv.egovernment.moa.util.BoolUtils;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * An implementation of the <code>ValidationProfile</code> interface providing
+ * information about certificat path validation.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ValidationProfileImpl implements ValidationProfile {
+
+ /** The <code>ConfigurationProvider</code> to read the configuration data
+ * from. */
+ private ConfigurationProvider config;
+ private boolean initialAnyPolicyInhibit;
+ private boolean initialExplicitPolicy;
+ private boolean initialPolicyMappingInhibit;
+ private Set initialPolicySet;
+ private boolean nameConstraintsProcessing;
+ private boolean policyProcessing;
+
+ /**
+ * Create a new <code>ValidationProfileImpl</code> object.
+ *
+ * This objects's fields are preset to the following values:
+ *
+ * <ul>
+ * <li><code>initialAnyPolicyInhibit = true</code></li>
+ * <li><code>initialExplicitPoliy = true</code></li>
+ * <li><code>initialPolicyMappingInhibit = true</code></li>
+ * <li><code>initialPolicySet = empty</code></li>
+ * <li><code>policyProcessing = false</code></li>
+ * <li><code>nameConstraintsProcessing = false</code></li>
+ * <li><code>revocationChecking = false</code></li>
+ * </ul>
+ *
+ * @param config MOA configuration data for additional configuration
+ * information (currently unused).
+ */
+ public ValidationProfileImpl(ConfigurationProvider config) {
+ this.config = config;
+ initialAnyPolicyInhibit = true;
+ initialExplicitPolicy = true;
+ initialPolicyMappingInhibit = true;
+ initialPolicySet = Collections.EMPTY_SET;
+ policyProcessing = false;
+ nameConstraintsProcessing = false;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getInitialAnyPolicyInhibit()
+ */
+ public boolean getInitialAnyPolicyInhibit() {
+ return initialAnyPolicyInhibit;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getInitialExplicitPolicy()
+ */
+ public boolean getInitialExplicitPolicy() {
+ return initialExplicitPolicy;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getInitialPolicyMappingInhibit()
+ */
+ public boolean getInitialPolicyMappingInhibit() {
+ return initialPolicyMappingInhibit;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getInitialPolicySet()
+ */
+ public Set getInitialPolicySet() {
+ return initialPolicySet;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getPolicyProcessing()
+ */
+ public boolean getPolicyProcessing() {
+ return policyProcessing;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getNameConstraintsProcessing()
+ */
+ public boolean getNameConstraintsProcessing() {
+ return nameConstraintsProcessing;
+ }
+
+ /**
+ * @see iaik.pki.pathvalidation.ValidationProfile#getRevocationChecking()
+ */
+ public boolean getRevocationChecking() {
+ String checkingStr =
+ config.getGenericConfiguration(
+ ConfigurationProvider.REVOCATION_CHECKING_PROPERTY,
+ "false");
+
+ return BoolUtils.valueOf(checkingStr);
+ }
+
+} \ No newline at end of file
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java
new file mode 100644
index 000000000..186d24934
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/revocation/RevocationProfileImpl.java
@@ -0,0 +1,65 @@
+package at.gv.egovernment.moa.spss.server.iaik.pki.revocation;
+
+import java.security.cert.X509Certificate;
+
+import iaik.pki.revocation.RevocationProfile;
+import iaik.pki.revocation.RevocationSourceTypes;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * An implementation of the <code>RevocationProfile</code> interface providing
+ * information about revocation status checking, based on MOA configuration
+ * data.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class RevocationProfileImpl implements RevocationProfile {
+ /** The default service order. */
+ private static final String[] DEFAULT_SERVICE_ORDER =
+ { RevocationSourceTypes.CRL };
+ /** The <code>ConfigurationProvider</code> to read the MOA configuration data
+ * from. */
+ private ConfigurationProvider config;
+ /** The OCSP request hash algorithm. */
+ private String oCSPRequestHashAlgorithm;
+
+ /**
+ * Create a new <code>RevocationProfileImpl</code>.
+ *
+ * @param config The MOA configuration data.
+ */
+ public RevocationProfileImpl(ConfigurationProvider config) {
+ this.config = config;
+ this.oCSPRequestHashAlgorithm = "";
+ }
+
+ /**
+ * @see iaik.pki.revocation.RevocationProfile#getMaxRevocationAge(String)
+ */
+ public long getMaxRevocationAge(String distributionPointUri) {
+ String maxRevocationAgeStr =
+ config.getGenericConfiguration(
+ ConfigurationProvider.MAX_REVOCATION_AGE_PROPERTY,
+ "0");
+ long revocationAge = Long.parseLong(maxRevocationAgeStr);
+
+ return revocationAge;
+ }
+
+ /**
+ * @see iaik.pki.revocation.RevocationProfile#getOCSPRequestHashAlgorithm()
+ */
+ public String getOCSPRequestHashAlgorithm() {
+ return oCSPRequestHashAlgorithm;
+ }
+
+ /**
+ * @see iaik.pki.revocation.RevocationProfile#getPreferredServiceOrder(java.security.cert.X509Certificate)
+ */
+ public String[] getPreferredServiceOrder(X509Certificate cert) {
+ return DEFAULT_SERVICE_ORDER;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java
new file mode 100644
index 000000000..8a1161b95
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/pki/store/truststore/TrustStoreProfileImpl.java
@@ -0,0 +1,119 @@
+package at.gv.egovernment.moa.spss.server.iaik.pki.store.truststore;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import iaik.pki.store.truststore.TrustStoreProfile;
+import iaik.pki.store.truststore.TrustStoreTypes;
+import iaik.servertools.observer.NotificationData;
+import iaik.servertools.observer.Observer;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.config.TrustProfile;
+
+/**
+ * An implementation of the <code>TrustStoreProfile</code> interface, using data
+ * from the MOA configuration.
+ *
+ * @see iaik.pki.store.truststore.TrustStoreProfile
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class TrustStoreProfileImpl implements TrustStoreProfile {
+
+ /** The observers of this profile. */
+ private List observers = new ArrayList();
+ /** The type of the trust profile. */
+ private String type;
+ /** The URI of the trust profile.*/
+ private String URI;
+
+ /**
+ * Create a new <code>TrustStoreProfileImpl</code>.
+ *
+ * @param config The MOA configuration data, from which trust store
+ * configuration data is read.
+ * @param trustProfileId The trust profile id on which this
+ * <code>TrustStoreProfile</code> is based.
+ * @throws MOAApplicationException The <code>trustProfileId</code> could not
+ * be found in the MOA configuration.
+ */
+ public TrustStoreProfileImpl(
+ ConfigurationProvider config,
+ String trustProfileId)
+ throws MOAApplicationException {
+
+ TrustProfile tp = (TrustProfile) config.getTrustProfile(trustProfileId);
+ if (tp != null) {
+ setURI(tp.getUri());
+ setType(TrustStoreTypes.DIRECTORY);
+ } else {
+ throw new MOAApplicationException(
+ "2203",
+ new Object[] { trustProfileId });
+ }
+ }
+
+ /**
+ * @see iaik.pki.store.truststore.TrustStoreProfile#getType()
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * Sets the the trust store type.
+ *
+ * @param type The trust store type to set.
+ */
+ protected void setType(String type) {
+ this.type = type;
+ }
+
+ /**
+ * @see iaik.pki.store.truststore.TrustStoreProfile#getURI()
+ */
+ public String getURI() {
+ return URI;
+ }
+
+ /**
+ * Sets the trust store URI.
+ *
+ * @param URI The trust store URI to set.
+ */
+ protected void setURI(String URI) {
+ this.URI = URI;
+ }
+
+ //
+ // Methods of iaik.utils.observer.Observable interface
+ //
+
+ /**
+ * @see iaik.utils.observer.Observable#addObserver(Observer)
+ */
+ public void addObserver(Observer observer) {
+ observers.add(observer);
+ }
+
+ /**
+ * @see iaik.utils.observer.Observable#removeObserver(Observer)
+ */
+ public boolean removeObserver(Observer observer) {
+ return observers.remove(observer);
+ }
+
+ /**
+ * @see iaik.utils.observer.Observable#notify(NotificationData)
+ */
+ public void notify(NotificationData notificationData) {
+ for (Iterator iter = observers.iterator(); iter.hasNext();) {
+ Observer observer = (Observer) iter.next();
+ observer.notify(notificationData);
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java
new file mode 100644
index 000000000..e076fe1eb
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/Base64TransformationImpl.java
@@ -0,0 +1,43 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import iaik.server.modules.xml.Base64Transformation;
+
+/**
+ * An implementation of the <code>Base64Transformation</code>
+ * <code>Transformation</code> type.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class Base64TransformationImpl
+ extends TransformationImpl
+ implements Base64Transformation {
+
+ /**
+ * Create a new <code>Base64TransformationImpl</code>.
+ *
+ * @see java.lang.Object#Object()
+ */
+ public Base64TransformationImpl() {
+ setAlgorithmURI(Base64Transformation.BASE64_DECODING);
+ }
+
+ /**
+ * Compare this <code>Base64Transformation</code> to another.
+ *
+ * @param other The object to compare this<code>Base64Transformation</code>
+ * to.
+ * @return <code>true</code>, if <code>other</code> is a
+ * <code>Base64Transformation</code> and the algorithm URIs match, otherwise
+ * <code>false</code>.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof Base64Transformation) {
+ Base64Transformation transform = (Base64Transformation) other;
+ return getAlgorithmURI().equals(transform.getAlgorithmURI());
+ }
+ return false;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java
new file mode 100644
index 000000000..921b10cb6
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteArrayDataObjectImpl.java
@@ -0,0 +1,54 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import iaik.server.modules.xml.BinaryDataObject;
+
+/**
+ * A <code>BinaryDataObject</code> encapsulating Base64 data.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ByteArrayDataObjectImpl
+ extends DataObjectImpl
+ implements BinaryDataObject {
+
+ /** The binary data contained in this <code>BinaryDataObject</code>. */
+ private byte[] bytes;
+
+ /**
+ * Create a new <code>ByteArrayDataObjectImpl</code>.
+ *
+ * @param bytes The binary data contained in this
+ * <code>BinaryDataObject</code>.
+ */
+ public ByteArrayDataObjectImpl(byte[] bytes) {
+ setBytes(bytes);
+ }
+
+ /**
+ * Set the Base64 data.
+ *
+ * @param bytes The binary data contained in this
+ * <code>BinaryDataObject</code>.
+ */
+ public void setBytes(byte[] bytes) {
+ this.bytes = bytes;
+ }
+
+ /**
+ * Return the binary data encoded in the Base64 <code>String</code> as a
+ * stream.
+ *
+ * @return The binary data contained in this object, as a
+ * <code>InputStream</code>. Repeated calls to this function will return a
+ * new stream to the Base64 data.
+ * @see iaik.server.modules.xml.BinaryDataObject#getInputStream()
+ */
+ public InputStream getInputStream() {
+ return new ByteArrayInputStream(bytes);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java
new file mode 100644
index 000000000..ce400e61a
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ByteStreamDataObjectImpl.java
@@ -0,0 +1,49 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.io.InputStream;
+
+import iaik.server.modules.xml.BinaryDataObject;
+
+/**
+ * A <code>BinaryDataObject</code> encapsulating binary data from a stream.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ByteStreamDataObjectImpl
+ extends DataObjectImpl
+ implements BinaryDataObject {
+
+ /** The <code>InputStream</code> containing the binary data. */
+ private InputStream inputStream;
+
+ /**
+ * Create a new <code>ByteStreamDataObjectImpl</code>.
+ *
+ * @param inputStream The stream from which to read the binary data.
+ */
+ public ByteStreamDataObjectImpl(InputStream inputStream) {
+ setInputStream(inputStream);
+ }
+
+ /**
+ * Set the input stream from which to read the binary data.
+ *
+ * @param inputStream The input stream from which to read the binary data.
+ */
+ public void setInputStream(InputStream inputStream) {
+ this.inputStream = inputStream;
+ }
+
+ /**
+ * Return the binary data from this object as a stream.
+ *
+ * @return The stream containing the binary data. Calling this function
+ * repeatedly will always return the same <code>InputStream</code>.
+ * @see iaik.server.modules.xml.BinaryDataObject#getInputStream()
+ */
+ public InputStream getInputStream() {
+ return inputStream;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java
new file mode 100644
index 000000000..a597b214d
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/CanonicalizationImpl.java
@@ -0,0 +1,43 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import iaik.server.modules.xml.Canonicalization;
+
+/**
+ * An implementation of the <code>CanonicalizationTransform</code>
+ * <code>Transformation</code> type.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CanonicalizationImpl
+ extends TransformationImpl
+ implements Canonicalization {
+
+ /**
+ * Create a new <code>CanonicalizationTransformImpl</code> object.
+ *
+ * @param algorithmURI The canonicalization algorithm URI.
+ */
+ public CanonicalizationImpl(String algorithmURI) {
+ setAlgorithmURI(algorithmURI);
+ }
+
+ /**
+ * Compare this object to another <code>Canonicalization</code>.
+ *
+ * @param other The object to compare this
+ * <code>Canonicalization</code> to.
+ * @return <code>true</code>, if <code>other</code> is a
+ * <code>Canonicalization</code> and the algorithm URIs match, otherwise
+ * <code>false</code>.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof Canonicalization) {
+ Canonicalization c14n = (Canonicalization) other;
+ return getAlgorithmURI().equals(c14n.getAlgorithmURI());
+ }
+ return false;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java
new file mode 100644
index 000000000..875d82613
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/DataObjectImpl.java
@@ -0,0 +1,87 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import iaik.server.modules.xml.DataObject;
+
+/**
+ * Abstract base implementation for the classes derived from
+ * <code>DataObject</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public abstract class DataObjectImpl implements DataObject {
+
+ /** The MIME type of the data object. */
+ private String mimeType;
+ /** The refernce ID. */
+ private String referenceID;
+ /** The URI of the type. */
+ private String typeURI;
+ /** The URI identifying the data. */
+ private String URI;
+
+ /**
+ * @see iaik.server.modules.xml.DataObject#getMimeType()
+ */
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ /**
+ * Set the mime type.
+ *
+ * @param mimeType The mime type to set.
+ */
+ public void setMimeType(String mimeType) {
+ this.mimeType = mimeType;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.DataObject#getReferenceID()
+ */
+ public String getReferenceID() {
+ return referenceID;
+ }
+
+ /**
+ * Set the reference ID.
+ *
+ * @param referenceID The reference ID.
+ */
+ public void setReferenceID(String referenceID) {
+ this.referenceID = referenceID;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.DataObject#getTypeURI()
+ */
+ public String getTypeURI() {
+ return typeURI;
+ }
+
+ /**
+ * Set the type URI.
+ *
+ * @param typeURI The type URI.
+ */
+ public void setTypeURI(String typeURI) {
+ this.typeURI = typeURI;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.DataObject#getURI()
+ */
+ public String getURI() {
+ return URI;
+ }
+
+ /**
+ * Set the URI.
+ *
+ * @param URI The URI.
+ */
+ public void setURI(String URI) {
+ this.URI = URI;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java
new file mode 100644
index 000000000..41a47d0a1
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/EnvelopedSignatureTransformationImpl.java
@@ -0,0 +1,42 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import iaik.server.modules.xml.EnvelopedSignatureTransformation;
+
+/**
+ * An implementation of the <code>EnvelopedSignatureTransformation</code>
+ * <code>Transformation</code> type.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class EnvelopedSignatureTransformationImpl
+ extends TransformationImpl
+ implements EnvelopedSignatureTransformation {
+
+ /**
+ * Create a new <code>EnvelopedSignatureTransformationImpl</code>.
+ */
+ public EnvelopedSignatureTransformationImpl() {
+ setAlgorithmURI(EnvelopedSignatureTransformation.ENVELOPED_SIGNATURE);
+ }
+
+ /**
+ * Compare this object to another <code>EnvelopedSignatureTransformation</code>.
+ *
+ * @param other The object to compare this
+ * <code>EnvelopedSignatureTransformation</code> to.
+ * @return <code>true</code>, if <code>other</code> is a
+ * <code>EnvelopedSignatureTransformation</code>, otherwise
+ * <code>false</code>.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof EnvelopedSignatureTransformation) {
+ EnvelopedSignatureTransformation transform =
+ (EnvelopedSignatureTransformation) other;
+ return getAlgorithmURI().equals(transform.getAlgorithmURI());
+ }
+ return false;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java
new file mode 100644
index 000000000..f50d0d9b1
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/ExclusiveCanonicalizationImpl.java
@@ -0,0 +1,71 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.util.List;
+
+import iaik.server.modules.xml.ExclusiveCanonicalization;
+
+/**
+ * An implementation of the <code>ExclusiveCanonicalization</code> type
+ * of <code>Transformation</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ExclusiveCanonicalizationImpl
+ extends TransformationImpl
+ implements ExclusiveCanonicalization {
+
+ /** The prefixes of the namespaces to treat according to canonical XML. */
+ private List inclusiveNamespacePrefixes;
+
+ /**
+ * Create a new <code>ExclusiveCanonicalizationImpl</code> object.
+ *
+ * @param algorithmURI The exclusive canonicalization algorithm URI.
+ * @param inclusiveNamespacePrefixes The namespace prefixes to be processed
+ * according to canonical XML.
+ */
+ public ExclusiveCanonicalizationImpl(
+ String algorithmURI,
+ List inclusiveNamespacePrefixes) {
+ setAlgorithmURI(algorithmURI);
+ setInclusiveNamespacePrefixes(inclusiveNamespacePrefixes);
+ }
+
+ /**
+ * Sets the namespace prefixes to be processed according to canonical XML.
+ *
+ * @param inclusiveNamespacePrefixes The prefixes of the namespaces to treat
+ * according to canonical XML.
+ */
+ protected void setInclusiveNamespacePrefixes(List inclusiveNamespacePrefixes) {
+ this.inclusiveNamespacePrefixes = inclusiveNamespacePrefixes;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.ExclusiveCanonicalization#getInclusiveNamespacePrefixes()
+ */
+ public List getInclusiveNamespacePrefixes() {
+ return inclusiveNamespacePrefixes;
+ }
+
+ /**
+ * Compare this object to another <code>CanonicalizationTransform</code>.
+ *
+ * @param other The object to compare this
+ * <code>ExclusiveCanonicalization</code> to.
+ * @return <code>true</code>, if <code>other</code> is a
+ * <code>ExclusiveCanonicalization</code> and the algorithm URIs match,
+ * otherwise <code>false</code>.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof ExclusiveCanonicalizationImpl) {
+ ExclusiveCanonicalizationImpl c14n =
+ (ExclusiveCanonicalizationImpl) other;
+ return getAlgorithmURI().equals(c14n.getAlgorithmURI());
+ }
+ return false;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java
new file mode 100644
index 000000000..19ca3dadf
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/SigningTimeImpl.java
@@ -0,0 +1,34 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.util.Date;
+
+import iaik.server.modules.xml.SigningTime;
+
+/**
+ * An implementation of the <code>SigningTime</code> <code>Property</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SigningTimeImpl implements SigningTime {
+
+ /** The signing time. */
+ private Date signingTime;
+
+ /**
+ * Create a new <code>SigningTimeImpl</code>.
+ *
+ * @param signingTime The signing time.
+ */
+ public SigningTimeImpl(Date signingTime) {
+ this.signingTime = signingTime;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.SigningTime#getSigningTime()
+ */
+ public Date getSigningTime() {
+ return signingTime;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java
new file mode 100644
index 000000000..59a414b69
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/TransformationImpl.java
@@ -0,0 +1,43 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import iaik.server.modules.xml.Transformation;
+
+/**
+ * Base implementation class for <code>Transformation</code> derived classes.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public abstract class TransformationImpl implements Transformation {
+
+ /** The algorithm URI identifying the transformation algorithm. */
+ private String algorithmURI;
+
+ /**
+ * @see iaik.server.modules.xml.Transformation#getAlgorithmURI()
+ */
+ public String getAlgorithmURI() {
+ return algorithmURI;
+ }
+
+ /**
+ * Sets the algorithm URI.
+ *
+ * @param algorithmURI The algorithm URI to set.
+ */
+ protected void setAlgorithmURI(String algorithmURI) {
+ this.algorithmURI = algorithmURI;
+ }
+
+ /**
+ * Returns the hash code of the algorithm URI. Should be overridden if a
+ * transformation distinguishes itself from others by more than just the
+ * algorithm URI.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return getAlgorithmURI().hashCode();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java
new file mode 100644
index 000000000..bc31d694e
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLDataObjectImpl.java
@@ -0,0 +1,46 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import org.w3c.dom.Element;
+
+import iaik.server.modules.xml.XMLDataObject;
+
+/**
+ * A <code>DataObject</code> containing a single DOM element.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLDataObjectImpl
+ extends DataObjectImpl
+ implements XMLDataObject {
+
+ /** The XML data contained in this <code>XMLDataObject</code>. */
+ private Element element;
+
+ /**
+ * Create a new <code>XMLDataObjectImpl</code>.
+ *
+ * @param element The DOM element contained in this
+ * <code>XMLDataObject</code>.
+ */
+ public XMLDataObjectImpl(Element element) {
+ setElement(element);
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XMLDataObject#getElement()
+ */
+ public Element getElement() {
+ return element;
+ }
+
+ /**
+ * Set the DOM element contained in this <code>XMLDataObject</code>.
+ *
+ * @param element The DOM element to set.
+ */
+ public void setElement(Element element) {
+ this.element = element;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java
new file mode 100644
index 000000000..c855a922a
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLNodeListDataObjectImpl.java
@@ -0,0 +1,47 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import org.w3c.dom.NodeList;
+
+import iaik.server.modules.xml.XMLNodeListDataObject;
+
+/**
+ * A <code>DataObject</code> containing a list of DOM nodes.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLNodeListDataObjectImpl
+ extends DataObjectImpl
+ implements XMLNodeListDataObject {
+
+ /** The nodes contained in this <code>XMLNodeListDataObject</code>. */
+ private NodeList nodeList;
+
+ /**
+ * Create a new <code>XMLNodeListDataObjectImpl</code>.
+ *
+ * @param nodeList The list of DOM nodes contained in this
+ * <code>XMLNodeListDataObject</code>.
+ */
+ public XMLNodeListDataObjectImpl(NodeList nodeList) {
+ setNodeList(nodeList);
+ }
+
+ /**
+ * Set the list of DOM nodes contained in this
+ * <code>XMLNodeListDataObject</code>.
+ *
+ * @param nodeList The list of DOM nodes to set.
+ */
+ public void setNodeList(NodeList nodeList) {
+ this.nodeList = nodeList;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XMLNodeListDataObject#getNodeList()
+ */
+ public NodeList getNodeList() {
+ return nodeList;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java
new file mode 100644
index 000000000..4fca907f3
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XMLSignatureImpl.java
@@ -0,0 +1,43 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import org.w3c.dom.Element;
+
+import iaik.server.modules.xml.XMLSignature;
+
+/**
+ * An object containing an XMLDsig signature in the form of a
+ * <code>dsig:Signature</code> DOM element.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureImpl implements XMLSignature {
+ /** The signature DOM element. */
+ private Element element;
+
+ /**
+ * Create a new <code>XMLSignatureImpl</code>.
+ *
+ * @param element The <code>dsig:Signature</code> DOM element.
+ */
+ public XMLSignatureImpl(Element element) {
+ setElement(element);
+ }
+
+ /**
+ * Set the <code>dsig:Signature</code> DOM element.
+ *
+ * @param element The <code>dsig:Signature</code> element to set.
+ */
+ public void setElement(Element element) {
+ this.element = element;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XMLSignature#getElement()
+ */
+ public Element getElement() {
+ return element;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java
new file mode 100644
index 000000000..034d4b653
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2FilterImpl.java
@@ -0,0 +1,116 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.util.Map;
+
+import iaik.server.modules.xml.XPath2Transformation;
+import iaik.server.modules.xml.XPath2Transformation.XPath2Filter;
+
+/**
+ * An object encapsulating an XPath-Filter2 expression.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XPath2FilterImpl implements XPath2Filter {
+
+ /** The type of this filter. */
+ private String filterType;
+ /** The XPath expression of this filter. */
+ private String xPathExpression;
+ /** The namespace prefix to URI mapping to use for evaluating the XPath. */
+ private Map namespaceDeclarations;
+
+ /**
+ * Create a new <code>XPath2FilterImpl</code> object.
+ *
+ * @param filterType The type of filter. Must be one of the filter type
+ * constants declared in <code>iaik.server.modules.xml.XPath2Transformation.XPath2Filter</code>
+ * @param xPathExpression The XPath expression belonging to this filter.
+ * @param namespaceDeclarations The namespace declarations visible for this
+ * XPath2Filter.
+ */
+ public XPath2FilterImpl(
+ String filterType,
+ String xPathExpression,
+ Map namespaceDeclarations) {
+
+ setFilterType(filterType);
+ setXPathExpression(xPathExpression);
+ setNamespaceDeclarations(namespaceDeclarations);
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XPath2Transformation.XPath2Filter#getFilterType()
+ */
+ public String getFilterType() {
+ return filterType;
+ }
+
+ /**
+ * Set the filter type.
+ *
+ * @param filterType The filter type to set.
+ */
+ protected void setFilterType(String filterType) {
+ this.filterType = filterType;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XPath2Transformation.XPath2Filter#getXPathExpression()
+ */
+ public String getXPathExpression() {
+ return xPathExpression;
+ }
+
+ /**
+ * Set the XPath expression.
+ *
+ * @param xPathExpression The XPath expression to set.
+ */
+ protected void setXPathExpression(String xPathExpression) {
+ this.xPathExpression = xPathExpression;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XPath2Transformation.XPath2Filter#getNamespaceDeclarations()
+ */
+ public Map getNamespaceDeclarations() {
+ return namespaceDeclarations;
+ }
+
+ /**
+ * Set the namespace declarations.
+ *
+ * @param namespaceDeclarations The mapping between namespace prefixes and
+ * their associated URI.
+ */
+ protected void setNamespaceDeclarations(Map namespaceDeclarations) {
+ this.namespaceDeclarations = namespaceDeclarations;
+ }
+
+ /**
+ * Compare this object to another.
+ *
+ * @param other The object to compare this <code>XPath2Filter</code> to.
+ * @return <code>true</code>, if <code>other</code> is a
+ * <code>XPath2Filter</code> and the filter types match and the XPath
+ * expressions match. Otherwise <code>false</code> is returned.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof XPath2Transformation.XPath2Filter) {
+ XPath2Filter filter = (XPath2Transformation.XPath2Filter) other;
+ return getFilterType().equals(filter.getFilterType())
+ && getXPathExpression().equals(filter.getXPathExpression());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return getXPathExpression().hashCode() * 31 + getFilterType().hashCode();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java
new file mode 100644
index 000000000..c7496c2cd
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPath2TransformationImpl.java
@@ -0,0 +1,82 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import iaik.server.modules.xml.XPath2Transformation;
+
+/**
+ * An object encapsulating a <code>Transformation</code> containing several
+ * XPath-Filter2 expressions.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XPath2TransformationImpl
+ extends TransformationImpl
+ implements XPath2Transformation {
+
+ /** The filters contained in this <code>XPath2Transformation</code> */
+ private List xPathFilters = new ArrayList();
+
+ /**
+ * Create a new <code>XPath2TransformationImpl</code>.
+ *
+ * The list of XPath-Filter2 expression is initially empty.
+ */
+ public XPath2TransformationImpl() {
+ setAlgorithmURI(XPath2Transformation.XPATH2);
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XPath2Transformation#getXPathFilters()
+ */
+ public List getXPathFilters() {
+ return xPathFilters;
+ }
+
+ /**
+ * Add an XPath-Filter2 expression to the list of filters.
+ *
+ * @param filter The filter to add.
+ */
+ public void addXPathFilter(XPath2Filter filter) {
+ xPathFilters.add(filter);
+ }
+
+ /**
+ * Compare this <code>XPath2Transformation</code> to another.
+ *
+ * @param other The object to compare this
+ * <code>XPath2Transformation</code> to.
+ * @return <code>true</code>, if <code>other</code> is an
+ * <code>XPath2Transformation</code> and <code>getXPathFilters()</code> equals
+ * <code>other.getXPathFilters()</code>. Otherwise <code>false</code> is
+ * returned.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof XPath2Transformation) {
+ XPath2Transformation transform = (XPath2Transformation) other;
+
+ return getXPathFilters().equals(transform.getXPathFilters());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ Iterator iter = getXPathFilters().iterator();
+ int hashCode = 0;
+
+ while (iter.hasNext()) {
+ hashCode ^= iter.next().hashCode();
+ }
+
+ return hashCode;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java
new file mode 100644
index 000000000..ccedbadb2
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XPathTransformationImpl.java
@@ -0,0 +1,98 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.util.Map;
+
+import iaik.server.modules.xml.XPathTransformation;
+
+/**
+ * A <code>Transformation</code> containing an XPath expression.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XPathTransformationImpl
+ extends TransformationImpl
+ implements XPathTransformation {
+
+ /** The XPath expression. */
+ private String xPathExpression;
+ /** The namespace prefix to URI mapping to use for XPath evaluation. */
+ private Map namespaceDeclarations;
+
+ /**
+ * Create a new <code>XPathTransformationImpl</code>.
+ *
+ * The namespace declarations are initialized empty.
+ *
+ * @param xPathExpression The XPath expression this object will contain.
+ * @param namespaceDeclarations The namespace declarations visible for this
+ * XPath.
+ */
+ public XPathTransformationImpl(
+ String xPathExpression,
+ Map namespaceDeclarations) {
+
+ setAlgorithmURI(XPathTransformation.XPATH);
+ setXPathExpression(xPathExpression);
+ setNamespaceDeclarations(namespaceDeclarations);
+ }
+
+ /**
+ * Set the XPath expression.
+ *
+ * @param xPathExpression The XPath expression.
+ */
+ protected void setXPathExpression(String xPathExpression) {
+ this.xPathExpression = xPathExpression;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XPathTransformation#getXPathExpression()
+ */
+ public String getXPathExpression() {
+ return xPathExpression;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XPathTransformation#getNamespaceDeclarations()
+ */
+ public Map getNamespaceDeclarations() {
+ return namespaceDeclarations;
+ }
+
+ /**
+ * Set the namespace declarations.
+ *
+ * @param namespaceDeclarations The mapping between namespace prefixes and
+ * their associated URI.
+ */
+ protected void setNamespaceDeclarations(Map namespaceDeclarations) {
+ this.namespaceDeclarations = namespaceDeclarations;
+ }
+
+ /**
+ * Compare this <code>XPathTransformation</code> to another.
+ *
+ * @param other The object to compare this
+ * <code>XPathTransformation</code> to.
+ * @return <code>true</code>, if <code>other</code> is an
+ * <code>XPathTransformation</code> and if this object contains the same XPath
+ * expression as <code>other</code>. Otherwise <code>false</code> is returned.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof XPathTransformation) {
+ XPathTransformation transform = (XPathTransformation) other;
+ return getXPathExpression().equals(transform.getXPathExpression());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ return getXPathExpression().hashCode();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java
new file mode 100644
index 000000000..d38da650b
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xml/XSLTTransformationImpl.java
@@ -0,0 +1,168 @@
+package at.gv.egovernment.moa.spss.server.iaik.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import iaik.ixsil.algorithms.CanonicalizationAlgorithm;
+import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplExclusiveCanonicalXML;
+import iaik.ixsil.exceptions.AlgorithmException;
+import iaik.server.modules.xml.XSLTTransformation;
+
+import at.gv.egovernment.moa.util.NodeListAdapter;
+import at.gv.egovernment.moa.util.StreamUtils;
+import at.gv.egovernment.moa.util.XPathException;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+
+/**
+ * A <code>Transformation</code> containing an XSLT transformation.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XSLTTransformationImpl
+ extends TransformationImpl
+ implements XSLTTransformation {
+
+ /** The XSLT stylesheet. */
+ private Element styleSheetElement;
+ /** The hash code of the canonicalized stylesheet. If calculated, this value
+ * should be != 0. */
+ private int hashCode;
+
+ /**
+ * Create a new <code>XSLTTransformationImpl</code> object.
+ *
+ * @param styleSheetElement The XSLT stylesheet element.
+ */
+ public XSLTTransformationImpl(Element styleSheetElement) {
+ setAlgorithmURI(XSLTTransformation.XSLT);
+ setStyleSheetElement(styleSheetElement);
+ }
+
+ /**
+ * Set the XSLT stylesheet element.
+ *
+ * @param styleSheetElement The XSLT stylesheet element to set.
+ */
+ protected void setStyleSheetElement(Element styleSheetElement) {
+ this.styleSheetElement = styleSheetElement;
+ this.hashCode = 0;
+ }
+
+ /**
+ * @see iaik.server.modules.xml.XSLTTransformation#getStylesheetElement()
+ */
+ public Element getStylesheetElement() {
+ return styleSheetElement;
+ }
+
+ /**
+ * Compare this <code>XSLTTransformation</code> to another.
+ *
+ * @param other The object to compare this
+ * <code>XSLTTransformation</code> to.
+ * @return <code>true</code>, if <code>other</code> is an
+ * <code>XSLTTransformation</code> and if the canonicalized representations of
+ * the stylesheets contained in <code>this</code> and <code>other</code>
+ * match. Otherwise, <code>false</code> is returned.
+ * @see java.lang.Object#equals(Object)
+ */
+ public boolean equals(Object other) {
+ if (other instanceof XSLTTransformation) {
+ XSLTTransformation xslt = (XSLTTransformation) other;
+
+ return compareElements(
+ getStylesheetElement(),
+ xslt.getStylesheetElement());
+ }
+ return false;
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ if (hashCode == 0) {
+ hashCode = calculateHashCode(getStylesheetElement());
+ }
+ return hashCode;
+ }
+
+ /**
+ * Calculate the hash code for a DOM element by canonicalizing it.
+ *
+ * @param element The DOM element for which the hash code is to be calculated.
+ * @return int The hash code, or <code>0</code>, if it could not be
+ * calculated.
+ */
+ private static int calculateHashCode(Element element) {
+ try {
+ InputStream is = canonicalize(element);
+ byte[] buf = new byte[256];
+ int hashCode = 1;
+ int length;
+ int i;
+
+ while ((length = is.read(buf)) > 0) {
+ for (i = 0; i < length; i++) {
+ hashCode += buf[i] * 31 + i;
+ }
+ }
+ is.close();
+ return hashCode;
+ } catch (AlgorithmException e) {
+ return 0;
+ } catch (IOException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Compare two DOM elements by canonicalizing their contents and comparing the
+ * resulting byte stream.
+ *
+ * @param elem1 The 1st element to compare.
+ * @param elem2 The 2nd element to compare.
+ * @return boolean <code>true</code>, if the elements are considered equal
+ * after canonicalization. Otherwise <code>false</code> is returned.
+ */
+ private static boolean compareElements(Element elem1, Element elem2) {
+ try {
+ InputStream is1 = canonicalize(elem1);
+ InputStream is2 = canonicalize(elem2);
+ return StreamUtils.compareStreams(is1, is2);
+ } catch (AlgorithmException e) {
+ return false;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Canonicalize a DOM element.
+ *
+ * @param element The element to canonicalize.
+ * @return InputStream A stream with the canonicalized data.
+ * @throws AlgorithmException An error occurred canonicalizing the element.
+ */
+ private static InputStream canonicalize(Element element)
+ throws AlgorithmException {
+ CanonicalizationAlgorithm c14n =
+ new CanonicalizationAlgorithmImplExclusiveCanonicalXML();
+ NodeList nodeList;
+
+ try {
+ nodeList = XPathUtils.selectNodeList(element, XPathUtils.ALL_NODES_XPATH);
+ } catch (XPathException e) {
+ nodeList = new NodeListAdapter(Collections.EMPTY_LIST);
+ }
+ c14n.setInput(nodeList);
+ return c14n.canonicalize();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java
new file mode 100644
index 000000000..a14b83b7d
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/DataObjectTreatmentImpl.java
@@ -0,0 +1,150 @@
+package at.gv.egovernment.moa.spss.server.iaik.xmlsign;
+
+import java.util.List;
+
+import iaik.server.modules.xmlsign.DataObjectTreatment;
+
+import at.gv.egovernment.moa.spss.server.util.IdGenerator;
+
+/**
+ * An object encapsulating how to treat an associated <code>DataObject</code>
+ * when creating a signature.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class DataObjectTreatmentImpl implements DataObjectTreatment {
+ /** The final content MIME type. */
+ private String finalContentType;
+ /** The name of the hash algorithm. */
+ private String hashAlgorithmName;
+ /** This transformations to apply to the associated data object. */
+ private List transformationList;
+ /** Supplemental information for the transformations. */
+ private List transformationSupplements;
+ /** Whether to include the associated data object in the signature. */
+ private boolean includedInSignature;
+ /** Whether to include the associated data object in the manifest. */
+ private boolean referenceInManifest;
+ /** The object ID generator. */
+ private IdGenerator objIdGen;
+
+ /**
+ * Create a new <code>DataObjectTreatmentImpl</code>.
+ *
+ * @param objIdGen The <code>IdGenerator</code> for unique object IDs.
+ */
+ public DataObjectTreatmentImpl(IdGenerator objIdGen) {
+ this.objIdGen = objIdGen;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#getFinalContentType()
+ */
+ public String getFinalContentType() {
+ return finalContentType;
+ }
+
+ /**
+ * Sets the final content type.
+ *
+ * @param finalContentType The final content type to set (a MIME-type type of
+ * <code>String</code>).
+ */
+ public void setFinalContentType(String finalContentType) {
+ this.finalContentType = finalContentType;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#getHashAlgorithmName()
+ */
+ public String getHashAlgorithmName() {
+ return hashAlgorithmName;
+ }
+
+ /**
+ * Sets the hash algorithm name.
+ *
+ * @param hashAlgorithmName The hash algorithm name to set.
+ */
+ public void setHashAlgorithmName(String hashAlgorithmName) {
+ this.hashAlgorithmName = hashAlgorithmName;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#isIncludedInSignature()
+ */
+ public boolean isIncludedInSignature() {
+ return includedInSignature;
+ }
+
+ /**
+ * Sets whether the associated <code>DataObject</code> is to be included in
+ * the signature.
+ *
+ * @param includedInSignature If <code>true</code>, the associated
+ * <code>DataObject</code> will be included in the signature, otherwise not.
+ */
+ public void setIncludedInSignature(boolean includedInSignature) {
+ this.includedInSignature = includedInSignature;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#isReferenceInManifest()
+ */
+ public boolean isReferenceInManifest() {
+ return referenceInManifest;
+ }
+
+ /**
+ * Sets whether the associated <code>DataObject</code> is
+ * to be included in the <code>dsig:Manifest</code>.
+ *
+ * @param referenceInManifest If <code>true</code>, the associated
+ * <code>DataObject</code> will be included in the manifest, otherwise not.
+ */
+ public void setReferenceInManifest(boolean referenceInManifest) {
+ this.referenceInManifest = referenceInManifest;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#getTransformationList()
+ */
+ public List getTransformationList() {
+ return transformationList;
+ }
+
+ /**
+ * Set the list of transformations for the associated <code>DataObject</code>.
+ *
+ * @param transformationList The transformations to set.
+ */
+ public void setTransformationList(List transformationList) {
+ this.transformationList = transformationList;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#getTransformationSupplements()
+ */
+ public List getTransformationSupplements() {
+ return transformationSupplements;
+ }
+
+ /**
+ * Sets the transformation supplements for the associated
+ * <code>DataObject</code>.
+ *
+ * @param transformationSupplements The transformation supplements to set.
+ */
+ public void setTransformationSupplements(List transformationSupplements) {
+ this.transformationSupplements = transformationSupplements;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.DataObjectTreatment#getDsigDataObjectID()
+ */
+ public String getDsigDataObjectID() {
+ return objIdGen.uniqueId();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java
new file mode 100644
index 000000000..5ec0057fb
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureCreationProfileImpl.java
@@ -0,0 +1,276 @@
+package at.gv.egovernment.moa.spss.server.iaik.xmlsign;
+
+import java.util.List;
+import java.util.Set;
+
+import iaik.server.modules.algorithms.SignatureAlgorithms;
+import iaik.server.modules.keys.AlgorithmUnavailableException;
+import iaik.server.modules.keys.KeyEntryID;
+import iaik.server.modules.keys.KeyModule;
+import iaik.server.modules.keys.KeyModuleFactory;
+import iaik.server.modules.keys.UnknownKeyException;
+import iaik.server.modules.xml.Canonicalization;
+import iaik.server.modules.xmlsign.XMLSignatureCreationProfile;
+import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation;
+
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.server.util.IdGenerator;
+
+/**
+ * An object providing auxiliary information for creating an XML signature.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureCreationProfileImpl
+ implements XMLSignatureCreationProfile {
+
+ /** The transformations to apply to a data object. */
+ private List dataObjectTreatmentList;
+ /** The set of keys available to the signing process. */
+ private Set keySet;
+ /** The type URI of the signature manifest. */
+ private String securityLayerManifestTypeURI;
+ /** Whether the created signature is to be Security Layer conform. */
+ private boolean securityLayerConform;
+ /** Where to insert the signature into the signature environment. */
+ private XMLSignatureInsertionLocation signatureInsertionLocation;
+ /** The signature structur type. */
+ private String signatureStructureType;
+ /** The type of <code>Canonicalization</code> to use for the signed info. */
+ private Canonicalization signedInfoCanonicalization;
+ /** Properties to be signed during signature creation. */
+ private List signedProperties;
+ /** The ID generator for signature IDs. */
+ private IdGenerator signatureIDGenerator;
+ /** The ID generator for manifst IDs. */
+ private IdGenerator manifestIDGenerator;
+ /** The ID generator for XMLDsig manifest IDs. */
+ private IdGenerator dsigManifestIDGenerator;
+ /** The ID generator for signed property IDs. */
+ private IdGenerator propertyIDGenerator;
+
+ /**
+ * Create a new <code>XMLSignatureCreationProfileImpl</code>.
+ *
+ * @param createProfileCount Provides external information about the
+ * number of calls to the signature creation module, using the same request.
+ * @param reservedIDs The set of IDs that must not be used while generating
+ * new IDs.
+ */
+ public XMLSignatureCreationProfileImpl(
+ int createProfileCount,
+ Set reservedIDs) {
+ signatureIDGenerator =
+ new IdGenerator("signature-" + createProfileCount, reservedIDs);
+ manifestIDGenerator =
+ new IdGenerator("manifest-" + createProfileCount, reservedIDs);
+ dsigManifestIDGenerator =
+ new IdGenerator("dsig-manifest-" + createProfileCount, reservedIDs);
+ propertyIDGenerator =
+ new IdGenerator("etsi-signed-" + createProfileCount, reservedIDs);
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getDataObjectTreatmentList()
+ */
+ public List getDataObjectTreatmentList() {
+ return dataObjectTreatmentList;
+ }
+
+ /**
+ * Sets the list of <code>DataObjectTreatment</code>s.
+ *
+ * @param dataObjectTreatmentList The <code>DataObjectTreatment</code>s to
+ * set.
+ */
+ public void setDataObjectTreatmentList(List dataObjectTreatmentList) {
+ this.dataObjectTreatmentList = dataObjectTreatmentList;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getKeySet()
+ */
+ public Set getKeySet() {
+ return keySet;
+ }
+
+ /**
+ * Set the set of <code>KeyEntryID</code>s which may be used for signature
+ * creation.
+ *
+ * @param keySet The set of <code>KeyEntryID</code>s to set.
+ */
+ public void setKeySet(Set keySet) {
+ this.keySet = keySet;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSecurityLayerManifestTypeURI()
+ */
+ public String getSecurityLayerManifestTypeURI() {
+ return securityLayerManifestTypeURI;
+ }
+
+ /**
+ * Set the SecurityLayerManifestTypeURI.
+ *
+ * @param securityLayerManifestTypeURI The SecurityLayerManifestTypeURI to
+ * set.
+ */
+ public void setSecurityLayerManifestTypeURI(String securityLayerManifestTypeURI) {
+ this.securityLayerManifestTypeURI = securityLayerManifestTypeURI;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureAlgorithmName(KeyEntryID)
+ */
+ public String getSignatureAlgorithmName(KeyEntryID selectedKeyID)
+ throws AlgorithmUnavailableException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ TransactionId tid = new TransactionId(context.getTransactionID());
+ KeyModule module = KeyModuleFactory.getInstance(tid);
+ Set algorithms;
+
+ try {
+ algorithms = module.getSupportedSignatureAlgorithms(selectedKeyID);
+ } catch (UnknownKeyException e) {
+ throw new AlgorithmUnavailableException(
+ "Unknown key entry: " + selectedKeyID,
+ e,
+ null);
+ }
+
+ if (algorithms.contains(SignatureAlgorithms.MD2_WITH_RSA)
+ || algorithms.contains(SignatureAlgorithms.MD5_WITH_RSA)
+ || algorithms.contains(SignatureAlgorithms.RIPEMD128_WITH_RSA)
+ || algorithms.contains(SignatureAlgorithms.RIPEMD160_WITH_RSA)
+ || algorithms.contains(SignatureAlgorithms.SHA1_WITH_RSA)
+ || algorithms.contains(SignatureAlgorithms.SHA256_WITH_RSA)) {
+
+ return SignatureAlgorithms.SHA1_WITH_RSA;
+ } else if (
+ algorithms.contains(SignatureAlgorithms.ECDSA_X962_C2TNB191V1)) {
+ return SignatureAlgorithms.ECDSA_X962_C2TNB191V1;
+ } else {
+ throw new AlgorithmUnavailableException(
+ "No algorithm for key entry: " + selectedKeyID,
+ null,
+ null);
+ }
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureInsertionLocation()
+ */
+ public XMLSignatureInsertionLocation getSignatureInsertionLocation() {
+ return signatureInsertionLocation;
+ }
+
+ /**
+ * Set the location where the signature is to be inserted into the signature
+ * parent.
+ *
+ * @param signatureInsertionLocation The location to set.
+ */
+ public void setSignatureInsertionLocation(XMLSignatureInsertionLocation signatureInsertionLocation) {
+ this.signatureInsertionLocation = signatureInsertionLocation;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureStructureType()
+ */
+ public String getSignatureStructureType() {
+ return signatureStructureType;
+ }
+
+ /**
+ * Set the signature structure type.
+ * @param signatureStructureType The signature structure type to set.
+ */
+ public void setSignatureStructureType(String signatureStructureType) {
+ this.signatureStructureType = signatureStructureType;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignedInfoCanonicalization()
+ */
+ public Canonicalization getSignedInfoCanonicalization() {
+ return signedInfoCanonicalization;
+ }
+
+ /**
+ * Sets the canonicalization method to use for the SignedInfo object.
+ *
+ * @param signedInfoCanonicalization The canonicalization method to set.
+ */
+ public void setSignedInfoCanonicalization(Canonicalization signedInfoCanonicalization) {
+ this.signedInfoCanonicalization = signedInfoCanonicalization;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignedProperties()
+ */
+ public List getSignedProperties() {
+ return signedProperties;
+ }
+
+ /**
+ * Set the signed properties.
+ *
+ * @param signedProperties The signed properties to set.
+ */
+ public void setSignedProperties(List signedProperties) {
+ this.signedProperties = signedProperties;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#isSecurityLayerConform()
+ */
+ public boolean isSecurityLayerConform() {
+ return securityLayerConform;
+ }
+
+ /**
+ * Sets the security layer conformity.
+ *
+ * @param securityLayerConform <code>true</code>, if the created signature
+ * is to be conform to the Security Layer specification.
+ */
+ public void setSecurityLayerConform(boolean securityLayerConform) {
+ this.securityLayerConform = securityLayerConform;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignatureID()
+ */
+ public String getSignatureID() {
+ return signatureIDGenerator.uniqueId();
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSecurityLayerManifestID()
+ */
+ public String getSecurityLayerManifestID() {
+ return manifestIDGenerator.uniqueId();
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getDsigManifestID()
+ */
+ public String getDsigManifestID() {
+ return dsigManifestIDGenerator.uniqueId();
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureCreationProfile#getSignedPropertiesID()
+ */
+ public String getSignedPropertiesID() {
+ return propertyIDGenerator.uniqueId();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java
new file mode 100644
index 000000000..d55f61303
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlsign/XMLSignatureInsertionLocationImpl.java
@@ -0,0 +1,45 @@
+package at.gv.egovernment.moa.spss.server.iaik.xmlsign;
+
+import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation;
+
+/**
+ * An object giving the location of where the signature will be
+ * inserted into the parent element.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureInsertionLocationImpl
+ implements XMLSignatureInsertionLocation {
+
+ /** Where to put the signature into the signature parent element. */
+ private int signatureChildIndex;
+
+ /**
+ * Create a new <code>XMLSignatureInsertLocationImpl</code>.
+ *
+ * @param signatureChildIndex The position index at which to append the
+ * signature to the parent element.
+ */
+ public XMLSignatureInsertionLocationImpl(int signatureChildIndex) {
+ setSignatureChildIndex(signatureChildIndex);
+ }
+
+ /**
+ * @see iaik.server.modules.xmlsign.XMLSignatureInsertionLocation#getSignatureChildIndex()
+ */
+ public int getSignatureChildIndex() {
+ return signatureChildIndex;
+ }
+
+ /**
+ * Sets the position index at which to append the signature to the parent
+ * element.
+ *
+ * @param signatureChildIndex The position index to set.
+ */
+ public void setSignatureChildIndex(int signatureChildIndex) {
+ this.signatureChildIndex = signatureChildIndex;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java
new file mode 100644
index 000000000..216596dc3
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/iaik/xmlverify/XMLSignatureVerificationProfileImpl.java
@@ -0,0 +1,131 @@
+package at.gv.egovernment.moa.spss.server.iaik.xmlverify;
+
+import java.util.List;
+
+import iaik.pki.PKIProfile;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile;
+
+/**
+ * An object providing auxiliary information for verifying an XML signature.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureVerificationProfileImpl
+ implements XMLSignatureVerificationProfile {
+
+ /** Whether to check the Security Layer manifest. */
+ private boolean checkSecurityLayerManifest;
+ /** Whether to check the XMLDsig manifest. */
+ private boolean checkXMLDsigManifests;
+ /** The profile for validating the signer certificate. */
+ private PKIProfile certificateValidationProfile;
+ /** Supplements for the transformations. */
+ private List transformationSupplements;
+ /** Whether to include hash input data in the response. */
+ private boolean includeHashInputData;
+ /** Whether to include reference input data in the response. */
+ private boolean includeReferenceInputData;
+
+ /**
+ * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#checkSecurityLayerManifest()
+ */
+ public boolean checkSecurityLayerManifest() {
+ return checkSecurityLayerManifest;
+ }
+
+ /**
+ * Set whether to check the references in the Security Layer manifest.
+ *
+ * @param checkSecurityLayerManifest <code>true</code>, if the references
+ * in the Security Layer manifest must be checked.
+ */
+ public void setCheckSecurityLayerManifest(boolean checkSecurityLayerManifest) {
+ this.checkSecurityLayerManifest = checkSecurityLayerManifest;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#checkXMLDsigManifests()
+ */
+ public boolean checkXMLDsigManifests() {
+ return checkXMLDsigManifests;
+ }
+
+ /**
+ * Sets whether to check the references of all XML Dsig manifests.
+ *
+ * @param checkXMLDSigManifests <code>true</code>, if the references in the
+ * XML Dsig manifest must be checked.
+ */
+ public void setCheckXMLDsigManifests(boolean checkXMLDSigManifests) {
+ this.checkXMLDsigManifests = checkXMLDSigManifests;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#getCertificateValidationProfile()
+ */
+ public PKIProfile getCertificateValidationProfile() {
+ return certificateValidationProfile;
+ }
+
+ /**
+ * Sets the profile for validating the signer certificate.
+ *
+ * @param certificateValidationProfile The certificate validation profile to
+ * set.
+ */
+ public void setCertificateValidationProfile(PKIProfile certificateValidationProfile) {
+ this.certificateValidationProfile = certificateValidationProfile;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#getTransformationSupplements()
+ */
+ public List getTransformationSupplements() {
+ return transformationSupplements;
+ }
+
+ /**
+ * Sets the transformation supplements.
+ *
+ * @param transformationSupplements The transformation supplements to set.
+ */
+ public void setTransformationSupplements(List transformationSupplements) {
+ this.transformationSupplements = transformationSupplements;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#includeHashInputData()
+ */
+ public boolean includeHashInputData() {
+ return includeHashInputData;
+ }
+
+ /**
+ * Set whether to include the hash input data in the result.
+ *
+ * @param includeHashInputData If <code>true</code>, the hash input data
+ * will be returned in the result.
+ */
+ public void setIncludeHashInputData(boolean includeHashInputData) {
+ this.includeHashInputData = includeHashInputData;
+ }
+
+ /**
+ * @see iaik.server.modules.xmlverify.XMLSignatureVerificationProfile#includeReferenceInputData()
+ */
+ public boolean includeReferenceInputData() {
+ return includeReferenceInputData;
+ }
+
+ /**
+ * Set whether to include the reference input data in the result.
+ *
+ * @param includeReferenceInputData If <code>true</code>, the reference
+ * input data will be included in the result.
+ */
+ public void setIncludeReferenceInputData(boolean includeReferenceInputData) {
+ this.includeReferenceInputData = includeReferenceInputData;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java
new file mode 100644
index 000000000..caf17db66
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/init/ConfiguratorImpl.java
@@ -0,0 +1,42 @@
+package at.gv.egovernment.moa.spss.server.init;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.Configurator;
+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.iaik.config.IaikConfigurator;
+
+/**
+ * Default implementation of <code>Configurator</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ConfiguratorImpl extends Configurator {
+ /** whether the configuration has been initialized */
+ private boolean initialized = false;
+
+ public void init() throws MOAException {
+ if (!initialized) {
+ SystemInitializer.init();
+ initialized = true;
+ }
+ }
+
+ public void update() throws MOAException {
+ if (!initialized) {
+ return;
+ }
+
+ try {
+ // reconfigure the system
+ ConfigurationProvider config = ConfigurationProvider.reload();
+ new IaikConfigurator().configure(config);
+ } catch (MOAException e) {
+ throw e;
+ } catch (Throwable t) {
+ throw new ConfigurationException("", null, t);
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java b/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java
new file mode 100644
index 000000000..f968778d7
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/init/SystemInitializer.java
@@ -0,0 +1,122 @@
+package at.gv.egovernment.moa.spss.server.init;
+
+import java.io.IOException;
+import java.security.Security;
+
+import javax.net.ssl.SSLSocketFactory;
+
+import iaik.ixsil.init.IXSILInit;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator;
+import at.gv.egovernment.moa.spss.server.logging.IaikLog;
+import at.gv.egovernment.moa.spss.server.service.RevocationArchiveCleaner;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * MOA SP/SS web service initialization.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SystemInitializer {
+ /** Interval between archive cleanups in seconds */
+ private static final long ARCHIVE_CLEANUP_INTERVAL = 60 * 60; // 1h
+ /** The MOA SP/SS logging hierarchy. */
+ private static final String LOGGING_HIERARCHY = "moa.spss.server";
+ /** Whether XML schema grammars have been initialized. */
+ private static boolean grammarsInitialized = false;
+
+ /**
+ * Initialize the MOA SP/SS webservice.
+ */
+ public static void init() {
+ MessageProvider msg = MessageProvider.getInstance();
+ ClassLoader cl = SystemInitializer.class.getClassLoader();
+ Thread archiveCleaner;
+
+ // set up the MOA SPSS logging hierarchy
+ Logger.setHierarchy(LOGGING_HIERARCHY);
+
+ // set up a logging context for logging the startup
+ LoggingContextManager.getInstance().setLoggingContext(
+ new LoggingContext("startup"));
+
+ // load some jsse classes so that the integrity of the jars can be verified
+ // before the iaik jce is installed as the security provider
+ // this workaround is only needed when sun jsse is used in conjunction with
+ // iaik-jce (on jdk1.3)
+ try {
+ cl.loadClass("javax.security.cert.Certificate"); // from jcert.jar
+ } catch (ClassNotFoundException e) {
+ Logger.warn(msg.getMessage("init.03", null), e);
+ }
+
+ // set up SUN JSSE SSL
+ Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+ System.setProperty(
+ "java.protocol.handler.pkgs",
+ "com.sun.net.ssl.internal.www.protocol");
+ SSLSocketFactory.getDefault();
+
+ // initialize preparsed Xerces grammar pool for faster XML
+ // parsing/validating
+ try {
+ if (!grammarsInitialized) {
+ Class clazz = SystemInitializer.class;
+ // preparse XML schema
+ DOMUtils.addSchemaToPool(
+ clazz.getResourceAsStream(Constants.XML_SCHEMA_LOCATION),
+ Constants.XML_NS_URI);
+ // preparse XMLDsig Filter2 schema
+ DOMUtils.addSchemaToPool(
+ clazz.getResourceAsStream(Constants.DSIG_FILTER2_SCHEMA_LOCATION),
+ Constants.DSIG_FILTER2_NS_URI);
+ // preparse XMLDsig schema
+ DOMUtils.addSchemaToPool(
+ clazz.getResourceAsStream(Constants.DSIG_SCHEMA_LOCATION),
+ Constants.DSIG_NS_URI);
+ // preparse MOA schema
+ DOMUtils.addSchemaToPool(
+ clazz.getResourceAsStream(Constants.MOA_SCHEMA_LOCATION),
+ Constants.MOA_NS_URI);
+ grammarsInitialized = true;
+ }
+ } catch (IOException e) {
+ Logger.warn(new LogMsg(msg.getMessage("init.04", null)), e);
+ }
+
+ // initialize configuration
+ try {
+ ConfigurationProvider config = ConfigurationProvider.getInstance();
+ new IaikConfigurator().configure(config);
+ Logger.info(new LogMsg(msg.getMessage("init.01", null)));
+ } catch (MOAException e) {
+ Logger.fatal(new LogMsg(msg.getMessage("init.00", null)), e);
+ }
+
+ // set IXSIL debug output
+ IXSILInit.setPrintDebugLog(
+ Logger.isDebugEnabled(IaikLog.IAIK_LOG_HIERARCHY));
+
+ // start the archive cleanup thread
+ archiveCleaner =
+ new Thread(new RevocationArchiveCleaner(ARCHIVE_CLEANUP_INTERVAL));
+ archiveCleaner.setName("RevocationArchiveCleaner");
+ archiveCleaner.setDaemon(true);
+ archiveCleaner.setPriority(Thread.MIN_PRIORITY);
+ archiveCleaner.start();
+
+ // unset the startup logging context
+ LoggingContextManager.getInstance().setLoggingContext(null);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java
new file mode 100644
index 000000000..33b924e2b
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java
@@ -0,0 +1,207 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+import iaik.IAIKException;
+import iaik.IAIKRuntimeException;
+import iaik.server.modules.cmsverify.CMSSignatureVerificationModule;
+import iaik.server.modules.cmsverify.CMSSignatureVerificationModuleFactory;
+import iaik.server.modules.cmsverify.CMSSignatureVerificationProfile;
+import iaik.server.modules.cmsverify.CMSSignatureVerificationResult;
+
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContentExcplicit;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContentReference;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSDataObject;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.server.logging.IaikLog;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+
+/**
+ * A class providing an interface to the
+ * <code>CMSSignatureVerificationModule</code>.
+ *
+ * This class performs the invocation of the
+ * <code>iaik.server.modules.cmsverify.CMSSignatureVerificationModule</code>
+ * from a <code>VerifyCMSSignatureRequest</code>. The result of the invocation
+ * is integrated into a <code>VerifyCMSSignatureResponse</code> returned.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CMSSignatureVerificationInvoker {
+
+ /** The single instance of this class. */
+ private static CMSSignatureVerificationInvoker instance = null;
+
+ /**
+ * Return the only instance of this class.
+ *
+ * @return The only instance of this class.
+ */
+ public static synchronized CMSSignatureVerificationInvoker getInstance() {
+ if (instance == null) {
+ instance = new CMSSignatureVerificationInvoker();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>CMSSignatureVerificationInvoker</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected CMSSignatureVerificationInvoker() {
+ }
+
+ /**
+ * Verify a CMS signature.
+ *
+ * @param request The <code>VerifyCMSSignatureRequest</code> containing the
+ * CMS signature, as well as additional data needed for verification.
+ * @return Element A <code>VerifyCMSSignatureResponse</code> containing the
+ * answer to the <code>VerifyCMSSignatureRequest</code>.
+ * @throws MOAException An error occurred while processing the request.
+ */
+ public VerifyCMSSignatureResponse verifyCMSSignature(VerifyCMSSignatureRequest request)
+ throws MOAException {
+ CMSSignatureVerificationProfileFactory profileFactory =
+ new CMSSignatureVerificationProfileFactory(request);
+ VerifyCMSSignatureResponseBuilder responseBuilder =
+ new VerifyCMSSignatureResponseBuilder();
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ LoggingContext loggingCtx =
+ LoggingContextManager.getInstance().getLoggingContext();
+ InputStream signature;
+ InputStream signedContent;
+ CMSSignatureVerificationProfile profile;
+ Date signingTime;
+ List results;
+ CMSSignatureVerificationResult result;
+ int[] signatories;
+ InputStream input;
+ byte[] buf = new byte[256];
+
+ // get the signature
+ signature = request.getCMSSignature();
+
+ // get the signed content
+ signedContent = getSignedContent(request);
+
+ // build the profile
+ profile = profileFactory.createProfile();
+
+ // get the signing time
+ signingTime = request.getDateTime();
+
+ // verify the signature
+ try {
+ CMSSignatureVerificationModule module =
+ CMSSignatureVerificationModuleFactory.getInstance();
+
+ module.setLog(new IaikLog(loggingCtx.getNodeID()));
+
+ module.init(
+ signature,
+ signedContent,
+ profile,
+ new TransactionId(context.getTransactionID()));
+ input = module.getInputStream();
+
+ while (input.read(buf) > 0);
+ results = module.verifySignature(signingTime);
+ } catch (IAIKException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+ throw moaException;
+ } catch (IAIKRuntimeException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+ throw moaException;
+ } catch (IOException e) {
+ throw new MOAApplicationException("2244", null, e);
+ }
+
+ // build the response: for each signatory add the result to the response
+ signatories = request.getSignatories();
+ if (signatories == VerifyCMSSignatureRequest.ALL_SIGNATORIES) {
+ Iterator resultIter;
+
+ for (resultIter = results.iterator(); resultIter.hasNext();) {
+ result = (CMSSignatureVerificationResult) resultIter.next();
+ responseBuilder.addResult(result);
+ }
+ } else {
+ int i;
+
+ for (i = 0; i < signatories.length; i++) {
+ int sigIndex = signatories[i] - 1;
+
+ try {
+ result =
+ (CMSSignatureVerificationResult) results.get(signatories[i] - 1);
+ responseBuilder.addResult(result);
+ } catch (IndexOutOfBoundsException e) {
+ throw new MOAApplicationException(
+ "2249",
+ new Object[] { new Integer(sigIndex)});
+ }
+ }
+ }
+
+ return responseBuilder.getResponse();
+ }
+
+ /**
+ * Get the signed content contained either in the request itself or given as a
+ * reference to external data.
+ *
+ * @param request The <code>VerifyCMSSignatureRequest</code> containing the
+ * signed content (or the reference to the signed content).
+ * @return InputStream A stream providing the signed content data, or
+ * <code>null</code> if no signed content was provided with the request.
+ * @throws MOAApplicationException An error occurred building the stream.
+ */
+ private InputStream getSignedContent(VerifyCMSSignatureRequest request)
+ throws MOAApplicationException {
+
+ CMSDataObject dataObj;
+ CMSContent content;
+
+ // select the Content element
+ dataObj = request.getDataObject();
+ if (dataObj == null) {
+ return null;
+ }
+ content = dataObj.getContent();
+
+ // build the content data
+ switch (content.getContentType()) {
+ case CMSContent.EXPLICIT_CONTENT :
+ return ((CMSContentExcplicit) content).getBinaryContent();
+ case CMSContent.REFERENCE_CONTENT :
+ String reference = ((CMSContentReference) content).getReference();
+ if (!"".equals(reference)) {
+ ExternalURIResolver resolver = new ExternalURIResolver();
+ return resolver.resolve(reference);
+ } else {
+ return null;
+ }
+ default :
+ return null;
+ }
+
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java
new file mode 100644
index 000000000..442921850
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java
@@ -0,0 +1,61 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.cmsverify.CMSSignatureVerificationProfile;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.cmsverify.CMSSignatureVerificationProfileImpl;
+import at.gv.egovernment.moa.spss.server.iaik.pki.PKIProfileImpl;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+
+/**
+ * A factory to create a <code>CMSSignatureVerificationProfile</code> from a
+ * <code>VerifyCMSSignatureRequest</code> and the current MOA configuration
+ * data.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CMSSignatureVerificationProfileFactory {
+
+ /** The <code>VerifyCMSSignatureRequest</code> to draw profile data from. */
+ private VerifyCMSSignatureRequest request;
+
+ /**
+ * Create a new <code>CMSSignatureVerificationProfileFactory</code>.
+ *
+ * @param request The <code>VerifyCMSSignatureRequest</code> to draw profile
+ * data from.
+ */
+ public CMSSignatureVerificationProfileFactory(VerifyCMSSignatureRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * Create a <code>CMSSignatureVerificationProfile</code> from the given
+ * request and the current MOA configuration.
+ *
+ * @return The <code>CMSSignatureVerificationProfile</code> for the
+ * <code>request</code>, based on the current configuration.
+ * @throws MOAException An error occurred creating the profile.
+ */
+ public CMSSignatureVerificationProfile createProfile()
+ throws MOAException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CMSSignatureVerificationProfileImpl profile =
+ new CMSSignatureVerificationProfileImpl();
+ String trustProfileID;
+
+ // set the certificate validation profile
+ trustProfileID = request.getTrustProfileId();
+ profile.setCertificateValidationProfile(
+ new PKIProfileImpl(config, trustProfileID));
+
+ return profile;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java
new file mode 100644
index 000000000..6302cadfd
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java
@@ -0,0 +1,71 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse;
+import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse;
+
+/**
+ * A class to build a <code>CreateXMLSignatureResponse</code>.
+ *
+ * <p>The methods <code>addSignature()</code> and <code>addError()</code> may be
+ * called in any combination to add <code>SignatureEnvironment</code> and
+ * <code>ErrorResponse</code> elements to the response. One of these functions
+ * must be called at least once to produce a
+ * <code>CreateXMLSignatureResponse</code>.</p>
+ *
+ * <p>The <code>getResponseElement()</code> method then returns the
+ * <code>CreateXMLSignatureResponse</code> built so far.</p>
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CreateXMLSignatureResponseBuilder {
+
+ /** The <code>SPSSFactory</code> for creating API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+ /** The elements to add to the response. */
+ private List responseElements = new ArrayList();
+
+ /**
+ * Get the <code>CreateXMLSignatureResponse</code> built so far.
+ *
+ * @return The <code>CreateXMLSignatureResponse</code> built so far.
+ */
+ public CreateXMLSignatureResponse getResponse() {
+ return factory.createCreateXMLSignatureResponse(responseElements);
+ }
+
+ /**
+ * Add a <code>SignatureEnvironment</code> element to the response.
+ *
+ * @param signatureEnvironment The content to put under the
+ * <code>SignatureEnvironment</code> element. This should either be a
+ * <code>dsig:Signature</code> element (in case of a detached signature) or
+ * the signature environment containing the signature (in case of
+ * an enveloping signature).
+ */
+ public void addSignatureEnvironment(Element signatureEnvironment) {
+ SignatureEnvironmentResponse responseElement =
+ factory.createSignatureEnvironmentResponse(signatureEnvironment);
+ responseElements.add(responseElement);
+ }
+
+ /**
+ * Add a <code>ErrorResponse</code> element to the response.
+ *
+ * @param errorCode The error code.
+ * @param info Additional information about the error.
+ */
+ public void addError(String errorCode, String info) {
+ ErrorResponse errorResponse =
+ factory.createErrorResponse(Integer.parseInt(errorCode), info);
+ responseElements.add(errorResponse);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java
new file mode 100644
index 000000000..32c81dc07
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java
@@ -0,0 +1,717 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.SAXException;
+
+import iaik.ixsil.util.URI;
+import iaik.ixsil.util.XPointerReferenceResolver;
+import iaik.server.modules.xml.DataObject;
+import iaik.server.modules.xml.XMLDataObject;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.EntityResolverChain;
+import at.gv.egovernment.moa.util.MOAEntityResolver;
+import at.gv.egovernment.moa.util.MOAErrorHandler;
+import at.gv.egovernment.moa.util.StreamEntityResolver;
+import at.gv.egovernment.moa.util.StreamUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.common.ContentBinary;
+import at.gv.egovernment.moa.spss.api.common.ContentXML;
+import at.gv.egovernment.moa.spss.api.common.MetaInfo;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterBinary;
+import at.gv.egovernment.moa.spss.server.iaik.xml.ByteArrayDataObjectImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.ByteStreamDataObjectImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.DataObjectImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XMLDataObjectImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XMLNodeListDataObjectImpl;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A class to create <code>DataObject</code>s contained in different
+ * locations of the MOA XML request format.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class DataObjectFactory {
+
+ /** The single instance of this class. */
+ private static DataObjectFactory instance = null;
+
+ /**
+ * Return the only instance of this class.
+ *
+ * @return The only instance of this class.
+ */
+ public static synchronized DataObjectFactory getInstance() {
+ if (instance == null) {
+ instance = new DataObjectFactory();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>DataObjectFactory</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected DataObjectFactory() {
+ }
+
+ /**
+ * Return the signature environment, i.e., the root element of the
+ * document, into which the signature will be inserted (if created) or which
+ * contains the signature (if verified).
+ *
+ * @param content The <code>Content</code> object containing the signature
+ * environment.
+ * @param supplements Additional schema or DTD information.
+ * @return The signature environment or <code>null</code>, if no
+ * signature environment exists.
+ * @throws MOASystemException A system error occurred building the signature
+ * environment (see message for details).
+ * @throws MOAApplicationException An error occurred building the signature
+ * environment (see message for details).
+ */
+ public XMLDataObject createSignatureEnvironment(
+ Content content,
+ List supplements)
+ throws MOASystemException, MOAApplicationException {
+
+ String reference = content.getReference();
+ EntityResolver entityResolver;
+ byte[] contentBytes;
+
+ // check for content and reference not being set at the same time
+ checkAllowContentAndReference(content, false);
+
+ // build the EntityResolver for validating parsing
+ if (supplements == null || supplements.isEmpty()) {
+ entityResolver = new MOAEntityResolver();
+ } else {
+ EntityResolverChain chain = new EntityResolverChain();
+
+ chain.addEntityResolver(buildSupplementEntityResolver(supplements));
+ chain.addEntityResolver(new MOAEntityResolver());
+ entityResolver = chain;
+ }
+
+ // convert the content into a byte array
+ try {
+ switch (content.getContentType()) {
+ case Content.BINARY_CONTENT :
+ {
+ InputStream is = ((ContentBinary) content).getBinaryContent();
+ contentBytes = StreamUtils.readStream(is);
+ break;
+ }
+ case Content.REFERENCE_CONTENT :
+ {
+ ExternalURIResolver uriResolver = new ExternalURIResolver();
+ InputStream is = uriResolver.resolve(reference);
+ contentBytes = StreamUtils.readStream(is);
+ break;
+ }
+ case Content.XML_CONTENT :
+ {
+ Element element =
+ checkForSingleElement(((ContentXML) content).getXMLContent());
+ contentBytes = DOMUtils.serializeNode(element, "UTF-8");
+ break;
+ }
+ default :
+ contentBytes = null; // this will not happen
+ }
+ } catch (MOAApplicationException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new MOAApplicationException("2219", null);
+ }
+
+ // try to parse validating
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(contentBytes);
+ Document doc =
+ DOMUtils.parseDocument(
+ is,
+ true,
+ Constants.ALL_SCHEMA_LOCATIONS,
+ null,
+ entityResolver,
+ new MOAErrorHandler());
+
+ return new XMLDataObjectImpl(doc.getDocumentElement());
+ } catch (Exception e) {
+ // never mind, we'll try non-validating
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.info(new LogMsg(msg.getMessage("invoker.00", null)));
+ }
+
+ // try to parse non-validating
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(contentBytes);
+ Document doc = DOMUtils.parseDocument(is, false, null, null);
+ return new XMLDataObjectImpl(doc.getDocumentElement());
+ } catch (Exception e) {
+ throw new MOAApplicationException("2218", null);
+ }
+ }
+
+ /**
+ * Create an <code>XMLDataObject</code> from the given signature environment.
+ *
+ * @param signatureEnvironment The signature environment contained in the
+ * result.
+ * @param uri The URI identifying the data. This must be either the empty
+ * URI, an URI starting with <code>"#xpointer"</code>, <code>"#xmlns"</code>
+ * or <code>"#element"</code>; or an URI starting with <code>"#"</code> and
+ * followed by an element ID.
+ * @param referenceID The reference ID to set for the data object.
+ * @return A data object containing the signature environment.
+ */
+ public DataObject createFromSignatureEnvironment(
+ Element signatureEnvironment,
+ String uri,
+ String referenceID)
+ throws MOAApplicationException {
+
+ DataObjectImpl dataObject = null;
+
+ if ("".equals(uri)) {
+ dataObject = new XMLDataObjectImpl(signatureEnvironment);
+ } else if (
+ uri.startsWith("#xpointer")
+ || uri.startsWith("#xmlns")
+ || uri.startsWith("#element")) {
+ try {
+ XPointerReferenceResolver resolver = new XPointerReferenceResolver();
+ URI uriObj = new URI(uri);
+ NodeList nodes =
+ resolver.resolveForest(
+ uriObj,
+ signatureEnvironment.getOwnerDocument(),
+ null);
+ dataObject = new XMLNodeListDataObjectImpl(nodes);
+ } catch (Exception e) {
+ throw new MOAApplicationException("2237", new Object[] { uri });
+ }
+ } else if (uri.startsWith("#")) {
+ String id = uri.substring(1);
+ Element refElem =
+ signatureEnvironment.getOwnerDocument().getElementById(id);
+
+ if (refElem == null) {
+ throw new MOAApplicationException("2237", new Object[] { id });
+ }
+ dataObject = new XMLDataObjectImpl(refElem);
+ }
+
+ dataObject.setReferenceID(referenceID);
+ dataObject.setURI(uri);
+
+ return dataObject;
+ }
+
+ /**
+ * Build a <code>StreamEntityResolver</code> from a <code>List</code> of
+ * supplements.
+ *
+ * @param supplements The supplements, given as
+ * <code>XMLDataObjectAssociation</code>s.
+ * @return A <code>StreamEntityResolver</code> mapping the supplements by
+ * their reference URI to an <code>InputStream</code> of their respective
+ * content.
+ */
+ private static StreamEntityResolver buildSupplementEntityResolver(List supplements) {
+ Map entities = new HashMap();
+ Iterator iter;
+
+ for (iter = supplements.iterator(); iter.hasNext();) {
+ XMLDataObjectAssociation supplement =
+ (XMLDataObjectAssociation) iter.next();
+ Content content = supplement.getContent();
+ String reference = content.getReference();
+
+ switch (content.getContentType()) {
+ case Content.BINARY_CONTENT :
+ entities.put(reference, ((ContentBinary) content).getBinaryContent());
+ break;
+ case Content.XML_CONTENT :
+ // serialize the first element node that is found in the supplement
+ // and make it available as a stream
+ NodeList nodes = ((ContentXML) content).getXMLContent();
+ int i = 0;
+
+ // find the first element node
+ while (i < nodes.getLength()
+ && nodes.item(i).getNodeType() != Node.ELEMENT_NODE)
+ i++;
+
+ // serialize the node
+ if (i < nodes.getLength()) {
+ try {
+ byte[] serialized =
+ DOMUtils.serializeNode(nodes.item(i), "UTF-8");
+ entities.put(reference, new ByteArrayInputStream(serialized));
+ } catch (Exception e) {
+ // serializing the element failed - just don't put it in the map
+ }
+ }
+
+ break;
+ }
+ }
+
+ return new StreamEntityResolver(entities);
+ }
+
+ /**
+ * Create a <code>DataObject</code> from a <code>Content</code> object.
+ *
+ * @param content The <code>Content</code> object containing the data.
+ * @param referenceID The reference ID to set in the resulting
+ * <code>DataObject</code>. May be <code>null</code>.
+ * @param allowContentAndReference If <code>true</code>, then
+ * <code>content</code> is allowed to contain both a <code>Reference</code>
+ * attribute and content. Otherwise, either a <code>Reference</code>
+ * attribute or content must be set.
+ * @param binaryAsXml If <code>true</code>, a content child given as
+ * <code>Base64Content</code> must contain XML data.
+ * @param xmlAsNodeList If <code>true</code>, the children of a
+ * <code>XMLContent</code> child element are returned as a
+ * <code>XMLNodeListDataObject</code>. Otherwise, <code>XMLContent</code> may
+ * only contain a single child node, which must be an element and which is
+ * returned as an <code>XMLDataObject</code>.
+ * @param referenceAsXml If <code>true</code>, then content loaded from the
+ * URI given as the <code>Reference</code> attribute must be XML data.
+ * If <code>false</code>, an attempt is made to parse the data as XML and
+ * return an <code>XMLDataObject</code> but if this fails, a
+ * <code>BinaryDataObject</code> is returned containing a byte stream to the
+ * data.
+ * @return A <code>DataObject</code> representing the data in
+ * <code>content</code>. If <code>base64AsXml==true</code> and
+ * <code>xmlAsNodeList==false</code> and <code>referenceAsXml==true</code>,
+ * then the result can safely be cast to an <code>XMLDataObject</code>.
+ * @throws MOASystemException An error indicating an internal problem. See the
+ * wrapped exception for details.
+ * @throws MOAApplicationException An error occurred handling the content
+ * (probably while opening a reference or parsing the data). See the wrapped
+ * exception for details.
+ */
+ public DataObject createFromContentOptionalRefType(
+ Content content,
+ String referenceID,
+ boolean allowContentAndReference,
+ boolean binaryAsXml,
+ boolean xmlAsNodeList,
+ boolean referenceAsXml)
+ throws MOASystemException, MOAApplicationException {
+
+ String reference = content.getReference();
+ DataObjectImpl dataObject = null;
+
+ checkAllowContentAndReference(content, allowContentAndReference);
+
+ // ok, build the data object; use content first, if available
+ switch (content.getContentType()) {
+ case Content.XML_CONTENT :
+ ContentXML contentXml = (ContentXML) content;
+ dataObject = createFromXmlContent(contentXml, xmlAsNodeList);
+ break;
+ case Content.BINARY_CONTENT :
+ ContentBinary contentBinary = (ContentBinary) content;
+ dataObject = createFromBinaryContent(contentBinary, binaryAsXml, false);
+ break;
+ case Content.REFERENCE_CONTENT :
+ dataObject = createFromURIImpl(reference, referenceAsXml);
+ break;
+ }
+
+ // set URI and reference ID
+ dataObject.setURI(content.getReference());
+ dataObject.setReferenceID(referenceID);
+
+ return dataObject;
+ }
+
+ /**
+ * Check, if content and reference URIs are allowed in the content an throw
+ * an exception if an illegal combination of the two occurs.
+ *
+ * @param content The <code>Content</code> to check.
+ * @param allowContentAndReference Whether explicit content and a reference
+ * are allowed at the same time.
+ * @throws MOAApplicationException If <code>allowContentAndRefernece</code>
+ * is <code>false</code> and both explicit content and reference are set,
+ * an exception is thrown.
+ */
+ private static void checkAllowContentAndReference(
+ Content content,
+ boolean allowContentAndReference)
+ throws MOAApplicationException {
+ String reference = content.getReference();
+
+ // check for content and reference not being set
+ if (content.getContentType() == Content.REFERENCE_CONTENT
+ && reference == null) {
+ String errorCode = allowContentAndReference ? "1111" : "1110";
+ throw new MOAApplicationException(errorCode, null);
+ }
+
+ // if we only allow either content or reference being set at once, check
+ if (!allowContentAndReference
+ && (content.getContentType() != Content.REFERENCE_CONTENT)
+ && (reference != null)) {
+ throw new MOAApplicationException("1110", null);
+ }
+ }
+
+ /**
+ * Create a <code>DataObject</code> from a
+ * <code>XMLDataObjectAssociation</code> object.
+ *
+ * @param xmlDataObjAssoc The <code>XMLDataObjectAssociation</code> object.
+ * @param xmlContentAllowed Whether the content contained in the
+ * <code>xmlDataObjAssoc</code> is allowed to be of type
+ * <code>XML_CONTENT</code>.
+ * @param binaryContentRepeatable If binary content must be provided as a
+ * <code>DataObject</code> that can be read multiple times.
+ * @return A <code>DataObject</code> representing the data in
+ * <code>xmlDataObjAssoc</code>.
+ * @throws MOASystemException An error indicating an internal problem. See the
+ * wrapped exception for details.
+ * @throws MOAApplicationException An error occurred handling the content
+ * (probably while parsing the data). See the wrapped exception for details.
+ */
+ public DataObject createFromXmlDataObjectAssociation(
+ XMLDataObjectAssociation xmlDataObjAssoc,
+ boolean xmlContentAllowed,
+ boolean binaryContentRepeatable)
+ throws MOASystemException, MOAApplicationException {
+
+ Content content = xmlDataObjAssoc.getContent();
+ MetaInfo metaInfo = xmlDataObjAssoc.getMetaInfo();
+ String mimeType = metaInfo != null ? metaInfo.getMimeType() : null;
+ DataObjectImpl dataObject = null;
+
+ switch (content.getContentType()) {
+ case Content.XML_CONTENT :
+ if (xmlContentAllowed) {
+ dataObject = createFromXmlContent((ContentXML) content, true);
+ } else {
+ throw new MOAApplicationException("2280", null);
+ }
+ break;
+ case Content.BINARY_CONTENT :
+ dataObject =
+ createFromBinaryContent(
+ (ContentBinary) content,
+ false,
+ binaryContentRepeatable);
+ break;
+ }
+
+ dataObject.setURI(content.getReference());
+ dataObject.setMimeType(mimeType);
+ return dataObject;
+ }
+
+ /**
+ * Create a <code>DataObject</code> from a <code>TransformParameter</code>
+ * object.
+ *
+ * @param transformParameter The <code>TransformParameter</code> object
+ * containing the data.
+ * @return A <code>DataObject</code> representing the data in
+ * <code>root</code>.
+ * @throws MOASystemException An error indicating an internal problem. See the
+ * wrapped exception for details.
+ * @throws MOAApplicationException An error occurred handling the content
+ * (probably while opening a reference or parsing the data). See the wrapped
+ * exception for details.
+ */
+ public DataObject createFromTransformParameter(TransformParameter transformParameter)
+ throws MOASystemException, MOAApplicationException {
+
+ DataObjectImpl dataObject;
+
+ switch (transformParameter.getTransformParameterType()) {
+ case TransformParameter.BINARY_TRANSFORMPARAMETER :
+ TransformParameterBinary tpBinary =
+ (TransformParameterBinary) transformParameter;
+
+ try {
+ //dataObject = new ByteArrayDataObjectImpl(Base64Utils.encode(tpBinary.getBinaryContent()));
+ dataObject =
+ new ByteArrayDataObjectImpl(
+ StreamUtils.readStream(tpBinary.getBinaryContent()));
+ } catch (Exception e) {
+ return null;
+ }
+ //dataObject = new ByteStreamDataObjectImpl(tpBinary.getBinaryContent());
+ break;
+ default :
+ // resolve uri and build the content
+ ExternalURIResolver resolver = new ExternalURIResolver();
+ InputStream is = resolver.resolve(transformParameter.getURI());
+ String contentType = resolver.getContentType();
+ dataObject = new ByteStreamDataObjectImpl(is);
+ dataObject.setMimeType(contentType);
+ break;
+ }
+
+ dataObject.setURI(transformParameter.getURI());
+
+ return dataObject;
+ }
+
+ /**
+ * Create a <code>DataObject</code> from data located at the given URI.
+ *
+ * @param uri The <code>URI</code> where the data is located. This method uses
+ * an <code>ExternalURIResolver</code> to resolve URIs.
+ * @param asXml If <code>true</code>, a <code>DataObject</code> is only
+ * returned, if the content consists of XML data. If it does not consist of
+ * XML data, an <code>MOAApplicationException</code> will be thrown. If this
+ * parameter is <code>false</code> and the content consists of XML data, this
+ * method will still attempt to parse it.
+ * @return The <code>DataObject</code> contained at the URI.
+ * @throws MOASystemException A system error parsing the XML content.
+ * @throws MOAApplicationException An error occurred on opening, reading or
+ * parsing the data behind the URI.
+ */
+ public DataObject createFromURI(String uri, boolean asXml)
+ throws MOASystemException, MOAApplicationException {
+ return createFromURIImpl(uri, asXml);
+ }
+
+ /**
+ * Create a <code>DataObject</code> from data located at the given URI.
+ *
+ * @param uri The <code>URI</code> where the data is located. This method uses
+ * an <code>ExternalURIResolver</code> to resolve URIs.
+ * @param asXml If <code>true</code>, a <code>DataObject</code> is only
+ * returned, if the content consists of XML data. If it does not consist of
+ * XML data, an <code>MOAApplicationException</code> will be thrown. If this
+ * parameter is <code>false</code> and the content type is detected as being
+ * XML data, this method will still attemt to parse it.
+ * @return The <code>DataObject</code> contained at the URI.
+ * @throws MOASystemException A system error parsing the XML content.
+ * @throws MOAApplicationException An error occurred on opening, reading or
+ * parsing the data behind the URI.
+ */
+ private DataObjectImpl createFromURIImpl(String uri, boolean asXml)
+ throws MOASystemException, MOAApplicationException {
+
+ ExternalURIResolver resolver = new ExternalURIResolver();
+ InputStream is = resolver.resolve(uri);
+ String contentType = resolver.getContentType();
+ DataObjectImpl dataObject;
+
+ // read the content
+ if (contentType != null && contentTypeIsXml(contentType)) {
+ Document doc;
+
+ if (asXml) {
+ try {
+ // try parsing non-validating: this has to succeed or we
+ // bail out by throwing an exception
+ is = resolver.resolve(uri);
+ doc = DOMUtils.parseDocument(is, false, null, null);
+ dataObject = new XMLDataObjectImpl(doc.getDocumentElement());
+ } catch (ParserConfigurationException e) {
+ throw new MOASystemException("1106", null, e);
+ } catch (SAXException e) {
+ throw new MOAApplicationException("2209", null, e);
+ } catch (IOException e) {
+ throw new MOAApplicationException("2210", null, e);
+ }
+ } else {
+ try {
+ // try parsing non-validating: need not succeed
+ is = resolver.resolve(uri);
+ doc = DOMUtils.parseDocument(is, false, null, null);
+ dataObject = new XMLDataObjectImpl(doc.getDocumentElement());
+ } catch (Exception e) {
+ // this is the last chance: return the data as a byte stream
+ is = resolver.resolve(uri);
+ dataObject = new ByteStreamDataObjectImpl(is);
+ }
+ }
+ } else if (asXml) {
+ // if we need XML data, we're in the wrong place here
+ throw new MOAApplicationException("2211", new Object[] { uri });
+ } else {
+ // content is binary: make it available as a binary input stream
+ dataObject = new ByteStreamDataObjectImpl(is);
+ }
+
+ dataObject.setMimeType(contentType);
+ dataObject.setURI(uri);
+
+ return dataObject;
+ }
+
+ /**
+ * Determine whether the content type is XML.
+ *
+ * Content types recognized as XML start with <code>text/xml</code> and
+ * <code>application/xml</code>.
+ *
+ * @param contentType The content MIME type.
+ * @return boolean If <code>true</code>, the content type is XML, otherwise
+ * not.
+ */
+ private static boolean contentTypeIsXml(String contentType) {
+ return contentType.startsWith("text/xml")
+ || (contentType.startsWith("application/xml"));
+ }
+
+ /**
+ * Create a <code>DataObject</code> from a <code>ContentXML</code> object.
+ *
+ * @param xmlContent The <code>ContentXML</code> object from
+ * which the <code>DataObject</code> is to be built.
+ * @param xmlAsNodeList If <code>true</code>, the children of
+ * <code>xmlContent</code> are returned as a
+ * <code>XMLNodeListDataObject</code>. Otherwise,
+ * <code>xmlContent</code> may only contain a single child node, which must be
+ * an element and which is returned as an <code>XMLDataObject</code>.
+ * @return A <code>DataObject</code> representing the XML content in
+ * <code>xmlContent</code>.
+ * @throws MOAApplicationException If <code>xmlAsNodeList</code> is
+ * <code>false</code> and <code>xmlContent</code> does not have a single child
+ * element.
+ */
+ private DataObjectImpl createFromXmlContent(
+ ContentXML xmlContent,
+ boolean xmlAsNodeList)
+ throws MOAApplicationException {
+
+ DataObjectImpl dataObject;
+
+ if (xmlAsNodeList) {
+ dataObject = new XMLNodeListDataObjectImpl(xmlContent.getXMLContent());
+ } else {
+ NodeList nodes = xmlContent.getXMLContent();
+ Element element = checkForSingleElement(nodes);
+
+ // build the XMLDataObject
+ dataObject = new XMLDataObjectImpl(element);
+ }
+ return dataObject;
+ }
+
+ /**
+ * Check, that the given <code>NodeList</code> contains a single DOM element
+ * node and return it, otherwise throw an exception.
+ *
+ * @param nodes The <code>NodeList</code> to check for a single element.
+ * @return The single element contained in <code>nodes</code>.
+ * @throws MOAApplicationException Thrown, if <code>nodes</code> does not
+ * contain exactly 1 element node.
+ */
+ private Element checkForSingleElement(NodeList nodes)
+ throws MOAApplicationException {
+
+ Element element = null;
+ int i;
+
+ // check for a single element node
+ for (i = 0; i < nodes.getLength(); i++) {
+ if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ if (element == null) {
+ element = (Element) nodes.item(i);
+ } else {
+ throw new MOAApplicationException("1109", null);
+ }
+ }
+ }
+
+ // return the element node
+ if (element == null) {
+ throw new MOAApplicationException("1107", null);
+ } else {
+ return element;
+ }
+ }
+
+ /**
+ * Create a <code>DataObject</code> from a <code>ContentBinary</code> object.
+ *
+ * @param binaryContent The <code>ContentBinary</code> object containing the
+ * data.
+ * @param asXml If <code>true</code>, <code>binaryContent</code> must
+ * contain XML data. Otherwise, a <code>BinaryDataObject</code> will be
+ * returned containing a byte stream to the decoded Base64 data.
+ * @param repeatable If multiple calls to <code>getInputStream()</code> must
+ * repeatedly return the content of the data object.
+ * @return A <code>DataObject</code> representing the content contained in
+ * <code>binaryContent</code>.
+ * @throws MOASystemException An error indicating an internal problem. See the
+ * wrapped exception for details.
+ * @throws MOAApplicationException An error occurred handling the content
+ * (probably while parsing the data). See the wrapped exception for details.
+ */
+ private DataObjectImpl createFromBinaryContent(
+ ContentBinary binaryContent,
+ boolean asXml,
+ boolean repeatable)
+ throws MOASystemException, MOAApplicationException {
+
+ InputStream byteStream = binaryContent.getBinaryContent();
+ DataObjectImpl dataObject;
+
+ if (asXml) {
+ Document doc;
+
+ try {
+ doc = DOMUtils.parseDocument(byteStream, false, null, null);
+ dataObject = new XMLDataObjectImpl(doc.getDocumentElement());
+ } catch (ParserConfigurationException e) {
+ throw new MOASystemException("1106", null, e);
+ } catch (SAXException e) {
+ throw new MOAApplicationException("2209", null, e);
+ } catch (IOException e) {
+ throw new MOAApplicationException("2210", null, e);
+ }
+ } else {
+ if (repeatable) {
+ try {
+ dataObject =
+ new ByteArrayDataObjectImpl(StreamUtils.readStream(byteStream));
+ } catch (IOException e) {
+ throw new MOAApplicationException("2210", null);
+ }
+ } else {
+ dataObject = new ByteStreamDataObjectImpl(byteStream);
+ }
+ }
+
+ return dataObject;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java
new file mode 100644
index 000000000..806b76409
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java
@@ -0,0 +1,127 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+
+import iaik.ixsil.exceptions.URIException;
+import iaik.ixsil.util.URI;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+
+/**
+ * Resolve external URIs and provide them as a stream.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ExternalURIResolver {
+
+ /** The MIME type of the content currently resolved. */
+ private String contentType;
+
+ /**
+ * Return a stream to data at the given URI.
+ *
+ * This method will try to open an <code>URLConnection</code> to the given
+ * URI. Access to the file system is disallowed.
+ *
+ * @param uriStr The URI to resolve.
+ * @return InputStream The data contained at the URI.
+ * @throws MOAApplicationException An error occurred resolving the URI (e.g.,
+ * the URI is syntactically incorrect or the stream could not be opened).
+ */
+ public InputStream resolve(String uriStr) throws MOAApplicationException {
+ URI uri;
+ URL url;
+ URLConnection connection;
+ InputStream is;
+
+ // build the URI
+ try {
+ uri = new URI(uriStr);
+ } catch (URIException e) {
+ throw new MOAApplicationException("2207", new Object[] { uriStr });
+ }
+
+ // disallow access to local file system
+ if ("".equals(uri.getScheme()) || "file".equals(uri.getScheme())) {
+ throw new MOAApplicationException("2213", new Object[] { uriStr });
+ }
+
+ // convert URI to URL
+ try {
+ // create the URL
+ url = new URL(uriStr);
+ } catch (MalformedURLException e) {
+ throw new MOAApplicationException("2214", new Object[] { uriStr });
+ }
+
+ // build the URLConnection
+ try {
+ connection = url.openConnection();
+ if ("http".equals(url.getProtocol())) {
+ HttpURLConnection httpConnection = (HttpURLConnection) connection;
+
+ httpConnection.connect();
+ if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ throw new MOAApplicationException("2208", new Object[] { uri });
+ }
+ } else if ("https".equals(url.getProtocol())) {
+ /*
+ * this doesn't work because of some interaction between the IAIK
+ * JCE and Sun JSSE that results in an "Invalid AVA format" exception
+ */
+
+ /*
+ HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
+ InputStream trustStore =
+ getClass().getResourceAsStream(DEFAULT_TRUST_STORE);
+ SSLSocketFactory factory =
+ SSLUtils.getSSLSocketFactory("jks", trustStore, "changeit");
+ httpsConnection.setSSLSocketFactory(factory);
+ httpsConnection.connect();
+ if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ throw new MOAApplicationException("2208", new Object[] { uri });
+ }
+ */
+ connection.connect();
+ } else {
+ connection.connect();
+ }
+ is = connection.getInputStream();
+ } catch (IOException e) {
+ throw new MOAApplicationException("2208", new Object[] { uri }, e);
+ } /*catch (GeneralSecurityException e) {
+ throw new MOAApplicationException("2208", new Object[] { uri }, e);
+ }*/
+
+ // set the content type
+ setContentType(connection.getContentType());
+
+ return is;
+ }
+
+ /**
+ * Set the content type of the data at the URI.
+ *
+ * @param contentType The content type to set.
+ */
+ protected void setContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+ /**
+ * Return the content type of the data detected at the URI from the previous
+ * call of <code>resolve()</code>.
+ *
+ * @return String The content type.
+ */
+ public String getContentType() {
+ return contentType;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java
new file mode 100644
index 000000000..60f573e5a
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java
@@ -0,0 +1,267 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+
+import iaik.IAIKException;
+import iaik.IAIKRuntimeException;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+
+
+/**
+ * Map an exception from the <code>iaik</code> namespace to a
+ * <code>MOAException</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class IaikExceptionMapper {
+
+ /** The argument classes for <code>MOAException</code>s. */
+ private static final Class[] CONSTRUCTOR_ARGS =
+ new Class[] { String.class, Object[].class, Throwable.class };
+ /** The exception mapping, as an array. */
+ private static final Object[][] MESSAGES =
+ {
+ { iaik.IAIKException.class, "9900", MOASystemException.class },
+ { iaik.IAIKRuntimeException.class, "9901", MOASystemException.class },
+ { iaik.server.modules.xmlsign.XMLSignatureCreationException.class, "2220", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.XMLSignatureCreationRuntimeException.class, "2220", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.InvalidKeyException.class, "2221", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.ManifestException.class, "2222", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.ReferenceException.class, "2223", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.HashUnavailableException.class, "2224", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.SignatureAlgorithmException.class, "2225", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.SignatureEmbeddingException.class, "2226", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.SignatureValueException.class, "2227", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.SignedPropertyException.class, "2228", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.SignerCertificateUnavailableException.class, "2229", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.SupplementException.class, "2230", MOAApplicationException.class },
+ { iaik.server.modules.xmlsign.TransformationException.class, "2233", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.CMSSignatureVerificationException.class, "2240", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.CMSSignatureVerificationRuntimeException.class, "2240", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.AlgorithmNotSupportedException.class, "2241", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.CMSSignatureParsingException.class, "2242", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.SignerCertificateUnavailableException.class, "2243", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.CMSSignatureVerificationRuntimeException.class, "2247", MOAApplicationException.class },
+ { iaik.server.modules.cmsverify.InitException.class, "2248", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.XMLSignatureVerificationException.class, "2240", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.XMLSignatureVerificationRuntimeException.class, "2240", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.AlgorithmNotSupportedException.class, "2241", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.ManifestException.class, "2262", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.PropertiesException.class, "2263", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.ReferenceException.class, "2264", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.HashUnavailableException.class, "2224", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.SignerCertificateUnavailableException.class, "2243", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.SupplementException.class, "2230", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.TransformationException.class, "2265", MOAApplicationException.class },
+ { iaik.server.modules.xmlverify.TransformationParsingException.class, "2269", MOAApplicationException.class }
+ };
+
+ /** The single instance of this class. */
+ private static IaikExceptionMapper instance;
+ /** The exception mapping, as a <code>Map</code> for fast lookup. */
+ private Map messages = new HashMap();
+
+ /**
+ * Get the single instance of this class.
+ *
+ * @return The single instance of this class.
+ */
+ public static synchronized IaikExceptionMapper getInstance() {
+ if (instance == null) {
+ instance = new IaikExceptionMapper();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>IaikExceptionMapper</code>.
+ *
+ * Protected to disallow multple instances.
+ */
+ protected IaikExceptionMapper() {
+ registerMessages();
+ }
+
+ /**
+ * Build the complete <code>IAIKException</code> to message code mapping.
+ */
+ protected void registerMessages() {
+ int i;
+
+ for (i = 0; i < MESSAGES.length; i++) {
+ registerMessage(
+ (Class) MESSAGES[i][0],
+ (String) MESSAGES[i][1],
+ (Class) MESSAGES[i][2]);
+ }
+ }
+
+ /**
+ * Register a single <code>IAIKException</code> to message mapping.
+ *
+ * @param iaikExceptionClass An exception from the <code>iaik</code> package.
+ * @param messageId The corresponding error message id.
+ * @param moaExceptionClass The type of <code>MOAException</code> that the
+ * <code>IAIKException</code> is mapped to (usually
+ * <code>MOAApplicationException</code> or <code>MOASystemException</code>).
+ */
+ protected void registerMessage(
+ Class iaikExceptionClass,
+ String messageId,
+ Class moaExceptionClass) {
+
+ messages.put(
+ iaikExceptionClass,
+ new ExceptionMappingInfo(messageId, moaExceptionClass));
+ }
+
+ /**
+ * Map an <code>IAIKException</code> to a <code>MOAException</code>.
+ *
+ * @param iaikException The <code>IAIKException</code> to map.
+ * @return A <code>MOAException</code> containing the message for the
+ * given <code>IAIKException</code>.
+ */
+ public MOAException map(IAIKException iaikException) {
+ return mapImpl(iaikException);
+ }
+
+ /**
+ * Map an <code>IAIKRuntimeException</code> to a <code>MOAException</code>.
+ *
+ * @param iaikException The <code>IAIKException</code> to map.
+ * @return A <code>MOAException</code> containing the message for the
+ * given <code>IAIKRuntimeException</code>.
+ */
+ public MOAException map(IAIKRuntimeException iaikException) {
+ return mapImpl(iaikException);
+ }
+
+ /**
+ * Map an <code>IAIKException</code> or <code>IAIKRuntimeException</code> to a
+ * <code>MOAException</code>.
+ *
+ * @param iaikException The <code>IAIKException</code> or
+ * <code>IAIKRuntimeException</code> to map.
+ * @return A <code>MOAException</code> containing the message for the
+ * given <code>IAIKRuntimeException</code>.
+ */
+ private MOAException mapImpl(Exception iaikException) {
+ MOAException moaException = createMoaException(iaikException);
+
+ if (moaException == null) {
+ return new MOASystemException("9999", null, iaikException);
+ }
+ return moaException;
+ }
+
+ /**
+ * Create a <code>MOAException</code> from a given <code>IAIKException</code>
+ * by looking it up in the mapping.
+ *
+ * @param iaikException The <code>IAIKException</code> to map.
+ * @return A <code>MOAException</code> with an error code corresponding to
+ * the given <code>IAIKException</code>. Returns <code>null</code>, if no
+ * mapping could be found.
+ */
+ protected MOAException createMoaException(Exception iaikException) {
+ ExceptionMappingInfo info = lookupMessage(iaikException.getClass());
+ Constructor constructor;
+
+ if (info == null) {
+ return null;
+ }
+
+ // instantiate the proper MOAException and return it
+ try {
+ constructor =
+ info.getMoaExceptionClass().getConstructor(CONSTRUCTOR_ARGS);
+ return (MOAException) constructor.newInstance(
+ new Object[] {
+ info.getMessageId(),
+ new Object[] { iaikException.getMessage()},
+ iaikException });
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * Recursively look up the message associated with an
+ * <code>IAIKException</code>.
+ *
+ * This method walks up the exception inheritance hierarchy until it finds a
+ * mapping.
+ *
+ * @param iaikExceptionClass The <code>IAIKException</code> to look up.
+ * @return Information about the message id and
+ * <code>MOAException</code> class that the <code>iaikExceptionClass</code>
+ * maps to. If no mapping could be found, <code>null</code> is returned.
+ */
+ protected ExceptionMappingInfo lookupMessage(Class iaikExceptionClass) {
+ ExceptionMappingInfo info;
+
+ // break if
+ if (iaikExceptionClass.equals(Exception.class)) {
+ return null;
+ }
+
+ // look up the exception class
+ info = (ExceptionMappingInfo) messages.get(iaikExceptionClass);
+ if (info == null) {
+ return lookupMessage(iaikExceptionClass.getSuperclass());
+ }
+ return info;
+ }
+
+}
+
+/**
+ * A class containing a mapping from an error message ID to a
+ * <code>MOAException</code> class.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+class ExceptionMappingInfo {
+ /** The message ID. */
+ private String messageId;
+ /** The <code>MOAException</code> class. */
+ private Class moaExceptionClass;
+
+ /**
+ * Create a new <code>ExceptionMappingInfo</code>.
+ *
+ * @param messageId The message ID.
+ * @param moaExceptionClass The <code>MOAException</code> class.
+ */
+ public ExceptionMappingInfo(String messageId, Class moaExceptionClass) {
+ this.messageId = messageId;
+ this.moaExceptionClass = moaExceptionClass;
+ }
+
+ /**
+ * Return the message ID.
+ *
+ * @return The message ID.
+ */
+ public String getMessageId() {
+ return messageId;
+ }
+
+ /**
+ * Returns the <code>MOAException</code> class that the message ID maps to.
+ *
+ * @return The <code>MOAException</code> class.
+ */
+ public Class getMoaExceptionClass() {
+ return moaExceptionClass;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java
new file mode 100644
index 000000000..0c3b45539
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java
@@ -0,0 +1,63 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.util.XPathException;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.common.ElementSelector;
+
+/**
+ * Utility methods for invoking the IAIK MOA modules.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class InvokerUtils {
+
+ /**
+ * Select the signature parent element.
+ *
+ * @param root The root DOM element which contains the signature parent
+ * element somewhere in its subtree.
+ * @param location The <code>ElementSelector</code> containing the XPath
+ * expression to select the signature parent element from the document.
+ * It is also contains the namespace prefix to URI mapping.
+ * @return Element The signature parent element.
+ * @throws MOAApplicationException An error occurred evaluating the
+ * <code>location</code>.
+ */
+ public static Element evaluateSignatureLocation(
+ Element root,
+ ElementSelector location)
+ throws MOAApplicationException {
+
+ NodeList nodes;
+
+ try {
+ nodes =
+ XPathUtils.selectNodeList(
+ root,
+ location.getNamespaceDeclarations(),
+ location.getXPathExpression());
+ } catch (XPathException e) {
+ throw new MOAApplicationException(
+ "2212",
+ new Object[] { location.getXPathExpression()},
+ e);
+ }
+
+ if (nodes.getLength() != 1
+ || !(nodes.item(0).getNodeType() == Node.ELEMENT_NODE)) {
+ throw new MOAApplicationException(
+ "2212",
+ new Object[] { location.getXPathExpression()});
+ }
+ return (Element) nodes.item(0);
+ }
+
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java
new file mode 100644
index 000000000..158a3ddb5
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java
@@ -0,0 +1,249 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.xmlbind.ProfileParser;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileID;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileID;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileID;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileID;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * Map ProfileID objects to their explicit represantation.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ProfileMapper {
+
+ /** The parser to parse the profiles. */
+ private static ProfileParser profileParser = new ProfileParser();
+
+ /**
+ * Map a <code>CreateTransformsInfoProfile</code> to a
+ * <code>CreateTransformsInfoProfileExplicit</code>.
+ *
+ * @param profile The profile object to map.
+ * @param config The MOA configuration to use for looking up the profile.
+ * @return <code>profile</code>, if the given profile is of type
+ * <code>EXPLICIT_CREATETRANSFORMSINFOPROFILE</code>, otherwise the profile
+ * that is looked up and parsed from the configuration.
+ * @throws MOAApplicationException An error occurred parsing the profile.
+ */
+ public static CreateTransformsInfoProfileExplicit mapCreateTransformsInfoProfile(
+ CreateTransformsInfoProfile profile,
+ ConfigurationProvider config)
+ throws MOAApplicationException {
+
+ switch (profile.getCreateTransformsInfoProfileType()) {
+ case CreateTransformsInfoProfile.EXPLICIT_CREATETRANSFORMSINFOPROFILE :
+ return (CreateTransformsInfoProfileExplicit) profile;
+
+ case CreateTransformsInfoProfile.ID_CREATETRANSFORMSINFOPROFILE :
+ CreateTransformsInfoProfileID profileIdObj =
+ (CreateTransformsInfoProfileID) profile;
+ String profileID = profileIdObj.getCreateTransformsInfoProfileID();
+ Element profileElem = config.getCreateTransformsInfoProfile(profileID);
+
+ if (profileElem == null) {
+ throw new MOAApplicationException("2234", new Object[] { profileID });
+ }
+
+ return (
+ CreateTransformsInfoProfileExplicit) profileParser
+ .parseCreateTransformsInfoProfile(
+ profileElem);
+ }
+ return null; // this will not happen
+ }
+
+ /**
+ * Map a <code>CreateSignatureEnvironmentProfile</code> to a
+ * <code>CreateSignatureEnvironmentProfileExplicit</code>.
+ *
+ * @param profile The profile object to map.
+ * @param config The MOA configuration to use for looking up the profile.
+ * @return <code>profile</code>, if the given profile is of type
+ * <code>EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE</code>, otherwise the
+ * profile that is looked up and parsed from the configuration.
+ * @throws MOAApplicationException An error occurred parsing the profile.
+ */
+ public static CreateSignatureEnvironmentProfileExplicit mapCreateSignatureEnvironmentProfile(
+ CreateSignatureEnvironmentProfile profile,
+ ConfigurationProvider config)
+ throws MOAApplicationException {
+
+ switch (profile.getCreateSignatureEnvironmentProfileType()) {
+ case CreateSignatureEnvironmentProfile
+ .EXPLICIT_CREATESIGNATUREENVIRONMENTPROFILE :
+
+ return (CreateSignatureEnvironmentProfileExplicit) profile;
+
+ case CreateSignatureEnvironmentProfile
+ .ID_CREATESIGNATUREENVIRONMENTPROFILE :
+
+ CreateSignatureEnvironmentProfileID profileIdObj =
+ (CreateSignatureEnvironmentProfileID) profile;
+ String profileID =
+ profileIdObj.getCreateSignatureEnvironmentProfileID();
+ Element profileElem =
+ config.getCreateSignatureEnvironmentProfile(profileID);
+
+ if (profileElem == null) {
+ throw new MOAApplicationException("2236", new Object[] { profileID });
+ }
+
+ return (
+ CreateSignatureEnvironmentProfileExplicit) profileParser
+ .parseCreateSignatureEnvironmentProfile(
+ profileElem);
+
+ }
+ return null;
+
+ }
+
+ /**
+ * Map a <code>List</code> of <code>SupplementProfile</code>s to their
+ * explicit representation.
+ *
+ * @param profiles The profiles to map.
+ * @param config The MOA configuration to use for looking up profiles.
+ * @return The mapped profiles.
+ * @throws MOAApplicationException An error occurred mapping one of the
+ * profiles.
+ */
+ public static List mapSupplementProfiles(
+ List profiles,
+ ConfigurationProvider config)
+ throws MOAApplicationException {
+
+ List mappedProfiles = new ArrayList();
+ Iterator iter;
+
+ for (iter = profiles.iterator(); iter.hasNext();) {
+ SupplementProfile profile = (SupplementProfile) iter.next();
+ mappedProfiles.add(mapSupplementProfile(profile, config));
+ }
+
+ return mappedProfiles;
+ }
+
+ /**
+ * Map a <code>SupplementProfile</code> to a
+ * <code>SupplementProfileExplicit</code>.
+ *
+ * @param profile The profile object to map.
+ * @param config The MOA configuration to use for looking up the profile.
+ * @return <code>profile</code>, if the given profile is of type
+ * <code>EXPLICIT_SUPPLEMENTPROFILE</code>, otherwise the
+ * profile that is looked up and parsed from the configuration.
+ * @throws MOAApplicationException An error occurred parsing the profile.
+ */
+ public static SupplementProfileExplicit mapSupplementProfile(
+ SupplementProfile profile,
+ ConfigurationProvider config)
+ throws MOAApplicationException {
+
+ switch (profile.getSupplementProfileType()) {
+ case SupplementProfile.EXPLICIT_SUPPLEMENTPROFILE :
+ return (SupplementProfileExplicit) profile;
+
+ case SupplementProfile.ID_SUPPLEMENTPROFILE :
+ SupplementProfileID profileIdObj = (SupplementProfileID) profile;
+ String profileID = profileIdObj.getSupplementProfileID();
+ Element profileElem = config.getSupplementProfile(profileID);
+
+ if (profileElem == null) {
+ throw new MOAApplicationException("2267", new Object[] { profileID });
+ }
+
+ return (
+ SupplementProfileExplicit) profileParser.parseSupplementProfile(
+ profileElem);
+ }
+
+ return null;
+ }
+
+ /**
+ * Map a <code>List</code> of <code>VerifyTransformsInfoProfile</code>s to
+ * their explicit representation.
+ *
+ * @param profiles The profiles to map.
+ * @param config The MOA configuration to use for looking up profiles.
+ * @return The mapped profiles.
+ * @throws MOAApplicationException An error occurred mapping one of the
+ * profiles.
+ */
+ public static List mapVerifyTransformsInfoProfiles(
+ List profiles,
+ ConfigurationProvider config)
+ throws MOAApplicationException {
+
+ List mappedProfiles = new ArrayList();
+ Iterator iter;
+
+ for (iter = profiles.iterator(); iter.hasNext();) {
+ VerifyTransformsInfoProfile profile =
+ (VerifyTransformsInfoProfile) iter.next();
+ mappedProfiles.add(mapVerifyTransformsInfoProfile(profile, config));
+ }
+
+ return mappedProfiles;
+ }
+
+ /**
+ * Map a <code>VerifyTransformsInfoProfile</code> to a
+ * <code>VerifyTransformsInfoProfileExplicit</code>.
+ *
+ * @param profile The profile object to map.
+ * @param config The MOA configuration to use for looking up the profile.
+ * @return <code>profile</code>, if the given profile is of type
+ * <code>EXPLICIT_VERIFYTRANSFORMSINFOPROFILE</code>, otherwise the
+ * profile that is looked up and parsed from the configuration.
+ * @throws MOAApplicationException An error occurred parsing the profile.
+ */
+ public static VerifyTransformsInfoProfileExplicit mapVerifyTransformsInfoProfile(
+ VerifyTransformsInfoProfile profile,
+ ConfigurationProvider config)
+ throws MOAApplicationException {
+
+ switch (profile.getVerifyTransformsInfoProfileType()) {
+ case VerifyTransformsInfoProfile.EXPLICIT_VERIFYTRANSFORMSINFOPROFILE :
+ return (VerifyTransformsInfoProfileExplicit) profile;
+
+ case VerifyTransformsInfoProfile.ID_VERIFYTRANSFORMSINFOPROFILE :
+ VerifyTransformsInfoProfileID profileIdObj =
+ (VerifyTransformsInfoProfileID) profile;
+ String profileID = profileIdObj.getVerifyTransformsInfoProfileID();
+ Element profileElem =
+ config.getVerifyTransformsInfoProfile(profileID);
+
+ if (profileElem == null) {
+ throw new MOAApplicationException("2268", new Object[] { profileID });
+ }
+
+ return (
+ VerifyTransformsInfoProfileExplicit) profileParser
+ .parseVerifyTransformsInfoProfile(
+ profileElem);
+ }
+
+ return null;
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java
new file mode 100644
index 000000000..11f05a2f1
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java
@@ -0,0 +1,51 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+
+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.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+
+/**
+ * A utility class for setting up and tearing down thread-local context
+ * information needed for calling the <code>Invoker</code> classes.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ServiceContextUtils {
+
+ /**
+ * Set up the thread-local context information needed for calling the various
+ * <code>Invoker</code> classes.
+ *
+ * @throws ConfigurationException An error occurred setting up the
+ * configuration in the <code>TransactionContext</code>.
+ */
+ public static void setUpContexts() throws ConfigurationException {
+ TransactionContextManager txMgr = TransactionContextManager.getInstance();
+ LoggingContextManager logMgr = LoggingContextManager.getInstance();
+ String transactionID = Thread.currentThread().getName();
+
+ if (txMgr.getTransactionContext() == null) {
+ TransactionContext ctx = new TransactionContext(transactionID, null, ConfigurationProvider.getInstance());
+ txMgr.setTransactionContext(ctx);
+ }
+
+ if (logMgr.getLoggingContext() == null) {
+ LoggingContext ctx = new LoggingContext(transactionID);
+ logMgr.setLoggingContext(ctx);
+ }
+ }
+
+ /**
+ * Tear down thread-local context information.
+ */
+ public static void tearDownContexts() {
+ TransactionContextManager.getInstance().setTransactionContext(null);
+ LoggingContextManager.getInstance().setLoggingContext(null);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java
new file mode 100644
index 000000000..dc5ceb21e
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java
@@ -0,0 +1,45 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.Collections;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.Configurator;
+import at.gv.egovernment.moa.spss.api.SignatureCreationService;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse;
+
+/**
+ * An implementation of the <code>SignatureCreationService</code>, using
+ * the <code>XMLSignatureCreationInvoker</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SignatureCreationServiceImpl extends SignatureCreationService {
+
+ /**
+ * Create an XML signature.
+ *
+ * @param request The <code>CreateXMLSignatureRequest</code> containing
+ * information about the signature(s) to create.
+ * @return The created signature(s).
+ * @throws MOAException An error occurred creating the signature(s).
+ */
+ public CreateXMLSignatureResponse createXMLSignature(CreateXMLSignatureRequest request)
+ throws MOAException {
+
+ XMLSignatureCreationInvoker invoker =
+ XMLSignatureCreationInvoker.getInstance();
+ CreateXMLSignatureResponse response;
+
+ try {
+ Configurator.getInstance().init();
+ ServiceContextUtils.setUpContexts();
+ response = invoker.createXMLSignature(request, Collections.EMPTY_SET);
+ return response;
+ } finally {
+ ServiceContextUtils.tearDownContexts();
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java
new file mode 100644
index 000000000..94cdea5d9
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java
@@ -0,0 +1,72 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.api.Configurator;
+import at.gv.egovernment.moa.spss.api.SignatureVerificationService;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+
+/**
+ * An implementation of the <code>SignatureVerificationService</code> using
+ * the <code>XMLSignatureVerificationInvoker</code> and the
+ * <code>CMSSignatureVerificationInvoker</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SignatureVerificationServiceImpl
+ extends SignatureVerificationService {
+
+ /**
+ * Verify a CMS signature.
+ *
+ * @param request The <code>VerifyCMSSignatureRequest</code> containing
+ * information about the signature verification.
+ * @return The result of the signature verification.
+ * @throws MOAException An error occurred during signature verification.
+ */
+ public VerifyCMSSignatureResponse verifyCMSSignature(VerifyCMSSignatureRequest request)
+ throws MOAException {
+
+ CMSSignatureVerificationInvoker invoker =
+ CMSSignatureVerificationInvoker.getInstance();
+ VerifyCMSSignatureResponse response;
+
+ try {
+ Configurator.getInstance().init();
+ ServiceContextUtils.setUpContexts();
+ response = invoker.verifyCMSSignature(request);
+ return response;
+ } finally {
+ ServiceContextUtils.tearDownContexts();
+ }
+ }
+
+ /**
+ * Verify an XML signature.
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> containinig
+ * information about the signature verification.
+ * @return The result of the signature verification.
+ * @throws MOAException An error occurred during signature verification.
+ */
+ public VerifyXMLSignatureResponse verifyXMLSignature(VerifyXMLSignatureRequest request)
+ throws MOAException {
+
+ XMLSignatureVerificationInvoker invoker =
+ XMLSignatureVerificationInvoker.getInstance();
+ VerifyXMLSignatureResponse response;
+
+ try {
+ Configurator.getInstance().init();
+ ServiceContextUtils.setUpContexts();
+ response = invoker.verifyXMLSignature(request);
+ return response;
+ } finally {
+ ServiceContextUtils.tearDownContexts();
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java
new file mode 100644
index 000000000..9984a95a5
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java
@@ -0,0 +1,258 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import iaik.server.modules.xml.Base64Transformation;
+import iaik.server.modules.xml.Canonicalization;
+import iaik.server.modules.xml.EnvelopedSignatureTransformation;
+import iaik.server.modules.xml.Transformation;
+import iaik.server.modules.xml.XPath2Transformation;
+import iaik.server.modules.xml.XPathTransformation;
+import iaik.server.modules.xml.XSLTTransformation;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.common.ExclusiveCanonicalizationTransform;
+import at.gv.egovernment.moa.spss.api.common.Transform;
+import at.gv.egovernment.moa.spss.api.common.XPathFilter;
+import at.gv.egovernment.moa.spss.api.common.XPathFilter2Transform;
+import at.gv.egovernment.moa.spss.api.common.XPathTransform;
+import at.gv.egovernment.moa.spss.api.common.XSLTTransform;
+import at.gv.egovernment.moa.spss.server.iaik.xml.Base64TransformationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.CanonicalizationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.EnvelopedSignatureTransformationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.ExclusiveCanonicalizationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XPath2FilterImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XPath2TransformationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XPathTransformationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XSLTTransformationImpl;
+
+/**
+ * A factory to create <code>Transformation</code> objects from
+ * <code>Transform</code> objects.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class TransformationFactory {
+
+
+ /** The single instance of this class. */
+ private static TransformationFactory instance = null;
+
+ /** Maps <code>XPathFilter</code> filter types to
+ * <code>XPath2Transformation</code> filter types. */
+ private static Map FILTER_TYPE_MAPPING;
+
+ static {
+ FILTER_TYPE_MAPPING = new HashMap();
+
+ FILTER_TYPE_MAPPING.put(
+ XPathFilter.INTERSECT_TYPE,
+ XPath2Transformation.XPath2Filter.INTERSECTION);
+ FILTER_TYPE_MAPPING.put(
+ XPathFilter.SUBTRACT_TYPE,
+ XPath2Transformation.XPath2Filter.SUBTRACTION);
+ FILTER_TYPE_MAPPING.put(
+ XPathFilter.UNION_TYPE,
+ XPath2Transformation.XPath2Filter.UNION);
+ }
+
+ /**
+ * Get the single instance of the factory.
+ *
+ * @return TransformationFactory The single instance.
+ */
+ public static synchronized TransformationFactory getInstance() {
+ if (instance == null) {
+ instance = new TransformationFactory();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>TransformationFactory</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected TransformationFactory() {
+ }
+
+ /**
+ * Create a <code>Transformation</code> based on a
+ * <code>Transform</code> object.
+ *
+ * @param transform The <code>Transform</code> object to extract
+ * transformation data from.
+ * @return The transformation contained in the <code>transform</code>
+ * object.
+ * @throws MOAApplicationException An error occured creating the
+ * <code>Transformation</code>. See exception message for details.
+ */
+ public Transformation createTransformation(Transform transform)
+ throws MOAApplicationException {
+ String algorithmUri = transform.getAlgorithmURI();
+
+ if (Canonicalization.CANONICAL_XML.equals(algorithmUri)
+ || Canonicalization.CANONICAL_XML_WITH_COMMENTS.equals(algorithmUri)) {
+ return createC14nTransformation(algorithmUri);
+ } else if (
+ Canonicalization.EXCLUSIVE_CANONICAL_XML.equals(algorithmUri)
+ || Canonicalization.EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS.equals(
+ algorithmUri)) {
+
+ return createExclusiveC14nTransformation(
+ (ExclusiveCanonicalizationTransform) transform);
+
+ } else if (Base64Transformation.ALL.contains(algorithmUri)) {
+ return createBase64Transformation();
+ } else if (EnvelopedSignatureTransformation.ALL.contains(algorithmUri)) {
+ return createEnvelopedSignatureTransformation();
+ } else if (XPathTransformation.ALL.contains(algorithmUri)) {
+ return createXPathTransformation((XPathTransform) transform);
+ } else if (XPath2Transformation.ALL.contains(algorithmUri)) {
+ return createXPath2Transformation((XPathFilter2Transform) transform);
+ } else if (XSLTTransformation.ALL.contains(algorithmUri)) {
+ return createXSLTTransformation((XSLTTransform) transform);
+ } else {
+ throw new MOAApplicationException("1108", new Object[] { algorithmUri });
+ }
+ }
+
+ /**
+ * Create a <code>List</code> of <code>Transformation</code>s from a
+ * <code>List</code> of <code>Transform</code>s.
+ *
+ * @param transforms The <code>List</code> containing the
+ * <code>Transform</code>s.
+ * @return The <code>List</code> of <code>Transformation</code>s corresponding
+ * to the <code>transforms</code>.
+ * @throws MOAApplicationException An error occurred building one of the
+ * transformations. See exception message for details.
+ */
+ public List createTransformationList(List transforms)
+ throws MOAApplicationException {
+ List transformationList = new ArrayList();
+ Iterator trIter;
+
+ for (trIter = transforms.iterator(); trIter.hasNext();) {
+ Transform transform = (Transform) trIter.next();
+ transformationList.add(createTransformation(transform));
+ }
+
+ return transformationList;
+ }
+
+ /**
+ * Create a <code>Canonicalization</code>.
+ *
+ * @param algorithmUri The algorithm URI of the canonicalization.
+ * @return The <code>Canonicalization</code>.
+ */
+ private Transformation createC14nTransformation(String algorithmUri) {
+ return new CanonicalizationImpl(algorithmUri);
+ }
+
+ /**
+ * Create a <code>ExclusiveCanonicalization</code>.
+ *
+ * @param transform The <code>ExclusiveCanonicalizationTransform</code>
+ * containing the transformation data.
+ * @return The <code>ExclusiveCanonicalization</code>.
+ */
+ private Transformation createExclusiveC14nTransformation(ExclusiveCanonicalizationTransform transform) {
+ return new ExclusiveCanonicalizationImpl(
+ transform.getAlgorithmURI(),
+ transform.getInclusiveNamespacePrefixes());
+ }
+
+ /**
+ * Create a <code>Base64Transformation</code>.
+ *
+ * @return The <code></code>
+ */
+ private Transformation createBase64Transformation() {
+ return new Base64TransformationImpl();
+ }
+
+ /**
+ * Create an <code>EnvelopedSignatureTransformation</code>.
+ *
+ * @return An <code>EnvelopedSignatureTransformation</code>.
+ */
+ private Transformation createEnvelopedSignatureTransformation() {
+ return new EnvelopedSignatureTransformationImpl();
+ }
+
+ /**
+ * Create an <code>XPathTransformation</code>.
+ *
+ * @param transform The <code>Transform</code> object containing the
+ * XPath transformation.
+ * @return An <code>XPathTransformation</code> corresponding the
+ * transformation given in <code>transform</code>.
+ * @throws MOAApplicationException An error occurred creating the
+ * <code>Transformation</code>.
+ */
+ private Transformation createXPathTransformation(XPathTransform transform)
+ throws MOAApplicationException {
+
+ return new XPathTransformationImpl(
+ transform.getXPathExpression(),
+ transform.getNamespaceDeclarations());
+ }
+
+ /**
+ * Create an <code>XPath2Transformation</code>.
+ *
+ * @param transform The <code>Transform</code> object containing the
+ * XPath filter transformation.
+ * @return An <code>XPath2Transformation</code> corresponding the
+ * transformation given in <code>transform</code>.
+ * @throws MOAApplicationException An error occurred creating the
+ * <code>Transformation</code>.
+ */
+ private Transformation createXPath2Transformation(XPathFilter2Transform transform)
+ throws MOAApplicationException {
+
+ XPath2TransformationImpl xpath2 = new XPath2TransformationImpl();
+ Iterator iter;
+
+ for (iter = transform.getFilters().iterator(); iter.hasNext();) {
+ XPathFilter filter = (XPathFilter) iter.next();
+ String mappedFilterType =
+ (String) FILTER_TYPE_MAPPING.get(filter.getFilterType());
+ XPath2FilterImpl mappedFilter =
+ new XPath2FilterImpl(
+ mappedFilterType,
+ filter.getXPathExpression(),
+ filter.getNamespaceDeclarations());
+ xpath2.addXPathFilter(mappedFilter);
+ }
+
+ if (xpath2.getXPathFilters().size() == 0) {
+ throw new MOAApplicationException("2216", null);
+ }
+
+ return xpath2;
+ }
+
+ /**
+ * Create an <code>XSLTTransformation</code>.
+ *
+ * @param transform The <code>Transform</code> containing the XSLT stylesheet.
+ * @return An <code>XSLTTransformation</code> corresponding the transformation
+ * given in <code>transform</code>.
+ * @throws MOAApplicationException An error occurred creating the
+ * <code>Transformation</code>.
+ */
+ private Transformation createXSLTTransformation(XSLTTransform transform)
+ throws MOAApplicationException {
+
+ return new XSLTTransformationImpl(transform.getStylesheet());
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java
new file mode 100644
index 000000000..55e2e1505
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java
@@ -0,0 +1,86 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import iaik.server.modules.cmsverify.CMSSignatureVerificationResult;
+import iaik.server.modules.cmsverify.CertificateValidationResult;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponseElement;
+import at.gv.egovernment.moa.spss.api.common.CheckResult;
+import at.gv.egovernment.moa.spss.api.common.SignerInfo;
+
+/**
+ * A class to build a <code>VerifyCMSSignatureResponse</code> object.
+ *
+ * <p>Via subsequent calls to <code>addResult()</code> a number of results from
+ * a CMS signature verification can be added to the response.</p>
+ *
+ * <p>The <code>getResponseElement()</code> method then returns the
+ * <code>VerifyCMSSignatureResponse</code> built so far.</p>
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyCMSSignatureResponseBuilder {
+ /** The <code>SPSSFactory</code> for creating API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+ /** The elements making up the response. */
+ private List responseElements = new ArrayList();
+
+ /**
+ * Get the <code>VerifyCMSSignatureResponse</code> built so far.
+ *
+ * @return The <code>VerifyCMSSignatureResponse</code> built so far.
+ */
+ public VerifyCMSSignatureResponse getResponse() {
+ return factory.createVerifyCMSSignatureResponse(responseElements);
+ }
+
+ /**
+ * Add a verification result to the response.
+ *
+ * @param result The result to add.
+ * @throws MOAApplicationException An error occurred adding the result.
+ */
+ public void addResult(CMSSignatureVerificationResult result)
+ throws MOAApplicationException {
+
+ CertificateValidationResult certResult =
+ result.getCertificateValidationResult();
+ int signatureCheckCode =
+ result.getSignatureValueVerificationCode().intValue();
+ int certificateCheckCode = certResult.getValidationResultCode().intValue();
+ VerifyCMSSignatureResponseElement responseElement;
+ SignerInfo signerInfo;
+ CheckResult signatureCheck;
+ CheckResult certificateCheck;
+
+ // add SignerInfo element
+ signerInfo =
+ factory.createSignerInfo(
+ (X509Certificate) certResult.getCertificateChain().get(0),
+ certResult.isQualifiedCertificate(),
+ certResult.isPublicAuthorityCertificate(),
+ certResult.getPublicAuthorityID());
+
+ // add SignatureCheck element
+ signatureCheck = factory.createCheckResult(signatureCheckCode, null);
+
+ // add CertificateCheck element
+ certificateCheck = factory.createCheckResult(certificateCheckCode, null);
+
+ // build the response element
+ responseElement =
+ factory.createVerifyCMSSignatureResponseElement(
+ signerInfo,
+ signatureCheck,
+ certificateCheck);
+ responseElements.add(responseElement);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java
new file mode 100644
index 000000000..2f55261d1
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java
@@ -0,0 +1,317 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.NodeList;
+
+import iaik.ixsil.algorithms.CanonicalizationAlgorithm;
+import iaik.ixsil.algorithms.CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments;
+import iaik.server.modules.xml.BinaryDataObject;
+import iaik.server.modules.xml.DataObject;
+import iaik.server.modules.xml.XMLDataObject;
+import iaik.server.modules.xml.XMLNodeListDataObject;
+import iaik.server.modules.xmlverify.CertificateValidationResult;
+import iaik.server.modules.xmlverify.DsigManifest;
+import iaik.server.modules.xmlverify.HashUnavailableException;
+import iaik.server.modules.xmlverify.ReferenceData;
+import iaik.server.modules.xmlverify.ReferenceInfo;
+import iaik.server.modules.xmlverify.SecurityLayerManifest;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationResult;
+import iaik.x509.X509Certificate;
+
+import at.gv.egovernment.moa.util.CollectionUtils;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.NodeListAdapter;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.CheckResult;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.common.SignerInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResultInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+
+/**
+ * A class to build a <code>VerifyXMLSignatureResponse</code> object.
+ *
+ * <p>Via a call to <code>addResult()</code> the only result of the
+ * signature verification must be added.</p>
+ *
+ * <p>The <code>getResponseElement()</code> method then returns the
+ * <code>VerifyXMLSignatureResponse</code> built so far.</p>
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyXMLSignatureResponseBuilder {
+ /** The <code>SPSSFactory</code> for creating API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+
+ /** Information about the signer certificate. */
+ private SignerInfo signerInfo;
+ /** The hash input data. */
+ private List hashInputDatas;
+ /** The reference input data. */
+ private List referenceInputDatas;
+ /** The result of the signature check. */
+ private ReferencesCheckResult signatureCheck;
+ /** The result of the signature manifest check. */
+ private ReferencesCheckResult signatureManifestCheck;
+ /** The result of the XMLDsig manifest check. */
+ private List xmlDsigManifestChecks;
+ /** The result of the certificate check. */
+ private CheckResult certificateCheck;
+
+ /**
+ * Get the <code>VerifyMLSignatureResponse</code> built so far.
+ *
+ * @return The <code>VerifyXMLSignatureResponse</code> built so far.
+ */
+ public VerifyXMLSignatureResponse getResponse() {
+ return factory.createVerifyXMLSignatureResponse(
+ signerInfo,
+ hashInputDatas,
+ referenceInputDatas,
+ signatureCheck,
+ signatureManifestCheck,
+ xmlDsigManifestChecks,
+ certificateCheck);
+ }
+
+ /**
+ * Sets the verification result to the response.
+ *
+ * This method must be called exactly once to ensure a valid
+ * <code>VerifyXMLSignatureResponse</code>.
+ *
+ * @param result The result to set for the response.
+ * @param profile The profile used for verifying the signature.
+ * @throws MOAApplicationException An error occurred adding the result.
+ */
+ public void setResult(
+ XMLSignatureVerificationResult result,
+ XMLSignatureVerificationProfile profile,
+ ReferencesCheckResult transformsSignatureManifestCheck)
+ throws MOAApplicationException {
+
+ CertificateValidationResult certResult =
+ result.getCertificateValidationResult();
+ List referenceDataList;
+ ReferenceData referenceData;
+ List dsigManifestList;
+ ReferencesCheckResultInfo checkResultInfo;
+ int[] failedReferences;
+ Iterator iter;
+
+ // create the SignerInfo;
+ signerInfo =
+ factory.createSignerInfo(
+ (X509Certificate) certResult.getCertificateChain().get(0),
+ certResult.isQualifiedCertificate(),
+ certResult.isPublicAuthorityCertificate(),
+ certResult.getPublicAuthorityID());
+
+ // add HashInputData Content objects
+ referenceDataList = result.getReferenceDataList();
+ if (profile.includeHashInputData()) {
+ hashInputDatas = new ArrayList();
+ for (iter = referenceDataList.iterator(); iter.hasNext();) {
+ referenceData = (ReferenceData) iter.next();
+ hashInputDatas.add(buildContent(referenceData.getHashInputData()));
+ }
+ }
+
+ // create the ReferenceInputData Content objects
+ if (profile.includeReferenceInputData()) {
+ referenceInputDatas = new ArrayList();
+ for (iter = referenceDataList.iterator(); iter.hasNext();) {
+ referenceData = (ReferenceData) iter.next();
+ referenceInputDatas.add(
+ buildContent(referenceData.getReferenceInputData()));
+ }
+ }
+
+ // create the signature check
+ failedReferences = buildFailedReferences(result.getReferenceDataList());
+ checkResultInfo =
+ failedReferences != null
+ ? factory.createReferencesCheckResultInfo(null, failedReferences)
+ : null;
+ signatureCheck =
+ factory.createReferencesCheckResult(
+ result.getSignatureValueVerificationCode().intValue(),
+ checkResultInfo);
+
+ // create the signature manifest check
+ if (profile.checkSecurityLayerManifest()) {
+ if (transformsSignatureManifestCheck.getCode() == 1) {
+ // checking the transforms failed
+ signatureManifestCheck = transformsSignatureManifestCheck;
+ } else if (!result.containsSecurityLayerManifest()) {
+ // no security layer manifest in signature
+ signatureManifestCheck = factory.createReferencesCheckResult(2, null);
+ } else {
+ // other error codes provided by IAIK signature verification
+ // need to add 1 to the check code for MOA compatibility
+ SecurityLayerManifest slManifest = result.getSecurityLayerManifest();
+ int verificationResult =
+ slManifest.getManifestVerificationResult().intValue();
+
+ switch (verificationResult) {
+ case 0 :
+ signatureManifestCheck =
+ factory.createReferencesCheckResult(0, null);
+ break;
+ case 2 :
+ case 3 :
+ failedReferences =
+ buildFailedReferences(slManifest.getReferenceInfoList());
+ checkResultInfo =
+ failedReferences != null
+ ? factory.createReferencesCheckResultInfo(null, failedReferences)
+ : null;
+ signatureManifestCheck =
+ factory.createReferencesCheckResult(
+ verificationResult + 1,
+ checkResultInfo);
+ }
+ }
+
+ // Code = 1 prüfen
+
+ if (result.containsSecurityLayerManifest()) {
+ } else {
+ // SignatureManifestCheck Code = 2
+ }
+ }
+
+ // create the xmlDsigManifestCheck
+ if (profile.checkXMLDsigManifests()) {
+ xmlDsigManifestChecks = new ArrayList();
+ dsigManifestList = result.getDsigManifestList();
+ for (iter = dsigManifestList.iterator(); iter.hasNext();) {
+ DsigManifest dsigManifest = (DsigManifest) iter.next();
+ int refIndex =
+ dsigManifest.getReferringReferenceInfo().getReferenceIndex();
+ ManifestRefsCheckResultInfo manifestCheckResultInfo;
+
+ failedReferences =
+ buildFailedReferences(dsigManifest.getReferenceInfoList());
+ manifestCheckResultInfo =
+ factory.createManifestRefsCheckResultInfo(
+ null,
+ failedReferences,
+ refIndex);
+ xmlDsigManifestChecks.add(
+ factory.createManifestRefsCheckResult(
+ dsigManifest.getManifestVerificationResult().intValue(),
+ manifestCheckResultInfo));
+ }
+ }
+
+ // create the certificate check
+ certificateCheck =
+ factory.createCheckResult(
+ certResult.getValidationResultCode().intValue(),
+ null);
+ }
+
+ /**
+ * Build a <code>Content</code> object from the given <code>DataObject</code>.
+ *
+ * @param dataObject The <code>DataObject</code> from which to build the
+ * <code>Content</code>. Based on the type of this parameter, the type of
+ * <code>Content</code> will either be <code>XML_CONTENT</code> or
+ * <code>BINARY_CONTENT</code>.
+ * @return The <code>Content</code> object containing the data.
+ * @throws MOAApplicationException An error occurred adding the content.
+ */
+ private Content buildContent(DataObject dataObject)
+ throws MOAApplicationException {
+
+ if (dataObject instanceof BinaryDataObject) {
+ BinaryDataObject binaryData = (BinaryDataObject) dataObject;
+ return factory.createContent(binaryData.getInputStream(), null);
+ } else if (dataObject instanceof XMLDataObject) {
+ XMLDataObject xmlData = (XMLDataObject) dataObject;
+ List nodes = new ArrayList();
+
+ nodes.add(xmlData.getElement());
+ return factory.createContent(new NodeListAdapter(nodes), null);
+ } else { // dataObject instanceof XMLNodeListDataObject
+ // if the data in the NodeList can be converted back to valid XML,
+ // write it as XMLContent; otherwise, write it as Base64Content
+ XMLNodeListDataObject nodeData = (XMLNodeListDataObject) dataObject;
+ NodeList nodes = nodeData.getNodeList();
+
+ if (DOMUtils.checkAttributeParentsInNodeList(nodes)) {
+ // insert as XMLContent
+ try {
+ DocumentFragment fragment = DOMUtils.nodeList2DocumentFragment(nodes);
+
+ return factory.createContent(fragment.getChildNodes(), null);
+ } catch (Exception e) {
+ // not successful -> fall through to the Base64Content
+ }
+ }
+
+ // insert canonicalized NodeList as binary content
+ try {
+ CanonicalizationAlgorithm c14n =
+ new CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments();
+ InputStream is;
+
+ c14n.setInput(nodes);
+ is = c14n.canonicalize();
+ return factory.createContent(is, null);
+ } catch (Exception e) {
+ throw new MOAApplicationException("2200", null);
+ }
+ }
+ }
+
+ /**
+ * Build the failed references.
+ *
+ * Failed references are references for which the <code>isHashValid()</code>
+ * method returns <code>false</code>.
+ *
+ * @param refInfos A <code>List</code> containing the
+ * <code>ReferenceInfo</code> objects to be checked.
+ * @return The indexes of the failed references.
+ */
+ private int[] buildFailedReferences(List refInfos) {
+ List failedReferencesList = new ArrayList();
+ int i;
+
+ // find out the failed references
+ for (i = 0; i < refInfos.size(); i++) {
+ ReferenceInfo refInfo = (ReferenceInfo) refInfos.get(i);
+
+ try {
+ if (refInfo.isHashCalculated() && !refInfo.isHashValid()) {
+ failedReferencesList.add(new Integer(i + 1));
+ }
+ } catch (HashUnavailableException e) {
+ // nothing to do here because we called refInfo.isHashCalculated first
+ }
+ }
+
+ // convert to an int array
+ if (failedReferencesList.isEmpty()) {
+ return null;
+ } else {
+ int[] failedReferences = CollectionUtils.toIntArray(failedReferencesList);
+
+ return failedReferences;
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java
new file mode 100644
index 000000000..6b8a3db2d
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java
@@ -0,0 +1,522 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import iaik.IAIKException;
+import iaik.IAIKRuntimeException;
+import iaik.server.modules.xml.DataObject;
+import iaik.server.modules.xml.XMLDataObject;
+import iaik.server.modules.xml.XMLSignature;
+import iaik.server.modules.xmlsign.XMLSignatureCreationModule;
+import iaik.server.modules.xmlsign.XMLSignatureCreationModuleFactory;
+import iaik.server.modules.xmlsign.XMLSignatureCreationProfile;
+
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.xml.SigningTimeImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XMLDataObjectImpl;
+import at.gv.egovernment.moa.spss.server.logging.IaikLog;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.server.util.IdGenerator;
+
+/**
+ * A class providing an API based interface to the
+ * <code>XMLSignatureCreationModule</code>.
+ *
+ * This class performs the invocation of the
+ * <code>iaik.server.modules.xmlsign.XMLSignatureCreationModule</code> from a
+ * <code>CreateXMLSignatureRequest</code> given as an API object. The result of
+ * the invocation is integrated into a <code>CreateXMLSignatureResponse</code>
+ * and returned.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureCreationInvoker {
+
+ /** The single instance of this class. */
+ private static XMLSignatureCreationInvoker instance = null;
+
+ /**
+ * Get the only instance of this class.
+ *
+ * @return The only instance of this class.
+ */
+ public static synchronized XMLSignatureCreationInvoker getInstance() {
+ if (instance == null) {
+ instance = new XMLSignatureCreationInvoker();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>XMLSignatureCreationInvoker</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected XMLSignatureCreationInvoker() {
+ }
+
+ /**
+ * Process the <code>CreateXMLSignatureRequest<code> message and invoke the
+ * <code>XMLSignatureCreationModule</code> for every
+ * <code>SingleSignatureInfo</code> contained in the request.
+ *
+ * @param request A <code>CreateXMLSignatureRequest<code> API object
+ * containing the information for creating the signature(s).
+ * @param reserved A <code>Set</code> of reserved object IDs.
+ *
+ * @return A <code>CreateXMLSignatureResponse</code> API object containing
+ * the created signature(s). The response contains either a
+ * <code>SignatureEnvironment</code> or a <code>ErrorResponse</code>
+ * for each <code>SingleSignatureInfo</code> in the request.
+ * @throws MOAException An error occurred during signature creation.
+ */
+ public CreateXMLSignatureResponse createXMLSignature(
+ CreateXMLSignatureRequest request,
+ Set reserved)
+ throws MOAException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ LoggingContext loggingCtx =
+ LoggingContextManager.getInstance().getLoggingContext();
+ Set reservedIDs = new HashSet(reserved);
+ XMLSignatureCreationProfileFactory profileFactory =
+ new XMLSignatureCreationProfileFactory(request, reservedIDs);
+ CreateXMLSignatureResponseBuilder responseBuilder =
+ new CreateXMLSignatureResponseBuilder();
+ int createCount = 1;
+ IdGenerator refIdGen;
+ XMLSignatureCreationModule module;
+ Iterator singleSignatureInfoIter;
+
+ // create the XMLSignatureCreationModule and configure it
+ module = XMLSignatureCreationModuleFactory.getInstance();
+ module.setLog(new IaikLog(loggingCtx.getNodeID()));
+
+ // select the SingleSignatureInfo elements
+ singleSignatureInfoIter = request.getSingleSignatureInfos().iterator();
+
+ // iterate over all the SingleSignatureInfo elements in the request
+ while (singleSignatureInfoIter.hasNext()) {
+ SingleSignatureInfo singleSignatureInfo =
+ (SingleSignatureInfo) singleSignatureInfoIter.next();
+ CreateSignatureInfo createSignatureInfo;
+ List dataObjectList;
+ XMLSignatureCreationProfile profile;
+ XMLDataObject signatureEnvironment;
+ XMLDataObject signatureParent;
+ XMLSignature signature;
+ List additionalSignedProperties;
+ Node signatureEnvironmentParent = null;
+ Element requestElement = null;
+
+ try {
+ // create the reference id generator
+ refIdGen = new IdGenerator("reference-" + createCount++, reservedIDs);
+
+ // build the signature environment
+ createSignatureInfo = singleSignatureInfo.getCreateSignatureInfo();
+ if (createSignatureInfo != null) {
+ DataObjectFactory dataObjFactory = DataObjectFactory.getInstance();
+
+ signatureEnvironment =
+ dataObjFactory.createSignatureEnvironment(
+ createSignatureInfo.getCreateSignatureEnvironment(),
+ getCreateSignatureEnvironmentProfileSupplements(singleSignatureInfo));
+ } else {
+ signatureEnvironment = null;
+ }
+
+ // build the list of DataObjects
+ dataObjectList =
+ buildDataObjectList(
+ singleSignatureInfo,
+ signatureEnvironment,
+ refIdGen);
+
+ // build the XMLSignatureCreationProfile
+ profile = profileFactory.createProfile(singleSignatureInfo);
+
+ // build the additionalSignedProperties
+ additionalSignedProperties = buildAdditionalSignedProperties();
+
+ // build the signatureParentElement
+ if (signatureEnvironment != null) {
+ signatureParent =
+ buildSignatureParentElement(
+ signatureEnvironment.getElement(),
+ singleSignatureInfo);
+ } else {
+ signatureParent = null;
+ }
+
+ // make the signature environment the root of the document, if it is
+ // not a separate document anyway; this is done to assure that
+ // canonicalization of the signature environment contains the correct
+ // namespace declarations
+ if (signatureEnvironment != null) {
+ Document requestDoc =
+ signatureEnvironment.getElement().getOwnerDocument();
+ requestElement = requestDoc.getDocumentElement();
+ if (requestElement != signatureEnvironment.getElement()) {
+ signatureEnvironmentParent =
+ signatureEnvironment.getElement().getParentNode();
+ requestElement.getOwnerDocument().replaceChild(
+ signatureEnvironment.getElement(),
+ requestElement);
+ }
+ }
+
+ try {
+ // create the signature
+ signature =
+ module.createSignature(
+ dataObjectList,
+ profile,
+ additionalSignedProperties,
+ signatureParent,
+ new TransactionId(context.getTransactionID()));
+
+ // insert the result into the response
+ if (signatureParent != null) {
+ responseBuilder.addSignatureEnvironment(
+ signatureParent.getElement());
+ } else {
+ responseBuilder.addSignatureEnvironment(signature.getElement());
+ }
+
+ } catch (IAIKException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+
+ responseBuilder.addError(
+ moaException.getMessageId(),
+ moaException.getMessage());
+ Logger.warn(moaException.getMessage(), e);
+ } catch (IAIKRuntimeException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+
+ responseBuilder.addError(
+ moaException.getMessageId(),
+ moaException.getMessage());
+ Logger.warn(moaException.getMessage(), e);
+ }
+
+ // swap back in the request as root document
+ if (signatureEnvironment != null) {
+ if (requestElement != signatureEnvironment.getElement()) {
+ requestElement.getOwnerDocument().replaceChild(
+ requestElement,
+ signatureEnvironment.getElement());
+ signatureEnvironmentParent.appendChild(
+ signatureEnvironment.getElement());
+ }
+ }
+
+ } catch (MOAException e) {
+ responseBuilder.addError(e.getMessageId(), e.getMessage());
+ Logger.warn(e.getMessage(), e);
+ }
+
+ }
+
+ return responseBuilder.getResponse();
+ }
+
+ /**
+ * Build the list of <code>DataObject</code>s from the given
+ * <code>SingleSignatureInfo</code> object.
+ *
+ * <p>
+ * Only the following cases of <code>DataObject</code>s are
+ * valid in case of an enveloping signature:
+ *
+ * <ul>
+ * <li><code>Reference == null && Content != null</code>: The
+ * <code>Content</code> will be used in the <code>DataObject</code>.</li>
+ * <li><code>Reference != null && Content == null</code>: Resolve the
+ * <code>Reference</code> and use it as <code>DataObject</code>.
+ * Set the <code>Reference</code> in the <code>DataObject</code> as well.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * Only the following cases of <code>DataObject</code>s are valid in case
+ * of a detached signature:
+ *
+ * <ul>
+ * <li><code>Reference != null && Content == null</code>: Resolve the
+ * <code>Reference</code> and use it as <code>DataObject</code>.
+ * Set the <code>Reference</code> in the <code>DataObject</code> as well.</li>
+ * <li><code>Reference != null && Content != null</code>: The
+ * <code>Content</code> will be used in the <code>DataObject</code>.
+ * Set the <code>Reference</code> in the <code>DataObject</code> as well.</li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * All other cases will lead to an error.
+ * </p>
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * containing the <code>DataObjectInfo</code> objects.
+ * @param signatureEnvironment The
+ * @param idGen The ID generator for <code>DataObject</code> references.
+ * @return The <code>List</code> of <code>DataObject</code>s contained in the
+ * given <code>singleSignatureInfo</code>.
+ * @throws MOASystemException A system error occurred building the data
+ * objects.
+ * @throws MOAApplicationException An error occurred building the data
+ * objects.
+ */
+ private List buildDataObjectList(
+ SingleSignatureInfo singleSignatureInfo,
+ XMLDataObject signatureEnvironment,
+ IdGenerator idGen)
+ throws MOASystemException, MOAApplicationException {
+
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ List dataObjects = new ArrayList();
+ //Document requestDoc = singleSignatureInfo.getOwnerDocument();
+ Iterator dtIter;
+
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) {
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ String structure = dataObjInfo.getStructure();
+
+ if (DataObjectInfo.STRUCTURE_ENVELOPING.equals(structure)) {
+ dataObjects.add(
+ buildEnvelopingDataObject(
+ dataObjInfo.getDataObject(),
+ idGen.nextId()));
+ } else if (DataObjectInfo.STRUCTURE_DETACHED.equals(structure)) {
+ dataObjects.add(
+ buildDetachedDataObject(
+ dataObjInfo.getDataObject(),
+ signatureEnvironment,
+ idGen.nextId()));
+ } else {
+ throw new MOAApplicationException("1103", new Object[] { structure });
+ }
+ }
+
+ return dataObjects;
+
+ }
+
+ /**
+ * Build a <code>DataObject</code> to be used in an enveloping
+ * signature.
+ *
+ * @param content The <code>Content</code> object containing the data object.
+ * <code>ContentOptionalRefType</code>.
+ * @param referenceID The reference ID to use in the signature for the
+ * <code>DataObject</code> created.
+ * @return The <code>DataObject</code> representing the data contained in
+ * <code>dataObjectElem</code>.
+ * @throws MOAApplicationException An error occurred during the creation of
+ * the <code>DataObject</code>.
+ * @throws MOASystemException A system error occurred during the creation of
+ * the <code>DataObject</code>.
+ */
+ private DataObject buildEnvelopingDataObject(
+ Content content,
+ String referenceID)
+ throws MOASystemException, MOAApplicationException {
+
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+
+ dataObject =
+ factory.createFromContentOptionalRefType(
+ content,
+ referenceID,
+ false,
+ false,
+ true,
+ false);
+
+ return dataObject;
+ }
+
+ /**
+ * Build a <code>DataObject</code> to be used in a detached signature.
+ *
+ * @param content The <code>Content</code> object containing an the data.
+ * @param signatureEnvironment The signature environment where the signature
+ * will be inserted.
+ * @param referenceID The reference ID to use in the signature for the
+ * <code>DataObject</code> created.
+ * @return The <code>DataObject</code> representing the data contained in
+ * <code>dataObjectElem</code>.
+ * @throws MOAApplicationException An error occurred during the creation of
+ * the <code>DataObject</code>.
+ * @throws MOASystemException A system error occurred during the creation of
+ * the <code>DataObject</code>.
+ */
+ private DataObject buildDetachedDataObject(
+ Content content,
+ XMLDataObject signatureEnvironment,
+ String referenceID)
+ throws MOASystemException, MOAApplicationException {
+
+ String reference = content.getReference();
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+
+ if (reference == null) {
+ throw new MOAApplicationException("1102", null);
+ } else if ("".equals(reference) || reference.startsWith("#")) {
+ dataObject =
+ factory.createFromSignatureEnvironment(
+ signatureEnvironment.getElement(),
+ reference,
+ referenceID);
+ } else {
+ dataObject =
+ factory.createFromContentOptionalRefType(
+ content,
+ referenceID,
+ true,
+ false,
+ true,
+ false);
+ }
+ return dataObject;
+ }
+
+ /**
+ * Build the signature parent element.
+ *
+ * @param signatureEnvironment The signature environment containing the
+ * document in which to insert the signature.
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code>
+ * containing the signature parent element.
+ * @return An <code>XMLDataObject</code> containing the signature parent
+ * element or <code>null</code>, if the <code>CreateSignatureInfo</code> is
+ * <code>null</code>.
+ * @throws MOAApplicationException An error occurred during the creation of
+ * the signature parent.
+ */
+ private XMLDataObject buildSignatureParentElement(
+ Element signatureEnvironment,
+ SingleSignatureInfo singleSignatureInfo)
+ throws MOAApplicationException {
+
+ CreateSignatureInfo createInfo =
+ singleSignatureInfo.getCreateSignatureInfo();
+
+ // evaluate the CreateSignatureLocation
+ if (createInfo != null) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CreateSignatureEnvironmentProfileExplicit createProfile =
+ ProfileMapper.mapCreateSignatureEnvironmentProfile(
+ createInfo.getCreateSignatureEnvironmentProfile(),
+ config);
+ CreateSignatureLocation location =
+ createProfile.getCreateSignatureLocation();
+ Element signatureParent =
+ InvokerUtils.evaluateSignatureLocation(signatureEnvironment, location);
+
+ return new XMLDataObjectImpl(signatureParent);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Get the supplements contained in the
+ * <code>CreateSignatureEnvironmentProfile</code> of the given
+ * <code>SingleSignatureInfo</code>.
+ *
+ * @param singleSigInfo The <code>SingleSignatureInfo</code> from which
+ * to extract the supplements.
+ * @return A <code>List</code> of <code>XMLDataObjectAssociation</code>s
+ * or <code>null</code>, if the <code>singleSigInfo</code> does not contain
+ * supplements.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>CreateSignatureEnvironmentProfile</code>.
+ */
+ private List getCreateSignatureEnvironmentProfileSupplements(SingleSignatureInfo singleSigInfo)
+ throws MOAApplicationException {
+ CreateSignatureInfo sigInfo = singleSigInfo.getCreateSignatureInfo();
+
+ if (sigInfo != null) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CreateSignatureEnvironmentProfileExplicit profile =
+ ProfileMapper.mapCreateSignatureEnvironmentProfile(
+ sigInfo.getCreateSignatureEnvironmentProfile(),
+ config);
+ List supplements = profile.getSupplements();
+
+ return supplements;
+ }
+ return null;
+ }
+
+ /**
+ * Build the list of additional signed properties.
+ *
+ * Based on the generic configuration setting
+ * <code>ConfigurationProvider.TEST_SIGNING_TIME_PROPERTY</code>, a
+ * constant <code>SigningTime</code> will be added to the properties.
+ *
+ * @return The <code>List</code> of additional signed properties.
+ */
+ private List buildAdditionalSignedProperties() {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List additionalSignedProperties = Collections.EMPTY_LIST;
+ String testSigningTime =
+ config.getGenericConfiguration(
+ ConfigurationProvider.TEST_SIGNING_TIME_PROPERTY);
+
+ if (testSigningTime != null) {
+ try {
+ SigningTimeImpl signingTime =
+ new SigningTimeImpl(DateTimeUtils.parseDateTime(testSigningTime));
+ additionalSignedProperties = new ArrayList();
+ additionalSignedProperties.add(signingTime);
+ } catch (ParseException e) {
+ // if we fail here, the signing time will simply not be added to
+ // the list of signed properties
+ }
+ }
+
+ return additionalSignedProperties;
+ }
+
+} \ No newline at end of file
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
new file mode 100644
index 000000000..c9bb12f75
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
@@ -0,0 +1,448 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.math.BigInteger;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import iaik.server.modules.algorithms.HashAlgorithms;
+import iaik.server.modules.keys.KeyEntryID;
+import iaik.server.modules.keys.KeyModule;
+import iaik.server.modules.keys.KeyModuleFactory;
+import iaik.server.modules.xmlsign.SignatureStructureTypes;
+import iaik.server.modules.xmlsign.XMLSignatureCreationProfile;
+import iaik.server.modules.xmlsign.XMLSignatureInsertionLocation;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.Constants;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlsign.DataObjectInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.SingleSignatureInfo;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.config.KeyGroupEntry;
+import at.gv.egovernment.moa.spss.server.iaik.xml.CanonicalizationImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlsign.DataObjectTreatmentImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlsign.XMLSignatureCreationProfileImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlsign.XMLSignatureInsertionLocationImpl;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.server.util.IdGenerator;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A factory to create <code>XMLSignatureCreationProfile</code>s from a
+ * <code>CreateXMLSignatureRequest</code>, based on the current MOA
+ * configuration.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureCreationProfileFactory {
+
+ private static Map HASH_ALGORITHM_MAPPING;
+
+ static {
+ HASH_ALGORITHM_MAPPING = new HashMap();
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA1_URI, HashAlgorithms.SHA1);
+ }
+
+ /** The <code>CreateXMLSignatureRequest</code> for which to create the
+ * profile.*/
+ private CreateXMLSignatureRequest request;
+ /** How many profiles have been created based on the same request. */
+ private int createProfileCount;
+ /** The <code>Set</code> of reserved object IDs.*/
+ private Set reserved;
+
+ /**
+ * Create a new <code>XMLSignatureCreationProfileFactory</code>.
+ *
+ * @param request The request for which to create profiles.
+ * @param reserved The <code>Set</code> of reserved object IDs. IDs will
+ * be added during signature creation.
+ */
+ public XMLSignatureCreationProfileFactory(
+ CreateXMLSignatureRequest request,
+ Set reserved) {
+ this.request = request;
+ this.reserved = reserved;
+ createProfileCount = 1;
+ }
+
+ /**
+ * Create a <code>XMLSignatureCreationProfile</code> for the given
+ * <code>SingleSignatureInfo</code> object..
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * containing information about the creation of a signature.
+ * @return The <code>XMLSignatureCreationProfile</code> containing additional
+ * information for creating an XML signature.
+ * @throws MOASystemException A system error occurred during creation of the
+ * profile. See message for details
+ * @throws MOAApplicationException An application error occurred during
+ * creation of the profile. See message for details.
+ */
+ public XMLSignatureCreationProfile createProfile(SingleSignatureInfo singleSignatureInfo)
+ throws MOASystemException, MOAApplicationException {
+
+ XMLSignatureCreationProfileImpl profile =
+ new XMLSignatureCreationProfileImpl(createProfileCount, reserved);
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CanonicalizationImpl canonicalization;
+ List dataObjectTreatmentList;
+ String keyGroupID;
+ Set keySet;
+ List transformationSupplements;
+ List createTransformsProfiles;
+
+ // build the transformation supplements
+ createTransformsProfiles =
+ getCreateTransformsInfoProfiles(singleSignatureInfo);
+ transformationSupplements =
+ buildTransformationSupplements(createTransformsProfiles);
+
+ // build and set the data object treatment list
+ dataObjectTreatmentList =
+ buildDataObjectTreatmentList(
+ singleSignatureInfo,
+ createTransformsProfiles,
+ transformationSupplements);
+ profile.setDataObjectTreatmentList(dataObjectTreatmentList);
+
+ // set the key set
+ keyGroupID = request.getKeyIdentifier();
+ keySet = buildKeySet(keyGroupID);
+ if (keySet == null) {
+ throw new MOAApplicationException("2231", null);
+ } else if (keySet.size() == 0) {
+ throw new MOAApplicationException("2232", null);
+ }
+ profile.setKeySet(keySet);
+
+ // set the Security Layer manifest algorithm name
+ profile.setSecurityLayerManifestTypeURI(Constants.SL_MANIFEST_TYPE_URI);
+
+ // set the structure type
+ if (singleSignatureInfo.getCreateSignatureInfo() != null) {
+ profile.setSignatureStructureType(SignatureStructureTypes.ENVELOPED);
+ } else {
+ profile.setSignatureStructureType(SignatureStructureTypes.DETACHED);
+ }
+
+ // set insertion location
+ profile.setSignatureInsertionLocation(
+ getSignatureInsertionLocationIndex(singleSignatureInfo));
+
+ // set the canonicalization algorithm
+ canonicalization =
+ new CanonicalizationImpl(config.getCanonicalizationAlgorithmName());
+ profile.setSignedInfoCanonicalization(canonicalization);
+
+ // set the signed properties
+ profile.setSignedProperties(Collections.EMPTY_LIST);
+
+ // set security layer conformity
+ profile.setSecurityLayerConform(
+ singleSignatureInfo.isSecurityLayerConform());
+
+ // update the createProfileCount
+ createProfileCount++;
+
+ return profile;
+ }
+
+ /**
+ * Get the <code>List</code> of all <code>CreateTransformsInfoProfile</code>s
+ * contained in all the <code>DataObjectInfo</code>s of the given
+ * <code>SingleSignatureInfo</code>.
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object from
+ * which to extract the <code>CreateTransformsInfoProfile</code>s.
+ * @return All <code>CreateTransformsInfoProfile</code>s of all
+ * <code>DataObjectInfo</code>s of <code>singleSignatureInfo</code>.
+ * @throws MOAApplicationException An error occurred creating one of the
+ * profiles.
+ */
+ private List getCreateTransformsInfoProfiles(SingleSignatureInfo singleSignatureInfo)
+ throws MOAApplicationException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ List profiles = new ArrayList();
+ Iterator dtIter;
+
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) {
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ CreateTransformsInfoProfileExplicit profile =
+ ProfileMapper.mapCreateTransformsInfoProfile(
+ dataObjInfo.getCreateTransformsInfoProfile(),
+ config);
+ profiles.add(profile);
+ }
+
+ return profiles;
+ }
+
+ /**
+ * Build the <code>List</code> of transformation supplements contained in a
+ * <code>SingleSignatureInfo</code> object.
+ *
+ * @param createTransformsInfoProfiles The
+ * <code>CreateTransformsInfoProfile</code> object from which to extract the
+ * transformation supplements.
+ * @return A <code>List</code> of <code>DataObject</code>s containing the
+ * transformation supplements.
+ * @throws MOASystemException A system error occurred creating one of the
+ * transformation supplements.
+ * @throws MOAApplicationException An error occurred creating one of the
+ * transformation supplements.
+ */
+ private List buildTransformationSupplements(List createTransformsInfoProfiles)
+ throws MOASystemException, MOAApplicationException {
+
+ List transformationSupplements = new ArrayList();
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ Iterator iter;
+
+ for (iter = createTransformsInfoProfiles.iterator(); iter.hasNext();) {
+ CreateTransformsInfoProfileExplicit profile =
+ (CreateTransformsInfoProfileExplicit) iter.next();
+ List supplements = profile.getSupplements();
+
+ if (supplements != null) {
+ Iterator supplIter;
+
+ for (supplIter = supplements.iterator(); supplIter.hasNext();) {
+ XMLDataObjectAssociation supplement =
+ (XMLDataObjectAssociation) supplIter.next();
+
+ transformationSupplements.add(
+ factory.createFromXmlDataObjectAssociation(
+ supplement,
+ false,
+ true));
+ }
+ }
+ }
+
+ return transformationSupplements;
+ }
+
+ /**
+ * Build the <code>List</code> of <code>DataObjectTreatment</code>s for the
+ * given <code>SingleSignatureInfo</code> object..
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * from which to exctract the <code>CreateTransformsInfoProfile</code>s
+ * containing the data for the <code>DataObjectTreatment</code>s.
+ * @param createTransformsInfoProfiles The
+ * <code>CreateTransformsInfoProfile</code>s contained in the
+ * <code>singleSignatureInfo</code>.
+ * @param transformationSupplements Additional parameters for
+ * transformations contained in <code>DataObjectTreatment</code>s.
+ * @return A <code>List</code> of <code>DataObjectTreatment</code> objects.
+ * @throws MOAApplicationException An error occurred building one of the
+ * <code>DataObjectTreatment</code>s.
+ * @throws MOASystemException A system error occurred building one of the
+ * <code>DataObjectTreatment</code>s.
+ */
+ private List buildDataObjectTreatmentList(
+ SingleSignatureInfo singleSignatureInfo,
+ List createTransformsInfoProfiles,
+ List transformationSupplements)
+ throws MOASystemException, MOAApplicationException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List treatments = new ArrayList();
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ int dataObjectTreatmentCount = 1;
+ String hashAlgorithmName;
+ Iterator dtIter;
+ Iterator prIter;
+
+ prIter = createTransformsInfoProfiles.iterator();
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();) {
+ CreateTransformsInfoProfileExplicit profile =
+ (CreateTransformsInfoProfileExplicit) prIter.next();
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ IdGenerator objIdGen =
+ new IdGenerator(
+ ("signed-data-" + createProfileCount)
+ + ("-" + dataObjectTreatmentCount++),
+ reserved);
+ DataObjectTreatmentImpl treatment = new DataObjectTreatmentImpl(objIdGen);
+
+ treatment.setFinalContentType(
+ profile.getCreateTransformsInfo().getFinalDataMetaInfo().getMimeType());
+ treatment.setTransformationList(buildTransformationList(profile));
+ treatment.setReferenceInManifest(dataObjInfo.isChildOfManifest());
+
+ hashAlgorithmName =
+ (String) HASH_ALGORITHM_MAPPING.get(
+ config.getDigestMethodAlgorithmName());
+ if (hashAlgorithmName == null) {
+ error(
+ "config.17",
+ new Object[] { config.getDigestMethodAlgorithmName()});
+ throw new MOASystemException("2900", null);
+ }
+
+ treatment.setHashAlgorithmName(hashAlgorithmName);
+ treatment.setIncludedInSignature(
+ DataObjectInfo.STRUCTURE_ENVELOPING.equals(dataObjInfo.getStructure()));
+ treatment.setTransformationSupplements(transformationSupplements);
+
+ treatments.add(treatment);
+
+ }
+
+ return treatments;
+ }
+
+ /**
+ * Build the <code>List</code> of transformations contained in a
+ * <code>CreateTransformsInfoProfile</code> object.
+ *
+ * @param profile The <code>CreateTransformsInfoProfile</code> object
+ * from which to extract the <code>Transform</code>s.
+ * @return A <code>List</code> of <code>Transformation</code>s contained in
+ * the given <code>CreateTransformsInfoProfile</code>.
+ * @throws MOAApplicationException An error occurred building one of the
+ * <code>Transformation</code>s.
+ */
+ private List buildTransformationList(CreateTransformsInfoProfileExplicit profile)
+ throws MOAApplicationException {
+
+ TransformationFactory factory = TransformationFactory.getInstance();
+ List transforms = profile.getCreateTransformsInfo().getTransforms();
+
+ return transforms != null
+ ? factory.createTransformationList(transforms)
+ : Collections.EMPTY_LIST;
+ }
+
+ /**
+ * Build the set of <code>KeyEntryID</code>s available to the given
+ * <code>keyGroupID</code>.
+ *
+ * @param keyGroupID The keygroup ID for which the available keys should be
+ * returned.
+ * @return The <code>Set</code> of <code>KeyEntryID</code>s
+ * identifying the available keys.
+ */
+ private Set buildKeySet(String keyGroupID) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ Set keyGroupEntries;
+
+ // get the KeyGroup entries from the configuration
+ if (context.getClientCertificate() != null) {
+ X509Certificate cert = context.getClientCertificate()[0];
+ Principal issuer = cert.getIssuerDN();
+ BigInteger serialNumber = cert.getSerialNumber();
+
+ keyGroupEntries =
+ config.getKeyGroupEntries(issuer, serialNumber, keyGroupID);
+ } else {
+ keyGroupEntries = config.getKeyGroupEntries(null, null, keyGroupID);
+ }
+
+ // map the KeyGroup entries to a set of KeyEntryIDs
+ if (keyGroupEntries == null) {
+ return null;
+ } else if (keyGroupEntries.size() == 0) {
+ return Collections.EMPTY_SET;
+ } else {
+ KeyModule module =
+ KeyModuleFactory.getInstance(
+ new TransactionId(context.getTransactionID()));
+ Set keyEntryIDs = module.getPrivateKeyEntryIDs();
+ Set keySet = new HashSet();
+ Iterator iter;
+
+ // filter out the keys that do not exist in the IAIK configuration
+ // by walking through the key entries and checking if the exist in the
+ // keyGroupEntries
+ for (iter = keyEntryIDs.iterator(); iter.hasNext();) {
+ KeyEntryID entryID = (KeyEntryID) iter.next();
+ KeyGroupEntry entry =
+ new KeyGroupEntry(
+ entryID.getModuleID(),
+ entryID.getCertificateIssuer(),
+ entryID.getCertificateSerialNumber());
+ if (keyGroupEntries.contains(entry)) {
+ keySet.add(entryID);
+ }
+ }
+ return keySet;
+ }
+ }
+
+ /**
+ * Get the signature location index where the signature will be inserted into
+ * the signature parent element.
+ *
+ * @param singleSignatureInfo The <code>SingleSignatureInfo</code> object
+ * containing the <code>CreateSignatureLocation</code>.
+ * @return The index at which to insert the signature into the signature
+ * environment.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>CreateSignatureEnvironmentProfile</code>.
+ */
+ private XMLSignatureInsertionLocation getSignatureInsertionLocationIndex(SingleSignatureInfo singleSignatureInfo)
+ throws MOAApplicationException {
+
+ CreateSignatureInfo createInfo =
+ singleSignatureInfo.getCreateSignatureInfo();
+
+ if (createInfo != null) {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CreateSignatureEnvironmentProfileExplicit profile =
+ ProfileMapper.mapCreateSignatureEnvironmentProfile(
+ createInfo.getCreateSignatureEnvironmentProfile(),
+ config);
+ int index = profile.getCreateSignatureLocation().getIndex();
+
+ return new XMLSignatureInsertionLocationImpl(index);
+ } else {
+ return new XMLSignatureInsertionLocationImpl(0);
+ }
+ }
+
+ /**
+ * Utility function to issue an error message to the log.
+ *
+ * @param messageId The ID of the message to log.
+ * @param parameters Additional message parameters.
+ */
+ private static void error(String messageId, Object[] parameters) {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ Logger.error(new LogMsg(msg.getMessage(messageId, parameters)));
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
new file mode 100644
index 000000000..b8af3c02a
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
@@ -0,0 +1,580 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import iaik.IAIKException;
+import iaik.IAIKRuntimeException;
+import iaik.server.modules.xml.DataObject;
+import iaik.server.modules.xml.XMLDataObject;
+import iaik.server.modules.xml.XMLSignature;
+import iaik.server.modules.xmlsign.XMLConstants;
+import iaik.server.modules.xmlverify.DsigManifest;
+import iaik.server.modules.xmlverify.ReferenceData;
+import iaik.server.modules.xmlverify.SecurityLayerManifest;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationModule;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationModuleFactory;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile;
+import iaik.server.modules.xmlverify.XMLSignatureVerificationResult;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+import at.gv.egovernment.moa.util.CollectionUtils;
+import at.gv.egovernment.moa.util.Constants;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.XMLDataObjectAssociation;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResultInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameterHash;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.xml.XMLSignatureImpl;
+import at.gv.egovernment.moa.spss.server.logging.IaikLog;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A class providing a DOM based interface to the
+ * <code>XMLSignatureVerificationModule</code>.
+ *
+ * This class performs the invocation of the
+ * <code>iaik.server.modules.xmlverify.XMLSignatureVerificationModule</code>
+ * from a <code>VerifyXMLSignatureRequest</code> given as a DOM element. The
+ * result of the invocation is integrated into a
+ * <code>VerifyXMLSignatureResponse</code> and returned.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureVerificationInvoker {
+
+ /** The single instance of this class. */
+ private static XMLSignatureVerificationInvoker instance = null;
+
+ private static Set FILTERED_REF_TYPES;
+
+ static {
+ FILTERED_REF_TYPES = new HashSet();
+ FILTERED_REF_TYPES.add(DsigManifest.XML_DSIG_MANIFEST_TYPE);
+ FILTERED_REF_TYPES.add(SecurityLayerManifest.SECURITY_LAYER_MANIFEST_TYPE);
+ FILTERED_REF_TYPES.add(
+ SecurityLayerManifest.SECURITY_LAYER_MANIFEST_TYPE_OLD);
+ FILTERED_REF_TYPES.add(
+ XMLConstants.NAMESPACE_ETSI_STRING + "SignedProperties");
+ }
+
+ /**
+ * Get the single instance of this class.
+ *
+ * @return The single instance of this class.
+ */
+ public static synchronized XMLSignatureVerificationInvoker getInstance() {
+ if (instance == null) {
+ instance = new XMLSignatureVerificationInvoker();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>XMLSignatureCreationInvoker</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected XMLSignatureVerificationInvoker() {
+ }
+
+ /**
+ * Process the <code>VerifyXMLSignatureRequest<code> message and invoke the
+ * <code>XMLSignatureVerificationModule</code>.
+ *
+ * @param request A <code>VerifyXMLSignatureRequest<code> API object
+ * containing the data for verifying an XML signature.
+ * @return A <code>VerifyXMLSignatureResponse</code> containing the
+ * answert to the <code>VerifyXMLSignatureRequest</code>.
+ * MOA schema definition.
+ * @throws MOAException An error occurred during signature verification.
+ */
+ public VerifyXMLSignatureResponse verifyXMLSignature(VerifyXMLSignatureRequest request)
+ throws MOAException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ LoggingContext loggingCtx =
+ LoggingContextManager.getInstance().getLoggingContext();
+ XMLSignatureVerificationProfileFactory profileFactory =
+ new XMLSignatureVerificationProfileFactory(request);
+ VerifyXMLSignatureResponseBuilder responseBuilder =
+ new VerifyXMLSignatureResponseBuilder();
+ XMLSignatureVerificationResult result;
+ XMLSignatureVerificationProfile profile;
+ ReferencesCheckResult signatureManifestCheck;
+ DataObjectFactory dataObjFactory;
+ XMLDataObject signatureEnvironment;
+ Node signatureEnvironmentParent = null;
+ Element requestElement = null;
+ XMLSignature xmlSignature;
+ Date signingTime;
+ List supplements;
+ List dataObjectList;
+
+ // get the supplements
+ supplements = getSupplements(request);
+
+ // build XMLSignature
+ dataObjFactory = DataObjectFactory.getInstance();
+ signatureEnvironment =
+ dataObjFactory.createSignatureEnvironment(
+ request.getSignatureInfo().getVerifySignatureEnvironment(),
+ supplements);
+ xmlSignature = buildXMLSignature(signatureEnvironment, request);
+
+ // build the list of DataObjects
+ dataObjectList = buildDataObjectList(supplements);
+
+ // build profile
+ profile = profileFactory.createProfile();
+
+ // get the signingTime
+ signingTime = request.getDateTime();
+
+ // make the signature environment the root of the document, if it is not a
+ // separate document anyway; this is done to assure that canonicalization
+ // of the signature environment contains the correct namespace declarations
+ requestElement =
+ signatureEnvironment.getElement().getOwnerDocument().getDocumentElement();
+ if (requestElement != signatureEnvironment.getElement()) {
+ signatureEnvironmentParent =
+ signatureEnvironment.getElement().getParentNode();
+ requestElement.getOwnerDocument().replaceChild(
+ signatureEnvironment.getElement(),
+ requestElement);
+ }
+
+ // verify the signature
+ try {
+ XMLSignatureVerificationModule module =
+ XMLSignatureVerificationModuleFactory.getInstance();
+
+ module.setLog(new IaikLog(loggingCtx.getNodeID()));
+
+ result =
+ module.verifySignature(
+ xmlSignature,
+ dataObjectList,
+ profile,
+ signingTime,
+ new TransactionId(context.getTransactionID()));
+ } catch (IAIKException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+ throw moaException;
+ } catch (IAIKRuntimeException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+ throw moaException;
+ }
+
+ // swap back in the request as root document
+ if (requestElement != signatureEnvironment.getElement()) {
+ requestElement.getOwnerDocument().replaceChild(
+ requestElement,
+ signatureEnvironment.getElement());
+ signatureEnvironmentParent.appendChild(signatureEnvironment.getElement());
+ }
+
+ // check the result
+ signatureManifestCheck =
+ validateSignatureManifest(request, result, profile);
+
+ // build the response
+ responseBuilder.setResult(result, profile, signatureManifestCheck);
+
+ return responseBuilder.getResponse();
+ }
+
+ /**
+ * Select the <code>dsig:Signature</code> DOM element within the signature
+ * environment.
+ *
+ * @param signatureEnvironment The signature environment containing the
+ * <code>dsig:Signature</code>.
+ * @param request The <code>VerifyXMLSignatureRequest</code> containing the
+ * signature environment.
+ * @return The <code>dsig:Signature</code> element wrapped in a
+ * <code>XMLSignature</code> object.
+ * @throws MOAApplicationException An error occurred locating the
+ * <code>dsig:Signature</code>.
+ */
+ private XMLSignature buildXMLSignature(
+ XMLDataObject signatureEnvironment,
+ VerifyXMLSignatureRequest request)
+ throws MOAApplicationException {
+
+ VerifySignatureLocation signatureLocation =
+ request.getSignatureInfo().getVerifySignatureLocation();
+ Element signatureParent;
+
+ // evaluate the VerifySignatureLocation to get the signature parent
+ signatureParent =
+ InvokerUtils.evaluateSignatureLocation(
+ signatureEnvironment.getElement(),
+ signatureLocation);
+
+ // check for signatureParent to be a dsig:Signature element
+ if (!"Signature".equals(signatureParent.getLocalName())
+ || !Constants.DSIG_NS_URI.equals(signatureParent.getNamespaceURI())) {
+ throw new MOAApplicationException("2266", null);
+ }
+
+ return new XMLSignatureImpl(signatureParent);
+ }
+
+ /**
+ * Build the supplemental data objects contained in the
+ * <code>VerifyXMLSignatureRequest</code>.
+ *
+ * @param supplements A <code>List</code> of
+ * <code>XMLDataObjectAssociation</code>s containing the supplement data.
+ * @return A <code>List</code> of <code>DataObject</code>s representing the
+ * supplemental data objects.
+ * @throws MOASystemException A system error occurred building one of the data
+ * objects.
+ * @throws MOAApplicationException An error occurred building one of the data
+ * objects.
+ */
+ private List buildDataObjectList(List supplements)
+ throws MOASystemException, MOAApplicationException {
+ List dataObjectList = new ArrayList();
+
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+ Iterator iter;
+
+ for (iter = supplements.iterator(); iter.hasNext();) {
+ XMLDataObjectAssociation supplement =
+ (XMLDataObjectAssociation) iter.next();
+ dataObject =
+ factory.createFromXmlDataObjectAssociation(supplement, true, false);
+ dataObjectList.add(dataObject);
+ }
+
+ return dataObjectList;
+ }
+
+ /**
+ * Get the supplemental data contained in the
+ * <code>VerifyXMLSignatureRequest</code>.
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> containing the
+ * supplemental data.
+ * @return A <code>List</code> of <code>XMLDataObjectAssociation</code>
+ * objects containing the supplemental data.
+ * @throws MOAApplicationException An error occurred resolving one of the
+ * supplement profiles.
+ */
+ private List getSupplements(VerifyXMLSignatureRequest request)
+ throws MOAApplicationException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List supplementProfiles = request.getSupplementProfiles();
+
+ if (supplementProfiles != null) {
+ List supplements = new ArrayList();
+ List mappedProfiles =
+ ProfileMapper.mapSupplementProfiles(supplementProfiles, config);
+ Iterator iter;
+
+ for (iter = mappedProfiles.iterator(); iter.hasNext();) {
+ SupplementProfileExplicit profile =
+ (SupplementProfileExplicit) iter.next();
+ supplements.add(profile.getSupplementProfile());
+ }
+
+ return supplements;
+ }
+
+ return null;
+ }
+
+ /**
+ * Perform additional validations of the
+ * <code>XMLSignatureVerificationResult</code>.
+ *
+ * <p> In particular, it is verified that:
+ * <ul>
+ * <li>Each <code>ReferenceData</code> object contains transformation
+ * chain that matches one of the <code>Transforms</code> given in the
+ * corresponding <code>SignatureManifestCheckParams/ReferenceInfo</code></li>
+ * <li>The hash values of the <code>TransformParameter</code>s are valid.
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> containing the
+ * signature to verify.
+ * @param result The result produced by
+ * <code>XMLSignatureVerificationModule</code>.
+ * @param profile The profile used for validating the <code>request</code>.
+ * @return The result of additional validations of the signature manifest.
+ * @throws MOAApplicationException Post-validation of the
+ * <code>XMLSignatureVerificaitonResult</code> failed.
+ */
+ private ReferencesCheckResult validateSignatureManifest(
+ VerifyXMLSignatureRequest request,
+ XMLSignatureVerificationResult result,
+ XMLSignatureVerificationProfile profile)
+ throws MOAApplicationException {
+
+ SPSSFactory factory = SPSSFactory.getInstance();
+ MessageProvider msg = MessageProvider.getInstance();
+
+ // validate that each ReferenceData object contains transforms specified
+ // in the corresponding SignatureManifestCheckParams/ReferenceInfo
+ if (profile.checkSecurityLayerManifest()) {
+ List refInfos =
+ request.getSignatureManifestCheckParams().getReferenceInfos();
+ List refDatas = filterReferenceInfos(result.getReferenceDataList());
+ List failedReferencesList = new ArrayList();
+ Iterator refInfoIter;
+ Iterator refDataIter;
+
+ if (refInfos.size() != refDatas.size()) {
+ return factory.createReferencesCheckResult(1, null);
+ }
+
+ refInfoIter = refInfos.iterator();
+ refDataIter =
+ filterReferenceInfos(result.getReferenceDataList()).iterator();
+
+ while (refInfoIter.hasNext()) {
+ ReferenceInfo refInfo = (ReferenceInfo) refInfoIter.next();
+ ReferenceData refData = (ReferenceData) refDataIter.next();
+ List transforms = buildTransformsList(refInfo);
+ boolean found = false;
+ Iterator trIter;
+
+ for (trIter = transforms.iterator(); trIter.hasNext() && !found;) {
+ found = trIter.next().equals(refData.getTransformationList());
+ }
+
+ if (!found) {
+ Integer refIndex = new Integer(refData.getReferenceIndex());
+ String logMsg =
+ msg.getMessage("invoker.01", new Object[] { refIndex });
+
+ failedReferencesList.add(refIndex);
+ Logger.debug(new LogMsg(logMsg));
+ }
+ }
+
+ if (!failedReferencesList.isEmpty()) {
+ // at least one reference failed - return their indexes and check code 1
+ int[] failedReferences =
+ CollectionUtils.toIntArray(failedReferencesList);
+ ReferencesCheckResultInfo checkInfo =
+ factory.createReferencesCheckResultInfo(null, failedReferences);
+
+ return factory.createReferencesCheckResult(1, checkInfo);
+ }
+ }
+
+ // validate the hashes contained in all the ReferenceInfo objects of the
+ // security layer manifest
+ if (profile.checkSecurityLayerManifest()
+ && result.containsSecurityLayerManifest()) {
+ Map hashValues = buildTransformParameterHashValues(request);
+ Set transformParameterURIs =
+ buildTransformParameterURIs(profile.getTransformationSupplements());
+ List referenceInfoList =
+ result.getSecurityLayerManifest().getReferenceInfoList();
+ Iterator refIter;
+
+ for (refIter = referenceInfoList.iterator(); refIter.hasNext();) {
+ iaik.server.modules.xmlverify.ReferenceInfo ref =
+ (iaik.server.modules.xmlverify.ReferenceInfo) refIter.next();
+ byte[] hash = (byte[]) hashValues.get(ref.getURI());
+
+ if (!transformParameterURIs.contains(ref.getURI())
+ || (hash != null && !Arrays.equals(hash, ref.getHashValue()))) {
+
+ // the transform parameter doesn't exist or the hashs do not match
+ // return the index of the failed reference and check code 1
+ int[] failedReferences = new int[] { ref.getReferenceIndex()};
+ ReferencesCheckResultInfo checkInfo =
+ factory.createReferencesCheckResultInfo(null, failedReferences);
+ String logMsg =
+ msg.getMessage(
+ "invoker.02",
+ new Object[] { new Integer(ref.getReferenceIndex())});
+
+ Logger.debug(new LogMsg(logMsg));
+
+ return factory.createReferencesCheckResult(1, checkInfo);
+ }
+ }
+ }
+
+ return factory.createReferencesCheckResult(0, null);
+ }
+
+ /**
+ * Get all <code>Transform</code>s contained in all the
+ * <code>VerifyTransformsInfoProfile</code>s of the given
+ * <code>ReferenceInfo</code>.
+ *
+ * @param refInfo The <code>ReferenceInfo</code> object containing
+ * the transformations.
+ * @return A <code>List</code> of <code>List</code>s. Each of the
+ * <code>List</code>s contains <code>Transformation</code> objects.
+ * @throws MOAApplicationException An error occurred building one of the
+ * <code>Transformation</code>s.
+ */
+ private List buildTransformsList(ReferenceInfo refInfo)
+ throws MOAApplicationException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ List profiles = refInfo.getVerifyTransformsInfoProfiles();
+ List mappedProfiles =
+ ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config);
+ List transformsList = new ArrayList();
+ TransformationFactory factory = TransformationFactory.getInstance();
+ Iterator iter;
+
+ for (iter = mappedProfiles.iterator(); iter.hasNext();) {
+ VerifyTransformsInfoProfileExplicit profile =
+ (VerifyTransformsInfoProfileExplicit) iter.next();
+ List transforms = profile.getTransforms();
+
+ if (transforms != null) {
+ transformsList.add(factory.createTransformationList(transforms));
+ }
+ }
+
+ return transformsList;
+ }
+
+ /**
+ * Build the <code>Set</code> of all <code>TransformParameter</code> URIs.
+ *
+ * @param transformParameters The <code>List</code> of
+ * <code>TransformParameter</code>s, as provided to the verification.
+ * @return The <code>Set</code> of all <code>TransformParameter</code> URIs.
+ */
+ private Set buildTransformParameterURIs(List transformParameters) {
+ Set uris = new HashSet();
+ Iterator iter;
+
+ for (iter = transformParameters.iterator(); iter.hasNext();) {
+ DataObject transformParameter = (DataObject) iter.next();
+ uris.add(transformParameter.getURI());
+ }
+
+ return uris;
+ }
+
+ /**
+ * Build a mapping between <code>TransformParameter</code> URIs (a
+ * <code>String</code> and <code>dsig:HashValue</code> (a
+ * <code>byte[]</code>).
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code>.
+ * @return Map The resulting mapping.
+ * @throws MOAApplicationException An error occurred accessing one of
+ * the profiles.
+ */
+ private Map buildTransformParameterHashValues(VerifyXMLSignatureRequest request)
+ throws MOAApplicationException {
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ Map hashValues = new HashMap();
+ List refInfos =
+ request.getSignatureManifestCheckParams().getReferenceInfos();
+ Iterator refIter;
+
+ for (refIter = refInfos.iterator(); refIter.hasNext();) {
+ ReferenceInfo refInfo = (ReferenceInfo) refIter.next();
+ List profiles = refInfo.getVerifyTransformsInfoProfiles();
+ List mappedProfiles =
+ ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config);
+ Iterator prIter;
+
+ for (prIter = mappedProfiles.iterator(); prIter.hasNext();) {
+ VerifyTransformsInfoProfileExplicit profile =
+ (VerifyTransformsInfoProfileExplicit) prIter.next();
+ List trParameters = profile.getTransformParameters();
+ Iterator trIter;
+
+ for (trIter = trParameters.iterator(); trIter.hasNext();) {
+ TransformParameter transformParameter =
+ (TransformParameter) trIter.next();
+ String uri = transformParameter.getURI();
+
+ if (transformParameter.getTransformParameterType()
+ == TransformParameter.HASH_TRANSFORMPARAMETER) {
+ hashValues.put(
+ uri,
+ ((TransformParameterHash) transformParameter).getDigestValue());
+ }
+
+ }
+ }
+ }
+ return hashValues;
+ }
+
+ /**
+ * Filter the <code>ReferenceInfo</code>s returned by the
+ * <code>VerifyXMLSignatureResult</code> for comparison with the
+ * <code>ReferenceInfo</code> elements in the request.
+ *
+ * @param referenceInfos The <code>ReferenceInfo</code>s from the
+ * <code>VerifyXMLSignatureResult</code>.
+ * @return A <code>List</code> of all <code>ReferenceInfo</code>s whose type
+ * is not a XMLDsig manifest, Security Layer manifest, or ETSI signed
+ * property.
+ */
+ private List filterReferenceInfos(List referenceInfos) {
+ List filtered = new ArrayList();
+ Iterator iter;
+
+ for (iter = referenceInfos.iterator(); iter.hasNext();) {
+ iaik.server.modules.xmlverify.ReferenceInfo refInfo =
+ (iaik.server.modules.xmlverify.ReferenceInfo) iter.next();
+ String refType = refInfo.getReferenceType();
+
+ if (refType == null || !FILTERED_REF_TYPES.contains(refType)) {
+ filtered.add(refInfo);
+ }
+ }
+
+ return filtered;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java
new file mode 100644
index 000000000..858964c82
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java
@@ -0,0 +1,147 @@
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import iaik.server.modules.xmlverify.XMLSignatureVerificationProfile;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferenceInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.SignatureManifestCheckParams;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfileExplicit;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.pki.PKIProfileImpl;
+import at.gv.egovernment.moa.spss.server.iaik.xmlverify.XMLSignatureVerificationProfileImpl;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+
+/**
+ * A factory to create a <code>XMLSignatureVerificationProfile</code> from a
+ * <code>VerifyXMLSignatureRequest</code>, based on the current MOA
+ * configuration.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class XMLSignatureVerificationProfileFactory {
+
+ /** The <code>VerifyXMLSignatureRequest</code> for which to create profile
+ * information. */
+ private VerifyXMLSignatureRequest request;
+
+ /**
+ * Create a new <code>XMLSignatureVerificationProfileFactory</code>.
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> to extract
+ * profile data from.
+ */
+ public XMLSignatureVerificationProfileFactory(VerifyXMLSignatureRequest request) {
+ this.request = request;
+ }
+
+ /**
+ * Create a <code>XMLSignatureCreationProfile</code> from the
+ * <code>VerifyXMLSignaturesRequest</code> and the current MOA configuration.
+ *
+ * @return The <code>XMLSignatureVerificationProfile</code> containing
+ * additional information for verifying an XML signature.
+ * @throws MOASystemException A system error occurred building the profile.
+ * @throws MOAApplicationException An error occurred building the profile.
+ */
+ public XMLSignatureVerificationProfile createProfile()
+ throws MOASystemException, MOAApplicationException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ XMLSignatureVerificationProfileImpl profile =
+ new XMLSignatureVerificationProfileImpl();
+ SignatureManifestCheckParams checkParams;
+ String trustProfileID;
+
+ // set whether to check XMLDsig manifests
+ profile.setCheckXMLDsigManifests(true);
+
+ // set the certificate validation profile
+ trustProfileID = request.getTrustProfileId();
+ profile.setCertificateValidationProfile(
+ new PKIProfileImpl(config, trustProfileID));
+
+ // set whether hash input data is to be included
+ profile.setIncludeHashInputData(request.getReturnHashInputData());
+
+ // set the security layer manifest check parameters
+ checkParams = request.getSignatureManifestCheckParams();
+ if (checkParams != null) {
+ List transformationSupplements;
+
+ profile.setCheckSecurityLayerManifest(true);
+ profile.setIncludeReferenceInputData(
+ checkParams.getReturnReferenceInputData());
+ transformationSupplements = buildTransformationSupplements();
+ profile.setTransformationSupplements(transformationSupplements);
+ } else {
+ profile.setCheckSecurityLayerManifest(false);
+ profile.setIncludeReferenceInputData(false);
+ profile.setTransformationSupplements(Collections.EMPTY_LIST);
+ }
+
+ return profile;
+ }
+
+ /**
+ * Build supplemental data objects used in the transformations.
+ *
+ * @return A <code>List</code> of <code>DataObject</code>s providing
+ * supplemental data to the transformations.
+ * @throws MOASystemException A system error occurred building one of the
+ * transformations.
+ * @throws MOAApplicationException An error occurred building one of the
+ * transformations.
+ */
+ public List buildTransformationSupplements()
+ throws MOASystemException, MOAApplicationException {
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ SignatureManifestCheckParams checkParams =
+ request.getSignatureManifestCheckParams();
+ List transformsProfiles = new ArrayList();
+ List transformationSupplements = new ArrayList();
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ List refInfos = checkParams.getReferenceInfos();
+ Iterator refIter;
+ Iterator prIter;
+ Iterator trIter;
+
+ // build the list of all VerifyTransformsInfoProfiles in all ReferenceInfos
+ refInfos = checkParams.getReferenceInfos();
+ for (refIter = refInfos.iterator(); refIter.hasNext();) {
+ ReferenceInfo refInfo = (ReferenceInfo) refIter.next();
+ List profiles = refInfo.getVerifyTransformsInfoProfiles();
+
+ transformsProfiles.addAll(
+ ProfileMapper.mapVerifyTransformsInfoProfiles(profiles, config));
+ }
+
+ // build the DataObjects
+ for (prIter = transformsProfiles.iterator(); prIter.hasNext();) {
+ VerifyTransformsInfoProfileExplicit profile =
+ (VerifyTransformsInfoProfileExplicit) prIter.next();
+ List transformParameters = profile.getTransformParameters();
+
+ for (trIter = transformParameters.iterator(); trIter.hasNext();) {
+ TransformParameter trParam = (TransformParameter) trIter.next();
+ transformationSupplements.add(
+ factory.createFromTransformParameter(trParam));
+ }
+ }
+
+ return transformationSupplements;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java
new file mode 100644
index 000000000..068fab5ca
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLog.java
@@ -0,0 +1,126 @@
+package at.gv.egovernment.moa.spss.server.logging;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import iaik.logging.TransactionId;
+
+/**
+ * An implementation of the <code>iaik.logging.Log</code>
+ * interface that is based on Jakarta Commons-Logging.
+ *
+ * @author Fatemeh Philippi
+ * @version $Id$
+ */
+public class IaikLog implements iaik.logging.Log {
+ /** The hierarchy to log all IAIK output to. */
+ public static final String IAIK_LOG_HIERARCHY = "iaik.server";
+ /** The commons-loggin <code>Log</code> to use for logging the messages. */
+ private static Log log = LogFactory.getLog(IAIK_LOG_HIERARCHY);
+ /** The node ID to use. */
+ private String nodeId;
+
+ /**
+ * Create a new <code>IaikLog</code>.
+ *
+ * @param nodeId The node ID for this <code>Log</code> object.
+ */
+ public IaikLog(String nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ /**
+ * @see iaik.logging.Log#isDebugEnabled()
+ */
+ public boolean isDebugEnabled() {
+ return log.isDebugEnabled();
+ }
+
+ /**
+ * @see iaik.logging.Log#debug(TransactionId, Object, Throwable)
+ */
+ public void debug(TransactionId transactionId, Object message, Throwable t) {
+ IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message);
+
+ log.debug(msg, t);
+ }
+
+ /**
+ * @see iaik.logging.Log#isInfoEnabled()
+ */
+ public boolean isInfoEnabled() {
+ return log.isInfoEnabled();
+ }
+
+ /**
+ * @see iaik.logging.Log#info(TransactionId, Object, Throwable)
+ */
+ public void info(TransactionId transactionId, Object message, Throwable t) {
+ IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message);
+
+ log.info(msg, t);
+ }
+
+ /**
+ * @see iaik.logging.Log#isWarnEnabled()
+ */
+ public boolean isWarnEnabled() {
+ return log.isWarnEnabled();
+ }
+
+ /**
+ * @see iaik.logging.Log#warn(TransactionId, Object, Throwable)
+ */
+ public void warn(TransactionId transactionId, Object message, Throwable t) {
+ IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message);
+
+ log.warn(msg, t);
+ }
+
+ /**
+ * @see iaik.logging.Log#isErrorEnabled()
+ */
+ public boolean isErrorEnabled() {
+ return log.isErrorEnabled();
+ }
+
+ /**
+ * @see iaik.logging.Log#error(TransactionId, Object, Throwable)
+ */
+ public void error(TransactionId transactionId, Object message, Throwable t) {
+ IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message);
+
+ log.error(msg, t);
+ }
+
+ /**
+ * @see iaik.logging.Log#isFatalEnabled()
+ */
+ public boolean isFatalEnabled() {
+ return log.isFatalEnabled();
+ }
+
+ /**
+ * @see iaik.logging.Log#fatal(TransactionId, Object, Throwable)
+ */
+ public void fatal(TransactionId transactionId, Object message, Throwable t) {
+ IaikLogMsg msg = new IaikLogMsg(transactionId, nodeId, message);
+
+ log.fatal(msg, t);
+ }
+
+ /**
+ * @see iaik.logging.Log#setNodeId(String)
+ */
+ public void setNodeId(String nodeId) {
+ this.nodeId = nodeId;
+ }
+
+ /**
+ * @see iaik.logging.Log#getNodeId()
+ */
+ public String getNodeId() {
+ return nodeId;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java
new file mode 100644
index 000000000..a0e4def86
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogFactory.java
@@ -0,0 +1,42 @@
+package at.gv.egovernment.moa.spss.server.logging;
+
+import iaik.logging.Log;
+import iaik.logging.LogConfigurationException;
+import iaik.logging.LogFactory;
+
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+
+/**
+ * An implementation of the <code>iaik.logging.LogFactory</code> abstract
+ * class to log messages to the MOA logging subsystem.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class IaikLogFactory extends LogFactory {
+
+ public Log getInstance(Class clazz) throws LogConfigurationException {
+ return getInstanceImpl();
+ }
+
+ public Log getInstance(String name) throws LogConfigurationException {
+ return getInstanceImpl();
+ }
+
+ /**
+ * Return an instance of <code>iaik.logging.Log</code>.
+ *
+ * @return The <code>iaik.logging.Log</code> object to log messages to.
+ */
+ private Log getInstanceImpl() {
+ String nodeID =
+ LoggingContextManager.getInstance().getLoggingContext().getNodeID();
+
+ return new IaikLog(nodeID);
+ }
+
+ public void release() {
+ // we do not hold any resources
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java
new file mode 100644
index 000000000..75fb388a9
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/IaikLogMsg.java
@@ -0,0 +1,54 @@
+package at.gv.egovernment.moa.spss.server.logging;
+
+import iaik.logging.TransactionId;
+
+/**
+ * A unified message type to log messages from the IAIK subsystem.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class IaikLogMsg {
+
+ /** The transaction ID of this message. */
+ private TransactionId transactionId;
+ /** The node ID of this message. */
+ private String nodeId;
+ /** The message to log. */
+ private Object message;
+
+ /**
+ * Create a <code>IaikLogMsg</code> object.
+ *
+ * @param transactionId The transaction id of the transaction which
+ * generated this log message. May be <code>null</code>.
+ * @param nodeId The node id where this message was generated. May be
+ * <code>null</code>.
+ * @param message The actual message to log. May be <code>null</code>.
+ */
+ public IaikLogMsg(TransactionId transactionId, String nodeId, Object message) {
+ this.transactionId = transactionId;
+ this.nodeId = nodeId;
+ this.message = message;
+ }
+
+
+ /**
+ * Convert this log message to a <code>String</code>.
+ *
+ * @return The <code>String</code> representation of this log message.
+ */
+ public String toString() {
+ StringBuffer msg = new StringBuffer();
+
+ msg.append("TID=");
+ msg.append(transactionId != null ? transactionId.getLogID() : "<null>");
+ msg.append(" NID=");
+ msg.append(nodeId != null ? nodeId : "<null>");
+ msg.append(" MSG=");
+ msg.append(message != null ? message.toString() : "<null>");
+
+ return msg.toString();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java
new file mode 100644
index 000000000..9e0239464
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/logging/TransactionId.java
@@ -0,0 +1,38 @@
+package at.gv.egovernment.moa.spss.server.logging;
+
+/**
+ * An implementation of the <code>iaik.logging.TransactionId</code> interface.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class TransactionId implements iaik.logging.TransactionId {
+
+ /** The String representation for logging the transaction ID. */
+ private String logID;
+
+ /**
+ * Create a <code>TransactionId</code> object.
+ *
+ * @param logID The transaction id as it should be presented to the logging
+ * subsystem.
+ */
+ public TransactionId(String logID) {
+ this.logID = logID;
+ }
+
+ /**
+ * @see iaik.logging.TransactionId#getLogID()
+ */
+ public String getLogID() {
+ return logID;
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString() {
+ return getLogID();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java
new file mode 100644
index 000000000..9d6b255c2
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/AxisHandler.java
@@ -0,0 +1,252 @@
+package at.gv.egovernment.moa.spss.server.service;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.X509Certificate;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.MessageContext;
+import org.apache.axis.handlers.BasicHandler;
+import org.apache.axis.transport.http.HTTPConstants;
+import org.apache.axis.utils.Messages;
+import org.apache.axis.utils.XMLUtils;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionIDGenerator;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * An handler that is invoked on each web service request and performs some
+ * central message handling.
+ *
+ * Mainly sets up the <code>TransactionContext</code> for the current
+ * transaction (i.e. web service request).
+ *
+ * @author Patrick Peck
+ * @author Stefan Knirsch
+ * @version $Id$
+ */
+public class AxisHandler extends BasicHandler {
+
+ /** The property name for accessing the HTTP request. */
+ private static final String REQUEST_PROPERTY =
+ HTTPConstants.MC_HTTP_SERVLETREQUEST;
+ /** The property name for accessing the X509 client certificate chain. */
+ private static final String X509_CERTIFICATE_PROPERTY =
+ "javax.servlet.request.X509Certificate";
+ /** The property name for accessing the SOAP action header. */
+ private static final String SOAP_ACTION_HEADER = "soapaction";
+
+ /**
+ * Handle an invocation of this handler.
+ *
+ * @param msgContext Information about this request/response.
+ * @throws AxisFault An error occurred during processing of the request.
+ * @see org.apache.axis.Handler#invoke(MessageContext)
+ */
+ public void invoke(MessageContext msgContext) throws AxisFault {
+ if (!msgContext.getPastPivot()) {
+ handleRequest(msgContext);
+ } else {
+ handleResponse(msgContext);
+ }
+ }
+
+ /**
+ * This method is called by <code>invoke</code> to handle incoming requests.
+ *
+ * @param msgContext The context as provided to <code>invoke</code>.
+ * @throws AxisFault An error occurred during processing of the request.
+ */
+ private void handleRequest(MessageContext msgContext) throws AxisFault {
+ try {
+ // generate a unique transaction id and build the TransactionContext
+ // for this request
+ HttpServletRequest request =
+ (HttpServletRequest) msgContext.getProperty(REQUEST_PROPERTY);
+
+ X509Certificate[] clientCert =
+ (X509Certificate[]) request.getAttribute(X509_CERTIFICATE_PROPERTY);
+
+ ConfigurationProvider configuration =
+ ConfigurationProvider.getInstance();
+
+ TransactionContext context =
+ new TransactionContext(
+ TransactionIDGenerator.nextID(),
+ clientCert,
+ configuration);
+
+ context.setRequestName((String) request.getHeader(SOAP_ACTION_HEADER));
+
+ setUpContexts(context);
+
+ // log some information about the request
+ info(
+ "handler.00",
+ new Object[] {
+ context.getTransactionID(),
+ msgContext.getTargetService()});
+ info("handler.01", new Object[] { request.getRemoteAddr()});
+ if (clientCert != null) {
+ info(
+ "handler.02",
+ new Object[] {
+ clientCert[0].getSubjectDN(),
+ clientCert[0].getSerialNumber(),
+ clientCert[0].getIssuerDN()});
+
+ } else {
+ info("handler.03", null);
+ }
+ if (Logger.isDebugEnabled()) {
+ String msg = msgContext.getCurrentMessage().getSOAPPartAsString();
+ Logger.debug(new LogMsg(msg));
+ }
+ } catch (MOASystemException e) {
+ MOASystemException se = new MOASystemException("2900", null, e);
+ AxisFault fault = AxisFault.makeFault(se);
+ fault.setFaultDetail(new Element[] { se.toErrorResponse()});
+ throw fault;
+ } catch (Throwable t) {
+ MOASystemException e = new MOASystemException("2900", null, t);
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ }
+ }
+
+ /**
+ * This method is called by <code>invoke</code> to handle outgoing
+ * responses.
+ *
+ * @param msgContext The context as provided to <code>invoke</code>.
+ * @throws AxisFault An error occurred during processing of the response.
+ */
+ private void handleResponse(MessageContext msgContext) throws AxisFault {
+ info("handler.04", null);
+ if (Logger.isDebugEnabled()) {
+ String msg = msgContext.getCurrentMessage().getSOAPPartAsString();
+ Logger.debug(new LogMsg(msg));
+ }
+ tearDownContexts();
+ }
+
+ /**
+ * Called, when the processing of the web service fails.
+ *
+ * @param msgContext Information about the current request.
+ * @see org.apache.axis.Handler#onFault(org.apache.axis.MessageContext)
+ */
+ public void onFault(MessageContext msgContext) {
+ info("handler.05", null);
+ tearDownContexts();
+ }
+
+ /**
+ * Set up the thread-local contexts (<code>TransactionContext</code> and
+ * <code>LoggingContext</code>).
+ *
+ * @param context The <code>TransactionContext</code> to set for the current
+ * request.
+ */
+ private void setUpContexts(TransactionContext context) {
+ // set the transaction context in the TransactionContextManager
+ TransactionContextManager tcm = TransactionContextManager.getInstance();
+ tcm.setTransactionContext(context);
+
+ // set the logging context in the LoggingContextManager
+ LoggingContextManager lcm = LoggingContextManager.getInstance();
+ LoggingContext lc = new LoggingContext(context.getTransactionID());
+ lcm.setLoggingContext(lc);
+ }
+
+ /**
+ * Tear down the thread-local contexts.
+ */
+ private void tearDownContexts() {
+ // unset the transaction context
+ TransactionContextManager tcm = TransactionContextManager.getInstance();
+ tcm.setTransactionContext(null);
+
+ // unset the logging context
+ LoggingContextManager lcm = LoggingContextManager.getInstance();
+ lcm.setLoggingContext(null);
+ }
+
+ /**
+ * Generate the WSDL into the <code>msgContext</code>.
+ *
+ * The code of this method is more or less copied from the
+ * <code>org.apache.axis.handlers.soap.SOAPService</code> class contained in
+ * the 1.1 release of Axis to allow for a missing <code>wsdlFile</code> (so
+ * that a resource by the same name is searched for in the classpath). The
+ * implementation of this method should be obsolete if Axis 1.1 or higher is
+ * used.
+ *
+ * @param msgContext The <code>MessageContext</code> that will contain the
+ * WSDL description of the current web service.
+ * @throws AxisFault An error occurred producing the WSDL.
+ */
+ public void generateWSDL(MessageContext msgContext) throws AxisFault {
+ InputStream instream = null;
+
+ // Got a WSDL file in the service description, so try and read it
+ try {
+ String filename = "/resources/wsdl/MOA-SP-SS-1.0-20020829.wsdl";
+ msgContext.getService().getServiceDescription().getWSDLFile();
+ File file = new File(filename);
+ if (file.exists()) {
+ //if this resolves to a file, load it
+ instream = new FileInputStream(filename);
+ } else {
+ //else load a named resource in our classloader.
+ instream = this.getClass().getResourceAsStream(filename);
+ if (instream == null) {
+ String errorText = Messages.getMessage("wsdlFileMissing", filename);
+ throw new AxisFault(errorText);
+ }
+ }
+ Document doc = XMLUtils.newDocument(instream);
+ msgContext.setProperty("WSDL", doc);
+ } catch (Exception e) {
+ throw AxisFault.makeFault(e);
+ } finally {
+ if (instream != null) {
+ try {
+ instream.close();
+ } catch (IOException e) {
+ // ok to do nothing here
+ }
+ }
+ }
+ }
+
+ /**
+ * Utility function to issue an info message to the log.
+ *
+ * @param messageId The ID of the message to log.
+ * @param parameters Additional message parameters.
+ */
+ private static void info(String messageId, Object[] parameters) {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ Logger.info(new LogMsg(msg.getMessage(messageId, parameters)));
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java
new file mode 100644
index 000000000..7783ed3f6
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ConfigurationServlet.java
@@ -0,0 +1,120 @@
+package at.gv.egovernment.moa.spss.server.service;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.logging.LoggingContext;
+import at.gv.egovernment.moa.logging.LoggingContextManager;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.iaik.config.IaikConfigurator;
+import at.gv.egovernment.moa.spss.server.init.*;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A servlet to initialize and update the MOA configuration.
+ *
+ * @author Fatemeh Philippi
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ConfigurationServlet extends HttpServlet {
+ /** The document type of the HTML to generate. */
+ private static final String DOC_TYPE =
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n";
+
+ /**
+ * Handle a HTTP GET request, used to indicated that the MOA
+ * configuration needs to be updated (reloaded).
+ *
+ * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest, HttpServletResponse)
+ */
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+
+ MessageProvider msg = MessageProvider.getInstance();
+ PrintWriter out;
+
+ // set up a logging context for logging the reconfiguration
+ LoggingContextManager.getInstance().setLoggingContext(
+ new LoggingContext("configuration update"));
+
+ response.setContentType("text/html");
+ out = response.getWriter();
+ out.println(DOC_TYPE);
+ out.println("<head><title>MOA configuration update</title></head>");
+ out.println("<body bgcolor=\"#FFFFFF\">");
+ try {
+ // reconfigure the system
+ ConfigurationProvider config = ConfigurationProvider.reload();
+ IaikConfigurator iaikConfigurator = new IaikConfigurator();
+
+ iaikConfigurator.configure(config);
+
+ // print a status message
+ out.println("<p><b>" + msg.getMessage("config.06", null) + "</b></p>");
+ Logger.info(new LogMsg(msg.getMessage("config.06", null)));
+
+ if (!config.getWarnings().isEmpty()) {
+ // print the warnings
+ List allWarnings = new ArrayList();
+ Iterator iter;
+
+ allWarnings.addAll(config.getWarnings());
+ allWarnings.addAll(iaikConfigurator.getWarnings());
+
+ out.println("<p><b>" + msg.getMessage("config.29", null) + "</b></p>");
+ for (iter = allWarnings.iterator(); iter.hasNext();) {
+ out.println(iter.next() + "<br />");
+ }
+ out.println("<p><b>" + msg.getMessage("config.28", null) + "</b></p>");
+ }
+
+ } catch (Throwable t) {
+ out.println("<p><b>" + msg.getMessage("config.20", null) + "</b></p>");
+ out.println("<p><b>" + msg.getMessage("config.28", null) + "</b></p>");
+ Logger.warn(new LogMsg(msg.getMessage("config.20", null)), t);
+ }
+ out.println("</body>");
+
+ out.flush();
+ out.close();
+
+ // tear down the logging context
+ LoggingContextManager.getInstance().setLoggingContext(null);
+ }
+
+ /**
+ * Do the same as <code>doGet</code>.
+ *
+ * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse)
+ */
+ public void doPost(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ doGet(request, response);
+ }
+
+ /**
+ * Perform some initial initialization tasks for the MOA web services
+ * application.
+ *
+ * Does an initial load of the MOA configuration to test if a working web
+ * service can be provided.
+ *
+ * @see javax.servlet.GenericServlet#init()
+ */
+ public void init() throws ServletException {
+ SystemInitializer.init();
+ }
+
+} \ No newline at end of file
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java
new file mode 100644
index 000000000..997375305
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/RevocationArchiveCleaner.java
@@ -0,0 +1,83 @@
+package at.gv.egovernment.moa.spss.server.service;
+
+import java.util.Date;
+
+import iaik.pki.revocation.RevocationSourceTypes;
+import iaik.pki.store.revocation.archive.Archive;
+import iaik.pki.store.revocation.archive.ArchiveFactory;
+
+import at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+import at.gv.egovernment.moa.util.BoolUtils;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+import at.gv.egovernment.moa.spss.server.logging.TransactionId;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+
+/**
+ * A <code>Runnable</code> for periodically cleaning up the revocation archive.
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class RevocationArchiveCleaner implements Runnable {
+
+ /** The inverval between two clean-ups of the revocation archive. */
+ private long archiveCleanupInterval;
+
+ /**
+ * Create a new <code>RevocationArchiveCleaner</code>.
+ *
+ * @param archiveCleanupInterval The interval between two clean-ups of the
+ * revocation archive.
+ */
+ public RevocationArchiveCleaner(long archiveCleanupInterval) {
+ this.archiveCleanupInterval = archiveCleanupInterval;
+ }
+
+ /**
+ * Run the <code>RevocationArchiveCleaner</code> in its own
+ * <code>Thread</code>.
+ */
+ public void run() {
+ while (true) {
+ try {
+ ConfigurationProvider config =
+ ConfigurationProvider.getInstance();
+ String archiveInfo =
+ config.getGenericConfiguration(
+ ConfigurationProvider.ARCHIVE_REVOCATION_INFO_PROPERTY,
+ "false");
+
+ if (BoolUtils.valueOf(archiveInfo)) {
+ Archive archive = ArchiveFactory.getInstance().getArchive();
+ long archiveDurationMillis =
+ (long) config.getCRLArchiveDuration() * 86400000;
+
+ // delete old archive data
+ if (archiveDurationMillis > 0) {
+ Date olderThan =
+ new Date(System.currentTimeMillis() - archiveDurationMillis);
+
+ archive.deleteOldArchiveEntries(
+ RevocationSourceTypes.CRL,
+ olderThan,
+ new TransactionId("RevocationArchiveCleaner"));
+ }
+ }
+
+ } catch (Exception e) {
+ MessageProvider msg = MessageProvider.getInstance();
+ Logger.error(new LogMsg(msg.getMessage("init.02", null)), e);
+ }
+
+ // sleep
+ try {
+ Thread.sleep(archiveCleanupInterval * 1000);
+ } catch (InterruptedException e) {
+ // ok to do nothing here
+ }
+
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java
new file mode 100644
index 000000000..4224f5665
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/ServiceUtils.java
@@ -0,0 +1,72 @@
+package at.gv.egovernment.moa.spss.server.service;
+
+import java.io.ByteArrayInputStream;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+
+/**
+ * Helper methods for the Service classes.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ServiceUtils {
+
+ /**
+ * Schema-validate a request.
+ *
+ * @param request The request to validate.
+ * @throws MOAApplicationException An error occurred validating the requst.
+ */
+ public static void validateRequest(Element[] request)
+ throws MOAApplicationException {
+
+ // validate the request
+ try {
+ DOMUtils.validateElement(
+ request[0],
+ Constants.ALL_SCHEMA_LOCATIONS,
+ null);
+ } catch (Exception e) {
+ throw new MOAApplicationException(
+ "1100",
+ new Object[] { e.getMessage()},
+ e);
+ }
+ }
+
+ /**
+ * Reparse the request with schema-validation turned on so that ID references
+ * are resolved.
+ *
+ * @param request The request to reparse.
+ * @return The reparsed request.
+ * @throws MOAApplicationException An error occurred parsing the request.
+ */
+ public static Element reparseRequest(Element request)
+ throws MOAApplicationException {
+
+ try {
+ byte[] requestBytes = DOMUtils.serializeNode(request, "UTF-8");
+ Document validatedRequest =
+ DOMUtils.parseDocument(
+ new ByteArrayInputStream(requestBytes),
+ true,
+ Constants.ALL_SCHEMA_LOCATIONS,
+ null);
+ return validatedRequest.getDocumentElement();
+ } catch (Exception e) {
+ throw new MOAApplicationException(
+ "1100",
+ new Object[] { e.getMessage()},
+ e);
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java
new file mode 100644
index 000000000..07d7ab371
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureCreationService.java
@@ -0,0 +1,90 @@
+package at.gv.egovernment.moa.spss.server.service;
+
+import java.util.Collections;
+
+import javax.xml.namespace.QName;
+
+import org.w3c.dom.Element;
+
+import org.apache.axis.AxisFault;
+import org.apache.axis.i18n.Messages;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureRequestParser;
+import at.gv.egovernment.moa.spss.api.xmlbind.CreateXMLSignatureResponseBuilder;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureCreationInvoker;
+
+/**
+ * The service endpoint for the <code>SignatureCreation</code> web service.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SignatureCreationService {
+
+ /**
+ * Handle a <code>CreateXMLSignatureRequest</code>.
+ *
+ * @param request The <code>CreateXMLSignatureRequest</code> to work on
+ * (contained in the 0th element of the array).
+ * @return A <code>CreateXMLSignatureResponse</code> as the only element of
+ * the <code>Element</code> array.
+ * @throws AxisFault An error occurred during handling of the message.
+ */
+ public Element[] CreateXMLSignatureRequest(Element[] request)
+ throws AxisFault {
+ XMLSignatureCreationInvoker invoker =
+ XMLSignatureCreationInvoker.getInstance();
+ Element[] response = new Element[1];
+
+ // check that we have a CreateXMLSignatureRequest; if not, create an
+ // AxisFault, just like the org.apache.axis.providers.java.MsgProvider
+ if (request[0].getNodeName() != "CreateXMLSignatureRequest") {
+ QName qname =
+ new QName(request[0].getNamespaceURI(), request[0].getNodeName());
+ throw new AxisFault(
+ Messages.getMessage("noOperationForQName", qname.toString()));
+ }
+
+ // handle the request
+ try {
+ // create a parser and builder for binding API objects to/from XML
+ CreateXMLSignatureRequestParser requestParser =
+ new CreateXMLSignatureRequestParser();
+ CreateXMLSignatureResponseBuilder responseBuilder =
+ new CreateXMLSignatureResponseBuilder();
+ Element reparsedReq;
+ CreateXMLSignatureRequest requestObj;
+ CreateXMLSignatureResponse responseObj;
+
+ // validate the request
+ reparsedReq = ServiceUtils.reparseRequest(request[0]);
+
+ // convert to API objects
+ requestObj = requestParser.parse(reparsedReq);
+
+ // invoke the core logic
+ responseObj =
+ invoker.createXMLSignature(requestObj, Collections.EMPTY_SET);
+
+ // map back to XML
+ response[0] = responseBuilder.build(responseObj).getDocumentElement();
+
+ } catch (MOAException e) {
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ } catch (Throwable t) {
+ MOASystemException e = new MOASystemException("2900", null, t);
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ }
+
+ return response;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java
new file mode 100644
index 000000000..adb09ca0a
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/service/SignatureVerificationService.java
@@ -0,0 +1,130 @@
+package at.gv.egovernment.moa.spss.server.service;
+
+import org.w3c.dom.Element;
+
+import org.apache.axis.AxisFault;
+
+import at.gv.egovernment.moa.spss.MOAException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmsverify.VerifyCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyCMSSignatureRequestParser;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyCMSSignatureResponseBuilder;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureRequestParser;
+import at.gv.egovernment.moa.spss.api.xmlbind.VerifyXMLSignatureResponseBuilder;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.server.invoke.CMSSignatureVerificationInvoker;
+import at.gv.egovernment.moa.spss.server.invoke.XMLSignatureVerificationInvoker;
+
+/**
+ * The service endpoint for the <code>SignatureVerification</code> web service.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class SignatureVerificationService {
+
+ /**
+ * Handle a <code>VerifyCMSSignatureRequest</code>.
+ *
+ * @param request The <code>VerifyCMSSignatureRequest</code> to work on
+ * (contained in the 0th element of the array).
+ * @return A <code>VerifyCMSSignatureResponse</code> as the only element of
+ * the <code>Element</code> array.
+ * @throws AxisFault An error occurred during handling of the message.
+ */
+ public Element[] VerifyCMSSignatureRequest(Element[] request)
+ throws AxisFault {
+ CMSSignatureVerificationInvoker invoker =
+ CMSSignatureVerificationInvoker.getInstance();
+ Element[] response = new Element[1];
+
+ try {
+ // create a parser and builder for binding API objects to/from XML
+ VerifyCMSSignatureRequestParser requestParser =
+ new VerifyCMSSignatureRequestParser();
+ VerifyCMSSignatureResponseBuilder responseBuilder =
+ new VerifyCMSSignatureResponseBuilder();
+ Element reparsedReq;
+ VerifyCMSSignatureRequest requestObj;
+ VerifyCMSSignatureResponse responseObj;
+
+ // validate the request
+ reparsedReq = ServiceUtils.reparseRequest(request[0]);
+
+ // convert to API objects
+ requestObj = requestParser.parse(reparsedReq);
+
+ // invoke the core logic
+ responseObj = invoker.verifyCMSSignature(requestObj);
+
+ // map back to XML
+ response[0] = responseBuilder.build(responseObj).getDocumentElement();
+
+ } catch (MOAException e) {
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ } catch (Throwable t) {
+ MOASystemException e = new MOASystemException("2900", null, t);
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ }
+
+ return response;
+ }
+
+ /**
+ * Handle a <code>VerifyXMLSignatureRequest</code>.
+ *
+ * @param request The <code>VerifyXMLSignatureRequest</code> to work on
+ * (contained in the 0th element of the array).
+ * @return A <code>VerifyXMLSignatureResponse</code> as the only element of
+ * the <code>Element</code> array.
+ * @throws AxisFault An error occurred during handling of the message.
+ */
+ public Element[] VerifyXMLSignatureRequest(Element[] request)
+ throws AxisFault {
+ XMLSignatureVerificationInvoker invoker =
+ XMLSignatureVerificationInvoker.getInstance();
+ Element[] response = new Element[1];
+
+ try {
+ // create a parser and builder for binding API objects to/from XML
+ VerifyXMLSignatureRequestParser requestParser =
+ new VerifyXMLSignatureRequestParser();
+ VerifyXMLSignatureResponseBuilder responseBuilder =
+ new VerifyXMLSignatureResponseBuilder();
+ Element reparsedReq;
+ VerifyXMLSignatureRequest requestObj;
+ VerifyXMLSignatureResponse responseObj;
+
+ // validate the request
+ reparsedReq = ServiceUtils.reparseRequest(request[0]);
+
+ // convert to API objects
+ requestObj = requestParser.parse(reparsedReq);
+
+ // invoke the core logic
+ responseObj = invoker.verifyXMLSignature(requestObj);
+
+ // map back to XML
+ response[0] = responseBuilder.build(responseObj).getDocumentElement();
+
+ } catch (MOAException e) {
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ } catch (Throwable t) {
+ MOASystemException e = new MOASystemException("2900", null, t);
+ AxisFault fault = AxisFault.makeFault(e);
+ fault.setFaultDetail(new Element[] { e.toErrorResponse()});
+ throw fault;
+ }
+
+ return response;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java b/spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java
new file mode 100644
index 000000000..9fe17eae2
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/tools/CertTool.java
@@ -0,0 +1,242 @@
+package at.gv.egovernment.moa.spss.server.tools;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.security.cert.CertificateException;
+
+import iaik.asn1.structures.Name;
+import iaik.pki.store.certstore.CertStoreException;
+import iaik.pki.store.certstore.CertStoreTypes;
+import iaik.pki.store.certstore.directory.DirectoryCertStore;
+import iaik.pki.store.certstore.directory.DirectoryCertStoreParameters;
+import iaik.pki.store.certstore.directory.DirectoryStoreException;
+import iaik.security.ecc.provider.ECCProvider;
+import iaik.security.provider.IAIK;
+import iaik.utils.RFC2253NameParserException;
+import iaik.x509.X509Certificate;
+
+/**
+ * A tool to support X509 certificate handling for configuring the MOA SP/SS
+ * service.
+ *
+ * This class provides functions for:
+ * <ul>
+ * <li>printing certificate information</li>
+ * <li>adding certificates to the cert store</li>
+ * </ul>
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CertTool {
+
+ /** Error message if the DN cannot be parsed according to RFC2253. */
+ private static final String ILLEGAL_RFC2253_NAME =
+ "Kein gültiger RFC2253-Name";
+
+ /**
+ * Main entry point of the tool.
+ *
+ * @param args The command line arguments. A single argument is expected,
+ * which is the file name of the X509 certificate to inspect.
+ */
+ public static void main(String args[]) {
+ CertTool certTool = new CertTool();
+
+ if (args.length == 2 && "-info".equals(args[0])) {
+ initProviders();
+ certTool.printCertInfo(args[1], System.out);
+ } else if (args.length == 3 && "-add".equals(args[0])) {
+ initProviders();
+ certTool.addCertToCertStore(args[1], args[2]);
+ } else {
+ certTool.printUsage(System.err);
+ }
+ }
+
+ /**
+ * Init the JCE providers, depending on the JDK used.
+ *
+ * Adds the IAIK JCE and IAIK ECC providers.
+ */
+ private static void initProviders() {
+ if (System.getProperty("java.version").startsWith("1.3")) {
+ IAIK.addAsProvider();
+ } else {
+ IAIK.addAsJDK14Provider();
+ }
+ ECCProvider.addAsProvider();
+ }
+
+ /**
+ * Print the information about the certificate.
+ *
+ * This method will output information about the Subject DN, the Issuer DN and
+ * the serial number of the certificate.
+ *
+ * @param certFile The name of the certificate file to inspect.
+ * @param out The stream to print the information to.
+ */
+ public void printCertInfo(String certFile, PrintStream out) {
+ try {
+ InputStream is = new BufferedInputStream(new FileInputStream(certFile));
+ X509Certificate cert = new X509Certificate(is);
+ String issuerDN;
+ String serial;
+ String subjectDN;
+
+ try {
+ subjectDN = ((Name) (cert.getSubjectDN())).getRFC2253String();
+ } catch (RFC2253NameParserException e) {
+ subjectDN = ILLEGAL_RFC2253_NAME;
+ }
+
+ try {
+ issuerDN = ((Name) (cert.getIssuerDN())).getRFC2253String();
+ } catch (RFC2253NameParserException e) {
+ issuerDN = ILLEGAL_RFC2253_NAME;
+ }
+
+ serial = cert.getSerialNumber().toString();
+
+ out.println("SubjectDN (RFC2253): " + subjectDN);
+ out.println("IssuerDN (RFC2253) : " + issuerDN);
+ out.println("Serial Number : " + serial);
+ } catch (FileNotFoundException e) {
+ System.err.println("Zertifikat nicht gefunden: " + certFile);
+ } catch (IOException e) {
+ System.err.println(
+ "I/O Fehler beim Lesen des Zertifikats: " + e.getMessage());
+ } catch (CertificateException e) {
+ System.err.println(
+ "Fehler beim Lesen des Zertifikats: " + e.getMessage());
+ } catch (Throwable t) {
+ System.err.println("Allgemeiner Fehler: " + t.getMessage());
+ }
+ }
+
+ /**
+ * Add a certificate to a directory certificate store.
+ *
+ * @param certFile The certificate to add.
+ * @param certStoreRoot The root directory of the certificate store.
+ */
+ public void addCertToCertStore(String certFile, String certStoreRoot) {
+ try {
+ // read the certificate
+ InputStream is = new BufferedInputStream(new FileInputStream(certFile));
+ X509Certificate cert = new X509Certificate(is);
+
+ // initialize the DirectoryCertStore
+ DirectoryCertStore certStore =
+ new DirectoryCertStore(
+ new SimpleDirectoryCertStoreParameters(certStoreRoot),
+ null);
+
+ certStore.storeCertificate(cert, null);
+
+ System.out.println("\nDas Zertifikat wurde erfolreich hinzugefügt.\n");
+
+ } catch (FileNotFoundException e) {
+ System.err.println("Zertifikat nicht gefunden: " + certFile);
+ } catch (IOException e) {
+ System.err.println(
+ "I/O Fehler beim Lesen des Zertifikats: " + e.getMessage());
+ } catch (CertificateException e) {
+ System.err.println(
+ "Fehler beim Lesen des Zertifikats: " + e.getMessage());
+ } catch (DirectoryStoreException e) {
+ System.err.println(
+ "Fehler beim Öffnen des Zertifikatsspeichers: " + e.getMessage());
+ } catch (CertStoreException e) {
+ System.err.println(
+ "Fehler beim Hinzufügen des Zertifikats: " + e.getMessage());
+ } catch (Throwable t) {
+ System.err.println("Allgemeiner Fehler: " + t.getMessage());
+ t.printStackTrace();
+ }
+ }
+
+ /**
+ * Print tool usage.
+ *
+ * @param out The <code>PrintStream</code> to print to.
+ */
+ private void printUsage(PrintStream out) {
+ out.println("\nCerttool-Syntax:\n");
+ out.println("-info <X509 Zertifikatsdatei");
+ out.println();
+ out.println("-add <X509 Zertifikatsdatei> <Zertifikatsspeicher>");
+ out.println("\n");
+ }
+
+}
+
+/**
+ * Simple implementation of the <code>DirectoryCertStoreParameters</code>
+ * interface intelligent enough for setting up a simple
+ * <code>DirectoryCertStore</code> in the <code>CertTool</code>.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+class SimpleDirectoryCertStoreParameters
+ implements DirectoryCertStoreParameters {
+
+ /** The cert store root directory. */
+ private String rootDirectory;
+
+ /**
+ * Create a new <code>SimpleDirectoryCertStoreParameters</code> object.
+ *
+ * @param rootDirectory The root directory of the cert store.
+ */
+ public SimpleDirectoryCertStoreParameters(String rootDirectory) {
+ this.rootDirectory = rootDirectory;
+ }
+
+ /**
+ * @return <code>&quot;MOA Directory CertStore&quot;</code>
+ * @see iaik.pki.store.certstore.CertStoreParameters#getId()
+ */
+ public String getId() {
+ return "MOA Directory CertStore";
+ }
+
+ /**
+ * @return CertStoreTypes.DIRECTORY
+ * @see iaik.pki.store.certstore.CertStoreParameters#getType()
+ */
+ public String getType() {
+ return CertStoreTypes.DIRECTORY;
+ }
+
+ /**
+ * @return <code>false</code>
+ * @see iaik.pki.store.certstore.CertStoreParameters#isReadOnly()
+ */
+ public boolean isReadOnly() {
+ return false;
+ }
+
+ /**
+ * @return <code>false</code>
+ * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#createNew()
+ */
+ public boolean createNew() {
+ return false;
+ }
+
+ /**
+ * @return The root directory given at construction time.
+ * @see iaik.pki.store.certstore.directory.DirectoryCertStoreParameters#getRootDirectory()
+ */
+ public String getRootDirectory() {
+ return rootDirectory;
+ }
+
+} \ No newline at end of file
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java
new file mode 100644
index 000000000..407dbd4e9
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContext.java
@@ -0,0 +1,90 @@
+package at.gv.egovernment.moa.spss.server.transaction;
+
+import java.security.cert.X509Certificate;
+
+import at.gv.egovernment.moa.spss.server.config.ConfigurationProvider;
+
+/**
+ * Contains information about the current request.
+ *
+ * @author Stefan Knirsch
+ * @author Patrick Peck
+ */
+public class TransactionContext {
+
+ /** The client certificate. */
+ private X509Certificate[] clientCertificate = null;
+ /** The transaction ID. */
+ private String transactionID = null;
+ /** The name of the request. */
+ private String requestName = null;
+ /** The configuration to use throughout the request. */
+ private ConfigurationProvider configuration = null;
+
+ /**
+ * Create a <code>TransactionContext</code> object.
+ *
+ * @param transactionID A unique ID for this <code>TransactionContext</code>.
+ * @param clientCertificate The client certificate chain.
+ * @param configuration The MOA configuration to use for this transaction.
+ */
+ public TransactionContext(
+ String transactionID,
+ X509Certificate[] clientCertificate,
+ ConfigurationProvider configuration) {
+
+ this.transactionID = transactionID;
+ this.clientCertificate = clientCertificate;
+ this.configuration = configuration;
+ }
+
+ /**
+ * Returns the client certificate.
+ *
+ * @return The client certificate chain, if SSL client authentication has been
+ * configured in the web server and has been used by the client. The 0th
+ * element of the array contains the client certificate. <code>null</code>
+ * otherwise.
+ */
+ public X509Certificate[] getClientCertificate() {
+ return clientCertificate;
+ }
+
+ /**
+ * Returns the unique transaction ID.
+ *
+ * @return The transaction ID.
+ */
+ public String getTransactionID() {
+ return transactionID;
+ }
+
+ /**
+ * Returns the name of the request.
+ *
+ * @return The name of the request.
+ */
+ public String getRequestName() {
+ return requestName;
+ }
+
+ /**
+ * Sets the name of the request.
+ *
+ * @param requestName The request name to set.
+ */
+ public void setRequestName(String requestName) {
+ this.requestName = requestName;
+ }
+
+ /**
+ * Returns the <code>ConfigurationProvider</code> associated with this
+ * transaction.
+ *
+ * @return The ConfigurationProvider associated with this transaction.
+ */
+ public ConfigurationProvider getConfiguration() {
+ return configuration;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java
new file mode 100644
index 000000000..13127c3ae
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionContextManager.java
@@ -0,0 +1,62 @@
+package at.gv.egovernment.moa.spss.server.transaction;
+
+/**
+ * Provides each thread with an instance of <code>TransactionContext</code>.
+ *
+ * The single instance of the <code>TransactionContextManager</code> should be
+ * used to access contextual information for each web service transaction, e.g.
+ * the transaction ID, MOA configuration, client certificate, etc.
+ *
+ * @author Stefan Knirsch
+ * @author Patrick Peck
+ */
+public class TransactionContextManager {
+
+ /** The single instance of <code>TransactionContextManager</code> */
+ private static TransactionContextManager instance = null;
+
+ /** Contains a single <code>TransactionContext</code> for each thread. */
+ private ThreadLocal context = null;
+
+ /**
+ * Get the single instance of <code>TransactionContextManager</code>.
+ *
+ * @return The single instanc of <code>TransactionContextManager</code>.
+ */
+ public static synchronized TransactionContextManager getInstance() {
+ if (instance == null) {
+ instance = new TransactionContextManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Creates a new <code>TransactionContextManager</code>.
+ *
+ * Protected to disallow direct instantiation.
+ */
+ protected TransactionContextManager() {
+ context = new ThreadLocal();
+ }
+
+ /**
+ * Set the <code>TransactionContext</code> for the current thread.
+ *
+ * @param txContext The <code>TransactionContext</code> for this thread.
+ */
+ public void setTransactionContext(TransactionContext txContext) {
+ context.set(txContext);
+ }
+
+ /**
+ * Get the <code>TransactionContext</code> for the current thread.
+ *
+ * @return The <code>TransactionContext</code> for the current thread or
+ * <code>null</code>, if none has been set (or if this method is being invoked
+ * outside the bounds of a transaction).
+ */
+ public TransactionContext getTransactionContext() {
+ return (TransactionContext) context.get();
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java
new file mode 100644
index 000000000..6eb07defe
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/transaction/TransactionIDGenerator.java
@@ -0,0 +1,51 @@
+package at.gv.egovernment.moa.spss.server.transaction;
+
+
+/**
+ * A generator for unique transaction IDs.
+ *
+ * <p>The transaction IDs are of the form "<base>-<counter>", where:
+ * <ul>
+ * <li><code>base</code> is initialized with the system time when this class is
+ * being loaded</li>
+ * <li><code>counter</code> is incremented sequentially on each call to
+ * <code>nextID()</code></li>
+ * </ul>
+ * </p>
+ *
+ * <p> Assuming that it is highly unlikely that MOA servers are started at
+ * exactly the same time instant, the mechanism provided by this class should
+ * guarantee unique transaction IDs across multiple restarts and/or instances of
+ * the server.</p>
+ *
+ * @author Patrick Peck
+ * @author Stefan Knirsch
+ */
+public class TransactionIDGenerator {
+
+ /** Request sequence number. */
+ private static long counter = 0;
+ /** The base value to which to append the sequence number. */
+ private static String base = null;
+
+ /**
+ * Set up the initial base value.
+ */
+ static {
+ synchronized (TransactionIDGenerator.class) {
+ base = Long.toString(System.currentTimeMillis());
+ }
+ }
+
+ /**
+ * Returns the next transaction ID.
+ *
+ * @return The next transaction ID.
+ */
+ public static synchronized String nextID() {
+ counter++;
+
+ return (base + "-" + counter);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java b/spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java
new file mode 100644
index 000000000..92e8cb0f8
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/server/util/IdGenerator.java
@@ -0,0 +1,61 @@
+package at.gv.egovernment.moa.spss.server.util;
+
+import java.util.Set;
+
+/**
+ * Generate unique ID values for various objects in the response.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class IdGenerator {
+ /** The base value to append the counter to. */
+ private String base;
+ /** The <code>Set</code> of reserved ID values. */
+ private Set reserved;
+ /** The sequence number. */
+ private int count;
+
+ /**
+ * Create a new <code>IdGenerator</code>.
+ *
+ * @param base A base value to append the IDs to. The creator of this object
+ * should provide a base value, so that appending the counter leads to unique
+ * IDs.
+ * @param reserved The <code>Set</code> of reserved IDs. A call to
+ * <code>uniqueId()</code> will respect the reserved IDs.
+ */
+ public IdGenerator(String base, Set reserved) {
+ this.base = base;
+ this.reserved = reserved;
+ count = 1;
+ }
+
+ /**
+ * Create the next ID value in the sequence.
+ *
+ * @return The next ID value in the sequence.
+ */
+ public String nextId() {
+ return base + "-" + count++;
+ }
+
+ /**
+ * Create the next unique ID value which is unique in the reserved ID set.
+ *
+ * The created ID is added to the set of reserved IDs.
+ *
+ * @return The next ID value.
+ */
+ public String uniqueId() {
+ String nextId;
+
+ while (reserved.contains(nextId = nextId()));
+
+ reserved.add(nextId);
+
+ return nextId;
+
+ }
+
+}