aboutsummaryrefslogtreecommitdiff
path: root/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke
diff options
context:
space:
mode:
authorAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-11-03 14:38:34 +0100
committerAndreas Fitzek <andreas.fitzek@iaik.tugraz.at>2015-11-03 14:38:34 +0100
commit0872d2d8a64fd701776b272f49222428d8def07f (patch)
tree0954a523ad2cc7ad615dbbae5282dd56497e4c6e /moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke
parente635718b8d6a12e4e80207c8bdf30b02eed3f2ab (diff)
downloadmoa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.gz
moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.tar.bz2
moa-sig-0872d2d8a64fd701776b272f49222428d8def07f.zip
initial commit
Diffstat (limited to 'moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke')
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureCreationInvoker.java437
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java371
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java85
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateCMSSignatureResponseBuilder.java93
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java95
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java1039
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java177
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java318
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java87
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java273
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java75
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java71
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java100
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java282
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java127
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java501
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java586
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java543
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java727
-rw-r--r--moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java170
20 files changed, 6157 insertions, 0 deletions
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureCreationInvoker.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureCreationInvoker.java
new file mode 100644
index 0000000..718673a
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureCreationInvoker.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.algorithms.HashAlgorithms;
+import iaik.server.modules.cmssign.CMSSignature;
+import iaik.server.modules.cmssign.CMSSignatureCreationException;
+import iaik.server.modules.cmssign.CMSSignatureCreationModule;
+import iaik.server.modules.cmssign.CMSSignatureCreationModuleFactory;
+import iaik.server.modules.cmssign.CMSSignatureCreationProfile;
+import iaik.server.modules.keys.KeyEntryID;
+import iaik.server.modules.keys.KeyModule;
+import iaik.server.modules.keys.KeyModuleFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+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 at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+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.cmssign.CreateCMSSignatureRequest;
+import at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.cmssign.DataObjectInfo;
+import at.gv.egovernment.moa.spss.api.cmssign.SingleSignatureInfo;
+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.common.MetaInfo;
+import at.gv.egovernment.moa.spss.api.impl.CreateCMSSignatureResponseImpl;
+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.cmssign.CMSSignatureCreationProfileImpl;
+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;
+import at.gv.egovernment.moa.util.Constants;
+
+/**
+ * A class providing an API based interface to the
+ * <code>CMSSignatureCreationModule</code>.
+ *
+ * This class performs the invocation of the
+ * <code>iaik.server.modules.cmssign.CMSSignatureCreationModule</code> from a
+ * <code>CreateCMSSignatureRequest</code> given as an API object. The result of
+ * the invocation is integrated into a <code>CreateCMSSignatureResponse</code>
+ * and returned.
+ *
+ * @version $Id$
+ */
+public class CMSSignatureCreationInvoker {
+
+ private static Map HASH_ALGORITHM_MAPPING;
+
+ static {
+ HASH_ALGORITHM_MAPPING = new HashMap();
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA1_URI, HashAlgorithms.SHA1);
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA256_URI, HashAlgorithms.SHA256);
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA384_URI, HashAlgorithms.SHA384);
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA512_URI, HashAlgorithms.SHA512);
+ }
+
+
+ /** The single instance of this class. */
+ private static CMSSignatureCreationInvoker instance = null;
+
+ /**
+ * Get the only instance of this class.
+ *
+ * @return The only instance of this class.
+ */
+ public static synchronized CMSSignatureCreationInvoker getInstance() {
+ if (instance == null) {
+ instance = new CMSSignatureCreationInvoker();
+ }
+ return instance;
+ }
+
+ /**
+ * Create a new <code>CMSSignatureCreationInvoker</code>.
+ *
+ * Protected to disallow multiple instances.
+ */
+ protected CMSSignatureCreationInvoker() {
+ }
+
+
+
+ /**
+ * Process the <code>CreateCMSSignatureRequest<code> message and invoke the
+ * <code>XMLSignatureCreationModule</code> for every
+ * <code>SingleSignatureInfo</code> contained in the request.
+ *
+ * @param request A <code>CreateCMSSignatureRequest<code> API object
+ * containing the information for creating the signature(s).
+ * @param reserved A <code>Set</code> of reserved object IDs.
+ *
+ * @return A <code>CreateCMSSignatureResponse</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 CreateCMSSignatureResponse createCMSSignature(
+ CreateCMSSignatureRequest request,
+ Set reserved)
+ throws MOAException {
+
+ TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();
+ //LoggingContext loggingCtx = LoggingContextManager.getInstance().getLoggingContext();
+
+ CreateCMSSignatureResponseBuilder responseBuilder = new CreateCMSSignatureResponseBuilder();
+ CreateCMSSignatureResponse response = new CreateCMSSignatureResponseImpl();
+
+ boolean isSecurityLayerConform = false;
+ String structure = null;
+ String mimetype = null;
+
+ // select the SingleSignatureInfo elements
+ Iterator singleSignatureInfoIter = request.getSingleSignatureInfos().iterator();
+
+ // iterate over all the SingleSignatureInfo elements in the request
+ while (singleSignatureInfoIter.hasNext()) {
+ SingleSignatureInfo singleSignatureInfo = (SingleSignatureInfo) singleSignatureInfoIter.next();
+ isSecurityLayerConform = singleSignatureInfo.isSecurityLayerConform();
+
+
+ DataObjectInfo dataObjectInfo = singleSignatureInfo.getDataObjectInfo();
+ structure = dataObjectInfo.getStructure();
+
+ CMSDataObject dataobject = dataObjectInfo.getDataObject();
+ MetaInfo metainfo = dataobject.getMetaInfo();
+ mimetype = metainfo.getMimeType();
+
+ CMSContent content = dataobject.getContent();
+ InputStream contentIs = null;
+ // build the content data
+ switch (content.getContentType()) {
+ case CMSContent.EXPLICIT_CONTENT :
+ contentIs = ((CMSContentExcplicit) content).getBinaryContent();
+ break;
+ case CMSContent.REFERENCE_CONTENT :
+ String reference = ((CMSContentReference) content).getReference();
+ if (!"".equals(reference)) {
+ ExternalURIResolver resolver = new ExternalURIResolver();
+ contentIs = resolver.resolve(reference);
+ } else {
+ throw new MOAApplicationException("2301", null);
+ }
+ break;
+ default : {
+ throw new MOAApplicationException("2301", null);
+ }
+ }
+
+ // create CMSSignatureCreationModuleFactory
+ CMSSignatureCreationModule module = CMSSignatureCreationModuleFactory.getInstance();
+
+ List signedProperties = null;
+ boolean includeData = true;
+ if (structure.compareTo("enveloping") == 0)
+ includeData = true;
+ if (structure.compareTo("detached") == 0)
+ includeData = false;
+
+ ConfigurationProvider config = context.getConfiguration();
+
+ // get the key group id
+ String keyGroupID = request.getKeyIdentifier();
+ // set the key set
+ Set keySet = buildKeySet(keyGroupID);
+ if (keySet == null) {
+ throw new MOAApplicationException("2231", null);
+ } else if (keySet.size() == 0) {
+ throw new MOAApplicationException("2232", null);
+ }
+
+ // get digest algorithm
+ String digestAlgorithm = getDigestAlgorithm(config, keyGroupID);
+
+ // create CMSSignatureCreation profile:
+ CMSSignatureCreationProfile profile = new CMSSignatureCreationProfileImpl(
+ keySet,
+ digestAlgorithm,
+ signedProperties,
+ isSecurityLayerConform,
+ includeData,
+ mimetype);
+
+ // create CMSSignature from the CMSSignatureCreationModule
+ // build the additionalSignedProperties
+ List additionalSignedProperties = buildAdditionalSignedProperties();
+ TransactionId tid = new TransactionId(context.getTransactionID());
+ try {
+ CMSSignature signature = module.createSignature(profile, additionalSignedProperties, tid);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ // get CMS SignedData output stream from the CMSSignature and wrap it around out
+ boolean base64 = true;
+ OutputStream signedDataStream = signature.getSignature(out, base64);
+
+ // now write the data to be signed to the signedDataStream
+
+ int byteRead;
+ BigDecimal counter = new BigDecimal("0");
+ BigDecimal one = new BigDecimal("1");
+
+ while ((byteRead=contentIs.read()) >= 0) {
+ //System.out.println("counterXX: " + counter);
+
+ if (inRange(counter, dataobject)) {
+ //System.out.println("Lösche...");
+ // set byte to 0x00
+ signedDataStream.write(0);
+ }
+ else
+ signedDataStream.write(byteRead);
+
+ counter = counter.add(one);
+ }
+
+
+// byte[] buf = new byte[4096];
+// int bytesRead;
+// while ((bytesRead = contentIs.read(buf)) >= 0) {
+// signedDataStream.write(buf, 0, bytesRead);
+// }
+//
+ // finish SignedData processing by closing signedDataStream
+ signedDataStream.close();
+ String base64value = out.toString();
+
+ responseBuilder.addCMSSignature(base64value);
+
+
+ } catch (CMSSignatureCreationException e) {
+ MOAException moaException = IaikExceptionMapper.getInstance().map(e);
+
+ responseBuilder.addError(
+ moaException.getMessageId(),
+ moaException.getMessage());
+ Logger.warn(moaException.getMessage(), e);
+
+ }
+ catch (IOException e) {
+ throw new MOAApplicationException("2301", null, e);
+ }
+
+ }
+
+
+ return responseBuilder.getResponse();
+ }
+
+ private boolean inRange(BigDecimal counter, CMSDataObject dataobject) {
+ BigDecimal from = dataobject.getExcludeByteRangeFrom();
+ BigDecimal to = dataobject.getExcludeByteRangeTo();
+
+ if ( (from == null) || (to == null))
+ return false;
+
+ int compare = counter.compareTo(from);
+ if (compare == -1)
+ return false;
+ else {
+ compare = counter.compareTo(to);
+ if (compare == 1)
+ return false;
+ else
+ return true;
+ }
+
+
+
+ }
+
+
+ private String getDigestAlgorithm(ConfigurationProvider config, String keyGroupID) throws MOASystemException {
+ // get digest method on key group level (if configured)
+ String configDigestMethodKG = config.getKeyGroup(keyGroupID).getDigestMethodAlgorithm();
+ // get default digest method (if configured)
+ String configDigestMethod = config.getDigestMethodAlgorithmName();
+
+
+ String digestMethod = null;
+ if (configDigestMethodKG != null) {
+ // if KG specific digest method is configured
+ digestMethod = (String) HASH_ALGORITHM_MAPPING.get(configDigestMethodKG);
+ if (digestMethod == null) {
+ error(
+ "config.17",
+ new Object[] { configDigestMethodKG});
+ throw new MOASystemException("2900", null);
+ }
+ Logger.debug("Digest algorithm: " + digestMethod + "(configured in KeyGroup)");
+ }
+ else {
+ // else get default configured digest method
+ digestMethod = (String) HASH_ALGORITHM_MAPPING.get(configDigestMethod);
+ if (digestMethod == null) {
+ error(
+ "config.17",
+ new Object[] { configDigestMethod});
+ throw new MOASystemException("2900", null);
+ }
+ Logger.debug("Digest algorithm: " + digestMethod + "(default)");
+
+ }
+ return digestMethod;
+ }
+
+ /**
+ * 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)));
+ }
+
+ /**
+ * 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;
+ }
+ }
+
+ /**
+ * 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;
+
+ return additionalSignedProperties;
+ }
+
+} \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java
new file mode 100644
index 0000000..aca6f58
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationInvoker.java
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.IAIKException;
+import iaik.server.modules.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 iaik.x509.X509Certificate;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+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.config.TrustProfile;
+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.CertificateUtils;
+import at.gv.egovernment.moa.spss.util.QCSSCDResult;
+
+/**
+ * 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 = null;
+ 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 actual trustprofile
+ TrustProfile trustProfile = context.getConfiguration().getTrustProfile(request.getTrustProfileId());
+
+ try {
+ // get the signed content
+ signedContent = getSignedContent(request);
+
+ // build the profile
+ profile = profileFactory.createProfile();
+
+ // get the signing time
+ signingTime = request.getDateTime();
+
+ // verify the signature
+ 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);
+ } catch (MOAException e)
+ {
+ throw e;
+ }
+ finally
+ {
+ try
+ {
+ if (signedContent != null) signedContent.close();
+ }
+ catch (Throwable t)
+ {
+ // Intentionally do nothing here
+ }
+ }
+
+ QCSSCDResult qcsscdresult = new QCSSCDResult();
+
+ // 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();
+ String issuerCountryCode = null;
+ // QC/SSCD check
+ List list = result.getCertificateValidationResult().getCertificateChain();
+ if (list != null) {
+ X509Certificate[] chain = new X509Certificate[list.size()];
+
+ Iterator it = list.iterator();
+ int i = 0;
+ while(it.hasNext()) {
+ chain[i] = (X509Certificate)it.next();
+ i++;
+ }
+
+
+ qcsscdresult = CertificateUtils.checkQCSSCD(chain, trustProfile.isTSLEnabled());
+
+ // get signer certificate issuer country code
+ issuerCountryCode = CertificateUtils.getIssuerCountry((X509Certificate)list.get(0));
+
+ }
+
+ responseBuilder.addResult(result, trustProfile, qcsscdresult.isQC(), qcsscdresult.isQCSourceTSL(), qcsscdresult.isSSCD(), qcsscdresult.isSSCDSourceTSL(), issuerCountryCode);
+ }
+ } else {
+ int i;
+
+ for (i = 0; i < signatories.length; i++) {
+ int sigIndex = signatories[i] - 1;
+
+ try {
+ result =
+ (CMSSignatureVerificationResult) results.get(signatories[i] - 1);
+
+ String issuerCountryCode = null;
+ // QC/SSCD check
+ List list = result.getCertificateValidationResult().getCertificateChain();
+ if (list != null) {
+ X509Certificate[] chain = new X509Certificate[list.size()];
+
+ Iterator it = list.iterator();
+ int j = 0;
+ while(it.hasNext()) {
+ chain[j] = (X509Certificate)it.next();
+ j++;
+ }
+
+
+ qcsscdresult = CertificateUtils.checkQCSSCD(chain, trustProfile.isTSLEnabled());
+
+ issuerCountryCode = CertificateUtils.getIssuerCountry((X509Certificate)list.get(0));
+ }
+
+ responseBuilder.addResult(result, trustProfile, qcsscdresult.isQC(), qcsscdresult.isQCSourceTSL(), qcsscdresult.isSSCD(), qcsscdresult.isSSCDSourceTSL(), issuerCountryCode);
+ } 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 {
+
+ InputStream is = null;
+ 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 :
+ is = ((CMSContentExcplicit) content).getBinaryContent();
+ is = excludeByteRange(is, request);
+ return is;
+ case CMSContent.REFERENCE_CONTENT :
+ String reference = ((CMSContentReference) content).getReference();
+ if (!"".equals(reference)) {
+ ExternalURIResolver resolver = new ExternalURIResolver();
+ is = resolver.resolve(reference);
+ is = excludeByteRange(is, request);
+ return is;
+ } else {
+ return null;
+ }
+ default :
+ return null;
+ }
+
+
+
+ }
+
+ private InputStream excludeByteRange(InputStream contentIs, VerifyCMSSignatureRequest request) throws MOAApplicationException {
+
+ int byteRead;
+
+ ByteArrayOutputStream contentOs = new ByteArrayOutputStream();
+
+ CMSDataObject dataobject = request.getDataObject();
+ BigDecimal from = dataobject.getExcludeByteRangeFrom();
+ BigDecimal to = dataobject.getExcludeByteRangeTo();
+
+ if ( (from == null) || (to == null))
+ return contentIs;
+
+ BigDecimal counter = new BigDecimal("0");
+ BigDecimal one = new BigDecimal("1");
+
+ try {
+ while ((byteRead=contentIs.read()) >= 0) {
+
+ if (inRange(counter, dataobject)) {
+ // if byte is in byte range, set byte to 0x00
+ contentOs.write(0);
+ }
+ else
+ contentOs.write(byteRead);
+
+ counter = counter.add(one);
+ }
+
+ InputStream is = new ByteArrayInputStream(contentOs.toByteArray());
+
+ return is;
+
+
+ } catch (IOException e) {
+ throw new MOAApplicationException("2301", null, e);
+ }
+
+ }
+
+
+ private boolean inRange(BigDecimal counter, CMSDataObject dataobject) {
+ BigDecimal from = dataobject.getExcludeByteRangeFrom();
+ BigDecimal to = dataobject.getExcludeByteRangeTo();
+
+ if ( (from == null) || (to == null))
+ return false;
+
+ int compare = counter.compareTo(from);
+ if (compare == -1)
+ return false;
+ else {
+ compare = counter.compareTo(to);
+ if (compare == 1)
+ return false;
+ else
+ return true;
+ }
+
+
+
+ }
+
+}
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java
new file mode 100644
index 0000000..5f459ac
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CMSSignatureVerificationProfileFactory.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateCMSSignatureResponseBuilder.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateCMSSignatureResponseBuilder.java
new file mode 100644
index 0000000..aa52fe0
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateCMSSignatureResponseBuilder.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmssign.CMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.cmssign.CreateCMSSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse;
+
+/**
+ * A class to build a <code>CreateCMSSignatureResponse</code>.
+ *
+ * <p>The methods <code>addSignature()</code> and <code>addError()</code> may be
+ * called in any combination to add <code>CMSignature</code> and
+ * <code>ErrorResponse</code> elements to the response. One of these functions
+ * must be called at least once to produce a
+ * <code>CreateCMSSignatureResponse</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 CreateCMSSignatureResponseBuilder {
+
+ /** 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>CreateCMSSignatureResponse</code> built so far.
+ *
+ * @return The <code>CreateCMSSignatureResponse</code> built so far.
+ */
+ public CreateCMSSignatureResponse getResponse() {
+ return factory.createCreateCMSSignatureResponse(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 addCMSSignature(String base64value) {
+ CMSSignatureResponse responseElement =
+ factory.createCMSSignatureResponse(base64value);
+ 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java
new file mode 100644
index 0000000..7a7161d
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/CreateXMLSignatureResponseBuilder.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java
new file mode 100644
index 0000000..d775fdb
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/DataObjectFactory.java
@@ -0,0 +1,1039 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.NodeSetData;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIReference;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.xerces.dom.CoreDocumentImpl;
+import org.w3c.dom.Attr;
+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 at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+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.ContentLocRef;
+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.server.transaction.TransactionContext;
+import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
+import at.gv.egovernment.moa.spss.util.MOASPSSEntityResolver;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+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.MOAErrorHandler;
+import at.gv.egovernment.moa.util.StreamEntityResolver;
+import at.gv.egovernment.moa.util.StreamUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+import iaik.server.modules.xml.DataObject;
+import iaik.server.modules.xml.NodeListImplementation;
+import iaik.server.modules.xml.URIReferenceImpl;
+import iaik.server.modules.xml.XMLDataObject;
+import iaik.xml.crypto.utils.URIDereferencerImpl;
+
+/**
+ * A class to create <code>DataObject</code>s contained in different
+ * locations of the MOA XML request format.
+ *
+ * @author Patrick Peck
+ * @author Gregor Karlinger
+ * @version $Id$
+ */
+public class DataObjectFactory {
+
+ /**
+ * XPATH for registering ID attributes of known schemas if
+ * validating parsing fails.
+ */
+ private static final String XPATH =
+ "descendant-or-self::node()[" +
+ "namespace-uri()='http://www.w3.org/2000/09/xmldsig#' " +
+ "or namespace-uri()='http://reference.e-government.gv.at/namespace/persondata/20020228#' " +
+ "or starts-with(namespace-uri(), 'http://uri.etsi.org/01903/')" +
+ "]/attribute::Id";
+
+ /** 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 MOASPSSEntityResolver();
+ } else {
+ EntityResolverChain chain = new EntityResolverChain();
+
+ chain.addEntityResolver(buildSupplementEntityResolver(supplements));
+ chain.addEntityResolver(new MOASPSSEntityResolver());
+ 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.LOCREF_CONTENT:
+ {
+ String locRefURI = ((ContentLocRef) content).getLocationReferenceURI();
+ InputStream is = null;
+ try
+ {
+ TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();
+ is = context.ResolveURI(locRefURI);
+ if (is == null) {
+ ExternalURIResolver uriResolver = new ExternalURIResolver();
+ is = uriResolver.resolve(locRefURI);
+ }
+ contentBytes = StreamUtils.readStream(is);
+ }
+ catch (MOAApplicationException e)
+ {
+ throw new MOAApplicationException("3203", new Object[]{reference, locRefURI}, e);
+ }
+ finally
+ {
+ closeInputStream(is);
+ }
+ break;
+ }
+ case Content.REFERENCE_CONTENT :
+ {
+ ExternalURIResolver uriResolver = new ExternalURIResolver();
+ InputStream is = null;
+ try
+ {
+ is = uriResolver.resolve(reference);
+ contentBytes = StreamUtils.readStream(is);
+ }
+ catch (Exception e)
+ {
+ throw e;
+ }
+ finally
+ {
+ closeInputStream(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);
+ }
+
+ if (Logger.isTraceEnabled()) {
+ // For logging in Debug-Mode: Mask baseid with xxx
+ String logString = new String(contentBytes);
+ // TODO use RegExp
+ String startS = "<pr:Identification><pr:Value>";
+ String endS = "</pr:Value><pr:Type>urn:publicid:gv.at:baseid</pr:Type>";
+ String logWithMaskedBaseid = logString;
+ int start = logString.indexOf(startS);
+ if (start > -1) {
+ int end = logString.indexOf(endS);
+ if (end > -1) {
+ logWithMaskedBaseid = logString.substring(0, start);
+ logWithMaskedBaseid += startS;
+ logWithMaskedBaseid += "xxxxxxxxxxxxxxxxxxxxxxxx";
+ logWithMaskedBaseid += logString.substring(end, logString.length());
+ }
+ }
+
+ // try to parse validating
+ Logger.trace(">>> parsing the following content: \n" + logWithMaskedBaseid);
+ }
+ try {
+ ByteArrayInputStream is = new ByteArrayInputStream(contentBytes);
+ Document doc =
+ DOMUtils.parseDocument(
+ is,
+ true,
+ Constants.ALL_SCHEMA_LOCATIONS,
+ null,
+ entityResolver,
+ new MOAErrorHandler());
+ Logger.trace("<<< parsed");
+
+ 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);
+ // Since the parse tree will not contain any post schema validation information,
+ // we need to register any attributes known to be of type xsd:Id manually.
+ NodeList idAttributes = XPathUtils.selectNodeList(doc.getDocumentElement(), XPATH);
+ for (int i = 0; i < idAttributes.getLength(); i++) {
+ Node item = idAttributes.item(i);
+ if (item instanceof Attr) {
+ Attr attr = (Attr) item;
+ Element owner = attr.getOwnerElement();
+ // Only available in DOM-Level 3 (Java 1.5):
+ // owner.setIdAttributeNode(attr, true);
+ if (doc instanceof CoreDocumentImpl) {
+ ((CoreDocumentImpl) doc).putIdentifier(attr.getValue(), owner);
+ }
+ }
+ }
+ 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 {
+ // CHANGE IXSIL to XSECT
+ // maybe use URIDereferencerImpl or XPath ...??
+ //XPointerReferenceResolver resolver = new XPointerReferenceResolver();
+ URIDereferencerImpl uriDereferencer = new URIDereferencerImpl();
+ URIReference uriReference = new URIReferenceImpl(uri, null, signatureEnvironment);
+ Data returnedData = uriDereferencer.dereference(uriReference, null);
+
+ if(returnedData instanceof NodeSetData) {
+ NodeSetData nodeSetData = (NodeSetData)returnedData;
+ Iterator nodesIterator = nodeSetData.iterator();
+ List nodeList = new ArrayList();
+
+ while(nodesIterator.hasNext()) {
+ nodeList.add(nodesIterator.next());
+ }
+
+ NodeList nodes = new NodeListImplementation(nodeList);
+ dataObject = new XMLNodeListDataObjectImpl(nodes);
+ } else if(returnedData instanceof OctetStreamData) {
+ OctetStreamData streamData = (OctetStreamData)returnedData;
+ dataObject = new ByteStreamDataObjectImpl(streamData.getOctetStream());
+ } else {
+ throw new MOAApplicationException("2237", new Object[] { uri });
+ }
+
+ //URI uriObj = new URI(uri);
+ //NodeList nodes =
+ // resolver.resolveForest(
+ // uriObj,
+ // signatureEnvironment.getOwnerDocument(),
+ // null);
+
+ } 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)
+ throws MOAApplicationException
+ {
+ 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.LOCREF_CONTENT:
+ {
+ String locRefURI = ((ContentLocRef) content).getLocationReferenceURI();
+
+ TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();
+ if (context.FindResolvedEntity(locRefURI)==null) {
+
+ ExternalURIResolver uriResolver = new ExternalURIResolver();
+ InputStream uriStream = null;
+ byte[] contentBytes;
+ String contentType = null;
+ try
+ {
+ uriStream = uriResolver.resolve(locRefURI);
+ contentBytes = StreamUtils.readStream(uriStream);
+ contentType = uriResolver.getContentType();
+ }
+ catch (Exception e)
+ {
+ throw new MOAApplicationException("3202", new Object[]{reference, locRefURI}, e);
+ }
+ finally
+ {
+ closeInputStream(uriStream);
+ }
+ context.PutResolvedEntity(locRefURI, contentBytes, contentType);
+ }
+ InputStream contentIS = context.ResolveURI(locRefURI);
+ entities.put(reference, contentIS);
+ 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)
+ {
+ throw new MOAApplicationException("2281", new Object[]{reference}, e);
+ }
+ }
+ 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 finalDataMetaInfo The meta information corresponding with <code>content</code>.
+ * @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,
+ MetaInfo finalDataMetaInfo,
+ 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.LOCREF_CONTENT :
+ {
+ String locRefURI = ((ContentLocRef) content).getLocationReferenceURI();
+ try
+ {
+ dataObject = createFromURIImpl(locRefURI, referenceAsXml);
+ }
+ catch (MOAApplicationException e)
+ {
+ throw new MOAApplicationException("3201", new Object[]{reference, locRefURI}, e);
+ }
+ break;
+ }
+ case Content.REFERENCE_CONTENT :
+ {
+ dataObject = createFromURIImpl(reference, referenceAsXml);
+ break;
+ }
+ }
+
+ // set URI and reference ID
+ dataObject.setURI(reference);
+ dataObject.setReferenceID(referenceID);
+
+ // set Type gathered from corresponding meta information
+ dataObject.setTypeURI(finalDataMetaInfo.getType());
+
+ 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;
+ }
+ case Content.LOCREF_CONTENT :
+ {
+ String locRefURI = ((ContentLocRef) content).getLocationReferenceURI();
+ try
+ {
+ dataObject = createFromURIImpl(locRefURI, false);
+ }
+ catch (MOAApplicationException e)
+ {
+ throw new MOAApplicationException("3201", new Object[]{content.getReference(), locRefURI}, e);
+ }
+ 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());
+ ByteArrayInputStream bis;
+ try
+ {
+ bis = new ByteArrayInputStream(StreamUtils.readStream(is));
+ }
+ catch (IOException e)
+ {
+ throw new MOAApplicationException("2238", new Object[] {transformParameter.getURI()}, e);
+ }
+ finally
+ {
+ closeInputStream(is);
+ }
+ String contentType = resolver.getContentType();
+ dataObject = new ByteStreamDataObjectImpl(bis);
+ 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 {
+
+ Logger.trace(">>> resolving uri \"" + uri + "\"");
+
+ ExternalURIResolver resolver = new ExternalURIResolver();
+
+ TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();
+ InputStream is = context.ResolveURI(uri);
+ String contentType = null;
+ boolean foundURI = false;
+ if (is == null) {
+ is = resolver.resolve(uri);
+ contentType = resolver.getContentType();
+ } else {
+ foundURI = true;
+ contentType = (String) context.FindResolvedEntity(uri).get(1);
+ Logger.trace("found \"" + uri + "\" InputStream in preread Supplements!, do not read any more. Content=" + contentType);
+ }
+
+ 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);
+ }
+ finally
+ {
+ closeInputStream(is);
+ }
+ } else {
+ try {
+ // try parsing non-validating: need not succeed
+ is = resolver.resolve(uri);
+ doc = DOMUtils.parseDocument(is, false, null, null);
+ closeInputStream(is);
+ dataObject = new XMLDataObjectImpl(doc.getDocumentElement());
+ } catch (Exception e) {
+ // this is the last chance: return the data as a byte stream
+ Logger.trace(">>> reading stream for \"" + uri + "\"");
+ is = resolver.resolve(uri);
+ ByteArrayInputStream bis;
+ try
+ {
+ bis = new ByteArrayInputStream(StreamUtils.readStream(is));
+ dataObject = new ByteStreamDataObjectImpl(bis);
+ }
+ catch (IOException e1)
+ {
+ throw new MOAApplicationException("2210", new Object[] { uri }, e1);
+ }
+ finally
+ {
+ closeInputStream(is);
+ }
+ Logger.trace(">>> read stream for \"" + uri + "\"");
+ }
+ }
+ }
+
+ else if (asXml)
+ {
+ // if we need XML data, we're in the wrong place here
+ closeInputStream(is);
+ throw new MOAApplicationException("2211", new Object[] { uri });
+ }
+ else
+ {
+ // content is binary: make it available as a binary input stream
+ Logger.trace(">>> getting binary input for \"" + uri + "\"");
+ byte[] contentBytes;
+ ByteArrayInputStream bis;
+ try
+ {
+ contentBytes = StreamUtils.readStream(is);
+ bis = new ByteArrayInputStream(contentBytes);
+ }
+ catch (IOException e)
+ {
+ throw new MOAApplicationException("2210", null, e);
+ }
+ finally
+ {
+ closeInputStream(is);
+ }
+ if (!foundURI) {
+ context.PutResolvedEntity(uri, contentBytes, contentType);
+ }
+ dataObject = new ByteStreamDataObjectImpl(bis);
+ Logger.trace("<<< got binary input for \"" + uri + "\"");
+ }
+
+ dataObject.setMimeType(contentType);
+ dataObject.setURI(uri);
+
+ Logger.trace("<<< resolved uri \"" + uri + "\"");
+
+ return dataObject;
+ }
+
+ /**
+ * Savely closes the specified input stream.
+ *
+ * @param is The input stream to be closed.
+ */
+ private static void closeInputStream(InputStream is)
+ {
+ try
+ {
+ if (is != null) {
+ is.close();
+ }
+ }
+ catch (Throwable t)
+ {
+ // Intentionally do nothing here
+ }
+ }
+
+ /**
+ * 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java
new file mode 100644
index 0000000..933d058
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ExternalURIResolver.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.xml.crypto.utils.URI;
+import iaik.xml.crypto.utils.URIException;
+
+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 at.gv.egovernment.moa.spss.MOAApplicationException;
+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.ExternalURIVerifier;
+
+/**
+ * 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 });
+ }
+
+ // if we have local content (SOAP with attachments)
+ if ("formdata".equals(uri.getScheme())) {
+ TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();
+ if (context==null) {
+ //no transaction
+ throw new MOAApplicationException("2282", new Object[] { uri });
+ } else {
+ InputStream attachmentIs = context.getAttachmentInputStream(uri);
+ if (attachmentIs != null) {
+ setContentType(context.getAttachmentContentType(uri.getPath()));
+ return attachmentIs;
+ } else {
+ //maybe attachments provided but no suiting attachment found
+ throw new MOAApplicationException("2282", new Object[] { uri });
+ }
+ }
+ }
+
+ // convert URI to URL
+ try {
+ // create the URL
+ url = new URL(uriStr);
+ //System.out.println("ExternalURIResolver: " + url);
+ ExternalURIVerifier.verify(url.getHost(), url.getPort());
+
+ } 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;
+ // disallow redirects
+ httpConnection.setInstanceFollowRedirects(false);
+
+ 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java
new file mode 100644
index 0000000..1136ff2
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/IaikExceptionMapper.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.IAIKException;
+import iaik.server.modules.IAIKRuntimeException;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.Map;
+
+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.server.modules.IAIKException.class, "9900", MOASystemException.class },
+ { iaik.server.modules.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 },
+ { iaik.xml.crypto.tsl.ex.TSLEngineDiedException.class, "2290", MOAApplicationException.class },
+ { iaik.xml.crypto.tsl.ex.TSLSearchException.class, "2290", MOAApplicationException.class } ,
+ { iaik.server.modules.cmssign.CMSSignatureCreationException.class, "2300", 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>iaik.xml.crypto.tsl.ex.TSLSearchException</code> to a <code>MOAException</code>.
+ *
+ * @param tslSearchException The <code>iaik.xml.crypto.tsl.ex.TSLSearchException</code> to map.
+ * @return A <code>MOAException</code> containing the message for the
+ * given <code>IAIKException</code>.
+ */
+ public MOAException map(iaik.xml.crypto.tsl.ex.TSLSearchException tslSearchException) {
+ return mapImpl(tslSearchException);
+ }
+
+ /**
+ * Map an <code>iaik.xml.crypto.tsl.ex.TSLEngineDiedException</code> to a <code>MOAException</code>.
+ *
+ * @param tslEngineDiedException The <code>iaik.xml.crypto.tsl.ex.TSLEngineDiedException</code> to map.
+ * @return A <code>MOAException</code> containing the message for the
+ * given <code>IAIKException</code>.
+ */
+ public MOAException map(iaik.xml.crypto.tsl.ex.TSLEngineDiedException tslEngineDiedException) {
+ return mapImpl(tslEngineDiedException);
+ }
+
+ /**
+ * 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java
new file mode 100644
index 0000000..0bca8ae
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/InvokerUtils.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java
new file mode 100644
index 0000000..c6eaa4f
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ProfileMapper.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java
new file mode 100644
index 0000000..8f3c075
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/ServiceContextUtils.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java
new file mode 100644
index 0000000..b746333
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureCreationServiceImpl.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java
new file mode 100644
index 0000000..5b6033c
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/SignatureVerificationServiceImpl.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java
new file mode 100644
index 0000000..7842f14
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/TransformationFactory.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java
new file mode 100644
index 0000000..1ea10cb
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyCMSSignatureResponseBuilder.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.cmsverify.CMSSignatureVerificationResult;
+import iaik.server.modules.cmsverify.CertificateValidationResult;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+
+import at.gv.egovernment.moa.spss.MOAException;
+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;
+import at.gv.egovernment.moa.spss.server.config.TrustProfile;
+
+/**
+ * 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.
+ * @param trustprofile The actual trustprofile
+ * @param checkQCFromTSL <code>true</code>, if the TSL check verifies the
+ * certificate as qualified, otherwise <code>false</code>.
+ * @param checkSSCD <code>true</code>, if the TSL check verifies the
+ * signature based on a SSDC, otherwise <code>false</code>.
+ * @param sscdSourceTSL <code>true</code>, if the SSCD information comes from the TSL,
+ * otherwise <code>false</code>.
+ * @throws MOAException
+ */
+ public void addResult(CMSSignatureVerificationResult result, TrustProfile trustProfile, boolean checkQC, boolean qcSourceTSL, boolean checkSSCD, boolean sscdSourceTSL, String issuerCountryCode)
+ throws MOAException {
+
+ CertificateValidationResult certResult =
+ result.getCertificateValidationResult();
+ int signatureCheckCode =
+ result.getSignatureValueVerificationCode().intValue();
+ int certificateCheckCode = certResult.getValidationResultCode().intValue();
+
+ VerifyCMSSignatureResponseElement responseElement;
+ SignerInfo signerInfo;
+ CheckResult signatureCheck;
+ CheckResult certificateCheck;
+
+ boolean qualifiedCertificate = checkQC;
+
+ // add SignerInfo element
+ signerInfo =
+ factory.createSignerInfo(
+ (X509Certificate) certResult.getCertificateChain().get(0),
+ qualifiedCertificate,
+ qcSourceTSL,
+ certResult.isPublicAuthorityCertificate(),
+ certResult.getPublicAuthorityID(),
+ checkSSCD,
+ sscdSourceTSL,
+ issuerCountryCode);
+
+ // 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java
new file mode 100644
index 0000000..9021785
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/VerifyXMLSignatureResponseBuilder.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
+
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.NodeList;
+
+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.InputData;
+import at.gv.egovernment.moa.spss.api.common.SignerInfo;
+import at.gv.egovernment.moa.spss.api.impl.InputDataBinaryImpl;
+import at.gv.egovernment.moa.spss.api.impl.InputDataXMLImpl;
+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;
+import at.gv.egovernment.moa.util.CollectionUtils;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.NodeListAdapter;
+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 iaik.xml.crypto.alg.transform.C14NTransformService;
+import iaik.xml.crypto.dsig.CanonicalizationMethodImpl;
+
+/**
+ * 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.
+ * @param transformsSignatureManifestCheck The overall result for the signature
+ * manifest check.
+ * @param certificateCheck The overall result for the certificate check.
+ * @param checkQC <code>true</code>, if the certificate is QC, otherwise <code>false</code>.
+ * @param qcSourceTSL <code>true</code>, if the QC information comes from the TSL,
+ * otherwise <code>false</code>.
+ * @param checkSSCD <code>true</code>, if the signature is created by an SSCD, otherwise <code>false</code>.
+ * @param sscdSourceTSL <code>true</code>, if the SSCD information comes from the TSL,
+ * otherwise <code>false</code>.
+ * @throws MOAApplicationException An error occurred adding the result.
+ */
+ public void setResult(
+ XMLSignatureVerificationResult result,
+ XMLSignatureVerificationProfile profile,
+ ReferencesCheckResult transformsSignatureManifestCheck,
+ CheckResult certificateCheck,
+ boolean checkQC,
+ boolean qcSourceTSL,
+ boolean checkSSCD,
+ boolean sscdSourceTSL,
+ boolean isTSLEnabledTrustprofile,
+ String issuerCountryCode)
+ throws MOAApplicationException {
+
+ CertificateValidationResult certResult =
+ result.getCertificateValidationResult();
+ List referenceDataList;
+ ReferenceData referenceData;
+ List dsigManifestList;
+ ReferencesCheckResultInfo checkResultInfo;
+ int[] failedReferences;
+ Iterator iter;
+
+ boolean qualifiedCertificate = false;
+
+ qualifiedCertificate = checkQC;
+
+ // create the SignerInfo;
+ signerInfo =
+ factory.createSignerInfo(
+ (X509Certificate) certResult.getCertificateChain().get(0),
+ qualifiedCertificate,
+ qcSourceTSL,
+ certResult.isPublicAuthorityCertificate(),
+ certResult.getPublicAuthorityID(),
+ checkSSCD,
+ sscdSourceTSL,
+ issuerCountryCode);
+
+ // Create HashInputData Content objects
+ referenceDataList = result.getReferenceDataList();
+ if (profile.includeHashInputData()) {
+ hashInputDatas = new ArrayList();
+
+ // Include SignedInfo references
+ addHashInputDatas(
+ hashInputDatas,
+ referenceDataList,
+ InputData.CONTAINER_SIGNEDINFO_,
+ InputData.REFERER_NONE_);
+
+ // Include XMLDSIGManifest references
+ List xMLDSIGManifests = result.getDsigManifestList();
+ for (iter = xMLDSIGManifests.iterator(); iter.hasNext();)
+ {
+ DsigManifest currentMF = (DsigManifest) iter.next();
+ List xMLDSIGMFReferenceDataList = currentMF.getReferenceDataList();
+ addHashInputDatas(
+ hashInputDatas,
+ xMLDSIGMFReferenceDataList,
+ InputData.CONTAINER_XMLDSIGMANIFEST_,
+ currentMF.getReferringReferenceInfo().getReferenceIndex());
+ }
+ }
+
+ // Create the ReferenceInputData Content objects
+ if (profile.includeReferenceInputData()) {
+ referenceInputDatas = new ArrayList();
+
+ // Include SignedInfo references
+ addReferenceInputDatas(
+ referenceInputDatas,
+ referenceDataList,
+ InputData.CONTAINER_SIGNEDINFO_,
+ InputData.REFERER_NONE_);
+
+ // Include XMLDSIGManifest references
+ List xMLDSIGManifests = result.getDsigManifestList();
+ for (iter = xMLDSIGManifests.iterator(); iter.hasNext();)
+ {
+ DsigManifest currentMF = (DsigManifest) iter.next();
+ List xMLDSIGMFReferenceDataList = currentMF.getReferenceDataList();
+ addReferenceInputDatas(
+ referenceInputDatas,
+ xMLDSIGMFReferenceDataList,
+ InputData.CONTAINER_XMLDSIGMANIFEST_,
+ currentMF.getReferringReferenceInfo().getReferenceIndex());
+ }
+ }
+
+ // 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.isSecurityLayerManifestRequired())
+ {
+ if (!result.containsSecurityLayerManifest())
+ {
+ // required security layer manifest is missing in signature
+ signatureManifestCheck = factory.createReferencesCheckResult(2, null);
+ }
+ else
+ {
+ // security layer manifest exists, so we have to check its validity
+ SecurityLayerManifest slManifest = result.getSecurityLayerManifest();
+ int verificationResult = slManifest.getManifestVerificationResult().intValue();
+
+ if (SecurityLayerManifest.CODE_MANIFEST_VALID.intValue() == verificationResult)
+ {
+ // security layer manifest exists and is free of errors
+ signatureManifestCheck = factory.createReferencesCheckResult(0, null);
+ }
+ else
+ {
+ // security layer manifest exists, but has errors
+ failedReferences = buildFailedReferences(slManifest.getReferenceDataList());
+ checkResultInfo = (failedReferences != null)
+ ? factory.createReferencesCheckResultInfo(null, failedReferences)
+ : null;
+ if (SecurityLayerManifest.CODE_MANIFEST_INCOMPLETE.intValue() == verificationResult)
+ {
+ signatureManifestCheck = factory.createReferencesCheckResult(3, checkResultInfo);
+ }
+ else if (SecurityLayerManifest.CODE_REFERENCE_HASH_INVALID.intValue() == verificationResult)
+ {
+ signatureManifestCheck = factory.createReferencesCheckResult(4, checkResultInfo);
+ }
+ else
+ {
+ // Should not happen
+ throw new RuntimeException("Unexpected result from security layer manifest verification.");
+ }
+ }
+ }
+ }
+ else
+ {
+ // no security layer manifest is required, so the signature manifest check is ok
+ signatureManifestCheck = factory.createReferencesCheckResult(0, null);
+ }
+ }
+
+ // 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.getReferenceDataList());
+ manifestCheckResultInfo =
+ factory.createManifestRefsCheckResultInfo(
+ null,
+ failedReferences,
+ refIndex);
+ xmlDsigManifestChecks.add(
+ factory.createManifestRefsCheckResult(
+ dsigManifest.getManifestVerificationResult().intValue(),
+ manifestCheckResultInfo));
+ }
+ }
+
+ // create the certificate check
+ this.certificateCheck = certificateCheck;
+
+
+
+ }
+
+ /**
+ * Adds {@link InputData} entries to the specified <code>inputDatas</code> list. The content of the entry will
+ * be created from {@link ReferenceData#getHashInputData()}.
+ *
+ * @param inputDatas The list to be amended.
+ *
+ * @param referenceDataList The list of {@link ReferenceData} objects to be investigated.
+ *
+ * @param containerType The type of container of the {@link InputData} objects to be created.
+ *
+ * @param refererNumber The number of the referring reference for the {@link InputData} objects to be created.
+ *
+ * @throws MOAApplicationException if creating an {@link InputData} fails.
+ */
+ private void addHashInputDatas(List inputDatas, List referenceDataList, String containerType, int refererNumber)
+ throws MOAApplicationException
+ {
+ for (Iterator iter = referenceDataList.iterator(); iter.hasNext();)
+ {
+ ReferenceData referenceData = (ReferenceData) iter.next();
+ inputDatas.add(buildInputData(
+ referenceData.getHashInputData(),
+ containerType,
+ refererNumber));
+ }
+ }
+
+ /**
+ * Adds {@link InputData} entries to the specified <code>inputDatas</code> list. The content of the entry will
+ * be created from {@link ReferenceData#getReferenceInputData()}.
+ *
+ * @param inputDatas The list to be amended.
+ *
+ * @param referenceDataList The list of {@link ReferenceData} objects to be investigated.
+ *
+ * @param containerType The type of container of the {@link InputData} objects to be created.
+ *
+ * @param refererNumber The number of the referring reference for the {@link InputData} objects to be created.
+ *
+ * @throws MOAApplicationException if creating an {@link InputData} fails.
+ */
+ private void addReferenceInputDatas(List inputDatas, List referenceDataList, String containerType, int refererNumber)
+ throws MOAApplicationException
+ {
+ for (Iterator iter = referenceDataList.iterator(); iter.hasNext();)
+ {
+ ReferenceData referenceData = (ReferenceData) iter.next();
+ inputDatas.add(buildInputData(
+ referenceData.getReferenceInputData(),
+ containerType,
+ refererNumber));
+ }
+ }
+
+ /**
+ * Build a <code>InputDataBinaryImpl</code> or an <code>InputDataXMLImpl</code>
+ * object from the given <code>DataObject</code> and the given attributes.
+ *
+ * @param dataObject The <code>DataObject</code> from which to build the result.
+ * Based on the type of this parameter, the type of the result will either be
+ * <code>InputDataBinaryImpl</code> or <code>InputDataXMLImpl</code>.
+ *
+ * @param partof see {@link InputData}
+ *
+ * @param referringReferenceNumber see {@link InputData}
+ *
+ * @return The corresponinding input data implementation.
+ *
+ * @throws MOAApplicationException An error occurred creating the result.
+ */
+ private Content buildInputData(DataObject dataObject, String partOf, int referringReferenceNumber)
+ throws MOAApplicationException {
+
+ if (dataObject instanceof BinaryDataObject) {
+ BinaryDataObject binaryData = (BinaryDataObject) dataObject;
+ return new InputDataBinaryImpl(
+ factory.createContent(binaryData.getInputStream(), null),
+ partOf,
+ referringReferenceNumber);
+ } else if (dataObject instanceof XMLDataObject) {
+ XMLDataObject xmlData = (XMLDataObject) dataObject;
+ List nodes = new ArrayList();
+
+ nodes.add(xmlData.getElement());
+ return new InputDataXMLImpl(
+ factory.createContent(new NodeListAdapter(nodes), null),
+ partOf,
+ referringReferenceNumber);
+ } 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 new InputDataXMLImpl(
+ factory.createContent(fragment.getChildNodes(), null),
+ partOf,
+ referringReferenceNumber);
+ } catch (Exception e) {
+ // not successful -> fall through to the Base64Content
+ }
+ }
+
+ // insert canonicalized NodeList as binary content
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ for(int i = 0; i < nodes.getLength(); i++) {
+ baos.write(DOMUtils.nodeToByteArray(nodes.item(i)));
+ }
+ baos.close();
+ ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+ OctetStreamData inputData = new OctetStreamData(bais);
+
+ CanonicalizationMethodImpl canonicalizationMethodImpl = new CanonicalizationMethodImpl(
+ CanonicalizationMethod.EXCLUSIVE_WITH_COMMENTS, new ExcC14NParameterSpec());
+ OctetStreamData data = (OctetStreamData)canonicalizationMethodImpl.transform(inputData, null);
+ bais.close();
+ //CanonicalizationAlgorithm c14n =
+ //new CanonicalizationAlgorithmImplExclusiveCanonicalXMLWithComments();
+ InputStream is = data.getOctetStream();
+
+ //c14n.setInput(nodes);
+ //is = c14n.canonicalize();
+ return new InputDataBinaryImpl(
+ factory.createContent(is, null),
+ partOf,
+ referringReferenceNumber);
+ } 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java
new file mode 100644
index 0000000..7debb7b
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationInvoker.java
@@ -0,0 +1,586 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.server.modules.IAIKException;
+import iaik.server.modules.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 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.Set;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+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.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.common.MetaInfo;
+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.CreateTransformsInfoProfileExplicit;
+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.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;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+/**
+ * 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();
+ reserved = new HashSet(reserved);
+ XMLSignatureCreationProfileFactory profileFactory =
+ new XMLSignatureCreationProfileFactory(request, reserved);
+ 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 {
+
+ // build the signature environment
+ createSignatureInfo = singleSignatureInfo.getCreateSignatureInfo();
+ if (createSignatureInfo != null) {
+ DataObjectFactory dataObjFactory = DataObjectFactory.getInstance();
+
+ signatureEnvironment =
+ dataObjFactory.createSignatureEnvironment(
+ createSignatureInfo.getCreateSignatureEnvironment(),
+ getCreateSignatureEnvironmentProfileSupplements(singleSignatureInfo));
+ } else {
+ signatureEnvironment = null;
+ }
+
+ HashSet sigInfoReservedIDs = new HashSet();
+ if (signatureEnvironment != null)
+ {
+ // Find Id attributes of existing XML signatures in signature environment
+ HashMap nSMap = new HashMap();
+ String dsp = Constants.DSIG_PREFIX;
+ nSMap.put(dsp, Constants.DSIG_NS_URI);
+ String xPathExpr = "//" + dsp + ":Signature/@Id | //" + dsp + ":Reference/@Id | //"
+ + dsp + ":Object/@Id | //" + dsp + ":Manifest/@Id";
+ NodeList idAttrs = XPathUtils.selectNodeList(signatureEnvironment.getElement(), nSMap, xPathExpr);
+
+ // Add found Id attributes to set of reserved IDs
+ for (int i = 0; i < idAttrs.getLength(); i++) sigInfoReservedIDs.add(idAttrs.item(i).getNodeValue());
+ }
+
+ // create the reference id generator
+ HashSet allReservedIDs = new HashSet(reserved);
+ allReservedIDs.addAll(sigInfoReservedIDs);
+ refIdGen = new IdGenerator("reference-" + createCount++, allReservedIDs);
+
+ // build the list of DataObjects
+ List createTransformsProfiles = profileFactory.getCreateTransformsInfoProfiles(singleSignatureInfo);
+ dataObjectList =
+ buildDataObjectList(
+ singleSignatureInfo,
+ createTransformsProfiles,
+ signatureEnvironment,
+ refIdGen);
+
+ // build the XMLSignatureCreationProfile
+ profile = profileFactory.createProfile(singleSignatureInfo, sigInfoReservedIDs);
+
+ // 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 {
+ ConfigurationProvider config = context.getConfiguration();
+ String xadesVersion = config.getXAdESVersion();
+
+ if (xadesVersion!= null && xadesVersion.compareTo(XMLSignatureCreationModule.XADES_VERSION_1_4_2) == 0) {
+ // create the signature (XAdES 1.4.2)
+ signature =
+ module.createSignature(
+ dataObjectList,
+ profile,
+ additionalSignedProperties,
+ signatureParent,
+ XMLSignatureCreationModule.XADES_VERSION_1_4_2,
+ new TransactionId(context.getTransactionID()));
+ }
+ else {
+ // create the signature (XAdES 1.1.1 = default)
+ signature =
+ module.createSignature(
+ dataObjectList,
+ profile,
+ additionalSignedProperties,
+ signatureParent,
+ XMLSignatureCreationModule.XADES_VERSION_1_1_1,
+ new TransactionId(context.getTransactionID()));
+ }
+
+ // insert the result into the response
+ if (signatureParent != null) {
+ responseBuilder.addSignatureEnvironment(
+ signatureEnvironment.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 createTransformsProfiles A list of objects of type {@link CreateTransformsInfoProfileExplicit},
+ * each representing the transforms info profile information for the corresponding <code>DataObject</code>.
+ * @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,
+ List createTransformsProfiles,
+ XMLDataObject signatureEnvironment,
+ IdGenerator idGen)
+ throws MOASystemException, MOAApplicationException {
+
+ List dataObjInfos = singleSignatureInfo.getDataObjectInfos();
+ List dataObjects = new ArrayList();
+ Iterator dtIter;
+ Iterator ctpIter = createTransformsProfiles.iterator();
+
+ for (dtIter = dataObjInfos.iterator(); dtIter.hasNext();)
+ {
+ DataObjectInfo dataObjInfo = (DataObjectInfo) dtIter.next();
+ String structure = dataObjInfo.getStructure();
+
+ CreateTransformsInfoProfileExplicit transformsProfile =
+ (CreateTransformsInfoProfileExplicit) ctpIter.next();
+ MetaInfo finalDataMetaInfo = transformsProfile.getCreateTransformsInfo().getFinalDataMetaInfo();
+
+ if (DataObjectInfo.STRUCTURE_ENVELOPING.equals(structure)) {
+ dataObjects.add(
+ buildEnvelopingDataObject(
+ dataObjInfo.getDataObject(),
+ finalDataMetaInfo,
+ idGen.uniqueId()));
+ } else if (DataObjectInfo.STRUCTURE_DETACHED.equals(structure)) {
+ dataObjects.add(
+ buildDetachedDataObject(
+ dataObjInfo.getDataObject(),
+ finalDataMetaInfo,
+ signatureEnvironment,
+ idGen.uniqueId()));
+ } 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 finalDataMetaInfo The meta information corresponding with <code>content</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,
+ MetaInfo finalDataMetaInfo,
+ String referenceID)
+ throws MOASystemException, MOAApplicationException {
+
+ DataObjectFactory factory = DataObjectFactory.getInstance();
+ DataObject dataObject;
+
+ dataObject =
+ factory.createFromContentOptionalRefType(
+ content,
+ finalDataMetaInfo,
+ 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 finalDataMetaInfo The meta information corresponding with <code>content</code>.
+ * @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,
+ MetaInfo finalDataMetaInfo,
+ 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,
+ finalDataMetaInfo,
+ 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;
+
+ return additionalSignedProperties;
+ }
+
+} \ No newline at end of file
diff --git a/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
new file mode 100644
index 0000000..6a85415
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureCreationProfileFactory.java
@@ -0,0 +1,543 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+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 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 at.gv.egovernment.moa.logging.LogMsg;
+import at.gv.egovernment.moa.logging.Logger;
+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.KeyGroup;
+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;
+import at.gv.egovernment.moa.util.Constants;
+
+/**
+ * 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);
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA256_URI, HashAlgorithms.SHA256);
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA384_URI, HashAlgorithms.SHA384);
+ HASH_ALGORITHM_MAPPING.put(Constants.SHA512_URI, HashAlgorithms.SHA512);
+ }
+
+ /** 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.
+ * @param sigInfoReservedIDs The <code>Set</code> of reserved ID attribue values
+ * for the particular <code>singleSignatureInfo</code>.
+ * @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,
+ Set sigInfoReservedIDs) throws MOASystemException, MOAApplicationException {
+
+ HashSet allReservedIDs = new HashSet(reserved);
+ allReservedIDs.addAll(sigInfoReservedIDs);
+
+ TransactionContext context =
+ TransactionContextManager.getInstance().getTransactionContext();
+ ConfigurationProvider config = context.getConfiguration();
+ CanonicalizationImpl canonicalization;
+ List dataObjectTreatmentList;
+ Set keySet;
+ List transformationSupplements;
+ List createTransformsProfiles;
+
+ // get the key group id
+ String keyGroupID = request.getKeyIdentifier();
+ // get digest method on key group level (if configured)
+ KeyGroup keygroup = config.getKeyGroup(keyGroupID);
+ if(null == keygroup) {
+ Logger.error("Could not find key group '" + keyGroupID + "'");
+ throw new MOAApplicationException("2231", null);
+ }
+ String configDigestMethodKG = keygroup.getDigestMethodAlgorithm();
+ // get default digest method (if configured)
+ String configDigestMethod = config.getDigestMethodAlgorithmName();
+
+ String xadesVersion = config.getXAdESVersion();
+
+ String digestMethodXAdES142 = null;
+ boolean isXAdES142 = false;
+ // if XAdES Version 1.4.2 is configured
+ if (xadesVersion != null && xadesVersion.compareTo("1.4.2") == 0) {
+ isXAdES142 = true;
+ Logger.debug("XAdES version '" + xadesVersion + "' used");
+ }
+
+ if (isXAdES142) {
+ if (configDigestMethodKG != null) {
+ // if KG specific digest method is configured
+ digestMethodXAdES142 = (String) HASH_ALGORITHM_MAPPING.get(configDigestMethodKG);
+ if (digestMethodXAdES142 == null) {
+ error(
+ "config.17",
+ new Object[] { configDigestMethodKG});
+ throw new MOASystemException("2900", null);
+ }
+ Logger.debug("Digest algorithm: " + digestMethodXAdES142 + "(configured in KeyGroup)");
+ }
+ else {
+ // else get default configured digest method
+ digestMethodXAdES142 = (String) HASH_ALGORITHM_MAPPING.get(configDigestMethod);
+ if (digestMethodXAdES142 == null) {
+ error(
+ "config.17",
+ new Object[] { configDigestMethod});
+ throw new MOASystemException("2900", null);
+ }
+ Logger.debug("Digest algorithm: " + digestMethodXAdES142 + "(default)");
+
+ }
+ }
+
+ XMLSignatureCreationProfileImpl profile =
+ new XMLSignatureCreationProfileImpl(createProfileCount, allReservedIDs, digestMethodXAdES142);
+
+
+ // build the transformation supplements
+ createTransformsProfiles =
+ getCreateTransformsInfoProfiles(singleSignatureInfo);
+ transformationSupplements =
+ buildTransformationSupplements(createTransformsProfiles);
+
+ // build and set the data object treatment list
+ dataObjectTreatmentList =
+ buildDataObjectTreatmentList(
+ singleSignatureInfo,
+ createTransformsProfiles,
+ transformationSupplements,
+ allReservedIDs,
+ digestMethodXAdES142);
+ profile.setDataObjectTreatmentList(dataObjectTreatmentList);
+
+ // set the key set
+ 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.
+ */
+ 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.
+ * @param reservedIDs The <code>Set</code> of reserved object IDs.
+ * @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,
+ Set reservedIDs,
+ String digestMethodXAdES142)
+ 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++),
+ reservedIDs);
+ DataObjectTreatmentImpl treatment = new DataObjectTreatmentImpl(objIdGen);
+
+ treatment.setFinalContentType(
+ profile.getCreateTransformsInfo().getFinalDataMetaInfo().getMimeType());
+ treatment.setTransformationList(buildTransformationList(profile));
+ treatment.setReferenceInManifest(dataObjInfo.isChildOfManifest());
+
+ // if XAdES version is 1.4.2
+ if (digestMethodXAdES142 != null) {
+ // use configured digest algorithm
+ hashAlgorithmName = digestMethodXAdES142;
+ }
+ else {
+ // stay as it is
+ 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
new file mode 100644
index 0000000..2b158dd
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationInvoker.java
@@ -0,0 +1,727 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.invoke;
+
+import iaik.xml.crypto.utils.URI;
+import iaik.xml.crypto.utils.URIException;
+import iaik.server.modules.IAIKException;
+import iaik.server.modules.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 iaik.x509.X509Certificate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+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 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.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.CheckResult;
+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.config.TrustProfile;
+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.CertificateUtils;
+import at.gv.egovernment.moa.spss.util.MessageProvider;
+import at.gv.egovernment.moa.spss.util.QCSSCDResult;
+import at.gv.egovernment.moa.util.CollectionUtils;
+import at.gv.egovernment.moa.util.Constants;
+
+/**
+ * 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");
+ FILTERED_REF_TYPES.add("http://uri.etsi.org/01903#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);
+ }
+
+ QCSSCDResult qcsscdresult = new QCSSCDResult();
+ String tpID = profile.getCertificateValidationProfile().getTrustStoreProfile().getId();
+ ConfigurationProvider config = ConfigurationProvider.getInstance();
+ TrustProfile tp = config.getTrustProfile(tpID);
+
+ // 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;
+ }
+
+
+ // QC/SSCD check
+ List list = result.getCertificateValidationResult().getCertificateChain();
+ if (list != null) {
+ X509Certificate[] chain = new X509Certificate[list.size()];
+
+ Iterator it = list.iterator();
+ int i = 0;
+ while(it.hasNext()) {
+ chain[i] = (X509Certificate)it.next();
+ i++;
+ }
+
+ qcsscdresult = CertificateUtils.checkQCSSCD(chain, tp.isTSLEnabled());
+ }
+
+
+ // get signer certificate issuer country code
+ String issuerCountryCode = CertificateUtils.getIssuerCountry((X509Certificate)list.get(0));
+
+ // 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);
+
+ // Check if signer certificate is in trust profile's allowed signer certificates pool
+ TrustProfile trustProfile = context.getConfiguration().getTrustProfile(request.getTrustProfileId());
+ CheckResult certificateCheck = validateSignerCertificate(result, trustProfile);
+
+
+ // build the response
+ responseBuilder.setResult(result, profile, signatureManifestCheck, certificateCheck, qcsscdresult.isQC(), qcsscdresult.isQCSourceTSL(), qcsscdresult.isSSCD(), qcsscdresult.isSSCDSourceTSL(), tp.isTSLEnabled(), issuerCountryCode);
+ return responseBuilder.getResponse();
+ }
+
+ /**
+ * Checks if the signer certificate matches one of the allowed signer certificates specified
+ * in the provided <code>trustProfile</code>.
+ *
+ * @param result The result produced by the <code>XMLSignatureVerificationModule</code>.
+ *
+ * @param trustProfile The trust profile the signer certificate is validated against.
+ *
+ * @return The overal result of the certificate validation for the signer certificate.
+ *
+ * @throws MOAException if one of the signer certificates specified in the <code>trustProfile</code>
+ * cannot be read from the file system.
+ */
+ private CheckResult validateSignerCertificate(XMLSignatureVerificationResult result, TrustProfile trustProfile)
+ throws MOAException
+ {
+ MessageProvider msg = MessageProvider.getInstance();
+
+ int resultCode = result.getCertificateValidationResult().getValidationResultCode().intValue();
+ if (resultCode == 0 && trustProfile.getSignerCertsUri() != null)
+ {
+ X509Certificate signerCertificate = (X509Certificate) result.getCertificateValidationResult().getCertificateChain().get(0);
+
+ File signerCertsDir = null;
+ try
+ {
+ signerCertsDir = new File(new URI(trustProfile.getSignerCertsUri()).getPath());
+ }
+ catch (URIException e)
+ {
+ throw new MOASystemException("2900", null, e); // Should not happen, already checked at loading the MOA configuration
+ }
+
+ File[] files = signerCertsDir.listFiles();
+ if (files == null) resultCode = 1;
+ int i;
+ for (i = 0; i < files.length; i++)
+ {
+ if (!files[i].isDirectory())
+ {
+ FileInputStream currentFIS = null;
+ try
+ {
+ currentFIS = new FileInputStream(files[i]);
+ }
+ catch (FileNotFoundException e) {
+ throw new MOASystemException("2900", null, e);
+ }
+
+ try
+ {
+ X509Certificate currentCert = new X509Certificate(currentFIS);
+ currentFIS.close();
+ if (currentCert.equals(signerCertificate)) break;
+ }
+ catch (Exception e)
+ {
+ // Simply ignore file if it cannot be interpreted as certificate
+ String logMsg = msg.getMessage("invoker.03", new Object[]{trustProfile.getId(), files[i].getName()});
+ Logger.warn(logMsg);
+ try
+ {
+ currentFIS.close();
+ }
+ catch (IOException e1) {
+ // If clean-up fails, do nothing
+ }
+ }
+ }
+ }
+ if (i >= files.length)
+ {
+ resultCode = 1; // No signer certificate from the trustprofile pool matches the actual signer certificate
+ }
+ }
+
+ SPSSFactory factory = SPSSFactory.getInstance();
+ return factory.createCheckResult(resultCode, null);
+ }
+
+
+
+ /**
+ * 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;
+
+ if (supplements != null) {
+ 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();
+
+ List supplements = new ArrayList();
+
+ if (supplementProfiles != null) {
+
+ 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;
+ }
+
+ /**
+ * 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 (request.getSignatureManifestCheckParams() != null) {
+ 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 (request.getSignatureManifestCheckParams() != null
+ && result.containsSecurityLayerManifest()) {
+ Map hashValues = buildTransformParameterHashValues(request);
+ Set transformParameterURIs =
+ buildTransformParameterURIs(profile.getTransformationSupplements());
+ List referenceInfoList =
+ result.getSecurityLayerManifest().getReferenceDataList();
+ 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/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java
new file mode 100644
index 0000000..3e4c712
--- /dev/null
+++ b/moaSig/moa-sig-lib/src/main/java/at/gv/egovernment/moa/spss/server/invoke/XMLSignatureVerificationProfileFactory.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2003 Federal Chancellery Austria
+ * MOA-SPSS has been developed in a cooperation between BRZ, the Federal
+ * Chancellery Austria - ICT staff unit, and Graz University of Technology.
+ *
+ * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by
+ * the European Commission - subsequent versions of the EUPL (the "Licence");
+ * You may not use this work except in compliance with the Licence.
+ * You may obtain a copy of the Licence at:
+ * http://www.osor.eu/eupl/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the Licence is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Licence for the specific language governing permissions and
+ * limitations under the Licence.
+ *
+ * This product combines work with different licenses. See the "NOTICE" text
+ * file for details on the various modules and licenses.
+ * The "NOTICE" text file is part of the distribution. Any derivative works
+ * that you distribute must include a readable copy of the "NOTICE" text file.
+ */
+
+
+package at.gv.egovernment.moa.spss.server.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
+ // and transformation supplements (if present)
+ checkParams = request.getSignatureManifestCheckParams();
+ profile.setCheckSecurityLayerManifest(true);
+ profile.setIncludeReferenceInputData(checkParams != null ? checkParams.getReturnReferenceInputData() : false);
+ if (checkParams != null) {
+ List transformationSupplements;
+ transformationSupplements = buildTransformationSupplements();
+ profile.setTransformationSupplements(transformationSupplements);
+ } else {
+ profile.setTransformationSupplements(Collections.EMPTY_LIST);
+ }
+
+ profile.setPermitFileURIs(config.getPermitFileURIs());
+
+ 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;
+ }
+
+}