aboutsummaryrefslogtreecommitdiff
path: root/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind
diff options
context:
space:
mode:
Diffstat (limited to 'spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind')
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java288
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java119
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java285
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java147
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java213
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java251
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java169
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java101
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java275
-rw-r--r--spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java300
10 files changed, 2148 insertions, 0 deletions
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java
new file mode 100644
index 000000000..319d3ac9d
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureRequestParser.java
@@ -0,0 +1,288 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egovernment.moa.util.BoolUtils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureEnvironmentProfile;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile;
+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;
+
+/**
+ * A parser to parse <code>CreateXMLSignatureRequest</code> DOM trees into
+ * <code>CreateXMLSignatureRequest</code> API objects.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CreateXMLSignatureRequestParser {
+
+ //
+ // XPath expresssions to select elements in the CreateXMLSignatureRequest
+ //
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ private static final String KEY_IDENTIFIER_XPATH =
+ "/" + MOA + "CreateXMLSignatureRequest/" + MOA + "KeyIdentifier";
+ private static final String SINGLE_SIGNATURE_INFO_XPATH =
+ "/" + MOA + "CreateXMLSignatureRequest/" + MOA + "SingleSignatureInfo";
+ private static final String DATA_OBJECT_INFO_XPATH = MOA + "DataObjectInfo";
+ private static final String DATA_OBJECT_XPATH = MOA + "DataObject";
+ private static final String CREATE_SIGNATURE_INFO_XPATH =
+ MOA + "CreateSignatureInfo";
+ private static final String CREATE_TRANSFORMS_INFO_PROFILE_XPATH =
+ (MOA + "CreateTransformsInfoProfile | ")
+ + (MOA + "CreateTransformsInfoProfileID");
+ private static final String CREATE_SIGNATURE_ENVIRONMENT_XPATH =
+ MOA + "CreateSignatureEnvironment";
+ private static final String CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH =
+ (MOA + "CreateSignatureEnvironmentProfile | ")
+ + (MOA + "CreateSignatureEnvironmentProfileID");
+ private static final String SL_CONFORM_ATTR_NAME = "SecurityLayerConformity";
+
+ /** The factory to create API objects. */
+ private SPSSFactory factory;
+
+ /**
+ * Create a new <code>CreateXMLSignatureRequestParser</code>.
+ */
+ public CreateXMLSignatureRequestParser() {
+ this.factory = SPSSFactory.getInstance();
+ }
+
+ /**
+ * Parse a <code>CreateXMLSignatureRequest</code> DOM element, as defined
+ * by the MOA schema.
+ *
+ * @param requestElem The <code>CreateXMLSignatureRequest</code> to parse. The
+ * request must have been successfully parsed against the schema for this
+ * method to succeed.
+ * @return A <code>CreateXMLSignatureRequest</code> API object containing
+ * the data from the DOM element.
+ * @throws MOAApplicationException An error occurred parsing the request.
+ */
+ public CreateXMLSignatureRequest parse(Element requestElem)
+ throws MOAApplicationException {
+
+ List singleSignatureInfos = parseSingleSignatureInfos(requestElem);
+ String keyIdentifier =
+ XPathUtils.getElementValue(requestElem, KEY_IDENTIFIER_XPATH, null);
+
+ return factory.createCreateXMLSignatureRequest(
+ keyIdentifier,
+ singleSignatureInfos);
+ }
+
+ /**
+ * Parse all <code>SingleSignatureInfo</code> elements of the
+ * <code>CreateXMLSignatureRequest</code>.
+ *
+ * @param requestElem The <code>CreateXMLSignatureRequest</code> to parse.
+ * @return A <code>List</code> of <code>SingleSignatureInfo</code> API
+ * objects.
+ * @throws MOAApplicationException An error occurred parsing on of the
+ * <code>SingleSignatureInfo</code> elements.
+ */
+ private List parseSingleSignatureInfos(Element requestElem)
+ throws MOAApplicationException {
+
+ List singleSignatureInfos = new ArrayList();
+ NodeIterator sigInfoElems =
+ XPathUtils.selectNodeIterator(requestElem, SINGLE_SIGNATURE_INFO_XPATH);
+ Element sigInfoElem;
+
+ while ((sigInfoElem = (Element) sigInfoElems.nextNode()) != null) {
+ singleSignatureInfos.add(parseSingleSignatureInfo(sigInfoElem));
+ }
+
+ return singleSignatureInfos;
+ }
+
+ /**
+ * Parse a <code>SingleSignatureInfo</code> DOM element.
+ *
+ * @param sigInfoElem The <code>SingleSignatureInfo</code> DOM element to
+ * parse.
+ * @return A <code>SingleSignatureInfo</code> API object containing the
+ * information of <code>sigInfoElem</code>.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>SingleSignatureInfo</code>.
+ */
+ private SingleSignatureInfo parseSingleSignatureInfo(Element sigInfoElem)
+ throws MOAApplicationException {
+
+ List dataObjectInfos = parseDataObjectInfos(sigInfoElem);
+ CreateSignatureInfo createSignatureInfo =
+ parseCreateSignatureInfo(sigInfoElem);
+ boolean securityLayerConform;
+
+ if (sigInfoElem.hasAttribute(SL_CONFORM_ATTR_NAME)) {
+ securityLayerConform =
+ BoolUtils.valueOf(sigInfoElem.getAttribute(SL_CONFORM_ATTR_NAME));
+ } else {
+ securityLayerConform = true;
+ }
+
+ return factory.createSingleSignatureInfo(
+ dataObjectInfos,
+ createSignatureInfo,
+ securityLayerConform);
+ }
+
+ /**
+ * Parse the <code>DataObjectInfo</code> DOM elements contained in the given
+ * <code>SingleSignatureInfo</code> DOM element.
+ *
+ * @param sigInfoElem The <code>SingleSignatureInfo</code> DOM element
+ * whose <code>DataObjectInfo</code>s to parse.
+ * @return A <code>List</code> of <code>DataObjectInfo</code> API objects
+ * containing the data from the <code>DataObjectInfo</code> DOM elements.
+ * @throws MOAApplicationException An error occurred parsing one of the
+ * <code>DataObjectInfo</code>s.
+ */
+ private List parseDataObjectInfos(Element sigInfoElem)
+ throws MOAApplicationException {
+
+ List dataObjectInfos = new ArrayList();
+ NodeIterator dataObjInfoElems =
+ XPathUtils.selectNodeIterator(sigInfoElem, DATA_OBJECT_INFO_XPATH);
+ Element dataObjInfoElem;
+
+ while ((dataObjInfoElem = (Element) dataObjInfoElems.nextNode()) != null) {
+ dataObjectInfos.add(parseDataObjectInfo(dataObjInfoElem));
+ }
+ return dataObjectInfos;
+ }
+
+ /**
+ * Parse a <code>DataObjectInfo</code> DOM element.
+ *
+ * @param dataObjInfoElem The <code>DataObjectInfo</code> DOM element to
+ * parse.
+ * @return A <code>DataObjectInfo</code> API element containing the data
+ * from <code>dataObjInfoElem</code>.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>DataObjectInfo</code>.
+ */
+ private DataObjectInfo parseDataObjectInfo(Element dataObjInfoElem)
+ throws MOAApplicationException {
+
+ String structure = dataObjInfoElem.getAttribute("Structure");
+ Element dataObjectElem =
+ (Element) XPathUtils.selectSingleNode(dataObjInfoElem, DATA_OBJECT_XPATH);
+ Content dataObject = RequestParserUtils.parseContent(dataObjectElem);
+ CreateTransformsInfoProfile createTransformsInfoProfile =
+ parseCreateTransformsInfoProfile(dataObjInfoElem);
+ boolean childOfManifest;
+
+ if (dataObjInfoElem.hasAttribute("ChildOfManifest")) {
+ childOfManifest =
+ BoolUtils.valueOf(dataObjInfoElem.getAttribute("ChildOfManifest"));
+ } else {
+ childOfManifest = false;
+ }
+
+ return factory.createDataObjectInfo(
+ structure,
+ childOfManifest,
+ dataObject,
+ createTransformsInfoProfile);
+ }
+
+ /**
+ * Parse a <code>CreateTransformsInfoProfile</code> DOM element.
+ *
+ * @param dataObjInfoElem The <code>DataObjectInfo</code> DOM element
+ * containing the <code>CreateTransformsInfoProfile</code>.
+ * @return The <code>CreateTransformsInfoProfile</code> API object containing
+ * the profile found in <code>dataObjInfoElem</code>.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>CreateTransformsInfoProfile</code>.
+ */
+ private CreateTransformsInfoProfile parseCreateTransformsInfoProfile(Element dataObjInfoElem)
+ throws MOAApplicationException {
+
+ Element profileElem =
+ (Element) XPathUtils.selectSingleNode(
+ dataObjInfoElem,
+ CREATE_TRANSFORMS_INFO_PROFILE_XPATH);
+
+ if ("CreateTransformsInfoProfile".equals(profileElem.getLocalName())) {
+ ProfileParser profileParser = new ProfileParser();
+ return profileParser.parseCreateTransformsInfoProfile(profileElem);
+
+ } else {
+ String profileID = DOMUtils.getText(profileElem);
+ return factory.createCreateTransformsInfoProfile(profileID);
+ }
+ }
+
+ /**
+ * Parse the <code>CreateSignatureInfo</code> DOM element contained in
+ * a <code>SingleSignatureInfo</code>.
+ *
+ * @param sigInfoElem The <code>SingleSignatureInfo</code> DOM element
+ * containing the <code>CreateSignatureInfo</code> to be parsed.
+ * @return A <code>CreateSignatureInfo</code> API object containing the
+ * data from the <code>CreateSignatureInfo</code> DOM element, or
+ * <code>null</code>, if none was found.
+ */
+ private CreateSignatureInfo parseCreateSignatureInfo(Element sigInfoElem) {
+ Element createInfoElem =
+ (Element) XPathUtils.selectSingleNode(
+ sigInfoElem,
+ CREATE_SIGNATURE_INFO_XPATH);
+
+ if (createInfoElem != null) {
+ Element environmentElem =
+ (Element) XPathUtils.selectSingleNode(
+ createInfoElem,
+ CREATE_SIGNATURE_ENVIRONMENT_XPATH);
+ Content environment = RequestParserUtils.parseContent(environmentElem);
+ CreateSignatureEnvironmentProfile environmentProfile =
+ parseCreateSignatureEnvironmentProfile(createInfoElem);
+
+ return factory.createCreateSignatureInfo(environment, environmentProfile);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Parse the <code>CreateSignatureEnvironmentProfile</code> contained in
+ * the given <code>CreateSignatureInfo</code> DOM element.
+ *
+ * @param createInfoElem <code>CreateSignatureInfo</code> DOM element to
+ * parse.
+ * @return The <code>CreateSignatureEnvironmentProfile</code> contained
+ * in the given <code>CreateSignatureInfo</code> DOM element..
+ */
+ private CreateSignatureEnvironmentProfile parseCreateSignatureEnvironmentProfile(Element createInfoElem) {
+ Element profileElem =
+ (Element) XPathUtils.selectSingleNode(
+ createInfoElem,
+ CREATE_SIGNATURE_ENVIRONMENT_PROFILE_XPATH);
+
+ if ("CreateSignatureEnvironmentProfile"
+ .equals(profileElem.getLocalName())) {
+ ProfileParser profileParser = new ProfileParser();
+ return profileParser.parseCreateSignatureEnvironmentProfile(profileElem);
+ } else {
+ String profileID = DOMUtils.getText(profileElem);
+ return factory.createCreateSignatureEnvironmentProfile(profileID);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java
new file mode 100644
index 000000000..eec9c4882
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/CreateXMLSignatureResponseBuilder.java
@@ -0,0 +1,119 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.util.Iterator;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import at.gv.egovernment.moa.util.Constants;
+
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponse;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateXMLSignatureResponseElement;
+import at.gv.egovernment.moa.spss.api.xmlsign.ErrorResponse;
+import at.gv.egovernment.moa.spss.api.xmlsign.SignatureEnvironmentResponse;
+
+/**
+ * Convert a <code>CreateXMLSignatureResponse</code> API object into its
+ * XML representation, according to the MOA XML schema.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class CreateXMLSignatureResponseBuilder {
+ private static final String MOA_NS_URI = Constants.MOA_NS_URI;
+
+ /** The XML document containing the response element. */
+ private Document responseDoc;
+ /** The response <code>CreateXMLSignatureResponse</code> DOM element. */
+ private Element responseElem;
+
+ /**
+ * Create a new <code>CreateXMLSignatureResponseBuilder</code>:
+ *
+ * @throws MOASystemException An error occurred setting up the resulting
+ * XML document.
+ */
+ public CreateXMLSignatureResponseBuilder() throws MOASystemException {
+ responseDoc =
+ ResponseBuilderUtils.createResponse("CreateXMLSignatureResponse");
+ responseElem = responseDoc.getDocumentElement();
+ }
+
+ /**
+ * Build a document containing a <code>CreateXMLSignatureResponse</code>
+ * DOM element being the XML representation of the given
+ * <code>CreateXMLSignatureResponse</code> API object.
+ *
+ * @param response The <code>CreateXMLSignatureResponse</code> to convert
+ * to XML.
+ * @return A document containing the <code>CreateXMLSignatureResponse</code>
+ * DOM element.
+ */
+ public Document build(CreateXMLSignatureResponse response) {
+ Iterator iter;
+
+ for (iter = response.getResponseElements().iterator(); iter.hasNext();) {
+ CreateXMLSignatureResponseElement responseElement =
+ (CreateXMLSignatureResponseElement) iter.next();
+
+ switch (responseElement.getResponseType()) {
+ case CreateXMLSignatureResponseElement.SIGNATURE_ENVIRONMENT_RESPONSE :
+ SignatureEnvironmentResponse envResponse =
+ (SignatureEnvironmentResponse) responseElement;
+ addSignatureEnvironment(envResponse);
+ break;
+
+ case CreateXMLSignatureResponseElement.ERROR_RESPONSE :
+ ErrorResponse errorResponse = (ErrorResponse) responseElement;
+ addErrorResponse(errorResponse);
+ break;
+ }
+
+ }
+
+ return responseDoc;
+ }
+
+ /**
+ * Add a <code>SignatureEnvironment</code> element to the response.
+ *
+ * @param envResponse 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).
+ */
+ private void addSignatureEnvironment(SignatureEnvironmentResponse envResponse) {
+ Element content = envResponse.getSignatureEnvironment();
+ Node importedSignature = responseDoc.importNode(content, true);
+ Element signatureEnvironment =
+ responseDoc.createElementNS(MOA_NS_URI, "SignatureEnvironment");
+ signatureEnvironment.appendChild(importedSignature);
+ responseElem.appendChild(signatureEnvironment);
+ }
+
+ /**
+ * Add a <code>ErrorResponse</code> element to the response.
+ *
+ * @param errorResponse The API object containing the information to put into
+ * the <code>ErrorResponse</code> DOM element.
+ */
+ private void addErrorResponse(ErrorResponse errorResponse) {
+ Element errorElem =
+ responseDoc.createElementNS(MOA_NS_URI, "ErrorResponse");
+ Element errorCodeElem =
+ responseDoc.createElementNS(MOA_NS_URI, "ErrorCode");
+ Element infoElem = responseDoc.createElementNS(MOA_NS_URI, "Info");
+ String errorCodeStr = Integer.toString(errorResponse.getErrorCode());
+
+ errorCodeElem.appendChild(responseDoc.createTextNode(errorCodeStr));
+ errorElem.appendChild(errorCodeElem);
+ infoElem.appendChild(responseDoc.createTextNode(errorResponse.getInfo()));
+ errorElem.appendChild(errorCodeElem);
+ errorElem.appendChild(infoElem);
+ responseElem.appendChild(errorElem);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java
new file mode 100644
index 000000000..66c08e0ab
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ProfileParser.java
@@ -0,0 +1,285 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+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.xmlsign.CreateSignatureEnvironmentProfile;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateSignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfo;
+import at.gv.egovernment.moa.spss.api.xmlsign.CreateTransformsInfoProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.SupplementProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.TransformParameter;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyTransformsInfoProfile;
+
+/**
+ * Parse the various profile elements contained in the MOA web service requests
+ * and given as separate files in the MOA configuration.
+ *
+ * The profiles parsed must be schema valid according to the MOA XML schema.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class ProfileParser {
+
+ //
+ // XPath expressions to select parts of the profiles
+ //
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ private static final String DSIG = Constants.DSIG_PREFIX + ":";
+ private static final String CREATE_TRANSFORMS_XPATH =
+ MOA + "CreateTransformsInfo/" + DSIG + "Transforms";
+ private static final String FINAL_DATA_META_INFO_XPATH =
+ MOA + "CreateTransformsInfo/" + MOA + "FinalDataMetaInfo";
+ private static final String CREATE_SIGNATURE_LOCATION_XPATH =
+ MOA + "CreateSignatureLocation";
+ private static final String SUPPLEMENT_XPATH = MOA + "Supplement";
+ private static final String VERIFY_TRANSFORMS_XPATH = DSIG + "Transforms";
+ private static final String TRANSFORM_PARAMETER_XPATH =
+ MOA + "TransformParameter";
+ private static final String TRANSFORM_PARAMETER_CONTENT_XPATH =
+ MOA + "Base64Content | " + MOA + "Hash";
+ private static final String DIGEST_METHOD_XPATH = DSIG + "DigestMethod";
+ private static final String DIGEST_VALUE_XPATH = DSIG + "DigestValue";
+
+ /** The factory used to create API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+
+ /**
+ * Parse a <code>CreateTransformsInfoProfile</code> DOM element.
+ *
+ * @param profileElem The <code>CreateTransformsInfoProfile</code> element
+ * to parse.
+ * @return The <code>CreateTransformsInfoProfile</code> API object containing
+ * the data from the <code>profileElem</code>.
+ * @throws MOAApplicationException An error occurred parsing the DOM element.
+ */
+ public CreateTransformsInfoProfile parseCreateTransformsInfoProfile(Element profileElem)
+ throws MOAApplicationException {
+ CreateTransformsInfo createTransformsInfo =
+ parseCreateTransformsInfo(profileElem);
+ List supplements = parseSupplements(profileElem);
+
+ return factory.createCreateTransformsInfoProfile(
+ createTransformsInfo,
+ supplements);
+ }
+
+ /**
+ * Parse the <code>CreateTransformsInfo</code> DOM element contained in a
+ * <code>CreateTransformsInfoProfile</code>.
+ *
+ * @param profileElem The <code>CreateTransformsInfoProfile</code> DOM
+ * element containing the <code>CreateTransformsInfo</code>.
+ * @return The <code>CreateTransformsInfo</code> API object containinig the
+ * data from the <code>CreateTransformsInfo</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>CreateTransformsInfo</code> DOM element.
+ */
+ private CreateTransformsInfo parseCreateTransformsInfo(Element profileElem)
+ throws MOAApplicationException {
+
+ Element transformsElem =
+ (Element) XPathUtils.selectSingleNode(
+ profileElem,
+ CREATE_TRANSFORMS_XPATH);
+ Element metaInfoElem =
+ (Element) XPathUtils.selectSingleNode(
+ profileElem,
+ FINAL_DATA_META_INFO_XPATH);
+ MetaInfo finalDataMetaInfo;
+ List transforms;
+
+ // parse the dsig:Transforms
+ if (transformsElem != null) {
+ TransformParser transformsParser = new TransformParser();
+ transforms = transformsParser.parseTransforms(transformsElem);
+ } else {
+ transforms = null;
+ }
+
+ // parse the meta info
+ finalDataMetaInfo = RequestParserUtils.parseMetaInfo(metaInfoElem);
+
+ return factory.createCreateTransformsInfo(transforms, finalDataMetaInfo);
+ }
+
+ /**
+ * Parse a <code>CreateSignatureEnvironmentProfile</code> DOM element.
+ *
+ * @param profileElem The <code>CreateSignatureEnvironmentProfile</code>
+ * DOM element to parse.
+ * @return The <code>CreateSignatureEnvironmentProfile</code> API object
+ * containing the data from the <code>profileElem</code>.
+ */
+ public CreateSignatureEnvironmentProfile parseCreateSignatureEnvironmentProfile(Element profileElem) {
+ CreateSignatureLocation createSignatureLocation =
+ parseCreateSignatureLocation(profileElem);
+ List supplements = parseSupplements(profileElem);
+
+ return factory.createCreateSignatureEnvironmentProfile(
+ createSignatureLocation,
+ supplements);
+ }
+
+ /**
+ * Parse a <code>CreateSignatureLocation</code> DOM element contained in
+ * a <code>CreateSignatureEnvironmentProfile</code>.
+ *
+ * @param profileElem The <code>CreateSignatureEnvironmentProfile</code> DOM
+ * element containing the <code>CreateSignatureLocation</code>.
+ * @return The <code>CreateSignatureLocation</code> API object containing
+ * the data from the <code>CreateSignatureLocation</code> DOM element.
+ */
+ private CreateSignatureLocation parseCreateSignatureLocation(Element profileElem) {
+ Element locationElem =
+ (Element) XPathUtils.selectSingleNode(
+ profileElem,
+ CREATE_SIGNATURE_LOCATION_XPATH);
+ String xPathExpression = DOMUtils.getText(locationElem);
+ Map namespaceDeclarations = DOMUtils.getNamespaceDeclarations(locationElem);
+ String indexStr = locationElem.getAttribute("Index");
+ int index = Integer.parseInt(indexStr);
+
+ return factory.createCreateSignatureLocation(
+ xPathExpression,
+ index,
+ namespaceDeclarations);
+ }
+
+ /**
+ * Parse all <code>Supplement</code> DOM elements contained in a given
+ * parent DOM element.
+ *
+ * @param supplementsParentElem The DOM element being the parent of the
+ * <code>Supplement</code>s.
+ * @return A <code>List</code> of <code>Supplement</code> API objects
+ * containing the data from the <code>Supplement</code> DOM elements.
+ */
+ private List parseSupplements(Element supplementsParentElem) {
+ List supplements = new ArrayList();
+ NodeIterator supplementElems =
+ XPathUtils.selectNodeIterator(supplementsParentElem, SUPPLEMENT_XPATH);
+ Element supplementElem;
+
+ while ((supplementElem = (Element) supplementElems.nextNode()) != null) {
+ XMLDataObjectAssociation supplement =
+ RequestParserUtils.parseXMLDataObjectAssociation(supplementElem);
+ supplements.add(supplement);
+ }
+ return supplements;
+ }
+
+ /**
+ * Parse a <code>SupplementProfile</code> DOM element.
+ *
+ * @param profileElem The <code>SupplementProfile</code> DOM element to parse.
+ * @return The <code>SupplementProfile</code> API object containing the
+ * data from the <code>SupplementProfile</code> DOM element.
+ */
+ public SupplementProfile parseSupplementProfile(Element profileElem) {
+ XMLDataObjectAssociation supplementProfile =
+ RequestParserUtils.parseXMLDataObjectAssociation(profileElem);
+
+ return factory.createSupplementProfile(supplementProfile);
+ }
+
+ /**
+ * Parse a <code>VerifyTransformsInfoProfile</code> DOM element.
+ *
+ * @param profileElem The <code>VerifyTransformsInfoProfile</code> DOM
+ * element to parse.
+ * @return A <code>VerifyTransformsInfoProfile</code> API object containing
+ * the information from the <code>VerifyTransformsInfoProfile</code> DOM
+ * element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>VerifyTransformsInfoProfile</code>.
+ */
+ public VerifyTransformsInfoProfile parseVerifyTransformsInfoProfile(Element profileElem)
+ throws MOAApplicationException {
+ Element transformsElem =
+ (Element) XPathUtils.selectSingleNode(
+ profileElem,
+ VERIFY_TRANSFORMS_XPATH);
+ List transforms = null;
+ NodeIterator paramElems =
+ XPathUtils.selectNodeIterator(profileElem, TRANSFORM_PARAMETER_XPATH);
+ Element paramElem;
+ List transformParameters = new ArrayList();
+
+ // parse the dsig:Transforms
+ if (transformsElem != null) {
+ TransformParser transformsParser = new TransformParser();
+ transforms = transformsParser.parseTransforms(transformsElem);
+ }
+
+ // parse the TransformParameter elements
+ while ((paramElem = (Element) paramElems.nextNode()) != null) {
+ transformParameters.add(parseTransformParameter(paramElem));
+ }
+
+ return factory.createVerifyTransformsInfoProfile(
+ transforms,
+ transformParameters);
+ }
+
+ /**
+ * Parse a <code>TransformParameter</code> DOM element.
+ *
+ * @param paramElem The <code>TransformParameter</code> DOM element to
+ * parse.
+ * @return The <code>TransformParameter</code> API object containing the
+ * information from the <code>TransformParameter</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>TransformParameter</code> DOM element.
+ */
+ private TransformParameter parseTransformParameter(Element paramElem)
+ throws MOAApplicationException {
+ String uri = paramElem.getAttribute("URI");
+ Element contentElem =
+ (Element) XPathUtils.selectSingleNode(
+ paramElem,
+ TRANSFORM_PARAMETER_CONTENT_XPATH);
+
+ if (contentElem == null) {
+ return factory.createTransformParameter(uri);
+ } else if ("Base64Content".equals(contentElem.getLocalName())) {
+ String base64Str = DOMUtils.getText(contentElem);
+ InputStream binaryContent = Base64Utils.decodeToStream(base64Str, true);
+
+ return factory.createTransformParameter(uri, binaryContent);
+ } else { // "Hash".equals(contentElem.getLocalName())
+ String digestMethodStr =
+ XPathUtils.getElementValue(contentElem, DIGEST_METHOD_XPATH, "");
+ String digestValueStr =
+ XPathUtils.getElementValue(contentElem, DIGEST_VALUE_XPATH, "");
+ byte[] digestValue = null;
+
+ try {
+ digestValue = Base64Utils.decode(digestValueStr, true);
+ } catch (IOException e) {
+ throw new MOAApplicationException("2270", null);
+ }
+ return factory.createTransformParameter(
+ uri,
+ digestMethodStr,
+ digestValue);
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java
new file mode 100644
index 000000000..0fff949b1
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/RequestParserUtils.java
@@ -0,0 +1,147 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.text.ParseException;
+import java.util.Date;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.DateTimeUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+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.common.XMLDataObjectAssociation;
+
+/**
+ * Utility methods for parsing XML requests definied in the MOA XML schema.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class RequestParserUtils {
+ //
+ // XPath expressions for parsing parts of a request
+ //
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ private static final String REFERENCE_ATTR_NAME = "Reference";
+ private static final String MIME_TYPE_XPATH = MOA + "MimeType";
+ private static final String DESCRIPTION_XPATH = MOA + "Description";
+ private static final String XML_ASSOC_CONTENT_XPATH = MOA + "Content";
+ private static final String CONTENT_XPATH =
+ MOA + "Base64Content | " + MOA + "XMLContent";
+ private static final String ANY_OTHER_XPATH =
+ "*[namespace-uri() != \"" + Constants.MOA_NS_URI + "\"]";
+
+ /**
+ * Parse a <code>XMLDataObjectAssociationType</code> kind of DOM element.
+ *
+ * @param assocElem The <code>XMLDataObjectAssociationType</code> kind of
+ * DOM elmeent to parse.
+ * @return The <code>XMLDataObjectAssociation</code> API object containing
+ * the data from the <code>XMLDataObjectAssociationType</code> DOM element.
+ */
+ public static XMLDataObjectAssociation parseXMLDataObjectAssociation(Element assocElem) {
+ SPSSFactory factory = SPSSFactory.getInstance();
+ MetaInfo metaInfo = parseMetaInfo(assocElem);
+ Element contentElem =
+ (Element) XPathUtils.selectSingleNode(assocElem, XML_ASSOC_CONTENT_XPATH);
+ Content content = parseContent(contentElem);
+
+ return factory.createXMLDataObjectAssociation(metaInfo, content);
+ }
+
+ /**
+ * Parse a <code>MetaInfoType</code> kind of DOM element.
+ *
+ * @param metaInfoElem The <code>MetaInfoType</code> kind of DOM element.
+ * @return The <code>MetaInfo</code> API object containing the data from
+ * the <code>metaInfoElem</code>.
+ */
+ public static MetaInfo parseMetaInfo(Element metaInfoElem) {
+ SPSSFactory factory = SPSSFactory.getInstance();
+ String mimeType =
+ XPathUtils.getElementValue(metaInfoElem, MIME_TYPE_XPATH, null);
+ String description =
+ XPathUtils.getElementValue(metaInfoElem, DESCRIPTION_XPATH, null);
+ NodeList anyOther =
+ XPathUtils.selectNodeList(metaInfoElem, ANY_OTHER_XPATH);
+
+ return factory.createMetaInfo(mimeType, description, anyOther);
+ }
+
+ /**
+ * Parse a <code>ContentOptionalRefType</code> or
+ * <code>ContentRequiredRefType</code> kind of DOM element.
+ * @param contentParentElem The DOM element being the parent of the
+ * content element.
+ * @return The <code>Content</code> API object containing the data from
+ * the given DOM element.
+ */
+ public static Content parseContent(Element contentParentElem) {
+ SPSSFactory factory = SPSSFactory.getInstance();
+ String referenceURI =
+ contentParentElem.hasAttribute(REFERENCE_ATTR_NAME)
+ ? contentParentElem.getAttribute(REFERENCE_ATTR_NAME)
+ : null;
+ Element contentElem =
+ (Element) XPathUtils.selectSingleNode(contentParentElem, CONTENT_XPATH);
+
+ if (contentElem == null) {
+ return factory.createContent(referenceURI);
+ }
+
+ if ("Base64Content".equals(contentElem.getLocalName())) {
+ String base64String = DOMUtils.getText(contentElem);
+ return factory.createContent(
+ Base64Utils.decodeToStream(base64String, true),
+ referenceURI);
+ } else { // "XMLContent".equals(contentElem.getLocalName())
+ return factory.createContent(contentElem.getChildNodes(), referenceURI);
+ }
+ }
+
+ /**
+ * Get the signing time from a Verfiy(CMS|XML)SignatureRequest.
+ *
+ * @param requestElem A <code>Verify(CMS|XML)SignatureRequest</code> DOM
+ * element.
+ * @param dateTimeXPath The XPath to lookup the <code>DateTime</code> element
+ * within the request.
+ * @return Date The date and time corresponding to the <code>DateTime</code>
+ * element in the request. If no <code>DateTime</code> element exists in the
+ * request, <code>null</code> is returned.
+ * @throws MOAApplicationException An error occurred during a parsing the
+ * <code>DateTime</code> element or creating the return value.
+ */
+ public static Date parseDateTime(Element requestElem, String dateTimeXPath)
+ throws MOAApplicationException {
+
+ Element dateTimeElem;
+ String dateTimeText;
+
+ // select the DateTime element
+ dateTimeElem =
+ (Element) XPathUtils.selectSingleNode(requestElem, dateTimeXPath);
+
+ // parse a date from the element value
+ if (dateTimeElem != null) {
+ dateTimeText = DOMUtils.getText(dateTimeElem);
+ try {
+ return DateTimeUtils.parseDateTime(dateTimeText);
+ } catch (ParseException e) {
+ throw new MOAApplicationException(
+ "1104",
+ new Object[] { dateTimeText });
+ }
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java
new file mode 100644
index 000000000..cc3e73e41
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/ResponseBuilderUtils.java
@@ -0,0 +1,213 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.io.IOException;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.X509Certificate;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import iaik.utils.RFC2253NameParser;
+import iaik.utils.RFC2253NameParserException;
+
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.Constants;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+
+/**
+ * Utility methods used by the verious <code>ResponseBuilder</code> classes.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+class ResponseBuilderUtils {
+ //
+ // shortcuts to various XML namespace constants
+ //
+ private static final String MOA_NS_URI = Constants.MOA_NS_URI;
+ private static final String SL11 = Constants.SL11_PREFIX + ":";
+ private static final String SL11_NS_URI = Constants.SL11_NS_URI;
+ private static final String DSIG = Constants.DSIG_PREFIX + ":";
+ private static final String DSIG_NS_URI = Constants.DSIG_NS_URI;
+ private static final String XMLNS_NS_URI = Constants.XMLNS_NS_URI;
+
+ /**
+ * Create a response element with all the namespaces set.
+ *
+ * @param responseName The name of the response root element.
+ * @return A DOM document containing the response root element and predefined
+ * MOA, DSIG and XML namespace declarations.
+ * @throws MOASystemException An error building the response document.
+ */
+ public static Document createResponse(String responseName)
+ throws MOASystemException {
+
+ try {
+ DocumentBuilder docBuilder =
+ DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ DOMImplementation impl = docBuilder.getDOMImplementation();
+ Document response;
+ Element root;
+ String attrValue;
+
+ response = impl.createDocument(MOA_NS_URI, responseName, null);
+ root = response.getDocumentElement();
+
+ // add namespace prefix declarations
+ root.setAttributeNS(XMLNS_NS_URI, "xmlns", MOA_NS_URI);
+ attrValue = "xmlns:" + Constants.DSIG_PREFIX;
+ root.setAttributeNS(XMLNS_NS_URI, attrValue, DSIG_NS_URI);
+
+ return response;
+ } catch (ParserConfigurationException e) {
+ throw new MOASystemException("2200", null, e);
+ }
+ }
+
+ /**
+ * Add a <code>SignerInfo</code> element to the response.
+ *
+ * @param response The response document, in order to create new elements in
+ * it.
+ * @param root The root element into which the <code>SignerInfo</code> element
+ * will be inserted.
+ * @param cert The signer certificate to add.
+ * @param isQualified Indicates, whether <code>cert</code> is a qualified
+ * certificate.
+ * @param isPublicAuthority Indicates, whether <code>cert</code> is
+ * certificate owned by a public authority.
+ * @param publicAuthorityID Information about the public authority owning
+ * <code>cert</code>. Must not be <code>null</code>, if
+ * <code>isPublicAuthority ! = null</code>.
+ * @throws MOAApplicationException An error occurred reading data from the
+ * certificate.
+ */
+ public static void addSignerInfo(
+ Document response,
+ Element root,
+ X509Certificate cert,
+ boolean isQualified,
+ boolean isPublicAuthority,
+ String publicAuthorityID)
+ throws MOAApplicationException {
+
+ Element signerInfoElem = response.createElementNS(MOA_NS_URI, "SignerInfo");
+ Element x509DataElem =
+ response.createElementNS(DSIG_NS_URI, DSIG + "X509Data");
+ Element x509IssuerSerialElem =
+ response.createElementNS(DSIG_NS_URI, DSIG + "X509IssuerSerial");
+ Element x509IssuerElem =
+ response.createElementNS(DSIG_NS_URI, DSIG + "X509IssuerName");
+ String issuer = cert.getIssuerDN().getName();
+ Element x509SerialNumberElem =
+ response.createElementNS(DSIG_NS_URI, DSIG + "X509SerialNumber");
+ String serialNumber = cert.getSerialNumber().toString();
+ Element x509SubjectNameElem =
+ response.createElementNS(DSIG_NS_URI, DSIG + "X509SubjectName");
+ Element x509CertificateElem =
+ response.createElementNS(DSIG_NS_URI, DSIG + "X509Certificate");
+ Element qualifiedCertificateElem =
+ isQualified
+ ? response.createElementNS(SL11_NS_URI, SL11 + "QualifiedCertificate")
+ : null;
+ Element publicAuthorityElem =
+ isPublicAuthority
+ ? response.createElementNS(MOA_NS_URI, "PublicAuthority")
+ : null;
+ Element codeElem =
+ publicAuthorityID != null
+ ? response.createElementNS(MOA_NS_URI, "Code")
+ : null;
+
+ // fill in text
+ x509IssuerElem.appendChild(response.createTextNode(issuer));
+ x509SerialNumberElem.appendChild(response.createTextNode(serialNumber));
+ try {
+ RFC2253NameParser parser =
+ new RFC2253NameParser(cert.getSubjectDN().getName());
+ String subjectRfc2253 = parser.parse().getRFC2253String();
+ x509SubjectNameElem.appendChild(response.createTextNode(subjectRfc2253));
+ } catch (RFC2253NameParserException e) {
+ x509SubjectNameElem.appendChild(
+ response.createTextNode(cert.getSubjectDN().getName()));
+ }
+ try {
+ x509CertificateElem.appendChild(
+ response.createTextNode(Base64Utils.encode(cert.getEncoded())));
+ } catch (CertificateEncodingException e) {
+ throw new MOAApplicationException("2245", null, e);
+ } catch (IOException e) {
+ throw new MOAApplicationException("2245", null, e);
+ }
+
+ // build structure
+ x509DataElem.appendChild(x509SubjectNameElem);
+ x509IssuerSerialElem.appendChild(x509IssuerElem);
+ x509IssuerSerialElem.appendChild(x509SerialNumberElem);
+ x509DataElem.appendChild(x509IssuerSerialElem);
+ x509DataElem.appendChild(x509CertificateElem);
+ if (isQualified) {
+ String attrValue = "xmlns:" + Constants.SL11_PREFIX;
+ qualifiedCertificateElem.setAttributeNS(
+ XMLNS_NS_URI,
+ attrValue,
+ SL11_NS_URI);
+ x509DataElem.appendChild(qualifiedCertificateElem);
+ }
+ if (isPublicAuthority) {
+ x509DataElem.appendChild(publicAuthorityElem);
+ if (publicAuthorityID != null) {
+ codeElem.appendChild(response.createTextNode(publicAuthorityID));
+ publicAuthorityElem.appendChild(codeElem);
+ }
+ }
+ signerInfoElem.appendChild(x509DataElem);
+ root.appendChild(signerInfoElem);
+ }
+
+ /**
+ * Add an element containing <code>Code</code> and <code>Info</code>
+ * subelements.
+ *
+ * @param response The response document, in order to create new elements in
+ * it.
+ * @param root The root element into which to insert the newly created
+ * element.
+ * @param elementName The name of the newly created element.
+ * @param code The content of the <code>Code</code> subelement.
+ * @param info The content of the <code>Info</code> subelement.
+ */
+ public static void addCodeInfoElement(
+ Document response,
+ Element root,
+ String elementName,
+ int code,
+ NodeList info) {
+
+ Element codeInfoElem = response.createElementNS(MOA_NS_URI, elementName);
+ Element codeElem = response.createElementNS(MOA_NS_URI, "Code");
+ Element infoElem;
+ int i;
+
+ codeElem.appendChild(response.createTextNode(Integer.toString(code)));
+ codeInfoElem.appendChild(codeElem);
+ if (info != null) {
+ infoElem = response.createElementNS(MOA_NS_URI, "Info");
+
+ for (i = 0; i < info.getLength(); i++) {
+ infoElem.appendChild(info.item(i).cloneNode(true));
+ }
+ codeInfoElem.appendChild(infoElem);
+ }
+ root.appendChild(codeInfoElem);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java
new file mode 100644
index 000000000..84f377826
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/TransformParser.java
@@ -0,0 +1,251 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.Base64Transform;
+import at.gv.egovernment.moa.spss.api.common.CanonicalizationTransform;
+import at.gv.egovernment.moa.spss.api.common.EnvelopedSignatureTransform;
+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;
+
+/**
+ * A parser to parse XMLDsig <code>Transform</code> DOM elements into their
+ * MOA SPSS API representation.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class TransformParser {
+ //
+ // XPath expressions for selecting information from the DOM tree
+ //
+ private static final String DSIG = Constants.DSIG_PREFIX + ":";
+ private static final String DSIG_FILTER2 =
+ Constants.DSIG_FILTER2_PREFIX + ":";
+ private static final String XSLT = Constants.XSLT_PREFIX + ":";
+ private static final String EC = Constants.DSIG_EC_PREFIX + ":";
+ private static final String TRANSFORM_XPATH = DSIG + "Transform";
+ private static final String XPATH_XPATH = DSIG + "XPath";
+ private static final String XSLT_ELEMENT_XPATH = XSLT + "stylesheet";
+ private static final String XPATH2_XPATH =
+ (DSIG_FILTER2 + "XPath[@Filter=\"intersect\"] | ")
+ + (DSIG_FILTER2 + "XPath[@Filter=\"subtract\"] | ")
+ + (DSIG_FILTER2 + "XPath[@Filter=\"union\"]");
+ private static final String INCLUSIVE_NAMESPACES_XPATH =
+ EC + "InclusiveNamespaces";
+
+ /**
+ * The <code>SPSSFactory</code> to use for creating new API objects.
+ */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+
+ /**
+ * Parse an XMLDsig <code>Transforms</code> DOM element.
+ *
+ * @param transformsElem The <code>Transforms</code> DOM element to parse.
+ * @return A <code>List</code> of <code>Transform</code> API objects
+ * containing the data from the individual <code>Transform</code> DOM
+ * elements.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>Transforms</code> DOM element.
+ */
+ public List parseTransforms(Element transformsElem)
+ throws MOAApplicationException {
+ List transforms = new ArrayList();
+ NodeIterator transformElems =
+ XPathUtils.selectNodeIterator(transformsElem, TRANSFORM_XPATH);
+ Element transformElem;
+ Transform transform;
+
+ while ((transformElem = (Element) transformElems.nextNode()) != null) {
+ transform = parseTransform(transformElem);
+ transforms.add(transform);
+ }
+
+ return transforms;
+ }
+
+ /**
+ * Parse an XMLDsig <code>Transform</code> DOM element.
+ *
+ * @param transformElem <code>Transform</code> DOM element to parse.
+ * @return The <code>Transform</code> API object containing the data
+ * from the <code>Transform</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>Transform</code> DOM element.
+ */
+ public Transform parseTransform(Element transformElem)
+ throws MOAApplicationException {
+
+ String algorithmUri = transformElem.getAttribute("Algorithm");
+
+ if (CanonicalizationTransform.CANONICAL_XML.equals(algorithmUri)
+ || CanonicalizationTransform.CANONICAL_XML_WITH_COMMENTS.equals(
+ algorithmUri)) {
+ return factory.createCanonicalizationTransform(algorithmUri);
+ } else if (
+ ExclusiveCanonicalizationTransform.EXCLUSIVE_CANONICAL_XML.equals(
+ algorithmUri)
+ || ExclusiveCanonicalizationTransform
+ .EXCLUSIVE_CANONICAL_XML_WITH_COMMENTS
+ .equals(
+ algorithmUri)) {
+ return parseExclusiveC14nTransform(algorithmUri, transformElem);
+ } else if (Base64Transform.BASE64_DECODING.equals(algorithmUri)) {
+ return factory.createBase64Transform();
+ } else if (
+ EnvelopedSignatureTransform.ENVELOPED_SIGNATURE.equals(algorithmUri)) {
+ return factory.createEnvelopedSignatureTransform();
+ } else if (XPathTransform.XPATH.equals(algorithmUri)) {
+ return parseXPathTransform(transformElem);
+ } else if (XPathFilter2Transform.XPATH_FILTER2.equals(algorithmUri)) {
+ return parseXPathFilter2Transform(transformElem);
+ } else if (XSLTTransform.XSLT.equals(algorithmUri)) {
+ return parseXSLTTransform(transformElem);
+ } else {
+ throw new MOAApplicationException("1108", new Object[] { algorithmUri });
+ }
+ }
+
+ /**
+ * Parse an exclusive canonicalization type of transform.
+ *
+ * @param algorithmUri The algorithm URI of the canonicalization algorithm.
+ * @param transformElem The <code>Transform</code> DOM element to parse.
+ * @return An <code>ExclusiveCanonicalizationTransform</code> API object
+ * containing the data from the <code>transformElem</code>.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>transformElem</code>.
+ */
+ private Transform parseExclusiveC14nTransform(
+ String algorithmUri,
+ Element transformElem)
+ throws MOAApplicationException {
+
+ Element inclusiveNamespacesElem =
+ (Element) XPathUtils.selectSingleNode(
+ transformElem,
+ INCLUSIVE_NAMESPACES_XPATH);
+
+ if (inclusiveNamespacesElem == null) {
+ throw new MOAApplicationException("2217", null);
+ } else {
+ StringTokenizer tokenizer =
+ new StringTokenizer(inclusiveNamespacesElem.getAttribute("PrefixList"));
+ List inclusiveNamespaces = new ArrayList();
+
+ while (tokenizer.hasMoreTokens()) {
+ inclusiveNamespaces.add(tokenizer.nextToken());
+ }
+
+ return factory.createExclusiveCanonicalizationTransform(
+ algorithmUri,
+ inclusiveNamespaces);
+ }
+ }
+
+ /**
+ * Parse an <code>XPath</code> type of <code>Transform</code>.
+ *
+ * @param transformElem The <code>Transform</code> DOM element to parse.
+ * @return The <code>Transform</code> API object representation of the
+ * <code>Transform</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>Transform</code> DOM element.
+ */
+ private Transform parseXPathTransform(Element transformElem)
+ throws MOAApplicationException {
+ Element xPathElem =
+ (Element) XPathUtils.selectSingleNode(transformElem, XPATH_XPATH);
+ Map nsDecls;
+
+ if (xPathElem == null) {
+ throw new MOAApplicationException("2202", null);
+ }
+
+ nsDecls = DOMUtils.getNamespaceDeclarations(xPathElem);
+ nsDecls.remove("");
+
+ return factory.createXPathTransform(DOMUtils.getText(xPathElem), nsDecls);
+ }
+
+ /**
+ * Parse an <code>XPathFilter2</code> type of <code>Transform</code>.
+ *
+ * @param transformElem The <code>Transform</code> DOM element to parse.
+ * @return The <code>Transform</code> API object representation of the
+ * <code>Transform</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>Transform</code> DOM element.
+ */
+ private Transform parseXPathFilter2Transform(Element transformElem)
+ throws MOAApplicationException {
+ List filters = new ArrayList();
+ NodeIterator iter =
+ XPathUtils.selectNodeIterator(transformElem, XPATH2_XPATH);
+ Element filterElem;
+
+ while ((filterElem = (Element) iter.nextNode()) != null) {
+ String filterAttr = filterElem.getAttribute("Filter");
+ String filterType;
+ String expression;
+ Map nsDecls;
+
+ if (filterAttr.equals("intersect")) {
+ filterType = XPathFilter.INTERSECT_TYPE;
+ } else if (filterAttr.equals("subtract")) {
+ filterType = XPathFilter.SUBTRACT_TYPE;
+ } else {
+ filterType = XPathFilter.UNION_TYPE;
+ }
+
+ expression = DOMUtils.getText(filterElem);
+ nsDecls = DOMUtils.getNamespaceDeclarations(filterElem);
+ nsDecls.remove("");
+ filters.add(factory.createXPathFilter(filterType, expression, nsDecls));
+ }
+ if (filters.size() == 0) {
+ throw new MOAApplicationException("2216", null);
+ }
+
+ return factory.createXPathFilter2Transform(filters);
+ }
+
+ /**
+ * Parse an <code>XSLT</code> type of <code>Transform</code>.
+ *
+ * @param transformElem The <code>Transform</code> DOM element to parse.
+ * @return The <code>Transform</code> API object representation of the
+ * <code>Transform</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>Transform</code> DOM element.
+ */
+ private Transform parseXSLTTransform(Element transformElem)
+ throws MOAApplicationException {
+ Element xsltElem =
+ (Element) XPathUtils.selectSingleNode(transformElem, XSLT_ELEMENT_XPATH);
+
+ if (xsltElem == null) {
+ throw new MOAApplicationException("2215", null);
+ }
+
+ return factory.createXSLTTransform(xsltElem);
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java
new file mode 100644
index 000000000..74d14b7cc
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureRequestParser.java
@@ -0,0 +1,169 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.CollectionUtils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.cmsverify.CMSContent;
+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.common.MetaInfo;
+
+/**
+ * A parser to parse <code>VerifyCMSSignatureRequest</code> DOM trees into
+ * <code>VerifyCMSSignatureRequest</code> API objects.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyCMSSignatureRequestParser {
+
+ //
+ // XPath expressions for selecting parts of the DOM message
+ //
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ private static final String DATE_TIME_XPATH = MOA + "DateTime";
+ private static final String CMS_SIGNATURE_XPATH = MOA + "CMSSignature";
+ private static final String TRUST_PROFILE_ID_XPATH = MOA + "TrustProfileID";
+ private static final String DATA_OBJECT_XPATH = MOA + "DataObject";
+ private static final String META_INFO_XPATH = MOA + "MetaInfo";
+ private static final String CONTENT_XPATH = MOA + "Content";
+ private static final String BASE64_CONTENT_XPATH = MOA + "Base64Content";
+
+ /** The <code>SPSSFactory</code> for creating new API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+
+ /**
+ * Parse a <code>VerifyCMSSignatureRequest</code> DOM element, as defined
+ * by the MOA schema.
+ *
+ * @param requestElem The <code>VerifyCMSSignatureRequest</code> to parse. The
+ * request must have been successfully parsed against the schema for this
+ * method to succeed.
+ * @return A <code>VerifyCMSSignatureRequest</code> API objects containing
+ * the data from the DOM element.
+ * @throws MOAApplicationException An error occurred parsing the request.
+ */
+ public VerifyCMSSignatureRequest parse(Element requestElem)
+ throws MOAApplicationException {
+
+ int[] signatories = parseSignatories(requestElem);
+ Date dateTime =
+ RequestParserUtils.parseDateTime(requestElem, DATE_TIME_XPATH);
+ String cmsSignatureStr =
+ XPathUtils.getElementValue(requestElem, CMS_SIGNATURE_XPATH, "");
+ CMSDataObject dataObject = parseDataObject(requestElem);
+ String trustProfileID =
+ XPathUtils.getElementValue(requestElem, TRUST_PROFILE_ID_XPATH, null);
+ InputStream cmsSignature =
+ Base64Utils.decodeToStream(cmsSignatureStr, true);
+
+ return factory.createVerifyCMSSignatureRequest(
+ signatories,
+ dateTime,
+ cmsSignature,
+ dataObject,
+ trustProfileID);
+ }
+
+ /**
+ * Parse the <code>Signatories</code> attribute contained in the
+ * <code>VerifyCMSSignatureRequest</code> DOM element.
+ *
+ * @param requestElem The <code>VerifyCMSSignatureRequest</code> DOM element.
+ * @return The signatories contained in the given
+ * <code>VerifyCMSSignatureRequest</code> DOM element.
+ */
+ private int[] parseSignatories(Element requestElem) {
+ String signatoriesStr = requestElem.getAttribute("Signatories");
+
+ if ("all".equals(signatoriesStr)) {
+ return VerifyCMSSignatureRequest.ALL_SIGNATORIES;
+ } else {
+ StringTokenizer tokenizer = new StringTokenizer(signatoriesStr);
+ List signatoriesList = new ArrayList();
+ int[] signatories;
+
+ // put the signatories into a List
+ while (tokenizer.hasMoreTokens()) {
+ try {
+ signatoriesList.add(new Integer(tokenizer.nextToken()));
+ } catch (NumberFormatException e) {
+ // this cannot occur if the request has been validated
+ }
+ }
+
+ // convert the List into an int array
+ signatories = CollectionUtils.toIntArray(signatoriesList);
+
+ return signatories;
+ }
+ }
+
+ /**
+ * Parse a the <code>DataObject</code> DOM element contained in a given
+ * <code>VerifyCMSSignatureRequest</code> DOM element.
+ *
+ * @param requestElem The <code>VerifyCMSSignatureRequest</code> DOM element
+ * to parse.
+ * @return The <code>CMSDataObject</code> API object containing the data
+ * from the <code>DataObject</code> DOM element.
+ */
+ private CMSDataObject parseDataObject(Element requestElem) {
+ Element dataObjectElem =
+ (Element) XPathUtils.selectSingleNode(requestElem, DATA_OBJECT_XPATH);
+
+ if (dataObjectElem != null) {
+ Element metaInfoElem =
+ (Element) XPathUtils.selectSingleNode(dataObjectElem, META_INFO_XPATH);
+ MetaInfo metaInfo = null;
+ Element contentElem =
+ (Element) XPathUtils.selectSingleNode(dataObjectElem, CONTENT_XPATH);
+ CMSContent content = parseContent(contentElem);
+
+ if (metaInfoElem != null) {
+ metaInfo = RequestParserUtils.parseMetaInfo(metaInfoElem);
+ }
+
+ return factory.createCMSDataObject(metaInfo, content);
+ } else {
+ return null;
+ }
+
+ }
+
+ /**
+ * Parse the content contained in a <code>CMSContentBaseType</code> kind of
+ * DOM element.
+ *
+ * @param contentElem The <code>CMSContentBaseType</code> kind of element to
+ * parse.
+ * @return A <code>CMSDataObject</code> API object containing the data
+ * from the given DOM element.
+ */
+ private CMSContent parseContent(Element contentElem) {
+ Element base64ContentElem =
+ (Element) XPathUtils.selectSingleNode(contentElem, BASE64_CONTENT_XPATH);
+
+ if (base64ContentElem != null) {
+ String base64Str = DOMUtils.getText(base64ContentElem);
+ InputStream binaryContent = Base64Utils.decodeToStream(base64Str, true);
+ return factory.createCMSContent(binaryContent);
+ } else {
+ return factory.createCMSContent(
+ contentElem.getAttribute("Reference"));
+ }
+ }
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java
new file mode 100644
index 000000000..3fc8f223d
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyCMSSignatureResponseBuilder.java
@@ -0,0 +1,101 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.util.Iterator;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+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;
+
+/**
+ * Convert a <code>VerifyCMSSignatureResponse</code> API object into its
+ * XML representation, according to the MOA XML schema.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyCMSSignatureResponseBuilder {
+ /** The XML document containing the response element. */
+ private Document responseDoc;
+ /** The response <code>VerifyCMSSignatureResponse</code> DOM element. */
+ private Element responseElem;
+
+ /**
+ * Create a new <code>VerifyCMSSignatureResponseBuilder</code>:
+ *
+ * @throws MOASystemException An error occurred setting up the resulting
+ * XML document.
+ */
+ public VerifyCMSSignatureResponseBuilder() throws MOASystemException {
+ responseDoc =
+ ResponseBuilderUtils.createResponse("VerifyCMSSignatureResponse");
+ responseElem = responseDoc.getDocumentElement();
+ }
+
+ /**
+ * Build a document containing a <code>VerifyCMSSignatureResponse</code>
+ * DOM element being the XML representation of the given
+ * <code>VerifyCMSSignatureResponse</code> API object.
+ *
+ * @param response The <code>VerifyCMSSignatureResponse</code> to convert
+ * to XML.
+ * @return A document containing the <code>VerifyCMSSignatureResponse</code>
+ * DOM element.
+ * @throws MOAApplicationException An error occurred building the response.
+ */
+ public Document build(VerifyCMSSignatureResponse response)
+ throws MOAApplicationException {
+
+ Iterator iter;
+
+ for (iter = response.getResponseElements().iterator(); iter.hasNext();) {
+ VerifyCMSSignatureResponseElement responseElement =
+ (VerifyCMSSignatureResponseElement) iter.next();
+ addResponseElement(responseElement);
+ }
+
+ return responseDoc;
+ }
+
+ /**
+ * Add an element to the response.
+ *
+ * @param responseElement The element to add to the response.
+ * @throws MOAApplicationException An error occurred adding the element.
+ */
+ private void addResponseElement(VerifyCMSSignatureResponseElement responseElement)
+ throws MOAApplicationException {
+
+ SignerInfo signerInfo = responseElement.getSignerInfo();
+ CheckResult signatureCheck = responseElement.getSignatureCheck();
+ CheckResult certCheck = responseElement.getCertificateCheck();
+
+ ResponseBuilderUtils.addSignerInfo(
+ responseDoc,
+ responseElem,
+ signerInfo.getSignerCertificate(),
+ signerInfo.isQualifiedCertificate(),
+ signerInfo.isPublicAuthority(),
+ signerInfo.getPublicAuhtorityID());
+
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ "SignatureCheck",
+ signatureCheck.getCode(),
+ signatureCheck.getInfo());
+
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ "CertificateCheck",
+ certCheck.getCode(),
+ certCheck.getInfo());
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java
new file mode 100644
index 000000000..e736af522
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureRequestParser.java
@@ -0,0 +1,275 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.w3c.dom.Element;
+import org.w3c.dom.traversal.NodeIterator;
+
+import at.gv.egovernment.moa.util.BoolUtils;
+import at.gv.egovernment.moa.util.Constants;
+import at.gv.egovernment.moa.util.DOMUtils;
+import at.gv.egovernment.moa.util.XPathUtils;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.api.SPSSFactory;
+import at.gv.egovernment.moa.spss.api.common.Content;
+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.SupplementProfile;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureInfo;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifySignatureLocation;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureRequest;
+
+/**
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyXMLSignatureRequestParser {
+
+ //
+ // XPath expressions for parsing parts of the request
+ //
+ private static final String MOA = Constants.MOA_PREFIX + ":";
+ private static final String DATE_TIME_XPATH = MOA + "DateTime";
+ private static final String RETURN_HASH_INPUT_DATA_XPATH =
+ MOA + "ReturnHashInputData";
+ private static final String TRUST_PROFILE_ID_XPATH = MOA + "TrustProfileID";
+ private static final String VERIFY_SIGNATURE_ENVIRONMENT_XPATH =
+ MOA + "VerifySignatureInfo/" + MOA + "VerifySignatureEnvironment";
+ private static final String VERIFY_SIGNATURE_LOCATION_XPATH =
+ MOA + "VerifySignatureInfo/" + MOA + "VerifySignatureLocation";
+ private static final String SUPPLEMENT_PROFILE_XPATH =
+ MOA + "SupplementProfile | " + MOA + "SupplementProfileID";
+ private static final String SIGNATURE_MANIFEST_CHECK_PARAMS_XPATH =
+ MOA + "SignatureManifestCheckParams";
+ private static final String VERIFY_TRANSFORMS_INFO_PROFILE_XPATH =
+ (MOA + "VerifyTransformsInfoProfile | ")
+ + (MOA + "VerifyTransformsInfoProfileID");
+ private static final String REFERENCE_INFO_XPATH = MOA + "ReferenceInfo";
+
+ /** The <code>SPSSFactory</code> for creating new API objects. */
+ private SPSSFactory factory = SPSSFactory.getInstance();
+
+
+ /**
+ * Parse a <code>VerifyXMLSignatureRequest</code> DOM element, as defined
+ * by the MOA schema.
+ *
+ * @param requestElem The <code>VerifyXMLSignatureRequest</code> to parse. The
+ * request must have been successfully parsed against the schema for this
+ * method to succeed.
+ * @return A <code>VerifyXMLSignatureRequest</code> API object containing
+ * the data from the DOM element.
+ * @throws MOAApplicationException An error occurred parsing the request.
+ */
+ public VerifyXMLSignatureRequest parse(Element requestElem)
+ throws MOAApplicationException {
+
+ Date dateTime =
+ RequestParserUtils.parseDateTime(requestElem, DATE_TIME_XPATH);
+ VerifySignatureInfo verifySignatureInfo =
+ parseVerifySignatureInfo(requestElem);
+ List supplementProfiles = parseSupplementProfiles(requestElem);
+ SignatureManifestCheckParams signatureManifestCheckParams =
+ parseSignatureManifestCheckParams(requestElem);
+ boolean returnHashInputData =
+ XPathUtils.selectSingleNode(requestElem, RETURN_HASH_INPUT_DATA_XPATH)
+ != null;
+ String trustProfileID =
+ XPathUtils.getElementValue(requestElem, TRUST_PROFILE_ID_XPATH, null);
+
+ return factory.createVerifyXMLSignatureRequest(
+ dateTime,
+ verifySignatureInfo,
+ supplementProfiles,
+ signatureManifestCheckParams,
+ returnHashInputData,
+ trustProfileID);
+ }
+
+ /**
+ * Parse the <code>VerifySignatureInfo</code> DOM element contained in
+ * the <code>VerifyXMLSignatureRequest</code> DOM element.
+ *
+ * @param requestElem The <code>VerifyXMLSignatureRequest</code> DOM element
+ * containing the <code>VerifySignatureInfo</code> DOM element.
+ * @return The <code>VerifySignatureInfo</code> API object containing the
+ * data from the DOM element.
+ */
+ private VerifySignatureInfo parseVerifySignatureInfo(Element requestElem) {
+ Element verifySignatureEnvironmentElem =
+ (Element) XPathUtils.selectSingleNode(
+ requestElem,
+ VERIFY_SIGNATURE_ENVIRONMENT_XPATH);
+ Content verifySignatureEnvironment =
+ RequestParserUtils.parseContent(verifySignatureEnvironmentElem);
+ VerifySignatureLocation verifySignatureLocation =
+ parseVerifySignatureLocation(requestElem);
+
+ return factory.createVerifySignatureInfo(
+ verifySignatureEnvironment,
+ verifySignatureLocation);
+ }
+
+ /**
+ * Parse the <code>VerifySignatureLocation</code> DOM element contained
+ * in the given <code>VerifyXMLSignatureRequest</code> DOM element.
+ *
+ * @param requestElem The <code>VerifyXMLSignatureRequst</code> DOM element.
+ * @return The <code>VerifySignatureLocation</code> API object containing the
+ * data from the DOM element.
+ */
+ private VerifySignatureLocation parseVerifySignatureLocation(Element requestElem) {
+ Element locationElem =
+ (Element) XPathUtils.selectSingleNode(
+ requestElem,
+ VERIFY_SIGNATURE_LOCATION_XPATH);
+ String xPathExpression = DOMUtils.getText(locationElem);
+ Map namespaceDeclarations = DOMUtils.getNamespaceDeclarations(locationElem);
+
+ return factory.createVerifySignatureLocation(
+ xPathExpression,
+ namespaceDeclarations);
+ }
+
+ /**
+ * Parse the supplement profiles contained in the given
+ * <code>VerifyXMLSignatureRequest</code> DOM element.
+ *
+ * @param requestElem The <code>VerifyXMLSignatureRequest</code> DOM element.
+ * @return A <code>List</code> of <code>SupplementProfile</code> API objects
+ * containing the data from the <code>SupplementProfile</code> DOM elements.
+ */
+ private List parseSupplementProfiles(Element requestElem) {
+ List supplementProfiles = new ArrayList();
+ NodeIterator profileElems =
+ XPathUtils.selectNodeIterator(requestElem, SUPPLEMENT_PROFILE_XPATH);
+ Element profileElem;
+
+ while ((profileElem = (Element) profileElems.nextNode()) != null) {
+ SupplementProfile profile;
+
+ if ("SupplementProfile".equals(profileElem.getLocalName())) {
+ ProfileParser profileParser = new ProfileParser();
+ profile = profileParser.parseSupplementProfile(profileElem);
+ } else {
+ String profileID = DOMUtils.getText(profileElem);
+ profile = factory.createSupplementProfile(profileID);
+ }
+ supplementProfiles.add(profile);
+ }
+ return supplementProfiles;
+ }
+
+ /**
+ * Parse the <code>SignatureManifestCheckParams</code> DOM element contained
+ * in the given <code>VerifyXMLSignatureRequest</code> DOM element.
+ * @param requestElem The <code>VerifyXMLSignatureRequest</code> DOM element.
+ * @return The <code>SignatureManifestCheckParams</code> API object containing
+ * the data from the <code>SignatureManifestCheckParams</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>SignatureManifestCheckParams</code> DOM element.
+ */
+ private SignatureManifestCheckParams parseSignatureManifestCheckParams(Element requestElem)
+ throws MOAApplicationException {
+ Element paramsElem =
+ (Element) XPathUtils.selectSingleNode(
+ requestElem,
+ SIGNATURE_MANIFEST_CHECK_PARAMS_XPATH);
+
+ if (paramsElem != null) {
+ String returnReferenceInputDataStr =
+ paramsElem.getAttribute("ReturnReferenceInputData");
+ boolean returnReferencInputData =
+ BoolUtils.valueOf(returnReferenceInputDataStr);
+ List referenceInfos = parseReferenceInfos(paramsElem);
+
+ return factory.createSignatureManifestCheckParams(
+ referenceInfos,
+ returnReferencInputData);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Parse the <code>ReferenceInfo</code> DOM elements contained in a
+ * <code>SignatureManifestCheckParams</code> DOM element.
+ *
+ * @param paramsElem The <code>SignatureManifestCheckParams</code> DOM element
+ * containing the <code>ReferenceInfo</code> DOM elements.
+ * @return A <code>List</code> of <code>RefernceInfo</code> API objects
+ * containing the data from the <code>ReferenceInfo</code> DOM elements.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>ReferenceInfo</code> DOM elements.
+ */
+ private List parseReferenceInfos(Element paramsElem)
+ throws MOAApplicationException {
+
+ List referenceInfos = new ArrayList();
+ NodeIterator refInfoElems =
+ XPathUtils.selectNodeIterator(paramsElem, REFERENCE_INFO_XPATH);
+ Element refInfoElem;
+
+ while ((refInfoElem = (Element) refInfoElems.nextNode()) != null) {
+ ReferenceInfo referenceInfo = parseReferenceInfo(refInfoElem);
+
+ referenceInfos.add(referenceInfo);
+ }
+
+ return referenceInfos;
+ }
+
+ /**
+ * Parse a <code>ReferenceInfo</code> DOM element.
+ *
+ * @param refInfoElem The <code>ReferenceInfo</code> DOM element to parse.
+ * @return The <code>ReferenceInfo</code> API object containing the data
+ * from the given <code>ReferenceInfo</code> DOM element.
+ * @throws MOAApplicationException An error occurred parsing the
+ * <code>ReferenceInfo</code> DOM element.
+ */
+ private ReferenceInfo parseReferenceInfo(Element refInfoElem)
+ throws MOAApplicationException {
+ List profiles = parseVerifyTransformsInfoProfiles(refInfoElem);
+ return factory.createReferenceInfo(profiles);
+ }
+
+ /**
+ * Parse the <code>VerifyTransformsInfoProfile</code> DOM elements contained
+ * in a <code>ReferenceInfo</code> DOM element.
+ *
+ * @param refInfoElem <code>ReferenceInfo</code> DOM element containing
+ * the <code>VerifyTransformsInfoProfile</code> DOM elements.
+ * @return A <code>List</code> of <code>VerifyTransformsInfoProfile</code>
+ * API objects containing the profile data.
+ * @throws MOAApplicationException An error occurred building the
+ * <code>VerifyTransformsInfoProfile</code>s.
+ */
+ private List parseVerifyTransformsInfoProfiles(Element refInfoElem)
+ throws MOAApplicationException {
+
+ List profiles = new ArrayList();
+ NodeIterator profileElems =
+ XPathUtils.selectNodeIterator(
+ refInfoElem,
+ VERIFY_TRANSFORMS_INFO_PROFILE_XPATH);
+ Element profileElem;
+
+ while ((profileElem = (Element) profileElems.nextNode()) != null) {
+ if ("VerifyTransformsInfoProfile".equals(profileElem.getLocalName())) {
+ ProfileParser profileParser = new ProfileParser();
+ profiles.add(
+ profileParser.parseVerifyTransformsInfoProfile(profileElem));
+ } else {
+ String profileID = DOMUtils.getText(profileElem);
+ profiles.add(factory.createVerifyTransformsInfoProfile(profileID));
+ }
+ }
+ return profiles;
+ }
+
+}
diff --git a/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java
new file mode 100644
index 000000000..56bcf63fa
--- /dev/null
+++ b/spss.server/src/at/gv/egovernment/moa/spss/api/xmlbind/VerifyXMLSignatureResponseBuilder.java
@@ -0,0 +1,300 @@
+package at.gv.egovernment.moa.spss.api.xmlbind;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import at.gv.egovernment.moa.util.Base64Utils;
+import at.gv.egovernment.moa.util.Constants;
+
+import at.gv.egovernment.moa.spss.MOAApplicationException;
+import at.gv.egovernment.moa.spss.MOASystemException;
+import at.gv.egovernment.moa.spss.api.common.Content;
+import at.gv.egovernment.moa.spss.api.common.ContentBinary;
+import at.gv.egovernment.moa.spss.api.common.ContentXML;
+import at.gv.egovernment.moa.spss.api.xmlverify.ManifestRefsCheckResult;
+import at.gv.egovernment.moa.spss.api.xmlverify.ReferencesCheckResult;
+import at.gv.egovernment.moa.spss.api.xmlverify.VerifyXMLSignatureResponse;
+
+/**
+ * Convert a <code>VerifyXMLSignatureResponse</code> API object into its
+ * XML representation, according to the MOA XML schema.
+ *
+ * @author Patrick Peck
+ * @version $Id$
+ */
+public class VerifyXMLSignatureResponseBuilder {
+ private static final String MOA_NS_URI = Constants.MOA_NS_URI;
+
+ /** The XML document containing the response element. */
+ private Document responseDoc;
+ /** The response <code>VerifyXMLSignatureResponse</code> DOM element. */
+ private Element responseElem;
+
+ /**
+ * Create a new <code>VerifyXMLSignatureResponseBuilder</code>:
+ *
+ * @throws MOASystemException An error occurred setting up the resulting
+ * XML document.
+ */
+ public VerifyXMLSignatureResponseBuilder() throws MOASystemException {
+ responseDoc =
+ ResponseBuilderUtils.createResponse("VerifyXMLSignatureResponse");
+ responseElem = responseDoc.getDocumentElement();
+ }
+
+ /**
+ * Build a document containing a <code>VerifyXMLSignatureResponse</code>
+ * DOM element being the XML representation of the given
+ * <code>VerifyXMLSignatureResponse</code> API object.
+ *
+ * @param response The <code>VerifyXMLSignatureResponse</code> to convert
+ * to XML.
+ * @return A document containing the <code>VerifyXMLSignatureResponse</code>
+ * DOM element.
+ * @throws MOAApplicationException An error occurred building the response.
+ */
+ public Document build(VerifyXMLSignatureResponse response)
+ throws MOAApplicationException {
+
+ Iterator iter;
+ List responseData;
+
+ // add the SignerInfo
+ ResponseBuilderUtils.addSignerInfo(
+ responseDoc,
+ responseElem,
+ response.getSignerInfo().getSignerCertificate(),
+ response.getSignerInfo().isQualifiedCertificate(),
+ response.getSignerInfo().isPublicAuthority(),
+ response.getSignerInfo().getPublicAuhtorityID());
+
+ // add HashInputData elements
+ responseData = response.getHashInputDatas();
+ if (responseData != null && !responseData.isEmpty()) {
+ for (iter = responseData.iterator(); iter.hasNext();) {
+ Content content = (Content) iter.next();
+ addContent("HashInputData", content);
+ }
+ }
+
+ // add ReferenceInputData elements
+ responseData = response.getReferenceInputDatas();
+ if (responseData != null && !responseData.isEmpty()) {
+ for (iter = responseData.iterator(); iter.hasNext();) {
+ Content content = (Content) iter.next();
+ addContent("ReferenceInputData", content);
+ }
+ }
+
+ // add the SignatureCheck
+ addReferencesCheckResult("SignatureCheck", response.getSignatureCheck());
+
+ // add the SignatureManifestCheck
+ if (response.getSignatureManifestCheck() != null) {
+ addReferencesCheckResult(
+ "SignatureManifestCheck",
+ response.getSignatureManifestCheck());
+ }
+
+ // add the XMLDsigManifestChecks
+ responseData = response.getXMLDsigManifestChecks();
+ if (responseData != null && !responseData.isEmpty()) {
+ for (iter = responseData.iterator(); iter.hasNext();) {
+ ManifestRefsCheckResult checkResult =
+ (ManifestRefsCheckResult) iter.next();
+ addManifestRefsCheckResult("XMLDSIGManifestCheck", checkResult);
+ }
+ }
+
+ // add the CertificateCheck
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ "CertificateCheck",
+ response.getCertificateCheck().getCode(),
+ response.getCertificateCheck().getInfo());
+
+ return responseDoc;
+ }
+
+ /**
+ * Add an element of type <code>ContentBaseType</code> to the response.
+ *
+ * @param elementName The name of the element.
+ * @param content The <code>Content</code> to add. Based on the type of
+ * the <code>Content</code>, either a <code>Base64Content</code> element
+ * or a <code>XMLContent</code> subelement will be added. A
+ * <code>ContentBinary</code> of type <code>BinaryDataObject</code> will be
+ * added as a <code>Base64Content</code> child element.
+ * <code>ContentXML</code> will be added as <code>XMLContent</code> child
+ * element.
+ * @throws MOAApplicationException An error occurred adding the content.
+ */
+ private void addContent(String elementName, Content content)
+ throws MOAApplicationException {
+
+ Element contentElem = responseDoc.createElementNS(MOA_NS_URI, elementName);
+
+ switch (content.getContentType()) {
+ case Content.XML_CONTENT :
+ ContentXML contentXml = (ContentXML) content;
+ NodeList nodes = contentXml.getXMLContent();
+ Element xmlElem;
+ int i;
+
+ xmlElem = responseDoc.createElementNS(MOA_NS_URI, "XMLContent");
+ //xmlElem.setAttributeNS(XML_NS_URI, "xml:space", "preserve");
+ xmlElem.setAttribute("xml:space", "preserve");
+
+ for (i = 0; i < nodes.getLength(); i++) {
+ xmlElem.appendChild(responseDoc.importNode(nodes.item(i), true));
+ }
+ contentElem.appendChild(xmlElem);
+ responseElem.appendChild(contentElem);
+ break;
+ case Content.BINARY_CONTENT :
+ Element binaryElem =
+ responseDoc.createElementNS(MOA_NS_URI, "Base64Content");
+ ContentBinary contentBinary = (ContentBinary) content;
+ String base64Str;
+
+ try {
+ base64Str = Base64Utils.encode(contentBinary.getBinaryContent());
+ } catch (IOException e) {
+ throw new MOAApplicationException("2200", null, e);
+ }
+ binaryElem.appendChild(responseDoc.createTextNode(base64Str));
+ contentElem.appendChild(binaryElem);
+ responseElem.appendChild(contentElem);
+ break;
+ }
+ }
+
+ /**
+ * Add a <code>ReferencesCheckResult</code> to the response.
+ *
+ * @param elementName The DOM element name to use.
+ * @param checkResult The <code>ReferencesCheckResult</code> to add.
+ */
+ private void addReferencesCheckResult(
+ String elementName,
+ ReferencesCheckResult checkResult) {
+
+ NodeList info = null;
+
+ if (checkResult.getInfo() != null) {
+ DocumentFragment fragment = responseDoc.createDocumentFragment();
+ NodeList anyOtherInfo = checkResult.getInfo().getAnyOtherInfo();
+ int[] failedReferences = checkResult.getInfo().getFailedReferences();
+
+ if (anyOtherInfo != null) {
+ addAnyOtherInfo(fragment, checkResult.getInfo().getAnyOtherInfo());
+ }
+
+ if (failedReferences != null) {
+ addFailedReferences(fragment, failedReferences);
+ }
+
+ info = fragment.getChildNodes();
+ }
+
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ elementName,
+ checkResult.getCode(),
+ info);
+ }
+
+
+ /**
+ * Add a <code>ManifestRefsCheckResult</code> to the response.
+ *
+ * @param elementName The DOM element name to use.
+ * @param checkResult The <code>ManifestRefsCheckResult</code> to add.
+ */
+ private void addManifestRefsCheckResult(
+ String elementName,
+ ManifestRefsCheckResult checkResult) {
+
+ DocumentFragment fragment = responseDoc.createDocumentFragment();
+ NodeList anyOtherInfo = checkResult.getInfo().getAnyOtherInfo();
+ int[] failedReferences = checkResult.getInfo().getFailedReferences();
+ Element referringSigRefElem;
+ String referringSigRefStr;
+
+ // add any other elements
+ if (anyOtherInfo != null) {
+ addAnyOtherInfo(fragment, checkResult.getInfo().getAnyOtherInfo());
+ }
+
+ // add the failed references
+ if (failedReferences != null) {
+ addFailedReferences(fragment, failedReferences);
+ }
+
+ // add the ReferringSigReference
+ referringSigRefElem =
+ responseDoc.createElementNS(MOA_NS_URI, "ReferringSigReference");
+ referringSigRefStr =
+ Integer.toString(checkResult.getInfo().getReferringSignatureReference());
+ referringSigRefElem.appendChild(
+ responseDoc.createTextNode(referringSigRefStr));
+ fragment.appendChild(referringSigRefElem);
+
+ // add XMLDSIGManifestCheckResult to the response
+ ResponseBuilderUtils.addCodeInfoElement(
+ responseDoc,
+ responseElem,
+ elementName,
+ checkResult.getCode(),
+ fragment.getChildNodes());
+ }
+
+ /**
+ * Add arbitrary XML content to a DOM <code>DocumentFragment</code>.
+ *
+ * @param fragment The fragment to add the XML content to.
+ * @param anyOtherInfo The XML content to add.
+ */
+ private void addAnyOtherInfo(
+ DocumentFragment fragment,
+ NodeList anyOtherInfo) {
+
+ int i;
+
+ for (i = 0; i < anyOtherInfo.getLength(); i++) {
+ fragment.appendChild(responseDoc.importNode(anyOtherInfo.item(i), true));
+ }
+ }
+
+ /**
+ * Add the failed references as <code>FailedReference</code> DOM elements to
+ * the fragment.
+ *
+ * @param fragment The DOM document fragment to add the
+ * <code>FailedReference</code> elements to.
+ * @param failedReferences The indexes of the failed references.
+ */
+ private void addFailedReferences(
+ DocumentFragment fragment,
+ int[] failedReferences) {
+ Element failedReferenceElem;
+ int i;
+
+ for (i = 0; i < failedReferences.length; i++) {
+ failedReferenceElem =
+ responseDoc.createElementNS(MOA_NS_URI, "FailedReference");
+ failedReferenceElem.appendChild(
+ responseDoc.createTextNode(Integer.toString(failedReferences[i])));
+ fragment.appendChild(failedReferenceElem);
+ }
+ }
+
+}